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
00037 namespace Intrepid {
00038
00039 template<class Scalar>
00040 const FieldContainer<double>& CellTools<Scalar>::getSubcellParametrization(const int subcellDim,
00041 const shards::CellTopology& parentCell){
00042
00043 #ifdef HAVE_INTREPID_DEBUG
00044 TEST_FOR_EXCEPTION( !(hasReferenceCell(parentCell) ), std::invalid_argument,
00045 ">>> ERROR (Intrepid::CellTools::getSubcellParametrization): the specified cell topology does not have a reference cell.");
00046
00047 TEST_FOR_EXCEPTION( !( (1 <= subcellDim) && (subcellDim <= 2 ) ), std::invalid_argument,
00048 ">>> ERROR (Intrepid::CellTools::getSubcellParametrization): parametrization defined only for 1 and 2-dimensional subcells.");
00049 #endif
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 static FieldContainer<double> lineEdges; static int lineEdgesSet = 0;
00068
00069
00070 static FieldContainer<double> triEdges; static int triEdgesSet = 0;
00071 static FieldContainer<double> quadEdges; static int quadEdgesSet = 0;
00072
00073
00074 static FieldContainer<double> shellTriEdges; static int shellTriEdgesSet = 0;
00075 static FieldContainer<double> shellQuadEdges; static int shellQuadEdgesSet = 0;
00076
00077
00078 static FieldContainer<double> tetEdges; static int tetEdgesSet = 0;
00079 static FieldContainer<double> hexEdges; static int hexEdgesSet = 0;
00080 static FieldContainer<double> pyrEdges; static int pyrEdgesSet = 0;
00081 static FieldContainer<double> wedgeEdges; static int wedgeEdgesSet = 0;
00082
00083
00084
00085 static FieldContainer<double> shellTriFaces; static int shellTriFacesSet = 0;
00086 static FieldContainer<double> shellQuadFaces; static int shellQuadFacesSet = 0;
00087
00088
00089 static FieldContainer<double> tetFaces; static int tetFacesSet = 0;
00090 static FieldContainer<double> hexFaces; static int hexFacesSet = 0;
00091 static FieldContainer<double> pyrFaces; static int pyrFacesSet = 0;
00092 static FieldContainer<double> wedgeFaces; static int wedgeFacesSet = 0;
00093
00094
00095 switch(parentCell.getKey() ) {
00096
00097
00098 case shards::Tetrahedron<4>::key:
00099 case shards::Tetrahedron<8>::key:
00100 case shards::Tetrahedron<10>::key:
00101 if(subcellDim == 2) {
00102 if(!tetFacesSet){
00103 setSubcellParametrization(tetFaces, subcellDim, parentCell);
00104 tetFacesSet = 1;
00105 }
00106 return tetFaces;
00107 }
00108 else if(subcellDim == 1) {
00109 if(!tetEdgesSet){
00110 setSubcellParametrization(tetEdges, subcellDim, parentCell);
00111 tetEdgesSet = 1;
00112 }
00113 return tetEdges;
00114 }
00115 else{
00116 TEST_FOR_EXCEPTION( (subcellDim != 1 || subcellDim != 2), std::invalid_argument,
00117 ">>> ERROR (Intrepid::CellTools::getSubcellParametrization): Tet parametrizations defined for 1 and 2-subcells only");
00118 }
00119 break;
00120
00121
00122 case shards::Hexahedron<8>::key:
00123 case shards::Hexahedron<20>::key:
00124 case shards::Hexahedron<27>::key:
00125 if(subcellDim == 2) {
00126 if(!hexFacesSet){
00127 setSubcellParametrization(hexFaces, subcellDim, parentCell);
00128 hexFacesSet = 1;
00129 }
00130 return hexFaces;
00131 }
00132 else if(subcellDim == 1) {
00133 if(!hexEdgesSet){
00134 setSubcellParametrization(hexEdges, subcellDim, parentCell);
00135 hexEdgesSet = 1;
00136 }
00137 return hexEdges;
00138 }
00139 else{
00140 TEST_FOR_EXCEPTION( (subcellDim != 1 || subcellDim != 2), std::invalid_argument,
00141 ">>> ERROR (Intrepid::CellTools::getSubcellParametrization): Hex parametrizations defined for 1 and 2-subcells only");
00142 }
00143 break;
00144
00145
00146 case shards::Pyramid<5>::key:
00147 case shards::Pyramid<13>::key:
00148 case shards::Pyramid<14>::key:
00149 if(subcellDim == 2) {
00150 if(!pyrFacesSet){
00151 setSubcellParametrization(pyrFaces, subcellDim, parentCell);
00152 pyrFacesSet = 1;
00153 }
00154 return pyrFaces;
00155 }
00156 else if(subcellDim == 1) {
00157 if(!pyrEdgesSet){
00158 setSubcellParametrization(pyrEdges, subcellDim, parentCell);
00159 pyrEdgesSet = 1;
00160 }
00161 return pyrEdges;
00162 }
00163 else {
00164 TEST_FOR_EXCEPTION( (subcellDim != 1 || subcellDim != 2), std::invalid_argument,
00165 ">>> ERROR (Intrepid::CellTools::getSubcellParametrization): Pyramid parametrizations defined for 1 and 2-subcells only");
00166 }
00167 break;
00168
00169
00170 case shards::Wedge<6>::key:
00171 case shards::Wedge<15>::key:
00172 case shards::Wedge<18>::key:
00173 if(subcellDim == 2) {
00174 if(!wedgeFacesSet){
00175 setSubcellParametrization(wedgeFaces, subcellDim, parentCell);
00176 wedgeFacesSet = 1;
00177 }
00178 return wedgeFaces;
00179 }
00180 else if(subcellDim == 1) {
00181 if(!wedgeEdgesSet){
00182 setSubcellParametrization(wedgeEdges, subcellDim, parentCell);
00183 wedgeEdgesSet = 1;
00184 }
00185 return wedgeEdges;
00186 }
00187 else {
00188 TEST_FOR_EXCEPTION( (subcellDim != 1 || subcellDim != 2), std::invalid_argument,
00189 ">>> ERROR (Intrepid::CellTools::getSubcellParametrization): Wedge parametrization defined for 1 and 2-subcells only");
00190 }
00191 break;
00192
00193
00194
00195 case shards::Triangle<3>::key:
00196 case shards::Triangle<4>::key:
00197 case shards::Triangle<6>::key:
00198 if(subcellDim == 1) {
00199 if(!triEdgesSet){
00200 setSubcellParametrization(triEdges, subcellDim, parentCell);
00201 triEdgesSet = 1;
00202 }
00203 return triEdges;
00204 }
00205 else{
00206 TEST_FOR_EXCEPTION( true, std::invalid_argument,
00207 ">>> ERROR (Intrepid::CellTools::getSubcellParametrization): Triangle parametrizations defined for 1-subcells only");
00208 }
00209 break;
00210
00211 case shards::Quadrilateral<4>::key:
00212 case shards::Quadrilateral<8>::key:
00213 case shards::Quadrilateral<9>::key:
00214 if(subcellDim == 1) {
00215 if(!quadEdgesSet){
00216 setSubcellParametrization(quadEdges, subcellDim, parentCell);
00217 quadEdgesSet = 1;
00218 }
00219 return quadEdges;
00220 }
00221 else{
00222 TEST_FOR_EXCEPTION( true, std::invalid_argument,
00223 ">>> ERROR (Intrepid::CellTools::getSubcellParametrization): Quad parametrizations defined for 1-subcells only");
00224 }
00225 break;
00226
00227
00228
00229
00230 case shards::ShellTriangle<3>::key:
00231 case shards::ShellTriangle<6>::key:
00232 if(subcellDim == 2) {
00233 if(!shellTriFacesSet){
00234 setSubcellParametrization(shellTriFaces, subcellDim, parentCell);
00235 shellTriFacesSet = 1;
00236 }
00237 return shellTriFaces;
00238 }
00239 else if(subcellDim == 1) {
00240 if(!shellTriEdgesSet){
00241 setSubcellParametrization(shellTriEdges, subcellDim, parentCell);
00242 shellTriEdgesSet = 1;
00243 }
00244 return shellTriEdges;
00245 }
00246 else if( subcellDim != 1 || subcellDim != 2){
00247 TEST_FOR_EXCEPTION( true, std::invalid_argument,
00248 ">>> ERROR (Intrepid::CellTools::getSubcellParametrization): Shell Triangle parametrizations defined for 1 and 2-subcells only");
00249 }
00250 break;
00251
00252 case shards::ShellQuadrilateral<4>::key:
00253 case shards::ShellQuadrilateral<8>::key:
00254 case shards::ShellQuadrilateral<9>::key:
00255 if(subcellDim == 2) {
00256 if(!shellQuadFacesSet){
00257 setSubcellParametrization(shellQuadFaces, subcellDim, parentCell);
00258 shellQuadFacesSet = 1;
00259 }
00260 return shellQuadFaces;
00261 }
00262 else if(subcellDim == 1) {
00263 if(!shellQuadEdgesSet){
00264 setSubcellParametrization(shellQuadEdges, subcellDim, parentCell);
00265 shellQuadEdgesSet = 1;
00266 }
00267 return shellQuadEdges;
00268 }
00269 else if( subcellDim != 1 || subcellDim != 2){
00270 TEST_FOR_EXCEPTION( true, std::invalid_argument,
00271 ">>> ERROR (Intrepid::CellTools::getSubcellParametrization): Shell Quad parametrizations defined for 1 and 2-subcells only");
00272 }
00273 break;
00274
00275
00276
00277
00278 case shards::ShellLine<2>::key:
00279 case shards::ShellLine<3>::key:
00280 case shards::Beam<2>::key:
00281 case shards::Beam<3>::key:
00282 if(subcellDim == 1) {
00283 if(!lineEdgesSet){
00284 setSubcellParametrization(lineEdges, subcellDim, parentCell);
00285 lineEdgesSet = 1;
00286 }
00287 return lineEdges;
00288 }
00289 else{
00290 TEST_FOR_EXCEPTION( true, std::invalid_argument,
00291 ">>> ERROR (Intrepid::CellTools::getSubcellParametrization): shell line/beam parametrizations defined for 1-subcells only");
00292 }
00293 break;
00294
00295 default:
00296 TEST_FOR_EXCEPTION( true, std::invalid_argument,
00297 ">>> ERROR (Intrepid::CellTools::getSubcellParametrization): invalid cell topology.");
00298 }
00299
00300 return lineEdges;
00301 }
00302
00303
00304
00305 template<class Scalar>
00306 void CellTools<Scalar>::setSubcellParametrization(FieldContainer<double>& subcellParametrization,
00307 const int subcellDim,
00308 const shards::CellTopology& parentCell)
00309 {
00310 #ifdef HAVE_INTREPID_DEBUG
00311 TEST_FOR_EXCEPTION( !(hasReferenceCell(parentCell) ), std::invalid_argument,
00312 ">>> ERROR (Intrepid::CellTools::setSubcellParametrization): the specified cell topology does not have a reference cell.");
00313
00314 TEST_FOR_EXCEPTION( !( (1 <= subcellDim) && (subcellDim <= 2 ) ), std::invalid_argument,
00315 ">>> ERROR (Intrepid::CellTools::setSubcellParametrization): parametrization defined only for 1 and 2-dimensional subcells.");
00316 #endif
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 unsigned sc = parentCell.getSubcellCount(subcellDim);
00336 unsigned pcd = parentCell.getDimension();
00337 unsigned coeff = (subcellDim == 1) ? 2 : 3;
00338
00339
00340
00341 subcellParametrization.resize(sc, pcd, coeff);
00342
00343
00344 if(subcellDim == 1){
00345 for(unsigned subcellOrd = 0; subcellOrd < sc; subcellOrd++){
00346
00347 int v0ord = parentCell.getNodeMap(subcellDim, subcellOrd, 0);
00348 int v1ord = parentCell.getNodeMap(subcellDim, subcellOrd, 1);
00349
00350
00351
00352 const double* v0 = getReferenceVertex(parentCell, v0ord);
00353 const double* v1 = getReferenceVertex(parentCell, v1ord);
00354
00355
00356 subcellParametrization(subcellOrd, 0, 0) = (v0[0] + v1[0])/2.0;
00357 subcellParametrization(subcellOrd, 0, 1) = (v1[0] - v0[0])/2.0;
00358
00359
00360 subcellParametrization(subcellOrd, 1, 0) = (v0[1] + v1[1])/2.0;
00361 subcellParametrization(subcellOrd, 1, 1) = (v1[1] - v0[1])/2.0;
00362
00363 if( pcd == 3 ) {
00364
00365 subcellParametrization(subcellOrd, 2, 0) = (v0[2] + v1[2])/2.0;
00366 subcellParametrization(subcellOrd, 2, 1) = (v1[2] - v0[2])/2.0;
00367 }
00368 }
00369 }
00370
00371
00372
00373
00374 else if(subcellDim == 2) {
00375 for(unsigned subcellOrd = 0; subcellOrd < sc; subcellOrd++){
00376
00377 switch(parentCell.getKey(subcellDim,subcellOrd)){
00378
00379
00380 case shards::Triangle<3>::key:
00381 case shards::Triangle<4>::key:
00382 case shards::Triangle<6>::key:
00383 {
00384 int v0ord = parentCell.getNodeMap(subcellDim, subcellOrd, 0);
00385 int v1ord = parentCell.getNodeMap(subcellDim, subcellOrd, 1);
00386 int v2ord = parentCell.getNodeMap(subcellDim, subcellOrd, 2);
00387 const double* v0 = getReferenceVertex(parentCell, v0ord);
00388 const double* v1 = getReferenceVertex(parentCell, v1ord);
00389 const double* v2 = getReferenceVertex(parentCell, v2ord);
00390
00391
00392 subcellParametrization(subcellOrd, 0, 0) = v0[0];
00393 subcellParametrization(subcellOrd, 0, 1) = v1[0] - v0[0];
00394 subcellParametrization(subcellOrd, 0, 2) = v2[0] - v0[0];
00395
00396
00397 subcellParametrization(subcellOrd, 1, 0) = v0[1];
00398 subcellParametrization(subcellOrd, 1, 1) = v1[1] - v0[1];
00399 subcellParametrization(subcellOrd, 1, 2) = v2[1] - v0[1];
00400
00401
00402 subcellParametrization(subcellOrd, 2, 0) = v0[2];
00403 subcellParametrization(subcellOrd, 2, 1) = v1[2] - v0[2];
00404 subcellParametrization(subcellOrd, 2, 2) = v2[2] - v0[2];
00405 }
00406 break;
00407
00408
00409 case shards::Quadrilateral<4>::key:
00410 case shards::Quadrilateral<8>::key:
00411 case shards::Quadrilateral<9>::key:
00412 {
00413 int v0ord = parentCell.getNodeMap(subcellDim, subcellOrd, 0);
00414 int v1ord = parentCell.getNodeMap(subcellDim, subcellOrd, 1);
00415 int v2ord = parentCell.getNodeMap(subcellDim, subcellOrd, 2);
00416 int v3ord = parentCell.getNodeMap(subcellDim, subcellOrd, 3);
00417 const double* v0 = getReferenceVertex(parentCell, v0ord);
00418 const double* v1 = getReferenceVertex(parentCell, v1ord);
00419 const double* v2 = getReferenceVertex(parentCell, v2ord);
00420 const double* v3 = getReferenceVertex(parentCell, v3ord);
00421
00422
00423 subcellParametrization(subcellOrd, 0, 0) = ( v0[0] + v1[0] + v2[0] + v3[0])/4.0;
00424 subcellParametrization(subcellOrd, 0, 1) = (-v0[0] + v1[0] + v2[0] - v3[0])/4.0;
00425 subcellParametrization(subcellOrd, 0, 2) = (-v0[0] - v1[0] + v2[0] + v3[0])/4.0;
00426
00427
00428 subcellParametrization(subcellOrd, 1, 0) = ( v0[1] + v1[1] + v2[1] + v3[1])/4.0;
00429 subcellParametrization(subcellOrd, 1, 1) = (-v0[1] + v1[1] + v2[1] - v3[1])/4.0;
00430 subcellParametrization(subcellOrd, 1, 2) = (-v0[1] - v1[1] + v2[1] + v3[1])/4.0;
00431
00432
00433 subcellParametrization(subcellOrd, 2, 0) = ( v0[2] + v1[2] + v2[2] + v3[2])/4.0;
00434 subcellParametrization(subcellOrd, 2, 1) = (-v0[2] + v1[2] + v2[2] - v3[2])/4.0;
00435 subcellParametrization(subcellOrd, 2, 2) = (-v0[2] - v1[2] + v2[2] + v3[2])/4.0;
00436 }
00437 break;
00438 default:
00439 TEST_FOR_EXCEPTION( true, std::invalid_argument,
00440 ">>> ERROR (Intrepid::CellTools::setSubcellParametrization): parametrization not defined for the specified face topology.");
00441
00442 }
00443 }
00444 }
00445 }
00446
00447
00448
00449 template<class Scalar>
00450 const double* CellTools<Scalar>::getReferenceVertex(const shards::CellTopology& cell,
00451 const int vertexOrd){
00452
00453 #ifdef HAVE_INTREPID_DEBUG
00454 TEST_FOR_EXCEPTION( !(hasReferenceCell(cell) ), std::invalid_argument,
00455 ">>> ERROR (Intrepid::CellTools::getReferenceVertex): the specified cell topology does not have a reference cell.");
00456
00457 TEST_FOR_EXCEPTION( !( (0 <= vertexOrd) && (vertexOrd < (int)cell.getVertexCount() ) ), std::invalid_argument,
00458 ">>> ERROR (Intrepid::CellTools::getReferenceVertex): invalid node ordinal for the specified cell topology. ");
00459 #endif
00460
00461
00462 return getReferenceNode(cell.getBaseTopology(), vertexOrd);
00463 }
00464
00465
00466
00467 template<class Scalar>
00468 template<class ArrayOut>
00469 void CellTools<Scalar>::getReferenceSubcellVertices(ArrayOut& subcellVertices,
00470 const int subcellDim,
00471 const int subcellOrd,
00472 const shards::CellTopology& parentCell){
00473 #ifdef HAVE_INTREPID_DEBUG
00474 TEST_FOR_EXCEPTION( !(hasReferenceCell(parentCell) ), std::invalid_argument,
00475 ">>> ERROR (Intrepid::CellTools::getReferenceSubcellVertices): the specified cell topology does not have a reference cell.");
00476
00477
00478
00479 TEST_FOR_EXCEPTION( !( (0 <= subcellDim) && (subcellDim <= (int)parentCell.getDimension()) ), std::invalid_argument,
00480 ">>> ERROR (Intrepid::CellTools::getReferenceSubcellVertices): subcell dimension out of range.");
00481
00482 TEST_FOR_EXCEPTION( !( (0 <= subcellOrd) && (subcellOrd < (int)parentCell.getSubcellCount(subcellDim) ) ), std::invalid_argument,
00483 ">>> ERROR (Intrepid::CellTools::getReferenceSubcellVertices): subcell ordinal out of range.");
00484
00485
00486 {
00487 std::string errmsg = ">>> ERROR (Intrepid::CellTools::getReferenceSubcellVertices):";
00488 TEST_FOR_EXCEPTION( !( requireRankRange(errmsg, subcellVertices, 2, 2) ), std::invalid_argument, errmsg);
00489
00490 int subcVertexCount = parentCell.getVertexCount(subcellDim, subcellOrd);
00491 int spaceDim = parentCell.getDimension();
00492
00493 TEST_FOR_EXCEPTION( !( requireDimensionRange(errmsg, subcellVertices, 0, subcVertexCount, subcVertexCount) ),
00494 std::invalid_argument, errmsg);
00495
00496 TEST_FOR_EXCEPTION( !( requireDimensionRange(errmsg, subcellVertices, 1, spaceDim, spaceDim) ),
00497 std::invalid_argument, errmsg);
00498 }
00499 #endif
00500
00501
00502 getReferenceSubcellNodes(subcellVertices, subcellDim, subcellOrd, parentCell.getBaseTopology() );
00503 }
00504
00505
00506
00507 template<class Scalar>
00508 const double* CellTools<Scalar>::getReferenceNode(const shards::CellTopology& cell,
00509 const int nodeOrd){
00510
00511 #ifdef HAVE_INTREPID_DEBUG
00512 TEST_FOR_EXCEPTION( !(hasReferenceCell(cell) ), std::invalid_argument,
00513 ">>> ERROR (Intrepid::CellTools::getReferenceNode): the specified cell topology does not have a reference cell.");
00514
00515 TEST_FOR_EXCEPTION( !( (0 <= nodeOrd) && (nodeOrd < (int)cell.getNodeCount() ) ), std::invalid_argument,
00516 ">>> ERROR (Intrepid::CellTools::getReferenceNode): invalid node ordinal for the specified cell topology. ");
00517 #endif
00518
00519
00520
00521 static const double line[2][3] ={
00522 {-1.0, 0.0, 0.0}, { 1.0, 0.0, 0.0}
00523 };
00524 static const double line_3[3][3] = {
00525 {-1.0, 0.0, 0.0}, { 1.0, 0.0, 0.0},
00526
00527 { 0.0, 0.0, 0.0}
00528 };
00529
00530
00531
00532 static const double triangle[3][3] = {
00533 { 0.0, 0.0, 0.0}, { 1.0, 0.0, 0.0}, { 0.0, 1.0, 0.0}
00534 };
00535 static const double triangle_4[4][3] = {
00536 { 0.0, 0.0, 0.0}, { 1.0, 0.0, 0.0}, { 0.0, 1.0, 0.0},
00537
00538 { 1/3, 1/3, 0.0}
00539 };
00540 static const double triangle_6[6][3] = {
00541 { 0.0, 0.0, 0.0}, { 1.0, 0.0, 0.0}, { 0.0, 1.0, 0.0},
00542
00543 { 0.5, 0.0, 0.0}, { 0.5, 0.5, 0.0}, { 0.0, 0.5, 0.0}
00544 };
00545
00546
00547
00548 static const double quadrilateral[4][3] = {
00549 {-1.0,-1.0, 0.0}, { 1.0,-1.0, 0.0}, { 1.0, 1.0, 0.0}, {-1.0, 1.0, 0.0}
00550 };
00551 static const double quadrilateral_8[8][3] = {
00552 {-1.0,-1.0, 0.0}, { 1.0,-1.0, 0.0}, { 1.0, 1.0, 0.0}, {-1.0, 1.0, 0.0},
00553
00554 { 0.0,-1.0, 0.0}, { 1.0, 0.0, 0.0}, { 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0}
00555 };
00556 static const double quadrilateral_9[9][3] = {
00557 {-1.0,-1.0, 0.0}, { 1.0,-1.0, 0.0}, { 1.0, 1.0, 0.0}, {-1.0, 1.0, 0.0},
00558
00559 { 0.0,-1.0, 0.0}, { 1.0, 0.0, 0.0}, { 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0}, { 0.0, 0.0, 0.0}
00560 };
00561
00562
00563
00564 static const double tetrahedron[4][3] = {
00565 { 0.0, 0.0, 0.0}, { 1.0, 0.0, 0.0}, { 0.0, 1.0, 0.0}, { 0.0, 0.0, 1.0}
00566 };
00567 static const double tetrahedron_8[8][3] = {
00568 { 0.0, 0.0, 0.0}, { 1.0, 0.0, 0.0}, { 0.0, 1.0, 0.0}, { 0.0, 0.0, 1.0},
00569
00570 { 1/3, 0.0, 1/3}, { 1/3, 1/3, 1/3}, { 1/3, 1/3, 0.0}, { 0.0, 1/3, 1/3}
00571 };
00572 static const double tetrahedron_10[10][3] = {
00573 { 0.0, 0.0, 0.0}, { 1.0, 0.0, 0.0}, { 0.0, 1.0, 0.0}, { 0.0, 0.0, 1.0},
00574
00575 { 0.5, 0.0, 0.0}, { 0.5, 0.5, 0.0}, { 0.0, 0.5, 0.0}, { 0.0, 0.0, 0.5}, { 0.5, 0.0, 0.5}, { 0.0, 0.5, 0.5}
00576 };
00577
00578
00579
00580 static const double hexahedron[8][3] = {
00581 {-1.0,-1.0,-1.0}, { 1.0,-1.0,-1.0}, { 1.0, 1.0,-1.0}, {-1.0, 1.0,-1.0},
00582 {-1.0,-1.0, 1.0}, { 1.0,-1.0, 1.0}, { 1.0, 1.0, 1.0}, {-1.0, 1.0, 1.0}
00583 };
00584 static const double hexahedron_20[20][3] = {
00585 {-1.0,-1.0,-1.0}, { 1.0,-1.0,-1.0}, { 1.0, 1.0,-1.0}, {-1.0, 1.0,-1.0},
00586 {-1.0,-1.0, 1.0}, { 1.0,-1.0, 1.0}, { 1.0, 1.0, 1.0}, {-1.0, 1.0, 1.0},
00587
00588 { 0.0,-1.0,-1.0}, { 1.0, 0.0,-1.0}, { 0.0, 1.0,-1.0}, {-1.0, 0.0,-1.0},
00589 {-1.0,-1.0, 0.0}, { 1.0,-1.0, 0.0}, { 1.0, 1.0, 0.0}, {-1.0, 1.0, 0.0},
00590 { 0.0,-1.0, 1.0}, { 1.0, 0.0, 1.0}, { 0.0, 1.0, 1.0}, {-1.0, 0.0, 1.0}
00591 };
00592 static const double hexahedron_27[27][3] = {
00593 {-1.0,-1.0,-1.0}, { 1.0,-1.0,-1.0}, { 1.0, 1.0,-1.0}, {-1.0, 1.0,-1.0},
00594 {-1.0,-1.0, 1.0}, { 1.0,-1.0, 1.0}, { 1.0, 1.0, 1.0}, {-1.0, 1.0, 1.0},
00595
00596 { 0.0,-1.0,-1.0}, { 1.0, 0.0,-1.0}, { 0.0, 1.0,-1.0}, {-1.0, 0.0,-1.0},
00597 {-1.0,-1.0, 0.0}, { 1.0,-1.0, 0.0}, { 1.0, 1.0, 0.0}, {-1.0, 1.0, 0.0},
00598 { 0.0,-1.0, 1.0}, { 1.0, 0.0, 1.0}, { 0.0, 1.0, 1.0}, {-1.0, 0.0, 1.0},
00599 { 0.0, 0.0, 0.0},
00600 { 0.0, 0.0,-1.0}, { 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0}, { 1.0, 0.0, 0.0}, {0.0,-1.0, 0.0}, {0.0, 1.0, 0.0}
00601 };
00602
00603
00604
00605 static const double pyramid[5][3] = {
00606 {-1.0,-1.0, 0.0}, { 1.0,-1.0, 0.0}, { 1.0, 1.0, 0.0}, {-1.0, 1.0, 0.0}, { 0.0, 0.0, 1.0}
00607 };
00608 static const double pyramid_13[13][3] = {
00609 {-1.0,-1.0, 0.0}, { 1.0,-1.0, 0.0}, { 1.0, 1.0, 0.0}, {-1.0, 1.0, 0.0}, { 0.0, 0.0, 1.0},
00610
00611 { 0.0,-1.0, 0.0}, { 1.0, 0.0, 0.0}, { 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0},
00612 {-0.5,-0.5, 0.5}, { 0.5,-0.5, 0.5}, { 0.5, 0.5, 0.5}, {-0.5, 0.5, 0.5}
00613 };
00614 static const double pyramid_14[14][3] = {
00615 {-1.0,-1.0, 0.0}, { 1.0,-1.0, 0.0}, { 1.0, 1.0, 0.0}, {-1.0, 1.0, 0.0}, { 0.0, 0.0, 1.0},
00616
00617 { 0.0,-1.0, 0.0}, { 1.0, 0.0, 0.0}, { 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0},
00618 {-0.5,-0.5, 0.5}, { 0.5,-0.5, 0.5}, { 0.5, 0.5, 0.5}, {-0.5, 0.5, 0.5}, { 0.0, 0.0, 0.0}
00619 };
00620
00621
00622
00623 static const double wedge[6][3] = {
00624 { 0.0, 0.0,-1.0}, { 1.0, 0.0,-1.0}, { 0.0, 1.0,-1.0}, { 0.0, 0.0, 1.0}, { 1.0, 0.0, 1.0}, { 0.0, 1.0, 1.0}
00625 };
00626 static const double wedge_15[15][3] = {
00627 { 0.0, 0.0,-1.0}, { 1.0, 0.0,-1.0}, { 0.0, 1.0,-1.0}, { 0.0, 0.0, 1.0}, { 1.0, 0.0, 1.0}, { 0.0, 1.0, 1.0},
00628
00629 { 0.5, 0.0,-1.0}, { 0.5, 0.5,-1.0}, { 0.0, 0.5,-1.0}, { 0.0, 0.0, 0.0}, { 1.0, 0.0, 0.0}, { 0.0, 1.0, 0.0},
00630 { 0.5, 0.0, 1.0}, { 0.5, 0.5, 1.0}, { 0.0, 0.5, 1.0}
00631 };
00632 static const double wedge_18[18][3] = {
00633 { 0.0, 0.0,-1.0}, { 1.0, 0.0,-1.0}, { 0.0, 1.0,-1.0}, { 0.0, 0.0, 1.0}, { 1.0, 0.0, 1.0}, { 0.0, 1.0, 1.0},
00634
00635 { 0.5, 0.0,-1.0}, { 0.5, 0.5,-1.0}, { 0.0, 0.5,-1.0}, { 0.0, 0.0, 0.0}, { 1.0, 0.0, 0.0}, { 0.0, 1.0, 0.0},
00636 { 0.5, 0.0, 1.0}, { 0.5, 0.5, 1.0}, { 0.0, 0.5, 1.0},
00637 { 0.5, 0.0, 0.0}, { 0.5, 0.5, 0.0}, { 0.0, 0.5, 0.0}
00638 };
00639
00640
00641 switch(cell.getKey() ) {
00642
00643
00644 case shards::Line<2>::key:
00645 case shards::ShellLine<2>::key:
00646 case shards::Beam<2>::key:
00647 return line[nodeOrd];
00648 break;
00649
00650
00651 case shards::Line<3>::key:
00652 case shards::ShellLine<3>::key:
00653 case shards::Beam<3>::key:
00654 return line_3[nodeOrd];
00655 break;
00656
00657
00658
00659 case shards::Triangle<3>::key:
00660 case shards::ShellTriangle<3>::key:
00661 return triangle[nodeOrd];
00662 break;
00663
00664
00665 case shards::Triangle<4>::key:
00666 return triangle_4[nodeOrd];
00667 break;
00668 case shards::Triangle<6>::key:
00669 case shards::ShellTriangle<6>::key:
00670 return triangle_6[nodeOrd];
00671 break;
00672
00673
00674
00675 case shards::Quadrilateral<4>::key:
00676 case shards::ShellQuadrilateral<4>::key:
00677 return quadrilateral[nodeOrd];
00678 break;
00679
00680
00681 case shards::Quadrilateral<8>::key:
00682 case shards::ShellQuadrilateral<8>::key:
00683 return quadrilateral_8[nodeOrd];
00684 break;
00685 case shards::Quadrilateral<9>::key:
00686 case shards::ShellQuadrilateral<9>::key:
00687 return quadrilateral_9[nodeOrd];
00688 break;
00689
00690
00691
00692 case shards::Tetrahedron<4>::key:
00693 return tetrahedron[nodeOrd];
00694 break;
00695
00696
00697 case shards::Tetrahedron<8>::key:
00698 return tetrahedron_8[nodeOrd];
00699 break;
00700 case shards::Tetrahedron<10>::key:
00701 return tetrahedron_10[nodeOrd];
00702 break;
00703
00704
00705
00706 case shards::Hexahedron<8>::key:
00707 return hexahedron[nodeOrd];
00708 break;
00709
00710
00711 case shards::Hexahedron<20>::key:
00712 return hexahedron_20[nodeOrd];
00713 break;
00714 case shards::Hexahedron<27>::key:
00715 return hexahedron_27[nodeOrd];
00716 break;
00717
00718
00719
00720 case shards::Pyramid<5>::key:
00721 return pyramid[nodeOrd];
00722 break;
00723
00724
00725 case shards::Pyramid<13>::key:
00726 return pyramid_13[nodeOrd];
00727 break;
00728 case shards::Pyramid<14>::key:
00729 return pyramid_14[nodeOrd];
00730 break;
00731
00732
00733
00734 case shards::Wedge<6>::key:
00735 return wedge[nodeOrd];
00736 break;
00737
00738
00739 case shards::Wedge<15>::key:
00740 return wedge_15[nodeOrd];
00741 break;
00742 case shards::Wedge<18>::key:
00743 return wedge_18[nodeOrd];
00744 break;
00745
00746 default:
00747 TEST_FOR_EXCEPTION( true, std::invalid_argument,
00748 ">>> ERROR (Intrepid::CellTools::getReferenceNode): invalid cell topology.");
00749 }
00750
00751 return line[0];
00752 }
00753
00754
00755
00756 template<class Scalar>
00757 template<class ArrayOut>
00758 void CellTools<Scalar>::getReferenceSubcellNodes(ArrayOut& subcellNodes,
00759 const int subcellDim,
00760 const int subcellOrd,
00761 const shards::CellTopology& parentCell){
00762 #ifdef HAVE_INTREPID_DEBUG
00763 TEST_FOR_EXCEPTION( !(hasReferenceCell(parentCell) ), std::invalid_argument,
00764 ">>> ERROR (Intrepid::CellTools::getReferenceSubcellNodes): the specified cell topology does not have a reference cell.");
00765
00766
00767
00768 TEST_FOR_EXCEPTION( !( (0 <= subcellDim) && (subcellDim <= (int)parentCell.getDimension()) ), std::invalid_argument,
00769 ">>> ERROR (Intrepid::CellTools::getReferenceSubcellNodes): subcell dimension out of range.");
00770
00771 TEST_FOR_EXCEPTION( !( (0 <= subcellOrd) && (subcellOrd < (int)parentCell.getSubcellCount(subcellDim) ) ), std::invalid_argument,
00772 ">>> ERROR (Intrepid::CellTools::getReferenceSubcellNodes): subcell ordinal out of range.");
00773
00774
00775 {
00776 std::string errmsg = ">>> ERROR (Intrepid::CellTools::getReferenceSubcellNodes):";
00777 TEST_FOR_EXCEPTION( !( requireRankRange(errmsg, subcellNodes, 2, 2) ), std::invalid_argument, errmsg);
00778
00779 int subcNodeCount = parentCell.getNodeCount(subcellDim, subcellOrd);
00780 int spaceDim = parentCell.getDimension();
00781
00782 TEST_FOR_EXCEPTION( !( requireDimensionRange(errmsg, subcellNodes, 0, subcNodeCount, subcNodeCount) ),
00783 std::invalid_argument, errmsg);
00784
00785 TEST_FOR_EXCEPTION( !( requireDimensionRange(errmsg, subcellNodes, 1, spaceDim, spaceDim) ),
00786 std::invalid_argument, errmsg);
00787 }
00788 #endif
00789
00790
00791 int subcNodeCount = parentCell.getNodeCount(subcellDim, subcellOrd);
00792
00793
00794 for(int subcNodeOrd = 0; subcNodeOrd < subcNodeCount; subcNodeOrd++){
00795
00796
00797 int cellNodeOrd = parentCell.getNodeMap(subcellDim, subcellOrd, subcNodeOrd);
00798
00799
00800 for(int dim = 0; dim < (int)parentCell.getDimension(); dim++){
00801 subcellNodes(subcNodeOrd, dim) = CellTools::getReferenceNode(parentCell, cellNodeOrd)[dim];
00802 }
00803 }
00804 }
00805
00806
00807
00808 template<class Scalar>
00809 int CellTools<Scalar>::hasReferenceCell(const shards::CellTopology& cell) {
00810
00811 switch(cell.getKey() ) {
00812 case shards::Line<2>::key:
00813 case shards::Line<3>::key:
00814 case shards::ShellLine<2>::key:
00815 case shards::ShellLine<3>::key:
00816 case shards::Beam<2>::key:
00817 case shards::Beam<3>::key:
00818
00819 case shards::Triangle<3>::key:
00820 case shards::Triangle<4>::key:
00821 case shards::Triangle<6>::key:
00822 case shards::ShellTriangle<3>::key:
00823 case shards::ShellTriangle<6>::key:
00824
00825 case shards::Quadrilateral<4>::key:
00826 case shards::Quadrilateral<8>::key:
00827 case shards::Quadrilateral<9>::key:
00828 case shards::ShellQuadrilateral<4>::key:
00829 case shards::ShellQuadrilateral<8>::key:
00830 case shards::ShellQuadrilateral<9>::key:
00831
00832 case shards::Tetrahedron<4>::key:
00833 case shards::Tetrahedron<8>::key:
00834 case shards::Tetrahedron<10>::key:
00835
00836 case shards::Hexahedron<8>::key:
00837 case shards::Hexahedron<20>::key:
00838 case shards::Hexahedron<27>::key:
00839
00840 case shards::Pyramid<5>::key:
00841 case shards::Pyramid<13>::key:
00842 case shards::Pyramid<14>::key:
00843
00844 case shards::Wedge<6>::key:
00845 case shards::Wedge<15>::key:
00846 case shards::Wedge<18>::key:
00847 return 1;
00848 break;
00849
00850 default:
00851 return 0;
00852 }
00853 return 0;
00854 }
00855
00856
00857
00858
00859
00860
00861
00862 template<class Scalar>
00863 template<class ArrayScalar>
00864 void CellTools<Scalar>::setJacobian(ArrayScalar & jacobian,
00865 const ArrayScalar & points,
00866 const ArrayScalar & cellWorkset,
00867 const shards::CellTopology & cellTopo,
00868 const int & whichCell)
00869 {
00870 INTREPID_VALIDATE( validateArguments_setJacobian(jacobian, points, cellWorkset, whichCell, cellTopo) );
00871
00872 int spaceDim = (int)cellTopo.getDimension();
00873 int numCells = cellWorkset.dimension(0);
00874
00875 int numPoints = (points.rank() == 2) ? points.dimension(0) : points.dimension(1);
00876
00877
00878 Teuchos::RCP< Basis< Scalar, FieldContainer<Scalar> > > HGRAD_Basis;
00879
00880
00881 switch( cellTopo.getKey() ){
00882
00883
00884 case shards::Line<2>::key:
00885 HGRAD_Basis = Teuchos::rcp( new Basis_HGRAD_LINE_C1_FEM<Scalar, FieldContainer<Scalar> >() );
00886 break;
00887
00888 case shards::Triangle<3>::key:
00889 HGRAD_Basis = Teuchos::rcp( new Basis_HGRAD_TRI_C1_FEM<Scalar, FieldContainer<Scalar> >() );
00890 break;
00891
00892 case shards::Quadrilateral<4>::key:
00893 HGRAD_Basis = Teuchos::rcp( new Basis_HGRAD_QUAD_C1_FEM<Scalar, FieldContainer<Scalar> >() );
00894 break;
00895
00896 case shards::Tetrahedron<4>::key:
00897 HGRAD_Basis = Teuchos::rcp( new Basis_HGRAD_TET_C1_FEM<Scalar, FieldContainer<Scalar> >() );
00898 break;
00899
00900 case shards::Hexahedron<8>::key:
00901 HGRAD_Basis = Teuchos::rcp( new Basis_HGRAD_HEX_C1_FEM<Scalar, FieldContainer<Scalar> >() );
00902 break;
00903
00904 case shards::Wedge<6>::key:
00905 HGRAD_Basis = Teuchos::rcp( new Basis_HGRAD_WEDGE_C1_FEM<Scalar, FieldContainer<Scalar> >() );
00906 break;
00907
00908
00909 case shards::Triangle<6>::key:
00910 HGRAD_Basis = Teuchos::rcp( new Basis_HGRAD_TRI_C2_FEM<Scalar, FieldContainer<Scalar> >() );
00911 break;
00912 case shards::Quadrilateral<9>::key:
00913 HGRAD_Basis = Teuchos::rcp( new Basis_HGRAD_QUAD_C2_FEM<Scalar, FieldContainer<Scalar> >() );
00914 break;
00915
00916 case shards::Tetrahedron<10>::key:
00917 HGRAD_Basis = Teuchos::rcp( new Basis_HGRAD_TET_C2_FEM<Scalar, FieldContainer<Scalar> >() );
00918 break;
00919
00920 case shards::Hexahedron<27>::key:
00921 HGRAD_Basis = Teuchos::rcp( new Basis_HGRAD_HEX_C2_FEM<Scalar, FieldContainer<Scalar> >() );
00922 break;
00923
00924 case shards::Wedge<18>::key:
00925 HGRAD_Basis = Teuchos::rcp( new Basis_HGRAD_WEDGE_C2_FEM<Scalar, FieldContainer<Scalar> >() );
00926 break;
00927
00928
00929 case shards::Quadrilateral<8>::key:
00930 case shards::Hexahedron<20>::key:
00931 case shards::Wedge<15>::key:
00932 TEST_FOR_EXCEPTION( (true), std::invalid_argument,
00933 ">>> ERROR (Intrepid::CellTools::setJacobian): Cell topology not supported. ");
00934 break;
00935
00936
00937 case shards::Line<3>::key:
00938 case shards::Beam<2>::key:
00939 case shards::Beam<3>::key:
00940 case shards::ShellLine<2>::key:
00941 case shards::ShellLine<3>::key:
00942 case shards::ShellTriangle<3>::key:
00943 case shards::ShellTriangle<6>::key:
00944 case shards::ShellQuadrilateral<4>::key:
00945 case shards::ShellQuadrilateral<8>::key:
00946 case shards::ShellQuadrilateral<9>::key:
00947 TEST_FOR_EXCEPTION( (true), std::invalid_argument,
00948 ">>> ERROR (Intrepid::CellTools::setJacobian): Cell topology not supported. ");
00949 break;
00950 default:
00951 TEST_FOR_EXCEPTION( (true), std::invalid_argument,
00952 ">>> ERROR (Intrepid::CellTools::setJacobian): Cell topology not supported.");
00953 }
00954
00955
00956 int basisCardinality = HGRAD_Basis -> getCardinality();
00957 FieldContainer<Scalar> basisGrads(basisCardinality, numPoints, spaceDim);
00958
00959
00960 for(int i = 0; i < jacobian.size(); i++){
00961 jacobian[i] = 0.0;
00962 }
00963
00964
00965 switch(points.rank()) {
00966
00967
00968 case 2:
00969 {
00970
00971 FieldContainer<Scalar> tempPoints( points.dimension(0), points.dimension(1) );
00972
00973 for(int pt = 0; pt < points.dimension(0); pt++){
00974 for(int dm = 0; dm < points.dimension(1) ; dm++){
00975 tempPoints(pt, dm) = points(pt, dm);
00976 }
00977 }
00978 HGRAD_Basis -> getValues(basisGrads, tempPoints, OPERATOR_GRAD);
00979
00980
00981
00982 int cellLoop = (whichCell == -1) ? numCells : 1 ;
00983
00984 for(int cellOrd = 0; cellOrd < cellLoop; cellOrd++) {
00985 for(int pointOrd = 0; pointOrd < numPoints; pointOrd++) {
00986 for(int row = 0; row < spaceDim; row++){
00987 for(int col = 0; col < spaceDim; col++){
00988
00989
00990 for(int bfOrd = 0; bfOrd < basisCardinality; bfOrd++){
00991
00992 if(whichCell == -1) {
00993 jacobian(cellOrd, pointOrd, row, col) += cellWorkset(cellOrd, bfOrd, row)*basisGrads(bfOrd, pointOrd, col);
00994 }
00995 else {
00996 jacobian(pointOrd, row, col) += cellWorkset(whichCell, bfOrd, row)*basisGrads(bfOrd, pointOrd, col);
00997 }
00998 }
00999 }
01000 }
01001 }
01002 }
01003 }
01004 break;
01005
01006
01007 case 3:
01008 {
01009
01010 FieldContainer<Scalar> tempPoints( points.dimension(1), points.dimension(2) );
01011
01012 for(int cellOrd = 0; cellOrd < numCells; cellOrd++) {
01013
01014
01015 for(int pt = 0; pt < points.dimension(1); pt++){
01016 for(int dm = 0; dm < points.dimension(2) ; dm++){
01017 tempPoints(pt, dm) = points(cellOrd, pt, dm);
01018 }
01019 }
01020
01021
01022 HGRAD_Basis -> getValues(basisGrads, tempPoints, OPERATOR_GRAD);
01023
01024
01025 for(int pointOrd = 0; pointOrd < numPoints; pointOrd++) {
01026 for(int row = 0; row < spaceDim; row++){
01027 for(int col = 0; col < spaceDim; col++){
01028
01029
01030 for(int bfOrd = 0; bfOrd < basisCardinality; bfOrd++){
01031 jacobian(cellOrd, pointOrd, row, col) += cellWorkset(cellOrd, bfOrd, row)*basisGrads(bfOrd, pointOrd, col);
01032 }
01033 }
01034 }
01035 }
01036 }
01037 }
01038
01039 break;
01040
01041 default:
01042 TEST_FOR_EXCEPTION( !( (points.rank() == 2) && (points.rank() == 3) ), std::invalid_argument,
01043 ">>> ERROR (Intrepid::CellTools::setJacobian): rank 2 or 3 required for points array. ");
01044 }
01045 }
01046
01047
01048
01049 template<class Scalar>
01050 template<class ArrayScalar>
01051 void CellTools<Scalar>::setJacobianInv(ArrayScalar & jacobianInv,
01052 const ArrayScalar & jacobian)
01053 {
01054 INTREPID_VALIDATE( validateArguments_setJacobianInv(jacobianInv, jacobian) );
01055
01056 RealSpaceTools<Scalar>::inverse(jacobianInv, jacobian);
01057 }
01058
01059
01060
01061 template<class Scalar>
01062 template<class ArrayScalar>
01063 void CellTools<Scalar>::setJacobianDet(ArrayScalar & jacobianDet,
01064 const ArrayScalar & jacobian)
01065 {
01066 INTREPID_VALIDATE( validateArguments_setJacobianDetArgs(jacobianDet, jacobian) );
01067
01068 RealSpaceTools<Scalar>::det(jacobianDet, jacobian);
01069 }
01070
01071
01072
01073
01074
01075
01076
01077 template<class Scalar>
01078 template<class ArrayScalar>
01079 void CellTools<Scalar>::mapToPhysicalFrame(ArrayScalar & physPoints,
01080 const ArrayScalar & refPoints,
01081 const ArrayScalar & cellWorkset,
01082 const shards::CellTopology & cellTopo,
01083 const int & whichCell)
01084 {
01085 INTREPID_VALIDATE(validateArguments_mapToPhysicalFrame( physPoints, refPoints, cellWorkset, cellTopo, whichCell) );
01086
01087 int spaceDim = (int)cellTopo.getDimension();
01088 int numCells = cellWorkset.dimension(0);
01089
01090 int numPoints = (refPoints.rank() == 2) ? refPoints.dimension(0) : refPoints.dimension(1);
01091
01092
01093 Teuchos::RCP<Basis<Scalar, FieldContainer<Scalar> > > HGRAD_Basis;
01094
01095
01096 switch( cellTopo.getKey() ){
01097
01098
01099 case shards::Line<2>::key:
01100 HGRAD_Basis = Teuchos::rcp( new Basis_HGRAD_LINE_C1_FEM<Scalar, FieldContainer<Scalar> >() );
01101 break;
01102
01103 case shards::Triangle<3>::key:
01104 HGRAD_Basis = Teuchos::rcp( new Basis_HGRAD_TRI_C1_FEM<Scalar, FieldContainer<Scalar> >() );
01105 break;
01106
01107 case shards::Quadrilateral<4>::key:
01108 HGRAD_Basis = Teuchos::rcp( new Basis_HGRAD_QUAD_C1_FEM<Scalar, FieldContainer<Scalar> >() );
01109 break;
01110
01111 case shards::Tetrahedron<4>::key:
01112 HGRAD_Basis = Teuchos::rcp( new Basis_HGRAD_TET_C1_FEM<Scalar, FieldContainer<Scalar> >() );
01113 break;
01114
01115 case shards::Hexahedron<8>::key:
01116 HGRAD_Basis = Teuchos::rcp( new Basis_HGRAD_HEX_C1_FEM<Scalar, FieldContainer<Scalar> >() );
01117 break;
01118
01119 case shards::Wedge<6>::key:
01120 HGRAD_Basis = Teuchos::rcp( new Basis_HGRAD_WEDGE_C1_FEM<Scalar, FieldContainer<Scalar> >() );
01121 break;
01122
01123
01124 case shards::Triangle<6>::key:
01125 HGRAD_Basis = Teuchos::rcp( new Basis_HGRAD_TRI_C2_FEM<Scalar, FieldContainer<Scalar> >() );
01126 break;
01127
01128 case shards::Quadrilateral<9>::key:
01129 HGRAD_Basis = Teuchos::rcp( new Basis_HGRAD_QUAD_C2_FEM<Scalar, FieldContainer<Scalar> >() );
01130 break;
01131
01132 case shards::Tetrahedron<10>::key:
01133 HGRAD_Basis = Teuchos::rcp( new Basis_HGRAD_TET_C2_FEM<Scalar, FieldContainer<Scalar> >() );
01134 break;
01135
01136 case shards::Hexahedron<27>::key:
01137 HGRAD_Basis = Teuchos::rcp( new Basis_HGRAD_HEX_C2_FEM<Scalar, FieldContainer<Scalar> >() );
01138 break;
01139
01140 case shards::Wedge<18>::key:
01141 HGRAD_Basis = Teuchos::rcp( new Basis_HGRAD_WEDGE_C2_FEM<Scalar, FieldContainer<Scalar> >() );
01142 break;
01143
01144
01145 case shards::Quadrilateral<8>::key:
01146 case shards::Hexahedron<20>::key:
01147 case shards::Wedge<15>::key:
01148 TEST_FOR_EXCEPTION( (true), std::invalid_argument,
01149 ">>> ERROR (Intrepid::CellTools::mapToPhysicalFrame): Cell topology not supported. ");
01150 break;
01151
01152
01153 case shards::Line<3>::key:
01154 case shards::Beam<2>::key:
01155 case shards::Beam<3>::key:
01156 case shards::ShellLine<2>::key:
01157 case shards::ShellLine<3>::key:
01158 case shards::ShellTriangle<3>::key:
01159 case shards::ShellTriangle<6>::key:
01160 case shards::ShellQuadrilateral<4>::key:
01161 case shards::ShellQuadrilateral<8>::key:
01162 case shards::ShellQuadrilateral<9>::key:
01163 TEST_FOR_EXCEPTION( (true), std::invalid_argument,
01164 ">>> ERROR (Intrepid::CellTools::mapToPhysicalFrame): Cell topology not supported. ");
01165 break;
01166 default:
01167 TEST_FOR_EXCEPTION( (true), std::invalid_argument,
01168 ">>> ERROR (Intrepid::CellTools::mapToPhysicalFrame): Cell topology not supported.");
01169 }
01170
01171
01172 int basisCardinality = HGRAD_Basis -> getCardinality();
01173 FieldContainer<Scalar> basisVals(basisCardinality, numPoints);
01174
01175
01176 for(int i = 0; i < physPoints.size(); i++){
01177 physPoints[i] = 0.0;
01178 }
01179
01180
01181 switch(refPoints.rank()) {
01182
01183
01184 case 2:
01185 {
01186
01187 FieldContainer<Scalar> tempPoints( refPoints.dimension(0), refPoints.dimension(1) );
01188
01189 for(int pt = 0; pt < refPoints.dimension(0); pt++){
01190 for(int dm = 0; dm < refPoints.dimension(1) ; dm++){
01191 tempPoints(pt, dm) = refPoints(pt, dm);
01192 }
01193 }
01194 HGRAD_Basis -> getValues(basisVals, tempPoints, OPERATOR_VALUE);
01195
01196
01197 int cellLoop = (whichCell == -1) ? numCells : 1 ;
01198
01199
01200 for(int cellOrd = 0; cellOrd < cellLoop; cellOrd++) {
01201 for(int pointOrd = 0; pointOrd < numPoints; pointOrd++) {
01202 for(int dim = 0; dim < spaceDim; dim++){
01203 for(int bfOrd = 0; bfOrd < basisCardinality; bfOrd++){
01204
01205 if(whichCell == -1){
01206 physPoints(cellOrd, pointOrd, dim) += cellWorkset(cellOrd, bfOrd, dim)*basisVals(bfOrd, pointOrd);
01207 }
01208 else{
01209 physPoints(pointOrd, dim) += cellWorkset(whichCell, bfOrd, dim)*basisVals(bfOrd, pointOrd);
01210 }
01211 }
01212 }
01213 }
01214 }
01215 }
01216 break;
01217
01218
01219 case 3:
01220 {
01221
01222 FieldContainer<Scalar> tempPoints( refPoints.dimension(1), refPoints.dimension(2) );
01223
01224
01225 for(int cellOrd = 0; cellOrd < numCells; cellOrd++) {
01226
01227
01228 for(int pt = 0; pt < refPoints.dimension(1); pt++){
01229 for(int dm = 0; dm < refPoints.dimension(2) ; dm++){
01230 tempPoints(pt, dm) = refPoints(cellOrd, pt, dm);
01231 }
01232 }
01233
01234
01235 HGRAD_Basis -> getValues(basisVals, tempPoints, OPERATOR_VALUE);
01236
01237 for(int pointOrd = 0; pointOrd < numPoints; pointOrd++) {
01238 for(int dim = 0; dim < spaceDim; dim++){
01239 for(int bfOrd = 0; bfOrd < basisCardinality; bfOrd++){
01240
01241 physPoints(cellOrd, pointOrd, dim) += cellWorkset(cellOrd, bfOrd, dim)*basisVals(bfOrd, pointOrd);
01242
01243 }
01244 }
01245 }
01246 }
01247 }
01248 break;
01249
01250 default:
01251 TEST_FOR_EXCEPTION( !( (refPoints.rank() == 2) && (refPoints.rank() == 3) ), std::invalid_argument,
01252 ">>> ERROR (Intrepid::CellTools::mapToPhysicalFrame): rank 2 or 3 required for refPoints array. ");
01253 }
01254 }
01255
01256
01257
01258 template<class Scalar>
01259 template<class ArrayScalar>
01260 void CellTools<Scalar>::mapToReferenceFrame(ArrayScalar & refPoints,
01261 const ArrayScalar & physPoints,
01262 const ArrayScalar & cellWorkset,
01263 const shards::CellTopology & cellTopo,
01264 const int & whichCell)
01265 {
01266 INTREPID_VALIDATE( validateArguments_mapToReferenceFrame(refPoints, physPoints, cellWorkset, cellTopo, whichCell) );
01267
01268 int spaceDim = (int)cellTopo.getDimension();
01269 int numPoints;
01270 int numCells;
01271
01272
01273 FieldContainer<Scalar> cellCenter(spaceDim);
01274 switch( cellTopo.getKey() ){
01275
01276 case shards::Line<2>::key:
01277 cellCenter(0) = 0.0; break;
01278
01279 case shards::Triangle<3>::key:
01280 case shards::Triangle<6>::key:
01281 cellCenter(0) = 1./3.; cellCenter(1) = 1./3.; break;
01282
01283 case shards::Quadrilateral<4>::key:
01284 case shards::Quadrilateral<9>::key:
01285 cellCenter(0) = 0.0; cellCenter(1) = 0.0; break;
01286
01287 case shards::Tetrahedron<4>::key:
01288 case shards::Tetrahedron<10>::key:
01289 cellCenter(0) = 1./6.; cellCenter(1) = 1./6.; cellCenter(2) = 1./6.; break;
01290
01291 case shards::Hexahedron<8>::key:
01292 case shards::Hexahedron<27>::key:
01293 cellCenter(0) = 0.0; cellCenter(1) = 0.0; cellCenter(2) = 0.0; break;
01294
01295 case shards::Wedge<6>::key:
01296 case shards::Wedge<18>::key:
01297 cellCenter(0) = 1./3.; cellCenter(1) = 1./3.; cellCenter(2) = 0.0; break;
01298
01299
01300 case shards::Quadrilateral<8>::key:
01301 case shards::Hexahedron<20>::key:
01302 case shards::Wedge<15>::key:
01303 TEST_FOR_EXCEPTION( (true), std::invalid_argument,
01304 ">>> ERROR (Intrepid::CellTools::mapToReferenceFrame): Cell topology not supported. ");
01305 break;
01306
01307
01308 case shards::Line<3>::key:
01309 case shards::Beam<2>::key:
01310 case shards::Beam<3>::key:
01311 case shards::ShellLine<2>::key:
01312 case shards::ShellLine<3>::key:
01313 case shards::ShellTriangle<3>::key:
01314 case shards::ShellTriangle<6>::key:
01315 case shards::ShellQuadrilateral<4>::key:
01316 case shards::ShellQuadrilateral<8>::key:
01317 case shards::ShellQuadrilateral<9>::key:
01318 TEST_FOR_EXCEPTION( (true), std::invalid_argument,
01319 ">>> ERROR (Intrepid::CellTools::mapToReferenceFrame): Cell topology not supported. ");
01320 break;
01321 default:
01322 TEST_FOR_EXCEPTION( (true), std::invalid_argument,
01323 ">>> ERROR (Intrepid::CellTools::mapToReferenceFrame): Cell topology not supported.");
01324 }
01325
01326
01327 FieldContainer<Scalar> initGuess;
01328
01329
01330 if(whichCell == -1){
01331 numPoints = physPoints.dimension(1);
01332 numCells = cellWorkset.dimension(0);
01333 initGuess.resize(numCells, numPoints, spaceDim);
01334
01335 for(int c = 0; c < numCells; c++){
01336 for(int p = 0; p < numPoints; p++){
01337 for(int d = 0; d < spaceDim; d++){
01338 initGuess(c, p, d) = cellCenter(d);
01339 }
01340 }
01341 }
01342 }
01343
01344 else {
01345 numPoints = physPoints.dimension(0);
01346 initGuess.resize(numPoints, spaceDim);
01347
01348 for(int p = 0; p < numPoints; p++){
01349 for(int d = 0; d < spaceDim; d++){
01350 initGuess(p, d) = cellCenter(d);
01351 }
01352 }
01353 }
01354
01355
01356 mapToReferenceFrame(refPoints, initGuess, physPoints, cellWorkset, cellTopo, whichCell);
01357 }
01358
01359
01360
01361 template<class Scalar>
01362 template<class ArrayType1, class ArrayType2>
01363 void CellTools<Scalar>::mapToReferenceFrame(ArrayType1 & refPoints,
01364 const ArrayType2 & initGuess,
01365 const ArrayType1 & physPoints,
01366 const ArrayType1 & cellWorkset,
01367 const shards::CellTopology & cellTopo,
01368 const int & whichCell)
01369 {
01370 INTREPID_VALIDATE( validateArguments_mapToReferenceFrame(refPoints, initGuess, physPoints, cellWorkset, cellTopo, whichCell) );
01371
01372 int spaceDim = (int)cellTopo.getDimension();
01373 int numPoints;
01374 int numCells=0;
01375
01376
01377 FieldContainer<Scalar> xOld;
01378 FieldContainer<Scalar> xTem;
01379 FieldContainer<Scalar> jacobian;
01380 FieldContainer<Scalar> jacobInv;
01381 FieldContainer<Scalar> error;
01382 FieldContainer<Scalar> cellCenter(spaceDim);
01383
01384
01385 if(whichCell == -1){
01386 numPoints = physPoints.dimension(1);
01387 numCells = cellWorkset.dimension(0);
01388 xOld.resize(numCells, numPoints, spaceDim);
01389 xTem.resize(numCells, numPoints, spaceDim);
01390 jacobian.resize(numCells,numPoints, spaceDim, spaceDim);
01391 jacobInv.resize(numCells,numPoints, spaceDim, spaceDim);
01392 error.resize(numCells,numPoints);
01393
01394 for(int c = 0; c < numCells; c++){
01395 for(int p = 0; p < numPoints; p++){
01396 for(int d = 0; d < spaceDim; d++){
01397 xOld(c, p, d) = initGuess(c, p, d);
01398 }
01399 }
01400 }
01401 }
01402
01403 else {
01404 numPoints = physPoints.dimension(0);
01405 xOld.resize(numPoints, spaceDim);
01406 xTem.resize(numPoints, spaceDim);
01407 jacobian.resize(numPoints, spaceDim, spaceDim);
01408 jacobInv.resize(numPoints, spaceDim, spaceDim);
01409 error.resize(numPoints);
01410
01411 for(int p = 0; p < numPoints; p++){
01412 for(int d = 0; d < spaceDim; d++){
01413 xOld(p, d) = initGuess(p, d);
01414 }
01415 }
01416 }
01417
01418
01419
01420
01421 for(int iter = 0; iter < INTREPID_MAX_NEWTON; ++iter) {
01422
01423
01424 setJacobian(jacobian, xOld, cellWorkset, cellTopo, whichCell);
01425 setJacobianInv(jacobInv, jacobian);
01426
01427
01428 mapToPhysicalFrame( xTem, xOld, cellWorkset, cellTopo, whichCell );
01429 RealSpaceTools<Scalar>::subtract( xTem, physPoints, xTem );
01430 RealSpaceTools<Scalar>::matvec( refPoints, jacobInv, xTem);
01431 RealSpaceTools<Scalar>::add( refPoints, xOld );
01432
01433
01434 RealSpaceTools<Scalar>::subtract( xTem, xOld, refPoints );
01435 RealSpaceTools<Scalar>::vectorNorm( error, xTem, NORM_TWO );
01436
01437
01438 double totalError;
01439 if(whichCell == -1) {
01440 FieldContainer<Scalar> cellWiseError(numCells);
01441
01442 RealSpaceTools<Scalar>::vectorNorm( cellWiseError, error, NORM_ONE );
01443 totalError = RealSpaceTools<Scalar>::vectorNorm( cellWiseError, NORM_ONE );
01444 }
01445
01446 else{
01447 totalError = RealSpaceTools<Scalar>::vectorNorm( error, NORM_ONE );
01448 totalError = totalError;
01449 }
01450
01451
01452 if (totalError < INTREPID_TOL) {
01453 break;
01454 }
01455 else if ( iter > INTREPID_MAX_NEWTON) {
01456 INTREPID_VALIDATE(std::cout << " Intrepid::CellTools::mapToReferenceFrame failed to converge to desired tolerance within "
01457 << INTREPID_MAX_NEWTON << " iterations\n" );
01458 break;
01459 }
01460
01461
01462 xOld = refPoints;
01463 }
01464 }
01465
01466
01467
01468 template<class Scalar>
01469 template<class ArrayTypeOut, class ArrayTypeIn>
01470 void CellTools<Scalar>::mapToReferenceSubcell(ArrayTypeOut & refSubcellPoints,
01471 const ArrayTypeIn & paramPoints,
01472 const int subcellDim,
01473 const int subcellOrd,
01474 const shards::CellTopology & parentCell){
01475
01476 int cellDim = parentCell.getDimension();
01477 int numPts = paramPoints.dimension(0);
01478
01479 #ifdef HAVE_INTREPID_DEBUG
01480 TEST_FOR_EXCEPTION( !(hasReferenceCell(parentCell) ), std::invalid_argument,
01481 ">>> ERROR (Intrepid::CellTools::mapToReferenceSubcell): the specified cell topology does not have a reference cell.");
01482
01483 TEST_FOR_EXCEPTION( !( (1 <= subcellDim) && (subcellDim <= 2 ) ), std::invalid_argument,
01484 ">>> ERROR (Intrepid::CellTools::mapToReferenceSubcell): method defined only for 1 and 2-dimensional subcells.");
01485
01486 TEST_FOR_EXCEPTION( !( (0 <= subcellOrd) && (subcellOrd < (int)parentCell.getSubcellCount(subcellDim) ) ), std::invalid_argument,
01487 ">>> ERROR (Intrepid::CellTools::mapToReferenceSubcell): subcell ordinal out of range.");
01488
01489
01490 std::string errmsg = ">>> ERROR (Intrepid::mapToReferenceSubcell):";
01491 TEST_FOR_EXCEPTION( !requireRankRange(errmsg, refSubcellPoints, 2,2), std::invalid_argument, errmsg);
01492 TEST_FOR_EXCEPTION( !requireDimensionRange(errmsg, refSubcellPoints, 1, cellDim, cellDim), std::invalid_argument, errmsg);
01493
01494
01495 TEST_FOR_EXCEPTION( !requireRankRange(errmsg, paramPoints, 2,2), std::invalid_argument, errmsg);
01496 TEST_FOR_EXCEPTION( !requireDimensionRange(errmsg, paramPoints, 1, subcellDim, subcellDim), std::invalid_argument, errmsg);
01497
01498
01499 TEST_FOR_EXCEPTION( !requireDimensionMatch(errmsg, refSubcellPoints, 0, paramPoints, 0), std::invalid_argument, errmsg);
01500 #endif
01501
01502
01503
01504 const FieldContainer<double>& subcellMap = getSubcellParametrization(subcellDim, parentCell);
01505
01506
01507 if(subcellDim == 2) {
01508 for(int pt = 0; pt < numPts; pt++){
01509 double u = paramPoints(pt,0);
01510 double v = paramPoints(pt,1);
01511
01512
01513 for(int dim = 0; dim < cellDim; dim++){
01514 refSubcellPoints(pt, dim) = subcellMap(subcellOrd, dim, 0) + \
01515 subcellMap(subcellOrd, dim, 1)*u + \
01516 subcellMap(subcellOrd, dim, 2)*v;
01517 }
01518 }
01519 }
01520 else if(subcellDim == 1) {
01521 for(int pt = 0; pt < numPts; pt++){
01522 for(int dim = 0; dim < cellDim; dim++) {
01523 refSubcellPoints(pt, dim) = subcellMap(subcellOrd, dim, 0) + subcellMap(subcellOrd, dim, 1)*paramPoints(pt,0);
01524 }
01525 }
01526 }
01527 else{
01528 TEST_FOR_EXCEPTION( !( (subcellDim == 1) || (subcellDim == 2) ), std::invalid_argument,
01529 ">>> ERROR (Intrepid::CellTools::mapToReferenceSubcell): method defined only for 1 and 2-subcells");
01530 }
01531 }
01532
01533
01534
01535 template<class Scalar>
01536 template<class ArrayTypeOut>
01537 void CellTools<Scalar>::getReferenceEdgeTangent(ArrayTypeOut & refEdgeTangent,
01538 const int & edgeOrd,
01539 const shards::CellTopology & parentCell){
01540
01541 int spaceDim = parentCell.getDimension();
01542
01543 #ifdef HAVE_INTREPID_DEBUG
01544
01545 TEST_FOR_EXCEPTION( !( (spaceDim == 2) || (spaceDim == 3) ), std::invalid_argument,
01546 ">>> ERROR (Intrepid::CellTools::getReferenceFaceTangents): two or three-dimensional parent cell required");
01547
01548 TEST_FOR_EXCEPTION( !( (0 <= edgeOrd) && (edgeOrd < (int)parentCell.getSubcellCount(1) ) ), std::invalid_argument,
01549 ">>> ERROR (Intrepid::CellTools::getReferenceFaceTangents): edge ordinal out of bounds");
01550
01551 TEST_FOR_EXCEPTION( !( refEdgeTangent.size() == spaceDim ), std::invalid_argument,
01552 ">>> ERROR (Intrepid::CellTools::getReferenceFaceTangents): output array size is required to match space dimension");
01553 #endif
01554
01555
01556
01557 const FieldContainer<double>& edgeMap = getSubcellParametrization(1, parentCell);
01558
01559
01560
01561 refEdgeTangent(0) = edgeMap(edgeOrd, 0, 1);
01562 refEdgeTangent(1) = edgeMap(edgeOrd, 1, 1);
01563
01564
01565 if(spaceDim == 3) {
01566 refEdgeTangent(2) = edgeMap(edgeOrd, 2, 1);
01567 }
01568 }
01569
01570
01571
01572 template<class Scalar>
01573 template<class ArrayTypeOut>
01574 void CellTools<Scalar>::getReferenceFaceTangents(ArrayTypeOut & uTan,
01575 ArrayTypeOut & vTan,
01576 const int & faceOrd,
01577 const shards::CellTopology & parentCell){
01578
01579 #ifdef HAVE_INTREPID_DEBUG
01580 int spaceDim = parentCell.getDimension();
01581 TEST_FOR_EXCEPTION( !(spaceDim == 3), std::invalid_argument,
01582 ">>> ERROR (Intrepid::CellTools::getReferenceFaceTangents): three-dimensional parent cell required");
01583
01584 TEST_FOR_EXCEPTION( !( (0 <= faceOrd) && (faceOrd < (int)parentCell.getSubcellCount(2) ) ), std::invalid_argument,
01585 ">>> ERROR (Intrepid::CellTools::getReferenceFaceTangents): face ordinal out of bounds");
01586
01587 TEST_FOR_EXCEPTION( !( (uTan.rank() == 1) && (vTan.rank() == 1) ), std::invalid_argument,
01588 ">>> ERROR (Intrepid::CellTools::getReferenceFaceTangents): rank = 1 required for output arrays");
01589
01590 TEST_FOR_EXCEPTION( !( uTan.dimension(0) == spaceDim ), std::invalid_argument,
01591 ">>> ERROR (Intrepid::CellTools::getReferenceFaceTangents): dim0 (spatial dim) must match that of parent cell");
01592
01593 TEST_FOR_EXCEPTION( !( vTan.dimension(0) == spaceDim ), std::invalid_argument,
01594 ">>> ERROR (Intrepid::CellTools::getReferenceFaceTangents): dim0 (spatial dim) must match that of parent cell");
01595 #endif
01596
01597
01598
01599 const FieldContainer<double>& faceMap = getSubcellParametrization(2, parentCell);
01600
01601
01602
01603
01604
01605 uTan(0) = faceMap(faceOrd, 0, 1);
01606 uTan(1) = faceMap(faceOrd, 1, 1);
01607 uTan(2) = faceMap(faceOrd, 2, 1);
01608
01609
01610 vTan(0) = faceMap(faceOrd, 0, 2);
01611 vTan(1) = faceMap(faceOrd, 1, 2);
01612 vTan(2) = faceMap(faceOrd, 2, 2);
01613 }
01614
01615
01616
01617 template<class Scalar>
01618 template<class ArrayTypeOut>
01619 void CellTools<Scalar>::getReferenceSideNormal(ArrayTypeOut & refSideNormal,
01620 const int & sideOrd,
01621 const shards::CellTopology & parentCell){
01622 int spaceDim = parentCell.getDimension();
01623 #ifdef HAVE_INTREPID_DEBUG
01624
01625 TEST_FOR_EXCEPTION( !( (spaceDim == 2) || (spaceDim == 3) ), std::invalid_argument,
01626 ">>> ERROR (Intrepid::CellTools::getReferenceSideNormal): two or three-dimensional parent cell required");
01627
01628
01629 TEST_FOR_EXCEPTION( !( (0 <= sideOrd) && (sideOrd < (int)parentCell.getSubcellCount(spaceDim - 1) ) ), std::invalid_argument,
01630 ">>> ERROR (Intrepid::CellTools::getReferenceSideNormal): side ordinal out of bounds");
01631 #endif
01632
01633 if(spaceDim == 2){
01634
01635
01636 getReferenceEdgeTangent(refSideNormal, sideOrd, parentCell);
01637
01638
01639 Scalar temp = refSideNormal(0);
01640 refSideNormal(0) = refSideNormal(1);
01641 refSideNormal(1) = -temp;
01642 }
01643 else{
01644
01645 getReferenceFaceNormal(refSideNormal, sideOrd, parentCell);
01646 }
01647 }
01648
01649
01650
01651 template<class Scalar>
01652 template<class ArrayTypeOut>
01653 void CellTools<Scalar>::getReferenceFaceNormal(ArrayTypeOut & refFaceNormal,
01654 const int & faceOrd,
01655 const shards::CellTopology & parentCell){
01656 int spaceDim = parentCell.getDimension();
01657
01658 #ifdef HAVE_INTREPID_DEBUG
01659
01660 TEST_FOR_EXCEPTION( !(spaceDim == 3), std::invalid_argument,
01661 ">>> ERROR (Intrepid::CellTools::getReferenceFaceNormal): three-dimensional parent cell required");
01662
01663 TEST_FOR_EXCEPTION( !( (0 <= faceOrd) && (faceOrd < (int)parentCell.getSubcellCount(2) ) ), std::invalid_argument,
01664 ">>> ERROR (Intrepid::CellTools::getReferenceFaceNormal): face ordinal out of bounds");
01665
01666 TEST_FOR_EXCEPTION( !( refFaceNormal.rank() == 1 ), std::invalid_argument,
01667 ">>> ERROR (Intrepid::CellTools::getReferenceFaceNormal): rank = 1 required for output array");
01668
01669 TEST_FOR_EXCEPTION( !( refFaceNormal.dimension(0) == spaceDim ), std::invalid_argument,
01670 ">>> ERROR (Intrepid::CellTools::getReferenceFaceNormal): dim0 (spatial dim) must match that of parent cell");
01671 #endif
01672
01673
01674 FieldContainer<Scalar> uTan(spaceDim);
01675 FieldContainer<Scalar> vTan(spaceDim);
01676 getReferenceFaceTangents(uTan, vTan, faceOrd, parentCell);
01677
01678
01679 RealSpaceTools<Scalar>::vecprod(refFaceNormal, uTan, vTan);
01680 }
01681
01682
01683
01684 template<class Scalar>
01685 template<class ArrayTypeOut, class ArrayTypeIn>
01686 void CellTools<Scalar>::getPhysicalEdgeTangents(ArrayTypeOut & edgeTangents,
01687 const ArrayTypeIn & worksetJacobians,
01688 const int & worksetEdgeOrd,
01689 const shards::CellTopology & parentCell){
01690 int worksetSize = worksetJacobians.dimension(0);
01691 int edgePtCount = worksetJacobians.dimension(1);
01692 int pCellDim = parentCell.getDimension();
01693
01694 #ifdef HAVE_INTREPID_DEBUG
01695 std::string errmsg = ">>> ERROR (Intrepid::CellTools::getPhysicalEdgeTangents):";
01696
01697 TEST_FOR_EXCEPTION( !( (pCellDim == 3) || (pCellDim == 2) ), std::invalid_argument,
01698 ">>> ERROR (Intrepid::CellTools::getPhysicalEdgeTangents): 2D or 3D parent cell required");
01699
01700
01701 TEST_FOR_EXCEPTION( !requireRankRange(errmsg, edgeTangents, 3,3), std::invalid_argument, errmsg);
01702 TEST_FOR_EXCEPTION( !requireDimensionRange(errmsg, edgeTangents, 2, 2,3), std::invalid_argument, errmsg);
01703
01704
01705 TEST_FOR_EXCEPTION( !requireRankRange(errmsg, worksetJacobians, 4,4), std::invalid_argument, errmsg);
01706 TEST_FOR_EXCEPTION( !requireDimensionRange(errmsg, worksetJacobians, 2, 2,3), std::invalid_argument, errmsg);
01707 TEST_FOR_EXCEPTION( !requireDimensionRange(errmsg, worksetJacobians, 3, 2,3), std::invalid_argument, errmsg);
01708
01709
01710 TEST_FOR_EXCEPTION( !requireDimensionMatch(errmsg, edgeTangents, 0,1,2,2, worksetJacobians, 0,1,2,3), std::invalid_argument, errmsg);
01711
01712 #endif
01713
01714
01715 FieldContainer<double> refEdgeTan(pCellDim);
01716 getReferenceEdgeTangent(refEdgeTan, worksetEdgeOrd, parentCell);
01717
01718
01719 for(int pCell = 0; pCell < worksetSize; pCell++){
01720 for(int pt = 0; pt < edgePtCount; pt++){
01721
01722
01723 for(int i = 0; i < pCellDim; i++){
01724 edgeTangents(pCell, pt, i) = 0.0;
01725 for(int j = 0; j < pCellDim; j++){
01726 edgeTangents(pCell, pt, i) += worksetJacobians(pCell, pt, i, j)*refEdgeTan(j);
01727 }
01728 }
01729 }
01730 }
01731 }
01732
01733
01734
01735 template<class Scalar>
01736 template<class ArrayTypeOut, class ArrayTypeIn>
01737 void CellTools<Scalar>::getPhysicalFaceTangents(ArrayTypeOut & faceTanU,
01738 ArrayTypeOut & faceTanV,
01739 const ArrayTypeIn & worksetJacobians,
01740 const int & worksetFaceOrd,
01741 const shards::CellTopology & parentCell){
01742 int worksetSize = worksetJacobians.dimension(0);
01743 int facePtCount = worksetJacobians.dimension(1);
01744 int pCellDim = parentCell.getDimension();
01745
01746 #ifdef HAVE_INTREPID_DEBUG
01747 std::string errmsg = ">>> ERROR (Intrepid::CellTools::getPhysicalFaceTangents):";
01748
01749 TEST_FOR_EXCEPTION( !(pCellDim == 3), std::invalid_argument,
01750 ">>> ERROR (Intrepid::CellTools::getPhysicalFaceTangents): three-dimensional parent cell required");
01751
01752
01753 TEST_FOR_EXCEPTION( !requireRankRange(errmsg, faceTanU, 3,3), std::invalid_argument, errmsg);
01754 TEST_FOR_EXCEPTION( !requireDimensionRange(errmsg, faceTanU, 2, 3,3), std::invalid_argument, errmsg);
01755
01756 TEST_FOR_EXCEPTION( !requireRankRange(errmsg, faceTanV, 3,3), std::invalid_argument, errmsg);
01757 TEST_FOR_EXCEPTION( !requireDimensionRange(errmsg, faceTanV, 2, 3,3), std::invalid_argument, errmsg);
01758
01759 TEST_FOR_EXCEPTION( !requireDimensionMatch(errmsg, faceTanU, faceTanV), std::invalid_argument, errmsg);
01760
01761
01762 TEST_FOR_EXCEPTION( !requireRankRange(errmsg, worksetJacobians, 4,4), std::invalid_argument, errmsg);
01763 TEST_FOR_EXCEPTION( !requireDimensionRange(errmsg, worksetJacobians, 2, 3,3), std::invalid_argument, errmsg);
01764 TEST_FOR_EXCEPTION( !requireDimensionRange(errmsg, worksetJacobians, 3, 3,3), std::invalid_argument, errmsg);
01765
01766
01767 TEST_FOR_EXCEPTION( !requireDimensionMatch(errmsg, faceTanU, 0,1,2,2, worksetJacobians, 0,1,2,3), std::invalid_argument, errmsg);
01768
01769 #endif
01770
01771
01772 FieldContainer<double> refFaceTanU(pCellDim);
01773 FieldContainer<double> refFaceTanV(pCellDim);
01774 getReferenceFaceTangents(refFaceTanU, refFaceTanV, worksetFaceOrd, parentCell);
01775
01776
01777 for(int pCell = 0; pCell < worksetSize; pCell++){
01778 for(int pt = 0; pt < facePtCount; pt++){
01779
01780
01781 for(int dim = 0; dim < pCellDim; dim++){
01782 faceTanU(pCell, pt, dim) = 0.0;
01783 faceTanV(pCell, pt, dim) = 0.0;
01784
01785
01786 faceTanU(pCell, pt, dim) = \
01787 worksetJacobians(pCell, pt, dim, 0)*refFaceTanU(0) + \
01788 worksetJacobians(pCell, pt, dim, 1)*refFaceTanU(1) + \
01789 worksetJacobians(pCell, pt, dim, 2)*refFaceTanU(2);
01790 faceTanV(pCell, pt, dim) = \
01791 worksetJacobians(pCell, pt, dim, 0)*refFaceTanV(0) + \
01792 worksetJacobians(pCell, pt, dim, 1)*refFaceTanV(1) + \
01793 worksetJacobians(pCell, pt, dim, 2)*refFaceTanV(2);
01794 }
01795 }
01796 }
01797 }
01798
01799
01800 template<class Scalar>
01801 template<class ArrayTypeOut, class ArrayTypeIn>
01802 void CellTools<Scalar>::getPhysicalSideNormals(ArrayTypeOut & sideNormals,
01803 const ArrayTypeIn & worksetJacobians,
01804 const int & worksetSideOrd,
01805 const shards::CellTopology & parentCell){
01806 int worksetSize = worksetJacobians.dimension(0);
01807 int sidePtCount = worksetJacobians.dimension(1);
01808 int spaceDim = parentCell.getDimension();
01809
01810 #ifdef HAVE_INTREPID_DEBUG
01811 TEST_FOR_EXCEPTION( !( (spaceDim == 2) || (spaceDim == 3) ), std::invalid_argument,
01812 ">>> ERROR (Intrepid::CellTools::getPhysicalSideNormals): two or three-dimensional parent cell required");
01813
01814
01815 TEST_FOR_EXCEPTION( !( (0 <= worksetSideOrd) && (worksetSideOrd < (int)parentCell.getSubcellCount(spaceDim - 1) ) ), std::invalid_argument,
01816 ">>> ERROR (Intrepid::CellTools::getPhysicalSideNormals): side ordinal out of bounds");
01817 #endif
01818
01819 if(spaceDim == 2){
01820
01821
01822 getPhysicalEdgeTangents(sideNormals, worksetJacobians, worksetSideOrd, parentCell);
01823
01824
01825 for(int cell = 0; cell < worksetSize; cell++){
01826 for(int pt = 0; pt < sidePtCount; pt++){
01827 Scalar temp = sideNormals(cell, pt, 0);
01828 sideNormals(cell, pt, 0) = sideNormals(cell, pt, 1);
01829 sideNormals(cell, pt, 1) = -temp;
01830 }
01831 }
01832 }
01833 else{
01834
01835 getPhysicalFaceNormals(sideNormals, worksetJacobians, worksetSideOrd, parentCell);
01836 }
01837 }
01838
01839
01840
01841 template<class Scalar>
01842 template<class ArrayTypeOut, class ArrayTypeIn>
01843 void CellTools<Scalar>::getPhysicalFaceNormals(ArrayTypeOut & faceNormals,
01844 const ArrayTypeIn & worksetJacobians,
01845 const int & worksetFaceOrd,
01846 const shards::CellTopology & parentCell){
01847 int worksetSize = worksetJacobians.dimension(0);
01848 int facePtCount = worksetJacobians.dimension(1);
01849 int pCellDim = parentCell.getDimension();
01850
01851 #ifdef HAVE_INTREPID_DEBUG
01852 std::string errmsg = ">>> ERROR (Intrepid::CellTools::getPhysicalFaceNormals):";
01853
01854 TEST_FOR_EXCEPTION( !(pCellDim == 3), std::invalid_argument,
01855 ">>> ERROR (Intrepid::CellTools::getPhysicalFaceNormals): three-dimensional parent cell required");
01856
01857
01858 TEST_FOR_EXCEPTION( !requireRankRange(errmsg, faceNormals, 3,3), std::invalid_argument, errmsg);
01859 TEST_FOR_EXCEPTION( !requireDimensionRange(errmsg, faceNormals, 2, 3,3), std::invalid_argument, errmsg);
01860
01861
01862 TEST_FOR_EXCEPTION( !requireRankRange(errmsg, worksetJacobians, 4,4), std::invalid_argument, errmsg);
01863 TEST_FOR_EXCEPTION( !requireDimensionRange(errmsg, worksetJacobians, 2, 3,3), std::invalid_argument, errmsg);
01864 TEST_FOR_EXCEPTION( !requireDimensionRange(errmsg, worksetJacobians, 3, 3,3), std::invalid_argument, errmsg);
01865
01866
01867 TEST_FOR_EXCEPTION( !requireDimensionMatch(errmsg, faceNormals, 0,1,2,2, worksetJacobians, 0,1,2,3), std::invalid_argument, errmsg);
01868 #endif
01869
01870
01871 FieldContainer<double> faceTanU(worksetSize, facePtCount, pCellDim);
01872 FieldContainer<double> faceTanV(worksetSize, facePtCount, pCellDim);
01873 getPhysicalFaceTangents(faceTanU, faceTanV, worksetJacobians, worksetFaceOrd, parentCell);
01874
01875
01876 RealSpaceTools<Scalar>::vecprod(faceNormals, faceTanU, faceTanV);
01877
01878
01879 }
01880
01881
01882
01883
01884
01885
01886
01887
01888 template<class Scalar>
01889 int CellTools<Scalar>::checkPointInclusion(const Scalar* point,
01890 const int pointDim,
01891 const shards::CellTopology & cellTopo,
01892 const double & threshold) {
01893 #ifdef HAVE_INTREPID_DEBUG
01894 TEST_FOR_EXCEPTION( !(pointDim == (int)cellTopo.getDimension() ), std::invalid_argument,
01895 ">>> ERROR (Intrepid::CellTools::checkPointInclusion): Point and cell dimensions do not match. ");
01896 #endif
01897 int testResult = 1;
01898
01899
01900 double minus_one = -1.0 - threshold;
01901 double plus_one = 1.0 + threshold;
01902 double minus_zero = - threshold;
01903
01904
01905
01906
01907 unsigned key = cellTopo.getBaseTopology() -> key ;
01908 switch( key ) {
01909
01910 case shards::Line<>::key :
01911 if( !(minus_one <= point[0] && point[0] <= plus_one)) testResult = 0;
01912 break;
01913
01914 case shards::Triangle<>::key : {
01915 Scalar distance = std::max( std::max( -point[0], -point[1] ), point[0] + point[1] - 1.0 );
01916 if( distance > threshold ) testResult = 0;
01917 break;
01918 }
01919
01920 case shards::Quadrilateral<>::key :
01921 if(!( (minus_one <= point[0] && point[0] <= plus_one) && \
01922 (minus_one <= point[1] && point[1] <= plus_one) ) ) testResult = 0;
01923 break;
01924
01925 case shards::Tetrahedron<>::key : {
01926 Scalar distance = std::max( std::max(-point[0],-point[1]), \
01927 std::max(-point[2], point[0] + point[1] + point[2] - 1) );
01928 if( distance > threshold ) testResult = 0;
01929 break;
01930 }
01931
01932 case shards::Hexahedron<>::key :
01933 if(!((minus_one <= point[0] && point[0] <= plus_one) && \
01934 (minus_one <= point[1] && point[1] <= plus_one) && \
01935 (minus_one <= point[2] && point[2] <= plus_one))) \
01936 testResult = 0;
01937 break;
01938
01939
01940
01941 case shards::Wedge<>::key : {
01942 Scalar distance = std::max( std::max( -point[0], -point[1] ), point[0] + point[1] - 1 );
01943 if( distance > threshold || \
01944 point[2] < minus_one || point[2] > plus_one) \
01945 testResult = 0;
01946 break;
01947 }
01948
01949
01950
01951
01952 case shards::Pyramid<>::key : {
01953 Scalar left = minus_one + point[2];
01954 Scalar right = plus_one - point[2];
01955 if(!( (left <= point[0] && point[0] <= right) && \
01956 (left <= point[1] && point[1] <= right) &&
01957 (minus_zero <= point[2] && point[2] <= plus_one) ) ) \
01958 testResult = 0;
01959 break;
01960 }
01961
01962 default:
01963 TEST_FOR_EXCEPTION( !( (key == shards::Line<>::key ) ||
01964 (key == shards::Triangle<>::key) ||
01965 (key == shards::Quadrilateral<>::key) ||
01966 (key == shards::Tetrahedron<>::key) ||
01967 (key == shards::Hexahedron<>::key) ||
01968 (key == shards::Wedge<>::key) ||
01969 (key == shards::Pyramid<>::key) ),
01970 std::invalid_argument,
01971 ">>> ERROR (Intrepid::CellTools::checkPointInclusion): Invalid cell topology. ");
01972 }
01973 return testResult;
01974 }
01975
01976
01977
01978 template<class Scalar>
01979 template<class ArrayPoint>
01980 int CellTools<Scalar>::checkPointsetInclusion(const ArrayPoint& points,
01981 const shards::CellTopology & cellTopo,
01982 const double & threshold) {
01983
01984 int rank = points.rank();
01985
01986 #ifdef HAVE_INTREPID_DEBUG
01987 TEST_FOR_EXCEPTION( !( (1 <= points.rank() ) && (points.rank() <= 3) ), std::invalid_argument,
01988 ">>> ERROR (Intrepid::CellTools::checkPointsetInclusion): rank-1, 2 or 3 required for input points array. ");
01989
01990
01991 TEST_FOR_EXCEPTION( !( points.dimension(rank - 1) == (int)cellTopo.getDimension() ), std::invalid_argument,
01992 ">>> ERROR (Intrepid::CellTools::checkPointsetInclusion): Point and cell dimensions do not match. ");
01993 #endif
01994
01995
01996 FieldContainer<int> inRefCell;
01997 switch(rank) {
01998 case 1: inRefCell.resize(1); break;
01999 case 2: inRefCell.resize( points.dimension(0) ); break;
02000 case 3: inRefCell.resize( points.dimension(0), points.dimension(1) ); break;
02001 }
02002
02003
02004 checkPointwiseInclusion(inRefCell, points, cellTopo, threshold);
02005
02006
02007 int allInside = 1;
02008 for(int i = 0; i < inRefCell.size(); i++ ){
02009 if (inRefCell[i] == 0) {
02010 allInside = 0;
02011 break;
02012 }
02013 }
02014 return allInside;
02015 }
02016
02017
02018
02019 template<class Scalar>
02020 template<class ArrayInt, class ArrayPoint>
02021 void CellTools<Scalar>::checkPointwiseInclusion(ArrayInt & inRefCell,
02022 const ArrayPoint & points,
02023 const shards::CellTopology & cellTopo,
02024 const double & threshold) {
02025 int apRank = points.rank();
02026
02027 #ifdef HAVE_INTREPID_DEBUG
02028
02029
02030 std::string errmsg = ">>> ERROR (Intrepid::CellTools::checkPointwiseInclusion):";
02031 if(points.rank() == 1) {
02032 TEST_FOR_EXCEPTION( !(inRefCell.rank() == 1 ), std::invalid_argument,
02033 ">>> ERROR (Intrepid::CellTools::checkPointwiseInclusion): rank-1 input array requires rank-1 output array.");
02034 TEST_FOR_EXCEPTION( !(inRefCell.dimension(0) == 1), std::invalid_argument,
02035 ">>> ERROR (Intrepid::CellTools::checkPointwiseInclusion): rank-1 input array requires dim0 = 1 for output array.");
02036 }
02037 else if(points.rank() == 2){
02038 TEST_FOR_EXCEPTION( !(inRefCell.rank() == 1 ), std::invalid_argument,
02039 ">>> ERROR (Intrepid::CellTools::checkPointwiseInclusion): rank-2 input array requires rank-1 output array.");
02040
02041 TEST_FOR_EXCEPTION( !requireDimensionMatch( errmsg, inRefCell, 0, points, 0), std::invalid_argument, errmsg);
02042 }
02043 else if (points.rank() == 3) {
02044 TEST_FOR_EXCEPTION( !(inRefCell.rank() == 2 ), std::invalid_argument,
02045 ">>> ERROR (Intrepid::CellTools::checkPointwiseInclusion): rank-3 input array requires rank-2 output array.");
02046
02047 TEST_FOR_EXCEPTION( !requireDimensionMatch( errmsg, inRefCell, 0,1, points, 0,1), std::invalid_argument, errmsg);
02048 }
02049 else{
02050 TEST_FOR_EXCEPTION( !( (points.rank() == 1) || (points.rank() == 2) || (points.rank() == 3) ), std::invalid_argument,
02051 ">>> ERROR (Intrepid::CellTools::checkPointwiseInclusion): rank-1, 2 or 3 required for input points array. ");
02052 }
02053
02054
02055 TEST_FOR_EXCEPTION( !( points.dimension(apRank - 1) == (int)cellTopo.getDimension() ), std::invalid_argument,
02056 ">>> ERROR (Intrepid::CellTools::checkPointwiseInclusion): Point and cell dimensions do not match. ");
02057
02058 #endif
02059
02060
02061 int dim0 = 1;
02062 int dim1 = 1;
02063 int pointDim = 0;
02064 switch(apRank) {
02065 case 1:
02066 pointDim = points.dimension(0);
02067 break;
02068 case 2:
02069 dim1 = points.dimension(0);
02070 pointDim = points.dimension(1);
02071 break;
02072 case 3:
02073 dim0 = points.dimension(0);
02074 dim1 = points.dimension(1);
02075 pointDim = points.dimension(2);
02076 break;
02077 default:
02078 TEST_FOR_EXCEPTION( !( (1 <= points.rank() ) && (points.rank() <= 3) ), std::invalid_argument,
02079 ">>> ERROR (Intrepid::CellTools::checkPointwiseInclusion): rank-1, 2 or 3 required for input points array. ");
02080 }
02081
02082
02083
02084
02085
02086
02087
02088 int inPtr0 = 0;
02089 int inPtr1 = 0;
02090 int outPtr0 = 0;
02091 Scalar point[3] = {0.0, 0.0, 0.0};
02092
02093 for(int i0 = 0; i0 < dim0; i0++){
02094 outPtr0 = i0*dim1;
02095 inPtr0 = outPtr0*pointDim;
02096
02097 for(int i1 = 0; i1 < dim1; i1++) {
02098 inPtr1 = inPtr0 + i1*pointDim;
02099 point[0] = points[inPtr1];
02100 if(pointDim > 1) {
02101 point[1] = points[inPtr1 + 1];
02102 if(pointDim > 2) {
02103 point[2] = points[inPtr1 + 2];
02104 if(pointDim > 3) {
02105 TEST_FOR_EXCEPTION( !( (1 <= pointDim) && (pointDim <= 3)), std::invalid_argument,
02106 ">>> ERROR (Intrepid::CellTools::checkPointwiseInclusion): Input array specifies invalid point dimension ");
02107 }
02108 }
02109 }
02110 inRefCell[outPtr0 + i1] = checkPointInclusion(point, pointDim, cellTopo, threshold);
02111 }
02112 }
02113
02114 }
02115
02116
02117 template<class Scalar>
02118 template<class ArrayInt, class ArrayPoint, class ArrayScalar>
02119 void CellTools<Scalar>::checkPointwiseInclusion(ArrayInt & inCell,
02120 const ArrayPoint & points,
02121 const ArrayScalar & cellWorkset,
02122 const shards::CellTopology & cell,
02123 const int & whichCell,
02124 const double & threshold)
02125 {
02126 INTREPID_VALIDATE( validateArguments_checkPointwiseInclusion(inCell, points, cellWorkset, whichCell, cell) );
02127
02128
02129
02130 unsigned baseKey = cell.getBaseTopology() -> key;
02131
02132 switch(baseKey){
02133
02134 case shards::Line<>::key :
02135 case shards::Triangle<>::key:
02136 case shards::Quadrilateral<>::key :
02137 case shards::Tetrahedron<>::key :
02138 case shards::Hexahedron<>::key :
02139 case shards::Wedge<>::key :
02140 case shards::Pyramid<>::key :
02141 {
02142 FieldContainer<Scalar> refPoints;
02143
02144 if(points.rank() == 2){
02145 refPoints.resize(points.dimension(0), points.dimension(1) );
02146 mapToReferenceFrame(refPoints, points, cellWorkset, cell, whichCell);
02147 checkPointwiseInclusion(inCell, refPoints, cell, threshold );
02148 }
02149 else if(points.rank() == 3){
02150 refPoints.resize(points.dimension(0), points.dimension(1), points.dimension(2) );
02151 mapToReferenceFrame(refPoints, points, cellWorkset, cell, whichCell);
02152 checkPointwiseInclusion(inCell, refPoints, cell, threshold );
02153 }
02154 break;
02155 }
02156 default:
02157 TEST_FOR_EXCEPTION( true, std::invalid_argument,
02158 ">>> ERROR (Intrepid::CellTools::checkPointwiseInclusion): cell topology not supported");
02159 }
02160
02161 }
02162
02163
02164
02165
02166
02167
02168
02169
02170 template<class Scalar>
02171 template<class ArrayScalar>
02172 void CellTools<Scalar>::validateArguments_setJacobian(const ArrayScalar & jacobian,
02173 const ArrayScalar & points,
02174 const ArrayScalar & cellWorkset,
02175 const int & whichCell,
02176 const shards::CellTopology & cellTopo){
02177
02178
02179 TEST_FOR_EXCEPTION( (cellWorkset.rank() != 3), std::invalid_argument,
02180 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian): rank = 3 required for cellWorkset array");
02181
02182 TEST_FOR_EXCEPTION( (cellWorkset.dimension(0) <= 0), std::invalid_argument,
02183 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian): dim 0 (number of cells) >= 1 required for cellWorkset array");
02184
02185 TEST_FOR_EXCEPTION( (cellWorkset.dimension(1) != (int)cellTopo.getSubcellCount(0) ), std::invalid_argument,
02186 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian): dim 1 (number of cell nodes) of cellWorkset array does not match cell topology");
02187
02188 TEST_FOR_EXCEPTION( (cellWorkset.dimension(2) != (int)cellTopo.getDimension() ), std::invalid_argument,
02189 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian): dim 2 (spatial dimension) of cellWorkset array does not match cell dimension");
02190
02191
02192 TEST_FOR_EXCEPTION( !( ( (0 <= whichCell ) && (whichCell < cellWorkset.dimension(0) ) || (whichCell == -1) ) ), std::invalid_argument,
02193 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian): whichCell = -1 or a valid cell ordinal is required.");
02194
02195
02196
02197
02198 if(points.rank() == 2) {
02199 TEST_FOR_EXCEPTION( (points.dimension(0) <= 0), std::invalid_argument,
02200 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian): dim 0 (number of points) >= 1 required for points array ");
02201
02202 TEST_FOR_EXCEPTION( (points.dimension(1) != (int)cellTopo.getDimension() ), std::invalid_argument,
02203 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian): dim 1 (spatial dimension) of points array does not match cell dimension");
02204
02205
02206 if(whichCell == -1) {
02207 TEST_FOR_EXCEPTION( (jacobian.rank() != 4), std::invalid_argument,
02208 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian): rank = 4 required for jacobian array");
02209
02210 TEST_FOR_EXCEPTION( (jacobian.dimension(0) != cellWorkset.dimension(0)), std::invalid_argument,
02211 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian): dim 0 (number of cells) of jacobian array must equal dim 0 of cellWorkset array");
02212
02213 TEST_FOR_EXCEPTION( (jacobian.dimension(1) != points.dimension(0)), std::invalid_argument,
02214 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian): dim 1 (number of points) of jacobian array must equal dim 0 of points array");
02215
02216 TEST_FOR_EXCEPTION( (jacobian.dimension(2) != points.dimension(1)), std::invalid_argument,
02217 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian): dim 2 (spatial dimension) of jacobian array must equal dim 1 of points array");
02218
02219 TEST_FOR_EXCEPTION( !(jacobian.dimension(2) == jacobian.dimension(3) ), std::invalid_argument,
02220 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian): dim 2 = dim 3 (same spatial dimensions) required for jacobian array. ");
02221
02222 TEST_FOR_EXCEPTION( !( (0 < jacobian.dimension(3) ) && (jacobian.dimension(3) < 4) ), std::invalid_argument,
02223 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian): dim 2 and dim 3 (spatial dimensions) must be between 1 and 3. ");
02224 }
02225
02226 else {
02227 TEST_FOR_EXCEPTION( (jacobian.rank() != 3), std::invalid_argument,
02228 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian): rank = 3 required for jacobian array");
02229
02230 TEST_FOR_EXCEPTION( (jacobian.dimension(0) != points.dimension(0)), std::invalid_argument,
02231 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian): dim 0 (number of points) of jacobian array must equal dim 0 of points array");
02232
02233 TEST_FOR_EXCEPTION( (jacobian.dimension(1) != points.dimension(1)), std::invalid_argument,
02234 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian): dim 1 (spatial dimension) of jacobian array must equal dim 1 of points array");
02235
02236 TEST_FOR_EXCEPTION( !(jacobian.dimension(1) == jacobian.dimension(2) ), std::invalid_argument,
02237 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian): dim 1 = dim 2 (same spatial dimensions) required for jacobian array. ");
02238
02239 TEST_FOR_EXCEPTION( !( (0 < jacobian.dimension(1) ) && (jacobian.dimension(1) < 4) ), std::invalid_argument,
02240 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian): dim 1 and dim 2 (spatial dimensions) must be between 1 and 3. ");
02241 }
02242 }
02243
02244 else if(points.rank() ==3){
02245 std::string errmsg = ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian):";
02246 TEST_FOR_EXCEPTION( (points.dimension(0) != cellWorkset.dimension(0) ), std::invalid_argument,
02247 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian): dim 0 (number of cells) of points array must equal dim 0 of cellWorkset array");
02248
02249 TEST_FOR_EXCEPTION( (points.dimension(1) <= 0), std::invalid_argument,
02250 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian): dim 1 (number of points) >= 1 required for points array ");
02251
02252 TEST_FOR_EXCEPTION( (points.dimension(2) != (int)cellTopo.getDimension() ), std::invalid_argument,
02253 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian): dim 2 (spatial dimension) of points array does not match cell dimension");
02254
02255 TEST_FOR_EXCEPTION( (whichCell != -1), std::invalid_argument,
02256 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian): default value whichCell=-1 required for rank-3 input points");
02257
02258
02259 TEST_FOR_EXCEPTION( !requireRankRange(errmsg, jacobian, 4, 4), std::invalid_argument,errmsg);
02260
02261 TEST_FOR_EXCEPTION( (jacobian.dimension(0) != points.dimension(0)), std::invalid_argument,
02262 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian): dim 0 (number of cells) of jacobian array must equal dim 0 of points array");
02263
02264 TEST_FOR_EXCEPTION( (jacobian.dimension(1) != points.dimension(1)), std::invalid_argument,
02265 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian): dim 1 (number of points) of jacobian array must equal dim 1 of points array");
02266
02267 TEST_FOR_EXCEPTION( (jacobian.dimension(2) != points.dimension(2)), std::invalid_argument,
02268 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian): dim 2 (spatial dimension) of jacobian array must equal dim 2 of points array");
02269
02270 TEST_FOR_EXCEPTION( !(jacobian.dimension(2) == jacobian.dimension(3) ), std::invalid_argument,
02271 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian): dim 2 = dim 3 (same spatial dimensions) required for jacobian array. ");
02272
02273 TEST_FOR_EXCEPTION( !( (0 < jacobian.dimension(3) ) && (jacobian.dimension(3) < 4) ), std::invalid_argument,
02274 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian): dim 2 and dim 3 (spatial dimensions) must be between 1 and 3. ");
02275 }
02276 else {
02277 TEST_FOR_EXCEPTION( !( (points.rank() == 2) && (points.rank() ==3) ), std::invalid_argument,
02278 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobian): rank = 2 or 3 required for points array");
02279 }
02280 }
02281
02282
02283
02284 template<class Scalar>
02285 template<class ArrayScalar>
02286 void CellTools<Scalar>::validateArguments_setJacobianInv(const ArrayScalar & jacobianInv,
02287 const ArrayScalar & jacobian)
02288 {
02289
02290
02291 int jacobRank = jacobian.rank();
02292 TEST_FOR_EXCEPTION( !( (jacobRank == 4) || (jacobRank == 3) ), std::invalid_argument,
02293 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobianInv): rank = 4 or 3 required for jacobian array. ");
02294
02295
02296 TEST_FOR_EXCEPTION( !(jacobian.dimension(jacobRank - 1) == jacobian.dimension(jacobRank - 2) ), std::invalid_argument,
02297 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobianInv): dim(rank-2) = dim(rank-2) (same spatial dimensions) required for jacobian array. ");
02298
02299 TEST_FOR_EXCEPTION( !( (0 < jacobian.dimension(jacobRank - 1) ) && (jacobian.dimension(jacobRank - 1) < 4) ), std::invalid_argument,
02300 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobianInv): dim(rank-1) and dim(rank-2) (spatial dimensions) must be between 1 and 3. ");
02301
02302
02303 std::string errmsg = ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobianInv):";
02304
02305 TEST_FOR_EXCEPTION( !(requireRankMatch(errmsg, jacobianInv, jacobian) ), std::invalid_argument, errmsg);
02306
02307 TEST_FOR_EXCEPTION( !(requireDimensionMatch(errmsg, jacobianInv, jacobian) ), std::invalid_argument, errmsg);
02308 }
02309
02310
02311
02312 template<class Scalar>
02313 template<class ArrayScalar>
02314 void CellTools<Scalar>::validateArguments_setJacobianDetArgs(const ArrayScalar & jacobianDet,
02315 const ArrayScalar & jacobian)
02316 {
02317
02318
02319 int jacobRank = jacobian.rank();
02320 TEST_FOR_EXCEPTION( !( (jacobRank == 4) || (jacobRank == 3) ), std::invalid_argument,
02321 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobianInv): rank = 4 or 3 required for jacobian array. ");
02322
02323
02324 TEST_FOR_EXCEPTION( !(jacobian.dimension(jacobRank - 1) == jacobian.dimension(jacobRank - 2) ), std::invalid_argument,
02325 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobianInv): dim(rank-2) = dim(rank-2) (same spatial dimensions) required for jacobian array. ");
02326
02327 TEST_FOR_EXCEPTION( !( (0 < jacobian.dimension(jacobRank - 1) ) && (jacobian.dimension(jacobRank - 1) < 4) ), std::invalid_argument,
02328 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobianInv): dim(rank-1) and dim(rank-2) (spatial dimensions) must be between 1 and 3. ");
02329
02330
02331
02332 if(jacobRank == 4){
02333 TEST_FOR_EXCEPTION( !(jacobianDet.rank() == 2), std::invalid_argument,
02334 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobianDetArgs): rank = 2 required for jacobianDet if jacobian is rank-4. ");
02335
02336 TEST_FOR_EXCEPTION( !(jacobianDet.dimension(0) == jacobian.dimension(0) ), std::invalid_argument,
02337 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobianDetArgs): dim 0 (number of cells) of jacobianDet array must equal dim 0 of jacobian array. ");
02338
02339 TEST_FOR_EXCEPTION( !(jacobianDet.dimension(1) == jacobian.dimension(1) ), std::invalid_argument,
02340 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobianDetArgs): dim 1 (number of points) of jacobianDet array must equal dim 1 of jacobian array.");
02341 }
02342
02343
02344 else {
02345 TEST_FOR_EXCEPTION( !(jacobianDet.rank() == 1), std::invalid_argument,
02346 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobianDetArgs): rank = 1 required for jacobianDet if jacobian is rank-3. ");
02347
02348 TEST_FOR_EXCEPTION( !(jacobianDet.dimension(0) == jacobian.dimension(0) ), std::invalid_argument,
02349 ">>> ERROR (Intrepid::CellTools::validateArguments_setJacobianDetArgs): dim 0 (number of points) of jacobianDet array must equal dim 0 of jacobian array.");
02350 }
02351 }
02352
02353
02354
02355 template<class Scalar>
02356 template<class ArrayScalar>
02357 void CellTools<Scalar>::validateArguments_mapToPhysicalFrame(const ArrayScalar & physPoints,
02358 const ArrayScalar & refPoints,
02359 const ArrayScalar & cellWorkset,
02360 const shards::CellTopology & cellTopo,
02361 const int& whichCell)
02362 {
02363 std::string errmsg = ">>> ERROR (Intrepid::CellTools::validateArguments_mapToPhysicalFrame):";
02364
02365
02366 TEST_FOR_EXCEPTION( (cellWorkset.rank() != 3), std::invalid_argument,
02367 ">>> ERROR (Intrepid::CellTools::validateArguments_mapToPhysicalFrame): rank = 3 required for cellWorkset array");
02368
02369 TEST_FOR_EXCEPTION( (cellWorkset.dimension(0) <= 0), std::invalid_argument,
02370 ">>> ERROR (Intrepid::CellTools::validateArguments_mapToPhysicalFrame): dim 0 (number of cells) >= 1 required for cellWorkset array");
02371
02372 TEST_FOR_EXCEPTION( (cellWorkset.dimension(1) != (int)cellTopo.getSubcellCount(0) ), std::invalid_argument,
02373 ">>> ERROR (Intrepid::CellTools::validateArguments_mapToPhysicalFrame): dim 1 (number of cell nodes) of cellWorkset array does not match cell topology");
02374
02375 TEST_FOR_EXCEPTION( (cellWorkset.dimension(2) != (int)cellTopo.getDimension() ), std::invalid_argument,
02376 ">>> ERROR (Intrepid::CellTools::validateArguments_mapToPhysicalFrame): dim 2 (spatial dimension) of cellWorkset array does not match cell dimension");
02377
02378
02379
02380 TEST_FOR_EXCEPTION( !( ( (0 <= whichCell ) && (whichCell < cellWorkset.dimension(0) ) || (whichCell == -1) ) ), std::invalid_argument,
02381 ">>> ERROR (Intrepid::CellTools::validateArguments_mapToPhysicalFrame): whichCell = -1 or a valid cell ordinal is required.");
02382
02383
02384
02385 if(refPoints.rank() == 2) {
02386 TEST_FOR_EXCEPTION( (refPoints.dimension(0) <= 0), std::invalid_argument,
02387 ">>> ERROR (Intrepid::CellTools::validateArguments_mapToPhysicalFrame): dim 0 (number of points) >= 1 required for refPoints array ");
02388
02389 TEST_FOR_EXCEPTION( (refPoints.dimension(1) != (int)cellTopo.getDimension() ), std::invalid_argument,
02390 ">>> ERROR (Intrepid::CellTools::validateArguments_mapToPhysicalFrame): dim 1 (spatial dimension) of refPoints array does not match cell dimension");
02391
02392
02393 if(whichCell == -1) {
02394 TEST_FOR_EXCEPTION( ( (physPoints.rank() != 3) && (whichCell == -1) ), std::invalid_argument,
02395 ">>> ERROR (Intrepid::CellTools::validateArguments_mapToPhysicalFrame): rank = 3 required for physPoints array for the default whichCell value");
02396
02397 TEST_FOR_EXCEPTION( (physPoints.dimension(0) != cellWorkset.dimension(0)), std::invalid_argument,
02398 ">>> ERROR (Intrepid::CellTools::validateArguments_mapToPhysicalFrame): dim 0 (number of cells) of physPoints array must equal dim 0 of cellWorkset array");
02399
02400 TEST_FOR_EXCEPTION( (physPoints.dimension(1) != refPoints.dimension(0)), std::invalid_argument,
02401 ">>> ERROR (Intrepid::CellTools::validateArguments_mapToPhysicalFrame): dim 1 (number of points) of physPoints array must equal dim 0 of refPoints array");
02402
02403 TEST_FOR_EXCEPTION( (physPoints.dimension(2) != (int)cellTopo.getDimension()), std::invalid_argument,
02404 ">>> ERROR (Intrepid::CellTools::validateArguments_mapToPhysicalFrame): dim 2 (spatial dimension) does not match cell dimension ");
02405 }
02406
02407 else{
02408 TEST_FOR_EXCEPTION( (physPoints.rank() != 2), std::invalid_argument,
02409 ">>> ERROR (Intrepid::CellTools::validateArguments_mapToPhysicalFrame): rank = 2 required for physPoints array");
02410
02411 TEST_FOR_EXCEPTION( (physPoints.dimension(0) != refPoints.dimension(0)), std::invalid_argument,
02412 ">>> ERROR (Intrepid::CellTools::validateArguments_mapToPhysicalFrame): dim 0 (number of points) of physPoints array must equal dim 0 of refPoints array");
02413
02414 TEST_FOR_EXCEPTION( (physPoints.dimension(1) != (int)cellTopo.getDimension()), std::invalid_argument,
02415 ">>> ERROR (Intrepid::CellTools::validateArguments_mapToPhysicalFrame): dim 1 (spatial dimension) does not match cell dimension ");
02416 }
02417 }
02418
02419 else if(refPoints.rank() == 3) {
02420
02421
02422 TEST_FOR_EXCEPTION( (refPoints.dimension(0) != cellWorkset.dimension(0) ), std::invalid_argument,
02423 ">>> ERROR (Intrepid::CellTools::validateArguments_mapToPhysicalFrame): dim 0 (number of cells) of refPoints and cellWorkset arraya are required to match ");
02424
02425 TEST_FOR_EXCEPTION( (refPoints.dimension(1) <= 0), std::invalid_argument,
02426 ">>> ERROR (Intrepid::CellTools::validateArguments_mapToPhysicalFrame): dim 1 (number of points) >= 1 required for refPoints array ");
02427
02428 TEST_FOR_EXCEPTION( (refPoints.dimension(2) != (int)cellTopo.getDimension() ), std::invalid_argument,
02429 ">>> ERROR (Intrepid::CellTools::validateArguments_mapToPhysicalFrame): dim 2 (spatial dimension) of refPoints array does not match cell dimension");
02430
02431
02432 TEST_FOR_EXCEPTION( (whichCell != -1), std::invalid_argument,
02433 ">>> ERROR (Intrepid::CellTools::validateArguments_mapToPhysicalFrame): default value is required for rank-3 refPoints array");
02434
02435
02436 TEST_FOR_EXCEPTION( !requireRankMatch(errmsg, refPoints, physPoints), std::invalid_argument, errmsg );
02437 TEST_FOR_EXCEPTION( !requireDimensionMatch(errmsg, refPoints, physPoints), std::invalid_argument, errmsg);
02438 }
02439
02440 else {
02441 TEST_FOR_EXCEPTION( !( (refPoints.rank() == 2) || (refPoints.rank() == 3) ), std::invalid_argument,
02442 ">>> ERROR (Intrepid::CellTools::validateArguments_mapToPhysicalFrame): rank = 2 or 3 required for refPoints array");
02443 }
02444 }
02445
02446
02447
02448 template<class Scalar>
02449 template<class ArrayScalar>
02450 void CellTools<Scalar>::validateArguments_mapToReferenceFrame(const ArrayScalar & refPoints,
02451 const ArrayScalar & physPoints,
02452 const ArrayScalar & cellWorkset,
02453 const shards::CellTopology & cellTopo,
02454 const int& whichCell)
02455 {
02456 std::string errmsg = ">>> ERROR (Intrepid::CellTools::validateArguments_mapToReferenceFrame):";
02457 std::string errmsg1 = ">>> ERROR (Intrepid::CellTools::validateArguments_mapToReferenceFrame):";
02458
02459
02460 TEST_FOR_EXCEPTION( (cellWorkset.rank() != 3), std::invalid_argument,
02461 ">>> ERROR (Intrepid::CellTools::validateArguments_mapToReferenceFrame): rank = 3 required for cellWorkset array");
02462
02463 TEST_FOR_EXCEPTION( (cellWorkset.dimension(0) <= 0), std::invalid_argument,
02464 ">>> ERROR (Intrepid::CellTools::validateArguments_mapToReferenceFrame): dim 0 (number of cells) >= 1 required for cellWorkset array");
02465
02466 TEST_FOR_EXCEPTION( (cellWorkset.dimension(1) != (int)cellTopo.getSubcellCount(0) ), std::invalid_argument,
02467 ">>> ERROR (Intrepid::CellTools::validateArguments_mapToReferenceFrame): dim 1 (number of cell nodes) of cellWorkset array does not match cell topology");
02468
02469 TEST_FOR_EXCEPTION( (cellWorkset.dimension(2) != (int)cellTopo.getDimension() ), std::invalid_argument,
02470 ">>> ERROR (Intrepid::CellTools::validateArguments_mapToReferenceFrame): dim 2 (spatial dimension) of cellWorkset array does not match cell dimension");
02471
02472
02473 TEST_FOR_EXCEPTION( !( ( (0 <= whichCell ) && (whichCell < cellWorkset.dimension(0) ) || (whichCell == -1) ) ), std::invalid_argument,
02474 ">>> ERROR (Intrepid::CellTools::validateArguments_mapToReferenceFrame): whichCell = -1 or a valid cell ordinal is required.");
02475
02476
02477
02478 int validRank;
02479 if(whichCell == -1) {
02480 validRank = 3;
02481 errmsg1 += " default value of whichCell requires rank-3 arrays:";
02482 }
02483
02484 else{
02485 errmsg1 += " rank-2 arrays required when whichCell is valid cell ordinal";
02486 validRank = 2;
02487 }
02488 TEST_FOR_EXCEPTION( !requireRankRange(errmsg1, refPoints, validRank,validRank), std::invalid_argument, errmsg1);
02489 TEST_FOR_EXCEPTION( !requireRankMatch(errmsg1, physPoints, refPoints), std::invalid_argument, errmsg1);
02490 TEST_FOR_EXCEPTION( !requireDimensionMatch(errmsg1, refPoints, physPoints), std::invalid_argument, errmsg1);
02491 }
02492
02493
02494
02495 template<class Scalar>
02496 template<class ArrayType1, class ArrayType2>
02497 void CellTools<Scalar>::validateArguments_mapToReferenceFrame(const ArrayType1 & refPoints,
02498 const ArrayType2 & initGuess,
02499 const ArrayType1 & physPoints,
02500 const ArrayType1 & cellWorkset,
02501 const shards::CellTopology & cellTopo,
02502 const int& whichCell)
02503 {
02504
02505 validateArguments_mapToReferenceFrame(refPoints, physPoints, cellWorkset, cellTopo, whichCell);
02506
02507
02508 std::string errmsg = ">>> ERROR (Intrepid::CellTools::validateArguments_mapToReferenceFrame):";
02509 TEST_FOR_EXCEPTION( !requireDimensionMatch(errmsg, initGuess, physPoints), std::invalid_argument, errmsg);
02510 }
02511
02512
02513 template<class Scalar>
02514 template<class ArrayInt, class ArrayPoint, class ArrayScalar>
02515 void CellTools<Scalar>::validateArguments_checkPointwiseInclusion(ArrayInt & inCell,
02516 const ArrayPoint & physPoints,
02517 const ArrayScalar & cellWorkset,
02518 const int & whichCell,
02519 const shards::CellTopology & cell)
02520 {
02521
02522 TEST_FOR_EXCEPTION( (cellWorkset.rank() != 3), std::invalid_argument,
02523 ">>> ERROR (Intrepid::CellTools::validateArguments_checkPointwiseInclusion): rank = 3 required for cellWorkset array");
02524
02525 TEST_FOR_EXCEPTION( (cellWorkset.dimension(0) <= 0), std::invalid_argument,
02526 ">>> ERROR (Intrepid::CellTools::validateArguments_checkPointwiseInclusion): dim 0 (number of cells) >= 1 required for cellWorkset array");
02527
02528 TEST_FOR_EXCEPTION( (cellWorkset.dimension(1) != (int)cell.getSubcellCount(0) ), std::invalid_argument,
02529 ">>> ERROR (Intrepid::CellTools::validateArguments_checkPointwiseInclusion): dim 1 (number of cell nodes) of cellWorkset array does not match cell topology");
02530
02531 TEST_FOR_EXCEPTION( (cellWorkset.dimension(2) != (int)cell.getDimension() ), std::invalid_argument,
02532 ">>> ERROR (Intrepid::CellTools::validateArguments_checkPointwiseInclusion): dim 2 (spatial dimension) of cellWorkset array does not match cell dimension");
02533
02534
02535
02536 TEST_FOR_EXCEPTION( !( ( (0 <= whichCell ) && (whichCell < cellWorkset.dimension(0) ) || (whichCell == -1) ) ), std::invalid_argument,
02537 ">>> ERROR (Intrepid::CellTools::validateArguments_checkPointwiseInclusion): whichCell = -1 or a valid cell ordinal is required.");
02538
02539
02540
02541
02542 if(physPoints.rank() == 2) {
02543
02544 TEST_FOR_EXCEPTION( (whichCell == -1), std::invalid_argument,
02545 ">>> ERROR (Intrepid::CellTools::validateArguments_checkPointwiseInclusion): whichCell = a valid cell ordinal is required with rank-2 input array.");
02546
02547 TEST_FOR_EXCEPTION( (physPoints.dimension(0) <= 0), std::invalid_argument,
02548 ">>> ERROR (Intrepid::CellTools::validateArguments_checkPointwiseInclusion): dim 0 (number of points) >= 1 required for physPoints array ");
02549
02550 TEST_FOR_EXCEPTION( (physPoints.dimension(1) != (int)cell.getDimension() ), std::invalid_argument,
02551 ">>> ERROR (Intrepid::CellTools::validateArguments_checkPointwiseInclusion): dim 1 (spatial dimension) of physPoints array does not match cell dimension");
02552
02553
02554 TEST_FOR_EXCEPTION( (inCell.rank() != 1), std::invalid_argument,
02555 ">>> ERROR (Intrepid::CellTools::validateArguments_checkPointwiseInclusion): rank = 1 required for inCell array");
02556
02557 TEST_FOR_EXCEPTION( (inCell.dimension(0) != physPoints.dimension(0)), std::invalid_argument,
02558 ">>> ERROR (Intrepid::CellTools::validateArguments_checkPointwiseInclusion): dim 0 (number of points) of inCell array must equal dim 0 of physPoints array");
02559 }
02560
02561 else if (physPoints.rank() == 3){
02562
02563 TEST_FOR_EXCEPTION( !(whichCell == -1), std::invalid_argument,
02564 ">>> ERROR (Intrepid::CellTools::validateArguments_checkPointwiseInclusion): whichCell = -1 is required with rank-3 input array.");
02565
02566 TEST_FOR_EXCEPTION( (physPoints.dimension(0) != cellWorkset.dimension(0) ), std::invalid_argument,
02567 ">>> ERROR (Intrepid::CellTools::validateArguments_checkPointwiseInclusion): dim 0 (number of cells) of physPoints array must equal dim 0 of cellWorkset array ");
02568
02569 TEST_FOR_EXCEPTION( (physPoints.dimension(1) <= 0), std::invalid_argument,
02570 ">>> ERROR (Intrepid::CellTools::validateArguments_checkPointwiseInclusion): dim 1 (number of points) >= 1 required for physPoints array ");
02571
02572 TEST_FOR_EXCEPTION( (physPoints.dimension(2) != (int)cell.getDimension() ), std::invalid_argument,
02573 ">>> ERROR (Intrepid::CellTools::validateArguments_checkPointwiseInclusion): dim 2 (spatial dimension) of physPoints array does not match cell dimension");
02574
02575
02576 TEST_FOR_EXCEPTION( (inCell.rank() != 2), std::invalid_argument,
02577 ">>> ERROR (Intrepid::CellTools::validateArguments_checkPointwiseInclusion): rank = 2 required for inCell array");
02578
02579 TEST_FOR_EXCEPTION( (inCell.dimension(0) != physPoints.dimension(0)), std::invalid_argument,
02580 ">>> ERROR (Intrepid::CellTools::validateArguments_checkPointwiseInclusion): dim 0 (number of cells) of inCell array must equal dim 0 of physPoints array");
02581
02582 TEST_FOR_EXCEPTION( (inCell.dimension(1) != physPoints.dimension(1)), std::invalid_argument,
02583 ">>> ERROR (Intrepid::CellTools::validateArguments_checkPointwiseInclusion): dim 1 (number of points) of inCell array must equal dim 1 of physPoints array");
02584 }
02585 else {
02586 TEST_FOR_EXCEPTION( !( (physPoints.rank() == 2) && (physPoints.rank() ==3) ), std::invalid_argument,
02587 ">>> ERROR (Intrepid::CellTools::validateArguments_checkPointwiseInclusion): rank = 2 or 3 required for points array");
02588 }
02589 }
02590
02591
02592
02593
02594
02595
02596
02597
02598
02599
02600 template<class Scalar>
02601 void CellTools<Scalar>::printSubcellVertices(const int subcellDim,
02602 const int subcellOrd,
02603 const shards::CellTopology & parentCell){
02604
02605
02606 int subcVertexCount = parentCell.getVertexCount(subcellDim, subcellOrd);
02607 int cellDim = parentCell.getDimension();
02608
02609
02610 FieldContainer<double> subcellVertices(subcVertexCount, cellDim);
02611
02612
02613 getReferenceSubcellVertices(subcellVertices,
02614 subcellDim,
02615 subcellOrd,
02616 parentCell);
02617
02618
02619 std::cout
02620 << " Subcell " << std::setw(2) << subcellOrd
02621 << " is " << parentCell.getName(subcellDim, subcellOrd) << " with vertices = {";
02622
02623
02624 for(int subcVertOrd = 0; subcVertOrd < subcVertexCount; subcVertOrd++){
02625 std::cout<< "(";
02626
02627
02628 for(int dim = 0; dim < (int)parentCell.getDimension(); dim++){
02629 std::cout << subcellVertices(subcVertOrd, dim);
02630 if(dim < (int)parentCell.getDimension()-1 ) { std::cout << ","; }
02631 }
02632 std::cout<< ")";
02633 if(subcVertOrd < subcVertexCount - 1) { std::cout << ", "; }
02634 }
02635 std::cout << "}\n";
02636 }
02637
02638
02639 template<class Scalar>
02640 template<class ArrayTypeIn>
02641 void CellTools<Scalar>::printWorksetSubcell(const ArrayTypeIn& cellWorkset,
02642 const shards::CellTopology& parentCell,
02643 const int& pCellOrd,
02644 const int& subcellDim,
02645 const int& subcellOrd,
02646 const int& fieldWidth){
02647
02648
02649 int subcNodeCount = parentCell.getNodeCount(subcellDim, subcellOrd);
02650 int pCellDim = parentCell.getDimension();
02651 std::vector<int> subcNodeOrdinals(subcNodeCount);
02652
02653 for(int i = 0; i < subcNodeCount; i++){
02654 subcNodeOrdinals[i] = parentCell.getNodeMap(subcellDim, subcellOrd, i);
02655 }
02656
02657
02658
02659 std::cout
02660 << " Subcell " << subcellOrd << " on parent cell " << pCellOrd << " is "
02661 << parentCell.getName(subcellDim, subcellOrd) << " with node(s) \n ({";
02662
02663 for(int i = 0; i < subcNodeCount; i++){
02664
02665
02666 for(int dim = 0; dim < pCellDim; dim++){
02667 std::cout
02668 << std::setw(fieldWidth) << std::right << cellWorkset(pCellOrd, subcNodeOrdinals[i], dim);
02669 if(dim < pCellDim - 1){ std::cout << ","; }
02670 }
02671 std::cout << "}";
02672 if(i < subcNodeCount - 1){ std::cout <<", {"; }
02673 }
02674 std::cout << ")\n\n";
02675 }
02676
02677
02678
02679 }