LagrangeFE.cpp

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

Generated on Tue Nov 22 11:10:22 2005 for SyFi by  doxygen 1.4.4