Intrepid
/usr/src/RPM/BUILD/trilinos10-10.6.4/packages/intrepid/example/CellTools/example_01.cpp
Go to the documentation of this file.
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