|
Intrepid
|
00001 // @HEADER 00002 // ************************************************************************ 00003 // 00004 // Intrepid Package 00005 // Copyright (2007) Sandia Corporation 00006 // 00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00008 // license for use of this work by or on behalf of the U.S. Government. 00009 // 00010 // This library is free software; you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as 00012 // published by the Free Software Foundation; either version 2.1 of the 00013 // License, or (at your option) any later version. 00014 // 00015 // This library is distributed in the hope that it will be useful, but 00016 // WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 // Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public 00021 // License along with this library; if not, write to the Free Software 00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00023 // USA 00024 // Questions? Contact Pavel Bochev (pbboche@sandia.gov) or 00025 // Denis Ridzal (dridzal@sandia.gov) 00026 // Kara Peterson (kjpeter@sandia.gov) 00027 // 00028 // ************************************************************************ 00029 // @HEADER 00030 00031 00036 #include "Intrepid_FieldContainer.hpp" 00037 #include "Intrepid_CellTools.hpp" 00038 #include "Intrepid_RealSpaceTools.hpp" 00039 #include "Shards_CellTopology.hpp" 00040 #include "Teuchos_GlobalMPISession.hpp" 00041 00042 using namespace std; 00043 using namespace Intrepid; 00044 using namespace shards; 00045 00046 int main(int argc, char *argv[]) { 00047 00048 Teuchos::GlobalMPISession mpiSession(&argc, &argv); 00049 00050 std::cout \ 00051 << "===============================================================================\n" \ 00052 << "| |\n" \ 00053 << "| Example use of the CellTools class |\n" \ 00054 << "| |\n" \ 00055 << "| 1) Using shards::CellTopology to get cell types and topology |\n" \ 00056 << "| 2) Using CellTools to get cell Jacobians and their inverses and dets |\n" \ 00057 << "| 3) Testing points for inclusion in reference and physical cells |\n" \ 00058 << "| 4) Mapping points to and from reference cells with base and extended |\n" \ 00059 << "| topologies. |\n" \ 00060 << "| |\n" \ 00061 << "| Questions? Contact Pavel Bochev (pbboche@sandia.gov) or |\n" \ 00062 << "| Denis Ridzal (dridzal@sandia.gov) |\n" \ 00063 << "| Kara Peterson (kjpeter@sandia.gov). |\n" \ 00064 << "| |\n" \ 00065 << "| Intrepid's website: http://trilinos.sandia.gov/packages/intrepid |\n" \ 00066 << "| Shards's website: http://trilinos.sandia.gov/packages/shards |\n" \ 00067 << "| Trilinos website: http://trilinos.sandia.gov |\n" \ 00068 << "| |\n" \ 00069 << "===============================================================================\n"\ 00070 << "| EXAMPLE 1: Query of cell types and topology |\n"\ 00071 << "===============================================================================\n"; 00072 00073 00074 typedef CellTools<double> CellTools; 00075 typedef RealSpaceTools<double> RealSpaceTools; 00076 typedef shards::CellTopology CellTopology; 00077 00078 00079 // Vector to hold cell topologies 00080 std::vector<CellTopology> shardsTopologies; 00081 00082 00083 // All 2D cell topologies in Shards: 00084 int cellDim = 2; 00085 shards::getTopologies(shardsTopologies, cellDim); 00086 std::cout << "Number of all " << cellDim 00087 << "D Shards cell topologies = " << shardsTopologies.size() << "\n\n"; 00088 00089 for(unsigned i = 0; i < shardsTopologies.size(); i++){ 00090 std::cout << shardsTopologies[i].getName() << "\n"; 00091 } 00092 std::cout <<"\n"; 00093 00094 00095 // All standard 2D cell topologies in Shards: 00096 shards::getTopologies(shardsTopologies, cellDim, 00097 shards::STANDARD_CELL); 00098 std::cout << "Number of all " 00099 << cellDim << "D standard Shards cell topologies = " << shardsTopologies.size() << "\n\n"; 00100 00101 for(unsigned i = 0; i < shardsTopologies.size(); i++){ 00102 std::cout << shardsTopologies[i].getName() << "\n"; 00103 } 00104 std::cout <<"\n"; 00105 00106 00107 // All standard 2D cells with base topologies in Shards: 00108 shards::getTopologies(shardsTopologies, cellDim, 00109 shards::STANDARD_CELL, 00110 shards::BASE_TOPOLOGY); 00111 std::cout << "Number of all " << cellDim 00112 << "D standard Shards cells with base topologies = " << shardsTopologies.size() << "\n\n"; 00113 00114 for(unsigned i = 0; i < shardsTopologies.size(); i++){ 00115 std::cout << shardsTopologies[i].getName() << "\n"; 00116 } 00117 std::cout <<"\n"; 00118 00119 00120 // All standard 2D cells with extended topologies in Shards: 00121 shards::getTopologies(shardsTopologies, cellDim, 00122 shards::STANDARD_CELL, 00123 shards::EXTENDED_TOPOLOGY); 00124 std::cout << "Number of all " << cellDim 00125 << "D standard Shards cells with extended topologies = " << shardsTopologies.size() << "\n\n"; 00126 00127 for(unsigned i = 0; i < shardsTopologies.size(); i++){ 00128 std::cout << shardsTopologies[i].getName() << "\n"; 00129 } 00130 std::cout <<"\n"; 00131 00132 00133 // All non-standard 2D cells with base topologies in Shards: 00134 shards::getTopologies(shardsTopologies, cellDim, 00135 shards::NONSTANDARD_CELL, 00136 shards::BASE_TOPOLOGY); 00137 std::cout << "Number of all " << cellDim 00138 << "D non-standard Shards cells with base topologies = " << shardsTopologies.size() << "\n\n"; 00139 00140 for(unsigned i = 0; i < shardsTopologies.size(); i++){ 00141 std::cout << shardsTopologies[i].getName() << "\n"; 00142 } 00143 std::cout <<"\n"; 00144 00145 00146 // All non-standard 2D cells with extended topologies in Shards: 00147 shards::getTopologies(shardsTopologies, cellDim, 00148 shards::NONSTANDARD_CELL, 00149 shards::EXTENDED_TOPOLOGY); 00150 std::cout << "Number of all " << cellDim 00151 << "D non-standard Shards cells with extended topologies = " << shardsTopologies.size() << "\n\n"; 00152 00153 for(unsigned i = 0; i < shardsTopologies.size(); i++){ 00154 std::cout << shardsTopologies[i].getName() << "\n"; 00155 } 00156 std::cout <<"\n"; 00157 00158 // Finally, get all shards cell topologies and print them! 00159 shards::getTopologies(shardsTopologies); 00160 std::cout << "Number of all Shards cell topologies = " << shardsTopologies.size() << "\n\n"; 00161 for(unsigned i = 0; i < shardsTopologies.size(); i++){ 00162 std::cout << shardsTopologies[i] << "\n"; 00163 } 00164 std::cout <<"\n"; 00165 00166 00167 00168 cout \ 00169 << "===============================================================================\n"\ 00170 << "| EXAMPLE 2: Using CellTools to get Jacobian, Jacobian inverse & Jacobian det |\n"\ 00171 << "===============================================================================\n"; 00172 00173 // 4 triangles with basic triangle topology: number of nodes = number of vertices 00174 CellTopology triangle_3(shards::getCellTopologyData<Triangle<3> >() ); 00175 int numCells = 4; 00176 int numNodes = triangle_3.getNodeCount(); 00177 int spaceDim = triangle_3.getDimension(); 00178 00179 // Rank-3 array with dimensions (C,N,D) for the node coordinates of 3 traingle cells 00180 FieldContainer<double> triNodes(numCells, numNodes, spaceDim); 00181 00182 // Initialize node data: accessor is (cellOrd, nodeOrd, coordinateOrd) 00183 triNodes(0, 0, 0) = 0.0; triNodes(0, 0, 1) = 0.0; // 1st triangle = the reference tri 00184 triNodes(0, 1, 0) = 1.0; triNodes(0, 1, 1) = 0.0; 00185 triNodes(0, 2, 0) = 0.0; triNodes(0, 2, 1) = 1.0; 00186 00187 triNodes(1, 0, 0) = 1.0; triNodes(1, 0, 1) = 1.0; // 2nd triangle = 1st shifted by (1,1) 00188 triNodes(1, 1, 0) = 2.0; triNodes(1, 1, 1) = 1.0; 00189 triNodes(1, 2, 0) = 1.0; triNodes(1, 2, 1) = 2.0; 00190 00191 triNodes(2, 0, 0) = 0.0; triNodes(2, 0, 1) = 0.0; // 3rd triangle = flip 1st vertical 00192 triNodes(2, 1, 0) =-1.0; triNodes(2, 1, 1) = 0.0; 00193 triNodes(2, 2, 0) = 0.0; triNodes(2, 2, 1) = 1.0; 00194 00195 triNodes(3, 0, 0) = 2.0; triNodes(3, 0, 1) = 1.0; // 4th triangle = just a triangle 00196 triNodes(3, 1, 0) = 3.0; triNodes(3, 1, 1) = 0.5; 00197 triNodes(3, 2, 0) = 3.5; triNodes(3, 2, 1) = 2.0; 00198 00199 00200 // Rank-2 array with dimensions (P,D) for some points on the reference triangle 00201 int numRefPoints = 2; 00202 FieldContainer<double> refPoints(numRefPoints, spaceDim); 00203 refPoints(0,0) = 0.0; refPoints(0,1) = 0.0; 00204 refPoints(1,0) = 0.5; refPoints(1,1) = 0.5; 00205 00206 00207 // Rank-4 array (C,P,D,D) for the Jacobian and its inverse and Rank-2 array (C,P) for its determinant 00208 FieldContainer<double> triJacobian(numCells, numRefPoints, spaceDim, spaceDim); 00209 FieldContainer<double> triJacobInv(numCells, numRefPoints, spaceDim, spaceDim); 00210 FieldContainer<double> triJacobDet(numCells, numRefPoints); 00211 00212 // Rank-4 and Rank-2 auxiliary arrays 00213 FieldContainer<double> rank4Aux (numCells, numRefPoints, spaceDim, spaceDim); 00214 FieldContainer<double> rank2Aux (numCells, numRefPoints); 00215 00216 00217 // Methods to compute cell Jacobians, their inverses and their determinants 00218 CellTools::setJacobian(triJacobian, refPoints, triNodes, triangle_3); 00219 CellTools::setJacobianInv(triJacobInv, triJacobian ); 00220 CellTools::setJacobianDet(triJacobDet, triJacobian ); 00221 00222 // Checks: compute det(Inv(DF)) and Inv(Inv(DF)) 00223 RealSpaceTools::det(rank2Aux, triJacobInv); 00224 RealSpaceTools::inverse(rank4Aux, triJacobInv); 00225 00226 // Print data 00227 std::cout 00228 << std::scientific<< std::setprecision(4) 00229 << std::right << std::setw(16) << "DF(P)" 00230 << std::right << std::setw(30) << "Inv(DF(P))" 00231 << std::right << std::setw(30) << "Inv(Inv(DF(P)))\n"; 00232 00233 for(int cellOrd = 0; cellOrd < numCells; cellOrd++){ 00234 std::cout 00235 << "===============================================================================\n" 00236 << "Cell " << cellOrd << "\n"; 00237 for(int pointOrd = 0; pointOrd < numRefPoints; pointOrd++){ 00238 std::cout << "Point = (" 00239 << std::setw(4) << std::right << refPoints(pointOrd, 0) << ","<< std::setw(4) << std::right<< refPoints(pointOrd,1) << ")\n"; 00240 for(int row = 0; row < spaceDim; row++){ 00241 std::cout 00242 << std::setw(11) << std::right << triJacobian(cellOrd, pointOrd, row, 0) << " " 00243 << std::setw(11) << std::right << triJacobian(cellOrd, pointOrd, row, 1) 00244 // 00245 << std::setw(16) << std::right << triJacobInv(cellOrd, pointOrd, row, 0) << " " 00246 << std::setw(11) << std::right << triJacobInv(cellOrd, pointOrd, row, 1) 00247 // 00248 << std::setw(16) << std::right << rank4Aux(cellOrd, pointOrd, row, 0) << " " 00249 << std::setw(11) << std::right << rank4Aux(cellOrd, pointOrd, row, 1) << "\n"; 00250 } 00251 std::cout 00252 << setw(5)<<std::left<< "Determinant:\n" 00253 << std::setw(11) << std::right << triJacobDet(cellOrd, pointOrd) 00254 << std::setw(28) << std::right << rank2Aux(cellOrd, pointOrd) 00255 << std::setw(28) << std::right << " product = " << triJacobDet(cellOrd, pointOrd)*rank2Aux(cellOrd, pointOrd); 00256 std::cout<< "\n\n"; 00257 } 00258 } 00259 00260 00261 // 2 Quadrilateral cells with base topology 00262 CellTopology quad_4(shards::getCellTopologyData<Quadrilateral<4> >() ); 00263 numCells = 2; 00264 numNodes = quad_4.getNodeCount(); 00265 spaceDim = quad_4.getDimension(); 00266 00267 FieldContainer<double> quadNodes(numCells, numNodes, spaceDim); 00268 // 1st QUAD 00269 quadNodes(0,0,0) = 1.00; quadNodes(0,0,1) = 1.00; 00270 quadNodes(0,1,0) = 2.00; quadNodes(0,1,1) = 0.75; 00271 quadNodes(0,2,0) = 1.75; quadNodes(0,2,1) = 2.00; 00272 quadNodes(0,3,0) = 1.25; quadNodes(0,3,1) = 2.00, 00273 // 2ND QUAD 00274 quadNodes(1,0,0) = 2.00; quadNodes(1,0,1) = 0.75; 00275 quadNodes(1,1,0) = 3.00; quadNodes(1,1,1) = 1.25; 00276 quadNodes(1,2,0) = 2.75; quadNodes(1,2,1) = 2.25; 00277 quadNodes(1,3,0) = 1.75; quadNodes(1,3,1) = 2.00; 00278 00279 00280 00281 // 1 Hexahedron cell with base topology: number of nodes = number of vertices 00282 CellTopology hex_8(shards::getCellTopologyData<Hexahedron<8> >() ); 00283 numCells = 1; 00284 numNodes = hex_8.getNodeCount(); 00285 spaceDim = hex_8.getDimension(); 00286 00287 FieldContainer<double> hexNodes(numCells, numNodes, spaceDim); 00288 hexNodes(0,0,0) = 00289 // bottom face vertices 00290 hexNodes(0,0,0) = 1.00; hexNodes(0,0,1) = 1.00; hexNodes(0,0,2) = 0.00; 00291 hexNodes(0,1,0) = 2.00; hexNodes(0,1,1) = 0.75; hexNodes(0,1,2) =-0.25; 00292 hexNodes(0,2,0) = 1.75; hexNodes(0,2,1) = 2.00; hexNodes(0,2,2) = 0.00; 00293 hexNodes(0,3,0) = 1.25; hexNodes(0,3,1) = 2.00; hexNodes(0,3,1) = 0.25; 00294 // top face vertices 00295 hexNodes(0,4,0) = 1.25; hexNodes(0,4,1) = 0.75; hexNodes(0,4,2) = 0.75; 00296 hexNodes(0,5,0) = 1.75; hexNodes(0,5,1) = 1.00; hexNodes(0,5,2) = 1.00; 00297 hexNodes(0,6,0) = 2.00; hexNodes(0,6,1) = 2.00; hexNodes(0,6,2) = 1.25; 00298 hexNodes(0,7,0) = 1.00; hexNodes(0,7,1) = 2.00; hexNodes(0,7,2) = 1.00; 00299 00300 00301 00302 std::cout << std::setprecision(16) << "\n" \ 00303 << "===============================================================================\n"\ 00304 << "| EXAMPLE 3: Using single point inclusion test method |\n"\ 00305 << "===============================================================================\n"; 00306 00307 // Define cell topologies 00308 CellTopology edge3(shards::getCellTopologyData<Line<3> >() ); 00309 CellTopology tri6 (shards::getCellTopologyData<Triangle<6> >() ); 00310 CellTopology quad9(shards::getCellTopologyData<Quadrilateral<9> >() ); 00311 CellTopology tet4 (shards::getCellTopologyData<Tetrahedron<> >() ); 00312 CellTopology hex27(shards::getCellTopologyData<Hexahedron<27> >() ); 00313 CellTopology wedge(shards::getCellTopologyData<Wedge<> >() ); 00314 CellTopology pyr (shards::getCellTopologyData<Pyramid<> >() ); 00315 00316 // Points that are close to the boundaries of their reference cells 00317 double point_in_edge[1] = {1.0-INTREPID_EPSILON}; 00318 double point_in_quad[2] = {1.0, 1.0-INTREPID_EPSILON}; 00319 double point_in_tri[2] = {0.5-INTREPID_EPSILON, 0.5-INTREPID_EPSILON}; 00320 double point_in_tet[3] = {0.5-INTREPID_EPSILON, 0.5-INTREPID_EPSILON, 2.0*INTREPID_EPSILON}; 00321 double point_in_hex[3] = {1.0-INTREPID_EPSILON, 1.0-INTREPID_EPSILON, 1.0-INTREPID_EPSILON}; 00322 double point_in_wedge[3] = {0.5, 0.25, 1.0-INTREPID_EPSILON}; 00323 double point_in_pyramid[3] = {-INTREPID_EPSILON, INTREPID_EPSILON, 1.0-INTREPID_EPSILON}; 00324 00325 // Run the inclusion test for each point and print results 00326 int in_edge = CellTools::checkPointInclusion( point_in_edge, 1, edge3, INTREPID_THRESHOLD ); 00327 int in_quad = CellTools::checkPointInclusion( point_in_quad, 2, quad9 ); 00328 int in_tri = CellTools::checkPointInclusion( point_in_tri, 2, tri6 ); 00329 int in_tet = CellTools::checkPointInclusion( point_in_tet, 3, tet4 ); 00330 int in_hex = CellTools::checkPointInclusion( point_in_hex, 3, hex27 ); 00331 int in_prism = CellTools::checkPointInclusion( point_in_wedge, 3, wedge ); 00332 int in_pyramid = CellTools::checkPointInclusion( point_in_pyramid, 3, pyr ); 00333 00334 if(in_edge) { 00335 std::cout << "(" << point_in_edge[0] << ")" 00336 << " is inside reference Line " << endl; 00337 } 00338 if(in_quad) { 00339 std::cout << "(" << point_in_quad[0] << "," << point_in_quad[1] << ")" 00340 << " is inside reference Quadrilateral " << endl; 00341 } 00342 if(in_tri) { 00343 std::cout << "(" << point_in_tri[0] << "," << point_in_tri[1] << ")" 00344 << " is inside reference Triangle " << endl; 00345 } 00346 if(in_tet) { 00347 std::cout << "(" << point_in_tet[0] << "," << point_in_tet[1] << "," << point_in_tet[2]<<")" 00348 << " is inside reference Tetrahedron " << endl; 00349 } 00350 if(in_hex) { 00351 std::cout << "(" << point_in_hex[0] << "," << point_in_hex[1] << "," << point_in_hex[2]<<")" 00352 << " is inside reference Hexahedron " << endl; 00353 } 00354 if(in_prism) { 00355 std::cout << "(" << point_in_wedge[0] << "," << point_in_wedge[1] << "," << point_in_wedge[2]<<")" 00356 << " is inside reference Wedge " << endl; 00357 } 00358 if(in_pyramid) { 00359 std::cout << "(" << point_in_pyramid[0] << "," << point_in_pyramid[1] << "," << point_in_pyramid[2]<<")" 00360 << " is inside reference Pyramid " << endl; 00361 } 00362 00363 // Change the points to be outside their reference cells. 00364 double small = 2.0*INTREPID_THRESHOLD; 00365 point_in_edge[0] += small; 00366 00367 point_in_tri[0] += small; 00368 point_in_tri[1] += small; 00369 00370 point_in_pyramid[0] += small; 00371 point_in_pyramid[1] += small; 00372 point_in_pyramid[2] += small; 00373 00374 in_edge = CellTools::checkPointInclusion(point_in_edge, 1, edge3); 00375 in_tri = CellTools::checkPointInclusion(point_in_tri, 2, tri6); 00376 in_pyramid = CellTools::checkPointInclusion(point_in_pyramid, 3, pyr); 00377 00378 std::cout << "\nChecking if perturbed Points belong to reference cell: " << endl; 00379 if(!in_edge) { 00380 std::cout << "(" << point_in_edge[0] << ")" << " is NOT inside reference Line " << endl; 00381 } 00382 if(!in_tri) { 00383 std::cout << "(" << point_in_tri[0] << "," << point_in_tri[1] << ")" << " is NOT inside reference Triangle " << endl; 00384 } 00385 if(!in_pyramid) { 00386 std::cout << "(" << point_in_pyramid[0] << "," << point_in_pyramid[1] << "," << point_in_pyramid[2]<<")" 00387 << " is NOT inside reference Pyramid " << endl; 00388 } 00389 00390 00391 00392 std::cout << std::setprecision(6) << "\n" \ 00393 << "===============================================================================\n"\ 00394 << "| EXAMPLE 4-A: Using pointwise inclusion test method for reference cells |\n"\ 00395 << "===============================================================================\n"; 00396 00397 00398 // Rank-1 array for one 2D reference point and rank-1 array for the test result 00399 FieldContainer<double> onePoint(2); 00400 FieldContainer<int> testOnePoint(1); 00401 00402 onePoint(0) = 0.2; onePoint(1) = 0.3; 00403 00404 std::cout <<"\t Pointwise inclusion test for Triangle<6>: rank-1 array with a single 2D point: \n"; 00405 00406 CellTools::checkPointwiseInclusion(testOnePoint, onePoint, tri6); 00407 00408 std::cout << "point(" 00409 << std::setw(13) << std::right << onePoint(0) << "," 00410 << std::setw(13) << std::right << onePoint(1) << ") "; 00411 if( testOnePoint(0) ) { 00412 std::cout << " is inside. \n"; 00413 } 00414 else{ 00415 std::cout << " is not inside. \n"; 00416 } 00417 std::cout << "\n"; 00418 00419 00420 // Rank-2 array for 4 2D reference points (vector of points) and rank-1 array for the test result 00421 FieldContainer<double> fourPoints(4, 2); 00422 FieldContainer<int> testFourPoints(4); 00423 00424 fourPoints(0,0) = 0.5; fourPoints(0,1) = 0.5; 00425 fourPoints(1,0) = 1.0; fourPoints(1,1) = 1.1; 00426 fourPoints(2,0) =-1.0; fourPoints(2,1) =-1.1; 00427 fourPoints(3,0) =-1.0; fourPoints(3,1) = 0.5; 00428 00429 std::cout <<"\t Pointwise inclusion test for Quadrilateral<9>: rank-2 array with 4 2D points: \n"; 00430 00431 CellTools::checkPointwiseInclusion(testFourPoints, fourPoints, quad9); 00432 00433 for(int i1 = 0; i1 < fourPoints.dimension(0); i1++) { 00434 std::cout << " point(" << i1 << ") = (" 00435 << std::setw(13) << std::right << fourPoints(i1, 0) << "," 00436 << std::setw(13) << std::right << fourPoints(i1, 1) << ") "; 00437 if( testFourPoints(i1) ) { 00438 std::cout << " is inside. \n"; 00439 } 00440 else{ 00441 std::cout << " is not inside. \n"; 00442 } 00443 } 00444 std::cout << "\n"; 00445 00446 00447 // Rank-3 array for 6 2D points and rank-2 array for the test result 00448 FieldContainer<double> sixPoints(2, 3, 2); 00449 FieldContainer<int> testSixPoints(2, 3); 00450 00451 sixPoints(0,0,0) = -1.0; sixPoints(0,0,1) = 1.0; 00452 sixPoints(0,1,0) = 1.0; sixPoints(0,1,1) = 0.0; 00453 sixPoints(0,2,0) = 0.0; sixPoints(0,2,1) = 1.0; 00454 sixPoints(1,0,0) = -1.0; sixPoints(1,0,1) = -1.0; 00455 sixPoints(1,1,0) = 0.1; sixPoints(1,1,1) = 0.2; 00456 sixPoints(1,2,0) = 0.2; sixPoints(1,2,1) = 0.3; 00457 00458 std::cout <<"\t Pointwise inclusion test for Triangle<6>: rank-3 array with six 2D points: \n"; 00459 00460 CellTools::checkPointwiseInclusion(testSixPoints, sixPoints, tri6); 00461 00462 for(int i0 = 0; i0 < sixPoints.dimension(0); i0++){ 00463 for(int i1 = 0; i1 < sixPoints.dimension(1); i1++) { 00464 std::cout << " point(" << i0 << "," << i1 << ") = (" 00465 << std::setw(13) << std::right << sixPoints(i0, i1, 0) << "," 00466 << std::setw(13) << std::right << sixPoints(i0, i1, 1) << ") "; 00467 if( testSixPoints(i0, i1) ) { 00468 std::cout << " is inside. \n"; 00469 } 00470 else{ 00471 std::cout << " is not inside. \n"; 00472 } 00473 00474 } 00475 } 00476 std::cout << "\n"; 00477 00478 00479 // Rank-3 array for 6 3D reference points and rank-2 array for the test results 00480 FieldContainer<double> six3DPoints(2, 3, 3); 00481 FieldContainer<int> testSix3DPoints(2, 3); 00482 00483 six3DPoints(0,0,0) = -1.0; six3DPoints(0,0,1) = 1.0; six3DPoints(0,0,2) = 1.0; 00484 six3DPoints(0,1,0) = 1.0; six3DPoints(0,1,1) = 1.0; six3DPoints(0,1,2) = -1.0; 00485 six3DPoints(0,2,0) = 0.0; six3DPoints(0,2,1) = 1.1; six3DPoints(0,2,2) = 1.0; 00486 six3DPoints(1,0,0) = -1.1; six3DPoints(1,0,1) = -1.0; six3DPoints(1,0,2) = -1.0; 00487 six3DPoints(1,1,0) = 0.1; six3DPoints(1,1,1) = 0.2; six3DPoints(1,1,2) = 0.2; 00488 six3DPoints(1,2,0) = 1.1; six3DPoints(1,2,1) = 0.3; six3DPoints(1,2,2) = 0.3; 00489 00490 std::cout <<"\t Pointwise inclusion test for Hexahedron<27>: rank-3 array with six 3D points: \n"; 00491 00492 CellTools::checkPointwiseInclusion(testSix3DPoints, six3DPoints, hex27); 00493 00494 00495 00496 for(int i0 = 0; i0 < six3DPoints.dimension(0); i0++){ 00497 for(int i1 = 0; i1 < six3DPoints.dimension(1); i1++) { 00498 std::cout << " point(" << i0 << "," << i1 << ") = (" 00499 << std::setw(13) << std::right << six3DPoints(i0, i1, 0) << "," 00500 << std::setw(13) << std::right << six3DPoints(i0, i1, 1) << "," 00501 << std::setw(13) << std::right << six3DPoints(i0, i1, 2) << ") "; 00502 if( testSix3DPoints(i0, i1) ) { 00503 std::cout << " is inside. \n"; 00504 } 00505 else{ 00506 std::cout << " is not inside. \n"; 00507 } 00508 } 00509 } 00510 00511 00512 std::cout << std::setprecision(6) << "\n" \ 00513 << "===============================================================================\n"\ 00514 << "| EXAMPLE 4-B: Pointwise inclusion test for a physical cell in cell workset |\n"\ 00515 << "===============================================================================\n"; 00516 00517 // Rank-2 array for a single set of 5 2D physical points and rank-1 array for the test results 00518 FieldContainer<double> fivePoints(5,2); 00519 FieldContainer<int> testFivePoints(5); 00520 00521 // These points will be tested for inclusion in the last Triangle cell specified by triNodes 00522 fivePoints(0, 0) = 2.1 ; fivePoints(0, 1) = 1.0 ; // in 00523 fivePoints(1, 0) = 3.0 ; fivePoints(1, 1) = 0.75; // in 00524 fivePoints(2, 0) = 3.5 ; fivePoints(2, 1) = 1.9 ; // out 00525 fivePoints(3, 0) = 2.5 ; fivePoints(3, 1) = 1.0 ; // in 00526 fivePoints(4, 0) = 2.75; fivePoints(4, 1) = 2.0 ; // out 00527 00528 CellTools::checkPointwiseInclusion(testFivePoints, fivePoints, triNodes, triangle_3, 3); 00529 00530 std::cout << " Vertices of Triangle #3: \n" 00531 << "\t(" << triNodes(3, 0, 0) << ", " << triNodes(3, 0, 1) << ")\n" 00532 << "\t(" << triNodes(3, 1, 0) << ", " << triNodes(3, 1, 1) << ")\n" 00533 << "\t(" << triNodes(3, 1, 0) << ", " << triNodes(3, 1, 1) << ")\n" 00534 << " Inclusion test results for the physical points: \n\n"; 00535 00536 for(int i1 = 0; i1 < fivePoints.dimension(0); i1++) { 00537 std::cout << " point(" << i1 << ") = (" 00538 << std::setw(13) << std::right << fivePoints(i1, 0) << "," 00539 << std::setw(13) << std::right << fivePoints(i1, 1) << ") "; 00540 if( testFivePoints(i1) ) { 00541 std::cout << " is inside. \n"; 00542 } 00543 else{ 00544 std::cout << " is not inside. \n"; 00545 } 00546 } 00547 std::cout << "\n"; 00548 00549 00550 00551 std::cout << std::setprecision(6) << "\n" \ 00552 << "===============================================================================\n"\ 00553 << "| EXAMPLE 4-C: Pointwise inclusion test for all physical cells in cell workset|\n"\ 00554 << "===============================================================================\n"; 00555 00556 // Rank-3 array for 4 sets of 2 2D physical points and rank-2 array for the test results 00557 FieldContainer<double> fourPointSets(4, 2, 2); 00558 FieldContainer<int> testFourSets(4, 2); 00559 00560 // 1st point set - will be tested for inclusion in Triangle #0 00561 fourPointSets(0, 0, 0) = 0.25; fourPointSets(0, 0, 1) = 0.75; // in 00562 fourPointSets(0, 1, 0) = 0.00; fourPointSets(0, 1, 1) =-0.01; // out 00563 00564 // 2nd point set - will be tested for inclusion in Triangle #1 00565 fourPointSets(1, 0, 0) = 1.50; fourPointSets(1, 0, 1) = 1.50; // in 00566 fourPointSets(1, 1, 0) = 0.99; fourPointSets(1, 1, 1) = 1.50; // out 00567 00568 // 3rd point set - will be tested for inclusion in Triangle #2 00569 fourPointSets(2, 0, 0) =-0.25; fourPointSets(2, 0, 1) = 0.70; // in 00570 fourPointSets(2, 1, 0) = 0.0001; fourPointSets(2, 1, 1) = 0.50; // out 00571 00572 // 4th point set - will be tested for inclusion in Triangle #3 00573 fourPointSets(3, 0, 0) = 3.00; fourPointSets(3, 0, 1) = 1.00; // in 00574 fourPointSets(3, 1, 0) = 3.50; fourPointSets(3, 1, 1) = 0.50; // out 00575 00576 CellTools::checkPointwiseInclusion(testFourSets, fourPointSets, triNodes, triangle_3); 00577 00578 for(int cell = 0; cell < triNodes.dimension(0); cell++){ 00579 00580 std::cout << " Testing point set inclusion for Triangle #" << cell << " with vertices \n" 00581 << "\t(" << triNodes(cell, 0, 0) << ", " << triNodes(cell, 0, 1) << ")\n" 00582 << "\t(" << triNodes(cell, 1, 0) << ", " << triNodes(cell, 1, 1) << ")\n" 00583 << "\t(" << triNodes(cell, 1, 0) << ", " << triNodes(cell, 1, 1) << ")\n" 00584 << " Results for physical point set indexed by the cell ordinal " << cell << " \n\n"; 00585 00586 for(int i1 = 0; i1 < fourPointSets.dimension(1); i1++) { 00587 std::cout << " point(" << i1 << ") = (" 00588 << std::setw(13) << std::right << fourPointSets(cell, i1, 0) << "," 00589 << std::setw(13) << std::right << fourPointSets(cell, i1, 1) << ") "; 00590 if( testFourSets(cell, i1) ) { 00591 std::cout << " is inside Triangle #" << cell << " \n"; 00592 } 00593 else{ 00594 std::cout << " is outside Triangle #" << cell << " \n"; 00595 } 00596 } 00597 if(cell < triNodes.dimension(0) - 1) { 00598 std::cout << "-------------------------------------------------------------------------------\n"; 00599 } 00600 else{ 00601 std::cout <<" \n"; 00602 } 00603 }// cell 00604 00605 00606 00607 std::cout << "\n" \ 00608 << "===============================================================================\n"\ 00609 << "| EXAMPLE 5: Using point set inclusion test method |\n"\ 00610 << "===============================================================================\n"; 00611 00612 std::cout <<"\t Point set inclusion test for Triangle<6>: rank-2 array with four 2D point: \n"; 00613 00614 if( CellTools::checkPointsetInclusion(fourPoints, tri6) ) { 00615 std::cout << "\t - All points are inside the reference Triangle<6> cell. \n\n "; 00616 } 00617 else{ 00618 std::cout << "\t - At least one point is not inside the reference Triangle<6> cell. \n\n"; 00619 } 00620 00621 std::cout <<"\t Point set inclusion test for Hexahedron<27>: rank-3 array with six 3D point: \n"; 00622 00623 if( CellTools::checkPointsetInclusion(six3DPoints, hex27) ) { 00624 std::cout << "\t - All points are inside the reference Hexahedron<27> cell. \n\n "; 00625 } 00626 else{ 00627 std::cout << "\t - At least one point is not inside the reference Hexahedron<27> cell. \n\n"; 00628 } 00629 00630 00631 00632 std::cout << std::setprecision(4) << "\n" \ 00633 << "===============================================================================\n"\ 00634 << "| EXAMPLE 6: mapping a single point set to physical cells with base topology |\n"\ 00635 << "===============================================================================\n"; 00636 00637 // Rank-3 array with dimensions (P, D) for points on the reference triangle 00638 FieldContainer<double> refTriPoints(3,triangle_3.getDimension() ); 00639 refTriPoints(0,0) = 0.2; refTriPoints(0,1) = 0.0; // on edge 0 00640 refTriPoints(1,0) = 0.4; refTriPoints(1,1) = 0.6; // on edge 1 00641 refTriPoints(2,0) = 0.0; refTriPoints(2,1) = 0.8; // on edge 2 00642 00643 // Reference points will be mapped to physical cells with vertices in triNodes: define the appropriate array 00644 FieldContainer<double> physTriPoints(triNodes.dimension(0), // cell count 00645 refTriPoints.dimension(0), // point count 00646 refTriPoints.dimension(1)); // point dimension (=2) 00647 00648 CellTools::mapToPhysicalFrame(physTriPoints, refTriPoints, triNodes, triangle_3); 00649 00650 for(int cell = 0; cell < triNodes.dimension(0); cell++){ 00651 std::cout << "====== Triangle " << cell << " ====== \n"; 00652 for(int pt = 0; pt < refTriPoints.dimension(0); pt++){ 00653 std::cout 00654 << "(" 00655 << std::setw(13) << std::right << refTriPoints(pt,0) << "," 00656 << std::setw(13) << std::right << refTriPoints(pt,1) << ") -> " 00657 << "(" 00658 << std::setw(13) << std::right << physTriPoints(cell, pt, 0) << "," 00659 << std::setw(13) << std::right << physTriPoints(cell, pt, 1) << ") \n"; 00660 } 00661 std::cout << "\n"; 00662 } 00663 00664 00665 std::cout << std::setprecision(4) << "\n" \ 00666 << "===============================================================================\n"\ 00667 << "| EXAMPLE 7: mapping a single point set to physical cells with ext. topology |\n"\ 00668 << "===============================================================================\n"; 00669 /* 00670 * This example illustrates reference-to-physical mapping for a triangle with curved sides. The 00671 * physical curved triangle is defined as follows: 00672 * 00673 * - edge 0: starts at (1, -1/2) ends at (1,1) and is a vertical line segment 00674 * - edge 1: starts at (1,1) ends at (0,0) and is parabolic segment lying on y=x^2 00675 * - edge 2: starts at (0,0) ends at (1,-1/2) and is parabolic segment lying on y = -1/2 x^2 00676 * 00677 * The triangle is uniquely specified by its 3 vertices and 3 edge points. Therefore, to compute the 00678 * map from reference to physical coordinates we specify Triangle<6> topology. 00679 */ 00680 00681 // A (C,V,D) array with the 6 nodes of the physical Triangle<6> 00682 FieldContainer<double> tri6Nodes(1,6,2); 00683 tri6Nodes(0,0,0) = 1.0; tri6Nodes(0,0,1) = -0.5; 00684 tri6Nodes(0,1,0) = 1.0; tri6Nodes(0,1,1) = 1.0; 00685 tri6Nodes(0,2,0) = 0.0; tri6Nodes(0,2,1) = 0.0; 00686 00687 tri6Nodes(0,3,0) = 1.0; tri6Nodes(0,3,1) = 0.0; 00688 tri6Nodes(0,4,0) = 0.5; tri6Nodes(0,4,1) = 0.25; 00689 tri6Nodes(0,5,0) = 0.5; tri6Nodes(0,5,1) = -0.125; 00690 00691 // A (P, D) array with the 6 nodes of the reference Triangle<6> plus some extra points 00692 FieldContainer<double> refTri6Points(9,2); 00693 refTri6Points(0,0) = 0.0; refTri6Points(0,1) = 0.0; 00694 refTri6Points(1,0) = 1.0; refTri6Points(1,1) = 0.0; 00695 refTri6Points(2,0) = 0.0; refTri6Points(2,1) = 1.0; 00696 00697 refTri6Points(3,0) = 0.5; refTri6Points(3,1) = 0.0; 00698 refTri6Points(4,0) = 0.5; refTri6Points(4,1) = 0.5; 00699 refTri6Points(5,0) = 0.0; refTri6Points(5,1) = 0.5; 00700 00701 refTri6Points(6,0) = 0.75; refTri6Points(6,1) = 0.0; // on ref edge 0 00702 refTri6Points(7,0) = 0.25; refTri6Points(7,1) = 0.75; // on ref edge 1 00703 refTri6Points(8,0) = 0.00; refTri6Points(8,1) = 0.25; // on ref edge 2 00704 00705 // A (C,P,D) array for the images of the reference points in physical frame 00706 FieldContainer<double> physTri6Points(tri6Nodes.dimension(0), // cell count 00707 refTri6Points.dimension(0), // point count 00708 refTri6Points.dimension(1)); // point dimension (=2) 00709 00710 // Define the cell topology: use the extended Triangle<6> topology to fit the curved edges 00711 CellTopology triangle_6(shards::getCellTopologyData<Triangle<6> >() ); 00712 00713 // 00714 CellTools::mapToPhysicalFrame(physTri6Points, refTri6Points, tri6Nodes, triangle_6); 00715 00716 for(int cell = 0; cell < tri6Nodes.dimension(0); cell++){ 00717 std::cout << "====== Triangle " << cell << " ====== \n"; 00718 for(int pt = 0; pt < refTri6Points.dimension(0); pt++){ 00719 std::cout 00720 << "(" 00721 << std::setw(13) << std::right << refTri6Points(pt,0) << "," 00722 << std::setw(13) << std::right << refTri6Points(pt,1) << ") -> " 00723 << "(" 00724 << std::setw(13) << std::right << physTri6Points(cell, pt, 0) << "," 00725 << std::setw(13) << std::right << physTri6Points(cell, pt, 1) << ") \n"; 00726 } 00727 std::cout << "\n"; 00728 } 00729 00730 00731 00732 std::cout << "\n" \ 00733 << "===============================================================================\n"\ 00734 << "| EXAMPLE 8: mapping a single physical point set to reference frame |\n"\ 00735 << "===============================================================================\n"; 00736 /* 00737 * This example shows use of mapToReferenceFrame with rank-2 array (P,D) of points in physical frame. 00738 * Points are mapped back to reference frame using the mapping for one of the physical cells whose 00739 * nodes are passed as an argument. Therefore, this use case requires a valid cell ordinal (relative 00740 * to the nodes array) to be specified. The output array for the images of the points is also rank-2 (P,D). 00741 * 00742 */ 00743 // Rank-2 arrays with dimensions (P, D) for physical points and their preimages 00744 FieldContainer<double> physPoints(5, triangle_3.getDimension() ); 00745 FieldContainer<double> preImages (5, triangle_3.getDimension() ); 00746 00747 // First 3 points are the vertices of the last triangle (ordinal = 3) stored in triNodes 00748 physPoints(0,0) = triNodes(3, 0, 0); physPoints(0,1) = triNodes(3, 0, 1) ; 00749 physPoints(1,0) = triNodes(3, 1, 0); physPoints(1,1) = triNodes(3, 1, 1); 00750 physPoints(2,0) = triNodes(3, 2, 0); physPoints(2,1) = triNodes(3, 2, 1); 00751 00752 // last 2 points are just some arbitrary points contained in the last triangle 00753 physPoints(3,0) = 3.0; physPoints(3,1) = 1.0; 00754 physPoints(4,0) = 2.5; physPoints(4,1) = 1.1; 00755 00756 00757 // Map physical points from triangle 3 to the reference frame 00758 int whichCell = 3; 00759 CellTools::mapToReferenceFrame(preImages, physPoints, triNodes, triangle_3, whichCell ); 00760 00761 std::cout << " Mapping from Triangle #"<< whichCell << " with vertices: \n" 00762 << "\t(" << triNodes(whichCell, 0, 0) << ", " << triNodes(whichCell, 0, 1) << ")\n" 00763 << "\t(" << triNodes(whichCell, 1, 0) << ", " << triNodes(whichCell, 1, 1) << ")\n" 00764 << "\t(" << triNodes(whichCell, 1, 0) << ", " << triNodes(whichCell, 1, 1) << ")\n\n" 00765 << " Physical points and their reference cell preimages: \n"; 00766 00767 for(int pt = 0; pt < physPoints.dimension(0); pt++){ 00768 std::cout 00769 << "(" << std::setw(13) << std::right << physPoints(pt,0) << "," 00770 << std::setw(13) << std::right << physPoints(pt,1) << ") -> " 00771 << "(" 00772 << std::setw(13) << std::right << preImages(pt, 0) << "," 00773 << std::setw(13) << std::right << preImages(pt, 1) << ") \n"; 00774 } 00775 std::cout << "\n"; 00776 00777 // As a check, map pre-images back to Triangle #3 00778 FieldContainer<double> images(5, triangle_3.getDimension() ); 00779 CellTools::mapToPhysicalFrame(images, preImages, triNodes, triangle_3, whichCell); 00780 00781 std::cout << " Check: map preimages back to Triangle #3: \n"; 00782 for(int pt = 0; pt < images.dimension(0); pt++){ 00783 std::cout 00784 << "(" << std::setw(13) << std::right << preImages(pt,0) << "," 00785 << std::setw(13) << std::right << preImages(pt,1) << ") -> " 00786 << "(" 00787 << std::setw(13) << std::right << images(pt, 0) << "," 00788 << std::setw(13) << std::right << images(pt, 1) << ") \n"; 00789 } 00790 std::cout << "\n"; 00791 00792 00793 std::cout << "\n" \ 00794 << "===============================================================================\n"\ 00795 << "| EXAMPLE 9: mapping physical point sets on a cell workset to reference frame |\n"\ 00796 << "===============================================================================\n"; 00797 /* 00798 * This example shows use of mapToReferenceFrame with rank-3 array (C,P,D) of points in physical frame. 00799 * For each cell ordinal (relative to the nodes array), the associated point set is mapped back to 00800 * reference frame using the mapping corresponding to the physical cell with that ordinal. This use case 00801 * requires the default value -1 for the cell ordinal. The output array for the images of the points 00802 * is also rank-3 (C,P,D). 00803 * 00804 */ 00805 // Rank-3 arrays with dimensions (C, P, D) for physical points and their preimages 00806 FieldContainer<double> physPointSets(triNodes.dimension(0), 2, triangle_3.getDimension() ); 00807 FieldContainer<double> preImageSets (triNodes.dimension(0), 2, triangle_3.getDimension() ); 00808 00809 // Point set on Triangle #0 00810 physPointSets(0,0,0) = 0.25; physPointSets(0,0,1) = 0.25; 00811 physPointSets(0,1,0) = 0.50; physPointSets(0,1,1) = 0.50; 00812 00813 // Point set on Triangle #1 00814 physPointSets(1,0,0) = 1.00; physPointSets(1,0,1) = 1.00; 00815 physPointSets(1,1,0) = 1.25; physPointSets(1,1,1) = 1.75; 00816 00817 // Point set on Triangle #2 00818 physPointSets(2,0,0) =-0.25; physPointSets(2,0,1) = 0.25; 00819 physPointSets(2,1,0) =-0.50; physPointSets(2,1,1) = 0.50; 00820 00821 // Point set on Triangle #3 00822 physPointSets(3,0,0) = 3.00; physPointSets(3,0,1) = 1.00; 00823 physPointSets(3,1,0) = 2.00; physPointSets(3,1,1) = 1.00; 00824 00825 00826 // Map physical point sets to reference frame: requires default value of cell ordinal (skip last arg) 00827 CellTools::mapToReferenceFrame(preImageSets, physPointSets, triNodes, triangle_3); 00828 00829 for(int cell = 0; cell < triNodes.dimension(0); cell++){ 00830 std::cout << "====== Triangle " << cell << " ====== \n"; 00831 for(int pt = 0; pt < physPointSets.dimension(1); pt++){ 00832 std::cout 00833 << "(" 00834 << std::setw(13) << std::right << physPointSets(cell, pt, 0) << "," 00835 << std::setw(13) << std::right << physPointSets(cell, pt, 1) << ") -> " 00836 << "(" 00837 << std::setw(13) << std::right << preImageSets(cell, pt, 0) << "," 00838 << std::setw(13) << std::right << preImageSets(cell, pt, 1) << ") \n"; 00839 } 00840 std::cout << "\n"; 00841 } 00842 00843 // As a check, map preImageSets back to physical frame 00844 FieldContainer<double> postImageSets(triNodes.dimension(0), 2, triangle_3.getDimension() ); 00845 00846 CellTools::mapToPhysicalFrame(postImageSets, preImageSets, triNodes, triangle_3); 00847 00848 std::cout << " Check: map preimages back to Triangles: \n"; 00849 for(int cell = 0; cell < triNodes.dimension(0); cell++){ 00850 std::cout << "====== Triangle " << cell << " ====== \n"; 00851 for(int pt = 0; pt < preImageSets.dimension(1); pt++){ 00852 std::cout 00853 << "(" 00854 << std::setw(13) << std::right << preImageSets(cell, pt, 0) << "," 00855 << std::setw(13) << std::right << preImageSets(cell, pt, 1) << ") -> " 00856 << "(" 00857 << std::setw(13) << std::right << postImageSets(cell, pt, 0) << "," 00858 << std::setw(13) << std::right << postImageSets(cell, pt, 1) << ") \n"; 00859 } 00860 std::cout << "\n"; 00861 } 00862 00863 return 0; 00864 } 00865 00866 00867 00868 00869 00870 00871 00872 00873 00874 00875 00876 00877 00878 00879 00880 00881 00882 00883 00884 00885 00886 00887 00888 00889 00890 00891 00892
1.7.4