CrouzeixRaviart.cpp

Go to the documentation of this file.
00001 #include <CrouzeixRaviart.h> 
00002 
00003 
00004 CrouzeixRaviart:: CrouzeixRaviart() : StandardFE() {
00005   order = 1; 
00006 }
00007 
00008 
00009 int CrouzeixRaviart:: nbf() {
00010   return Ns.size();  
00011 }
00012 
00013 void CrouzeixRaviart:: compute_basis_functions() {
00014 
00015   if ( p == NULL ) {
00016     cout <<"You need to set a polygon before the basisfunctions can be computed"<<endl; 
00017     return; 
00018   }
00019  
00020 
00021   // see e.g. Brezzi and Fortin book page 116 for the definition
00022   
00023   if (p->str() == "ReferenceLine") { 
00024     cout <<"Can not define the Raviart-Thomas element on a line"<<endl;  
00025   } else if (p->str() == "ReferenceTriangle" || p->str() == "Triangle"  ) { 
00026     Triangle& triangle = (Triangle&)(*p); 
00027 
00028     // create the polynomial space
00029     GiNaC::ex polynom_space = bernstein(1, triangle, "a"); 
00030     GiNaC::ex polynom = polynom_space.op(0); 
00031     GiNaC::ex variables = polynom_space.op(1); 
00032     GiNaC::ex basis = polynom_space.op(2); 
00033 
00034     // create the dofs
00035     int counter = 0; 
00036     GiNaC::symbol t("t"); 
00037     for (int i=1; i<= 3; i++) {
00038       Line line = triangle.line(i); 
00039       GiNaC::ex dofi = line.integrate(polynom); 
00040       dofs.insert(dofs.end(),dofi); 
00041     }
00042 
00043     // solve the linear system to compute 
00044     // each of the basis functions
00045     for (int i=1; i<= 3; i++) {
00046       GiNaC::lst equations; 
00047       for (int j=1; j<= 3; j++) {
00048         equations.append(dofs[j-1] == dirac(i,j));
00049       }
00050       GiNaC::ex sub = lsolve(equations, variables); 
00051       GiNaC::ex Ni = polynom.subs(sub); 
00052       Ns.insert(Ns.end(),Ni); 
00053     }
00054 
00055   } else if ( p->str() == "ReferenceTetrahedron" ||  p->str() == "Tetrahedron" ) { 
00056     Tetrahedron& tetrahedron = (Tetrahedron&)(*p); 
00057     GiNaC::ex polynom_space = bernstein(1, tetrahedron, "a"); 
00058     GiNaC::ex polynom = polynom_space.op(0); 
00059     GiNaC::ex variables = polynom_space.op(1); 
00060     GiNaC::ex basis = polynom_space.op(2); 
00061 
00062 
00063     GiNaC::ex bernstein_pol; 
00064 
00065     int counter = 0; 
00066     GiNaC::symbol t("t"); 
00067     // dofs related to edges  
00068     for (int i=1; i<= 4; i++) {
00069       Triangle triangle = tetrahedron.triangle(i); 
00070       GiNaC::ex dofi = triangle.integrate(polynom); 
00071       dofs.insert(dofs.end(),dofi); 
00072     }
00073     for (int i=1; i<= 4; i++) {
00074       GiNaC::lst equations; 
00075       for (int j=1; j<= 4; j++) {
00076         equations.append(dofs[j-1] == dirac(i,j));
00077       }
00078       GiNaC::ex sub = lsolve(equations, variables); 
00079       GiNaC::ex Ni = polynom.subs(sub); 
00080       Ns.insert(Ns.end(),Ni); 
00081     }
00082 
00083 
00084 
00085   }
00086 }
00087 
00088 
00089 void CrouzeixRaviart:: set(Polygon& p_) {
00090   StandardFE:: set(p_); 
00091 }
00092 
00093 
00094 void CrouzeixRaviart:: set(int order_) { 
00095   if (order_ != 1) {
00096     cout <<"Only Crouziex-Raviart elements of order 1 is possible"<<endl;  
00097   }
00098 }
00099 
00100 
00101 GiNaC::ex CrouzeixRaviart:: dof(int i) {
00102   return StandardFE::dof(i);  
00103 }
00104 
00105 
00106 GiNaC::ex CrouzeixRaviart::N(int i) {  
00107   return StandardFE::N(i); 
00108 }
00109 
00110 
00111 
00112 // ------------VectorCrouzeixRaviart --- 
00113 
00114 
00115 VectorCrouzeixRaviart:: VectorCrouzeixRaviart() : StandardFE() {
00116   order = 1; 
00117 }
00118 
00119 int VectorCrouzeixRaviart:: nbf() {
00120   return StandardFE::nbf();       
00121 }
00122 
00123 void VectorCrouzeixRaviart:: compute_basis_functions() {
00124   CrouzeixRaviart fe; 
00125   fe.set(*p); 
00126   fe.compute_basis_functions(); 
00127   GiNaC::lst zero_list; 
00128   for (int s=1; s<= size ; s++) {
00129     zero_list.append(0);  
00130   }
00131 
00132   for (int i=0; i< fe.nbf() ; i++) {
00133     for (int s=0; s< size ; s++) {
00134       GiNaC::lst Nis = zero_list;    
00135       Nis.let_op(s) = fe.N(i); 
00136       GiNaC::ex Nmat = GiNaC::matrix(size,1,Nis); 
00137       Ns.insert(Ns.end(), Nmat);  
00138 
00139       GiNaC::lst dof = GiNaC::lst(fe.dof(i), s) ; 
00140       dofs.insert(dofs.end(), dof);  
00141     }
00142   }
00143 }
00144 
00145 
00146 void VectorCrouzeixRaviart:: set_size(int size_) {
00147   size = size_; 
00148 }
00149 
00150 
00151 void VectorCrouzeixRaviart:: set(Polygon& p_) {
00152   StandardFE::set(p_); 
00153 }
00154 
00155 
00156 
00157 void VectorCrouzeixRaviart:: set(int order_) { 
00158   if (order_ != 1) {
00159     cout <<"Only Crouziex-Raviart elements of order 1 is possible"<<endl;  
00160   }
00161 }
00162 
00163 
00164 
00165 
00166 GiNaC::ex VectorCrouzeixRaviart:: dof(int i) {
00167   return StandardFE::dof(i);  
00168 }
00169 
00170 
00171 GiNaC::ex VectorCrouzeixRaviart::N(int i) {  
00172   return StandardFE::N(i); 
00173 }
00174 
00175 
00176 
00177 
00178 
00179 
00180 

Generated on Wed Apr 19 12:38:13 2006 for SyFi by  doxygen 1.4.4