LagrangeFE.cpp

Go to the documentation of this file.
00001 #include <LagrangeFE.h>
00002 #include <ElementComputations.h>
00003 
00004 int LagrangeFE:: nbf() {
00005   return StandardFE::nbf();       
00006 }
00007 
00008 void LagrangeFE:: compute_basis_functions() {
00009 
00010   // NOTE: in the below code dof(i) is not used to 
00011   // determine the basis functions 
00012 
00013   if ( order < 1 ) {
00014     cout <<"Lagrangian elements must be of order 1 or higher."<<endl; 
00015     return; 
00016   }
00017 
00018   if ( p == NULL ) {
00019     cout <<"You need to set a polygon before the basisfunctions can be computed"<<endl; 
00020     return; 
00021   }
00022    
00023 
00024   if (p->str() == "ReferenceLine") { 
00025     // Look at the case with the Triangle for a documented code
00026     GiNaC::ex polynom; 
00027     GiNaC::lst variables; 
00028   
00029 //    polynom = pol(order, 1, "a"); 
00030 //    variables = coeffs(polynom); 
00031     GiNaC::ex polynom_space = bernstein(order, *p, "a"); 
00032 //    GiNaC::ex polynom_space = pol(order, 1, "a"); 
00033     polynom = polynom_space.op(0); 
00034     variables = GiNaC::ex_to<GiNaC::lst>(polynom_space.op(1));
00035   
00036     GiNaC::ex increment = GiNaC::numeric(1,order); 
00037   
00038     GiNaC::ex Nj; 
00039     for (int j=1; j <= order+1; j++) {
00040       GiNaC::lst equations; 
00041       int i=0; 
00042       for (GiNaC::ex p=0; p<= 1 ; p += increment ) { 
00043         i++; 
00044         GiNaC::ex eq = polynom == dirac(i,j); 
00045         equations.append(eq.subs(x == p));  
00046         if (j == 1) dofs.insert(dofs.end(), p); 
00047       }
00048   
00049       GiNaC::ex subs = lsolve(equations, variables); 
00050       Nj = polynom.subs(subs);   
00051       Ns.insert(Ns.end(), Nj); 
00052     }
00053   
00054 
00055   } else if (p->str() == "ReferenceTriangle" ) { 
00056     // Look at the case with the Triangle for a documented code
00057     GiNaC::ex polynom; 
00058     GiNaC::lst variables; 
00059   
00060 //    polynom = pol(order, 2, "b"); 
00061 //    variables = coeffs(polynom); 
00062     GiNaC::ex polynom_space = bernstein(order, *p, "b"); 
00063 //    GiNaC::ex polynom_space = pol(order, 2, "a"); 
00064     polynom = polynom_space.op(0); 
00065     variables = GiNaC::ex_to<GiNaC::lst>(polynom_space.op(1));
00066   
00067     GiNaC::ex increment = GiNaC::numeric(1,order); 
00068   
00069     GiNaC::ex Nj; 
00070     for (int j=1; j <= (order+1)*(order+2)/2; j++) {
00071       GiNaC::lst equations; 
00072       int i=0; 
00073       GiNaC::numeric one = 1; 
00074       for (GiNaC::ex q=0; q<= one  ; q += increment ) { 
00075         for (GiNaC::ex p=0; p<= one-q ; p += increment ) { 
00076           i++; 
00077           GiNaC::ex eq = polynom == dirac(i,j); 
00078           equations.append(eq.subs(GiNaC::lst(x == p, y == q)));  
00079           if ( j == 1) dofs.insert(dofs.end(), GiNaC::lst(p,q)); 
00080         }
00081       }
00082 
00083   
00084       GiNaC::ex subs = lsolve(equations, variables); 
00085       Nj = polynom.subs(subs);   
00086       Ns.insert(Ns.end(), Nj); 
00087     }
00088   } 
00089   else if ( p->str() == "Triangle" ){ 
00090     // Look HERE for the documented code
00091     GiNaC::ex polynom; 
00092     GiNaC::lst variables; 
00093 
00094     GiNaC::ex polynom_space = pol(order, 2, "a"); 
00095     // the polynomial spaces on the form: 
00096     // first item:     a0 + a1*x + a2*y + a3*x^2 + a4*x*y ...     the polynom
00097     // second item:    a0, a1, a2, ...                            the coefficents 
00098     // third  item     1, x, y, x^2, ..                           the basis  
00099     // Could also do:
00100     // GiNaC::ex polynom_space = bernstein(order, t, "a"); 
00101 
00102 
00103     polynom = polynom_space.op(0); 
00104     variables = GiNaC::ex_to<GiNaC::lst>(polynom_space.op(1));
00105 
00106     GiNaC::ex Nj; 
00107     Polygon& pp = *p; 
00108     Triangle& t = (Triangle&) pp; 
00109     // The bezier ordinates (in which the basis function should be either 0 or 1)
00110     GiNaC::lst points = bezier_ordinates(t,order); 
00111 
00112     // Loop over all basis functions Nj and all points. 
00113     // Each basis function Nj is determined by a set of linear equations: 
00114     //   Nj(xi) = dirac(i,j) 
00115     // This system of equations is then solved by lsolve
00116     for (int j=1; j <= points.nops(); j++) {
00117       GiNaC::lst equations; 
00118       int i=0; 
00119       for (int i=1; i<= points.nops() ; i++ ) { 
00120         // The point xi 
00121         GiNaC::ex point = points.op(i-1); 
00122         // The equation Nj(xi) = dirac(i,j)  
00123         GiNaC::ex eq = polynom == dirac(i,j); 
00124         // The equation is appended to the list of equations
00125         equations.append(eq.subs(GiNaC::lst(x == point.op(0) , y == point.op(1))));  
00126         // Creation of dof(j)
00127         if ( j == 1) dofs.insert(dofs.end(), GiNaC::lst(point.op(0),point.op(1))); 
00128       }
00129   
00130 //      print(equations); 
00131 //      print(variables); 
00132       // We solve the linear system 
00133       GiNaC::ex subs = lsolve(equations, variables); 
00134       // Substitute to get the Nj 
00135       Nj = polynom.subs(subs);   
00136       // Append Nj to the list of basis functions 
00137       Ns.insert(Ns.end(), Nj); 
00138 
00139       // NOTE: In this case we create a linear system and solve it for each Nj.   
00140       // However, the matrix is always the same, it is only the right-hand side
00141       // that changes. Hence, it is possible to optimize here.  
00142 
00143     }
00144 
00145   } else if ( p->str() == "ReferenceTetrahedron" ) {
00146     // Look at the case with the Triangle for a documented code
00147     GiNaC::ex polynom; 
00148     GiNaC::lst variables; 
00149   
00150 //    polynom = pol(order, 3, "b"); 
00151 //    GiNaC::ex polynom_space = pol(order, 3, "a"); 
00152     GiNaC::ex polynom_space = bernstein(order, *p, "b"); 
00153     polynom = polynom_space.op(0); 
00154     variables = GiNaC::ex_to<GiNaC::lst>(polynom_space.op(1));
00155  
00156   
00157     int nno =0; 
00158     for (int j=0; j<= order; j++) { 
00159       nno += (j+1)*(j+2)/2; 
00160     }
00161   
00162     GiNaC::ex increment = GiNaC::numeric(1,order); 
00163   
00164     GiNaC::ex Nj; 
00165     for (int j=1; j <= nno; j++) {
00166       GiNaC::lst equations; 
00167       int i=0; 
00168       for (GiNaC::ex r=0; r<= 1 ; r += increment ) { 
00169         for (GiNaC::ex q=0; q<= 1-r ; q += increment ) { 
00170           for (GiNaC::ex p=0; p<= 1-r-q ; p += increment ) { 
00171             i++; 
00172             GiNaC::ex eq = polynom == dirac(i,j); 
00173             equations.append(eq.subs(GiNaC::lst(x == p, y == q, z == r )));  
00174             if (j == 1) dofs.insert(dofs.end(), GiNaC::lst(p,q,r)); 
00175           }
00176         }
00177       }
00178   
00179       GiNaC::ex subs = lsolve(equations, variables); 
00180       Nj = polynom.subs(subs);   
00181       Ns.insert(Ns.end(), Nj); 
00182     }
00183   }
00184   else if ( p->str() == "Tetrahedron" ){ 
00185     // Look at the case with the Triangle for a documented code
00186     GiNaC::ex polynom; 
00187     GiNaC::lst variables; 
00188 
00189   
00190     GiNaC::ex polynom_space = pol(order, 3, "a"); 
00191 //    GiNaC::ex polynom_space = bernstein(order, *p, "b"); 
00192     polynom = polynom_space.op(0); 
00193     variables = GiNaC::ex_to<GiNaC::lst>(polynom_space.op(1));
00194  
00195   
00196     GiNaC::ex increment = GiNaC::numeric(1,order); 
00197   
00198     GiNaC::ex Nj; 
00199     Polygon& pp = *p; 
00200     Tetrahedron& t = (Tetrahedron&) pp; 
00201     GiNaC::lst points = bezier_ordinates(t,order); 
00202     for (int j=1; j <= points.nops(); j++) {
00203       GiNaC::lst equations; 
00204       int i=0; 
00205       for (int i=1; i<= points.nops() ; i++ ) { 
00206         GiNaC::ex point = points.op(i-1); 
00207         GiNaC::ex eq = polynom == dirac(i,j); 
00208         equations.append(eq.subs(GiNaC::lst(x == point.op(0) , y == point.op(1), z == point.op(2))));  
00209         if ( j == 1) dofs.insert(dofs.end(), GiNaC::lst(point.op(0),point.op(1),point.op(2))); 
00210       }
00211   
00212       GiNaC::ex subs = lsolve(equations, variables); 
00213       Nj = polynom.subs(subs);   
00214       Ns.insert(Ns.end(), Nj); 
00215     }
00216   }
00217 }
00218 
00219 
00220 
00221 void LagrangeFE:: set(Polygon& p_) {
00222   StandardFE::set(p_); 
00223 }
00224 
00225 
00226 void LagrangeFE:: set(int order_) { 
00227   StandardFE::set(order_); 
00228 }
00229 
00230 
00231 GiNaC::ex LagrangeFE:: dof(int i) {
00232   return StandardFE::dof(i);  
00233 }
00234 
00235 
00236 GiNaC::ex LagrangeFE::N(int i) {  
00237   return StandardFE::N(i); 
00238 }
00239 
00240 // ------------VectorLagrangeFE --- 
00241 
00242 int VectorLagrangeFE:: nbf() {
00243   return StandardFE::nbf();       
00244 }
00245 
00246 void VectorLagrangeFE:: compute_basis_functions() {
00247 
00248   if ( order < 1 ) {
00249     cout <<"Lagrangian elements must be of order 1 or higher."<<endl; 
00250     return; 
00251   }
00252 
00253 
00254   if ( p == NULL ) {
00255     cout <<"You need to set a polygon before the basisfunctions can be computed"<<endl; 
00256     return; 
00257   }
00258  
00259 
00260   LagrangeFE fe; 
00261   fe.set(order); 
00262   fe.set(*p); 
00263   fe.compute_basis_functions(); 
00264   GiNaC::lst zero_list; 
00265   for (int s=1; s<= size ; s++) {
00266     zero_list.append(0);  
00267   }
00268 
00269   for (int i=0; i< fe.nbf() ; i++) {
00270     for (int s=0; s< size ; s++) {
00271       GiNaC::lst Nis = zero_list;    
00272       Nis.let_op(s) = fe.N(i); 
00273       GiNaC::ex Nmat = GiNaC::matrix(size,1,Nis);
00274       Ns.insert(Ns.end(), Nmat);  
00275 
00276       GiNaC::lst dof = GiNaC::lst(fe.dof(i), s) ; 
00277       dofs.insert(dofs.end(), dof);  
00278     }
00279   }
00280 }
00281 
00282 
00283 void VectorLagrangeFE:: set_size(int size_) {
00284   size = size_; 
00285 }
00286 
00287 
00288 void VectorLagrangeFE:: set(Polygon& p_) {
00289   StandardFE::set(p_); 
00290 }
00291 
00292 
00293 void VectorLagrangeFE:: set(int order_) { 
00294   StandardFE::set(order_); 
00295 }
00296 
00297 
00298 GiNaC::ex VectorLagrangeFE:: dof(int i) {
00299   return StandardFE::dof(i);  
00300 }
00301 
00302 
00303 GiNaC::ex VectorLagrangeFE::N(int i) {  
00304   return StandardFE::N(i); 
00305 }
00306 
00307 
00308 
00309 
00310 

Generated on Tue Apr 18 12:00:26 2006 for SyFi by  doxygen 1.4.4