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

# HermiteFE.cpp

Go to the documentation of this file.

    00001 #include <HermiteFE.h>
    00002
    00003 int HermiteFE:: nbf() {
    00004   return StandardFE::nbf();
    00005 }
    00006
    00007 void HermiteFE:: compute_basis_functions() {
    00008
    00009   if ( p == NULL ) {
    00010     cout <<"You need to set a polygon before the basisfunctions can be computed"<<endl;
    00011     return;
    00012   }
    00013
    00014
    00015   if (p->str() == "ReferenceTriangle" || p->str() == "Triangle") {
    00016     GiNaC::ex polynom_space = pol(3, 2, "a");
    00017     GiNaC::ex polynom = polynom_space.op(0);
    00018     GiNaC::lst variables = GiNaC::ex_to<GiNaC::lst>(polynom_space.op(1));
    00019     GiNaC::lst equations;
    00020
    00021     for (int i=0; i<= 2; i++) {
    00022        GiNaC::ex v = p->vertex(i);
    00023        GiNaC::ex dofv = polynom.subs(GiNaC::lst(x == v.op(0), y == v.op(1)));
    00024        GiNaC::ex dofvdx = diff(polynom,x).subs(GiNaC::lst(x == v.op(0), y == v.op(1)));
    00025        GiNaC::ex dofvdy = diff(polynom,y).subs(GiNaC::lst(x == v.op(0), y == v.op(1)));
    00026
    00027        equations.append( dofv   == GiNaC::numeric(0));
    00028        equations.append( dofvdx == GiNaC::numeric(0));
    00029        equations.append( dofvdy == GiNaC::numeric(0));
    00030
    00031        dofs.insert(dofs.end(), GiNaC::lst(v.op(0), v.op(1), 0));
    00032        dofs.insert(dofs.end(), GiNaC::lst(v.op(0), v.op(1), 1));
    00033        dofs.insert(dofs.end(), GiNaC::lst(v.op(0), v.op(1), 2));
    00034     }
    00035     GiNaC::ex midpoint = GiNaC::lst((p->vertex(0).op(0) + p->vertex(1).op(0) + p->vertex(2).op(0))/3,
    00036                                     (p->vertex(0).op(1) + p->vertex(1).op(1) + p->vertex(2).op(1))/3);
    00037     GiNaC::ex dofm = polynom.subs(GiNaC::lst(x == midpoint.op(0), y == midpoint.op(1)));
    00038     dofs.insert(dofs.end(), midpoint );
    00039     equations.append( dofm == GiNaC::numeric(0));
    00040
    00041     GiNaC::matrix b; GiNaC::matrix A;
    00042     matrix_from_equations(equations, variables, A, b);
    00043
    00044     int ncols = A.cols();
    00045     GiNaC::matrix vars_sq(ncols, ncols);
    00046
    00047     // matrix of symbols
    00048     for (unsigned r=0; r<ncols; ++r)
    00049       for (unsigned c=0; c<ncols; ++c)
    00050         vars_sq(r, c) = GiNaC::symbol();
    00051
    00052     GiNaC::matrix id(ncols, ncols);
    00053
    00054     // identity
    00055     const GiNaC::ex _ex1(1);
    00056     for (unsigned i=0; i<ncols; ++i)
    00057       id(i, i) = _ex1;
    00058
    00059
    00060     // invert the matrix
    00061     GiNaC::matrix m_inv(ncols, ncols);
    00062     m_inv = A.solve(vars_sq, id, GiNaC::solve_algo::gauss);
    00063
    00064     for (int i=0; i<dofs.size(); i++) {
    00065       b.let_op(i) = GiNaC::numeric(1);
    00066       GiNaC::ex xx = m_inv.mul(GiNaC::ex_to<GiNaC::matrix>(b));
    00067
    00068       GiNaC::lst subs;
    00069       for (int ii=0; ii<xx.nops(); ii++) {
    00070         subs.append(variables.op(ii) == xx.op(ii));
    00071       }
    00072       GiNaC::ex Nj= polynom.subs(subs);
    00073       Ns.insert(Ns.end(), Nj);
    00074       b.let_op(i) = GiNaC::numeric(0);
    00075     }
    00076   } else if (p->str() == "ReferenceTetrahedron" || p->str() == "Tetrahedron") {
    00077     GiNaC::ex polynom_space = pol(3, 3, "a");
    00078     GiNaC::ex polynom = polynom_space.op(0);
    00079     GiNaC::lst variables = GiNaC::ex_to<GiNaC::lst>(polynom_space.op(1));
    00080     GiNaC::lst equations;
    00081
    00082     cout <<"polynom "<<polynom<<endl;
    00083
    00084     for (int i=0; i<= 3; i++) {
    00085        GiNaC::ex v = p->vertex(i);
    00086        GiNaC::ex dofv   = polynom.subs(GiNaC::lst(x == v.op(0), y == v.op(1), z == v.op(2) ));
    00087        GiNaC::ex dofvdx = diff(polynom,x).subs(GiNaC::lst(x == v.op(0), y == v.op(1), z == v.op(2) ));
    00088        GiNaC::ex dofvdy = diff(polynom,y).subs(GiNaC::lst(x == v.op(0), y == v.op(1), z == v.op(2) ));
    00089        GiNaC::ex dofvdz = diff(polynom,z).subs(GiNaC::lst(x == v.op(0), y == v.op(1), z == v.op(2) ));
    00090
    00091        equations.append( dofv   == GiNaC::numeric(0));
    00092        equations.append( dofvdx == GiNaC::numeric(0));
    00093        equations.append( dofvdy == GiNaC::numeric(0));
    00094        equations.append( dofvdz == GiNaC::numeric(0));
    00095
    00096        dofs.insert(dofs.end(), GiNaC::lst(v.op(0), v.op(1), 0));
    00097        dofs.insert(dofs.end(), GiNaC::lst(v.op(0), v.op(1), 1));
    00098        dofs.insert(dofs.end(), GiNaC::lst(v.op(0), v.op(1), 2));
    00099        dofs.insert(dofs.end(), GiNaC::lst(v.op(0), v.op(1), 3));
    00100
    00101     }
    00102     GiNaC::ex midpoint1 = GiNaC::lst(
    00103                     (p->vertex(0).op(0)*2 + p->vertex(1).op(0) + p->vertex(2).op(0) + p->vertex(3).op(0))/5,
    00104                     (p->vertex(0).op(1)*2 + p->vertex(1).op(1) + p->vertex(2).op(1) + p->vertex(3).op(1))/5,
    00105                     (p->vertex(0).op(2)*2 + p->vertex(1).op(2) + p->vertex(2).op(2) + p->vertex(3).op(2))/5);
    00106
    00107     GiNaC::ex midpoint2 = GiNaC::lst(
    00108                     (p->vertex(0).op(0) + p->vertex(1).op(0)*2 + p->vertex(2).op(0) + p->vertex(3).op(0))/5,
    00109                     (p->vertex(0).op(1) + p->vertex(1).op(1)*2 + p->vertex(2).op(1) + p->vertex(3).op(1))/5,
    00110                     (p->vertex(0).op(2) + p->vertex(1).op(2)*2 + p->vertex(2).op(2) + p->vertex(3).op(2))/5);
    00111
    00112     GiNaC::ex midpoint3 = GiNaC::lst(
    00113                     (p->vertex(0).op(0) + p->vertex(1).op(0) + p->vertex(2).op(0)*2 + p->vertex(3).op(0))/5,
    00114                     (p->vertex(0).op(1) + p->vertex(1).op(1) + p->vertex(2).op(1)*2 + p->vertex(3).op(1))/5,
    00115                     (p->vertex(0).op(2) + p->vertex(1).op(2) + p->vertex(2).op(2)*2 + p->vertex(3).op(2))/5);
    00116
    00117     GiNaC::ex midpoint4 = GiNaC::lst(
    00118                     (p->vertex(0).op(0) + p->vertex(1).op(0) + p->vertex(2).op(0) + p->vertex(3).op(0)*2)/5,
    00119                     (p->vertex(0).op(1) + p->vertex(1).op(1) + p->vertex(2).op(1) + p->vertex(3).op(1)*2)/5,
    00120                     (p->vertex(0).op(2) + p->vertex(1).op(2) + p->vertex(2).op(2) + p->vertex(3).op(2)*2)/5);
    00121
    00122
    00123     GiNaC::ex dofm1 = polynom.subs(GiNaC::lst(x == midpoint1.op(0), y == midpoint1.op(1), z == midpoint1.op(2)));
    00124     GiNaC::ex dofm2 = polynom.subs(GiNaC::lst(x == midpoint2.op(0), y == midpoint2.op(1), z == midpoint2.op(2)));
    00125     GiNaC::ex dofm3 = polynom.subs(GiNaC::lst(x == midpoint3.op(0), y == midpoint3.op(1), z == midpoint3.op(2)));
    00126     GiNaC::ex dofm4 = polynom.subs(GiNaC::lst(x == midpoint4.op(0), y == midpoint4.op(1), z == midpoint4.op(2)));
    00127
    00128     dofs.insert(dofs.end(), midpoint1 );
    00129     dofs.insert(dofs.end(), midpoint2 );
    00130     dofs.insert(dofs.end(), midpoint3 );
    00131     dofs.insert(dofs.end(), midpoint4 );
    00132
    00133     equations.append( dofm1 == GiNaC::numeric(0));
    00134     equations.append( dofm2 == GiNaC::numeric(0));
    00135     equations.append( dofm3 == GiNaC::numeric(0));
    00136     equations.append( dofm4 == GiNaC::numeric(0));
    00137
    00138     GiNaC::matrix b; GiNaC::matrix A;
    00139     matrix_from_equations(equations, variables, A, b);
    00140     cout <<"A "<<A<<endl;
    00141
    00142     int ncols = A.cols();
    00143     int nrows = A.rows();
    00144     GiNaC::matrix vars_sq(ncols, ncols);
    00145
    00146     cout <<"ncols "<<ncols<<endl;
    00147     cout <<"nrows "<<nrows<<endl;
    00148
    00149     // matrix of symbols
    00150     for (unsigned r=0; r<ncols; ++r)
    00151       for (unsigned c=0; c<ncols; ++c)
    00152         vars_sq(r, c) = GiNaC::symbol();
    00153
    00154     GiNaC::matrix id(ncols, ncols);
    00155
    00156     // identity
    00157     const GiNaC::ex _ex1(1);
    00158     for (unsigned i=0; i<ncols; ++i)
    00159       id(i, i) = _ex1;
    00160
    00161
    00162     // invert the matrix
    00163     GiNaC::matrix m_inv(ncols, ncols);
    00164     m_inv = A.solve(vars_sq, id, GiNaC::solve_algo::gauss);
    00165
    00166     for (int i=0; i<dofs.size(); i++) {
    00167       b.let_op(i) = GiNaC::numeric(1);
    00168       GiNaC::ex xx = m_inv.mul(GiNaC::ex_to<GiNaC::matrix>(b));
    00169
    00170       GiNaC::lst subs;
    00171       for (int ii=0; ii<xx.nops(); ii++) {
    00172         subs.append(variables.op(ii) == xx.op(ii));
    00173       }
    00174       GiNaC::ex Nj= polynom.subs(subs);
    00175       Ns.insert(Ns.end(), Nj);
    00176       b.let_op(i) = GiNaC::numeric(0);
    00177     }
    00178   }
    00179 }
    00180
    00181 void HermiteFE:: set(Polygon& p_) {
    00182   StandardFE::set(p_);
    00183 }
    00184
    00185
    00186 GiNaC::ex HermiteFE:: dof(int i) {
    00187   return StandardFE::dof(i);
    00188 }
    00189
    00190
    00191 GiNaC::ex HermiteFE::N(int i) {
    00192   return StandardFE::N(i);
    00193 }
    00194