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