#include <LagrangeFE.h>
Inheritance diagram for LagrangeFE:
Public Member Functions | |
LagrangeFE () | |
~LagrangeFE () | |
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) |
Definition at line 6 of file LagrangeFE.h.
|
Definition at line 8 of file LagrangeFE.h.
|
|
Definition at line 9 of file LagrangeFE.h.
|
|
Reimplemented from StandardFE. Reimplemented in DiscontinuousLagrangeFE. Definition at line 8 of file LagrangeFE.cpp. References bezier_ordinates(), dirac(), StandardFE::dofs, StandardFE::Ns, StandardFE::order, StandardFE::p, pol(), Polygon::str(), x, y, and z. Referenced by VectorLagrangeFE::compute_basis_functions(), DiscontinuousLagrangeFE::compute_basis_functions(), main(), poisson(), and poisson_reference(). 00008 { 00009 00010 // FIXME: in the below code dof(i) is not used to 00011 // determine the basis functions 00012 00013 if ( order < 1 ) { 00014 cout <<"Lagrangian elements must be of order 1 or higher."<<endl; 00015 return; 00016 } 00017 00018 if (p->str() == "ReferenceLine") { 00019 // Look at the case with the Triangle for a documented code 00020 GiNaC::ex polynom; 00021 GiNaC::lst variables; 00022 00023 // polynom = pol(order, 1, "a"); 00024 // variables = coeffs(polynom); 00025 // GiNaC::ex polynom_space = bernstein(order, *p, "a"); 00026 GiNaC::ex polynom_space = pol(order, 1, "a"); 00027 polynom = polynom_space.op(0); 00028 variables = GiNaC::ex_to<GiNaC::lst>(polynom_space.op(1)); 00029 00030 GiNaC::ex increment = GiNaC::numeric(1,order); 00031 00032 GiNaC::ex Nj; 00033 for (int j=1; j <= order+1; j++) { 00034 GiNaC::lst equations; 00035 int i=0; 00036 for (GiNaC::ex p=0; p<= 1 ; p += increment ) { 00037 i++; 00038 GiNaC::ex eq = polynom == dirac(i,j); 00039 equations.append(eq.subs(x == p)); 00040 if (j == 1) dofs.insert(dofs.end(), p); 00041 } 00042 00043 GiNaC::ex subs = lsolve(equations, variables); 00044 Nj = polynom.subs(subs); 00045 Ns.insert(Ns.end(), Nj); 00046 } 00047 00048 00049 } else if (p->str() == "ReferenceTriangle" ) { 00050 // Look at the case with the Triangle for a documented code 00051 GiNaC::ex polynom; 00052 GiNaC::lst variables; 00053 00054 // polynom = pol(order, 2, "b"); 00055 // variables = coeffs(polynom); 00056 // GiNaC::ex polynom_space = bernstein(order, *p, "b"); 00057 GiNaC::ex polynom_space = pol(order, 2, "a"); 00058 polynom = polynom_space.op(0); 00059 variables = GiNaC::ex_to<GiNaC::lst>(polynom_space.op(1)); 00060 00061 GiNaC::ex increment = GiNaC::numeric(1,order); 00062 00063 GiNaC::ex Nj; 00064 for (int j=1; j <= (order+1)*(order+2)/2; j++) { 00065 GiNaC::lst equations; 00066 int i=0; 00067 GiNaC::numeric one = 1; 00068 for (GiNaC::ex p=0; p<= one ; p += increment ) { 00069 for (GiNaC::ex q=0; q<= one-p ; q += increment ) { 00070 i++; 00071 GiNaC::ex eq = polynom == dirac(i,j); 00072 equations.append(eq.subs(GiNaC::lst(x == p, y == q))); 00073 if ( j == 1) dofs.insert(dofs.end(), GiNaC::lst(p,q)); //FIXME akward way to do it 00074 } 00075 } 00076 00077 00078 GiNaC::ex subs = lsolve(equations, variables); 00079 Nj = polynom.subs(subs); 00080 Ns.insert(Ns.end(), Nj); 00081 } 00082 } 00083 else if ( p->str() == "Triangle" ){ 00084 // Look HERE for the documented code 00085 GiNaC::ex polynom; 00086 GiNaC::lst variables; 00087 00088 GiNaC::ex polynom_space = pol(order, 2, "a"); 00089 // the polynomial spaces on the form: 00090 // first item: a0 + a1*x + a2*y + a3*x^2 + a4*x*y ... the polynom 00091 // second item: a0, a1, a2, ... the coefficents 00092 // third item 1, x, y, x^2, .. the basis 00093 // Could also do: 00094 // GiNaC::ex polynom_space = bernstein(order, t, "a"); 00095 00096 00097 polynom = polynom_space.op(0); 00098 variables = GiNaC::ex_to<GiNaC::lst>(polynom_space.op(1)); 00099 00100 GiNaC::ex Nj; 00101 Polygon& pp = *p; 00102 Triangle& t = (Triangle&) pp; 00103 // The bezier ordinates (in which the basis function should be either 0 or 1) 00104 GiNaC::lst points = bezier_ordinates(t,order); 00105 00106 // Loop over all basis functions Nj and all points. 00107 // Each basis function Nj is determined by a set of linear equations: 00108 // Nj(xi) = dirac(i,j) 00109 // This system of equations is then solved by lsolve 00110 for (int j=1; j <= points.nops(); j++) { 00111 GiNaC::lst equations; 00112 int i=0; 00113 for (int i=1; i<= points.nops() ; i++ ) { 00114 // The point xi 00115 GiNaC::ex point = points.op(i-1); 00116 // The equation Nj(xi) = dirac(i,j) 00117 GiNaC::ex eq = polynom == dirac(i,j); 00118 // The equation is appended to the list of equations 00119 equations.append(eq.subs(GiNaC::lst(x == point.op(0) , y == point.op(1)))); 00120 // Creation of dof(j) 00121 if ( j == 1) dofs.insert(dofs.end(), GiNaC::lst(point.op(0),point.op(1))); //FIXME akward way to do it 00122 } 00123 00124 // print(equations); 00125 // print(variables); 00126 // We solve the linear system 00127 GiNaC::ex subs = lsolve(equations, variables); 00128 // Substitute to get the Nj 00129 Nj = polynom.subs(subs); 00130 // Append Nj to the list of basis functions 00131 Ns.insert(Ns.end(), Nj); 00132 00133 // FIXME: In this case we create a linear system and solve it for each Nj. 00134 // However, the matrix is always the same, it is only the right-hand side 00135 // that changes. Hence, it is possible to optimize here. 00136 00137 } 00138 00139 } else if ( p->str() == "ReferenceTetrahedron" ) { 00140 // Look at the case with the Triangle for a documented code 00141 GiNaC::ex polynom; 00142 GiNaC::lst variables; 00143 00144 // polynom = pol(order, 3, "b"); 00145 GiNaC::ex polynom_space = pol(order, 3, "a"); 00146 // GiNaC::ex polynom_space = bernstein(order, *p, "b"); 00147 polynom = polynom_space.op(0); 00148 variables = GiNaC::ex_to<GiNaC::lst>(polynom_space.op(1)); 00149 00150 00151 int nno =0; 00152 for (int j=0; j<= order; j++) { 00153 nno += (j+1)*(j+2)/2; 00154 } 00155 00156 GiNaC::ex increment = GiNaC::numeric(1,order); 00157 00158 GiNaC::ex Nj; 00159 for (int j=1; j <= nno; j++) { 00160 GiNaC::lst equations; 00161 int i=0; 00162 for (GiNaC::ex p=0; p<= 1 ; p += increment ) { 00163 for (GiNaC::ex q=0; q<= 1-p ; q += increment ) { 00164 for (GiNaC::ex r=0; r<= 1-p-q ; r += increment ) { 00165 i++; 00166 GiNaC::ex eq = polynom == dirac(i,j); 00167 equations.append(eq.subs(GiNaC::lst(x == p, y == q, z == r ))); 00168 if (j == 1) dofs.insert(dofs.end(), GiNaC::lst(p,q,r)); 00169 } 00170 } 00171 } 00172 00173 GiNaC::ex subs = lsolve(equations, variables); 00174 Nj = polynom.subs(subs); 00175 Ns.insert(Ns.end(), Nj); 00176 } 00177 } 00178 else if ( p->str() == "Tetrahedron" ){ 00179 // Look at the case with the Triangle for a documented code 00180 GiNaC::ex polynom; 00181 GiNaC::lst variables; 00182 00183 00184 GiNaC::ex polynom_space = pol(order, 3, "a"); 00185 // GiNaC::ex polynom_space = bernstein(order, *p, "b"); 00186 polynom = polynom_space.op(0); 00187 variables = GiNaC::ex_to<GiNaC::lst>(polynom_space.op(1)); 00188 00189 00190 GiNaC::ex increment = GiNaC::numeric(1,order); 00191 00192 GiNaC::ex Nj; 00193 Polygon& pp = *p; 00194 Tetrahedron& t = (Tetrahedron&) pp; 00195 GiNaC::lst points = bezier_ordinates(t,order); 00196 for (int j=1; j <= points.nops(); j++) { 00197 GiNaC::lst equations; 00198 int i=0; 00199 for (int i=1; i<= points.nops() ; i++ ) { 00200 GiNaC::ex point = points.op(i-1); 00201 GiNaC::ex eq = polynom == dirac(i,j); 00202 equations.append(eq.subs(GiNaC::lst(x == point.op(0) , y == point.op(1), z == point.op(2)))); 00203 if ( j == 1) dofs.insert(dofs.end(), GiNaC::lst(point.op(0),point.op(1),point.op(2))); //FIXME akward way to do it 00204 } 00205 00206 GiNaC::ex subs = lsolve(equations, variables); 00207 Nj = polynom.subs(subs); 00208 Ns.insert(Ns.end(), Nj); 00209 } 00210 } 00211 }
|
|
Reimplemented from StandardFE. Reimplemented in DiscontinuousLagrangeFE. Definition at line 225 of file LagrangeFE.cpp. References StandardFE::dof(). Referenced by VectorLagrangeFE::compute_basis_functions(), main(), poisson(), and poisson_reference(). 00225 { 00226 return StandardFE::dof(i); 00227 }
|
|
Reimplemented from StandardFE. Reimplemented in DiscontinuousLagrangeFE. Definition at line 230 of file LagrangeFE.cpp. References StandardFE::N(). Referenced by VectorLagrangeFE::compute_basis_functions(), main(), poisson(), and poisson_reference(). 00230 { 00231 return StandardFE::N(i); 00232 }
|
|
Reimplemented from StandardFE. Reimplemented in DiscontinuousLagrangeFE. Definition at line 4 of file LagrangeFE.cpp. References StandardFE::nbf(). Referenced by VectorLagrangeFE::compute_basis_functions(), main(), poisson(), and poisson_reference(). 00004 { 00005 return StandardFE::nbf(); 00006 }
|
|
Reimplemented from StandardFE. Reimplemented in DiscontinuousLagrangeFE. Definition at line 215 of file LagrangeFE.cpp. References StandardFE::set(). 00215 { 00216 StandardFE::set(p_); 00217 }
|
|
Reimplemented from StandardFE. Reimplemented in DiscontinuousLagrangeFE. Definition at line 220 of file LagrangeFE.cpp. References StandardFE::set(). Referenced by VectorLagrangeFE::compute_basis_functions(), main(), poisson(), and poisson_reference(). 00220 { 00221 StandardFE::set(order_); 00222 }
|