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