00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #include "SundancePeanoMesh3D.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
00070
00071
00072 Point PeanoMesh3D::returnPoint(0.0 , 0.0 , 0.0);
00073
00074 PeanoMesh3D::PeanoMesh3D(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 PeanoMesh3D::createMesh(
00083 double position_x,
00084 double position_y,
00085 double position_z,
00086 double offset_x,
00087 double offset_y,
00088 double offset_z,
00089 double resolution
00090 ){
00091 double position[3];
00092 double offset[3];
00093 double res[3];
00094
00095
00096 position[0] = position_x; position[1] = position_y; position[2] = position_z;
00097 offset[0] = offset_x; offset[1] = offset_y; offset[2] = offset_z;
00098 res[0] = resolution; res[1] = resolution; res[2] = resolution;
00099
00100
00101
00102
00103 SUNDANCE_VERB_LOW(" create Peano Mesh 3D ... ");
00104 _dimension = 3;
00105
00106 _peanoMesh = new SundancePeanoInterface3D( position , offset , res );
00107 _uniqueResolution = _peanoMesh->returnResolution(0);
00108
00109 SUNDANCE_VERB_LOW(" Peano Mesh created 3D ... \n");
00110 _peanoMesh->plotVTK("Peano3D");
00111 SUNDANCE_VERB_LOW(" After Plot 3D ... \n");
00112 }
00113
00114 PeanoMesh3D::~PeanoMesh3D() {
00115
00116 }
00117
00118
00119 int PeanoMesh3D::numCells(int dim) const {
00120
00121 return _peanoMesh->numCells(dim);
00122 }
00123
00124 Point PeanoMesh3D::nodePosition(int i) const {
00125
00126
00127 double* coords;
00128 coords = _peanoMesh->nodePositionView(i);
00129
00130 PeanoMesh3D::returnPoint[0] = coords[0];
00131 PeanoMesh3D::returnPoint[1] = coords[1];
00132 PeanoMesh3D::returnPoint[2] = coords[2];
00133 return PeanoMesh3D::returnPoint;
00134 }
00135
00136 const double* PeanoMesh3D::nodePositionView(int i) const {
00137
00138
00139 nodePosition(i);
00140 return &(PeanoMesh3D::returnPoint[0]);
00141 }
00142
00143 void PeanoMesh3D::getJacobians(int cellDim, const Array<int>& cellLID,
00144 CellJacobianBatch& jBatch) const
00145 {
00146
00147 SUNDANCE_VERB_HIGH("getJacobians()");
00148 TEUCHOS_TEST_FOR_EXCEPTION(cellDim < 0 || cellDim > spatialDim(), std::logic_error,
00149 "cellDim=" << cellDim << " is not in expected range [0, " << spatialDim() << "]");
00150 int nCells = cellLID.size();
00151 int tmp_index , tmp;
00152 int tmp_index1 , tmp_index2;
00153 Point pnt(0.0,0.0,0.0);
00154 Point pnt1(0.0,0.0,0.0);
00155 Point pnt2(0.0,0.0,0.0);
00156 jBatch.resize(cellLID.size(), spatialDim(), cellDim);
00157 if (cellDim < spatialDim())
00158 {
00159
00160 for (int i=0; i<nCells; i++)
00161 {
00162
00163 double* detJ = jBatch.detJ(i);
00164 switch(cellDim)
00165 {
00166 case 0: *detJ = 1.0;
00167 break;
00168 case 1:
00169 tmp_index = this->facetLID(cellDim, cellLID[i] , 0 , 0 , tmp );
00170 tmp_index1= this->facetLID(cellDim, cellLID[i] , 0 , 1 , tmp );
00171 pnt = nodePosition(tmp_index);
00172 pnt1 = nodePosition(tmp_index1);
00173 pnt = pnt1 - pnt;
00174 *detJ = sqrt(pnt * pnt);
00175 break;
00176 case 2:{
00177 tmp_index = this->facetLID(cellDim, cellLID[i] , 0 , 0 , tmp );
00178 tmp_index1= this->facetLID(cellDim, cellLID[i] , 0 , 1 , tmp );
00179 tmp_index2= this->facetLID(cellDim, cellLID[i] , 0 , 2 , tmp );
00180 pnt = nodePosition(tmp_index);
00181 pnt1 = nodePosition(tmp_index1);
00182 pnt2 = nodePosition(tmp_index2);
00183 Point directedArea = cross( pnt1 - pnt , pnt2 - pnt );
00184 *detJ = sqrt(directedArea * directedArea);
00185 break;}
00186 default:
00187 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "impossible switch value "
00188 "cellDim=" << cellDim << " in PeanoMesh3D::getJacobians()");
00189 }
00190 }
00191 }else{
00192
00193 SUNDANCE_VERB_HIGH("cellDim == spatialDim()");
00194 for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00195 {
00196
00197 double* J = jBatch.jVals(i);
00198 switch(cellDim)
00199 {
00200 case 3:
00201 J[0] = _peanoMesh->returnResolution(0);
00202 J[1] = 0.0; J[2] = 0.0; J[3] = 0.0;
00203 J[4] = _peanoMesh->returnResolution(1);
00204 J[5] = 0.0; J[6] = 0.0; J[7] = 0.0;
00205 J[8] = _peanoMesh->returnResolution(2);
00206 break;
00207 default:
00208 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "impossible switch value "
00209 "cellDim=" << cellDim
00210 << " in PeanoMesh3D::getJacobians()");
00211 }
00212 }
00213 }
00214 }
00215
00216 void PeanoMesh3D::getCellDiameters(int cellDim, const Array<int>& cellLID,
00217 Array<double>& cellDiameters) const {
00218 TEUCHOS_TEST_FOR_EXCEPTION(cellDim < 0 || cellDim > spatialDim(), std::logic_error,
00219 "cellDim=" << cellDim << " is not in expected range [0, " << spatialDim() << "]");
00220 SUNDANCE_VERB_HIGH("getCellDiameters()");
00221 cellDiameters.resize(cellLID.size());
00222
00223 int tmp_index , tmp;
00224 int tmp_index1;
00225 Point pnt(0.0,0.0,0.0);
00226 Point pnt1(0.0,0.0,0.0);
00227
00228 if (cellDim < spatialDim())
00229 {
00230
00231 for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00232 {
00233 switch(cellDim)
00234 {
00235 case 0:
00236 cellDiameters[i] = 1.0;
00237 break;
00238 case 1:
00239 tmp_index = this->facetLID(cellDim, cellLID[i] , 0 , 0 , tmp );
00240 tmp_index1= this->facetLID(cellDim, cellLID[i] , 0 , 1 , tmp );
00241 pnt = nodePosition(tmp_index);
00242 pnt1 = nodePosition(tmp_index1);
00243 pnt = pnt1 - pnt;
00244 cellDiameters[i] = sqrt(pnt * pnt);
00245 break;
00246 case 2:
00247 tmp_index = this->facetLID(cellDim, cellLID[i] , 0 , 0 , tmp );
00248 tmp_index1= this->facetLID(cellDim, cellLID[i] , 0 , 3 , tmp );
00249 pnt = nodePosition(tmp_index);
00250 pnt1 = nodePosition(tmp_index1);
00251 pnt = pnt1 - pnt;
00252 cellDiameters[i] = sqrt(pnt * pnt);
00253 break;
00254 default:
00255 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "impossible switch value "
00256 "cellDim=" << cellDim << " in PeanoMesh3D::getCellDiameters()");
00257 }
00258 }
00259 }
00260 else
00261 {
00262
00263 for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00264 {
00265 switch(cellDim)
00266 {
00267 case 3:
00268 cellDiameters[i] = (_peanoMesh->returnResolution(0) + _peanoMesh->returnResolution(1)
00269 + _peanoMesh->returnResolution(2))/3.0;
00270 break;
00271 default:
00272 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "impossible switch value "
00273 "cellDim=" << cellDim
00274 << " in PeanoMesh3D::getCellDiameters()");
00275 }
00276 }
00277 }
00278 }
00279
00280 void PeanoMesh3D::pushForward(int cellDim, const Array<int>& cellLID,
00281 const Array<Point>& refQuadPts,
00282 Array<Point>& physQuadPts) const {
00283
00284
00285 TEUCHOS_TEST_FOR_EXCEPTION(cellDim < 0 || cellDim > spatialDim(), std::logic_error,
00286 "cellDim=" << cellDim
00287 << " is not in expected range [0, " << spatialDim()
00288 << "]");
00289
00290 int nQuad = refQuadPts.size();
00291 double start_point[3] , end_point[3];
00292 Array<double> J(cellDim*cellDim);
00293
00294 if (physQuadPts.size() > 0) physQuadPts.resize(0);
00295 physQuadPts.reserve(cellLID.size() * refQuadPts.size());
00296 for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00297 {
00298 int lid = cellLID[i];
00299 _peanoMesh->pushForward( cellDim, lid ,start_point , end_point );
00300
00301
00302
00303 Point pnt( start_point[0] , start_point[1] , start_point[2] );
00304 Point pnt1( end_point[0] , end_point[1] , end_point[2]);
00305 switch(cellDim)
00306 {
00307 case 0:
00308 physQuadPts.append(pnt);
00309 break;
00310 case 1:{
00311 for (int q=0; q<nQuad; q++) {
00312 physQuadPts.append(pnt + refQuadPts[q][0]*(pnt1 - pnt));
00313 }
00314 break;}
00315 case 2:{
00316 for (int q=0; q<nQuad; q++) {
00317 if (fabs(pnt[0] - pnt1[0]) < 1e-8)
00318 physQuadPts.append( pnt + Point(pnt[0] - pnt1[0],
00319 refQuadPts[q][0]*_peanoMesh->returnResolution(1),
00320 refQuadPts[q][1]*_peanoMesh->returnResolution(2)));
00321 else
00322 if (fabs(pnt[1] - pnt1[1]) < 1e-8)
00323 physQuadPts.append( pnt + Point(refQuadPts[q][0]*_peanoMesh->returnResolution(0),
00324 pnt[1] - pnt1[1],
00325 refQuadPts[q][1]*_peanoMesh->returnResolution(2)));
00326 else
00327 physQuadPts.append( pnt + Point(refQuadPts[q][0]*_peanoMesh->returnResolution(0),
00328 refQuadPts[q][1]*_peanoMesh->returnResolution(1),
00329 pnt[2] - pnt1[2]));
00330 }
00331 break;}
00332 case 3:{
00333 for (int q=0; q<nQuad; q++) {
00334 physQuadPts.append( pnt
00335 + Point(refQuadPts[q][0]*_peanoMesh->returnResolution(0),
00336 refQuadPts[q][1]*_peanoMesh->returnResolution(1),
00337 refQuadPts[q][2]*_peanoMesh->returnResolution(2)));
00338 }
00339 break;}
00340 default:
00341 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "impossible switch value "
00342 "in PeanoMesh3D::getJacobians()");
00343 }
00344 }
00345 }
00346
00347 int PeanoMesh3D::ownerProcID(int cellDim, int cellLID) const {
00348 SUNDANCE_VERB_HIGH("ownerProcID()"); return 0; }
00349
00350
00351 int PeanoMesh3D::numFacets(int cellDim, int cellLID,
00352 int facetDim) const {
00353 SUNDANCE_VERB_HIGH("numFacets()");
00354 return _peanoMesh->numFacets(cellDim, cellLID, facetDim);
00355 }
00356
00357
00358 int PeanoMesh3D::facetLID(int cellDim, int cellLID,
00359 int facetDim, int facetIndex,
00360 int& facetOrientation) const {
00361 int LID;
00362 LID = _peanoMesh->facetLID( cellDim,cellLID, facetDim, facetIndex, facetOrientation);
00363
00364 return LID;
00365 }
00366
00367 void PeanoMesh3D::getFacetLIDs(int cellDim,
00368 const Array<int>& cellLID,
00369 int facetDim,
00370 Array<int>& facetLID,
00371 Array<int>& facetSign) const {
00372 SUNDANCE_VERB_HIGH("getFacetLIDs()");
00373
00374 int LID = 0 , cLID , facetOrientation ;
00375 int ptr = 0;
00376
00377 int nf = numFacets(cellDim, cellLID[0], facetDim);
00378 facetLID.resize(cellLID.size() * nf);
00379 facetSign.resize(cellLID.size() * nf);
00380
00381 for (unsigned int i = 0 ; i < (unsigned int)cellLID.size() ; i++){
00382 cLID = cellLID[i];
00383 for (int f=0; f<nf; f++, ptr++) {
00384
00385 LID = this->facetLID( cellDim, cLID, facetDim, f , facetOrientation);
00386
00387
00388 facetLID[ptr] = LID;
00389 facetSign[ptr] = facetOrientation;
00390 }
00391 }
00392 }
00393
00394 const int* PeanoMesh3D::elemZeroFacetView(int cellLID) const {
00395 return _peanoMesh->elemZeroFacetView(cellLID);
00396 }
00397
00398 int PeanoMesh3D::numMaxCofacets(int cellDim, int cellLID) const {
00399
00400 int coFacetCounter;
00401 coFacetCounter = _peanoMesh->numMaxCofacets( cellDim, cellLID);
00402
00403 return coFacetCounter;
00404 }
00405
00406 int PeanoMesh3D::maxCofacetLID(int cellDim, int cellLID,
00407 int cofacetIndex,
00408 int& facetIndex) const {
00409 int rtn;
00410 rtn = _peanoMesh->maxCofacetLID(cellDim, cellLID, cofacetIndex, facetIndex);
00411
00412
00413 return rtn;
00414 }
00415
00416 void PeanoMesh3D::getMaxCofacetLIDs(const Array<int>& cellLIDs,
00417 MaximalCofacetBatch& cofacets) const {
00418 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error," PeanoMesh3D::getMaxCofacetLIDs() not implemented yet");
00419
00420 }
00421
00422
00423 void PeanoMesh3D::getCofacets(int cellDim, int cellLID,
00424 int cofacetDim, Array<int>& cofacetLIDs) const {
00425 int tmpVect[12] , nrCofacets;
00426 _peanoMesh->getCofacets( cellDim, cellLID, cofacetDim, &tmpVect[0], nrCofacets);
00427 cofacetLIDs.resize(nrCofacets);
00428 for (int ii = 0 ; ii < nrCofacets ; ii++ ) cofacetLIDs[ii] = tmpVect[ii];
00429 }
00430
00431
00432 int PeanoMesh3D::mapGIDToLID(int cellDim, int globalIndex) const {
00433 SUNDANCE_VERB_HIGH("mapGIDToLID()");
00434
00435
00436 return globalIndex;
00437 }
00438
00439 bool PeanoMesh3D::hasGID(int cellDim, int globalIndex) const {
00440 SUNDANCE_VERB_HIGH("hasGID()");
00441
00442
00443 return true;
00444 }
00445
00446 int PeanoMesh3D::mapLIDToGID(int cellDim, int localIndex) const {
00447 SUNDANCE_VERB_HIGH("mapLIDToGID()");
00448
00449
00450 return localIndex;
00451 }
00452
00453 CellType PeanoMesh3D::cellType(int cellDim) const {
00454
00455 switch(cellDim)
00456 {
00457 case 0: return PointCell;
00458 case 1: return LineCell;
00459 case 2: return QuadCell;
00460 case 3: return BrickCell;
00461 default:
00462 return NullCell;
00463 }
00464 }
00465
00466 int PeanoMesh3D::label(int cellDim, int cellLID) const {
00467 return _peanoMesh->label( cellDim, cellLID);
00468 }
00469
00470 void PeanoMesh3D::getLabels(int cellDim, const Array<int>& cellLID,
00471 Array<int>& labels) const {
00472 int tmpIndex;
00473 SUNDANCE_VERB_HIGH("getLabels()");
00474
00475 labels.resize(cellLID.size());
00476
00477 for (tmpIndex = 0 ; tmpIndex < (int)cellLID.size() ; tmpIndex++){
00478 labels[tmpIndex] = _peanoMesh->label( cellDim, cellLID[tmpIndex]);
00479 }
00480 }
00481
00482 Set<int> PeanoMesh3D::getAllLabelsForDimension(int cellDim) const {
00483 Set<int> rtn;
00484 int tmpIndex;
00485 SUNDANCE_VERB_HIGH("getAllLabelsForDimension()");
00486
00487 for (tmpIndex = 0 ; tmpIndex < _peanoMesh->numCells(cellDim) ; tmpIndex++){
00488 rtn.put( _peanoMesh->label( cellDim, tmpIndex) );
00489 }
00490 return rtn;
00491 }
00492
00493 void PeanoMesh3D::getLIDsForLabel(int cellDim, int label, Array<int>& cellLIDs) const {
00494 int tmpIndex , tmpLabel;
00495 SUNDANCE_VERB_HIGH("getLIDsForLabel()");
00496 for (tmpIndex = 0 ; tmpIndex < _peanoMesh->numCells(cellDim) ; tmpIndex++){
00497 tmpLabel = this->label( cellDim , tmpIndex);
00498 if (tmpLabel == label) cellLIDs.append( tmpIndex );
00499 }
00500 }
00501
00502 void PeanoMesh3D::setLabel(int cellDim, int cellLID, int label) {
00503 _peanoMesh->setLabel(cellDim, cellLID, label);
00504 }
00505
00506
00507 void PeanoMesh3D::assignIntermediateCellGIDs(int cellDim) {
00508 SUNDANCE_VERB_HIGH("assignIntermediateCellGIDs()");
00509
00510 }
00511
00512
00513 bool PeanoMesh3D::hasIntermediateGIDs(int dim) const {
00514 SUNDANCE_VERB_HIGH("hasIntermediateGIDs()");
00515 return true;
00516 }
00517
00518 #endif