00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "SundanceLagrange.hpp"
00043 #include "SundanceADReal.hpp"
00044 #include "PlayaExceptions.hpp"
00045 #include "SundanceSpatialDerivSpecifier.hpp"
00046 #include "SundancePoint.hpp"
00047 #include "SundanceObjectWithVerbosity.hpp"
00048 #include "SundanceOut.hpp"
00049
00050 using namespace Sundance;
00051 using namespace Sundance;
00052 using namespace Sundance;
00053 using namespace Teuchos;
00054
00055
00056 Lagrange::Lagrange(int order)
00057 : order_(order) , doFInfromationCalculated_(false)
00058 {
00059 TEUCHOS_TEST_FOR_EXCEPTION(order < 0, std::runtime_error,
00060 "invalid polynomial order=" << order
00061 << " in Lagrange ctor");
00062 }
00063
00064 bool Lagrange::supportsCellTypePair(
00065 const CellType& maximalCellType,
00066 const CellType& cellType
00067 ) const
00068 {
00069 switch(maximalCellType)
00070 {
00071 case LineCell:
00072 switch(cellType)
00073 {
00074 case LineCell:
00075 case PointCell:
00076 return true;
00077 default:
00078 return false;
00079 }
00080 case TriangleCell:
00081 switch(cellType)
00082 {
00083 case TriangleCell:
00084 case LineCell:
00085 case PointCell:
00086 return true;
00087 default:
00088 return false;
00089 }
00090 case QuadCell:
00091 switch(cellType){
00092 case QuadCell:
00093 case LineCell:
00094 case PointCell:
00095 return true;
00096 default:
00097 return false;
00098 }
00099 case TetCell:
00100 switch(cellType)
00101 {
00102 case TetCell:
00103 case TriangleCell:
00104 case LineCell:
00105 case PointCell:
00106 return true;
00107 default:
00108 return false;
00109 }
00110 case BrickCell:
00111 switch(cellType)
00112 {
00113 case BrickCell:
00114 case QuadCell:
00115 case LineCell:
00116 case PointCell:
00117 return true;
00118 default:
00119 return false;
00120 }
00121 default:
00122 return false;
00123 }
00124 }
00125
00126 void Lagrange::print(std::ostream& os) const
00127 {
00128 os << "Lagrange(" << order_ << ")";
00129 }
00130
00131 int Lagrange::nReferenceDOFsWithoutFacets(
00132 const CellType& maximalCellType,
00133 const CellType& cellType
00134 ) const
00135 {
00136 if (order_==0)
00137 {
00138 if (maximalCellType != cellType) return 0;
00139 return 1;
00140 }
00141
00142 switch(cellType)
00143 {
00144 case PointCell:
00145 return 1;
00146 case LineCell:
00147 return order_-1;
00148 case TriangleCell:
00149 if (order_ < 3) return 0;
00150 if (order_ == 3) return 1;
00151 TEUCHOS_TEST_FOR_EXCEPTION(order_>3, std::runtime_error,
00152 "Lagrange order > 3 not implemented "
00153 "for triangle cells");
00154 return 0;
00155 case QuadCell:
00156 if (order_==1) return 0;
00157 if (order_==2) return 1;
00158 TEUCHOS_TEST_FOR_EXCEPTION(order_>2, std::runtime_error,
00159 "Lagrange order > 2 not implemented "
00160 "for quad cells");
00161 case TetCell:
00162 if (order_<=2) return 0;
00163 TEUCHOS_TEST_FOR_EXCEPTION(order_>2, std::runtime_error,
00164 "Lagrange order > 2 not implemented "
00165 "for tet cells");
00166 case BrickCell:
00167 if (order_<=1) return 0;
00168 if (order_==2) return 1;
00169 TEUCHOS_TEST_FOR_EXCEPTION(order_>2, std::runtime_error,
00170 "Lagrange order > 2 not implemented "
00171 "for brick cells");
00172 default:
00173 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, "Cell type "
00174 << cellType << " not implemented in Lagrange basis");
00175 return -1;
00176 }
00177 }
00178
00179 void Lagrange::getReferenceDOFs(
00180 const CellType& maximalCellType,
00181 const CellType& cellType,
00182 Array<Array<Array<int> > >& dofs) const
00183 {
00184 typedef Array<int> Aint;
00185
00186 if (order_==0)
00187 {
00188 int dim = dimension(cellType);
00189 dofs.resize(dim+1);
00190 for (int d=0; d<dim; d++)
00191 {
00192 Array<Array<int> > dd;
00193 for (int f=0; f<numFacets(cellType, d); f++) dd.append(Array<int>());
00194 dofs[d] = dd;
00195 }
00196 if (cellType==maximalCellType) dofs[dim] = tuple<Aint>(tuple(0));
00197 else dofs[dim] = tuple<Aint>(Array<int>());
00198 return;
00199 }
00200
00201 switch(cellType)
00202 {
00203 case PointCell:
00204 dofs.resize(1);
00205 dofs[0] = tuple<Aint>(tuple(0));
00206 return;
00207 case LineCell:
00208 dofs.resize(2);
00209 dofs[0] = tuple<Aint>(tuple(0), tuple(1));
00210 dofs[1] = tuple<Aint>(makeRange(2, order()));
00211 return;
00212 case TriangleCell:
00213 {
00214 int n = order()-1;
00215 dofs.resize(3);
00216 dofs[0] = tuple<Aint>(tuple(0), tuple(1), tuple(2));
00217 dofs[1] = tuple<Aint>(makeRange(3,2+n),
00218 makeRange(3+n, 2+2*n),
00219 makeRange(3+2*n, 2+3*n));
00220 if (order()<3)
00221 {
00222 dofs[2] = tuple(Array<int>());
00223 }
00224 else
00225 {
00226 dofs[2] = tuple<Aint>(makeRange(3+3*n, 3+3*n));
00227 }
00228 return;
00229 }
00230 case QuadCell:{
00231 dofs.resize(3);
00232
00233 dofs[0] = tuple<Aint>(tuple(0), tuple(1), tuple(2), tuple(3));
00234 if (order() == 2)
00235 {
00236
00237 dofs[1] = tuple<Aint>(tuple(4), tuple(5), tuple(6), tuple(7));
00238
00239
00240
00241 dofs[2] = tuple<Aint>(tuple(8));
00242 } else {
00243 dofs[1] = tuple(Array<int>(), Array<int>(),
00244 Array<int>(), Array<int>());
00245 dofs[2] = tuple(Array<int>());
00246 }
00247 return;
00248 }
00249 case TetCell:
00250 {
00251 dofs.resize(4);
00252 dofs[0] = tuple<Aint>(tuple(0), tuple(1), tuple(2), tuple(3));
00253 if (order() == 2)
00254 {
00255 dofs[1] = tuple<Aint>(tuple(4), tuple(5), tuple(6),
00256 tuple(7), tuple(8), tuple(9));
00257 }
00258 else
00259 {
00260 dofs[1] = tuple(Array<int>(), Array<int>(),
00261 Array<int>(), Array<int>(),
00262 Array<int>(), Array<int>());
00263 }
00264 dofs[2] = tuple(Array<int>(), Array<int>(),
00265 Array<int>(), Array<int>());
00266 dofs[3] = tuple(Array<int>());
00267 return;
00268 }
00269 case BrickCell:{
00270 dofs.resize(4);
00271
00272 dofs[0] = tuple<Aint>(tuple(0), tuple(1), tuple(2), tuple(3),
00273 tuple(4), tuple(5), tuple(6), tuple(7));
00274 if (order() == 2)
00275 {
00276
00277 dofs[1] = tuple<Aint>( tuple(8), tuple(9) , tuple(10), tuple(11),
00278 tuple(12), tuple(13), tuple(14), tuple(15),
00279 tuple(16), tuple(17), tuple(18), tuple(19));
00280
00281 dofs[2] = tuple<Aint>(tuple(20), tuple(21), tuple(22), tuple(23),
00282 tuple(24), tuple(25) );
00283 dofs[3] = tuple<Aint>(tuple(26));
00284 } else {
00285 dofs[1] = tuple(Array<int>(), Array<int>(), Array<int>(), Array<int>(),
00286 Array<int>(), Array<int>(), Array<int>(), Array<int>(),
00287 Array<int>(), Array<int>(), Array<int>(), Array<int>());
00288 dofs[2] = tuple(Array<int>(), Array<int>(), Array<int>(), Array<int>(),
00289 Array<int>(), Array<int>() );
00290 dofs[3] = tuple(Array<int>());
00291 }
00292 return;
00293 }
00294 default:
00295 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, "Cell type "
00296 << cellType << " not implemented in Lagrange basis");
00297 }
00298 }
00299
00300
00301
00302 Array<int> Lagrange::makeRange(int low, int high)
00303 {
00304 if (high < low) return Array<int>();
00305
00306 Array<int> rtn(high-low+1);
00307 for (int i=0; i<rtn.length(); i++) rtn[i] = low+i;
00308 return rtn;
00309 }
00310
00311 void Lagrange::refEval(
00312 const CellType& cellType,
00313 const Array<Point>& pts,
00314 const SpatialDerivSpecifier& sds,
00315 Array<Array<Array<double> > >& result,
00316 int verbosity) const
00317 {
00318 TEUCHOS_TEST_FOR_EXCEPTION(!(sds.isPartial() || sds.isIdentity()),
00319 std::runtime_error,
00320 "cannot evaluate spatial derivative " << sds << " on Lagrange basis");
00321 const MultiIndex& deriv = sds.mi();
00322 typedef Array<double> Adouble;
00323 result.resize(1);
00324 result[0].resize(pts.length());
00325
00326 switch(cellType)
00327 {
00328 case PointCell:
00329 result[0] = tuple<Adouble>(tuple(1.0));
00330 return;
00331 case LineCell:
00332 for (int i=0; i<pts.length(); i++)
00333 {
00334 evalOnLine(pts[i], deriv, result[0][i]);
00335 }
00336 return;
00337 case TriangleCell:
00338 for (int i=0; i<pts.length(); i++)
00339 {
00340 evalOnTriangle(pts[i], deriv, result[0][i]);
00341 }
00342 return;
00343 case QuadCell:
00344 for (int i=0; i<pts.length(); i++)
00345 {
00346 evalOnquad(pts[i], deriv, result[0][i]);
00347 }
00348 return;
00349 case TetCell:
00350 for (int i=0; i<pts.length(); i++)
00351 {
00352 evalOnTet(pts[i], deriv, result[0][i]);
00353 }
00354 return;
00355 case BrickCell:
00356 for (int i=0; i<pts.length(); i++)
00357 {
00358 evalOnBrick(pts[i], deriv, result[0][i]);
00359 }
00360 return;
00361 default:
00362 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
00363 "Lagrange::refEval() unimplemented for cell type "
00364 << cellType);
00365
00366 }
00367 }
00368
00369
00370
00371 void Lagrange::evalOnLine(const Point& pt,
00372 const MultiIndex& deriv,
00373 Array<double>& result) const
00374 {
00375 ADReal x = ADReal(pt[0], 0, 1);
00376 ADReal one(1.0, 1);
00377
00378 result.resize(order()+1);
00379 Array<ADReal> tmp(result.length());
00380 Array<double> x0(order()+1);
00381
00382 if (order_ == 0)
00383 {
00384 tmp[0] = one;
00385 }
00386 else
00387 {
00388 x0[0] = 0.0;
00389 x0[1] = 1.0;
00390 for (int i=0; i<order_-1; i++)
00391 {
00392 x0[i+2] = (i+1.0)/order_;
00393 }
00394
00395 for (int i=0; i<=order_; i++)
00396 {
00397 tmp[i] = one;
00398 for (int j=0; j<=order_; j++)
00399 {
00400 if (i==j) continue;
00401 tmp[i] *= (x - x0[j])/(x0[i]-x0[j]);
00402 }
00403 }
00404 }
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432 for (int i=0; i<tmp.length(); i++)
00433 {
00434 if (deriv.order()==0) result[i] = tmp[i].value();
00435 else result[i] = tmp[i].gradient()[0];
00436 }
00437 }
00438
00439 void Lagrange::evalOnTriangle(const Point& pt,
00440 const MultiIndex& deriv,
00441 Array<double>& result) const
00442
00443
00444
00445 {
00446 ADReal x = ADReal(pt[0], 0, 2);
00447 ADReal y = ADReal(pt[1], 1, 2);
00448 ADReal one(1.0, 2);
00449
00450 Array<ADReal> tmp;
00451
00452 SUNDANCE_OUT(this->verb() > 3, "x=" << x.value() << " y="
00453 << y.value());
00454
00455 switch(order_)
00456 {
00457 case 0:
00458 result.resize(1);
00459 tmp.resize(1);
00460 tmp[0] = one;
00461 break;
00462 case 1:
00463 result.resize(3);
00464 tmp.resize(3);
00465 tmp[0] = 1.0 - x - y;
00466 tmp[1] = x;
00467 tmp[2] = y;
00468 break;
00469 case 2:
00470 result.resize(6);
00471 tmp.resize(6);
00472 tmp[0] = (1.0-x-y)*(1.0-2.0*x-2.0*y);
00473 tmp[1] = 2.0*x*(x-0.5);
00474 tmp[2] = 2.0*y*(y-0.5);
00475 tmp[5] = 4.0*x*(1.0-x-y);
00476 tmp[3] = 4.0*x*y;
00477 tmp[4] = 4.0*y*(1.0-x-y);
00478 break;
00479 case 3:
00480 result.resize(10);
00481 tmp.resize(10);
00482 {
00483 ADReal q1 = 1.0 - x - y;
00484 ADReal q2 = x;
00485 ADReal q3 = y;
00486 tmp[0] = 9.0/2.0 * q1 * (q1 - 2.0/3.0) * (q1 - 1.0/3.0);
00487 tmp[1] = 9.0/2.0 * q2 * (q2 - 2.0/3.0) * (q2 - 1.0/3.0);
00488 tmp[2] = 9.0/2.0 * q3 * (q3 - 2.0/3.0) * (q3 - 1.0/3.0);
00489 tmp[7] = 27.0/2.0 * q1 * q2 * (q1 - 1.0/3.0);
00490 tmp[8] = 27.0/2.0 * q1 * q2 * (q2 - 1.0/3.0);
00491 tmp[3] = 27.0/2.0 * q2 * q3 * (q2 - 1.0/3.0);
00492 tmp[4] = 27.0/2.0 * q2 * q3 * (q3 - 1.0/3.0);
00493 tmp[6] = 27.0/2.0 * q3 * q1 * (q3 - 1.0/3.0);
00494 tmp[5] = 27.0/2.0 * q3 * q1 * (q1 - 1.0/3.0);
00495 tmp[9] = 27.0 * q1 * q2 * q3;
00496 }
00497 break;
00498 default:
00499 #ifndef TRILINOS_7
00500 SUNDANCE_ERROR("Lagrange::evalOnTriangle poly order > 2");
00501 #else
00502 SUNDANCE_ERROR7("Lagrange::evalOnTriangle poly order > 2");
00503 #endif
00504 }
00505
00506 for (int i=0; i<tmp.length(); i++)
00507 {
00508 SUNDANCE_OUT(this->verb() > 3,
00509 "tmp[" << i << "]=" << tmp[i].value()
00510 << " grad=" << tmp[i].gradient());
00511 if (deriv.order()==0) result[i] = tmp[i].value();
00512 else
00513 result[i] = tmp[i].gradient()[deriv.firstOrderDirection()];
00514 }
00515 }
00516
00517 void Lagrange::evalOnquad(const Point& pt,
00518 const MultiIndex& deriv,
00519 Array<double>& result) const {
00520
00521 ADReal x = ADReal(pt[0], 0, 2);
00522 ADReal y = ADReal(pt[1], 1, 2);
00523 ADReal one(1.0, 2);
00524
00525 Array<ADReal> tmp;
00526
00527 SUNDANCE_OUT(this->verb() > 3, "x=" << x.value() << " y="
00528 << y.value());
00529
00530 switch(order_)
00531 {
00532 case 0:
00533 result.resize(1);
00534 tmp.resize(1);
00535 tmp[0] = one;
00536 break;
00537 case 1:
00538 result.resize(4);
00539 tmp.resize(4);
00540 tmp[0] = (1.0 - x)*(1.0 - y);
00541 tmp[1] = x*(1.0 - y);
00542 tmp[2] = (1.0 - x)*y;
00543 tmp[3] = x*y;
00544 break;
00545 case 2:
00546
00547 result.resize(9);
00548 tmp.resize(9);
00549 tmp[0] = 9.0 - 9.0*x - 9.0*y + 9.0*x*y - 6.0*(x*x -1)*(y-1)
00550 - 6.0*(x-1)*(y*y-1) + 4.0*(x*x-1)*(y*y-1);
00551 tmp[1] = 6.0 - 3.0*x - 6.0*y + 3.0*x*y - 6.0*(x*x -1)*(y-1)
00552 - 3.0*(x-1)*(y*y-1) + 1.0*(x+1)*(y*y-1) + 4.0*(x*x-1)*(y*y-1);
00553 tmp[2] = 6.0 - 6.0*x - 3.0*y + 3.0*x*y - 3.0*(x*x -1)*(y-1) + 1.0*(x*x -1)*(y+1)
00554 -6.0*(x-1)*(y*y-1) + + 4.0*(x*x-1)*(y*y-1);
00555 tmp[3] = 4.0 - 2.0*x - 2.0*y + 1.0*x*y - 3.0*(x*x -1)*(y-1) + 1.0*(x*x -1)*(y+1)
00556 - 3.0*(x-1)*(y*y-1) + 1.0*(x+1)*(y*y-1) + 4.0*(x*x-1)*(y*y-1);
00557 tmp[4] = -12.0 + 12.0*x + 12.0*y - 12.0*x*y + 12.0*(x*x -1)*(y-1)
00558 + 8.0*(x-1)*(y*y-1) - 8.0*(x*x-1)*(y*y-1);
00559 tmp[5] = -12.0 + 12.0*x + 12.0*y - 12.0*x*y + 8.0*(x*x -1)*(y-1)
00560 + 12.0*(x-1)*(y*y-1) - 8.0*(x*x-1)*(y*y-1);
00561 tmp[6] = -8.0 + 4.0*x + 8.0*y - 4.0*x*y + 8.0*(x*x -1)*(y-1)
00562 + 6.0*(x-1)*(y*y-1) - 2.0*(x+1)*(y*y-1) - 8.0*(x*x-1)*(y*y-1);
00563 tmp[7] = -8.0 + 8.0*x + 4.0*y - 4.0*x*y + 6.0*(x*x -1)*(y-1) - 2.0*(x*x -1)*(y+1)
00564 + 8.0*(x-1)*(y*y-1) - 8.0*(x*x-1)*(y*y-1);
00565 tmp[8] = 16.0 - 16.0*x - 16.0*y + 16.0*x*y - 16.0*(x*x -1)*(y-1)
00566 - 16.0*(x-1)*(y*y-1) + 16.0*(x*x-1)*(y*y-1);
00567 break;
00568 default:{}
00569 }
00570
00571 for (int i=0; i<tmp.length(); i++) {
00572 SUNDANCE_OUT(this->verb() > 3 ,
00573 "tmp[" << i << "]=" << tmp[i].value()
00574 << " grad=" << tmp[i].gradient());
00575 if (deriv.order()==0)
00576 result[i] = tmp[i].value();
00577 else
00578 result[i] = tmp[i].gradient()[deriv.firstOrderDirection()];
00579 }
00580 }
00581
00582 void Lagrange::evalOnTet(const Point& pt,
00583 const MultiIndex& deriv,
00584 Array<double>& result) const
00585 {
00586 ADReal x = ADReal(pt[0], 0, 3);
00587 ADReal y = ADReal(pt[1], 1, 3);
00588 ADReal z = ADReal(pt[2], 2, 3);
00589 ADReal one(1.0, 3);
00590
00591
00592 Array<ADReal> tmp(result.length());
00593
00594 switch(order_)
00595 {
00596 case 0:
00597 tmp.resize(1);
00598 result.resize(1);
00599 tmp[0] = one;
00600 break;
00601 case 1:
00602 result.resize(4);
00603 tmp.resize(4);
00604 tmp[0] = 1.0 - x - y - z;
00605 tmp[1] = x;
00606 tmp[2] = y;
00607 tmp[3] = z;
00608 break;
00609 case 2:
00610 result.resize(10);
00611 tmp.resize(10);
00612 tmp[0] = (1.0-x-y-z)*(1.0-2.0*x-2.0*y-2.0*z);
00613 tmp[1] = 2.0*x*(x-0.5);
00614 tmp[2] = 2.0*y*(y-0.5);
00615 tmp[3] = 2.0*z*(z-0.5);
00616 tmp[9] = 4.0*x*(1.0-x-y-z);
00617 tmp[6] = 4.0*x*y;
00618 tmp[8] = 4.0*y*(1.0-x-y-z);
00619 tmp[7] = 4.0*z*(1.0-x-y-z);
00620 tmp[5] = 4.0*x*z;
00621 tmp[4] = 4.0*y*z;
00622 break;
00623 default:
00624 #ifndef TRILINOS_7
00625 SUNDANCE_ERROR("Lagrange::evalOnTet poly order > 2");
00626 #else
00627 SUNDANCE_ERROR7("Lagrange::evalOnTet poly order > 2");
00628 #endif
00629 }
00630
00631 for (int i=0; i<tmp.length(); i++)
00632 {
00633 if (deriv.order()==0) result[i] = tmp[i].value();
00634 else
00635 result[i] = tmp[i].gradient()[deriv.firstOrderDirection()];
00636 }
00637 }
00638
00639 void Lagrange::evalOnBrick(const Point& pt,
00640 const MultiIndex& deriv,
00641 Array<double>& result) const
00642 {
00643 ADReal x = ADReal(pt[0], 0, 3);
00644 ADReal y = ADReal(pt[1], 1, 3);
00645 ADReal z = ADReal(pt[2], 2, 3);
00646 ADReal one(1.0, 3);
00647
00648
00649 Array<ADReal> tmp(result.length());
00650
00651 switch(order_)
00652 {
00653 case 0:
00654 tmp.resize(1);
00655 result.resize(1);
00656 tmp[0] = one;
00657 break;
00658 case 1:
00659 result.resize(8);
00660 tmp.resize(8);
00661 tmp[0] = (1.0 - x)*(1.0 - y)*(1.0 - z);
00662 tmp[1] = (x)*(1.0 - y)*(1.0 - z);
00663 tmp[2] = (1.0 - x)*(y)*(1.0 - z);
00664 tmp[3] = (x)*(y)*(1.0 - z);
00665 tmp[4] = (1.0 - x)*(1.0 - y)*(z);
00666 tmp[5] = (x)*(1.0 - y)*(z);
00667 tmp[6] = (1.0 - x)*(y)*(z);
00668 tmp[7] = (x)*(y)*(z);
00669 break;
00670 case 2:
00671 result.resize(27);
00672 tmp.resize(27);
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683 tmp[0] = 27.0 - 27.0*x - 27.0*y - 27.0*z + 27.0*x*y + 27.0*x*z + 27.0*y*z - 27.0*x*y*z
00684 + 18.0*(x*x - 1)*(y-1)*(z-1)
00685 + 18.0*(y*y - 1)*(x-1)*(z-1)
00686 + 18.0*(z*z - 1)*(x-1)*(y-1)
00687 - 12.0*(x*x - 1)*(y*y - 1)*(z-1)
00688 - 12.0*(x*x - 1)*(z*z - 1)*(y-1)
00689 - 12.0*(y*y - 1)*(z*z - 1)*(x-1)
00690 + 8.0*(x*x - 1)*(y*y - 1)*(z*z - 1);
00691
00692 tmp[1] = 18.0 - 9.0*x - 18.0*y - 18.0*z + 9.0*x*y + 9.0*x*z + 18.0*y*z - 9.0*x*y*z
00693 + 18.0*(x*x - 1)*(y-1)*(z-1)
00694 + 9.0*(y*y - 1)*(x-1)*(z-1) - 3.0*(y*y - 1)*(x+1)*(z-1)
00695 + 9.0*(z*z - 1)*(x-1)*(y-1) - 3.0*(z*z - 1)*(x+1)*(y-1)
00696 - 12.0*(x*x - 1)*(y*y - 1)*(z-1)
00697 - 12.0*(x*x - 1)*(z*z - 1)*(y-1)
00698 - 6.0*(y*y - 1)*(z*z - 1)*(x-1) + 2.0*(y*y - 1)*(z*z - 1)*(x+1)
00699 + 8.0*(x*x - 1)*(y*y - 1)*(z*z - 1);
00700
00701 tmp[2] = 18.0 - 18.0*x - 9.0*y - 18.0*z + 9.0*x*y + 18.0*x*z + 9.0*y*z - 9.0*x*y*z
00702 + 9.0*(x*x - 1)*(y-1)*(z-1) - 3.0*(x*x - 1)*(y+1)*(z-1)
00703 + 18.0*(y*y - 1)*(x-1)*(z-1)
00704 + 9.0*(z*z - 1)*(x-1)*(y-1) - 3.0*(z*z - 1)*(x-1)*(y+1)
00705 - 12.0*(x*x - 1)*(y*y - 1)*(z-1)
00706 - 6.0*(x*x - 1)*(z*z - 1)*(y-1) + 2.0*(x*x - 1)*(z*z - 1)*(y+1)
00707 - 12.0*(y*y - 1)*(z*z - 1)*(x-1)
00708 + 8.0*(x*x - 1)*(y*y - 1)*(z*z - 1);
00709
00710 tmp[3] = 12.0 - 6.0*x - 6.0*y - 12.0*z + 3.0*x*y + 6.0*x*z + 6.0*y*z - 3.0*x*y*z
00711 + 9.0*(x*x - 1)*(y-1)*(z-1) - 3.0*(x*x - 1)*(y+1)*(z-1)
00712 + 9.0*(y*y - 1)*(x-1)*(z-1) - 3.0*(y*y - 1)*(x+1)*(z-1)
00713 + 4.5*(z*z - 1)*(x-1)*(y-1) - 1.5*(z*z - 1)*(x-1)*(y+1) - 1.5*(z*z - 1)*(x+1)*(y-1) + 0.5*(z*z - 1)*(x+1)*(y+1)
00714 - 12.0*(x*x - 1)*(y*y - 1)*(z-1)
00715 - 6.0*(x*x - 1)*(z*z - 1)*(y-1) + 2.0*(x*x - 1)*(z*z - 1)*(y+1)
00716 - 6.0*(y*y - 1)*(z*z - 1)*(x-1) + 2.0*(y*y - 1)*(z*z - 1)*(x+1)
00717 + 8.0*(x*x - 1)*(y*y - 1)*(z*z - 1);
00718
00719 tmp[4] = 18.0 - 18.0*x - 18.0*y - 9.0*z + 18.0*x*y + 9.0*x*z + 9.0*y*z - 9.0*x*y*z
00720 + 9.0*(x*x - 1)*(y-1)*(z-1) - 3.0*(x*x - 1)*(y-1)*(z+1)
00721 + 9.0*(y*y - 1)*(x-1)*(z-1) - 3.0*(y*y - 1)*(x-1)*(z+1)
00722 + 18.0*(z*z - 1)*(x-1)*(y-1)
00723 - 6.0*(x*x - 1)*(y*y - 1)*(z-1) + 2.0*(x*x - 1)*(y*y - 1)*(z+1)
00724 - 12.0*(x*x - 1)*(z*z - 1)*(y-1)
00725 - 12.0*(y*y - 1)*(z*z - 1)*(x-1)
00726 + 8.0*(x*x - 1)*(y*y - 1)*(z*z - 1);
00727
00728 tmp[5] = 12.0 - 6.0*x - 12.0*y - 6.0*z + 6.0*x*y + 3.0*x*z + 6.0*y*z - 3.0*x*y*z
00729 + 9.0*(x*x - 1)*(y-1)*(z-1) - 3.0*(x*x - 1)*(y-1)*(z+1)
00730 + 4.5*(y*y - 1)*(x-1)*(z-1) - 1.5*(y*y - 1)*(x-1)*(z+1) - 1.5*(y*y - 1)*(x+1)*(z-1) + 0.5*(y*y - 1)*(x+1)*(z+1)
00731 + 9.0*(z*z - 1)*(x-1)*(y-1) - 3.0*(z*z - 1)*(x+1)*(y-1)
00732 - 6.0*(x*x - 1)*(y*y - 1)*(z-1) + 2.0*(x*x - 1)*(y*y - 1)*(z+1)
00733 - 12.0*(x*x - 1)*(z*z - 1)*(y-1)
00734 - 6.0*(y*y - 1)*(z*z - 1)*(x-1) + 2.0*(y*y - 1)*(z*z - 1)*(x+1)
00735 + 8.0*(x*x - 1)*(y*y - 1)*(z*z - 1);
00736
00737 tmp[6] = 12.0 - 12.0*x - 6.0*y - 6.0*z + 6.0*x*y + 6.0*x*z + 3.0*y*z - 3.0*x*y*z
00738 + 4.5*(x*x - 1)*(y-1)*(z-1) - 1.5*(x*x - 1)*(y-1)*(z+1) - 1.5*(x*x - 1)*(y+1)*(z-1) + 0.5*(x*x - 1)*(y+1)*(z+1)
00739 + 9.0*(y*y - 1)*(x-1)*(z-1) - 3.0*(y*y - 1)*(x-1)*(z+1)
00740 + 9.0*(z*z - 1)*(x-1)*(y-1) - 3.0*(z*z - 1)*(x-1)*(y+1)
00741 - 6.0*(x*x - 1)*(y*y - 1)*(z-1) + 2.0*(x*x - 1)*(y*y - 1)*(z+1)
00742 - 6.0*(x*x - 1)*(z*z - 1)*(y-1) + 2.0*(x*x - 1)*(z*z - 1)*(y+1)
00743 - 12.0*(y*y - 1)*(z*z - 1)*(x-1)
00744 + 8.0*(x*x - 1)*(y*y - 1)*(z*z - 1);
00745
00746 tmp[7] = 8.0 - 4.0*x - 4.0*y - 4.0*z + 2.0*x*y + 2.0*x*z + 2.0*y*z - 1.0*x*y*z
00747 + 4.5*(x*x - 1)*(y-1)*(z-1) - 1.5*(x*x - 1)*(y-1)*(z+1) - 1.5*(x*x - 1)*(y+1)*(z-1) + 0.5*(x*x - 1)*(y+1)*(z+1)
00748 + 4.5*(y*y - 1)*(x-1)*(z-1) - 1.5*(y*y - 1)*(x-1)*(z+1) - 1.5*(y*y - 1)*(x+1)*(z-1) + 0.5*(y*y - 1)*(x+1)*(z+1)
00749 + 4.5*(z*z - 1)*(x-1)*(y-1) - 1.5*(z*z - 1)*(x-1)*(y+1) - 1.5*(z*z - 1)*(x+1)*(y-1) + 0.5*(z*z - 1)*(x+1)*(y+1)
00750 - 6.0*(x*x - 1)*(y*y - 1)*(z-1) + 2.0*(x*x - 1)*(y*y - 1)*(z+1)
00751 - 6.0*(x*x - 1)*(z*z - 1)*(y-1) + 2.0*(x*x - 1)*(z*z - 1)*(y+1)
00752 - 6.0*(y*y - 1)*(z*z - 1)*(x-1) + 2.0*(y*y - 1)*(z*z - 1)*(x+1)
00753 + 8.0*(x*x - 1)*(y*y - 1)*(z*z - 1);
00754
00755 tmp[8] = -36.0 + 36.0*x + 36.0*y + 36.0*z - 36.0*x*y - 36.0*x*z - 36.0*y*z + 36.0*x*y*z
00756 - 36.0*(x*x - 1)*(y-1)*(z-1)
00757 - 24.0*(y*y - 1)*(x-1)*(z-1)
00758 - 24.0*(z*z - 1)*(x-1)*(y-1)
00759 + 24.0*(x*x - 1)*(y*y - 1)*(z-1)
00760 + 24.0*(x*x - 1)*(z*z - 1)*(y-1)
00761 + 16.0*(y*y - 1)*(z*z - 1)*(x-1)
00762 - 16.0*(x*x - 1)*(y*y - 1)*(z*z - 1);
00763
00764 tmp[9] = -36.0 + 36.0*x + 36.0*y + 36.0*z - 36.0*x*y - 36.0*x*z - 36.0*y*z + 36.0*x*y*z
00765 - 24.0*(x*x - 1)*(y-1)*(z-1)
00766 - 36.0*(y*y - 1)*(x-1)*(z-1)
00767 - 24.0*(z*z - 1)*(x-1)*(y-1)
00768 + 24.0*(x*x - 1)*(y*y - 1)*(z-1)
00769 + 16.0*(x*x - 1)*(z*z - 1)*(y-1)
00770 + 24.0*(y*y - 1)*(z*z - 1)*(x-1)
00771 - 16.0*(x*x - 1)*(y*y - 1)*(z*z - 1);
00772
00773 tmp[10] = -36.0 + 36.0*x + 36.0*y + 36.0*z - 36.0*x*y - 36.0*x*z - 36.0*y*z + 36.0*x*y*z
00774 - 24.0*(x*x - 1)*(y-1)*(z-1)
00775 - 24.0*(y*y - 1)*(x-1)*(z-1)
00776 - 36.0*(z*z - 1)*(x-1)*(y-1)
00777 + 16.0*(x*x - 1)*(y*y - 1)*(z-1)
00778 + 24.0*(x*x - 1)*(z*z - 1)*(y-1)
00779 + 24.0*(y*y - 1)*(z*z - 1)*(x-1)
00780 - 16.0*(x*x - 1)*(y*y - 1)*(z*z - 1);
00781
00782 tmp[11] = -24.0 + 12.0*x + 24.0*y + 24.0*z - 12.0*x*y - 12.0*x*z - 24.0*y*z + 12.0*x*y*z
00783 - 24.0*(x*x - 1)*(y-1)*(z-1)
00784 - 18.0*(y*y - 1)*(x-1)*(z-1) + 6.0*(y*y - 1)*(x+1)*(z-1)
00785 - 12.0*(z*z - 1)*(x-1)*(y-1) + 4.0*(z*z - 1)*(x+1)*(y-1)
00786 + 24.0*(x*x - 1)*(y*y - 1)*(z-1)
00787 + 16.0*(x*x - 1)*(z*z - 1)*(y-1)
00788 + 12.0*(y*y - 1)*(z*z - 1)*(x-1) - 4.0*(y*y - 1)*(z*z - 1)*(x+1)
00789 - 16.0*(x*x - 1)*(y*y - 1)*(z*z - 1);
00790
00791 tmp[12] = -24.0 + 12.0*x + 24.0*y + 24.0*z - 12.0*x*y - 12.0*x*z - 24.0*y*z + 12.0*x*y*z
00792 - 24.0*(x*x - 1)*(y-1)*(z-1)
00793 - 12.0*(y*y - 1)*(x-1)*(z-1) + 4.0*(y*y - 1)*(x+1)*(z-1)
00794 - 18.0*(z*z - 1)*(x-1)*(y-1) + 6.0*(z*z - 1)*(x+1)*(y-1)
00795 + 16.0*(x*x - 1)*(y*y - 1)*(z-1)
00796 + 24.0*(x*x - 1)*(z*z - 1)*(y-1)
00797 + 12.0*(y*y - 1)*(z*z - 1)*(x-1) - 4.0*(y*y - 1)*(z*z - 1)*(x+1)
00798 - 16.0*(x*x - 1)*(y*y - 1)*(z*z - 1);
00799
00800 tmp[13] = -24.0 + 24.0*x + 12.0*y + 24.0*z - 12.0*x*y - 24.0*x*z - 12.0*y*z + 12.0*x*y*z
00801 - 18.0*(x*x - 1)*(y-1)*(z-1) + 6.0*(x*x - 1)*(y+1)*(z-1)
00802 - 24.0*(y*y - 1)*(x-1)*(z-1)
00803 - 12.0*(z*z - 1)*(x-1)*(y-1) + 4.0*(z*z - 1)*(x-1)*(y+1)
00804 + 24.0*(x*x - 1)*(y*y - 1)*(z-1)
00805 + 12.0*(x*x - 1)*(z*z - 1)*(y-1) - 4.0*(x*x - 1)*(z*z - 1)*(y+1)
00806 + 16.0*(y*y - 1)*(z*z - 1)*(x-1)
00807 - 16.0*(x*x - 1)*(y*y - 1)*(z*z - 1);
00808
00809 tmp[14] = -24.0 + 24.0*x + 12.0*y + 24.0*z - 12.0*x*y - 24.0*x*z - 12.0*y*z + 12.0*x*y*z
00810 - 12.0*(x*x - 1)*(y-1)*(z-1) + 4.0*(x*x - 1)*(y+1)*(z-1)
00811 - 24.0*(y*y - 1)*(x-1)*(z-1)
00812 - 18.0*(z*z - 1)*(x-1)*(y-1) + 6.0*(z*z - 1)*(x-1)*(y+1)
00813 + 16.0*(x*x - 1)*(y*y - 1)*(z-1)
00814 + 12.0*(x*x - 1)*(z*z - 1)*(y-1) - 4.0*(x*x - 1)*(z*z - 1)*(y+1)
00815 + 24.0*(y*y - 1)*(z*z - 1)*(x-1)
00816 - 16.0*(x*x - 1)*(y*y - 1)*(z*z - 1);
00817
00818 tmp[15] = -16.0 + 8.0*x + 8.0*y + 16.0*z - 4.0*x*y - 8.0*x*z - 8.0*y*z + 4.0*x*y*z
00819 - 12.0*(x*x - 1)*(y-1)*(z-1) + 4.0*(x*x - 1)*(y+1)*(z-1)
00820 - 12.0*(y*y - 1)*(x-1)*(z-1) + 4.0*(y*y - 1)*(x+1)*(z-1)
00821 - 9.0*(z*z - 1)*(x-1)*(y-1) + 3.0*(z*z - 1)*(x-1)*(y+1) + 3.0*(z*z - 1)*(x+1)*(y-1) - 1.0*(z*z - 1)*(x+1)*(y+1)
00822 + 16.0*(x*x - 1)*(y*y - 1)*(z-1)
00823 + 12.0*(x*x - 1)*(z*z - 1)*(y-1) - 4.0*(x*x - 1)*(z*z - 1)*(y+1)
00824 + 12.0*(y*y - 1)*(z*z - 1)*(x-1) - 4.0*(y*y - 1)*(z*z - 1)*(x+1)
00825 - 16.0*(x*x - 1)*(y*y - 1)*(z*z - 1);
00826
00827 tmp[16] = -24.0 + 24.0*x + 24.0*y + 12.0*z - 24.0*x*y - 12.0*x*z - 12.0*y*z + 12.0*x*y*z
00828 - 18.0*(x*x - 1)*(y-1)*(z-1) + 6.0*(x*x - 1)*(y-1)*(z+1)
00829 - 12.0*(y*y - 1)*(x-1)*(z-1) + 4.0*(y*y - 1)*(x-1)*(z+1)
00830 - 24.0*(z*z - 1)*(x-1)*(y-1)
00831 + 12.0*(x*x - 1)*(y*y - 1)*(z-1) - 4.0*(x*x - 1)*(y*y - 1)*(z+1)
00832 + 24.0*(x*x - 1)*(z*z - 1)*(y-1)
00833 + 16.0*(y*y - 1)*(z*z - 1)*(x-1)
00834 - 16.0*(x*x - 1)*(y*y - 1)*(z*z - 1);
00835
00836 tmp[17] = -24.0 + 24.0*x + 24.0*y + 12.0*z - 24.0*x*y - 12.0*x*z - 12.0*y*z + 12.0*x*y*z
00837 - 12.0*(x*x - 1)*(y-1)*(z-1) + 4.0*(x*x - 1)*(y-1)*(z+1)
00838 - 18.0*(y*y - 1)*(x-1)*(z-1) + 6.0*(y*y - 1)*(x-1)*(z+1)
00839 - 24.0*(z*z - 1)*(x-1)*(y-1)
00840 + 12.0*(x*x - 1)*(y*y - 1)*(z-1) - 4.0*(x*x - 1)*(y*y - 1)*(z+1)
00841 + 16.0*(x*x - 1)*(z*z - 1)*(y-1)
00842 + 24.0*(y*y - 1)*(z*z - 1)*(x-1)
00843 - 16.0*(x*x - 1)*(y*y - 1)*(z*z - 1);
00844
00845 tmp[18] = -16.0 + 8.0*x + 16.0*y + 8.0*z - 8.0*x*y - 4.0*x*z - 8.0*y*z + 4.0*x*y*z
00846 - 12.0*(x*x - 1)*(y-1)*(z-1) + 4.0*(x*x - 1)*(y-1)*(z+1)
00847 - 9.0*(y*y - 1)*(x-1)*(z-1) + 3.0*(y*y - 1)*(x-1)*(z+1) + 3.0*(y*y - 1)*(x+1)*(z-1) - 1.0*(y*y - 1)*(x+1)*(z+1)
00848 - 12.0*(z*z - 1)*(x-1)*(y-1) + 4.0*(z*z - 1)*(x+1)*(y-1)
00849 + 12.0*(x*x - 1)*(y*y - 1)*(z-1) - 4.0*(x*x - 1)*(y*y - 1)*(z+1)
00850 + 16.0*(x*x - 1)*(z*z - 1)*(y-1)
00851 + 12.0*(y*y - 1)*(z*z - 1)*(x-1) - 4.0*(y*y - 1)*(z*z - 1)*(x+1)
00852 - 16.0*(x*x - 1)*(y*y - 1)*(z*z - 1);
00853
00854 tmp[19] = -16.0 + 16.0*x + 8.0*y + 8.0*z - 8.0*x*y - 8.0*x*z - 4.0*y*z + 4.0*x*y*z
00855 - 9.0*(x*x - 1)*(y-1)*(z-1) + 3.0*(x*x - 1)*(y-1)*(z+1) + 3.0*(x*x - 1)*(y+1)*(z-1) - 1.0*(x*x - 1)*(y+1)*(z+1)
00856 - 12.0*(y*y - 1)*(x-1)*(z-1) + 4.0*(y*y - 1)*(x-1)*(z+1)
00857 - 12.0*(z*z - 1)*(x-1)*(y-1) + 4.0*(z*z - 1)*(x-1)*(y+1)
00858 + 12.0*(x*x - 1)*(y*y - 1)*(z-1) - 4.0*(x*x - 1)*(y*y - 1)*(z+1)
00859 + 12.0*(x*x - 1)*(z*z - 1)*(y-1) - 4.0*(x*x - 1)*(z*z - 1)*(y+1)
00860 + 16.0*(y*y - 1)*(z*z - 1)*(x-1)
00861 - 16.0*(x*x - 1)*(y*y - 1)*(z*z - 1);
00862
00863 tmp[20] = 48.0 - 48.0*x - 48.0*y - 48.0*z + 48.0*x*y + 48.0*x*z + 48.0*y*z - 48.0*x*y*z
00864 + 48.0*(x*x - 1)*(y-1)*(z-1)
00865 + 48.0*(y*y - 1)*(x-1)*(z-1)
00866 + 32.0*(z*z - 1)*(x-1)*(y-1)
00867 - 48.0*(x*x - 1)*(y*y - 1)*(z-1)
00868 - 32.0*(x*x - 1)*(z*z - 1)*(y-1)
00869 - 32.0*(y*y - 1)*(z*z - 1)*(x-1)
00870 + 32.0*(x*x - 1)*(y*y - 1)*(z*z - 1);
00871
00872 tmp[21] = 48.0 - 48.0*x - 48.0*y - 48.0*z + 48.0*x*y + 48.0*x*z + 48.0*y*z - 48.0*x*y*z
00873 + 48.0*(x*x - 1)*(y-1)*(z-1)
00874 + 32.0*(y*y - 1)*(x-1)*(z-1)
00875 + 48.0*(z*z - 1)*(x-1)*(y-1)
00876 - 32.0*(x*x - 1)*(y*y - 1)*(z-1)
00877 - 48.0*(x*x - 1)*(z*z - 1)*(y-1)
00878 - 32.0*(y*y - 1)*(z*z - 1)*(x-1)
00879 + 32.0*(x*x - 1)*(y*y - 1)*(z*z - 1);
00880
00881 tmp[22] = 48.0 - 48.0*x - 48.0*y - 48.0*z + 48.0*x*y + 48.0*x*z + 48.0*y*z - 48.0*x*y*z
00882 + 32.0*(x*x - 1)*(y-1)*(z-1)
00883 + 48.0*(y*y - 1)*(x-1)*(z-1)
00884 + 48.0*(z*z - 1)*(x-1)*(y-1)
00885 - 32.0*(x*x - 1)*(y*y - 1)*(z-1)
00886 - 32.0*(x*x - 1)*(z*z - 1)*(y-1)
00887 - 48.0*(y*y - 1)*(z*z - 1)*(x-1)
00888 + 32.0*(x*x - 1)*(y*y - 1)*(z*z - 1);
00889
00890 tmp[23] = 32.0 - 16.0*x - 32.0*y - 32.0*z + 16.0*x*y + 16.0*x*z + 32.0*y*z - 16.0*x*y*z
00891 + 32.0*(x*x - 1)*(y-1)*(z-1)
00892 + 24.0*(y*y - 1)*(x-1)*(z-1) - 8.0*(y*y - 1)*(x+1)*(z-1)
00893 + 24.0*(z*z - 1)*(x-1)*(y-1) - 8.0*(z*z - 1)*(x+1)*(y-1)
00894 - 32.0*(x*x - 1)*(y*y - 1)*(z-1)
00895 - 32.0*(x*x - 1)*(z*z - 1)*(y-1)
00896 - 24.0*(y*y - 1)*(z*z - 1)*(x-1) + 8.0*(y*y - 1)*(z*z - 1)*(x+1)
00897 + 32.0*(x*x - 1)*(y*y - 1)*(z*z - 1);
00898
00899 tmp[24] = 32.0 - 32.0*x - 16.0*y - 32.0*z + 16.0*x*y + 32.0*x*z + 16.0*y*z - 16.0*x*y*z
00900 + 24.0*(x*x - 1)*(y-1)*(z-1)- 8.0*(x*x - 1)*(y+1)*(z-1)
00901 + 32.0*(y*y - 1)*(x-1)*(z-1)
00902 + 24.0*(z*z - 1)*(x-1)*(y-1) - 8.0*(z*z - 1)*(x-1)*(y+1)
00903 - 32.0*(x*x - 1)*(y*y - 1)*(z-1)
00904 - 24.0*(x*x - 1)*(z*z - 1)*(y-1) + 8.0*(x*x - 1)*(z*z - 1)*(y+1)
00905 - 32.0*(y*y - 1)*(z*z - 1)*(x-1)
00906 + 32.0*(x*x - 1)*(y*y - 1)*(z*z - 1);
00907
00908 tmp[25] = 32.0 - 32.0*x - 32.0*y - 16.0*z + 32.0*x*y + 16.0*x*z + 16.0*y*z - 16.0*x*y*z
00909 + 24.0*(x*x - 1)*(y-1)*(z-1) - 8.0*(x*x - 1)*(y-1)*(z+1)
00910 + 24.0*(y*y - 1)*(x-1)*(z-1) - 8.0*(y*y - 1)*(x-1)*(z+1)
00911 + 32.0*(z*z - 1)*(x-1)*(y-1)
00912 - 24.0*(x*x - 1)*(y*y - 1)*(z-1) + 8.0*(x*x - 1)*(y*y - 1)*(z+1)
00913 - 32.0*(x*x - 1)*(z*z - 1)*(y-1)
00914 - 32.0*(y*y - 1)*(z*z - 1)*(x-1)
00915 + 32.0*(x*x - 1)*(y*y - 1)*(z*z - 1);
00916
00917 tmp[26] = -64.0 + 64.0*x + 64.0*y + 64.0*z - 64.0*x*y - 64.0*x*z - 64.0*y*z + 64.0*x*y*z
00918 - 64.0*(x*x - 1)*(y-1)*(z-1)
00919 - 64.0*(y*y - 1)*(x-1)*(z-1)
00920 - 64.0*(z*z - 1)*(x-1)*(y-1)
00921 + 64.0*(x*x - 1)*(y*y - 1)*(z-1)
00922 + 64.0*(x*x - 1)*(z*z - 1)*(y-1)
00923 + 64.0*(y*y - 1)*(z*z - 1)*(x-1)
00924 - 64.0*(x*x - 1)*(y*y - 1)*(z*z - 1);
00925
00926 break;
00927 default:
00928 #ifndef TRILINOS_7
00929 SUNDANCE_ERROR("Lagrange::evalOnBrick poly order > 2");
00930 #else
00931 SUNDANCE_ERROR7("Lagrange::evalOnBrick poly order > 2");
00932 #endif
00933 }
00934
00935 for (int i=0; i<tmp.length(); i++)
00936 {
00937 if (deriv.order()==0) result[i] = tmp[i].value();
00938 else
00939 result[i] = tmp[i].gradient()[deriv.firstOrderDirection()];
00940 }
00941 }
00942
00943 void Lagrange::getConstrainsForHNDoF(
00944 const int indexInParent,
00945 const int maxCellDim,
00946 const int maxNrChild,
00947 const int facetDim,
00948 const int facetIndex,
00949 const int nodeIndex,
00950 Array<int>& localDoFs,
00951 Array<int>& parentFacetDim,
00952 Array<int>& parentFacetIndex,
00953 Array<int>& parentFacetNode,
00954 Array<double>& coefs
00955 ) {
00956
00957
00958
00959
00960
00961
00962 Array<Array<Array<double> > > result;
00963 const SpatialDerivSpecifier deriv;
00964 int index = 0;
00965
00966
00967
00968 localDoFs.resize(0);
00969 coefs.resize(0);
00970 parentFacetDim.resize(0);
00971 parentFacetIndex.resize(0);
00972 parentFacetNode.resize(0);
00973
00974 CellType maximalCellType;
00975
00976 switch (maxCellDim){
00977 case 2:{
00978 maximalCellType = QuadCell;
00979
00980 switch (maxNrChild){
00981 case 9:{
00982 Point dofPos( 0.0 , 0.0 );
00983
00984 SUNDANCE_OUT(this->verb() > 3 , ",maxCellDim=" << maxCellDim << ",facetDim="
00985 << facetDim << ",facetIndex=" << facetIndex << ",nodeIndex=" << nodeIndex
00986 << ",dofPos=" << dofPos);
00987 returnDoFPositionOnRef( maxCellDim,
00988 facetDim, facetIndex, nodeIndex, dofPos);
00989 dofPos = dofPos/3.0;
00990 SUNDANCE_OUT(this->verb() > 3 , "dofPos=" << dofPos );
00991
00992
00993 switch (indexInParent){
00994 case 0: { break;}
00995 case 1: {dofPos[0] += 1.0/3.0; break;}
00996 case 2: {dofPos[0] += 2.0/3.0; break;}
00997 case 3: {dofPos[0] += 2.0/3.0; dofPos[1] += 1.0/3.0; break;}
00998 case 5: {dofPos[1] += 1.0/3.0; break;}
00999 case 6: {dofPos[1] += 2.0/3.0; break;}
01000 case 7: {dofPos[0] += 1.0/3.0; dofPos[1] += 2.0/3.0; break;}
01001 case 8: {dofPos[0] += 2.0/3.0; dofPos[1] += 2.0/3.0; break;}
01002 }
01003
01004 SUNDANCE_OUT(this->verb() > 3 , "dofPos=" << dofPos );
01005 Array<Point> tmp_points(1);
01006 tmp_points[0] = dofPos;
01007 refEval( maximalCellType , tmp_points ,
01008 deriv, result , 4);
01009
01010 break;}
01011 case 4:{
01012 Point dofPos( 0.0 , 0.0 );
01013
01014 SUNDANCE_OUT(this->verb() > 3 , ",maxCellDim=" << maxCellDim << ",facetDim="
01015 << facetDim << ",facetIndex=" << facetIndex << ",nodeIndex=" << nodeIndex
01016 << ",dofPos=" << dofPos);
01017 returnDoFPositionOnRef( maxCellDim,
01018 facetDim, facetIndex, nodeIndex, dofPos);
01019 dofPos = dofPos/2.0;
01020 SUNDANCE_OUT(this->verb() > 3 , "dofPos=" << dofPos );
01021
01022 switch (indexInParent){
01023 case 0: { break;}
01024 case 1: {dofPos[0] += 1.0/2.0; break;}
01025 case 2: {dofPos[1] += 1.0/2.0; break;}
01026 case 3: {dofPos[0] += 1.0/2.0; dofPos[1] += 1.0/2.0; break;}
01027 }
01028
01029 SUNDANCE_OUT(this->verb() > 3 , "dofPos=" << dofPos );
01030 Array<Point> tmp_points(1);
01031 tmp_points[0] = dofPos;
01032 refEval( maximalCellType , tmp_points ,
01033 deriv, result , 4);
01034 break;
01035 }
01036 }
01037 break;}
01038 case 3:{
01039
01040 maximalCellType = BrickCell;
01041
01042 Point dofPos( 0.0 , 0.0 , 0.0);
01043
01044 SUNDANCE_OUT(this->verb() > 3 , ",maxCellDim=" << maxCellDim << ",facetDim="
01045 << facetDim << ",facetIndex=" << facetIndex << ",nodeIndex=" << nodeIndex
01046 << ",dofPos=" << dofPos);
01047 returnDoFPositionOnRef( maxCellDim,
01048 facetDim, facetIndex, nodeIndex, dofPos);
01049
01050
01051 switch (maxNrChild){
01052 case 27:{
01053 dofPos = dofPos/3.0;
01054 SUNDANCE_OUT(this->verb() > 3 , "dofPos=" << dofPos );
01055 switch (indexInParent){
01056 case 0: {dofPos[0] += 0.0/3.0; dofPos[1] += 0.0/3.0; dofPos[2] += 0.0/3.0; break;}
01057 case 1: {dofPos[0] += 1.0/3.0; dofPos[1] += 0.0/3.0; dofPos[2] += 0.0/3.0; break;}
01058 case 2: {dofPos[0] += 2.0/3.0; dofPos[1] += 0.0/3.0; dofPos[2] += 0.0/3.0; break;}
01059 case 3: {dofPos[0] += 0.0/3.0; dofPos[1] += 1.0/3.0; dofPos[2] += 0.0/3.0; break;}
01060 case 4: {dofPos[0] += 1.0/3.0; dofPos[1] += 1.0/3.0; dofPos[2] += 0.0/3.0; break;}
01061 case 5: {dofPos[0] += 2.0/3.0; dofPos[1] += 1.0/3.0; dofPos[2] += 0.0/3.0; break;}
01062 case 6: {dofPos[0] += 0.0/3.0; dofPos[1] += 2.0/3.0; dofPos[2] += 0.0/3.0; break;}
01063 case 7: {dofPos[0] += 1.0/3.0; dofPos[1] += 2.0/3.0; dofPos[2] += 0.0/3.0; break;}
01064 case 8: {dofPos[0] += 2.0/3.0; dofPos[1] += 2.0/3.0; dofPos[2] += 0.0/3.0; break;}
01065 case 9: {dofPos[0] += 0.0/3.0; dofPos[1] += 0.0/3.0; dofPos[2] += 1.0/3.0; break;}
01066 case 10: {dofPos[0] += 1.0/3.0; dofPos[1] += 0.0/3.0; dofPos[2] += 1.0/3.0; break;}
01067 case 11: {dofPos[0] += 2.0/3.0; dofPos[1] += 0.0/3.0; dofPos[2] += 1.0/3.0; break;}
01068 case 12: {dofPos[0] += 0.0/3.0; dofPos[1] += 1.0/3.0; dofPos[2] += 1.0/3.0; break;}
01069
01070 case 13: {dofPos[0] += 1.0/3.0; dofPos[1] += 1.0/3.0; dofPos[2] += 1.0/3.0; break;}
01071 case 14: {dofPos[0] += 2.0/3.0; dofPos[1] += 1.0/3.0; dofPos[2] += 1.0/3.0; break;}
01072 case 15: {dofPos[0] += 0.0/3.0; dofPos[1] += 2.0/3.0; dofPos[2] += 1.0/3.0; break;}
01073 case 16: {dofPos[0] += 1.0/3.0; dofPos[1] += 2.0/3.0; dofPos[2] += 1.0/3.0; break;}
01074 case 17: {dofPos[0] += 2.0/3.0; dofPos[1] += 2.0/3.0; dofPos[2] += 1.0/3.0; break;}
01075 case 18: {dofPos[0] += 0.0/3.0; dofPos[1] += 0.0/3.0; dofPos[2] += 2.0/3.0; break;}
01076 case 19: {dofPos[0] += 1.0/3.0; dofPos[1] += 0.0/3.0; dofPos[2] += 2.0/3.0; break;}
01077 case 20: {dofPos[0] += 2.0/3.0; dofPos[1] += 0.0/3.0; dofPos[2] += 2.0/3.0; break;}
01078 case 21: {dofPos[0] += 0.0/3.0; dofPos[1] += 1.0/3.0; dofPos[2] += 2.0/3.0; break;}
01079 case 22: {dofPos[0] += 1.0/3.0; dofPos[1] += 1.0/3.0; dofPos[2] += 2.0/3.0; break;}
01080 case 23: {dofPos[0] += 2.0/3.0; dofPos[1] += 1.0/3.0; dofPos[2] += 2.0/3.0; break;}
01081 case 24: {dofPos[0] += 0.0/3.0; dofPos[1] += 2.0/3.0; dofPos[2] += 2.0/3.0; break;}
01082 case 25: {dofPos[0] += 1.0/3.0; dofPos[1] += 2.0/3.0; dofPos[2] += 2.0/3.0; break;}
01083 case 26: {dofPos[0] += 2.0/3.0; dofPos[1] += 2.0/3.0; dofPos[2] += 2.0/3.0; break;}
01084 }
01085 break;}
01086 case 8:{
01087 dofPos = dofPos/2.0;
01088 SUNDANCE_OUT(this->verb() > 3 , "dofPos=" << dofPos );
01089 switch (indexInParent){
01090 case 0: {dofPos[0] += 0.0/2.0; dofPos[1] += 0.0/2.0; dofPos[2] += 0.0/2.0; break;}
01091 case 1: {dofPos[0] += 1.0/2.0; dofPos[1] += 0.0/2.0; dofPos[2] += 0.0/2.0; break;}
01092 case 2: {dofPos[0] += 0.0/2.0; dofPos[1] += 1.0/2.0; dofPos[2] += 0.0/2.0; break;}
01093 case 3: {dofPos[0] += 1.0/2.0; dofPos[1] += 1.0/2.0; dofPos[2] += 0.0/2.0; break;}
01094 case 4: {dofPos[0] += 0.0/2.0; dofPos[1] += 0.0/2.0; dofPos[2] += 1.0/2.0; break;}
01095 case 5: {dofPos[0] += 1.0/2.0; dofPos[1] += 0.0/2.0; dofPos[2] += 1.0/2.0; break;}
01096 case 6: {dofPos[0] += 0.0/2.0; dofPos[1] += 1.0/2.0; dofPos[2] += 1.0/2.0; break;}
01097 case 7: {dofPos[0] += 1.0/2.0; dofPos[1] += 1.0/2.0; dofPos[2] += 1.0/2.0; break;}
01098 }
01099 break;}
01100 }
01101
01102 SUNDANCE_OUT(this->verb() > 3 , "dofPos=" << dofPos );
01103 Array<Point> tmp_points(1);
01104 tmp_points[0] = dofPos;
01105 refEval( maximalCellType , tmp_points ,
01106 deriv, result , 4);
01107
01108 break;}
01109 }
01110
01111
01112 Array<double>& res = result[0][0];
01113
01114
01115
01116 if (doFInfromationCalculated_ == false)
01117 {
01118 getDoFsOrdered( maximalCellType, res.size() , facetD_, facetI_, facetN_);
01119 doFInfromationCalculated_ = true;
01120 }
01121
01122
01123 index = 0;
01124 for ( int i=0 ; i < res.size() ; i++){
01125
01126 if ( fabs(res[i]) > 1e-5 ){
01127 SUNDANCE_OUT(this->verb() > 3 , "found DoF i=" << i );
01128 localDoFs.resize(index+1);
01129 coefs.resize(index+1);
01130 parentFacetDim.resize(index+1);
01131 parentFacetIndex.resize(index+1);
01132 parentFacetNode.resize(index+1);
01133 localDoFs[index] = i;
01134 coefs[index] = res[i];
01135 parentFacetDim[index] = facetD_[i];
01136 parentFacetIndex[index] = facetI_[i];
01137 parentFacetNode[index] = facetN_[i];
01138 index++;
01139 }
01140 }
01141
01142 SUNDANCE_OUT(this->verb() > 3 , "localDoFs=" << localDoFs );
01143 SUNDANCE_OUT(this->verb() > 3 , "coefs=" << coefs );
01144 SUNDANCE_OUT(this->verb() > 3 , "parentFacetDim=" << parentFacetDim );
01145 SUNDANCE_OUT(this->verb() > 3 , "parentFacetIndex=" << parentFacetIndex );
01146 SUNDANCE_OUT(this->verb() > 3 , "parentFacetNode=" << parentFacetNode );
01147
01148 }
01149
01150
01151 void Lagrange::returnDoFPositionOnRef(
01152 const int maxCellDim,
01153 const int facetDim,
01154 const int facetIndex,
01155 const int nodeIndex,
01156 Point& pos) const {
01157
01158 switch (facetDim){
01159 case 0:{
01160 switch (maxCellDim){
01161 case 2:{
01162 switch (facetIndex){
01163 case 0: {pos[0] = 0.0; pos[1] = 0.0; break;}
01164 case 1: {pos[0] = 1.0; pos[1] = 0.0; break;}
01165 case 2: {pos[0] = 0.0; pos[1] = 1.0; break;}
01166 case 3: {pos[0] = 1.0; pos[1] = 1.0; break;}
01167 }
01168 break;}
01169 case 3:{
01170 switch (facetIndex){
01171 case 0: {pos[0] = 0.0; pos[1] = 0.0; pos[2] = 0.0; break;}
01172 case 1: {pos[0] = 1.0; pos[1] = 0.0; pos[2] = 0.0; break;}
01173 case 2: {pos[0] = 0.0; pos[1] = 1.0; pos[2] = 0.0; break;}
01174 case 3: {pos[0] = 1.0; pos[1] = 1.0; pos[2] = 0.0; break;}
01175 case 4: {pos[0] = 0.0; pos[1] = 0.0; pos[2] = 1.0; break;}
01176 case 5: {pos[0] = 1.0; pos[1] = 0.0; pos[2] = 1.0; break;}
01177 case 6: {pos[0] = 0.0; pos[1] = 1.0; pos[2] = 1.0; break;}
01178 case 7: {pos[0] = 1.0; pos[1] = 1.0; pos[2] = 1.0; break;}
01179 }
01180 break;}
01181 }
01182 break;}
01183 case 1:{
01184 switch (maxCellDim){
01185 case 2:{
01186
01187 double posOnEdge = (1.0/ (double)(order())) +(double)(nodeIndex) / (double)(order()-1);
01188 switch (facetIndex){
01189 case 0: {pos[0] = 0.0+posOnEdge; pos[1] = 0.0; break;}
01190 case 1: {pos[0] = 0.0; pos[1] = 0.0+posOnEdge; break;}
01191 case 2: {pos[0] = 1.0; pos[1] = 0.0+posOnEdge; break;}
01192 case 3: {pos[0] = 0.0+posOnEdge; pos[1] = 1.0; break;}
01193 }
01194 break;}
01195 case 3:{
01196 double posOnEdge = (1.0/ (double)(order())) +(double)(nodeIndex) / (double)(order()-1);
01197 switch (facetIndex){
01198 case 0: {pos[0] = 0.0+posOnEdge; pos[1] = 0.0; pos[2] = 0.0; break;}
01199 case 1: {pos[0] = 0.0; pos[1] = 0.0+posOnEdge; pos[2] = 0.0; break;}
01200 case 2: {pos[0] = 0.0; pos[1] = 0.0; pos[2] = 0.0+posOnEdge; break;}
01201 case 3: {pos[0] = 1.0; pos[1] = 0.0+posOnEdge; pos[2] = 0.0; break;}
01202 case 4: {pos[0] = 1.0; pos[1] = 0.0; pos[2] = 0.0+posOnEdge; break;}
01203 case 5: {pos[0] = 0.0+posOnEdge; pos[1] = 1.0; pos[2] = 0.0; break;}
01204 case 6: {pos[0] = 0.0; pos[1] = 1.0; pos[2] = 0.0+posOnEdge; break;}
01205 case 7: {pos[0] = 1.0; pos[1] = 1.0; pos[2] = 0.0+posOnEdge; break;}
01206 case 8: {pos[0] = 0.0+posOnEdge; pos[1] = 0.0; pos[2] = 1.0; break;}
01207 case 9: {pos[0] = 0.0; pos[1] = 0.0+posOnEdge; pos[2] = 1.0; break;}
01208 case 10: {pos[0] = 1.0; pos[1] = 0.0+posOnEdge; pos[2] = 1.0; break;}
01209 case 11: {pos[0] = 0.0+posOnEdge; pos[1] = 1.0; pos[2] = 1.0; break;}
01210 }
01211 break;}
01212 }
01213 break;}
01214 case 2:{
01215
01216 int nrDoFoFace = (order()-1)*(order()-1);
01217 double posOnFace1 = (1.0/ (double)(order())) +(double)(nodeIndex % nrDoFoFace) / (double)(order()-1);
01218 double posOnFace2 = (1.0/ (double)(order())) +(double)(nodeIndex / nrDoFoFace) / (double)(order()-1);
01219 switch (facetIndex){
01220 case 0: {pos[0] = 0.0+posOnFace1; pos[1] = 0.0+posOnFace2; pos[2] = 0.0; break;}
01221 case 1: {pos[0] = 0.0+posOnFace1; pos[1] = 0.0; pos[2] = 0.0+posOnFace2; break;}
01222 case 2: {pos[0] = 0.0; pos[1] = 0.0+posOnFace1; pos[2] = 0.0+posOnFace2; break;}
01223 case 3: {pos[0] = 1.0; pos[1] = 0.0+posOnFace1; pos[2] = 0.0+posOnFace2; break;}
01224 case 4: {pos[0] = 0.0+posOnFace1; pos[1] = 1.0; pos[2] = 0.0+posOnFace2; break;}
01225 case 5: {pos[0] = 0.0+posOnFace1; pos[1] = 0.0+posOnFace2; pos[2] = 1.0; break;}
01226 }
01227 break;}
01228 }
01229
01230 }
01231
01232 void Lagrange::getDoFsOrdered(
01233 const CellType maxCellDim,
01234 int nrDoF,
01235 Array<int>& facetD,
01236 Array<int>& facetI,
01237 Array<int>& facetN)
01238 {
01239
01240
01241 Array<Array<Array<int> > > dofs_struct;
01242 getReferenceDOFs(maxCellDim , maxCellDim , dofs_struct);
01243 bool getNext;
01244 facetD.resize(nrDoF); facetI.resize(nrDoF); facetN.resize(nrDoF);
01245 int dimo=0 , indexo=0 , nodo=0;
01246 for ( int i=0 ; i < nrDoF ; i++){
01247 facetD[i] = dimo;
01248 facetI[i] = indexo;
01249 facetN[i] = nodo;
01250
01251
01252 getNext = true;
01253 while ( (getNext) && (dimo < dofs_struct.size() )){
01254
01255
01256 if (dofs_struct[dimo].size() > (indexo+1))
01257 {
01258 if (dofs_struct[dimo][indexo].size() > (nodo+1)){
01259 nodo++; getNext = false;
01260 }else{
01261 nodo = 0;
01262 if (dofs_struct[dimo].size() > (indexo+1)){
01263 indexo++; getNext = false;
01264 }else{
01265 indexo = 0;
01266 if (dofs_struct.size() > (dimo+1)){
01267 dimo++; getNext = false;
01268 }else{
01269
01270 getNext = false;
01271 }
01272 }
01273 }
01274 }
01275 else
01276 {
01277 dimo++; indexo = 0; nodo = 0; getNext = false;
01278 }
01279
01280
01281 if (dofs_struct.size() <= dimo ) {dimo++; getNext = true; continue;}
01282 if (dofs_struct[dimo].size() <= indexo ) {dimo++; getNext = true; continue;}
01283 if (dofs_struct[dimo][indexo].size() <= nodo ) {dimo++; getNext = true; continue;}
01284 }
01285 }
01286 SUNDANCE_OUT(this->verb() > 3, "facetD=" << facetD );
01287 SUNDANCE_OUT(this->verb() > 3, "facetI=" << facetI );
01288 SUNDANCE_OUT(this->verb() > 3, "facetN=" << facetN );
01289
01290 }