SyFi  0.3
SyFi::RaviartThomas Class Reference

#include <RaviartThomas.h>

Inheritance diagram for SyFi::RaviartThomas:
SyFi::StandardFE SyFi::FE

List of all members.

Public Member Functions

 RaviartThomas ()
 RaviartThomas (Polygon &p, int order=1, bool pointwise=true)
virtual ~RaviartThomas ()
virtual void compute_basis_functions ()

Public Attributes

bool pointwise
GiNaC::lst dof_repr

Detailed Description

Definition at line 26 of file RaviartThomas.h.


Constructor & Destructor Documentation

Definition at line 30 of file RaviartThomas.cpp.

References SyFi::StandardFE::description.

                                      : StandardFE()
        {
                description = "RaviartThomas";
        }
SyFi::RaviartThomas::RaviartThomas ( Polygon p,
int  order = 1,
bool  pointwise = true 
)

Definition at line 35 of file RaviartThomas.cpp.

References compute_basis_functions(), and pointwise.

virtual SyFi::RaviartThomas::~RaviartThomas ( ) [inline, virtual]

Definition at line 33 of file RaviartThomas.h.

{}

Member Function Documentation

Reimplemented from SyFi::StandardFE.

Definition at line 41 of file RaviartThomas.cpp.

References SyFi::bernstein(), SyFi::bernsteinv(), test_syfi::debug::c, SyFi::collapse(), SyFi::StandardFE::description, dof_repr, SyFi::StandardFE::dofs, SyFi::inner(), SyFi::Line::integrate(), SyFi::Triangle::integrate(), SyFi::Tetrahedron::integrate(), SyFi::interior_coordinates(), SyFi::istr(), SyFi::Triangle::line(), SyFi::matrix_from_equations(), SyFi::normal(), SyFi::StandardFE::Ns, SyFi::StandardFE::order, SyFi::StandardFE::p, pointwise, SyFi::Polygon::str(), SyFi::t, SyFi::Tetrahedron::triangle(), SyFi::Polygon::vertex(), SyFi::x, SyFi::y, and SyFi::z.

Referenced by check_RaviartThomas(), main(), and RaviartThomas().

        {

                if ( order < 1 )
                {
                        throw(std::logic_error("Raviart-Thomas elements must be of order 1 or higher."));
                }

                if ( p == NULL )
                {
                        throw(std::logic_error("You need to set a polygon before the basisfunctions can be computed"));
                }

                // see e.g. Brezzi and Fortin book page 116 for the definition

                GiNaC::ex nsymb = GiNaC::symbol("n");
                if (pointwise)
                {

                        if ( p->str().find("ReferenceLine") != string::npos )
                        {

                                cout <<"Can not define the Raviart-Thomas element on a line"<<endl;

                        }
                        else if ( p->str().find("Triangle") != string::npos )
                        {
                                description = istr("RaviartThomas_", order) + "_2D";

                                Triangle& triangle = (Triangle&)(*p);
                                GiNaC::lst equations;
                                GiNaC::lst variables;
                                GiNaC::ex polynom_space1 = bernstein(order-1, triangle, "a");
                                GiNaC::ex polynom1 = polynom_space1.op(0);
                                GiNaC::ex polynom1_vars = polynom_space1.op(1);
                                GiNaC::ex polynom1_basis = polynom_space1.op(2);

                                GiNaC::lst polynom_space2 = bernsteinv(2,order-1, triangle, "b");
                                GiNaC::ex polynom2 = polynom_space2.op(0).op(0);
                                GiNaC::ex polynom3 = polynom_space2.op(0).op(1);

                                GiNaC::lst pspace = GiNaC::lst( polynom2 + polynom1*x,
                                        polynom3 + polynom1*y);
                                GiNaC::lst v2 = collapse(GiNaC::ex_to<GiNaC::lst>(polynom_space2.op(1)));

                                variables = collapse(GiNaC::lst(polynom_space1.op(1), v2));

                                // remove multiple dofs
                                if ( order >= 2)
                                {
                                        GiNaC::ex expanded_pol = GiNaC::expand(polynom1);
                                        for (unsigned int c1=0; c1<= order-2;c1++)
                                        {
                                                for (unsigned int c2=0; c2<= order-2;c2++)
                                                {
                                                        for (unsigned int c3=0; c3<= order-2;c3++)
                                                        {
                                                                if ( c1 + c2 + c3 <= order -2 )
                                                                {
                                                                        GiNaC::ex eq =  expanded_pol.coeff(x,c1).coeff(y,c2).coeff(z,c3);
                                                                        if ( eq != GiNaC::numeric(0) )
                                                                        {
                                                                                equations.append(eq == 0);
                                                                        }
                                                                }
                                                        }
                                                }
                                        }
                                }

                                int removed_dofs = equations.nops();

                                GiNaC::ex bernstein_pol;

                                int counter = 0;
                                GiNaC::symbol t("t");
                                GiNaC::ex dofi;
                                // dofs related to edges
                                for (int i=0; i< 3; i++)
                                {
                                        Line line = triangle.line(i);
                                        GiNaC::lst normal_vec = normal(triangle, i);
                                        GiNaC::ex Vn = inner(pspace, normal_vec);
                                        GiNaC::lst points = interior_coordinates(line, order-1);
                                        GiNaC::ex edge_length = line.integrate(GiNaC::numeric(1));

                                        GiNaC::ex point;
                                        for (unsigned int j=0; j< points.nops(); j++)
                                        {
                                                point = points.op(j);
                                                dofi = Vn.subs(x == point.op(0)).subs(y == point.op(1))*edge_length;
                                                GiNaC::ex eq = dofi == GiNaC::numeric(0);
                                                equations.append(eq);
                                                dofs.insert(dofs.end(), GiNaC::lst(point,nsymb));
                                        }
                                }

                                // dofs related to the whole triangle
                                if ( order > 1)
                                {
                                        counter++;
                                        GiNaC::lst points = interior_coordinates(triangle, order-2);
                                        GiNaC::ex point;
                                        for (unsigned int j=0; j< points.nops(); j++)
                                        {
                                                point = points.op(j);

                                                // x -component
                                                dofi = pspace.op(0).subs(x == point.op(0)).subs(y == point.op(1));
                                                GiNaC::ex eq = dofi == GiNaC::numeric(0);
                                                equations.append(eq);
                                                dofs.insert(dofs.end(), GiNaC::lst(point,0));

                                                // y -component
                                                dofi = pspace.op(1).subs(x == point.op(0)).subs(y == point.op(1));
                                                eq = dofi == GiNaC::numeric(0);
                                                equations.append(eq);
                                                dofs.insert(dofs.end(), GiNaC::lst(point,1));

                                        }
                                }

                                //          std::cout <<"no variables "<<variables.nops()<<std::endl;
                                //          std::cout <<"no equations "<<equations.nops()<<std::endl;

                                // invert the matrix:
                                // GiNaC has a bit strange way to invert a matrix.
                                // It solves the system AA^{-1} = Id.
                                // It seems that this way is the only way to do
                                // properly with the solve_algo::gauss flag.
                                //
                                GiNaC::matrix b; GiNaC::matrix A;
                                matrix_from_equations(equations, variables, A, b);

                                unsigned int ncols = A.cols();
                                GiNaC::matrix vars_sq(ncols, ncols);

                                // matrix of symbols
                                for (unsigned r=0; r<ncols; ++r)
                                        for (unsigned c=0; c<ncols; ++c)
                                                vars_sq(r, c) = GiNaC::symbol();

                                GiNaC::matrix id(ncols, ncols);

                                // identity
                                const GiNaC::ex _ex1(1);
                                for (unsigned i=0; i<ncols; ++i)
                                        id(i, i) = _ex1;

                                // invert the matrix
                                GiNaC::matrix m_inv(ncols, ncols);
                                m_inv = A.solve(vars_sq, id, GiNaC::solve_algo::gauss);

                                for (unsigned int i=0; i<dofs.size(); i++)
                                {
                                        b.let_op(removed_dofs + i) = GiNaC::numeric(1);
                                        GiNaC::ex xx = m_inv.mul(GiNaC::ex_to<GiNaC::matrix>(b));

                                        GiNaC::lst subs;
                                        for (unsigned int ii=0; ii<xx.nops(); ii++)
                                        {
                                                subs.append(variables.op(ii) == xx.op(ii));
                                        }
                                        GiNaC::ex Nj1 = pspace.op(0).subs(subs);
                                        GiNaC::ex Nj2 = pspace.op(1).subs(subs);
                                        Ns.insert(Ns.end(), GiNaC::matrix(2,1,GiNaC::lst(Nj1,Nj2)));
                                        b.let_op(removed_dofs + i) = GiNaC::numeric(0);
                                }

                        }
                        else if ( p->str().find("Tetrahedron") != string::npos )
                        {

                                description = istr("RaviartThomas_", order) + "_3D";

                                Tetrahedron& tetrahedron = (Tetrahedron&)(*p);
                                GiNaC::lst equations;
                                GiNaC::lst variables;
                                GiNaC::ex polynom_space1 = bernstein(order-1, tetrahedron, "a");
                                GiNaC::ex polynom1 = polynom_space1.op(0);
                                GiNaC::ex polynom1_vars = polynom_space1.op(1);
                                GiNaC::ex polynom1_basis = polynom_space1.op(2);

                                GiNaC::lst polynom_space2 = bernsteinv(3,order-1, tetrahedron, "b");
                                GiNaC::ex polynom2 = polynom_space2.op(0).op(0);
                                GiNaC::ex polynom3 = polynom_space2.op(0).op(1);
                                GiNaC::ex polynom4 = polynom_space2.op(0).op(2);

                                GiNaC::lst pspace = GiNaC::lst( polynom2 + polynom1*x,
                                        polynom3 + polynom1*y,
                                        polynom4 + polynom1*z);

                                GiNaC::lst v2 = collapse(GiNaC::ex_to<GiNaC::lst>(polynom_space2.op(1)));

                                variables = collapse(GiNaC::lst(polynom_space1.op(1), v2));

                                GiNaC::ex bernstein_pol;

                                // remove multiple dofs
                                if ( order >= 2)
                                {
                                        GiNaC::ex expanded_pol = GiNaC::expand(polynom1);
                                        for (unsigned int c1=0; c1<= order-2;c1++)
                                        {
                                                for (unsigned int c2=0; c2<= order-2;c2++)
                                                {
                                                        for (unsigned int c3=0; c3<= order-2;c3++)
                                                        {
                                                                if ( c1 + c2 + c3 <= order -2 )
                                                                {
                                                                        GiNaC::ex eq =  expanded_pol.coeff(x,c1).coeff(y,c2).coeff(z,c3);
                                                                        if ( eq != GiNaC::numeric(0) )
                                                                        {
                                                                                equations.append(eq == 0);
                                                                        }
                                                                }
                                                        }
                                                }
                                        }
                                }

                                int removed_dofs = equations.nops();

                                GiNaC::symbol t("t");
                                GiNaC::ex dofi;
                                // dofs related to edges
                                for (int i=0; i< 4; i++)
                                {
                                        Triangle triangle = tetrahedron.triangle(i);
                                        GiNaC::lst normal_vec = normal(tetrahedron, i);
                                        GiNaC::ex Vn = inner(pspace, normal_vec);
                                        GiNaC::lst points = interior_coordinates(triangle, order-1);
                                        GiNaC::ex triangle_size = triangle.integrate(GiNaC::numeric(1));

                                        GiNaC::ex point;
                                        for (unsigned int j=0; j< points.nops(); j++)
                                        {
                                                point = points.op(j);
                                                dofi = Vn.subs(x == point.op(0)).subs(y == point.op(1)).subs(z == point.op(2))*triangle_size;
                                                GiNaC::ex eq = dofi == GiNaC::numeric(0);
                                                equations.append(eq);
                                                dofs.insert(dofs.end(), GiNaC::lst(point,nsymb));
                                        }
                                }

                                // dofs related to the whole tetrahedron
                                if ( order > 1)
                                {

                                        GiNaC::lst points = interior_coordinates(tetrahedron, order-2);
                                        GiNaC::ex point;
                                        for (unsigned int j=0; j< points.nops(); j++)
                                        {
                                                point = points.op(j);

                                                // x -component
                                                dofi = pspace.op(0).subs(x == point.op(0)).subs(y == point.op(1)).subs(z == point.op(2));
                                                GiNaC::ex eq = dofi == GiNaC::numeric(0);
                                                equations.append(eq);
                                                dofs.insert(dofs.end(), GiNaC::lst(point,0));

                                                // y -component
                                                dofi = pspace.op(1).subs(x == point.op(0)).subs(y == point.op(1)).subs(z == point.op(2));
                                                eq = dofi == GiNaC::numeric(0);
                                                equations.append(eq);
                                                dofs.insert(dofs.end(), GiNaC::lst(point,1));

                                                // z -component
                                                dofi = pspace.op(2).subs(x == point.op(0)).subs(y == point.op(1)).subs(z == point.op(2));
                                                eq = dofi == GiNaC::numeric(0);
                                                equations.append(eq);
                                                dofs.insert(dofs.end(), GiNaC::lst(point,1));
                                        }
                                }

                                //              std::cout <<"no variables "<<variables.nops()<<std::endl;
                                //              std::cout <<"no equations "<<equations.nops()<<std::endl;

                                // invert the matrix:
                                // GiNaC has a bit strange way to invert a matrix.
                                // It solves the system AA^{-1} = Id.
                                // It seems that this way is the only way to do
                                // properly with the solve_algo::gauss flag.
                                //
                                GiNaC::matrix b; GiNaC::matrix A;
                                matrix_from_equations(equations, variables, A, b);

                                unsigned int ncols = A.cols();
                                GiNaC::matrix vars_sq(ncols, ncols);

                                // matrix of symbols
                                for (unsigned r=0; r<ncols; ++r)
                                        for (unsigned c=0; c<ncols; ++c)
                                                vars_sq(r, c) = GiNaC::symbol();

                                GiNaC::matrix id(ncols, ncols);

                                // identity
                                const GiNaC::ex _ex1(1);
                                for (unsigned i=0; i<ncols; ++i)
                                        id(i, i) = _ex1;

                                // invert the matrix
                                GiNaC::matrix m_inv(ncols, ncols);
                                m_inv = A.solve(vars_sq, id, GiNaC::solve_algo::gauss);

                                for (unsigned int i=0; i<dofs.size(); i++)
                                {
                                        b.let_op(removed_dofs + i) = GiNaC::numeric(1);
                                        GiNaC::ex xx = m_inv.mul(GiNaC::ex_to<GiNaC::matrix>(b));

                                        GiNaC::lst subs;
                                        for (unsigned int ii=0; ii<xx.nops(); ii++)
                                        {
                                                subs.append(variables.op(ii) == xx.op(ii));
                                        }
                                        GiNaC::ex Nj1 = pspace.op(0).subs(subs);
                                        GiNaC::ex Nj2 = pspace.op(1).subs(subs);
                                        GiNaC::ex Nj3 = pspace.op(2).subs(subs);
                                        Ns.insert(Ns.end(), GiNaC::matrix(3,1,GiNaC::lst(Nj1,Nj2,Nj3)));
                                        b.let_op(removed_dofs + i) = GiNaC::numeric(0);
                                }
                        }
                }
                else
                {

                        if ( p->str().find("ReferenceLine") != string::npos )
                        {

                                cout <<"Can not define the Raviart-Thomas element on a line"<<endl;

                        }
                        else if ( p->str().find("Triangle") != string::npos )
                        {

                                description = istr("RaviartThomas_", order) + "_2D";

                                Triangle& triangle = (Triangle&)(*p);
                                GiNaC::lst equations;
                                GiNaC::lst variables;
                                GiNaC::ex polynom_space1 = bernstein(order-1, triangle, "a");
                                GiNaC::ex polynom1 = polynom_space1.op(0);
                                GiNaC::ex polynom1_vars = polynom_space1.op(1);
                                GiNaC::ex polynom1_basis = polynom_space1.op(2);

                                GiNaC::lst polynom_space2 = bernsteinv(2,order-1, triangle, "b");
                                GiNaC::ex polynom2 = polynom_space2.op(0).op(0);
                                GiNaC::ex polynom3 = polynom_space2.op(0).op(1);

                                GiNaC::lst pspace = GiNaC::lst( polynom2 + polynom1*x,
                                        polynom3 + polynom1*y);
                                GiNaC::lst v2 = collapse(GiNaC::ex_to<GiNaC::lst>(polynom_space2.op(1)));

                                variables = collapse(GiNaC::lst(polynom_space1.op(1), v2));

                                // remove multiple dofs
                                if ( order >= 2)
                                {
                                        GiNaC::ex expanded_pol = GiNaC::expand(polynom1);
                                        for (unsigned int c1=0; c1<= order-2;c1++)
                                        {
                                                for (unsigned int c2=0; c2<= order-2;c2++)
                                                {
                                                        for (unsigned int c3=0; c3<= order-2;c3++)
                                                        {
                                                                if ( c1 + c2 + c3 <= order -2 )
                                                                {
                                                                        GiNaC::ex eq =  expanded_pol.coeff(x,c1).coeff(y,c2).coeff(z,c3);
                                                                        if ( eq != GiNaC::numeric(0) )
                                                                        {
                                                                                equations.append(eq == 0);
                                                                        }
                                                                }
                                                        }
                                                }
                                        }
                                }

                                int removed_dofs = equations.nops();

                                GiNaC::ex bernstein_pol;

                                int counter = 0;
                                GiNaC::symbol t("t");
                                GiNaC::ex dofi;
                                // dofs related to edges
                                for (int i=0; i< 3; i++)
                                {
                                        Line line = triangle.line(i);
                                        GiNaC::lst normal_vec = normal(triangle, i);
                                        bernstein_pol = bernstein(order-1, line, istr("a",i));
                                        GiNaC::ex basis_space = bernstein_pol.op(2);
                                        GiNaC::ex pspace_n = inner(pspace, normal_vec);

                                        GiNaC::ex basis;
                                        for (unsigned int j=0; j< basis_space.nops(); j++)
                                        {
                                                counter++;
                                                basis = basis_space.op(j);
                                                GiNaC::ex integrand = pspace_n*basis;
                                                dofi =  line.integrate(integrand);
                                                GiNaC::ex eq = dofi == GiNaC::numeric(0);
                                                equations.append(eq);

                                                GiNaC::lst d = GiNaC::lst(GiNaC::lst(line.vertex(0), line.vertex(1)),j);
                                                dofs.insert(dofs.end(), d);

                                                GiNaC::ex u = GiNaC::matrix(2,1,GiNaC::lst(GiNaC::symbol("v[0]"), GiNaC::symbol("v[1]")));
                                                GiNaC::ex n = GiNaC::matrix(2,1,GiNaC::lst(GiNaC::symbol("normal_vec[0]"), GiNaC::symbol("normal_vec[1]")));
                                                dof_repr.append(GiNaC::lst(inner(u,n)*basis.subs( x == GiNaC::symbol("xi[0]"))
                                                        .subs( y == GiNaC::symbol("xi[1]")), d));

                                        }
                                }

                                // dofs related to the whole triangle
                                GiNaC::lst bernstein_polv;
                                if ( order > 1)
                                {
                                        counter++;
                                        bernstein_polv = bernsteinv(2,order-2, triangle, "a");
                                        GiNaC::ex basis_space = bernstein_polv.op(2);
                                        for (unsigned int i=0; i< basis_space.nops(); i++)
                                        {
                                                GiNaC::lst basis = GiNaC::ex_to<GiNaC::lst>(basis_space.op(i));
                                                GiNaC::ex integrand = inner(pspace, basis);
                                                dofi = triangle.integrate(integrand);
                                                GiNaC::ex eq = dofi == GiNaC::numeric(0);
                                                equations.append(eq);

                                                GiNaC::lst d = GiNaC::lst(GiNaC::lst(triangle.vertex(0), triangle.vertex(1), triangle.vertex(2)), i);
                                                dofs.insert(dofs.end(), d);

                                        }
                                }
                                // invert the matrix:
                                // GiNaC has a bit strange way to invert a matrix.
                                // It solves the system AA^{-1} = Id.
                                // It seems that this way is the only way to do
                                // properly with the solve_algo::gauss flag.
                                //
                                GiNaC::matrix b; GiNaC::matrix A;
                                matrix_from_equations(equations, variables, A, b);

                                unsigned int ncols = A.cols();
                                GiNaC::matrix vars_sq(ncols, ncols);

                                // matrix of symbols
                                for (unsigned r=0; r<ncols; ++r)
                                        for (unsigned c=0; c<ncols; ++c)
                                                vars_sq(r, c) = GiNaC::symbol();

                                GiNaC::matrix id(ncols, ncols);

                                // identity
                                const GiNaC::ex _ex1(1);
                                for (unsigned i=0; i<ncols; ++i)
                                        id(i, i) = _ex1;

                                // invert the matrix
                                GiNaC::matrix m_inv(ncols, ncols);
                                m_inv = A.solve(vars_sq, id, GiNaC::solve_algo::gauss);

                                for (unsigned int i=0; i<dofs.size(); i++)
                                {
                                        b.let_op(removed_dofs + i) = GiNaC::numeric(1);
                                        GiNaC::ex xx = m_inv.mul(GiNaC::ex_to<GiNaC::matrix>(b));

                                        GiNaC::lst subs;
                                        for (unsigned int ii=0; ii<xx.nops(); ii++)
                                        {
                                                subs.append(variables.op(ii) == xx.op(ii));
                                        }
                                        GiNaC::ex Nj1 = pspace.op(0).subs(subs);
                                        GiNaC::ex Nj2 = pspace.op(1).subs(subs);
                                        Ns.insert(Ns.end(), GiNaC::matrix(2,1,GiNaC::lst(Nj1,Nj2)));
                                        b.let_op(removed_dofs + i) = GiNaC::numeric(0);
                                }

                        }
                        else if ( p->str().find("Tetrahedron") != string::npos )
                        {

                                description = istr("RaviartThomas_", order) + "_3D";

                                Tetrahedron& tetrahedron = (Tetrahedron&)(*p);
                                GiNaC::lst equations;
                                GiNaC::lst variables;
                                GiNaC::ex polynom_space1 = bernstein(order-1, tetrahedron, "a");
                                GiNaC::ex polynom1 = polynom_space1.op(0);
                                GiNaC::ex polynom1_vars = polynom_space1.op(1);
                                GiNaC::ex polynom1_basis = polynom_space1.op(2);

                                GiNaC::lst polynom_space2 = bernsteinv(3,order-1, tetrahedron, "b");
                                GiNaC::ex polynom2 = polynom_space2.op(0).op(0);
                                GiNaC::ex polynom3 = polynom_space2.op(0).op(1);
                                GiNaC::ex polynom4 = polynom_space2.op(0).op(2);

                                GiNaC::lst pspace = GiNaC::lst( polynom2 + polynom1*x,
                                        polynom3 + polynom1*y,
                                        polynom4 + polynom1*z);

                                GiNaC::lst v2 = collapse(GiNaC::ex_to<GiNaC::lst>(polynom_space2.op(1)));

                                variables = collapse(GiNaC::lst(polynom_space1.op(1), v2));

                                GiNaC::ex bernstein_pol;

                                // remove multiple dofs
                                if ( order >= 2)
                                {
                                        GiNaC::ex expanded_pol = GiNaC::expand(polynom1);
                                        for (unsigned int c1=0; c1<= order-2;c1++)
                                        {
                                                for (unsigned int c2=0; c2<= order-2;c2++)
                                                {
                                                        for (unsigned int c3=0; c3<= order-2;c3++)
                                                        {
                                                                if ( c1 + c2 + c3 <= order -2 )
                                                                {
                                                                        GiNaC::ex eq =  expanded_pol.coeff(x,c1).coeff(y,c2).coeff(z,c3);
                                                                        if ( eq != GiNaC::numeric(0) )
                                                                        {
                                                                                equations.append(eq == 0);
                                                                        }
                                                                }
                                                        }
                                                }
                                        }
                                }

                                int removed_dofs = equations.nops();

                                int counter = 0;
                                GiNaC::symbol t("t");
                                GiNaC::ex dofi;
                                // dofs related to edges
                                for (int i=0; i< 4; i++)
                                {
                                        Triangle triangle = tetrahedron.triangle(i);
                                        GiNaC::lst normal_vec = normal(tetrahedron, i);
                                        bernstein_pol = bernstein(order-1, triangle, istr("a",i));
                                        GiNaC::ex basis_space = bernstein_pol.op(2);
                                        GiNaC::ex pspace_n = inner(pspace, normal_vec);

                                        GiNaC::ex basis;
                                        for (unsigned int j=0; j< basis_space.nops(); j++)
                                        {
                                                counter++;
                                                basis = basis_space.op(j);
                                                GiNaC::ex integrand = pspace_n*basis;
                                                dofi =  triangle.integrate(integrand);
                                                GiNaC::ex eq = dofi == GiNaC::numeric(0);
                                                equations.append(eq);

                                                GiNaC::lst d = GiNaC::lst(GiNaC::lst(triangle.vertex(0), triangle.vertex(1), triangle.vertex(2)), j);
                                                dofs.insert(dofs.end(), d);

                                                GiNaC::ex u = GiNaC::matrix(3,1,GiNaC::lst(GiNaC::symbol("v[0]"), GiNaC::symbol("v[1]"), GiNaC::symbol("v[2]")));
                                                GiNaC::ex n = GiNaC::matrix(3,1,GiNaC::lst(GiNaC::symbol("normal_vec[0]"), GiNaC::symbol("normal_vec[1]"), GiNaC::symbol("normal_vec[2]")));
                                                dof_repr.append(GiNaC::lst(inner(u,n)*basis.subs( x == GiNaC::symbol("xi[0]"))
                                                        .subs( y == GiNaC::symbol("xi[1]"))
                                                        .subs( z == GiNaC::symbol("xi[2]")), d));

                                        }
                                }

                                // dofs related to the whole tetrahedron
                                GiNaC::lst bernstein_polv;
                                if ( order > 1)
                                {
                                        counter++;
                                        bernstein_polv = bernsteinv(3,order-2, tetrahedron, "a");
                                        GiNaC::ex basis_space = bernstein_polv.op(2);
                                        for (unsigned int i=0; i< basis_space.nops(); i++)
                                        {
                                                GiNaC::lst basis = GiNaC::ex_to<GiNaC::lst>(basis_space.op(i));
                                                GiNaC::ex integrand = inner(pspace, basis);
                                                dofi = tetrahedron.integrate(integrand);
                                                GiNaC::ex eq = dofi == GiNaC::numeric(0);
                                                equations.append(eq);

                                                GiNaC::lst d = GiNaC::lst(GiNaC::lst(tetrahedron.vertex(0), tetrahedron.vertex(1), tetrahedron.vertex(2), tetrahedron.vertex(3)), i);
                                                dofs.insert(dofs.end(), d);
                                        }
                                }
                                // invert the matrix:
                                // GiNaC has a bit strange way to invert a matrix.
                                // It solves the system AA^{-1} = Id.
                                // It seems that this way is the only way to do
                                // properly with the solve_algo::gauss flag.
                                //
                                GiNaC::matrix b; GiNaC::matrix A;
                                matrix_from_equations(equations, variables, A, b);

                                unsigned int ncols = A.cols();
                                GiNaC::matrix vars_sq(ncols, ncols);

                                // matrix of symbols
                                for (unsigned r=0; r<ncols; ++r)
                                        for (unsigned c=0; c<ncols; ++c)
                                                vars_sq(r, c) = GiNaC::symbol();

                                GiNaC::matrix id(ncols, ncols);

                                // identity
                                const GiNaC::ex _ex1(1);
                                for (unsigned i=0; i<ncols; ++i)
                                        id(i, i) = _ex1;

                                // invert the matrix
                                GiNaC::matrix m_inv(ncols, ncols);
                                m_inv = A.solve(vars_sq, id, GiNaC::solve_algo::gauss);

                                for (unsigned int i=0; i<dofs.size(); i++)
                                {
                                        b.let_op(removed_dofs + i) = GiNaC::numeric(1);
                                        GiNaC::ex xx = m_inv.mul(GiNaC::ex_to<GiNaC::matrix>(b));

                                        GiNaC::lst subs;
                                        for (unsigned int ii=0; ii<xx.nops(); ii++)
                                        {
                                                subs.append(variables.op(ii) == xx.op(ii));
                                        }
                                        GiNaC::ex Nj1 = pspace.op(0).subs(subs);
                                        GiNaC::ex Nj2 = pspace.op(1).subs(subs);
                                        GiNaC::ex Nj3 = pspace.op(2).subs(subs);
                                        Ns.insert(Ns.end(), GiNaC::matrix(3,1,GiNaC::lst(Nj1,Nj2,Nj3)));
                                        b.let_op(removed_dofs + i) = GiNaC::numeric(0);
                                }
                        }
                }
        }

Member Data Documentation

Definition at line 30 of file RaviartThomas.h.

Referenced by compute_basis_functions().

Definition at line 29 of file RaviartThomas.h.

Referenced by compute_basis_functions(), and RaviartThomas().


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator