SundancePeanoMesh2D.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                             Sundance
00005 //                 Copyright 2011 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Kevin Long (kevin.long@ttu.edu)
00038 // 
00039 
00040 /* @HEADER@ */
00041 /*
00042  * SundancePeanoMesh2D.cpp
00043  *
00044  *  Created on: Sep 8, 2009
00045  *      Author: benk
00046  */
00047 
00048 #include "SundancePeanoMesh2D.hpp"
00049 
00050 #include "SundanceMeshType.hpp"
00051 #include "SundanceCellJacobianBatch.hpp"
00052 #include "SundanceMaximalCofacetBatch.hpp"
00053 #include "SundanceMeshSource.hpp"
00054 #include "SundanceDebug.hpp"
00055 #include "SundanceOut.hpp"
00056 #include "PlayaMPIContainerComm.hpp"
00057 #include "Teuchos_Time.hpp"
00058 #include "Teuchos_TimeMonitor.hpp"
00059 #include "SundanceObjectWithVerbosity.hpp"
00060 #include "SundanceCollectiveExceptionCheck.hpp"
00061 
00062 #ifdef HAVE_SUNDANCE_PEANO
00063 
00064 using namespace Sundance;
00065 using namespace Teuchos;
00066 using Playa::MPIComm;
00067 using Playa::MPIContainerComm;
00068 
00069 //#define printf(msg)
00070 //#define SUNDANCE_VERB_HIGH(msg) printf(msg);printf("\n");
00071 
00072 Point PeanoMesh2D::returnPoint(0.0 , 0.0);
00073 
00074 PeanoMesh2D::PeanoMesh2D(int dim, const MPIComm& comm ,
00075       const MeshEntityOrder& order)
00076 : MeshBase(dim, comm , order),_dimension(dim), _comm(comm)
00077  ,_peanoMesh(NULL)
00078 {
00079   _uniqueResolution = 1.0;
00080 }
00081 
00082 void PeanoMesh2D::createMesh(
00083                       double position_x,
00084                 double position_y,
00085                 double offset_x,
00086                 double offset_y,
00087                 double resolution
00088 ){
00089       double position[2];
00090       double offset[2];
00091       double res[2];
00092 
00093       // setting the values of the ctor argument
00094       position[0] = position_x; position[1] = position_y;
00095       offset[0] = offset_x;     offset[1] = offset_y;
00096       res[0] = resolution;      res[1] = resolution;
00097 
00098 
00099       // this is a 2D case
00100       // call the ctor for the Peano mesh
00101       SUNDANCE_VERB_LOW(" create Peano Mesh ... ");
00102       _dimension = 2;
00103       // here we create the Peano grid
00104       _peanoMesh = new SundancePeanoInterface2D( position , offset , res );
00105       _uniqueResolution = _peanoMesh->returnResolution(0);
00106 
00107       SUNDANCE_VERB_LOW(" Peano Mesh created ... \n");
00108       //_peanoMesh->plotVTK("Peano2D");
00109       SUNDANCE_VERB_LOW(" After Plot ... \n");
00110 }
00111 
00112 
00113 PeanoMesh2D::~PeanoMesh2D() {
00114   //delete _peanoMesh;
00115 }
00116 
00117 
00118 int PeanoMesh2D::numCells(int dim) const  {
00119   //printf("PeanoMesh2D::numCells(int dim):%d   dim:%d \n",_peanoMesh->numCells(dim),dim);
00120   return _peanoMesh->numCells(dim);
00121 }
00122 
00123 Point PeanoMesh2D::nodePosition(int i) const {
00124   //SUNDANCE_VERB_HIGH("nodePosition(int i)");
00125   //printf("PeanoMesh2D::nodePosition(int i)   i:%d \n", i);
00126   double* coords;
00127   coords = _peanoMesh->nodePositionView(i);
00128   // set the values
00129   PeanoMesh2D::returnPoint[0] = coords[0];
00130   PeanoMesh2D::returnPoint[1] = coords[1];
00131   return PeanoMesh2D::returnPoint;
00132 }
00133 
00134 const double* PeanoMesh2D::nodePositionView(int i) const {
00135   //printf("PeanoMesh2D::nodePositionView(int i)   i:%d \n", i);
00136   //SUNDANCE_VERB_HIGH("nodePosition(int i)");
00137   nodePosition(i);
00138   return &(PeanoMesh2D::returnPoint[0]);
00139 }
00140 
00141 void PeanoMesh2D::getJacobians(int cellDim, const Array<int>& cellLID,
00142                           CellJacobianBatch& jBatch) const
00143 {
00144     //printf("cellDim:%d  _uniqueResolution:%f ",cellDim, _uniqueResolution);
00145     SUNDANCE_VERB_HIGH("getJacobians()");
00146     TEUCHOS_TEST_FOR_EXCEPTION(cellDim < 0 || cellDim > spatialDim(), std::logic_error,
00147       "cellDim=" << cellDim << " is not in expected range [0, " << spatialDim() << "]");
00148     int nCells = cellLID.size();
00149     int tmp , tmp_index , tmp_index1;
00150     Point pnt(0.0,0.0);
00151     Point pnt1(0.0,0.0);
00152 
00153     jBatch.resize(cellLID.size(), spatialDim(), cellDim);
00154     if (cellDim < spatialDim()) // they need the Jacobian of a lower dinemsional element
00155     {
00156       //printf("PeanoMesh2D::getJacobians() cellDim < spatialDim() \n");
00157        for (int i=0; i<nCells; i++)
00158         {
00159          //printf("PeanoMesh2D::getJacobian() cellDim < spatialDim() cellDim:%d , ret:%f \n",cellDim , _uniqueResolution);
00160           double* detJ = jBatch.detJ(i);
00161           switch(cellDim)
00162           {
00163             case 0: *detJ = 1.0;
00164               break;
00165             case 1:
00166              tmp_index  = this->facetLID(cellDim,  cellLID[i] , 0 , 0 , tmp );
00167              tmp_index1 = this->facetLID(cellDim,  cellLID[i] , 0 , 1 , tmp );
00168              pnt = nodePosition(tmp_index);
00169              pnt1 = nodePosition(tmp_index1);
00170              pnt = pnt1 - pnt;
00171                  *detJ = sqrt(pnt * pnt); // the length of the edge
00172             break;
00173             default:
00174               TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "impossible switch value "
00175                 "cellDim=" << cellDim << " in PeanoMesh2D::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("PeanoMesh2D::getJacobian() cellDim == spatialDim() cellDim:%d , ret:%f \n",cellDim , _uniqueResolution);
00184           double* J = jBatch.jVals(i);
00185           switch(cellDim)
00186           {
00187             case 2:
00188               J[0] = _peanoMesh->returnResolution(0);
00189               J[1] = 0.0;  J[2] = 0.0;   //
00190               J[3] = _peanoMesh->returnResolution(1); // the Jacobi of the quad,
00191             break;
00192             default:
00193               TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "impossible switch value "
00194                 "cellDim=" << cellDim
00195                 << " in SundancePeano2D::getJacobians()");
00196           }
00197         }
00198     }
00199 }
00200 
00201 void PeanoMesh2D::getCellDiameters(int cellDim, const Array<int>& cellLID,
00202                               Array<double>& cellDiameters) const {
00203    TEUCHOS_TEST_FOR_EXCEPTION(cellDim < 0 || cellDim > spatialDim(), std::logic_error,
00204       "cellDim=" << cellDim << " is not in expected range [0, " << spatialDim() << "]");
00205    SUNDANCE_VERB_HIGH("getCellDiameters()");
00206     cellDiameters.resize(cellLID.size());
00207 
00208     int tmp , tmp_index , tmp_index1;
00209     Point pnt(0.0,0.0);
00210     Point pnt1(0.0,0.0);
00211 
00212     if (cellDim < spatialDim())
00213     {
00214     //printf("PeanoMesh2D::getCellDiameters(), cellDim < spatialDim() \n ");
00215       for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00216       {
00217         switch(cellDim)
00218         {
00219           case 0:
00220                cellDiameters[i] = 1.0;
00221             break;
00222           case 1:  //length of the edge
00223            tmp_index = this->facetLID(cellDim,  cellLID[i] , 0 , 0 , tmp );
00224            tmp_index1= this->facetLID(cellDim,  cellLID[i] , 0 , 1 , tmp );
00225            pnt = nodePosition(tmp_index);
00226            pnt1 = nodePosition(tmp_index1);
00227            pnt = pnt1 - pnt;
00228            cellDiameters[i] = sqrt(pnt * pnt); // the length of the edge
00229           break;
00230           default:
00231             TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "impossible switch value "
00232               "cellDim=" << cellDim << " in PeanoMesh2D::getCellDiameters()");
00233         }
00234       }
00235     }
00236     else
00237     {
00238     //printf("PeanoMesh2D::getCellDiameters(), cellDim == spatialDim() \n ");
00239       for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00240       {
00241         switch(cellDim)
00242         {
00243           case 2:
00244             cellDiameters[i] = (_peanoMesh->returnResolution(0)+_peanoMesh->returnResolution(1))/2.0;
00245           break;
00246           default:
00247             TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "impossible switch value "
00248               "cellDim=" << cellDim
00249               << " in PeanoMesh2D::getCellDiameters()");
00250         }
00251       }
00252     }
00253 }
00254 
00255 void PeanoMesh2D::pushForward(int cellDim, const Array<int>& cellLID,
00256                          const Array<Point>& refQuadPts,
00257                          Array<Point>& physQuadPts) const {
00258 
00259     //printf("PeanoMesh2D::pushForward cellDim:%d\n",cellDim);
00260     TEUCHOS_TEST_FOR_EXCEPTION(cellDim < 0 || cellDim > spatialDim(), std::logic_error,
00261       "cellDim=" << cellDim
00262       << " is not in expected range [0, " << spatialDim()
00263       << "]");
00264 
00265     int nQuad = refQuadPts.size();
00266     double start_point[2] , end_point[2];
00267 
00268     Array<double> J(cellDim*cellDim);
00269 
00270     if (physQuadPts.size() > 0) physQuadPts.resize(0);
00271     physQuadPts.reserve(cellLID.size() * refQuadPts.size());
00272     for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00273     {
00274       int lid = cellLID[i];
00275       _peanoMesh->pushForward( cellDim, lid ,start_point , end_point );
00276         Point pnt( start_point[0] , start_point[1] );
00277         Point pnt1( end_point[0] , end_point[1] );
00278       switch(cellDim)
00279       {
00280         case 0: // integrate one point
00281            physQuadPts.append(pnt);
00282           break;
00283         case 1:{ // integrate on one line
00284            for (int q=0; q<nQuad; q++) {
00285                  physQuadPts.append(pnt + (pnt1-pnt)*refQuadPts[q][0]);
00286             }
00287         break;}
00288         case 2:{
00289              for (int q=0; q<nQuad; q++) {
00290                   physQuadPts.append( pnt
00291                     + Point(refQuadPts[q][0]*_peanoMesh->returnResolution(0),
00292                         refQuadPts[q][1]*_peanoMesh->returnResolution(1)));
00293              }
00294         break;}
00295         default:
00296           TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "impossible switch value "
00297             "in PeanoMesh2D::getJacobians()");
00298       }
00299     }
00300 }
00301 
00302 int PeanoMesh2D::ownerProcID(int cellDim, int cellLID) const  {
00303    SUNDANCE_VERB_HIGH("ownerProcID()"); return 0; }
00304 
00305 
00306 int PeanoMesh2D::numFacets(int cellDim, int cellLID,
00307                       int facetDim) const  {
00308   SUNDANCE_VERB_HIGH("numFacets()");
00309     return _peanoMesh->numFacets(cellDim, cellLID, facetDim);
00310 }
00311 
00312 
00313 int PeanoMesh2D::facetLID(int cellDim, int cellLID,
00314                      int facetDim, int facetIndex,
00315                      int& facetOrientation) const  {
00316     int LID;
00317     LID = _peanoMesh->facetLID( cellDim,cellLID, facetDim, facetIndex, facetOrientation);
00318     //printf("PeanoMesh2D::facetLID  cellDim: %d , cellLID: %d , facetDim %d , facetIndex:%d  %d\n" , cellDim , cellLID , facetDim , facetIndex , LID );
00319   return LID;
00320 }
00321 
00322 void PeanoMesh2D::getFacetLIDs(int cellDim,
00323                           const Array<int>& cellLID,
00324                           int facetDim,
00325                           Array<int>& facetLID,
00326                           Array<int>& facetSign) const {
00327     SUNDANCE_VERB_HIGH("getFacetLIDs()");
00328     //printf("PeanoMesh2D::getFacetLIDs()  cellDim:%d  cellLID.size():%d  facetDim:%d\n" , cellDim, (int)cellLID.size() , facetDim);
00329       int LID = 0 , cLID , facetOrientation ;
00330       int ptr = 0;
00331 
00332       int nf = numFacets(cellDim, cellLID[0], facetDim);
00333       facetLID.resize(cellLID.size() * nf);
00334       facetSign.resize(cellLID.size() * nf);
00335     // At this moment we just use the previous function
00336     for (unsigned int i = 0 ; i < (unsigned int)cellLID.size() ; i++){
00337       cLID = cellLID[i];
00338         for (int f=0; f<nf; f++, ptr++) {
00339           // we use this->facetLID caz facetLID is already used as variable
00340         LID = this->facetLID( cellDim, cLID, facetDim, f , facetOrientation);
00341         //printf("LID:%d , cellDim:%d , cLID:%d , facetDim:%d , f:%d , facetOrientation:%d \n"
00342         //    ,LID , cellDim, cLID, facetDim, f , facetOrientation );
00343             facetLID[ptr] = LID;
00344             facetSign[ptr] = facetOrientation;
00345         }
00346     }
00347 }
00348 
00349 const int* PeanoMesh2D::elemZeroFacetView(int cellLID) const {
00350   return _peanoMesh->elemZeroFacetView(cellLID);
00351 }
00352 
00353 int PeanoMesh2D::numMaxCofacets(int cellDim, int cellLID) const  {
00354     //SUNDANCE_VERB_HIGH("numMaxCofacets()");
00355       int coFacetCounter;
00356       coFacetCounter = _peanoMesh->numMaxCofacets( cellDim, cellLID);
00357     //printf("numMaxCofacets:  cellDim:%d cellLID:%d ret:%d\n",cellDim, cellLID, coFacetCounter);
00358     return coFacetCounter;
00359 }
00360 
00361 int PeanoMesh2D::maxCofacetLID(int cellDim, int cellLID,
00362                        int cofacetIndex,
00363                        int& facetIndex) const  {
00364     int rtn;
00365     rtn = _peanoMesh->maxCofacetLID(cellDim, cellLID, cofacetIndex, facetIndex);
00366     //printf("maxCofacetLID() cellDim:%d,  cellLID:%d, cofacetIndex:%d , rtn:%d , facetIndex:%d\n",
00367     //    cellDim,  cellLID, cofacetIndex , rtn , facetIndex);
00368     return rtn;
00369 }
00370 
00371 void PeanoMesh2D::getMaxCofacetLIDs(const Array<int>& cellLIDs,
00372   MaximalCofacetBatch& cofacets) const {
00373     TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error," PeanoMesh2D::getMaxCofacetLIDs() not implemented yet");
00374   //TODO: Implement this, uses only in ExodusWriter::writeMesh
00375 }
00376 
00377 
00378 void PeanoMesh2D::getCofacets(int cellDim, int cellLID,
00379                  int cofacetDim, Array<int>& cofacetLIDs) const {
00380     int tmpVect[12] , nrCofacets;
00381     _peanoMesh->getCofacets( cellDim, cellLID, cofacetDim, &tmpVect[0], nrCofacets);
00382     cofacetLIDs.resize(nrCofacets);
00383     for (int ii = 0 ; ii < nrCofacets ; ii++ ) cofacetLIDs[ii] = tmpVect[ii];
00384 }
00385 
00386 
00387 int PeanoMesh2D::mapGIDToLID(int cellDim, int globalIndex) const  {
00388   SUNDANCE_VERB_HIGH("mapGIDToLID()");
00389   // in the serial implementation GID = LID
00390   // in the parallel version this should be done differently
00391   return globalIndex;
00392 }
00393 
00394 bool PeanoMesh2D::hasGID(int cellDim, int globalIndex) const {
00395   SUNDANCE_VERB_HIGH("hasGID()");
00396   // since currently we have a serial implementation , this is always true
00397   // in the parallel version this function has to be implemented differetly
00398   return true;
00399 }
00400 
00401 int PeanoMesh2D::mapLIDToGID(int cellDim, int localIndex) const  {
00402   SUNDANCE_VERB_HIGH("mapLIDToGID()");
00403   // at the current stage we have only serial implementation,
00404   // parallel implementation will(should) come soon
00405   return localIndex;
00406 }
00407 
00408 CellType PeanoMesh2D::cellType(int cellDim) const  {
00409   //printf("cellType() cellDim:%d\n",cellDim);
00410    switch(cellDim)
00411     {
00412       case 0:  return PointCell;
00413       case 1:  return LineCell;
00414       case 2:  return QuadCell;
00415       case 3:  return BrickCell;
00416       default:
00417         return NullCell; // -Wall
00418     }
00419 }
00420 
00421 int PeanoMesh2D::label(int cellDim, int cellLID) const {
00422    return _peanoMesh->label( cellDim, cellLID);
00423 }
00424 
00425 void PeanoMesh2D::getLabels(int cellDim, const Array<int>& cellLID,
00426     Array<int>& labels) const {
00427     int tmpIndex;
00428     SUNDANCE_VERB_HIGH("getLabels()");
00429     // resize the array
00430   labels.resize(cellLID.size());
00431 
00432     for (tmpIndex = 0 ; tmpIndex < (int)cellLID.size() ; tmpIndex++){
00433       labels[tmpIndex] = _peanoMesh->label( cellDim, cellLID[tmpIndex]);
00434     }
00435 }
00436 
00437 Set<int> PeanoMesh2D::getAllLabelsForDimension(int cellDim) const {
00438     Set<int>                 rtn;
00439     int                      tmpIndex;
00440     SUNDANCE_VERB_HIGH("getAllLabelsForDimension()");
00441 
00442     for (tmpIndex = 0 ; tmpIndex < _peanoMesh->numCells(cellDim) ; tmpIndex++){
00443       rtn.put( _peanoMesh->label( cellDim, tmpIndex) );
00444     }
00445     return rtn;
00446 }
00447 
00448 void PeanoMesh2D::getLIDsForLabel(int cellDim, int label, Array<int>& cellLIDs) const {
00449     int                      tmpIndex , tmpLabel;
00450   SUNDANCE_VERB_HIGH("getLIDsForLabel()");
00451     for (tmpIndex = 0 ; tmpIndex < _peanoMesh->numCells(cellDim) ; tmpIndex++){
00452       tmpLabel = this->label( cellDim , tmpIndex);
00453       if (tmpLabel == label) cellLIDs.append( tmpIndex );
00454     }
00455 }
00456 
00457 void PeanoMesh2D::setLabel(int cellDim, int cellLID, int label) {
00458   _peanoMesh->setLabel(cellDim, cellLID, label);
00459 }
00460 
00461 
00462 void PeanoMesh2D::assignIntermediateCellGIDs(int cellDim) {
00463   SUNDANCE_VERB_HIGH("assignIntermediateCellGIDs()");
00464   // in this method we could do synchronization between processors, not usede now
00465 }
00466 
00467 
00468 bool PeanoMesh2D::hasIntermediateGIDs(int dim) const {
00469   SUNDANCE_VERB_HIGH("hasIntermediateGIDs()");
00470   return true; // true means they have been synchronized ... not used now
00471 }
00472 
00473 
00474 #endif

Site Contact