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

# RaviartThomas Class Reference

`#include <RaviartThomas.h>`

Inheritance diagram for RaviartThomas:

List of all members.

## Public Member Functions
| RaviartThomas ()
virtual | ~RaviartThomas ()
virtual void | set (int order)
virtual void | set (Polygon &p)
virtual void | compute_basis_functions ()
virtual int | nbf ()
virtual GiNaC::ex | N (int i)
virtual GiNaC::ex | dof (int i)

## Detailed Description

Definition at line 8 of file RaviartThomas.h.

## Constructor & Destructor Documentation

RaviartThomas::RaviartThomas | ( |  | ) | `[inline]`

| Definition at line 10 of file RaviartThomas.h.
    00010 {}

virtual RaviartThomas::~RaviartThomas | ( |  | ) | `[inline, virtual]`

| Definition at line 11 of file RaviartThomas.h.
    00011 {}

## Member Function Documentation

void RaviartThomas::compute_basis_functions | ( |  | ) | `[virtual]`

| Reimplemented from StandardFE. Definition at line 9 of file RaviartThomas.cpp. References bernstein(), bernsteinv(), collapse(), StandardFE::dofs, inner(), Tetrahedron::integrate(), Triangle::integrate(), Line::integrate(), istr(), Triangle::line(), matrix_from_equations(), normal(), StandardFE::Ns, StandardFE::order, StandardFE::p, Polygon::str(), Tetrahedron::triangle(), x, y, and z. Referenced by check_RaviartThomas(), and main().
    00009                                              {
    00010
    00011   if ( order < 1 ) {
    00012     cout <<"Raviart-Thomas elements must be of order 1 or higher."<<endl;
    00013     return;
    00014   }
    00015
    00016
    00017   if ( p == NULL ) {
    00018     cout <<"You need to set a polygon before the basisfunctions can be computed"<<endl;
    00019     return;
    00020   }
    00021
    00022
    00023   // see e.g. Brezzi and Fortin book page 116 for the definition
    00024
    00025   if (p->str() == "ReferenceLine" || p->str() == "Line" ) {
    00026
    00027     cout <<"Can not define the Raviart-Thomas element on a line"<<endl;
    00028
    00029   } else if (p->str() == "ReferenceTriangle" || p->str() == "Triangle" ) {
    00030
    00031     Triangle& triangle = (Triangle&)(*p);
    00032     GiNaC::lst equations;
    00033     GiNaC::lst variables;
    00034     GiNaC::ex polynom_space1 = bernstein(order-1, triangle, "a");
    00035     GiNaC::ex polynom1 = polynom_space1.op(0);
    00036     GiNaC::ex polynom1_vars = polynom_space1.op(1);
    00037     GiNaC::ex polynom1_basis = polynom_space1.op(2);
    00038
    00039     GiNaC::lst polynom_space2 = bernsteinv(2,order-1, triangle, "b");
    00040     GiNaC::ex polynom2 = polynom_space2.op(0).op(0);
    00041     GiNaC::ex polynom3 = polynom_space2.op(0).op(1);
    00042
    00043
    00044     GiNaC::lst pspace = GiNaC::lst( polynom2 + polynom1*x,
    00045                       polynom3 + polynom1*y);
    00046     GiNaC::lst v2 = collapse(GiNaC::ex_to<GiNaC::lst>(polynom_space2.op(1)));
    00047
    00048
    00049     variables = collapse(GiNaC::lst(polynom_space1.op(1), v2));
    00050
    00051     // remove multiple dofs
    00052     if ( order >= 2) {
    00053       GiNaC::ex expanded_pol = GiNaC::expand(polynom1);
    00054       for (int c1=0; c1<= order-2;c1++) {
    00055         for (int c2=0; c2<= order-2;c2++) {
    00056           for (int c3=0; c3<= order-2;c3++) {
    00057             if ( c1 + c2 + c3 <= order -2 ) {
    00058               GiNaC::ex eq =  expanded_pol.coeff(x,c1).coeff(y,c2).coeff(z,c3);
    00059               if ( eq != GiNaC::numeric(0) ) {
    00060                 equations.append(eq == 0);
    00061               }
    00062             }
    00063           }
    00064         }
    00065       }
    00066     }
    00067
    00068     int removed_dofs = equations.nops();
    00069
    00070
    00071
    00072     GiNaC::ex bernstein_pol;
    00073
    00074     int counter = 0;
    00075     GiNaC::symbol t("t");
    00076     GiNaC::ex dofi;
    00077     // dofs related to edges
    00078     for (int i=1; i<= 3; i++) {
    00079       Line line = triangle.line(i);
    00080       GiNaC::lst normal_vec = normal(triangle, i);
    00081       bernstein_pol = bernstein(order-1, line, istr("a",i));
    00082       GiNaC::ex basis_space = bernstein_pol.op(2);
    00083       GiNaC::ex pspace_n = inner(pspace, normal_vec);
    00084
    00085       GiNaC::ex basis;
    00086       for (int j=0; j< basis_space.nops(); j++) {
    00087         counter++;
    00088         basis = basis_space.op(j);
    00089         GiNaC::ex integrand = pspace_n*basis;
    00090         dofi =  line.integrate(integrand);
    00091         dofs.insert(dofs.end(), dofi);
    00092         GiNaC::ex eq = dofi == GiNaC::numeric(0);
    00093         equations.append(eq);
    00094
    00095       }
    00096     }
    00097
    00098     // dofs related to the whole triangle
    00099     GiNaC::lst bernstein_polv;
    00100     if ( order > 1) {
    00101       counter++;
    00102       bernstein_polv = bernsteinv(2,order-2, triangle, "a");
    00103       GiNaC::ex basis_space = bernstein_polv.op(2);
    00104       for (int i=0; i< basis_space.nops(); i++) {
    00105         GiNaC::lst basis = GiNaC::ex_to<GiNaC::lst>(basis_space.op(i));
    00106         GiNaC::ex integrand = inner(pspace, basis);
    00107         dofi = triangle.integrate(integrand);
    00108         dofs.insert(dofs.end(), dofi);
    00109         GiNaC::ex eq = dofi == GiNaC::numeric(0);
    00110         equations.append(eq);
    00111       }
    00112     }
    00113     // invert the matrix:
    00114     // GiNaC has a bit strange way to invert a matrix.
    00115     // It solves the system AA^{-1} = Id.
    00116     // It seems that this way is the only way to do
    00117     // properly with the solve_algo::gauss flag.
    00118     //
    00119     GiNaC::matrix b; GiNaC::matrix A;
    00120     matrix_from_equations(equations, variables, A, b);
    00121
    00122     int ncols = A.cols();
    00123     GiNaC::matrix vars_sq(ncols, ncols);
    00124
    00125     // matrix of symbols
    00126     for (unsigned r=0; r<ncols; ++r)
    00127       for (unsigned c=0; c<ncols; ++c)
    00128         vars_sq(r, c) = GiNaC::symbol();
    00129
    00130     GiNaC::matrix id(ncols, ncols);
    00131
    00132     // identity
    00133     const GiNaC::ex _ex1(1);
    00134     for (unsigned i=0; i<ncols; ++i)
    00135       id(i, i) = _ex1;
    00136
    00137
    00138     // invert the matrix
    00139     GiNaC::matrix m_inv(ncols, ncols);
    00140     m_inv = A.solve(vars_sq, id, GiNaC::solve_algo::gauss);
    00141
    00142
    00143     for (int i=0; i<dofs.size(); i++) {
    00144       b.let_op(removed_dofs + i) = GiNaC::numeric(1);
    00145       GiNaC::ex xx = m_inv.mul(GiNaC::ex_to<GiNaC::matrix>(b));
    00146
    00147       GiNaC::lst subs;
    00148       for (int ii=0; ii<xx.nops(); ii++) {
    00149         subs.append(variables.op(ii) == xx.op(ii));
    00150       }
    00151       GiNaC::ex Nj1 = pspace.op(0).subs(subs);
    00152       GiNaC::ex Nj2 = pspace.op(1).subs(subs);
    00153       Ns.insert(Ns.end(), GiNaC::matrix(1,2,GiNaC::lst(Nj1,Nj2)));
    00154       b.let_op(removed_dofs + i) = GiNaC::numeric(0);
    00155     }
    00156
    00157   } else if ( p->str() == "ReferenceTetrahedron" || p->str() == "Tetrahedron" ) {
    00158
    00159
    00160     Tetrahedron& tetrahedron = (Tetrahedron&)(*p);
    00161     GiNaC::lst equations;
    00162     GiNaC::lst variables;
    00163     GiNaC::ex polynom_space1 = bernstein(order-1, tetrahedron, "a");
    00164     GiNaC::ex polynom1 = polynom_space1.op(0);
    00165     GiNaC::ex polynom1_vars = polynom_space1.op(1);
    00166     GiNaC::ex polynom1_basis = polynom_space1.op(2);
    00167
    00168
    00169     GiNaC::lst polynom_space2 = bernsteinv(3,order-1, tetrahedron, "b");
    00170     GiNaC::ex polynom2 = polynom_space2.op(0).op(0);
    00171     GiNaC::ex polynom3 = polynom_space2.op(0).op(1);
    00172     GiNaC::ex polynom4 = polynom_space2.op(0).op(2);
    00173
    00174
    00175
    00176     GiNaC::lst pspace = GiNaC::lst( polynom2 + polynom1*x,
    00177                                     polynom3 + polynom1*y,
    00178                                     polynom4 + polynom1*z);
    00179
    00180     GiNaC::lst v2 = collapse(GiNaC::ex_to<GiNaC::lst>(polynom_space2.op(1)));
    00181
    00182
    00183     variables = collapse(GiNaC::lst(polynom_space1.op(1), v2));
    00184
    00185     GiNaC::ex bernstein_pol;
    00186
    00187
    00188     // remove multiple dofs
    00189     if ( order >= 2) {
    00190       GiNaC::ex expanded_pol = GiNaC::expand(polynom1);
    00191       for (int c1=0; c1<= order-2;c1++) {
    00192         for (int c2=0; c2<= order-2;c2++) {
    00193           for (int c3=0; c3<= order-2;c3++) {
    00194             if ( c1 + c2 + c3 <= order -2 ) {
    00195               GiNaC::ex eq =  expanded_pol.coeff(x,c1).coeff(y,c2).coeff(z,c3);
    00196               if ( eq != GiNaC::numeric(0) ) {
    00197                 equations.append(eq == 0);
    00198               }
    00199             }
    00200           }
    00201         }
    00202       }
    00203     }
    00204
    00205     int removed_dofs = equations.nops();
    00206
    00207
    00208
    00209     int counter = 0;
    00210     GiNaC::symbol t("t");
    00211     GiNaC::ex dofi;
    00212     // dofs related to edges
    00213     for (int i=1; i<= 4; i++) {
    00214       Triangle triangle = tetrahedron.triangle(i);
    00215       GiNaC::lst normal_vec = normal(tetrahedron, i);
    00216       bernstein_pol = bernstein(order-1, triangle, istr("a",i));
    00217       GiNaC::ex basis_space = bernstein_pol.op(2);
    00218       GiNaC::ex pspace_n = inner(pspace, normal_vec);
    00219
    00220       GiNaC::ex basis;
    00221       for (int j=0; j< basis_space.nops(); j++) {
    00222         counter++;
    00223         basis = basis_space.op(j);
    00224         GiNaC::ex integrand = pspace_n*basis;
    00225         dofi =  triangle.integrate(integrand);
    00226         dofs.insert(dofs.end(), dofi);
    00227         GiNaC::ex eq = dofi == GiNaC::numeric(0);
    00228         equations.append(eq);
    00229
    00230       }
    00231     }
    00232
    00233     // dofs related to the whole tetrahedron
    00234     GiNaC::lst bernstein_polv;
    00235     if ( order > 1) {
    00236       counter++;
    00237       bernstein_polv = bernsteinv(3,order-2, tetrahedron, "a");
    00238       GiNaC::ex basis_space = bernstein_polv.op(2);
    00239       for (int i=0; i< basis_space.nops(); i++) {
    00240         GiNaC::lst basis = GiNaC::ex_to<GiNaC::lst>(basis_space.op(i));
    00241         GiNaC::ex integrand = inner(pspace, basis);
    00242         dofi = tetrahedron.integrate(integrand);
    00243         dofs.insert(dofs.end(), dofi);
    00244         GiNaC::ex eq = dofi == GiNaC::numeric(0);
    00245         equations.append(eq);
    00246       }
    00247     }
    00248     // invert the matrix:
    00249     // GiNaC has a bit strange way to invert a matrix.
    00250     // It solves the system AA^{-1} = Id.
    00251     // It seems that this way is the only way to do
    00252     // properly with the solve_algo::gauss flag.
    00253     //
    00254     GiNaC::matrix b; GiNaC::matrix A;
    00255     matrix_from_equations(equations, variables, A, b);
    00256
    00257     int ncols = A.cols();
    00258     GiNaC::matrix vars_sq(ncols, ncols);
    00259
    00260     // matrix of symbols
    00261     for (unsigned r=0; r<ncols; ++r)
    00262       for (unsigned c=0; c<ncols; ++c)
    00263         vars_sq(r, c) = GiNaC::symbol();
    00264
    00265     GiNaC::matrix id(ncols, ncols);
    00266
    00267     // identity
    00268     const GiNaC::ex _ex1(1);
    00269     for (unsigned i=0; i<ncols; ++i)
    00270       id(i, i) = _ex1;
    00271
    00272
    00273     // invert the matrix
    00274     GiNaC::matrix m_inv(ncols, ncols);
    00275     m_inv = A.solve(vars_sq, id, GiNaC::solve_algo::gauss);
    00276
    00277
    00278     for (int i=0; i<dofs.size(); i++) {
    00279       b.let_op(removed_dofs + i) = GiNaC::numeric(1);
    00280       GiNaC::ex xx = m_inv.mul(GiNaC::ex_to<GiNaC::matrix>(b));
    00281
    00282       GiNaC::lst subs;
    00283       for (int ii=0; ii<xx.nops(); ii++) {
    00284         subs.append(variables.op(ii) == xx.op(ii));
    00285       }
    00286       GiNaC::ex Nj1 = pspace.op(0).subs(subs);
    00287       GiNaC::ex Nj2 = pspace.op(1).subs(subs);
    00288       Ns.insert(Ns.end(), GiNaC::matrix(1,2,GiNaC::lst(Nj1,Nj2)));
    00289       b.let_op(removed_dofs + i) = GiNaC::numeric(0);
    00290     }
    00291   }
    00292 }

GiNaC::ex RaviartThomas::dof | ( | int | i | ) | `[virtual]`

| Reimplemented from StandardFE. Definition at line 305 of file RaviartThomas.cpp. References StandardFE::dof().
    00305                                  {
    00306   return StandardFE::dof(i);
    00307 }

GiNaC::ex RaviartThomas::N | ( | int | i | ) | `[virtual]`

| Reimplemented from StandardFE. Definition at line 310 of file RaviartThomas.cpp. References StandardFE::N(). Referenced by main().
    00310                               {
    00311   return StandardFE::N(i);
    00312 }

int RaviartThomas::nbf | ( |  | ) | `[virtual]`

| Reimplemented from StandardFE. Definition at line 5 of file RaviartThomas.cpp. References StandardFE::Ns. Referenced by main().
    00005                         {
    00006   return Ns.size();
    00007 }

void RaviartThomas::set | ( | Polygon & | p | ) | `[virtual]`

| Reimplemented from StandardFE. Definition at line 295 of file RaviartThomas.cpp. References StandardFE::set().
    00295                                     {
    00296   StandardFE:: set(p_);
    00297 }

void RaviartThomas::set | ( | int | order | ) | `[virtual]`

| Reimplemented from StandardFE. Definition at line 300 of file RaviartThomas.cpp. References StandardFE::set(). Referenced by check_RaviartThomas(), and main().
    00300                                    {
    00301   StandardFE:: set(order_);
    00302 }

The documentation for this class was generated from the following files:

- RaviartThomas.h
- RaviartThomas.cpp