00001 #include <LagrangeFE.h>
00002 #include <ElementComputations.h>
00003
00004 int LagrangeFE:: nbf() {
00005 return StandardFE::nbf();
00006 }
00007
00008 void LagrangeFE:: compute_basis_functions() {
00009
00010
00011
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
00020 GiNaC::ex polynom;
00021 GiNaC::lst variables;
00022
00023
00024
00025
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
00051 GiNaC::ex polynom;
00052 GiNaC::lst variables;
00053
00054
00055
00056
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));
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
00085 GiNaC::ex polynom;
00086 GiNaC::lst variables;
00087
00088 GiNaC::ex polynom_space = pol(order, 2, "a");
00089
00090
00091
00092
00093
00094
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
00104 GiNaC::lst points = bezier_ordinates(t,order);
00105
00106
00107
00108
00109
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
00115 GiNaC::ex point = points.op(i-1);
00116
00117 GiNaC::ex eq = polynom == dirac(i,j);
00118
00119 equations.append(eq.subs(GiNaC::lst(x == point.op(0) , y == point.op(1))));
00120
00121 if ( j == 1) dofs.insert(dofs.end(), GiNaC::lst(point.op(0),point.op(1)));
00122 }
00123
00124
00125
00126
00127 GiNaC::ex subs = lsolve(equations, variables);
00128
00129 Nj = polynom.subs(subs);
00130
00131 Ns.insert(Ns.end(), Nj);
00132
00133
00134
00135
00136
00137 }
00138
00139 } else if ( p->str() == "ReferenceTetrahedron" ) {
00140
00141 GiNaC::ex polynom;
00142 GiNaC::lst variables;
00143
00144
00145 GiNaC::ex polynom_space = pol(order, 3, "a");
00146
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
00180 GiNaC::ex polynom;
00181 GiNaC::lst variables;
00182
00183
00184 GiNaC::ex polynom_space = pol(order, 3, "a");
00185
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)));
00204 }
00205
00206 GiNaC::ex subs = lsolve(equations, variables);
00207 Nj = polynom.subs(subs);
00208 Ns.insert(Ns.end(), Nj);
00209 }
00210 }
00211 }
00212
00213
00214
00215 void LagrangeFE:: set(Polygon& p_) {
00216 StandardFE::set(p_);
00217 }
00218
00219
00220 void LagrangeFE:: set(int order_) {
00221 StandardFE::set(order_);
00222 }
00223
00224
00225 GiNaC::ex LagrangeFE:: dof(int i) {
00226 return StandardFE::dof(i);
00227 }
00228
00229
00230 GiNaC::ex LagrangeFE::N(int i) {
00231 return StandardFE::N(i);
00232 }
00233
00234
00235
00236 int VectorLagrangeFE:: nbf() {
00237 return StandardFE::nbf();
00238 }
00239
00240 void VectorLagrangeFE:: compute_basis_functions() {
00241 LagrangeFE fe;
00242 fe.set(order);
00243 fe.set(*p);
00244 fe.compute_basis_functions();
00245 GiNaC::lst zero_list;
00246 for (int s=1; s<= size ; s++) {
00247 zero_list.append(0);
00248 }
00249
00250 for (int i=1; i<= fe.nbf() ; i++) {
00251 for (int s=1; s<= size ; s++) {
00252 GiNaC::lst Nis = zero_list;
00253 Nis.let_op(s-1) = fe.N(i);
00254 GiNaC::ex Nmat = GiNaC::matrix(size,1,Nis);
00255 Ns.insert(Ns.end(), Nmat);
00256
00257 GiNaC::lst dof = GiNaC::lst(fe.dof(i), s) ;
00258 dofs.insert(dofs.end(), dof);
00259 }
00260 }
00261 }
00262
00263
00264 void VectorLagrangeFE:: set_size(int size_) {
00265 size = size_;
00266 }
00267
00268
00269 void VectorLagrangeFE:: set(Polygon& p_) {
00270 StandardFE::set(p_);
00271 }
00272
00273
00274 void VectorLagrangeFE:: set(int order_) {
00275 StandardFE::set(order_);
00276 }
00277
00278
00279 GiNaC::ex VectorLagrangeFE:: dof(int i) {
00280 return StandardFE::dof(i);
00281 }
00282
00283
00284 GiNaC::ex VectorLagrangeFE::N(int i) {
00285 return StandardFE::N(i);
00286 }
00287
00288
00289
00290
00291