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

# Polygon.h File Reference

`#include <tools.h>`

Go to the source code of this file.

## Classes
class | Polygon
class | Line
class | ReferenceLine
class | Triangle
class | ReferenceTriangle
class | Rectangle
class | ReferenceRectangle
class | Tetrahedron
class | ReferenceTetrahedron
class | Box
class | ReferenceBox
## Enumerations
enum | Repr_format { SUBS_PERFORMED = 1, SUBS_NOT_PERFORMED = 2 }
## Functions
GiNaC::ex | barycenter_line (GiNaC::ex p0, GiNaC::ex p1)
GiNaC::ex | barycenter_triangle (GiNaC::ex p0, GiNaC::ex p1, GiNaC::ex p2)
GiNaC::ex | barycenter_tetrahedron (GiNaC::ex p0, GiNaC::ex p1, GiNaC::ex p2, GiNaC::ex p3)
GiNaC::lst | bezier_ordinates (Triangle &triangle, int d)
GiNaC::lst | bezier_ordinates (Tetrahedron &tetrahedra, int d)
GiNaC::ex | bernstein (int order, Polygon &p, const string a)
GiNaC::lst | bernsteinv (int no_fields, int order, Polygon &p, const string a)
GiNaC::lst | normal (Triangle &, int i)
GiNaC::lst | normal (Tetrahedron &, int i)
GiNaC::lst | tangent (Triangle &, int i)

## Enumeration Type Documentation

enum Repr_format

  | Enumerator:
  SUBS_PERFORMED |
  SUBS_NOT_PERFORMED |
Definition at line 15 of file Polygon.h.
    00015                   {
    00016   SUBS_PERFORMED = 1,
    00017   SUBS_NOT_PERFORMED = 2
    00018 };

## Function Documentation

GiNaC::ex barycenter_line | ( | GiNaC::ex | p0,
|  | GiNaC::ex | p1
| ) |

| Definition at line 975 of file Polygon.cpp. References DUMMY, x, y, and z. Referenced by bernstein().
    00975                                                 {
    00976  GiNaC::ex sol = DUMMY;
    00977
    00978  // 1D
    00979  if ( p0.nops() == 1 && p1.nops() == 1 ) {
    00980    GiNaC::symbol b0("b0"), b1("b1");
    00981    GiNaC::ex eq1 = x == b0*p0.op(0) + b1*p1.op(0);
    00982    GiNaC::ex eq2 = 1 == b0 + b1;
    00983    sol = lsolve(GiNaC::lst(eq1, eq2), GiNaC::lst(b0, b1));
    00984    if ( sol == 0 ) {
    00985      GiNaC::ex eq1 = y == b0*p0.op(1) + b1*p1.op(1);
    00986      sol = lsolve(GiNaC::lst(eq1, eq2), GiNaC::lst(b0, b1));
    00987    }
    00988    if ( sol == 0 ) {
    00989      GiNaC::ex eq1 = z == b0*p0.op(2) + b1*p1.op(2);
    00990      sol = lsolve(GiNaC::lst(eq1, eq2), GiNaC::lst(b0, b1));
    00991    }
    00992  }
    00993  //2D
    00994  else if ( p0.nops() == 2 && p1.nops() == 2 ) {
    00995    GiNaC::symbol b0("b0"), b1("b1");
    00996    GiNaC::ex eq1 = x == b0*p0.op(0) + b1*p1.op(0);
    00997    GiNaC::ex eq3 = 1 == b0 + b1;
    00998    sol = lsolve(GiNaC::lst(eq1, eq3), GiNaC::lst(b0, b1));
    00999    if (sol.nops() == 0) {
    01000      GiNaC::ex eq2 = y == b0*p0.op(1) + b1*p1.op(1);
    01001      sol = lsolve(GiNaC::lst(eq2, eq3), GiNaC::lst(b0, b1));
    01002    }
    01003  }
    01004  //3D
    01005  else if ( p0.nops() == 3 && p1.nops() == 3 ) {
    01006    GiNaC::symbol b0("b0"), b1("b1");
    01007    GiNaC::ex eq1 = x == b0*p0.op(0) + b1*p1.op(0);
    01008    GiNaC::ex eq4 = 1 == b0 + b1;
    01009    sol = lsolve(GiNaC::lst(eq1, eq4), GiNaC::lst(b0, b1));
    01010    if (sol.nops() == 0) {
    01011      GiNaC::ex eq2 = y == b0*p0.op(1) + b1*p1.op(1);
    01012      sol = lsolve(GiNaC::lst(eq2, eq4), GiNaC::lst(b0, b1));
    01013    }
    01014    if (sol.nops() == 0) {
    01015      GiNaC::ex eq3 = z == b0*p0.op(2) + b1*p1.op(2);
    01016      sol = lsolve(GiNaC::lst(eq3, eq4), GiNaC::lst(b0, b1));
    01017    }
    01018  }
    01019  else {
    01020    cout <<"Could not compute the barycentric coordinates."<<endl;
    01021    cout <<"Check the coordinates."<<endl;
    01022  }
    01023  return sol;
    01024 }

GiNaC::ex barycenter_tetrahedron | ( | GiNaC::ex | p0,
|  | GiNaC::ex | p1,
|  | GiNaC::ex | p2,
|  | GiNaC::ex | p3
| ) |

| Definition at line 1063 of file Polygon.cpp. References x, y, and z. Referenced by bernstein(), and Bubble::compute_basis_functions().
    01063                                                                                {
    01064  GiNaC::symbol b0("b0"), b1("b1"), b2("b2"), b3("b3");
    01065
    01066  // 3D
    01067  GiNaC::ex eq1 = x == b0*p0.op(0) + b1*p1.op(0) + b2*p2.op(0) + b3*p3.op(0);
    01068  GiNaC::ex eq2 = y == b0*p0.op(1) + b1*p1.op(1) + b2*p2.op(1) + b3*p3.op(1);
    01069  GiNaC::ex eq3 = z == b0*p0.op(2) + b1*p1.op(2) + b2*p2.op(2) + b3*p3.op(2);
    01070  GiNaC::ex eq4 = 1 == b0 + b1 + b2 +b3;
    01071
    01072  GiNaC::ex sol = lsolve(GiNaC::lst(eq1, eq2, eq3, eq4), GiNaC::lst(b0, b1, b2, b3));
    01073
    01074  return sol;
    01075
    01076 }

GiNaC::ex barycenter_triangle | ( | GiNaC::ex | p0,
|  | GiNaC::ex | p1,
|  | GiNaC::ex | p2
| ) |

| Definition at line 1028 of file Polygon.cpp. References DUMMY, x, y, and z. Referenced by bernstein(), and Bubble::compute_basis_functions().
    01028                                                                 {
    01029  GiNaC::ex sol;
    01030  sol = DUMMY;
    01031
    01032  // 2D
    01033  if ( p0.nops() == 2 && p1.nops() == 2 && p2.nops() == 2) {
    01034    GiNaC::symbol b0("b0"), b1("b1"), b2("b2");
    01035    GiNaC::ex eq1 = x == b0*p0.op(0) + b1*p1.op(0) + b2*p2.op(0);
    01036    GiNaC::ex eq2 = y == b0*p0.op(1) + b1*p1.op(1) + b2*p2.op(1);
    01037    GiNaC::ex eq3 = 1 == b0 + b1 + b2;
    01038
    01039    sol = lsolve(GiNaC::lst(eq1, eq2, eq3), GiNaC::lst(b0, b1, b2));
    01040  }
    01041  // 3D
    01042  else if ( p0.nops() == 3 && p1.nops() == 3 && p2.nops() == 3) {
    01043    GiNaC::symbol b0("b0"), b1("b1"), b2("b2");
    01044    GiNaC::ex eq1 = x == b0*p0.op(0) + b1*p1.op(0) + b2*p2.op(0);
    01045    GiNaC::ex eq2 = y == b0*p0.op(1) + b1*p1.op(1) + b2*p2.op(1);
    01046    GiNaC::ex eq3 = z == b0*p0.op(2) + b1*p1.op(2) + b2*p2.op(2);
    01047    GiNaC::ex eq4 = 1 == b0 + b1 + b2;
    01048
    01049    sol = lsolve(GiNaC::lst(eq1, eq2, eq4), GiNaC::lst(b0, b1, b2));
    01050    if ( sol.nops() == 0 ) {
    01051      sol = lsolve(GiNaC::lst(eq1, eq3, eq4), GiNaC::lst(b0, b1, b2));
    01052    }
    01053    if ( sol.nops() == 0 ) {
    01054      sol = lsolve(GiNaC::lst(eq2, eq3, eq4), GiNaC::lst(b0, b1, b2));
    01055    }
    01056  }
    01057
    01058
    01059
    01060  return sol;
    01061 }

GiNaC::ex bernstein | ( | int | order,
|  | Polygon & | p,
|  | const string | a
| ) |

| Definition at line 1078 of file Polygon.cpp. References barycenter_line(), barycenter_tetrahedron(), barycenter_triangle(), DUMMY, matrix_to_lst2(), Polygon::str(), and Polygon::vertex(). Referenced by bernsteinv(), CrouzeixRaviart::compute_basis_functions(), LagrangeFE::compute_basis_functions(), Nedelec::compute_basis_functions(), RaviartThomas::compute_basis_functions(), and main().
    01078                                                          {
    01079
    01080   if ( order < 0 ) {
    01081     cout <<"Can not create polynomials of order less than 0!"<<endl;
    01082     return DUMMY;
    01083   }
    01084
    01085   GiNaC::ex ret; // GiNaC::ex to return
    01086   int dof;       // degrees of freedom
    01087   GiNaC::ex A;   // GiNaC::ex holding the coefficients a_0 .. a_dof
    01088   GiNaC::lst basis;
    01089
    01090   if ( p.str() == "Line" || p.str() == "ReferenceLine" ) {
    01091     GiNaC::ex bary = barycenter_line(p.vertex(0), p.vertex(1));
    01092     GiNaC::ex b0= bary.op(0).rhs();
    01093     GiNaC::ex b1= bary.op(1).rhs();
    01094     dof = order+1;
    01095     A = GiNaC::symbolic_matrix(1,dof, a);
    01096     int o=0;
    01097     for (GiNaC::const_iterator i = A.begin(); i != A.end(); ++i)  {
    01098       ret += (*i)*GiNaC::binomial(order,o)*pow(b0,o)*pow(b1,order-o);
    01099       basis.append(pow(b0,o)*pow(b1,order-o));
    01100       o++;
    01101     }
    01102   }
    01103   else if ( p.str() == "Triangle" || p.str() == "ReferenceTriangle" )  {
    01104
    01105     dof = (order+1)*(order+2)/2;
    01106     A = GiNaC::symbolic_matrix(1, dof , a);
    01107
    01108     GiNaC::ex bary = barycenter_triangle(p.vertex(0), p.vertex(1), p.vertex(2));
    01109     GiNaC::ex b0= bary.op(0).rhs();
    01110     GiNaC::ex b1= bary.op(1).rhs();
    01111     GiNaC::ex b2= bary.op(2).rhs();
    01112
    01113     size_t i=0;
    01114     for (int o1 = 0; o1 <= order; o1++) {
    01115       for (int o2 = 0; o2 <= order; o2++) {
    01116         for (int o3 = 0; o3 <= order; o3++) {
    01117           if ( o1 + o2 + o3 == order ) {
    01118             ret += A.op(i)*(GiNaC::factorial(order)/(GiNaC::factorial(o1)*GiNaC::factorial(o2)*GiNaC::factorial(o3)))
    01119                    *pow(b0,o1)*pow(b1,o2)*pow(b2,o3);
    01120
    01121             basis.append(pow(b0,o1)*pow(b1,o2)*pow(b2,o3));
    01122             i++;
    01123           }
    01124         }
    01125       }
    01126     }
    01127   }
    01128   else if (p.str() == "Tetrahedron" || p.str() == "ReferenceTetrahedron") {
    01129
    01130
    01131     dof = 0;
    01132     for (int j=0; j<= order; j++) {
    01133       dof += (j+1)*(j+2)/2;
    01134     }
    01135     A = GiNaC::symbolic_matrix(1, dof , a);
    01136
    01137
    01138     GiNaC::ex bary = barycenter_tetrahedron(p.vertex(0), p.vertex(1), p.vertex(2), p.vertex(3));
    01139     GiNaC::ex b0= bary.op(0).rhs();
    01140     GiNaC::ex b1= bary.op(1).rhs();
    01141     GiNaC::ex b2= bary.op(2).rhs();
    01142     GiNaC::ex b3= bary.op(3).rhs();
    01143
    01144
    01145     size_t i=0;
    01146     for (int o1 = 0; o1 <= order; o1++) {
    01147       for (int o2 = 0; o2 <= order; o2++) {
    01148         for (int o3 = 0; o3 <= order; o3++) {
    01149           for (int o4 = 0; o4 <= order; o4++) {
    01150             if ( o1 + o2 + o3 + o4 == order ) {
    01151               ret += A.op(i)*(GiNaC::factorial(order)/(GiNaC::factorial(o1)*GiNaC::factorial(o2)*GiNaC::factorial(o3)*GiNaC::factorial(o4)))
    01152                    *pow(b0,o1)*pow(b1,o2)*pow(b2,o3)*pow(b3,o4);
    01153               basis.append(pow(b0,o1)*pow(b1,o2)*pow(b2,o3)*pow(b3,o4));
    01154               i++;
    01155             }
    01156           }
    01157         }
    01158       }
    01159     }
    01160   }
    01161   return GiNaC::lst(ret,matrix_to_lst2(A),basis);
    01162 }

GiNaC::lst bernsteinv | ( | int | no_fields,
|  | int | order,
|  | Polygon & | p,
|  | const string | a
| ) |

| Definition at line 1164 of file Polygon.cpp. References bernstein(), DUMMY, pol(), and Polygon::str(). Referenced by Nedelec::compute_basis_functions(), and RaviartThomas::compute_basis_functions().
    01164                                                                           {
    01165
    01166   if ( order < 0 ) {
    01167     cout <<"Can not create polynomials of order less than 0!"<<endl;
    01168     return GiNaC::lst(DUMMY);
    01169   }
    01170
    01171   GiNaC::lst ret1;  // contains the polynom
    01172   GiNaC::lst ret2;  // contains the coefficients
    01173   GiNaC::lst ret3;  // constains the basis functions
    01174   GiNaC::lst basis_tmp;
    01175   for (int i=1; i<= no_fields; i++) {
    01176     GiNaC::lst basis;
    01177     std::ostringstream s;
    01178     s <<a<<""<<i<<"_";
    01179     GiNaC::ex pol = bernstein(order, p, s.str());
    01180     ret1.append(pol.op(0));
    01181     ret2.append(pol.op(1));
    01182     basis_tmp = GiNaC::ex_to<GiNaC::lst>(pol.op(2));
    01183     for (GiNaC::lst::const_iterator basis_iterator = basis_tmp.begin();
    01184          basis_iterator != basis_tmp.end(); ++basis_iterator) {
    01185       GiNaC::lst tmp_lst;
    01186       for (int d=1; d<=no_fields; d++) tmp_lst.append(0);
    01187       tmp_lst.let_op(i-1) = (*basis_iterator);
    01188       ret3.append(tmp_lst);
    01189     }
    01190   }
    01191   return GiNaC::lst(ret1,ret2,ret3);
    01192
    01193 }

GiNaC::lst bezier_ordinates | ( | Tetrahedron & | tetrahedra,
|  | int | d
| ) |

| Definition at line 899 of file Polygon.cpp. References lst_to_matrix2(), matrix_to_lst2(), and Tetrahedron::vertex().
    00899                                                           {
    00900
    00901   //FIXME: ugly conversion to matrix
    00902
    00903   GiNaC::lst ret;
    00904   GiNaC::ex V1 = tetrahedra.vertex(0);
    00905   GiNaC::ex V2 = tetrahedra.vertex(1);
    00906   GiNaC::ex V3 = tetrahedra.vertex(2);
    00907   GiNaC::ex V4 = tetrahedra.vertex(3);
    00908
    00909   GiNaC::lst V1l = GiNaC::ex_to<GiNaC::lst>(V1);
    00910   GiNaC::lst V2l = GiNaC::ex_to<GiNaC::lst>(V2);
    00911   GiNaC::lst V3l = GiNaC::ex_to<GiNaC::lst>(V3);
    00912   GiNaC::lst V4l = GiNaC::ex_to<GiNaC::lst>(V4);
    00913
    00914
    00915   GiNaC::ex V1m  = lst_to_matrix2(V1l);
    00916   GiNaC::ex V2m  = lst_to_matrix2(V2l);
    00917   GiNaC::ex V3m  = lst_to_matrix2(V3l);
    00918   GiNaC::ex V4m  = lst_to_matrix2(V4l);
    00919
    00920   int l;
    00921   for (int i=0; i<= d; i++) {
    00922     for (int j=0; j<= d; j++) {
    00923       for (int k=0; k<= d; k++) {
    00924         if ( d - i - j -k  >= 0 ) {
    00925           l= d - i - j -k;
    00926           GiNaC::ex sum = (l*V1m + k*V2m + j*V3m + i*V4m)/d;
    00927           ret.append(matrix_to_lst2(sum.evalm()));
    00928         }
    00929       }
    00930     }
    00931   }
    00932   // FIXME how should these be sorted ?????
    00933 //  ret = ret.sort();
    00934   return ret;
    00935 }

GiNaC::lst bezier_ordinates | ( | Triangle & | triangle,
|  | int | d
| ) |

| Definition at line 939 of file Polygon.cpp. References lst_to_matrix2(), matrix_to_lst2(), and Triangle::vertex().
    00939                                                      {
    00940
    00941   //FIXME: ugly conversion to matrix
    00942
    00943   GiNaC::lst ret;
    00944   GiNaC::ex V1 = triangle.vertex(0);
    00945   GiNaC::ex V2 = triangle.vertex(1);
    00946   GiNaC::ex V3 = triangle.vertex(2);
    00947
    00948   GiNaC::lst V1l = GiNaC::ex_to<GiNaC::lst>(V1);
    00949   GiNaC::lst V2l = GiNaC::ex_to<GiNaC::lst>(V2);
    00950   GiNaC::lst V3l = GiNaC::ex_to<GiNaC::lst>(V3);
    00951
    00952   GiNaC::ex V1m  = lst_to_matrix2(V1l);
    00953   GiNaC::ex V2m  = lst_to_matrix2(V2l);
    00954   GiNaC::ex V3m  = lst_to_matrix2(V3l);
    00955
    00956
    00957   int k;
    00958   for (int i=0; i <= d; i++) {
    00959     for (int j=0; j <= d; j++) {
    00960       if ( d - i - j >= 0  ) {
    00961         k = d - i - j;
    00962         GiNaC::ex sum = (k*V1m + j*V2m + i*V3m)/d;
    00963         ret.append(matrix_to_lst2(sum.evalm()));
    00964       }
    00965     }
    00966   }
    00967   // FIXME how should these be sorted ?????
    00968   // ret = ret.sort();
    00969   return ret;
    00970 }

GiNaC::lst normal | ( | Tetrahedron & | ,
|  | int | i
| ) |

| Definition at line 1195 of file Polygon.cpp. References cross(), Triangle::line(), Line::repr(), and Tetrahedron::triangle().
    01195                                                 {
    01196   Triangle triangle = tetrahedron.triangle(i);
    01197
    01198   GiNaC::symbol t("t");
    01199   GiNaC::ex line1_repr = triangle.line(1).repr(t);
    01200   GiNaC::ex n11 = line1_repr.op(0).rhs().coeff(t,1);
    01201   GiNaC::ex n12 = line1_repr.op(1).rhs().coeff(t,1);
    01202   GiNaC::ex n13 = line1_repr.op(2).rhs().coeff(t,1);
    01203
    01204   GiNaC::ex line2_repr = triangle.line(2).repr(t);
    01205   GiNaC::ex n21 = line2_repr.op(0).rhs().coeff(t,1);
    01206   GiNaC::ex n22 = line2_repr.op(1).rhs().coeff(t,1);
    01207   GiNaC::ex n23 = line2_repr.op(2).rhs().coeff(t,1);
    01208
    01209   GiNaC::lst n1 = GiNaC::lst(n11,n12,n13);
    01210   GiNaC::lst n2 = GiNaC::lst(n21,n22,n23);
    01211   GiNaC::lst n3 = cross(n1,n2);
    01212
    01213   GiNaC::ex norm = sqrt(pow(n3.op(0),2)
    01214                       + pow(n3.op(1),2)
    01215                       + pow(n3.op(2),2));
    01216
    01217   n3.let_op(0) = n3.op(0)/norm;
    01218   n3.let_op(1) = n3.op(1)/norm;
    01219   n3.let_op(2) = n3.op(2)/norm;
    01220
    01221   return n3;
    01222 }

GiNaC::lst normal | ( | Triangle & | ,
|  | int | i
| ) |

| Definition at line 1225 of file Polygon.cpp. References Triangle::line(), normal(), and Line::repr().
    01225                                           {
    01226   Line line = triangle.line(i);
    01227   //FIXME: 5 lines to compute the normal vector, these should
    01228   // be put somewhere else.
    01229   GiNaC::symbol t("t");
    01230   GiNaC::ex line_repr = line.repr(t);
    01231   GiNaC::ex n1 = line_repr.op(0).rhs().coeff(t,1);
    01232   GiNaC::ex n2 = line_repr.op(1).rhs().coeff(t,1);
    01233   GiNaC::ex norm = sqrt(pow(n1,2) + pow(n2,2));
    01234   GiNaC::lst normal = GiNaC::lst(n2/norm,-n1/norm);
    01235 return normal;
    01236 }

GiNaC::lst tangent | ( | Triangle & | ,
|  | int | i
| ) |

| Definition at line 1238 of file Polygon.cpp. References Triangle::line(), Line::repr(), and tangent(). Referenced by Nedelec::compute_basis_functions(), and tangent().
    01238                                            {
    01239   Line line = triangle.line(i);
    01240   //FIXME: 5 lines to compute the tangent vector, these should
    01241   // be put somewhere else.
    01242   GiNaC::symbol t("t");
    01243   GiNaC::ex line_repr = line.repr(t);
    01244   GiNaC::ex t1 = line_repr.op(0).rhs().coeff(t,1);
    01245   GiNaC::ex t2 = line_repr.op(1).rhs().coeff(t,1);
    01246   GiNaC::ex norm = sqrt(pow(t1,2) + pow(t2,2));
    01247   GiNaC::lst tangent = GiNaC::lst(t1/norm,t2/norm);
    01248 return tangent;
    01249 }