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 == 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
00026 GiNaC::ex polynom;
00027 GiNaC::lst variables;
00028
00029
00030
00031 GiNaC::ex polynom_space = bernstein(order, *p, "a");
00032
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
00057 GiNaC::ex polynom;
00058 GiNaC::lst variables;
00059
00060
00061
00062 GiNaC::ex polynom_space = bernstein(order, *p, "b");
00063
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
00091 GiNaC::ex polynom;
00092 GiNaC::lst variables;
00093
00094 GiNaC::ex polynom_space = pol(order, 2, "a");
00095
00096
00097
00098
00099
00100
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
00110 GiNaC::lst points = bezier_ordinates(t,order);
00111
00112
00113
00114
00115
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
00121 GiNaC::ex point = points.op(i-1);
00122
00123 GiNaC::ex eq = polynom == dirac(i,j);
00124
00125 equations.append(eq.subs(GiNaC::lst(x == point.op(0) , y == point.op(1))));
00126
00127 if ( j == 1) dofs.insert(dofs.end(), GiNaC::lst(point.op(0),point.op(1)));
00128 }
00129
00130
00131
00132
00133 GiNaC::ex subs = lsolve(equations, variables);
00134
00135 Nj = polynom.subs(subs);
00136
00137 Ns.insert(Ns.end(), Nj);
00138
00139
00140
00141
00142
00143 }
00144
00145 } else if ( p->str() == "ReferenceTetrahedron" ) {
00146
00147 GiNaC::ex polynom;
00148 GiNaC::lst variables;
00149
00150
00151
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
00186 GiNaC::ex polynom;
00187 GiNaC::lst variables;
00188
00189
00190 GiNaC::ex polynom_space = pol(order, 3, "a");
00191
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 }
00218
00219
00220
00221 void LagrangeFE:: set(Polygon& p_) {
00222 StandardFE::set(p_);
00223 }
00224
00225
00226 void LagrangeFE:: set(int order_) {
00227 StandardFE::set(order_);
00228 }
00229
00230
00231 GiNaC::ex LagrangeFE:: dof(int i) {
00232 return StandardFE::dof(i);
00233 }
00234
00235
00236 GiNaC::ex LagrangeFE::N(int i) {
00237 return StandardFE::N(i);
00238 }
00239
00240
00241
00242 int VectorLagrangeFE:: nbf() {
00243 return StandardFE::nbf();
00244 }
00245
00246 void VectorLagrangeFE:: compute_basis_functions() {
00247
00248 if ( order < 1 ) {
00249 cout <<"Lagrangian elements must be of order 1 or higher."<<endl;
00250 return;
00251 }
00252
00253
00254 if ( p == NULL ) {
00255 cout <<"You need to set a polygon before the basisfunctions can be computed"<<endl;
00256 return;
00257 }
00258
00259 LagrangeFE fe;
00260 fe.set(order);
00261 fe.set(*p);
00262 fe.compute_basis_functions();
00263 GiNaC::lst zero_list;
00264 for (int s=1; s<= size ; s++) {
00265 zero_list.append(0);
00266 }
00267
00268 for (int i=0; i< fe.nbf() ; i++) {
00269 for (int s=0; s< size ; s++) {
00270 GiNaC::lst Nis = zero_list;
00271 Nis.let_op(s) = fe.N(i);
00272 GiNaC::ex Nmat = GiNaC::matrix(size,1,Nis);
00273 Ns.insert(Ns.end(), Nmat);
00274
00275 GiNaC::lst dof = GiNaC::lst(fe.dof(i), s) ;
00276 dofs.insert(dofs.end(), dof);
00277 }
00278 }
00279 }
00280
00281
00282 void VectorLagrangeFE:: set_size(int size_) {
00283 size = size_;
00284 }
00285
00286
00287 void VectorLagrangeFE:: set(Polygon& p_) {
00288 StandardFE::set(p_);
00289 }
00290
00291
00292 void VectorLagrangeFE:: set(int order_) {
00293 StandardFE::set(order_);
00294 }
00295
00296
00297 GiNaC::ex VectorLagrangeFE:: dof(int i) {
00298 return StandardFE::dof(i);
00299 }
00300
00301
00302 GiNaC::ex VectorLagrangeFE::N(int i) {
00303 return StandardFE::N(i);
00304 }
00305
00306
00307
00308
00309