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 #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
00057
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
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
00089
00090 SUNDANCE_VERB_LOW(" create Peano Mesh 3D ... ");
00091 _dimension = 3;
00092
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
00103 }
00104
00105
00106 int PeanoMesh3D::numCells(int dim) const {
00107
00108 return _peanoMesh->numCells(dim);
00109 }
00110
00111 Point PeanoMesh3D::nodePosition(int i) const {
00112
00113
00114 double* coords;
00115 coords = _peanoMesh->nodePositionView(i);
00116
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
00125
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
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())
00145 {
00146
00147 for (int i=0; i<nCells; i++)
00148 {
00149
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);
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);
00172 break;}
00173 default:
00174 TEST_FOR_EXCEPTION(true, InternalError, "impossible switch value "
00175 "cellDim=" << cellDim << " in PeanoMesh3D::getJacobians()");
00176 }
00177 }
00178 }else{
00179
00180 SUNDANCE_VERB_HIGH("cellDim == spatialDim()");
00181 for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00182 {
00183
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);
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
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);
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);
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
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
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
00288
00289
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:
00295 physQuadPts.append(pnt);
00296 break;
00297 case 1:{
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
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
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
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
00372 LID = this->facetLID( cellDim, cLID, facetDim, f , facetOrientation);
00373
00374
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
00387 int coFacetCounter;
00388 coFacetCounter = _peanoMesh->numMaxCofacets( cellDim, cellLID);
00389
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
00399
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
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
00422
00423 return globalIndex;
00424 }
00425
00426 bool PeanoMesh3D::hasGID(int cellDim, int globalIndex) const {
00427 SUNDANCE_VERB_HIGH("hasGID()");
00428
00429
00430 return true;
00431 }
00432
00433 int PeanoMesh3D::mapLIDToGID(int cellDim, int localIndex) const {
00434 SUNDANCE_VERB_HIGH("mapLIDToGID()");
00435
00436
00437 return localIndex;
00438 }
00439
00440 CellType PeanoMesh3D::cellType(int cellDim) const {
00441
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;
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
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
00497 }
00498
00499
00500 bool PeanoMesh3D::hasIntermediateGIDs(int dim) const {
00501 SUNDANCE_VERB_HIGH("hasIntermediateGIDs()");
00502 return true;
00503 }
00504
00505 #endif