SundancePeanoMesh3D.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 //
00004 //                              Sundance
00005 //                 Copyright (2005) Sandia Corporation
00006 //
00007 // Copyright (year first published) Sandia Corporation.  Under the terms
00008 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
00009 // retains certain rights in this software.
00010 //
00011 // This library is free software; you can redistribute it and/or modify
00012 // it under the terms of the GNU Lesser General Public License as
00013 // published by the Free Software Foundation; either version 2.1 of the
00014 // License, or (at your option) any later version.
00015 //
00016 // This library is distributed in the hope that it will be useful, but
00017 // WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019 // Lesser General Public License for more details.
00020 //
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License along with this library; if not, write to the Free Software
00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00024 // USA
00025 // Questions? Contact Kevin Long (krlong@sandia.gov),
00026 // Sandia National Laboratories, Livermore, California, USA
00027 //
00028 // ************************************************************************
00029 /* @HEADER@ */
00030 /*
00031  * SundancePeanoMesh3D.cpp
00032  *
00033  *  Created on: Sep 8, 2009
00034  *      Author: benk
00035  */
00036 
00037 #include "SundancePeanoMesh3D.hpp"
00038 
00039 #include "SundanceMeshType.hpp"
00040 #include "SundanceCellJacobianBatch.hpp"
00041 #include "SundanceMaximalCofacetBatch.hpp"
00042 #include "SundanceMeshSource.hpp"
00043 #include "SundanceDebug.hpp"
00044 #include "SundanceOut.hpp"
00045 #include "Teuchos_MPIContainerComm.hpp"
00046 #include "Teuchos_Time.hpp"
00047 #include "Teuchos_TimeMonitor.hpp"
00048 #include "SundanceObjectWithVerbosity.hpp"
00049 #include "SundanceCollectiveExceptionCheck.hpp"
00050 
00051 #ifdef HAVE_SUNDANCE_PEANO
00052 
00053 using namespace Sundance;
00054 using namespace Teuchos;
00055 
00056 //#define printf(msg)
00057 //#define SUNDANCE_VERB_HIGH(msg) printf(msg);printf("\n");
00058 
00059 Point PeanoMesh3D::returnPoint(0.0 , 0.0 , 0.0);
00060 
00061 PeanoMesh3D::PeanoMesh3D(int dim, const MPIComm& comm,
00062       const MeshEntityOrder& order )
00063 : MeshBase(dim, comm , order),_dimension(dim), _comm(comm)
00064  ,_peanoMesh(NULL)
00065 {
00066   _uniqueResolution = 1.0;
00067 }
00068 
00069 void PeanoMesh3D::createMesh(
00070                       double position_x,
00071                 double position_y,
00072                 double position_z,
00073                 double offset_x,
00074                 double offset_y,
00075                 double offset_z,
00076                 double resolution
00077 ){
00078       double position[3];
00079       double offset[3];
00080       double res[3];
00081 
00082       // setting the values of the ctor argument
00083       position[0] = position_x; position[1] = position_y;  position[2] = position_z;
00084       offset[0] = offset_x;     offset[1] = offset_y;      offset[2] = offset_z;
00085       res[0] = resolution;      res[1] = resolution;       res[2] = resolution;
00086 
00087 
00088       // this is a 2D case
00089       // call the ctor for the Peano mesh
00090       SUNDANCE_VERB_LOW(" create Peano Mesh 3D ... ");
00091       _dimension = 3;
00092       // here we create the Peano grid
00093       _peanoMesh = new SundancePeanoInterface3D( position , offset , res );
00094       _uniqueResolution = _peanoMesh->returnResolution(0);
00095 
00096       SUNDANCE_VERB_LOW(" Peano Mesh created 3D ... \n");
00097       _peanoMesh->plotVTK("Peano3D");
00098       SUNDANCE_VERB_LOW(" After Plot 3D ... \n");
00099 }
00100 
00101 PeanoMesh3D::~PeanoMesh3D() {
00102   //delete _peanoMesh;
00103 }
00104 
00105 
00106 int PeanoMesh3D::numCells(int dim) const  {
00107   //printf("PeanoMesh3D::numCells(int dim):%d   dim:%d \n",_peanoMesh->numCells(dim),dim);
00108   return _peanoMesh->numCells(dim);
00109 }
00110 
00111 Point PeanoMesh3D::nodePosition(int i) const {
00112   //SUNDANCE_VERB_HIGH("nodePosition(int i)");
00113   //printf("PeanoMesh3D::nodePosition(int i)   i:%d \n", i);
00114   double* coords;
00115   coords = _peanoMesh->nodePositionView(i);
00116   // set the values
00117   PeanoMesh3D::returnPoint[0] = coords[0];
00118   PeanoMesh3D::returnPoint[1] = coords[1];
00119   PeanoMesh3D::returnPoint[2] = coords[2];
00120     return PeanoMesh3D::returnPoint;
00121 }
00122 
00123 const double* PeanoMesh3D::nodePositionView(int i) const {
00124   //printf("PeanoMesh3D::nodePositionView(int i)   i:%d \n", i);
00125   //SUNDANCE_VERB_HIGH("nodePosition(int i)");
00126   nodePosition(i);
00127   return &(PeanoMesh3D::returnPoint[0]);
00128 }
00129 
00130 void PeanoMesh3D::getJacobians(int cellDim, const Array<int>& cellLID,
00131                           CellJacobianBatch& jBatch) const
00132 {
00133     //printf("cellDim:%d  _uniqueResolution:%f ",cellDim, _uniqueResolution);
00134     SUNDANCE_VERB_HIGH("getJacobians()");
00135     TEST_FOR_EXCEPTION(cellDim < 0 || cellDim > spatialDim(), InternalError,
00136       "cellDim=" << cellDim << " is not in expected range [0, " << spatialDim() << "]");
00137     int nCells = cellLID.size();
00138     int tmp_index , tmp;
00139     int tmp_index1 , tmp_index2;
00140     Point pnt(0.0,0.0,0.0);
00141     Point pnt1(0.0,0.0,0.0);
00142     Point pnt2(0.0,0.0,0.0);
00143     jBatch.resize(cellLID.size(), spatialDim(), cellDim);
00144     if (cellDim < spatialDim()) // they need the Jacobian of a lower dinemsional element
00145     {
00146       //printf("PeanoMesh3D::getJacobians() cellDim < spatialDim() \n");
00147        for (int i=0; i<nCells; i++)
00148         {
00149           //printf("PeanoMesh3D::getJacobian() cellDim < spatialDim() cellDim:%d , ret:%f \n",cellDim , _uniqueResolution);
00150           double* detJ = jBatch.detJ(i);
00151           switch(cellDim)
00152           {
00153             case 0: *detJ = 1.0;
00154               break;
00155             case 1:
00156              tmp_index = this->facetLID(cellDim,  cellLID[i] , 0 , 0 , tmp );
00157              tmp_index1= this->facetLID(cellDim,  cellLID[i] , 0 , 1 , tmp );
00158              pnt = nodePosition(tmp_index);
00159              pnt1 = nodePosition(tmp_index1);
00160              pnt = pnt1 - pnt;
00161                  *detJ = sqrt(pnt * pnt); // the length of the edge
00162             break;
00163             case 2:{
00164              tmp_index = this->facetLID(cellDim,  cellLID[i] , 0 , 0 , tmp );
00165              tmp_index1= this->facetLID(cellDim,  cellLID[i] , 0 , 1 , tmp );
00166              tmp_index2= this->facetLID(cellDim,  cellLID[i] , 0 , 2 , tmp );
00167              pnt = nodePosition(tmp_index);
00168              pnt1 = nodePosition(tmp_index1);
00169              pnt2 = nodePosition(tmp_index2);
00170              Point directedArea = cross( pnt1 - pnt , pnt2 - pnt );
00171                  *detJ = sqrt(directedArea * directedArea); // the are of the face
00172             break;}
00173             default:
00174               TEST_FOR_EXCEPTION(true, InternalError, "impossible switch value "
00175                 "cellDim=" << cellDim << " in PeanoMesh3D::getJacobians()");
00176           }
00177         }
00178     }else{ // they request the complete Jacoby matrix for this bunch of elements
00179         //Array<double> J(cellDim*cellDim);
00180         SUNDANCE_VERB_HIGH("cellDim == spatialDim()");
00181         for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00182         {
00183         //printf("PeanoMesh3D::getJacobian() cellDim == spatialDim() cellDim:%d , ret:%f \n",cellDim , _uniqueResolution);
00184           double* J = jBatch.jVals(i);
00185           switch(cellDim)
00186           {
00187             case 3:
00188               J[0] = _peanoMesh->returnResolution(0);
00189               J[1] = 0.0; J[2] = 0.0; J[3] = 0.0;
00190               J[4] = _peanoMesh->returnResolution(1);
00191               J[5] = 0.0; J[6] = 0.0; J[7] = 0.0;
00192               J[8] = _peanoMesh->returnResolution(2); // the Jacobi of the tet
00193             break;
00194             default:
00195               TEST_FOR_EXCEPTION(true, InternalError, "impossible switch value "
00196                 "cellDim=" << cellDim
00197                 << " in PeanoMesh3D::getJacobians()");
00198           }
00199         }
00200     }
00201 }
00202 
00203 void PeanoMesh3D::getCellDiameters(int cellDim, const Array<int>& cellLID,
00204                               Array<double>& cellDiameters) const {
00205    TEST_FOR_EXCEPTION(cellDim < 0 || cellDim > spatialDim(), InternalError,
00206       "cellDim=" << cellDim << " is not in expected range [0, " << spatialDim() << "]");
00207    SUNDANCE_VERB_HIGH("getCellDiameters()");
00208     cellDiameters.resize(cellLID.size());
00209 
00210     int tmp_index , tmp;
00211     int tmp_index1;
00212     Point pnt(0.0,0.0,0.0);
00213     Point pnt1(0.0,0.0,0.0);
00214 
00215     if (cellDim < spatialDim())
00216     {
00217     //printf("PeanoMesh3D::getCellDiameters(), cellDim < spatialDim() \n ");
00218       for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00219       {
00220         switch(cellDim)
00221         {
00222           case 0:
00223             cellDiameters[i] = 1.0;
00224             break;
00225           case 1:
00226           tmp_index = this->facetLID(cellDim,  cellLID[i] , 0 , 0 , tmp );
00227           tmp_index1= this->facetLID(cellDim,  cellLID[i] , 0 , 1 , tmp );
00228           pnt = nodePosition(tmp_index);
00229           pnt1 = nodePosition(tmp_index1);
00230           pnt = pnt1 - pnt;
00231           cellDiameters[i] = sqrt(pnt * pnt); // the length of the edge
00232           break;
00233           case 2:
00234           tmp_index = this->facetLID(cellDim,  cellLID[i] , 0 , 0 , tmp );
00235           tmp_index1= this->facetLID(cellDim,  cellLID[i] , 0 , 3 , tmp );
00236           pnt = nodePosition(tmp_index);
00237           pnt1 = nodePosition(tmp_index1);
00238           pnt = pnt1 - pnt;
00239           cellDiameters[i] = sqrt(pnt * pnt); // the length of the edge
00240           break;
00241           default:
00242             TEST_FOR_EXCEPTION(true, InternalError, "impossible switch value "
00243               "cellDim=" << cellDim << " in PeanoMesh3D::getCellDiameters()");
00244         }
00245       }
00246     }
00247     else
00248     {
00249     //printf("PeanoMesh3D::getCellDiameters(), cellDim == spatialDim() \n ");
00250       for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00251       {
00252         switch(cellDim)
00253         {
00254       case 3:
00255             cellDiameters[i] = (_peanoMesh->returnResolution(0) + _peanoMesh->returnResolution(1)
00256                           + _peanoMesh->returnResolution(2))/3.0;
00257           break;
00258           default:
00259             TEST_FOR_EXCEPTION(true, InternalError, "impossible switch value "
00260               "cellDim=" << cellDim
00261               << " in PeanoMesh3D::getCellDiameters()");
00262         }
00263       }
00264     }
00265 }
00266 
00267 void PeanoMesh3D::pushForward(int cellDim, const Array<int>& cellLID,
00268                          const Array<Point>& refQuadPts,
00269                          Array<Point>& physQuadPts) const {
00270 
00271     //printf("PeanoMesh3D::pushForward cellDim:%d\n",cellDim);
00272     TEST_FOR_EXCEPTION(cellDim < 0 || cellDim > spatialDim(), InternalError,
00273       "cellDim=" << cellDim
00274       << " is not in expected range [0, " << spatialDim()
00275       << "]");
00276 
00277     int nQuad = refQuadPts.size();
00278     double start_point[3] , end_point[3];
00279     Array<double> J(cellDim*cellDim);
00280 
00281     if (physQuadPts.size() > 0) physQuadPts.resize(0);
00282     physQuadPts.reserve(cellLID.size() * refQuadPts.size());
00283     for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00284     {
00285       int lid = cellLID[i];
00286       _peanoMesh->pushForward( cellDim, lid ,start_point , end_point );
00287       //std::cout << "_peanoMesh->pushForward: " << cellDim << "," << lid << std::endl;
00288       //std::cout << "Start Point: "<< start_point[0] << " , " << start_point[1] << " , " << start_point[2] << std::endl;
00289       //std::cout << "End Point: "<< end_point[0] <<" , " << end_point[1] << " , "<< end_point[2] << std::endl;
00290         Point pnt( start_point[0] , start_point[1] , start_point[2] );
00291         Point pnt1( end_point[0] , end_point[1] , end_point[2]);
00292       switch(cellDim)
00293       {
00294         case 0: // integrate one point
00295            physQuadPts.append(pnt);
00296           break;
00297         case 1:{ // integrate on one line
00298            for (int q=0; q<nQuad; q++) {
00299              physQuadPts.append(pnt + refQuadPts[q][0]*(pnt1 - pnt));
00300            }
00301         break;}
00302         case 2:{
00303            for (int q=0; q<nQuad; q++) {
00304              if (fabs(pnt[0] - pnt1[0]) < 1e-8)
00305                     physQuadPts.append( pnt + Point(pnt[0] - pnt1[0],
00306                                                 refQuadPts[q][0]*_peanoMesh->returnResolution(1),
00307                                                 refQuadPts[q][1]*_peanoMesh->returnResolution(2)));
00308              else
00309                if (fabs(pnt[1] - pnt1[1]) < 1e-8)
00310                       physQuadPts.append( pnt + Point(refQuadPts[q][0]*_peanoMesh->returnResolution(0),
00311                                                   pnt[1] - pnt1[1],
00312                                                   refQuadPts[q][1]*_peanoMesh->returnResolution(2)));
00313                else
00314                       physQuadPts.append( pnt + Point(refQuadPts[q][0]*_peanoMesh->returnResolution(0),
00315                                                   refQuadPts[q][1]*_peanoMesh->returnResolution(1),
00316                                                   pnt[2] - pnt1[2]));
00317            }
00318         break;}
00319         case 3:{
00320             for (int q=0; q<nQuad; q++) {
00321                     physQuadPts.append( pnt
00322                        + Point(refQuadPts[q][0]*_peanoMesh->returnResolution(0),
00323                               refQuadPts[q][1]*_peanoMesh->returnResolution(1),
00324                                 refQuadPts[q][2]*_peanoMesh->returnResolution(2)));
00325             }
00326         break;}
00327         default:
00328           TEST_FOR_EXCEPTION(true, InternalError, "impossible switch value "
00329             "in PeanoMesh3D::getJacobians()");
00330       }
00331     }
00332 }
00333 
00334 int PeanoMesh3D::ownerProcID(int cellDim, int cellLID) const  {
00335    SUNDANCE_VERB_HIGH("ownerProcID()"); return 0; }
00336 
00337 
00338 int PeanoMesh3D::numFacets(int cellDim, int cellLID,
00339                       int facetDim) const  {
00340   SUNDANCE_VERB_HIGH("numFacets()");
00341     return _peanoMesh->numFacets(cellDim, cellLID, facetDim);
00342 }
00343 
00344 
00345 int PeanoMesh3D::facetLID(int cellDim, int cellLID,
00346                      int facetDim, int facetIndex,
00347                      int& facetOrientation) const  {
00348     int LID;
00349     LID = _peanoMesh->facetLID( cellDim,cellLID, facetDim, facetIndex, facetOrientation);
00350     //printf("PeanoMesh3D::facetLID  cellDim: %d , cellLID: %d , facetDim %d , facetIndex:%d  %d\n" , cellDim , cellLID , facetDim , facetIndex , LID );
00351   return LID;
00352 }
00353 
00354 void PeanoMesh3D::getFacetLIDs(int cellDim,
00355                           const Array<int>& cellLID,
00356                           int facetDim,
00357                           Array<int>& facetLID,
00358                           Array<int>& facetSign) const {
00359     SUNDANCE_VERB_HIGH("getFacetLIDs()");
00360     //printf("PeanoMesh3D::getFacetLIDs()  cellDim:%d  cellLID.size():%d  facetDim:%d\n" , cellDim, (int)cellLID.size() , facetDim);
00361       int LID = 0 , cLID , facetOrientation ;
00362       int ptr = 0;
00363 
00364       int nf = numFacets(cellDim, cellLID[0], facetDim);
00365       facetLID.resize(cellLID.size() * nf);
00366       facetSign.resize(cellLID.size() * nf);
00367     // At this moment we just use the previous function
00368     for (unsigned int i = 0 ; i < (unsigned int)cellLID.size() ; i++){
00369       cLID = cellLID[i];
00370         for (int f=0; f<nf; f++, ptr++) {
00371           // we use this->facetLID caz facetLID is already used as variable
00372         LID = this->facetLID( cellDim, cLID, facetDim, f , facetOrientation);
00373         //printf("LID:%d , cellDim:%d , cLID:%d , facetDim:%d , f:%d , facetOrientation:%d \n"
00374         //    ,LID , cellDim, cLID, facetDim, f , facetOrientation );
00375             facetLID[ptr] = LID;
00376             facetSign[ptr] = facetOrientation;
00377         }
00378     }
00379 }
00380 
00381 const int* PeanoMesh3D::elemZeroFacetView(int cellLID) const {
00382   return _peanoMesh->elemZeroFacetView(cellLID);
00383 }
00384 
00385 int PeanoMesh3D::numMaxCofacets(int cellDim, int cellLID) const  {
00386     //SUNDANCE_VERB_HIGH("numMaxCofacets()");
00387       int coFacetCounter;
00388       coFacetCounter = _peanoMesh->numMaxCofacets( cellDim, cellLID);
00389     //printf("numMaxCofacets:  cellDim:%d cellLID:%d ret:%d\n",cellDim, cellLID, coFacetCounter);
00390     return coFacetCounter;
00391 }
00392 
00393 int PeanoMesh3D::maxCofacetLID(int cellDim, int cellLID,
00394                        int cofacetIndex,
00395                        int& facetIndex) const  {
00396     int rtn;
00397     rtn = _peanoMesh->maxCofacetLID(cellDim, cellLID, cofacetIndex, facetIndex);
00398     //printf("maxCofacetLID() cellDim:%d,  cellLID:%d, cofacetIndex:%d , rtn:%d , facetIndex:%d\n",
00399     //    cellDim,  cellLID, cofacetIndex , rtn , facetIndex);
00400     return rtn;
00401 }
00402 
00403 void PeanoMesh3D::getMaxCofacetLIDs(const Array<int>& cellLIDs,
00404   MaximalCofacetBatch& cofacets) const {
00405     TEST_FOR_EXCEPTION(true, InternalError," PeanoMesh3D::getMaxCofacetLIDs() not implemented yet");
00406   //TODO: Implement this, uses only in ExodusWriter::writeMesh
00407 }
00408 
00409 
00410 void PeanoMesh3D::getCofacets(int cellDim, int cellLID,
00411                  int cofacetDim, Array<int>& cofacetLIDs) const {
00412     int tmpVect[12] , nrCofacets;
00413     _peanoMesh->getCofacets( cellDim, cellLID, cofacetDim, &tmpVect[0], nrCofacets);
00414     cofacetLIDs.resize(nrCofacets);
00415     for (int ii = 0 ; ii < nrCofacets ; ii++ ) cofacetLIDs[ii] = tmpVect[ii];
00416 }
00417 
00418 
00419 int PeanoMesh3D::mapGIDToLID(int cellDim, int globalIndex) const  {
00420   SUNDANCE_VERB_HIGH("mapGIDToLID()");
00421   // in the serial implementation GID = LID
00422   // in the parallel version this should be done differently
00423   return globalIndex;
00424 }
00425 
00426 bool PeanoMesh3D::hasGID(int cellDim, int globalIndex) const {
00427   SUNDANCE_VERB_HIGH("hasGID()");
00428   // since currently we have a serial implementation , this is always true
00429   // in the parallel version this function has to be implemented differetly
00430   return true;
00431 }
00432 
00433 int PeanoMesh3D::mapLIDToGID(int cellDim, int localIndex) const  {
00434   SUNDANCE_VERB_HIGH("mapLIDToGID()");
00435   // at the current stage we have only serial implementation,
00436   // parallel implementation will(should) come soon
00437   return localIndex;
00438 }
00439 
00440 CellType PeanoMesh3D::cellType(int cellDim) const  {
00441   //printf("cellType() cellDim:%d\n",cellDim);
00442    switch(cellDim)
00443     {
00444       case 0:  return PointCell;
00445       case 1:  return LineCell;
00446       case 2:  return QuadCell;
00447       case 3:  return BrickCell;
00448       default:
00449         return NullCell; // -Wall
00450     }
00451 }
00452 
00453 int PeanoMesh3D::label(int cellDim, int cellLID) const {
00454    return _peanoMesh->label( cellDim, cellLID);
00455 }
00456 
00457 void PeanoMesh3D::getLabels(int cellDim, const Array<int>& cellLID,
00458     Array<int>& labels) const {
00459     int tmpIndex;
00460     SUNDANCE_VERB_HIGH("getLabels()");
00461     // resize the array
00462   labels.resize(cellLID.size());
00463 
00464     for (tmpIndex = 0 ; tmpIndex < (int)cellLID.size() ; tmpIndex++){
00465       labels[tmpIndex] = _peanoMesh->label( cellDim, cellLID[tmpIndex]);
00466     }
00467 }
00468 
00469 Set<int> PeanoMesh3D::getAllLabelsForDimension(int cellDim) const {
00470     Set<int>                 rtn;
00471     int                      tmpIndex;
00472     SUNDANCE_VERB_HIGH("getAllLabelsForDimension()");
00473 
00474     for (tmpIndex = 0 ; tmpIndex < _peanoMesh->numCells(cellDim) ; tmpIndex++){
00475       rtn.put( _peanoMesh->label( cellDim, tmpIndex) );
00476     }
00477     return rtn;
00478 }
00479 
00480 void PeanoMesh3D::getLIDsForLabel(int cellDim, int label, Array<int>& cellLIDs) const {
00481     int                      tmpIndex , tmpLabel;
00482   SUNDANCE_VERB_HIGH("getLIDsForLabel()");
00483     for (tmpIndex = 0 ; tmpIndex < _peanoMesh->numCells(cellDim) ; tmpIndex++){
00484       tmpLabel = this->label( cellDim , tmpIndex);
00485       if (tmpLabel == label) cellLIDs.append( tmpIndex );
00486     }
00487 }
00488 
00489 void PeanoMesh3D::setLabel(int cellDim, int cellLID, int label) {
00490   _peanoMesh->setLabel(cellDim, cellLID, label);
00491 }
00492 
00493 
00494 void PeanoMesh3D::assignIntermediateCellGIDs(int cellDim) {
00495   SUNDANCE_VERB_HIGH("assignIntermediateCellGIDs()");
00496   // in this method we could do synchronization between processors, not usede now
00497 }
00498 
00499 
00500 bool PeanoMesh3D::hasIntermediateGIDs(int dim) const {
00501   SUNDANCE_VERB_HIGH("hasIntermediateGIDs()");
00502   return true; // true means they have been synchronized ... not used now
00503 }
00504 
00505 #endif

Site Contact