Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Search for

# 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