SundancePeanoMesh2D.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  * SundancePeanoMesh2D.cpp
00032  *
00033  *  Created on: Sep 8, 2009
00034  *      Author: benk
00035  */
00036 
00037 #include "SundancePeanoMesh2D.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 PeanoMesh2D::returnPoint(0.0 , 0.0);
00060 
00061 PeanoMesh2D::PeanoMesh2D(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 PeanoMesh2D::createMesh(
00070                       double position_x,
00071                 double position_y,
00072                 double offset_x,
00073                 double offset_y,
00074                 double resolution
00075 ){
00076       double position[2];
00077       double offset[2];
00078       double res[2];
00079 
00080       // setting the values of the ctor argument
00081       position[0] = position_x; position[1] = position_y;
00082       offset[0] = offset_x;     offset[1] = offset_y;
00083       res[0] = resolution;      res[1] = resolution;
00084 
00085 
00086       // this is a 2D case
00087       // call the ctor for the Peano mesh
00088       SUNDANCE_VERB_LOW(" create Peano Mesh ... ");
00089       _dimension = 2;
00090       // here we create the Peano grid
00091       _peanoMesh = new SundancePeanoInterface2D( position , offset , res );
00092       _uniqueResolution = _peanoMesh->returnResolution(0);
00093 
00094       SUNDANCE_VERB_LOW(" Peano Mesh created ... \n");
00095       //_peanoMesh->plotVTK("Peano2D");
00096       SUNDANCE_VERB_LOW(" After Plot ... \n");
00097 }
00098 
00099 
00100 PeanoMesh2D::~PeanoMesh2D() {
00101   //delete _peanoMesh;
00102 }
00103 
00104 
00105 int PeanoMesh2D::numCells(int dim) const  {
00106   //printf("PeanoMesh2D::numCells(int dim):%d   dim:%d \n",_peanoMesh->numCells(dim),dim);
00107   return _peanoMesh->numCells(dim);
00108 }
00109 
00110 Point PeanoMesh2D::nodePosition(int i) const {
00111   //SUNDANCE_VERB_HIGH("nodePosition(int i)");
00112   //printf("PeanoMesh2D::nodePosition(int i)   i:%d \n", i);
00113   double* coords;
00114   coords = _peanoMesh->nodePositionView(i);
00115   // set the values
00116   PeanoMesh2D::returnPoint[0] = coords[0];
00117   PeanoMesh2D::returnPoint[1] = coords[1];
00118   return PeanoMesh2D::returnPoint;
00119 }
00120 
00121 const double* PeanoMesh2D::nodePositionView(int i) const {
00122   //printf("PeanoMesh2D::nodePositionView(int i)   i:%d \n", i);
00123   //SUNDANCE_VERB_HIGH("nodePosition(int i)");
00124   nodePosition(i);
00125   return &(PeanoMesh2D::returnPoint[0]);
00126 }
00127 
00128 void PeanoMesh2D::getJacobians(int cellDim, const Array<int>& cellLID,
00129                           CellJacobianBatch& jBatch) const
00130 {
00131     //printf("cellDim:%d  _uniqueResolution:%f ",cellDim, _uniqueResolution);
00132     SUNDANCE_VERB_HIGH("getJacobians()");
00133     TEST_FOR_EXCEPTION(cellDim < 0 || cellDim > spatialDim(), InternalError,
00134       "cellDim=" << cellDim << " is not in expected range [0, " << spatialDim() << "]");
00135     int nCells = cellLID.size();
00136     int tmp , tmp_index , tmp_index1;
00137     Point pnt(0.0,0.0);
00138     Point pnt1(0.0,0.0);
00139 
00140     jBatch.resize(cellLID.size(), spatialDim(), cellDim);
00141     if (cellDim < spatialDim()) // they need the Jacobian of a lower dinemsional element
00142     {
00143       //printf("PeanoMesh2D::getJacobians() cellDim < spatialDim() \n");
00144        for (int i=0; i<nCells; i++)
00145         {
00146          //printf("PeanoMesh2D::getJacobian() cellDim < spatialDim() cellDim:%d , ret:%f \n",cellDim , _uniqueResolution);
00147           double* detJ = jBatch.detJ(i);
00148           switch(cellDim)
00149           {
00150             case 0: *detJ = 1.0;
00151               break;
00152             case 1:
00153              tmp_index  = this->facetLID(cellDim,  cellLID[i] , 0 , 0 , tmp );
00154              tmp_index1 = this->facetLID(cellDim,  cellLID[i] , 0 , 1 , tmp );
00155              pnt = nodePosition(tmp_index);
00156              pnt1 = nodePosition(tmp_index1);
00157              pnt = pnt1 - pnt;
00158                  *detJ = sqrt(pnt * pnt); // the length of the edge
00159             break;
00160             default:
00161               TEST_FOR_EXCEPTION(true, InternalError, "impossible switch value "
00162                 "cellDim=" << cellDim << " in PeanoMesh2D::getJacobians()");
00163           }
00164         }
00165     }else{ // they request the complete Jacoby matrix for this bunch of elements
00166         //Array<double> J(cellDim*cellDim);
00167         SUNDANCE_VERB_HIGH("cellDim == spatialDim()");
00168         for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00169         {
00170         //printf("PeanoMesh2D::getJacobian() cellDim == spatialDim() cellDim:%d , ret:%f \n",cellDim , _uniqueResolution);
00171           double* J = jBatch.jVals(i);
00172           switch(cellDim)
00173           {
00174             case 2:
00175               J[0] = _peanoMesh->returnResolution(0);
00176               J[1] = 0.0;  J[2] = 0.0;   //
00177               J[3] = _peanoMesh->returnResolution(1); // the Jacobi of the quad,
00178             break;
00179             default:
00180               TEST_FOR_EXCEPTION(true, InternalError, "impossible switch value "
00181                 "cellDim=" << cellDim
00182                 << " in SundancePeano2D::getJacobians()");
00183           }
00184         }
00185     }
00186 }
00187 
00188 void PeanoMesh2D::getCellDiameters(int cellDim, const Array<int>& cellLID,
00189                               Array<double>& cellDiameters) const {
00190    TEST_FOR_EXCEPTION(cellDim < 0 || cellDim > spatialDim(), InternalError,
00191       "cellDim=" << cellDim << " is not in expected range [0, " << spatialDim() << "]");
00192    SUNDANCE_VERB_HIGH("getCellDiameters()");
00193     cellDiameters.resize(cellLID.size());
00194 
00195     int tmp , tmp_index , tmp_index1;
00196     Point pnt(0.0,0.0);
00197     Point pnt1(0.0,0.0);
00198 
00199     if (cellDim < spatialDim())
00200     {
00201     //printf("PeanoMesh2D::getCellDiameters(), cellDim < spatialDim() \n ");
00202       for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00203       {
00204         switch(cellDim)
00205         {
00206           case 0:
00207                cellDiameters[i] = 1.0;
00208             break;
00209           case 1:  //length of the edge
00210            tmp_index = this->facetLID(cellDim,  cellLID[i] , 0 , 0 , tmp );
00211            tmp_index1= this->facetLID(cellDim,  cellLID[i] , 0 , 1 , tmp );
00212            pnt = nodePosition(tmp_index);
00213            pnt1 = nodePosition(tmp_index1);
00214            pnt = pnt1 - pnt;
00215            cellDiameters[i] = sqrt(pnt * pnt); // the length of the edge
00216           break;
00217           default:
00218             TEST_FOR_EXCEPTION(true, InternalError, "impossible switch value "
00219               "cellDim=" << cellDim << " in PeanoMesh2D::getCellDiameters()");
00220         }
00221       }
00222     }
00223     else
00224     {
00225     //printf("PeanoMesh2D::getCellDiameters(), cellDim == spatialDim() \n ");
00226       for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00227       {
00228         switch(cellDim)
00229         {
00230           case 2:
00231             cellDiameters[i] = (_peanoMesh->returnResolution(0)+_peanoMesh->returnResolution(1))/2.0;
00232           break;
00233           default:
00234             TEST_FOR_EXCEPTION(true, InternalError, "impossible switch value "
00235               "cellDim=" << cellDim
00236               << " in PeanoMesh2D::getCellDiameters()");
00237         }
00238       }
00239     }
00240 }
00241 
00242 void PeanoMesh2D::pushForward(int cellDim, const Array<int>& cellLID,
00243                          const Array<Point>& refQuadPts,
00244                          Array<Point>& physQuadPts) const {
00245 
00246     //printf("PeanoMesh2D::pushForward cellDim:%d\n",cellDim);
00247     TEST_FOR_EXCEPTION(cellDim < 0 || cellDim > spatialDim(), InternalError,
00248       "cellDim=" << cellDim
00249       << " is not in expected range [0, " << spatialDim()
00250       << "]");
00251 
00252     int nQuad = refQuadPts.size();
00253     double start_point[2] , end_point[2];
00254 
00255     Array<double> J(cellDim*cellDim);
00256 
00257     if (physQuadPts.size() > 0) physQuadPts.resize(0);
00258     physQuadPts.reserve(cellLID.size() * refQuadPts.size());
00259     for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00260     {
00261       int lid = cellLID[i];
00262       _peanoMesh->pushForward( cellDim, lid ,start_point , end_point );
00263         Point pnt( start_point[0] , start_point[1] );
00264         Point pnt1( end_point[0] , end_point[1] );
00265       switch(cellDim)
00266       {
00267         case 0: // integrate one point
00268            physQuadPts.append(pnt);
00269           break;
00270         case 1:{ // integrate on one line
00271            for (int q=0; q<nQuad; q++) {
00272                  physQuadPts.append(pnt + (pnt1-pnt)*refQuadPts[q][0]);
00273             }
00274         break;}
00275         case 2:{
00276              for (int q=0; q<nQuad; q++) {
00277                   physQuadPts.append( pnt
00278                     + Point(refQuadPts[q][0]*_peanoMesh->returnResolution(0),
00279                         refQuadPts[q][1]*_peanoMesh->returnResolution(1)));
00280              }
00281         break;}
00282         default:
00283           TEST_FOR_EXCEPTION(true, InternalError, "impossible switch value "
00284             "in PeanoMesh2D::getJacobians()");
00285       }
00286     }
00287 }
00288 
00289 int PeanoMesh2D::ownerProcID(int cellDim, int cellLID) const  {
00290    SUNDANCE_VERB_HIGH("ownerProcID()"); return 0; }
00291 
00292 
00293 int PeanoMesh2D::numFacets(int cellDim, int cellLID,
00294                       int facetDim) const  {
00295   SUNDANCE_VERB_HIGH("numFacets()");
00296     return _peanoMesh->numFacets(cellDim, cellLID, facetDim);
00297 }
00298 
00299 
00300 int PeanoMesh2D::facetLID(int cellDim, int cellLID,
00301                      int facetDim, int facetIndex,
00302                      int& facetOrientation) const  {
00303     int LID;
00304     LID = _peanoMesh->facetLID( cellDim,cellLID, facetDim, facetIndex, facetOrientation);
00305     //printf("PeanoMesh2D::facetLID  cellDim: %d , cellLID: %d , facetDim %d , facetIndex:%d  %d\n" , cellDim , cellLID , facetDim , facetIndex , LID );
00306   return LID;
00307 }
00308 
00309 void PeanoMesh2D::getFacetLIDs(int cellDim,
00310                           const Array<int>& cellLID,
00311                           int facetDim,
00312                           Array<int>& facetLID,
00313                           Array<int>& facetSign) const {
00314     SUNDANCE_VERB_HIGH("getFacetLIDs()");
00315     //printf("PeanoMesh2D::getFacetLIDs()  cellDim:%d  cellLID.size():%d  facetDim:%d\n" , cellDim, (int)cellLID.size() , facetDim);
00316       int LID = 0 , cLID , facetOrientation ;
00317       int ptr = 0;
00318 
00319       int nf = numFacets(cellDim, cellLID[0], facetDim);
00320       facetLID.resize(cellLID.size() * nf);
00321       facetSign.resize(cellLID.size() * nf);
00322     // At this moment we just use the previous function
00323     for (unsigned int i = 0 ; i < (unsigned int)cellLID.size() ; i++){
00324       cLID = cellLID[i];
00325         for (int f=0; f<nf; f++, ptr++) {
00326           // we use this->facetLID caz facetLID is already used as variable
00327         LID = this->facetLID( cellDim, cLID, facetDim, f , facetOrientation);
00328         //printf("LID:%d , cellDim:%d , cLID:%d , facetDim:%d , f:%d , facetOrientation:%d \n"
00329         //    ,LID , cellDim, cLID, facetDim, f , facetOrientation );
00330             facetLID[ptr] = LID;
00331             facetSign[ptr] = facetOrientation;
00332         }
00333     }
00334 }
00335 
00336 const int* PeanoMesh2D::elemZeroFacetView(int cellLID) const {
00337   return _peanoMesh->elemZeroFacetView(cellLID);
00338 }
00339 
00340 int PeanoMesh2D::numMaxCofacets(int cellDim, int cellLID) const  {
00341     //SUNDANCE_VERB_HIGH("numMaxCofacets()");
00342       int coFacetCounter;
00343       coFacetCounter = _peanoMesh->numMaxCofacets( cellDim, cellLID);
00344     //printf("numMaxCofacets:  cellDim:%d cellLID:%d ret:%d\n",cellDim, cellLID, coFacetCounter);
00345     return coFacetCounter;
00346 }
00347 
00348 int PeanoMesh2D::maxCofacetLID(int cellDim, int cellLID,
00349                        int cofacetIndex,
00350                        int& facetIndex) const  {
00351     int rtn;
00352     rtn = _peanoMesh->maxCofacetLID(cellDim, cellLID, cofacetIndex, facetIndex);
00353     //printf("maxCofacetLID() cellDim:%d,  cellLID:%d, cofacetIndex:%d , rtn:%d , facetIndex:%d\n",
00354     //    cellDim,  cellLID, cofacetIndex , rtn , facetIndex);
00355     return rtn;
00356 }
00357 
00358 void PeanoMesh2D::getMaxCofacetLIDs(const Array<int>& cellLIDs,
00359   MaximalCofacetBatch& cofacets) const {
00360     TEST_FOR_EXCEPTION(true, InternalError," PeanoMesh2D::getMaxCofacetLIDs() not implemented yet");
00361   //TODO: Implement this, uses only in ExodusWriter::writeMesh
00362 }
00363 
00364 
00365 void PeanoMesh2D::getCofacets(int cellDim, int cellLID,
00366                  int cofacetDim, Array<int>& cofacetLIDs) const {
00367     int tmpVect[12] , nrCofacets;
00368     _peanoMesh->getCofacets( cellDim, cellLID, cofacetDim, &tmpVect[0], nrCofacets);
00369     cofacetLIDs.resize(nrCofacets);
00370     for (int ii = 0 ; ii < nrCofacets ; ii++ ) cofacetLIDs[ii] = tmpVect[ii];
00371 }
00372 
00373 
00374 int PeanoMesh2D::mapGIDToLID(int cellDim, int globalIndex) const  {
00375   SUNDANCE_VERB_HIGH("mapGIDToLID()");
00376   // in the serial implementation GID = LID
00377   // in the parallel version this should be done differently
00378   return globalIndex;
00379 }
00380 
00381 bool PeanoMesh2D::hasGID(int cellDim, int globalIndex) const {
00382   SUNDANCE_VERB_HIGH("hasGID()");
00383   // since currently we have a serial implementation , this is always true
00384   // in the parallel version this function has to be implemented differetly
00385   return true;
00386 }
00387 
00388 int PeanoMesh2D::mapLIDToGID(int cellDim, int localIndex) const  {
00389   SUNDANCE_VERB_HIGH("mapLIDToGID()");
00390   // at the current stage we have only serial implementation,
00391   // parallel implementation will(should) come soon
00392   return localIndex;
00393 }
00394 
00395 CellType PeanoMesh2D::cellType(int cellDim) const  {
00396   //printf("cellType() cellDim:%d\n",cellDim);
00397    switch(cellDim)
00398     {
00399       case 0:  return PointCell;
00400       case 1:  return LineCell;
00401       case 2:  return QuadCell;
00402       case 3:  return BrickCell;
00403       default:
00404         return NullCell; // -Wall
00405     }
00406 }
00407 
00408 int PeanoMesh2D::label(int cellDim, int cellLID) const {
00409    return _peanoMesh->label( cellDim, cellLID);
00410 }
00411 
00412 void PeanoMesh2D::getLabels(int cellDim, const Array<int>& cellLID,
00413     Array<int>& labels) const {
00414     int tmpIndex;
00415     SUNDANCE_VERB_HIGH("getLabels()");
00416     // resize the array
00417   labels.resize(cellLID.size());
00418 
00419     for (tmpIndex = 0 ; tmpIndex < (int)cellLID.size() ; tmpIndex++){
00420       labels[tmpIndex] = _peanoMesh->label( cellDim, cellLID[tmpIndex]);
00421     }
00422 }
00423 
00424 Set<int> PeanoMesh2D::getAllLabelsForDimension(int cellDim) const {
00425     Set<int>                 rtn;
00426     int                      tmpIndex;
00427     SUNDANCE_VERB_HIGH("getAllLabelsForDimension()");
00428 
00429     for (tmpIndex = 0 ; tmpIndex < _peanoMesh->numCells(cellDim) ; tmpIndex++){
00430       rtn.put( _peanoMesh->label( cellDim, tmpIndex) );
00431     }
00432     return rtn;
00433 }
00434 
00435 void PeanoMesh2D::getLIDsForLabel(int cellDim, int label, Array<int>& cellLIDs) const {
00436     int                      tmpIndex , tmpLabel;
00437   SUNDANCE_VERB_HIGH("getLIDsForLabel()");
00438     for (tmpIndex = 0 ; tmpIndex < _peanoMesh->numCells(cellDim) ; tmpIndex++){
00439       tmpLabel = this->label( cellDim , tmpIndex);
00440       if (tmpLabel == label) cellLIDs.append( tmpIndex );
00441     }
00442 }
00443 
00444 void PeanoMesh2D::setLabel(int cellDim, int cellLID, int label) {
00445   _peanoMesh->setLabel(cellDim, cellLID, label);
00446 }
00447 
00448 
00449 void PeanoMesh2D::assignIntermediateCellGIDs(int cellDim) {
00450   SUNDANCE_VERB_HIGH("assignIntermediateCellGIDs()");
00451   // in this method we could do synchronization between processors, not usede now
00452 }
00453 
00454 
00455 bool PeanoMesh2D::hasIntermediateGIDs(int dim) const {
00456   SUNDANCE_VERB_HIGH("hasIntermediateGIDs()");
00457   return true; // true means they have been synchronized ... not used now
00458 }
00459 
00460 
00461 #endif

Site Contact