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 "SundanceHNMesh2D.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 _MSC_VER
00063 static double log2(double x)
00064 {
00065 return log(x)/log(2.0);
00066 }
00067 #endif
00068
00069 using namespace Sundance;
00070 using namespace Teuchos;
00071 using namespace std;
00072 using Playa::MPIComm;
00073 using Playa::MPIContainerComm;
00074
00075 int HNMesh2D::offs_Points_x_[4] = {0, 1, 0, 1};
00076
00077 int HNMesh2D::offs_Points_y_[4] = {0, 0, 1, 1};
00078
00079 int HNMesh2D::edge_Points_localIndex[4][2] = { {0,1} , {0,2} , {1,3} , {2,3} };
00080
00081
00082 HNMesh2D::HNMesh2D(int dim, const MPIComm& comm ,
00083 const MeshEntityOrder& order)
00084 : MeshBase(dim, comm , order),_dimension(dim), _comm(comm)
00085 {
00086 setVerb(0);
00087
00088 nrProc_ = MPIComm::world().getNProc();
00089 myRank_ = MPIComm::world().getRank();
00090
00091 points_.resize(0);
00092 nrElem_.resize(3,0);
00093 nrElemOwned_.resize(3,0);
00094
00095 cellsPoints_.resize(0);
00096 cellsEdges_.resize(0);
00097 isCellOut_.resize(0);
00098 edgePoints_.resize(0);
00099 edgeVertex_.resize(0);
00100
00101 edgeMaxCoF_.resize(0);
00102 pointMaxCoF_.resize(0);
00103
00104 elementOwner_.resize(3); elementOwner_[0].resize(0); elementOwner_[1].resize(0); elementOwner_[2].resize(0);
00105
00106 edgeIsProcBonudary_.resize(0);
00107 edgeIsMeshDomainBonudary_.resize(0);
00108
00109 indexInParent_.resize(0);
00110 parentCellLID_.resize(0);
00111 cellLevel_.resize(0);
00112 isCellLeaf_.resize(0);
00113
00114 isPointHanging_.resize(0);
00115 isEdgeHanging_.resize(0);
00116
00117 hangElmStore_.resize(2);
00118 hangElmStore_[0] = Hashtable< int, Array<int> >();
00119 hangElmStore_[1] = Hashtable< int, Array<int> >();
00120 refineCell_.resize(0);
00121
00122 nrCellLeafGID_ = 0; nrEdgeLeafGID_ = 0; nrVertexLeafGID_ = 0;
00123 nrVertexLeafLID_ = 0; nrCellLeafLID_ = 0; nrEdgeLeafLID_ = 0;
00124 }
00125
00126 int HNMesh2D::numCells(int dim) const {
00127 SUNDANCE_MSG3(verb(),"HNMesh2D::numCells(int dim): dim:" << dim );
00128 switch (dim){
00129 case 0: return nrVertexLeafLID_;
00130 case 1: return nrEdgeLeafLID_;
00131 case 2: return nrCellLeafLID_;
00132 }
00133 return 0;
00134 }
00135
00136 Point HNMesh2D::nodePosition(int i) const {
00137 SUNDANCE_MSG3(verb(),"HNMesh2D::nodePosition(int i) i:"<< i);
00138
00139 return points_[vertexLeafToLIDMapping_[i]];
00140 }
00141
00142 const double* HNMesh2D::nodePositionView(int i) const {
00143 SUNDANCE_MSG3(verb(),"HNMesh2D::nodePositionView(int i) i:" << i);
00144
00145 return &(points_[vertexLeafToLIDMapping_[i]][0]);;
00146 }
00147
00148 void HNMesh2D::getJacobians(int cellDim, const Array<int>& cellLID,
00149 CellJacobianBatch& jBatch) const
00150 {
00151 SUNDANCE_MSG3(verb(),"HNMesh2D::getJacobians cellDim:"<<cellDim<<" _x:"<<_ofs_x<<" _y:"<<_ofs_y);
00152 SUNDANCE_VERB_HIGH("getJacobians()");
00153 TEUCHOS_TEST_FOR_EXCEPTION(cellDim < 0 || cellDim > spatialDim(), std::logic_error,
00154 "cellDim=" << cellDim << " is not in expected range [0, " << spatialDim() << "]");
00155 int nCells = cellLID.size();
00156 int LID;
00157 Point pnt(0.0,0.0);
00158 jBatch.resize(cellLID.size(), spatialDim(), cellDim);
00159 if (cellDim < spatialDim())
00160 {
00161 for (int i=0; i<nCells; i++)
00162 {
00163 double* detJ = jBatch.detJ(i);
00164 switch(cellDim)
00165 {
00166 case 0: *detJ = 1.0;
00167 break;
00168 case 1:
00169 LID = edgeLeafToLIDMapping_[cellLID[i]];
00170 pnt = (points_[edgePoints_[LID][1]] - points_[edgePoints_[LID][0]]);
00171 *detJ = sqrt(pnt * pnt);
00172 break;
00173 default:
00174 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "impossible switch value " "cellDim=" << cellDim << " in HNMesh2D::getJacobians()");
00175 }
00176 }
00177 }else{
00178
00179 SUNDANCE_VERB_HIGH("cellDim == spatialDim()");
00180 for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00181 {
00182 double* J = jBatch.jVals(i);
00183 switch(cellDim)
00184 {
00185 case 2:
00186 LID = cellLeafToLIDMapping_[cellLID[i]];
00187
00188 J[0] = points_[cellsPoints_[LID][1]][0] - points_[cellsPoints_[LID][0]][0];
00189 J[1] = 0.0;
00190 J[2] = 0.0;
00191 J[3] = points_[cellsPoints_[LID][2]][1] - points_[cellsPoints_[LID][0]][1];
00192 SUNDANCE_MSG3(verb() , "HNMesh2D::getJacobians X:" << J[0] << " Y:" << J[3] );
00193 break;
00194 default:
00195 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "impossible switch value " "cellDim=" << cellDim << " in HNMesh2D::getJacobians()");
00196 }
00197 }
00198 }
00199 }
00200
00201 void HNMesh2D::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 Point pnt(0.0,0.0);
00208 int LID;
00209 if (cellDim < spatialDim())
00210 {
00211 SUNDANCE_MSG3(verb(),"HNMesh2D::getCellDiameters(), cellDim < spatialDim() ");
00212 for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00213 {
00214 switch(cellDim)
00215 {
00216 case 0:
00217 cellDiameters[i] = 1.0;
00218 break;
00219 case 1:
00220 LID = edgeLeafToLIDMapping_[cellLID[i]];
00221 pnt = (points_[edgePoints_[LID][1]] - points_[edgePoints_[LID][0]]);
00222 cellDiameters[i] = sqrt(pnt * pnt);
00223 break;
00224 default:
00225 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "impossible switch value " "cellDim=" << cellDim << " in HNMesh2D::getCellDiameters()");
00226 }
00227 }
00228 }
00229 else
00230 {
00231 SUNDANCE_MSG3(verb(),"HNMesh2D::getCellDiameters(), cellDim == spatialDim() ");
00232 for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00233 {
00234 switch(cellDim)
00235 {
00236 case 2:
00237 LID = cellLeafToLIDMapping_[cellLID[i]];
00238 pnt = points_[cellsPoints_[LID][3]] - points_[cellsPoints_[LID][0]];
00239 cellDiameters[i] = sqrt(pnt * pnt);
00240 break;
00241 default:
00242 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "impossible switch value "
00243 "cellDim=" << cellDim << " in HNMesh2D::getCellDiameters()");
00244 }
00245 }
00246 }
00247 }
00248
00249 void HNMesh2D::pushForward(int cellDim, const Array<int>& cellLID,
00250 const Array<Point>& refQuadPts,
00251 Array<Point>& physQuadPts) const {
00252
00253 SUNDANCE_MSG3(verb(),"HNMesh2D::pushForward cellDim:"<<cellDim);
00254 TEUCHOS_TEST_FOR_EXCEPTION(cellDim < 0 || cellDim > spatialDim(), std::logic_error,
00255 "cellDim=" << cellDim << " is not in expected range [0, " << spatialDim() << "]");
00256
00257 int nQuad = refQuadPts.size();
00258 Point pnt( 0.0 , 0.0 );
00259 Point pnt1( 0.0 , 0.0 );
00260
00261 if (physQuadPts.size() > 0) physQuadPts.resize(0);
00262 physQuadPts.reserve(cellLID.size() * refQuadPts.size());
00263 for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00264 {
00265 switch(cellDim)
00266 {
00267 case 0:
00268 physQuadPts.append(pnt);
00269 break;
00270 case 1:{
00271 int LID = edgeLeafToLIDMapping_[cellLID[i]];
00272 pnt = points_[edgePoints_[LID][0]];
00273 pnt1 = points_[edgePoints_[LID][1]] - points_[edgePoints_[LID][0]];
00274 for (int q=0; q<nQuad; q++) {
00275 physQuadPts.append(pnt + (pnt1)*refQuadPts[q][0]);
00276 }
00277 break;}
00278 case 2:{
00279 int LID = cellLeafToLIDMapping_[cellLID[i]];
00280 pnt = points_[cellsPoints_[LID][0]];
00281
00282 pnt1 = points_[cellsPoints_[LID][3]] - points_[cellsPoints_[LID][0]];
00283 for (int q=0; q<nQuad; q++) {
00284 physQuadPts.append( pnt + Point( refQuadPts[q][0] * pnt1[0] , refQuadPts[q][1] * pnt1[1] ) );
00285 }
00286 break;}
00287 default:
00288 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "impossible switch value " "in HNMesh2D::getJacobians()");
00289 }
00290 }
00291 }
00292
00293 int HNMesh2D::ownerProcID(int cellDim, int cellLID) const {
00294 int ID = -1;
00295 if (cellDim == 0) ID = vertexLeafToLIDMapping_[cellLID];
00296 if (cellDim == 1) ID = edgeLeafToLIDMapping_[cellLID];
00297 if (cellDim == 2) ID = cellLeafToLIDMapping_[cellLID];
00298 SUNDANCE_MSG3(verb() , " HNMesh2D::ownerProcID ,cellDim:" << cellDim << ", cellLID:"
00299 << cellLID <<" ,ID:" << ID << ", ret:"<< elementOwner_[cellDim][ID] );
00300 return elementOwner_[cellDim][ID];
00301 }
00302
00303
00304 int HNMesh2D::numFacets(int cellDim, int cellLID,
00305 int facetDim) const {
00306
00307 if (cellDim==1) {
00308 return 2;
00309 }
00310 else if (cellDim==2) {
00311 return 4;
00312 }
00313 return -1;
00314 }
00315
00316 int HNMesh2D::facetLID(int cellDim, int cellLID,
00317 int facetDim, int facetIndex,
00318 int& facetOrientation) const {
00319
00320 facetOrientation = 1;
00321 SUNDANCE_MSG3(verb(),"HNMesh2D::facetLID cellDim:"<<cellDim<<", cellLID:"<<cellLID<<", facetDim:"<<facetDim<< ", facetIndex:" << facetIndex);
00322 int rnt = -1 , LID=-1 , tmp=-1;
00323 if (facetDim == 0){
00324 if (cellDim == 2 ){
00325 LID = cellLeafToLIDMapping_[cellLID];
00326 rnt = cellsPoints_[LID][facetIndex]; tmp = rnt;
00327 rnt = vertexLIDToLeafMapping_[rnt];
00328 }
00329 else if ((cellDim==1)){
00330 LID = edgeLeafToLIDMapping_[cellLID];
00331 rnt = edgePoints_[LID][facetIndex]; tmp = rnt;
00332 rnt = vertexLIDToLeafMapping_[rnt];
00333 }
00334 } else if (facetDim == 1){
00335 LID = cellLeafToLIDMapping_[cellLID];
00336 rnt = cellsEdges_[LID][facetIndex]; tmp = rnt;
00337 rnt = edgeLIDToLeafMapping_[rnt];
00338 }
00339 SUNDANCE_MSG3(verb()," RET = " << rnt << ", LID:" << LID << ", tmp:" << tmp);
00340 return rnt;
00341 }
00342
00343
00344 void HNMesh2D::getFacetLIDs(int cellDim,
00345 const Array<int>& cellLID,
00346 int facetDim,
00347 Array<int>& facetLID,
00348 Array<int>& facetSign) const {
00349
00350 SUNDANCE_MSG3(verb(),"HNMesh2D::getFacetLIDs() cellDim:"<<cellDim<<" cellLID.size():"<<cellLID.size()<<" facetDim:" <<facetDim);
00351 int LID = 0 , cLID , facetOrientation ;
00352 int ptr = 0;
00353
00354 int nf = numFacets(cellDim, cellLID[0], facetDim);
00355 facetLID.resize(cellLID.size() * nf);
00356 facetSign.resize(cellLID.size() * nf);
00357
00358 for (unsigned int i = 0 ; i < (unsigned int)cellLID.size() ; i++){
00359 cLID = cellLID[i];
00360 for (int f=0; f<nf; f++, ptr++) {
00361
00362 LID = this->facetLID( cellDim, cLID, facetDim, f , facetOrientation);
00363 facetLID[ptr] = LID;
00364 facetSign[ptr] = facetOrientation;
00365 }
00366 }
00367 SUNDANCE_MSG3(verb() ,"HNMesh2D::getFacetLIDs() DONE. ");
00368 }
00369
00370
00371 const int* HNMesh2D::elemZeroFacetView(int cellLID) const {
00372 int LID = cellLeafToLIDMapping_[cellLID];
00373 SUNDANCE_MSG3(verb() , "HNMesh2D::elemZeroFacetView ");
00374 return (const int*)(&cellsPoints_[LID]);
00375 }
00376
00377
00378 int HNMesh2D::numMaxCofacets(int cellDim, int cellLID) const {
00379
00380 SUNDANCE_MSG3(verb() , "HNMesh2D::numMaxCofacets(): cellDim:"<<cellDim<<" cellLID:"<<cellLID );
00381 int rnt = -1;
00382 if (cellDim==0) {
00383 int LID = vertexLeafToLIDMapping_[cellLID];
00384 int sum = 0;
00385 for (int i = 0 ; i < 4 ; i++)
00386 if ( (pointMaxCoF_[LID][i] >= 0) && ( cellLIDToLeafMapping_[pointMaxCoF_[LID][i]] >= 0) )
00387 sum++;
00388
00389 rnt = sum;
00390 }
00391 else if (cellDim==1) {
00392 int LID = edgeLeafToLIDMapping_[cellLID];
00393 if ((edgeMaxCoF_[LID][0] >= 0) && ( cellLIDToLeafMapping_[edgeMaxCoF_[LID][0]] >= 0) &&
00394 (edgeMaxCoF_[LID][1] >= 0) && ( cellLIDToLeafMapping_[edgeMaxCoF_[LID][1]] >= 0))
00395 rnt = 2;
00396 else
00397 rnt = 1;
00398 }
00399 SUNDANCE_MSG3(verb() ," RET = " << rnt );
00400 return rnt;
00401 }
00402
00403
00404 int HNMesh2D::maxCofacetLID(int cellDim, int cellLID,
00405 int cofacetIndex,
00406 int& facetIndex) const {
00407
00408 SUNDANCE_MSG3(verb() ,"HNMesh2D::maxCofacetLID() cellDim:"<<cellDim<<" cellLID:"<<cellLID<<" cofacetIndex:"<<cofacetIndex<< " facetIndex:"
00409 << facetIndex);
00410 int rnt =-1;
00411 if (cellDim==0) {
00412
00413 int actCoFacetIndex = 0;
00414 int LID = vertexLeafToLIDMapping_[cellLID];
00415 for (int ii = 0 ; ii < 4 ; ii++){
00416
00417 if ( (pointMaxCoF_[LID][ii] >= 0) && (cellLIDToLeafMapping_[pointMaxCoF_[LID][ii]] >= 0) ){
00418 if ( actCoFacetIndex < cofacetIndex ){
00419 actCoFacetIndex++;
00420 }else{
00421 facetIndex = ii;
00422 rnt = pointMaxCoF_[LID][ii];
00423 break;
00424 }
00425 }
00426 }
00427 }
00428 else if (cellDim==1) {
00429 int orientation = 0;
00430 int addFakt = 0;
00431 int maxCoFacet = 0;
00432 int LID = edgeLeafToLIDMapping_[cellLID];
00433
00434 if ( edgeVertex_[LID] == 0 ){
00435 orientation = 0; addFakt = 2;
00436 }else{
00437 orientation = 1; addFakt = 1;
00438 }
00439 SUNDANCE_MSG3(verb() ," HNMesh2D::maxCofacetLID() , orientation:" <<orientation<< " addFakt:" << addFakt );
00440
00441 int actCoFacetIndex = 0;
00442 for (int ii = 0 ; ii < 2 ; ii++){
00443
00444 if ( (edgeMaxCoF_[LID][ii] >= 0) && (cellLIDToLeafMapping_[edgeMaxCoF_[LID][ii]] >= 0) ){
00445 if ( actCoFacetIndex < cofacetIndex ){
00446 actCoFacetIndex++;
00447 }else{
00448 facetIndex = 1-ii;
00449 maxCoFacet = edgeMaxCoF_[LID][ii];
00450 break;
00451 }
00452 }
00453 }
00454 SUNDANCE_MSG3(verb() ,"HNMesh2D::maxCofacetLID() , facetIndex:" << facetIndex <<", _edgeMaxCoFacet[0]:" << edgeMaxCoF_[LID][0] <<
00455 "_edgeMaxCoFacet[1]:" << edgeMaxCoF_[LID][1] );
00456
00457 if ( orientation == 0 ){
00458 facetIndex = facetIndex + facetIndex*addFakt;
00459 } else {
00460 facetIndex = facetIndex + addFakt;
00461 }
00462 SUNDANCE_MSG3(verb() ," maxCoFacet = " << maxCoFacet );
00463 rnt = ( maxCoFacet );
00464 }
00465
00466 rnt = cellLIDToLeafMapping_[ rnt ];
00467 SUNDANCE_MSG3(verb() ," RET = " << rnt << ", facetIndex:" << facetIndex);
00468 return rnt;
00469 }
00470
00471 void HNMesh2D::getCofacets(int cellDim, int cellLID,
00472 int cofacetDim, Array<int>& cofacetLIDs) const {
00473
00474 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error," HNMesh2D::getCofacets() not implemented");
00475 }
00476
00477
00478 void HNMesh2D::getMaxCofacetLIDs(const Array<int>& cellLIDs,
00479 MaximalCofacetBatch& cofacets) const {
00480
00481 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error," HNMesh2D::getMaxCofacetLIDs() not implemented");
00482 }
00483
00484
00485 int HNMesh2D::mapGIDToLID(int cellDim, int globalIndex) const {
00486
00487 switch (cellDim){
00488 case 0:{
00489 int ID = vertexLeafToGIDMapping_[globalIndex];
00490 SUNDANCE_MSG3(verb() , " HNMesh2D::mapGIDToLID 0 , globalIndex:" << globalIndex << " ,ID:" << ID << ", ret:"<< vertexLIDToLeafMapping_[ID]);
00491 return vertexLIDToLeafMapping_[ID];
00492 break;}
00493 case 1:{
00494 int ID = edgeLeafToGIDMapping_[globalIndex];
00495 SUNDANCE_MSG3(verb() , " HNMesh2D::mapGIDToLID 1 , globalIndex:" << globalIndex << " ,ID:" << ID << ", ret:"<< edgeLIDToLeafMapping_[ID]);
00496 return edgeLIDToLeafMapping_[ID];
00497 break;}
00498 case 2:{
00499 int ID = cellLeafToGIDMapping_[globalIndex];
00500 SUNDANCE_MSG3(verb() , " HNMesh2D::mapGIDToLID 2 , globalIndex:" << globalIndex << " ,ID:" << ID << ", ret:"<< cellLIDToLeafMapping_[ID]);
00501 return cellLIDToLeafMapping_[ID];
00502 break;}
00503 }
00504 return -1;
00505 }
00506
00507
00508 bool HNMesh2D::hasGID(int cellDim, int globalIndex) const {
00509
00510
00511 return true;
00512 }
00513
00514
00515 int HNMesh2D::mapLIDToGID(int cellDim, int localIndex) const {
00516
00517 switch (cellDim){
00518 case 0:{
00519 int ID = vertexLeafToLIDMapping_[localIndex];
00520 SUNDANCE_MSG3(verb() , " HNMesh2D::mapLIDToGID 0 , localIndex:" << localIndex << " ,ID:" << ID << ", ret:"<< vertexGIDToLeafMapping_[ID]);
00521 return vertexGIDToLeafMapping_[ID];
00522 break;}
00523 case 1:{
00524 int ID = edgeLeafToLIDMapping_[localIndex];
00525 SUNDANCE_MSG3(verb() , " HNMesh2D::mapLIDToGID 1 , localIndex:" << localIndex << " ,ID:" << ID << ", ret:"<< edgeGIDToLeafMapping_[ID]);
00526 return edgeGIDToLeafMapping_[ID];
00527 break;}
00528 case 2:{
00529 int ID = cellLeafToLIDMapping_[localIndex];
00530 SUNDANCE_MSG3(verb() , " HNMesh2D::mapLIDToGID 2 , localIndex:" << localIndex << " ,ID:" << ID << ", ret:"<< cellGIDToLeafMapping_[ID]);
00531 return cellGIDToLeafMapping_[ID];
00532 break;}
00533 }
00534 return -1;
00535 }
00536
00537
00538 CellType HNMesh2D::cellType(int cellDim) const {
00539 switch(cellDim)
00540 {
00541 case 0: return PointCell;
00542 case 1: return LineCell;
00543 case 2: return QuadCell;
00544 default:
00545 return NullCell;
00546 }
00547 }
00548
00549
00550 int HNMesh2D::label(int cellDim, int cellLID) const {
00551
00552 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error," HNMesh2D::label() not implemented yet");
00553 return 0;
00554 }
00555
00556
00557 void HNMesh2D::getLabels(int cellDim, const Array<int>& cellLID,
00558 Array<int>& labels) const {
00559
00560 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error," HNMesh2D::getLabels() not implemented yet");
00561 }
00562
00563 Set<int> HNMesh2D::getAllLabelsForDimension(int cellDim) const {
00564 Set<int> rtn;
00565
00566 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error," HNMesh2D::getAllLabelsForDimension() not implemented yet");
00567 return rtn;
00568 }
00569
00570 void HNMesh2D::getLIDsForLabel(int cellDim, int label, Array<int>& cellLIDs) const {
00571
00572 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error," HNMesh2D::getLIDsForLabel() not implemented yet");
00573 }
00574
00575 void HNMesh2D::setLabel(int cellDim, int cellLID, int label) {
00576
00577 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error," HNMesh2D::setLabel() not implemented yet");
00578 }
00579
00580
00581 void HNMesh2D::assignIntermediateCellGIDs(int cellDim) {
00582
00583
00584 }
00585
00586
00587 bool HNMesh2D::hasIntermediateGIDs(int dim) const {
00588
00589
00590 return true;
00591 }
00592
00593
00594
00595 bool HNMesh2D::isElementHangingNode(int cellDim , int cellLID) const {
00596 SUNDANCE_MSG3(verb() ,"HNMesh2D::isElementHangingNode cellDim:"<<cellDim<<" LID:"<< cellLID);
00597 if (cellDim==0) {
00598 int LID = vertexLeafToLIDMapping_[cellLID];
00599 return (isPointHanging_[LID]);
00600 }
00601 else if (cellDim==1) {
00602 int LID = edgeLeafToLIDMapping_[cellLID];
00603 return (isEdgeHanging_[LID]);
00604 } else {
00605 return false;
00606 }
00607 return false;
00608 }
00609
00610 int HNMesh2D::indexInParent(int maxCellLID) const {
00611
00612 int mapMyChilderIndexToStandardDoFMAP[9] = {0,5,6,1,4,7,2,3,8};
00613 int LID = cellLeafToLIDMapping_[maxCellLID];
00614 int indexInPar = indexInParent_[LID];
00615
00616 return mapMyChilderIndexToStandardDoFMAP[indexInPar];
00617 }
00618
00619 void HNMesh2D::returnParentFacets( int childCellLID , int dimFacets ,
00620 Array<int> &facetsLIDs , int &parentCellLIDs ) const {
00621 int LID = cellLeafToLIDMapping_[childCellLID];
00622 parentCellLIDs = parentCellLID_[LID];
00623 facetsLIDs.resize(4);
00624 SUNDANCE_MSG3(verb() , "HNMesh2D::returnParentFacets childCellLID:"<<childCellLID<<" dimFacets:"<<dimFacets<<
00625 " parentCellLIDs:"<< parentCellLIDs);
00626
00627 facetsLIDs[0] = facetLID_tree( 2 , parentCellLIDs , dimFacets , 0 );
00628 facetsLIDs[1] = facetLID_tree( 2 , parentCellLIDs , dimFacets , 1 );
00629 facetsLIDs[2] = facetLID_tree( 2 , parentCellLIDs , dimFacets , 2 );
00630 facetsLIDs[3] = facetLID_tree( 2 , parentCellLIDs , dimFacets , 3 );
00631
00632 parentCellLIDs = cellLIDToLeafMapping_[parentCellLIDs];
00633 }
00634
00635
00636 int HNMesh2D::facetLID_tree(int cellDim, int cellLID,
00637 int facetDim, int facetIndex) const{
00638 int rnt = -1;
00639 if (facetDim == 0){
00640 rnt = cellsPoints_[cellLID][facetIndex];
00641 rnt = vertexLIDToLeafMapping_[rnt];
00642
00643 } else if (facetDim == 1){
00644 rnt = cellsEdges_[cellLID][facetIndex];
00645 rnt = edgeLIDToLeafMapping_[rnt];
00646
00647 }
00648 SUNDANCE_MSG3(verb() , "HNMesh2D::facetLID_tree cellDim:"<<cellDim<<", cellLID:"<<cellLID<<", facetDim:"<<facetDim<<
00649 ", facetIndex:"<<facetIndex<<" RET = " << rnt );
00650 return rnt;
00651 }
00652
00653
00654
00655
00656 void HNMesh2D::addVertex(int vertexLID , int ownerProc , bool isHanging ,
00657 double coordx , double coordy , const Array<int> &maxCoF){
00658
00659
00660 if (points_.size() <= vertexLID){
00661 TEUCHOS_TEST_FOR_EXCEPTION(vertexLID != nrElem_[0] , std::logic_error ,"HNMesh2D::addVertex " <<
00662 " vertexLID:" << vertexLID << " nrElem_[0]:" << nrElem_[0] );
00663 Point pt(coordx,coordy);
00664 points_.append( pt );
00665 pointMaxCoF_.append( maxCoF );
00666 isPointHanging_.append( isHanging );
00667 elementOwner_[0].append( ownerProc );
00668 SUNDANCE_MSG3(verb() , "HNMesh2D::addVertex: " << nrElem_[0] << " P:" << pt << " , maxCoF:" << maxCoF);
00669 SUNDANCE_MSG3(verb() , " ownerProc:" << ownerProc << " , isHanging:" << isHanging);
00670 nrElem_[0]++;
00671 }
00672 }
00673
00674
00675 void HNMesh2D::addEdge(int edgeLID , int ownerProc , bool isHanging , int edgeVertex ,
00676 bool isProcBoundary , bool isMeshBoundary ,
00677 const Array<int> &vertexLIDs , const Array<int> &maxCoF){
00678
00679 if (edgePoints_.size() <= edgeLID ){
00680 TEUCHOS_TEST_FOR_EXCEPTION(edgeLID != nrElem_[1], std::logic_error, "HNMesh2D::addEdge edgeLID != nrElem_[1]");
00681 edgePoints_.append( vertexLIDs );
00682 edgeVertex_.append( edgeVertex );
00683 edgeMaxCoF_.append( maxCoF );
00684 edgeIsProcBonudary_.append( isProcBoundary );
00685 edgeIsMeshDomainBonudary_.append( isMeshBoundary );
00686 isEdgeHanging_.append(isHanging);
00687 elementOwner_[1].append( ownerProc );
00688 SUNDANCE_MSG3(verb() , "HNMesh2D::addEdge: " << nrElem_[1] << " vertexLIDs:" << vertexLIDs << " , maxCoF:" << maxCoF );
00689 SUNDANCE_MSG3(verb() , " ownerProc:" << ownerProc << ", isHanging:" << isHanging << ", edgeVertex:" << edgeVertex <<
00690 ", isProcBoundary:" << isProcBoundary << ", isMeshBoundary:" << isMeshBoundary);
00691 nrElem_[1]++;
00692 }
00693 }
00694
00695
00696 void HNMesh2D::addCell(int cellLID , int ownerProc ,
00697 int indexInParent , int parentCellLID , int level ,
00698 const Array<int> &edgeLIDs , const Array<int> &vertexLIDs){
00699
00700 if (cellsPoints_.size() <= cellLID ) {
00701 TEUCHOS_TEST_FOR_EXCEPTION(cellLID != nrElem_[2], std::logic_error, "HNMesh2D::cellLID cellLID != nrElem_[2]");
00702 cellsPoints_.append( vertexLIDs );
00703 cellsEdges_.append( edgeLIDs );
00704 indexInParent_.append( indexInParent );
00705 parentCellLID_.append( parentCellLID );
00706 cellLevel_.append( level );
00707 isCellLeaf_.append( true );
00708 refineCell_.append( 0 );
00709 cellsChildren_.append( Teuchos::tuple(1) );
00710 elementOwner_[2].append( ownerProc );
00711 SUNDANCE_MSG3(verb() , "HNMesh2D::addCell: " << nrElem_[2] << " vertexLIDs:" << vertexLIDs << " edgeLIDs:" << edgeLIDs);
00712 SUNDANCE_MSG3(verb() , "HNMesh2D::addCell p0:" << points_[vertexLIDs[0]] );
00713 SUNDANCE_MSG3(verb() , "HNMesh2D::addCell p1:" << points_[vertexLIDs[1]] );
00714 SUNDANCE_MSG3(verb() , "HNMesh2D::addCell p2:" << points_[vertexLIDs[2]] );
00715 SUNDANCE_MSG3(verb() , "HNMesh2D::addCell p3:" << points_[vertexLIDs[3]] );
00716
00717 isCellOut_.append( !( meshDomain_.isInsideComputationalDomain(points_[vertexLIDs[0]]) ||
00718 meshDomain_.isInsideComputationalDomain(points_[vertexLIDs[1]]) ||
00719 meshDomain_.isInsideComputationalDomain(points_[vertexLIDs[2]]) ||
00720 meshDomain_.isInsideComputationalDomain(points_[vertexLIDs[3]]) ) );
00721 SUNDANCE_MSG3(verb() , "HNMesh2D::addCell IN DOMAIN:" << isCellOut_[nrElem_[2]] );
00722 nrElem_[2]++;
00723 }
00724 }
00725
00726
00727
00728
00729
00730 void HNMesh2D::createMesh(
00731 double position_x,
00732 double position_y,
00733 double offset_x,
00734 double offset_y,
00735 int resolution_x,
00736 int resolution_y,
00737 const RefinementClass& refineClass ,
00738 const MeshDomainDef& meshDomain
00739 ){
00740
00741 setVerb(0);
00742
00743
00744 _pos_x = position_x; _pos_y = position_y;
00745 _ofs_x = offset_x; _ofs_y = offset_y;
00746 _res_x = resolution_x; _res_y = resolution_y;
00747 refineClass_ = refineClass;
00748 meshDomain_ = meshDomain;
00749
00750
00751 createCoarseMesh();
00752
00753
00754 bool doRefinement = true;
00755 while (doRefinement){
00756 doRefinement = oneRefinementIteration();
00757 }
00758
00759
00760
00761 createLeafNumbering_sophisticated();
00762
00763 }
00764
00765 void HNMesh2D::createCoarseMesh(){
00766
00767
00768
00769
00770 int nrCoarseCell = _res_x*_res_y;
00771 int nrCoarsePoints = (_res_x+1)*(_res_y+1);
00772 int nrCoarseEdge = (_res_x+1)*_res_y + _res_x*(_res_y+1);
00773 Array<int> coarseProcessCell( nrCoarseCell , -1 );
00774 Array<int> coarseCellOwner( nrCoarseCell , -1 );
00775 Array<int> coarsePointOwner( nrCoarsePoints , -1 );
00776 Array<int> coarseEdgeOwner( nrCoarseEdge , -1 );
00777 Array<int> coarseCellLID( nrCoarseCell , -1 );
00778 Array<int> coarsePointLID( nrCoarsePoints , -1 );
00779 Array<int> coarseEdgeLID( nrCoarseEdge , -1 );
00780 Array<int> coarseCellsLoad( nrCoarseCell , 0 );
00781 int totalLoad = 0;
00782
00783 SUNDANCE_MSG3(verb() , "HNMesh2D::createMesh nrCoarseCell:" << nrCoarseCell << " nrCoarsePoints:" << nrCoarsePoints
00784 << " nrCoarseEdge:" << nrCoarseEdge << " nrProc_:" << nrProc_ << " myRank_:" << myRank_);
00785 TEUCHOS_TEST_FOR_EXCEPTION( nrCoarseCell < nrProc_ , std::logic_error," HNMesh2D::createMesh nrCoarseCell < nrProc_ ");
00786
00787
00788
00789 double h[2];
00790 h[0] = _ofs_x/(double)_res_x; h[1] = _ofs_y/(double)_res_y;
00791 Point pos(h[0],h[1]);
00792 Point res(h[0],h[1]);
00793
00794 for (int i=0; i < nrCoarseCell; i++){
00795
00796 pos[0] = _pos_x + (double)(i / _res_y)*h[0] + 0.5*h[0];
00797 pos[1] = _pos_y + (double)(i % _res_y)*h[1] + 0.5*h[1];
00798
00799 coarseCellsLoad[i] = refineClass_.estimateRefinementLevel( pos , res );
00800 totalLoad += coarseCellsLoad[i];
00801 }
00802
00803 double loadPerProc = (double)totalLoad / (double)nrProc_;
00804 int actualProc=0;
00805 totalLoad = 0;
00806 Array<int> ind(2);
00807
00808 int vertexOffs[4] = {0 , _res_y + 1 , 1 , _res_y + 2};
00809 int edgeOffs[4] = {_res_y , 0 , 2*_res_y + 1 , _res_y + 1};
00810
00811
00812 SUNDANCE_MSG3(verb() , "Processor asign, loadPerProc:" << loadPerProc );
00813 double diff_load = 0.0;
00814 for (int i=0; i < nrCoarseCell; i++){
00815 ind[0] = (i / _res_y);
00816 ind[1] = (i % _res_y);
00817 int vertexInd = (_res_y+1)*ind[0] + ind[1];
00818 int edgeInd = (2*_res_y+1)*ind[0] + ind[1];
00819
00820
00821
00822 for (int jj = 0 ; jj < 4 ; jj++){
00823 if (coarsePointOwner[vertexInd+vertexOffs[jj]] < 0){
00824 coarsePointOwner[vertexInd+vertexOffs[jj]] = actualProc;
00825 SUNDANCE_MSG3(verb() , "Vertex CPU assign " << vertexInd+vertexOffs[jj] << " ->" << actualProc );
00826 }
00827 }
00828
00829 for (int jj = 0 ; jj < 4 ; jj++){
00830 if (coarseEdgeOwner[edgeInd+edgeOffs[jj]] < 0){
00831 coarseEdgeOwner[edgeInd+edgeOffs[jj]] = actualProc;
00832
00833 }
00834 }
00835
00836 coarseCellOwner[i] = actualProc;
00837 totalLoad += coarseCellsLoad[i];
00838 SUNDANCE_MSG3(verb() , "Cell CPU assign " << i << " ->" << actualProc <<
00839 ", totalLoad:" << totalLoad << " loadPerProc:" << loadPerProc);
00840
00841 if (((double)totalLoad >= (loadPerProc - 1e-8 - diff_load)) && ( actualProc < nrProc_-1 )){
00842 SUNDANCE_MSG3(verb() , "Increase CPU , totalLoad:" << totalLoad << " loadPerProc:" << loadPerProc );
00843
00844 diff_load = totalLoad - loadPerProc;
00845 actualProc = actualProc + 1;
00846 totalLoad = 0;
00847 }
00848 }
00849
00850
00851 for (int i=0; i < nrCoarseCell; i++){
00852 ind[0] = (i / _res_y);
00853 ind[1] = (i % _res_y);
00854 coarseProcessCell[i] = 1;
00855 }
00856
00857
00858 SUNDANCE_MSG3(verb() , " Process Cells:" << nrCoarseCell );
00859 for (int i=0; i < nrCoarseCell; i++){
00860 ind[0] = (i / _res_y);
00861 ind[1] = (i % _res_y);
00862 pos[0] = _pos_x + (double)(ind[0])*h[0];
00863 pos[1] = _pos_y + (double)(ind[1])*h[1];
00864 SUNDANCE_MSG3(verb() , "PCell ID:" << i << " coarseProcessCell[i]:" <<coarseProcessCell[i] << " pos:" << pos );
00865 SUNDANCE_MSG3(verb() , "PCell, actual index" << ind );
00866
00867 if (coarseProcessCell[i] > 0) {
00868 int vertexInd = (_res_y+1)*ind[0] + ind[1];
00869 int edgeInd = (2*_res_y+1)*ind[0] + ind[1];
00870 int cellLID = coarseCellLID[i];
00871 Array<int> vertexLID(4,-1) , vertexMaxCoF(4,-1) , vLID(4,-1);;
00872 Array<int> edgeLID(4,-1) , edgeVert(2,-1) , edgeMaxCoef(2,-1);
00873
00874
00875
00876 if (coarseCellLID[i] < 0 ){
00877 coarseCellLID[i] = nrElem_[2];
00878 cellLID = coarseCellLID[i];
00879 }
00880
00881 for (int jj = 0 ; jj < 4 ; jj++){
00882 vLID[jj] = coarsePointLID[vertexInd+vertexOffs[jj]];
00883
00884
00885
00886 if (coarsePointLID[vertexInd+vertexOffs[jj]] < 0){
00887 coarsePointLID[vertexInd+vertexOffs[jj]] = nrElem_[0];
00888 }
00889 vLID[jj] = coarsePointLID[vertexInd+vertexOffs[jj]];
00890
00891
00892
00893 addVertex( vLID[jj] , coarsePointOwner[vertexInd+vertexOffs[jj]] , false ,
00894 pos[0] + ((double)offs_Points_x_[jj])*h[0] , pos[1] + ((double)offs_Points_y_[jj])*h[1] ,
00895 vertexMaxCoF );
00896 }
00897
00898 for (int jj = 0 ; jj < 4 ; jj++){
00899 edgeLID[jj] = coarseEdgeLID[edgeInd+edgeOffs[jj]];
00900 if (coarseEdgeLID[edgeInd+edgeOffs[jj]] < 0){
00901 coarseEdgeLID[edgeInd+edgeOffs[jj]] = nrElem_[1];
00902 }
00903 edgeLID[jj] = coarseEdgeLID[edgeInd+edgeOffs[jj]];
00904 edgeVert[0] = vLID[edge_Points_localIndex[jj][0]];
00905 edgeVert[1] = vLID[edge_Points_localIndex[jj][1]];
00906
00907 addEdge( edgeLID[jj] , coarseEdgeOwner[edgeInd+edgeOffs[jj]] , false , (jj==0 || jj==3) ? 0 : 1 ,
00908 false , false ,
00909 edgeVert , edgeMaxCoef );
00910 }
00911
00912 addCell( cellLID , coarseCellOwner[i] , 0 , cellLID , 0 , edgeLID , vLID);
00913 }
00914 }
00915
00916
00917 SUNDANCE_MSG3(verb() , " Process maxCofacets:" << nrCoarseCell );
00918 for (int i=0; i < nrCoarseCell; i++){
00919
00920 if (coarseProcessCell[i] > 0){
00921 Array<int> vLID(4,-1) , eLID(4,-1) , maxVertexCoF(4,-1);
00922 ind[0] = (i / _res_y);
00923 ind[1] = (i % _res_y);
00924 int vertexInd = (_res_y+1)*ind[0] + ind[1];
00925 int edgeInd = (2*_res_y+1)*ind[0] + ind[1];
00926 int cellLID = coarseCellLID[i];
00927 SUNDANCE_MSG3(verb() , "MCell cellLID:" << cellLID << " coarseProcessCell[i]:" <<coarseProcessCell[i] );
00928
00929
00930
00931 for (int jj = 0 ; jj < 4 ; jj++){
00932 vLID[jj] = coarsePointLID[vertexInd+vertexOffs[jj]];
00933
00934 pointMaxCoF_[vLID[jj]][jj] = cellLID;
00935 SUNDANCE_MSG3(verb() , "Vertex MaxCoFacet vLID[jj]:" << vLID[jj] << " jj:" << jj << " cellLID:" << cellLID );
00936 }
00937
00938 for (int jj = 0 ; jj < 4 ; jj++){
00939 eLID[jj] = coarseEdgeLID[edgeInd+edgeOffs[jj]];
00940
00941 edgeMaxCoF_[eLID[jj]][(3-jj)/2] = cellLID;
00942 SUNDANCE_MSG3(verb() , "Edge MaxCoFacet eLID[jj]:" << eLID[jj] << " (3-jj)/2:" << (3-jj)/2 << " cellLID:" << cellLID );
00943
00944 int orientation = ( (jj==0) || (jj==3)) ? 1 : 0;
00945
00946 if (orientation == 0){
00947
00948 if ( (ind[0] == 0) && (jj==1)) edgeIsMeshDomainBonudary_[eLID[jj]] = true;
00949 if ( (ind[0] == _res_x - 1 ) && (jj==2)) edgeIsMeshDomainBonudary_[eLID[jj]] = true;
00950
00951 if ( edgeIsMeshDomainBonudary_[eLID[jj]] != true){
00952
00953 edgeIsProcBonudary_[eLID[jj]] = false;
00954 }
00955 }else{
00956
00957 if ( (ind[1] == 0) && (jj==0)) { edgeIsMeshDomainBonudary_[eLID[jj]] = true; }
00958 if ( (ind[1] == _res_y - 1 ) && (jj==3)) { edgeIsMeshDomainBonudary_[eLID[jj]] = true; }
00959
00960 if ( edgeIsMeshDomainBonudary_[eLID[jj]] != true){
00961
00962 edgeIsProcBonudary_[eLID[jj]] = false;
00963 }
00964 SUNDANCE_MSG3(verb() , "Neighb. H Cell DONE ");
00965 }
00966 }
00967 }
00968 }
00969
00970 }
00971
00972
00973 bool HNMesh2D::oneRefinementIteration(){
00974
00975 Array<int> ind(2);
00976 int nrActualCell = nrElem_[2];
00977 bool rtn = false;
00978 SUNDANCE_MSG3(verb() , " HNMesh2D::oneRefinementIteration, start one refinement iteration cycle ");
00979
00980 for (int i=0 ; i < nrActualCell ; i++){
00981
00982 ind[0] = (i / _res_y);
00983 ind[1] = (i % _res_y);
00984
00985
00986 SUNDANCE_MSG3(verb() , " Test cell " << i << ", elementOwner_[2][i]:" << elementOwner_[2][i] <<
00987 ", isCellLeaf_[i]:" << isCellLeaf_[i] << ", out:" << (!isCellOut_[i]));
00988
00989 if ( (isCellLeaf_[i] == true) )
00990
00991
00992
00993 {
00994
00995 Array<int>& cellsEdges = cellsEdges_[i];
00996 bool doRefined = true;
00997 bool refFunction = false;
00998 for (int jj = 0 ; jj < cellsEdges.size() ; jj++){
00999 SUNDANCE_MSG3(verb() , " eLID: " << cellsEdges[jj] << ", isHanging:" << isEdgeHanging_[cellsEdges[jj]]);
01000 doRefined = ( doRefined && ((isEdgeHanging_[cellsEdges[jj]]) == false) );
01001 }
01002
01003 SUNDANCE_MSG3(verb() , " is possible to refine cell nr: " << i << ", doRefined:" << doRefined);
01004
01005 Array<int>& cellsVertex = cellsPoints_[i];
01006 Point h = points_[cellsVertex[3]] - points_[cellsVertex[0]];
01007 Point p2 = points_[cellsVertex[0]] + 0.5*h;
01008 refFunction = ((refineCell_[i] == 1) || refineClass_.refine( cellLevel_[i] , p2 , h ));
01009
01010
01011 SUNDANCE_MSG3( verb() , " execute refinement on cell nr: " << i << ", refFunction:" << refFunction);
01012 if (doRefined && refFunction)
01013 {
01014
01015 refineCell(i);
01016 rtn = true;
01017 refineCell_[i] = 0;
01018 }
01019 else
01020 {
01021
01022
01023 if (refFunction){
01024
01025 for (int jj = 0 ; jj < cellsEdges.size() ; jj++){
01026 if (isEdgeHanging_[cellsEdges[jj]]){
01027
01028
01029 int cLevel = cellLevel_[i];
01030 int parentID = parentCellLID_[i];
01031 int parentCEdge = cellsEdges_[parentID][jj];
01032 int refCell = -1;
01033
01034 if ( (jj == 0) || ( jj == 1) )
01035 refCell = edgeMaxCoF_[parentCEdge][0];
01036 else
01037 refCell = edgeMaxCoF_[parentCEdge][1];
01038
01039
01040
01041
01042 if ( (refCell >= 0) && (cellLevel_[refCell] < cLevel) && (isCellLeaf_[refCell])){
01043
01044 refineCell_[refCell] = 1;
01045 rtn = true;
01046
01047
01048 }
01049 }
01050 }
01051 }
01052 }
01053 }
01054 }
01055
01056
01057
01058
01059 SUNDANCE_MSG3(verb() , " HNMesh2D::oneRefinementIteration DONE with one refinement iteration");
01060
01061 return rtn;
01062 }
01063
01064
01065 void HNMesh2D::refineCell(int cellLID){
01066
01067 Array<int>& cellsEdges = cellsEdges_[cellLID];
01068 Array<int>& cellsVertex = cellsPoints_[cellLID];
01069 int cellOwner = elementOwner_[2][cellLID];
01070 Point p = points_[cellsVertex[0]];
01071 Point h = points_[cellsVertex[3]] - points_[cellsVertex[0]];
01072
01073 double vertex_X[16] = { 0.0 , 0.0 , 0.0 , 0.0 , 1.0/3.0 , 1.0/3.0 , 1.0/3.0 , 1.0/3.0 ,
01074 2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 1.0 , 1.0 , 1.0 , 1.0 };
01075 double vertex_Y[16] = { 0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 , 0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 ,
01076 0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 , 0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 };
01077
01078 int hanginEdgeI[4][3] = { {3,10,17} , {0,1,2} , {21,22,23} , {6,13,20} };
01079
01080 int hanginVertexI[4][2] = { {4,8} , {1,2} , {13,14} , {7,11} };
01081
01082 int edgeVertex[24] = { 1,1,1 , 0,0,0,0 , 1,1,1 , 0,0,0,0 , 1,1,1 , 0,0,0,0 , 1,1,1};
01083
01084 int VertexIndex[4] = { 0 , 1 , 1 , 0 };
01085
01086 int VertexI[4] = { 0 , 0 , 1 , 2 };
01087
01088
01089 int vertexOwner[16] = { elementOwner_[0][cellsVertex[0]] , elementOwner_[1][cellsEdges[1]] ,
01090 elementOwner_[1][cellsEdges[1]] , elementOwner_[0][cellsVertex[2]] ,
01091 elementOwner_[1][cellsEdges[0]] , cellOwner , cellOwner , elementOwner_[1][cellsEdges[3]] ,
01092 elementOwner_[1][cellsEdges[0]] , cellOwner , cellOwner , elementOwner_[1][cellsEdges[3]] ,
01093 elementOwner_[0][cellsVertex[1]] , elementOwner_[1][cellsEdges[2]] ,
01094 elementOwner_[1][cellsEdges[2]] , elementOwner_[0][cellsVertex[3]] };
01095
01096 bool vertexIsHanging[16] = { false , !edgeIsMeshDomainBonudary_[cellsEdges[1]] , !edgeIsMeshDomainBonudary_[cellsEdges[1]], false ,
01097 !edgeIsMeshDomainBonudary_[cellsEdges[0]] , false , false , !edgeIsMeshDomainBonudary_[cellsEdges[3]] ,
01098 !edgeIsMeshDomainBonudary_[cellsEdges[0]] , false , false , !edgeIsMeshDomainBonudary_[cellsEdges[3]] ,
01099 false , !edgeIsMeshDomainBonudary_[cellsEdges[2]] , !edgeIsMeshDomainBonudary_[cellsEdges[2]], false };
01100
01101 int edgeOwner[24] = { elementOwner_[1][cellsEdges[1]] , elementOwner_[1][cellsEdges[1]] , elementOwner_[1][cellsEdges[1]] ,
01102 elementOwner_[1][cellsEdges[0]] , cellOwner , cellOwner , elementOwner_[1][cellsEdges[3]] ,
01103 cellOwner , cellOwner , cellOwner ,
01104 elementOwner_[1][cellsEdges[0]] , cellOwner , cellOwner , elementOwner_[1][cellsEdges[3]] ,
01105 cellOwner , cellOwner , cellOwner ,
01106 elementOwner_[1][cellsEdges[0]] , cellOwner , cellOwner , elementOwner_[1][cellsEdges[3]] ,
01107 elementOwner_[1][cellsEdges[2]] , elementOwner_[1][cellsEdges[2]] , elementOwner_[1][cellsEdges[2]] };
01108
01109 bool edgeIsHanging[24] = { !edgeIsMeshDomainBonudary_[cellsEdges[1]] , !edgeIsMeshDomainBonudary_[cellsEdges[1]] , !edgeIsMeshDomainBonudary_[cellsEdges[1]] ,
01110 !edgeIsMeshDomainBonudary_[cellsEdges[0]] , false , false , !edgeIsMeshDomainBonudary_[cellsEdges[3]] ,
01111 false , false , false ,
01112 !edgeIsMeshDomainBonudary_[cellsEdges[0]] , false , false , !edgeIsMeshDomainBonudary_[cellsEdges[3]] ,
01113 false , false , false ,
01114 !edgeIsMeshDomainBonudary_[cellsEdges[0]] , false , false , !edgeIsMeshDomainBonudary_[cellsEdges[3]] ,
01115 !edgeIsMeshDomainBonudary_[cellsEdges[2]] , !edgeIsMeshDomainBonudary_[cellsEdges[2]] , !edgeIsMeshDomainBonudary_[cellsEdges[2]] };
01116
01117 int edgeVertexes[24][2] = { {0,1} , {1,2} , {2,3} , {0,4} , {1,5} , {2,6} , {3,7} , {4,5} , {5,6} , {6,7} ,
01118 {4,8} , {5,9} , {6,10} , {7,11} , {8,9} , {9,10} , {10,11} ,
01119 {8,12} , {9,13} , {10,14} , {11,15} , {12,13} , {13,14} , {14,15}};
01120
01121 bool edgePBnd[24] = { edgeIsProcBonudary_[cellsEdges[1]] , edgeIsProcBonudary_[cellsEdges[1]] , edgeIsProcBonudary_[cellsEdges[1]] ,
01122 edgeIsProcBonudary_[cellsEdges[0]] , false , false , edgeIsProcBonudary_[cellsEdges[3]] ,
01123 false , false , false ,
01124 edgeIsProcBonudary_[cellsEdges[0]] , false , false , edgeIsProcBonudary_[cellsEdges[3]] ,
01125 false , false , false ,
01126 edgeIsProcBonudary_[cellsEdges[0]] , false , false , edgeIsProcBonudary_[cellsEdges[3]] ,
01127 edgeIsProcBonudary_[cellsEdges[2]] , edgeIsProcBonudary_[cellsEdges[2]] , edgeIsProcBonudary_[cellsEdges[2]] };
01128
01129 bool edgeMBnd[24] = { edgeIsMeshDomainBonudary_[cellsEdges[1]] , edgeIsMeshDomainBonudary_[cellsEdges[1]] , edgeIsMeshDomainBonudary_[cellsEdges[1]] ,
01130 edgeIsMeshDomainBonudary_[cellsEdges[0]] , false , false , edgeIsMeshDomainBonudary_[cellsEdges[3]] ,
01131 false , false , false ,
01132 edgeIsMeshDomainBonudary_[cellsEdges[0]] , false , false , edgeIsMeshDomainBonudary_[cellsEdges[3]] ,
01133 false , false , false ,
01134 edgeIsMeshDomainBonudary_[cellsEdges[0]] , false , false , edgeIsMeshDomainBonudary_[cellsEdges[3]] ,
01135 edgeIsMeshDomainBonudary_[cellsEdges[2]] , edgeIsMeshDomainBonudary_[cellsEdges[2]] , edgeIsMeshDomainBonudary_[cellsEdges[2]] };
01136
01137 int refinedCellsVertexes[9][4] = { {0,4,1,5} , {1,5,2,6} , {2,6,3,7} ,
01138 {4,8,5,9} , {5,9,6,10} , {6,10,7,11} ,
01139 {8,12,9,13} , {9,13,10,14} , {10,14,11,15} };
01140
01141 int refinedCellsEdges[9][4] = { {3,0,7,4} , {4,1,8,5} , {5,2,9,6} ,
01142 {10,7,14,11} , {11,8,15,12} , {12,9,16,13} ,
01143 {17,14,21,18} , {18,15,22,19} , {19,16,23,20} };
01144
01145 int hVertexIndex[16] = { -1 , 0 , 1 , -1 , 0 , -1 , -1 , 0 , 1 , -1 , -1 , 1 , -1 , 0 , 1 , -1 };
01146 int hEdgeIndex[24] = { 0 , 1 , 2 , 0 , -1 , -1 , 0 , -1 , -1 , -1 , 1 , -1 , -1 , 1 , -1 , -1 , -1 , 2 , -1 , -1 , 2 , 0 , 1 , 2 };
01147 int hVertexVertexIndex[16] = { -1 , 1 , 1 , -1 , 0 , -1 , -1 , 3 , 0 , -1 , -1 , 3 , -1 , 2 , 2 , -1 };
01148 int hEdgeVertexIndex[24] = { 1 , 1 , 1 , 0 , -1 , -1 , 3 , -1 , -1 , -1 , 0 , -1 , -1 , 3 , -1 , -1 , -1 , 0 , -1 , -1 , 3 , 2 , 2 , 2 };
01149
01150
01151 int vertexMaxCoFacet[16][4] = { {0,-1,-1,-1} , {1,-1,0,-1} , {2 ,-1,1,-1} , {-1,-1,2,-1} ,
01152 {3,0,-1,-1} , {4,1,3,0} , {5 ,2,4,1} , {-1,-1,5,2} ,
01153 {6,3,-1,-1} , {7,4,6,3} , {8 ,5,7,4} , {-1,-1,8,5} ,
01154 {-1,6,-1,-1} , {-1,7,-1,6} , {-1,8,-1,7} , {-1,-1,-1,8} };
01155
01156 int edgeMaxCoFacet[24][2] = { {-1,0} , {-1,1} , {-1,2} ,
01157 {-1,0} , {0,1} , {1,2} , {2,-1} ,
01158 {0,3} , {1,4} , {2,5} ,
01159 {-1,3} , {3,4} , {4,5} , {5,-1} ,
01160 {3,6} , {4,7} , {5,8} ,
01161 {-1,6} , {6,7} , {7,8} , {8,-1} ,
01162 {6,-1} , {7,-1} , {8,-1} };
01163
01164 int indexEdgeParentMaxCoFacet[24] = { 1 , 1, 1 , 0 , -1 , -1 , 3 , -1 , -1 , - 1, 0 , -1 , -1 , 3 , -1 , -1 , -1 , 0 ,-1,-1,3, 2,2,2 };
01165
01166 int offsEdgeParentMaxCoFacet[24] = { 0 , 0, 0 , 0 , -1 , -1 , 1 , -1 , -1 , - 1, 0 , -1 , -1 , 1 , -1 , -1 , -1 , 0 ,-1,-1,1, 1,1,1 };
01167
01168
01169 Array< Array<int> > hangingInfo(4);
01170 hangingInfo[0].resize(0); hangingInfo[1].resize(0); hangingInfo[2].resize(0); hangingInfo[3].resize(0);
01171
01172
01173 Array<int> vertexLIDs(16,-1);
01174 Array<int> edgeLIDs(24,-1);
01175 Array<int> cellLIDs(9,-1);
01176
01177 SUNDANCE_MSG3(verb() , " ========== HNMesh2D::refineCell, cellLID:" << cellLID << " ==========");
01178
01179
01180 vertexLIDs[0] = cellsVertex[0]; vertexLIDs[3] = cellsVertex[2];
01181 vertexLIDs[12] = cellsVertex[1]; vertexLIDs[15] = cellsVertex[3];
01182
01183
01184 for (int v = 0 ; v < 4 ; v++){
01185
01186
01187
01188 if (hangElmStore_[VertexIndex[v]].containsKey(cellsVertex[VertexI[v]])){
01189 const Array<int>& hnInfo = hangElmStore_[VertexIndex[v]].get(cellsVertex[VertexI[v]]);
01190
01191
01192
01193 vertexLIDs[hanginVertexI[v][0]] = hnInfo[0]; isPointHanging_[hnInfo[0]] = false;
01194 vertexLIDs[hanginVertexI[v][1]] = hnInfo[1]; isPointHanging_[hnInfo[1]] = false;
01195 edgeLIDs[hanginEdgeI[v][0]] = hnInfo[2];
01196 isEdgeHanging_[hnInfo[2]] = false;
01197 edgeLIDs[hanginEdgeI[v][1]] = hnInfo[3];
01198 isEdgeHanging_[hnInfo[3]] = false;
01199 edgeLIDs[hanginEdgeI[v][2]] = hnInfo[4]; isEdgeHanging_[hnInfo[4]] = false;
01200
01201 hangElmStore_[VertexIndex[v]].remove(cellsVertex[VertexI[v]]);
01202 }
01203 }
01204 SUNDANCE_MSG3(verb() , " refineCell bef. vertexLIDs:" << vertexLIDs );
01205 SUNDANCE_MSG3(verb() , " refineCell bef. edgeLIDs:" << edgeLIDs );
01206
01207
01208 for (int v = 0 ; v < 16 ; v++){
01209
01210 if (vertexLIDs[v] < 0){
01211
01212 Array<int> maxCoFacets(4,-1);
01213
01214 int vLID = nrElem_[0];
01215 addVertex( nrElem_[0] , vertexOwner[v] , vertexIsHanging[v] ,
01216 p[0] + vertex_X[v]*h[0] , p[1] + vertex_Y[v]*h[1] , maxCoFacets );
01217 vertexLIDs[v] = vLID;
01218
01219 if (vertexIsHanging[v]){
01220 Array<int>& hinf = hangingInfo[hVertexVertexIndex[v]];
01221 if (hinf.size() < 1) hinf.resize(5,-1);
01222 hinf[hVertexIndex[v]] = vLID;
01223
01224 if ( (v == 1) || ( v==2 )) { pointMaxCoF_[vertexLIDs[v]][1] = edgeMaxCoF_[cellsEdges[1]][0];
01225 pointMaxCoF_[vertexLIDs[v]][3] = edgeMaxCoF_[cellsEdges[1]][0]; }
01226 if ( (v == 4) || ( v==8 )) { pointMaxCoF_[vertexLIDs[v]][2] = edgeMaxCoF_[cellsEdges[0]][0];
01227 pointMaxCoF_[vertexLIDs[v]][3] = edgeMaxCoF_[cellsEdges[0]][0]; }
01228 if ( (v == 7) || ( v==11 )) { pointMaxCoF_[vertexLIDs[v]][0] = edgeMaxCoF_[cellsEdges[3]][1];
01229 pointMaxCoF_[vertexLIDs[v]][1] = edgeMaxCoF_[cellsEdges[3]][1]; }
01230 if ( (v == 13) || ( v==14 )) { pointMaxCoF_[vertexLIDs[v]][0] = edgeMaxCoF_[cellsEdges[2]][1];
01231 pointMaxCoF_[vertexLIDs[v]][2] = edgeMaxCoF_[cellsEdges[2]][1]; }
01232
01233
01234
01235
01236
01237
01238 }
01239 }
01240
01241 for (int hh = 0 ; hh < 4 ; hh++){
01242 SUNDANCE_MSG3(verb() , " vertexMaxCoFacet[v][hh]:" << vertexMaxCoFacet[v][hh] << " , vertexLIDs[v]:"<< vertexLIDs[v] );
01243 if (vertexMaxCoFacet[v][hh] >= 0)
01244 pointMaxCoF_[vertexLIDs[v]][hh] = nrElem_[2] + vertexMaxCoFacet[v][hh];
01245 }
01246 SUNDANCE_MSG3(verb() , " MaxCoFac point:" << vertexLIDs[v] << " , MaxCoFac:"<< pointMaxCoF_[vertexLIDs[v]] );
01247 }
01248 SUNDANCE_MSG3(verb() , " refineCell after Vertex creation vertexLIDs:" << vertexLIDs );
01249
01250
01251 for (int e = 0 ; e < 24 ; e++){
01252
01253 if (edgeLIDs[e] < 0){
01254 Array<int> maxCoFacets(2,-1);
01255 Array<int> edgeVertexLIDs(2,-1);
01256 edgeVertexLIDs[0] = vertexLIDs[edgeVertexes[e][0]];
01257 edgeVertexLIDs[1] = vertexLIDs[edgeVertexes[e][1]];
01258 int eLID = nrElem_[1];
01259 addEdge( nrElem_[1] , edgeOwner[e] , edgeIsHanging[e] , edgeVertex[e] ,
01260 edgePBnd[e] , edgeMBnd[e] , edgeVertexLIDs , maxCoFacets );
01261 edgeLIDs[e] = eLID;
01262
01263 if (edgeIsHanging[e]){
01264 Array<int>& hinf = hangingInfo[hEdgeVertexIndex[e]];
01265 if (hinf.size() < 1) hinf.resize(5,-1);
01266 SUNDANCE_MSG3(verb() , " HNI e:" << e << ", hEdgeIndex[e]:" << hEdgeIndex[e] );
01267 hinf[2+hEdgeIndex[e]] = eLID;
01268
01269 if ( edgeMBnd[e] == false){
01270
01271 edgeMaxCoF_[edgeLIDs[e]][offsEdgeParentMaxCoFacet[e]] =
01272 edgeMaxCoF_[cellsEdges[indexEdgeParentMaxCoFacet[e]]][offsEdgeParentMaxCoFacet[e]];
01273 }
01274 }
01275 }
01276
01277 for (int hh = 0 ; hh < 2 ; hh++){
01278
01279 if (edgeMaxCoFacet[e][hh] >= 0)
01280 edgeMaxCoF_[edgeLIDs[e]][hh] = nrElem_[2] + edgeMaxCoFacet[e][hh];
01281 }
01282
01283 }
01284 SUNDANCE_MSG3(verb() , " refineCell after Edges creation edgeLIDs:" << edgeLIDs );
01285
01286
01287 for (int c = 0 ; c < 9 ; c++){
01288 Array<int> eLIDs(4,-1);
01289 Array<int> vLIDs(4,-1);
01290 vLIDs[0] = vertexLIDs[refinedCellsVertexes[c][0]]; vLIDs[1] = vertexLIDs[refinedCellsVertexes[c][1]];
01291 vLIDs[2] = vertexLIDs[refinedCellsVertexes[c][2]]; vLIDs[3] = vertexLIDs[refinedCellsVertexes[c][3]];
01292 eLIDs[0] = edgeLIDs[refinedCellsEdges[c][0]]; eLIDs[1] = edgeLIDs[refinedCellsEdges[c][1]];
01293 eLIDs[2] = edgeLIDs[refinedCellsEdges[c][2]]; eLIDs[3] = edgeLIDs[refinedCellsEdges[c][3]];
01294
01295 cellLIDs[c] = nrElem_[2];
01296 addCell( nrElem_[2] , cellOwner , c , cellLID , cellLevel_[cellLID] + 1 , eLIDs , vLIDs );
01297 }
01298
01299 SUNDANCE_MSG3(verb() , " ---- Adding hanging node information ----- " );
01300
01301 if ( (hangElmStore_[0].containsKey(cellsPoints_[cellLID][0]) == false) && ( hangingInfo[0].size() > 0 ))
01302 {
01303 hangElmStore_[0].put(cellsPoints_[cellLID][0],hangingInfo[0]);
01304
01305 }
01306 if ( (hangElmStore_[1].containsKey(cellsPoints_[cellLID][0]) == false) && ( hangingInfo[1].size() > 0 ))
01307 {
01308 hangElmStore_[1].put(cellsPoints_[cellLID][0],hangingInfo[1]);
01309
01310 }
01311 if ( (hangElmStore_[1].containsKey(cellsPoints_[cellLID][1]) == false) && ( hangingInfo[2].size() > 0 ))
01312 {
01313 hangElmStore_[1].put(cellsPoints_[cellLID][1],hangingInfo[2]);
01314
01315 }
01316 if ( (hangElmStore_[0].containsKey(cellsPoints_[cellLID][2]) == false) && ( hangingInfo[3].size() > 0 ))
01317 {
01318 hangElmStore_[0].put(cellsPoints_[cellLID][2],hangingInfo[3]);
01319
01320 }
01321
01322 SUNDANCE_MSG3(verb() , " ---- Refinement cell DONE , mark cell as not leaf and store children LID ----");
01323 isCellLeaf_[cellLID] = false;
01324
01325 cellsChildren_[cellLID] = cellLIDs;
01326 }
01327
01328
01329 void HNMesh2D::createLeafNumbering(){
01330
01331
01332
01333
01334
01335
01336
01337 SUNDANCE_MSG3(verb() , "HNMesh2D::createLeafNumbering nrPoint:" << nrElem_[0] << " , nrEdge:" << nrElem_[1] << ", nrCell:" << nrElem_[2]);
01338
01339 vertexGIDToLeafMapping_.resize(nrElem_[0],-1);
01340 for (int dd = 0 ; dd < nrElem_[0] ; dd++) vertexGIDToLeafMapping_[dd] = -1;
01341 vertexLeafToGIDMapping_.resize(nrElem_[0],-1);
01342 for (int dd = 0 ; dd < nrElem_[0] ; dd++) vertexLeafToGIDMapping_[dd] = -1;
01343
01344 edgeGIDToLeafMapping_.resize(nrElem_[1],-1);
01345 for (int dd = 0 ; dd < nrElem_[1] ; dd++) edgeGIDToLeafMapping_[dd] = -1;
01346 edgeLeafToGIDMapping_.resize(nrElem_[1],-1);
01347 for (int dd = 0 ; dd < nrElem_[1] ; dd++) edgeLeafToGIDMapping_[dd] = -1;
01348
01349 cellGIDToLeafMapping_.resize(nrElem_[2],-1);
01350 for (int dd = 0 ; dd < nrElem_[2] ; dd++) cellGIDToLeafMapping_[dd] = -1;
01351 cellLeafToGIDMapping_.resize(nrElem_[2],-1);
01352 for (int dd = 0 ; dd < nrElem_[2] ; dd++) cellLeafToGIDMapping_[dd] = -1;
01353
01354 nrVertexLeafGID_ = 0; nrCellLeafGID_ = 0; nrEdgeLeafGID_ = 0;
01355
01356 nrVertexLeafLID_ = 0; nrCellLeafLID_ = 0; nrEdgeLeafLID_ = 0;
01357 vertexLIDToLeafMapping_.resize(nrElem_[0],-1);
01358 for (int dd = 0 ; dd < nrElem_[0] ; dd++) vertexLIDToLeafMapping_[dd] = -1;
01359 vertexLeafToLIDMapping_.resize(nrElem_[0],-1);
01360 for (int dd = 0 ; dd < nrElem_[0] ; dd++) vertexLeafToLIDMapping_[dd] = -1;
01361
01362 edgeLIDToLeafMapping_.resize(nrElem_[1],-1);
01363 for (int dd = 0 ; dd < nrElem_[1] ; dd++) edgeLIDToLeafMapping_[dd] = -1;
01364 edgeLeafToLIDMapping_.resize(nrElem_[1],-1);
01365 for (int dd = 0 ; dd < nrElem_[1] ; dd++) edgeLeafToLIDMapping_[dd] = -1;
01366
01367 cellLIDToLeafMapping_.resize(nrElem_[2],-1);
01368 for (int dd = 0 ; dd < nrElem_[2] ; dd++) cellLIDToLeafMapping_[dd] = -1;
01369 cellLeafToLIDMapping_.resize(nrElem_[2],-1);
01370 for (int dd = 0 ; dd < nrElem_[2] ; dd++) cellLeafToLIDMapping_[dd] = -1;
01371
01372 SUNDANCE_MSG3(verb() , "HNMesh2D::createLeafNumbering , start assigning leaf numbers");
01373
01374 for (int ind = 0 ; ind < nrElem_[0] ; ind++){
01375
01376 }
01377
01378
01379
01380 Array<bool> hasCellLID(nrElem_[2],false);
01381
01382 for (int ind = 0 ; ind < nrElem_[2] ; ind++){
01383 Array<int>& vertexIDs = cellsPoints_[ind];
01384 hasCellLID[ind] = false;
01385 for (int v = 0 ; v < 4 ; v++){
01386 Array<int>& maxCoFacet = pointMaxCoF_[vertexIDs[v]];
01387 hasCellLID[ind] = ( hasCellLID[ind]
01388 || ( (maxCoFacet[0] >= 0) && (elementOwner_[2][maxCoFacet[0]] == myRank_) )
01389 || ( (maxCoFacet[1] >= 0) && (elementOwner_[2][maxCoFacet[1]] == myRank_) )
01390 || ( (maxCoFacet[2] >= 0) && (elementOwner_[2][maxCoFacet[2]] == myRank_) )
01391 || ( (maxCoFacet[3] >= 0) && (elementOwner_[2][maxCoFacet[3]] == myRank_) ) ) ;
01392
01393
01394
01395
01396
01397 if ( (hasCellLID[ind] == false) && (isPointHanging_[vertexIDs[v]] == true)){
01398 int parentID = parentCellLID_[ind];
01399 Array<int>& parentVertexIDs = cellsPoints_[parentID];
01400 hasCellLID[ind] = hasCellLID[ind] || (elementOwner_[0][parentVertexIDs[v]] == myRank_);
01401 }
01402 }
01403 SUNDANCE_MSG3(verb() , "HNMesh2D::createLeafNumbering Cell ID :" << ind << " should be LID: " << hasCellLID[ind] <<
01404 " ,isCellLeaf_[ind]:" << isCellLeaf_[ind]);
01405 }
01406
01407
01408
01409
01410
01411 bool check_Ghost_cells = true;
01412 while (check_Ghost_cells){
01413 check_Ghost_cells = false;
01414 for (int ind = 0 ; ind < nrElem_[2] ; ind++){
01415 if ( (hasCellLID[ind] == true) && (elementOwner_[2][ind] != myRank_ ) ){
01416
01417 Array<int>& edgeIDs = cellsEdges_[ind];
01418
01419 for (int ii = 0 ; ii < 4 ; ii++ ){
01420
01421 if (isEdgeHanging_[edgeIDs[ii]] && ( elementOwner_[1][edgeIDs[ii]] != myRank_)){
01422
01423 int parentCell = parentCellLID_[ind];
01424 Array<int>& parentEdgesIDs = cellsEdges_[parentCell];
01425 for (int f = 0 ; f < 2 ; f++)
01426 if ( ( edgeMaxCoF_[parentEdgesIDs[ii]][f] >= 0 ) &&
01427 ( elementOwner_[2][ edgeMaxCoF_[parentEdgesIDs[ii]][f] ] != myRank_ ) &&
01428 ( hasCellLID[edgeMaxCoF_[parentEdgesIDs[ii]][f]] == false) &&
01429 ( isCellLeaf_[edgeMaxCoF_[parentEdgesIDs[ii]][f]] )
01430 ){
01431 hasCellLID[edgeMaxCoF_[parentEdgesIDs[ii]][f]] = true;
01432 check_Ghost_cells = true;
01433 }
01434 }
01435 }
01436 }
01437 }
01438 }
01439
01440
01441 for (int ind = 0 ; ind < nrElem_[2] ; ind++)
01442 {
01443
01444
01445 if ( (isCellLeaf_[ind] == true) && (!isCellOut_[ind]) )
01446 {
01447 Array<int>& vertexIDs = cellsPoints_[ind];
01448 for (int v = 0; v < 4 ; v++)
01449 {
01450 SUNDANCE_MSG3(verb() , " createLeafGIDNumbering vertexIDs[v]:" << vertexIDs[v] );
01451 if (vertexGIDToLeafMapping_[vertexIDs[v]] < 0)
01452 {
01453 SUNDANCE_MSG3(verb() , " createLeafGIDNumbering -> VertexID:" << vertexIDs[v] << " , nrVertexLeafGID_:" << nrVertexLeafGID_ );
01454 vertexLeafToGIDMapping_[nrVertexLeafGID_] = vertexIDs[v];
01455 vertexGIDToLeafMapping_[vertexIDs[v]] = nrVertexLeafGID_;
01456 nrVertexLeafGID_++;
01457 }
01458 }
01459 Array<int>& edgeIDs = cellsEdges_[ind];
01460
01461 for (int e = 0; e < 4 ; e++)
01462 {
01463
01464 if (edgeGIDToLeafMapping_[edgeIDs[e]] < 0)
01465 {
01466 SUNDANCE_MSG3(verb() , " createLeafGIDNumbering -> edgeID:" << edgeIDs[e] << " , nrEdgeLeafGID_:" << nrEdgeLeafGID_ );
01467
01468 edgeLeafToGIDMapping_[nrEdgeLeafGID_] = edgeIDs[e];
01469 edgeGIDToLeafMapping_[edgeIDs[e]] = nrEdgeLeafGID_;
01470 nrEdgeLeafGID_++;
01471 }
01472 }
01473
01474 SUNDANCE_MSG3(verb() , " createLeafGIDNumbering CELL cellID:" << ind << " , nrCellLeafGID_:" << nrCellLeafGID_ );
01475 cellLeafToGIDMapping_[nrCellLeafGID_] = ind;
01476 cellGIDToLeafMapping_[ind] = nrCellLeafGID_;
01477 nrCellLeafGID_++;
01478
01479
01480
01481 if (hasCellLID[ind]){
01482
01483 for (int v = 0; v < 4 ; v++)
01484 {
01485 if (vertexLIDToLeafMapping_[vertexIDs[v]] < 0)
01486 {
01487 SUNDANCE_MSG3(verb() , " createLeafLIDNumbering -> VertexID:" << vertexIDs[v] << " , nrVertexLeafLID_:" << nrVertexLeafLID_ );
01488 vertexLeafToLIDMapping_[nrVertexLeafLID_] = vertexIDs[v];
01489 vertexLIDToLeafMapping_[vertexIDs[v]] = nrVertexLeafLID_;
01490 nrVertexLeafLID_++;
01491 }
01492 }
01493
01494 for (int e = 0; e < 4 ; e++)
01495 {
01496 if (edgeLIDToLeafMapping_[edgeIDs[e]] < 0)
01497 {
01498 SUNDANCE_MSG3(verb() , " createLeafLIDNumbering -> edgeID:" << edgeIDs[e] << " , nrEdgeLeafLID_:" << nrEdgeLeafLID_ );
01499 edgeLeafToLIDMapping_[nrEdgeLeafLID_] = edgeIDs[e];
01500 edgeLIDToLeafMapping_[edgeIDs[e]] = nrEdgeLeafLID_;
01501 nrEdgeLeafLID_++;
01502 }
01503 }
01504
01505 SUNDANCE_MSG3(verb() , " createLeafLIDNumbering CELL cellID:" << ind << " , nrCellLeafLID_:" << nrCellLeafLID_ );
01506 cellLeafToLIDMapping_[nrCellLeafLID_] = ind;
01507 cellLIDToLeafMapping_[ind] = nrCellLeafLID_;
01508 nrCellLeafLID_++;
01509 }
01510 }
01511 }
01512 SUNDANCE_MSG3(verb() , "HNMesh2D::createLeafNumbering , DONE");
01513 }
01514
01515
01516
01517
01518 int HNMesh2D::estimateCellLoad(int ID){
01519 int rtn = 0;
01520 if (isCellLeaf_[ID]){
01521 if (!isCellOut_[ID]) rtn = 1;
01522 } else {
01523
01524 for (int r = 0 ; r < (int)cellsChildren_[ID].size() ; r++){
01525 rtn = rtn + estimateCellLoad(cellsChildren_[ID][r]);
01526 }
01527 }
01528 return rtn;
01529 }
01530
01531
01532 void HNMesh2D::markCellsAndFacets(int cellID , int procID){
01533
01534 if (elementOwner_[2][cellID] < 0) { elementOwner_[2][cellID] = procID; }
01535
01536 if (elementOwner_[1][cellsEdges_[cellID][0]] < 0 ) { elementOwner_[1][cellsEdges_[cellID][0]] = procID;}
01537 if (elementOwner_[1][cellsEdges_[cellID][1]] < 0 ) { elementOwner_[1][cellsEdges_[cellID][1]] = procID;}
01538 if (elementOwner_[1][cellsEdges_[cellID][2]] < 0 ) { elementOwner_[1][cellsEdges_[cellID][2]] = procID;}
01539 if (elementOwner_[1][cellsEdges_[cellID][3]] < 0 ) { elementOwner_[1][cellsEdges_[cellID][3]] = procID;}
01540
01541
01542 if (elementOwner_[0][cellsPoints_[cellID][0]] < 0 ) { elementOwner_[0][cellsPoints_[cellID][0]] = procID;}
01543 if (elementOwner_[0][cellsPoints_[cellID][1]] < 0 ) { elementOwner_[0][cellsPoints_[cellID][1]] = procID;}
01544 if (elementOwner_[0][cellsPoints_[cellID][2]] < 0 ) { elementOwner_[0][cellsPoints_[cellID][2]] = procID;}
01545 if (elementOwner_[0][cellsPoints_[cellID][3]] < 0 ) { elementOwner_[0][cellsPoints_[cellID][3]] = procID;}
01546
01547
01548 if (!isCellLeaf_[cellID]){
01549
01550 for (int r = 0 ; r < (int)cellsChildren_[cellID].size() ; r++){
01551 markCellsAndFacets(cellsChildren_[cellID][r] , procID);
01552 }
01553 }
01554 }
01555
01556 void HNMesh2D::createLeafNumbering_sophisticated(){
01557
01558
01559 Array<bool> hasCellLID(nrElem_[2],false);
01560 double total_load = 0.0;
01561 int nrCoarseCell = _res_x * _res_y;
01562 Array<int> coarseCellLoad( _res_x * _res_y , 1 );
01563
01564
01565
01566
01567
01568
01569
01570
01571 for (int ind = 0 ; ind < nrElem_[2] ; ind++){
01572 if (ind < nrCoarseCell) {
01573
01574 coarseCellLoad[ind] = estimateCellLoad(ind);
01575 }
01576 if ((isCellLeaf_[ind] == true) && (!isCellOut_[ind]) )
01577 { total_load = total_load + 1 ; }
01578 }
01579
01580 SUNDANCE_MSG3(verb() , "total_load = " << total_load << " , nrCell = " << nrElem_[2]);
01581
01582
01583
01584 #ifdef _MSC_VER
01585 int levelM = ::ceil( std::max<double>( ::log2(_res_x) , ::log2(_res_y ) ) );
01586 #else
01587 int levelM = ::ceil( ::fmax( ::log2(_res_x) , ::log2(_res_y ) ) );
01588 #endif
01589
01590 Array<int> vectX1(4), vectY1(4), vectX2(4), vectY2(4);
01591 vectX1[0] = 0; vectX1[1] = (int)std::pow(2,levelM-1); vectX1[2] = 0; vectX1[3] = (int)std::pow(2,levelM-1);
01592 vectY1[0] = 0; vectY1[1] = 0; vectY1[2] = (int)std::pow(2,levelM-1); vectY1[3] = (int)std::pow(2,levelM-1);
01593 vectX2[0] = 0; vectX2[1] = (int)std::pow(2,levelM-1); vectX2[2] = 0; vectX2[3] = (int)std::pow(2,levelM-1);
01594 vectY2[0] = 0; vectY2[1] = 0; vectY2[2] = (int)std::pow(2,levelM-1); vectY2[3] = (int)std::pow(2,levelM-1);
01595 int addX[4] = { 0 , 1 , 0 , 1};
01596 int addY[4] = { 0 , 0 , 1 , 1};
01597 Array<int> *inX = &vectX1 , *inY = &vectY1 , *outX = &vectX2 , *outY = &vectY2 , *tmpVectP;
01598 int levelActual = levelM - 2;
01599
01600 while (levelActual >= 0){
01601 outX->resize( 4 * inX->size() );
01602 outY->resize( 4 * inY->size() );
01603 int cI = 0 , addO = (int)std::pow(2,levelActual);
01604 SUNDANCE_MSG3(verb() , " outX->size():" << outX->size() << ", levelActual:" << levelActual << " , addO:" << addO);
01605
01606 for (int ce = 0 ; ce < inX->size() ; ce++){
01607 (*outX)[cI+0] = (*inX)[ce] + addO*addX[0];
01608 (*outX)[cI+1] = (*inX)[ce] + addO*addX[1];
01609 (*outX)[cI+2] = (*inX)[ce] + addO*addX[2];
01610 (*outX)[cI+3] = (*inX)[ce] + addO*addX[3];
01611 (*outY)[cI+0] = (*inY)[ce] + addO*addY[0];
01612 (*outY)[cI+1] = (*inY)[ce] + addO*addY[1];
01613 (*outY)[cI+2] = (*inY)[ce] + addO*addY[2];
01614 (*outY)[cI+3] = (*inY)[ce] + addO*addY[3];
01615 cI = cI + 4;
01616 }
01617 SUNDANCE_MSG3(verb() , " EX: " << (*outX)[0] << " , " << (*outX)[1] << " , " << (*outX)[2]);
01618 SUNDANCE_MSG3(verb() , " EY: " << (*outY)[0] << " , " << (*outY)[1] << " , " << (*outY)[2]);
01619
01620 levelActual = levelActual - 1;
01621 tmpVectP = inX; inX = outX; outX = tmpVectP;
01622 tmpVectP = inY; inY = outY; outY = tmpVectP;
01623 }
01624
01625 tmpVectP = inX; inX = outX; outX = tmpVectP;
01626 tmpVectP = inY; inY = outY; outY = tmpVectP;
01627
01628
01629 for (int tmp = 0 ; tmp < nrElem_[0] ; tmp++ ){ elementOwner_[0][tmp] = -1; }
01630 for (int tmp = 0 ; tmp < nrElem_[1] ; tmp++ ){ elementOwner_[1][tmp] = -1; }
01631 for (int tmp = 0 ; tmp < nrElem_[2] ; tmp++ ){ elementOwner_[2][tmp] = -1; }
01632
01633
01634 int coarseCellID , actProcID = 0 , actualLoad = 0;
01635 double loadPerProc = (double)total_load / (double)nrProc_ , diff_load = 0.0;
01636 for (int ind = 0 ; ind < outX->size() ; ind++){
01637
01638 if ( ((*outX)[ind] < _res_x) && ((*outY)[ind] < _res_y) ){
01639
01640 coarseCellID = ((*outX)[ind])*_res_y + ((*outY)[ind]);
01641 SUNDANCE_MSG3(verb(),"Z-curve trav. ind:" << ind << " , coarseCellID:" << coarseCellID << " , indX:" << (*outX)[ind] << " , indY:" << (*outY)[ind]);
01642
01643 TEUCHOS_TEST_FOR_EXCEPTION( cellLevel_[coarseCellID] > 0 , std::logic_error, " coarseCellID:" << coarseCellID << " has level:" << cellLevel_[coarseCellID] );
01644 markCellsAndFacets( coarseCellID , actProcID);
01645 actualLoad = actualLoad + coarseCellLoad[coarseCellID];
01646
01647 if (((double)actualLoad >= (loadPerProc - 1e-8 - diff_load)) && ( actProcID < nrProc_-1 )){
01648 SUNDANCE_MSG3(verb() , "Increase CPU , actualLoad:" << actualLoad << " loadPerProc:" << loadPerProc );
01649
01650 diff_load = actualLoad - loadPerProc;
01651 actProcID = actProcID + 1;
01652 actualLoad = 0;
01653 }
01654 }
01655 }
01656
01657
01658 SUNDANCE_MSG3(verb()," nrElem_[0]:" << nrElem_[0] << " , nrElem_[1]:" << nrElem_[1] << " , nrElem_[2]" << nrElem_[2]);
01659 for (int tmp = 0 ; tmp < nrElem_[0] ; tmp++ ){ TEUCHOS_TEST_FOR_EXCEPTION( elementOwner_[0][tmp] < 0 , std::logic_error, " 0 tmp:" << tmp); }
01660 for (int tmp = 0 ; tmp < nrElem_[1] ; tmp++ ){ TEUCHOS_TEST_FOR_EXCEPTION( elementOwner_[1][tmp] < 0 , std::logic_error, " 1 tmp:" << tmp); }
01661 for (int tmp = 0 ; tmp < nrElem_[2] ; tmp++ ){ TEUCHOS_TEST_FOR_EXCEPTION( elementOwner_[2][tmp] < 0 , std::logic_error, " 2 tmp:" << tmp); }
01662
01663
01664
01665
01666
01667
01668
01669 SUNDANCE_MSG3(verb() , "HNMesh2D::createLeafNumbering nrPoint:" << nrElem_[0] << " , nrEdge:" << nrElem_[1] << ", nrCell:" << nrElem_[2]);
01670
01671 vertexGIDToLeafMapping_.resize(nrElem_[0],-1);
01672 for (int dd = 0 ; dd < nrElem_[0] ; dd++) vertexGIDToLeafMapping_[dd] = -1;
01673 vertexLeafToGIDMapping_.resize(nrElem_[0],-1);
01674 for (int dd = 0 ; dd < nrElem_[0] ; dd++) vertexLeafToGIDMapping_[dd] = -1;
01675
01676 edgeGIDToLeafMapping_.resize(nrElem_[1],-1);
01677 for (int dd = 0 ; dd < nrElem_[1] ; dd++) edgeGIDToLeafMapping_[dd] = -1;
01678 edgeLeafToGIDMapping_.resize(nrElem_[1],-1);
01679 for (int dd = 0 ; dd < nrElem_[1] ; dd++) edgeLeafToGIDMapping_[dd] = -1;
01680
01681 cellGIDToLeafMapping_.resize(nrElem_[2],-1);
01682 for (int dd = 0 ; dd < nrElem_[2] ; dd++) cellGIDToLeafMapping_[dd] = -1;
01683 cellLeafToGIDMapping_.resize(nrElem_[2],-1);
01684 for (int dd = 0 ; dd < nrElem_[2] ; dd++) cellLeafToGIDMapping_[dd] = -1;
01685
01686 nrVertexLeafGID_ = 0; nrCellLeafGID_ = 0; nrEdgeLeafGID_ = 0;
01687
01688 nrVertexLeafLID_ = 0; nrCellLeafLID_ = 0; nrEdgeLeafLID_ = 0;
01689 vertexLIDToLeafMapping_.resize(nrElem_[0],-1);
01690 for (int dd = 0 ; dd < nrElem_[0] ; dd++) vertexLIDToLeafMapping_[dd] = -1;
01691 vertexLeafToLIDMapping_.resize(nrElem_[0],-1);
01692 for (int dd = 0 ; dd < nrElem_[0] ; dd++) vertexLeafToLIDMapping_[dd] = -1;
01693
01694 edgeLIDToLeafMapping_.resize(nrElem_[1],-1);
01695 for (int dd = 0 ; dd < nrElem_[1] ; dd++) edgeLIDToLeafMapping_[dd] = -1;
01696 edgeLeafToLIDMapping_.resize(nrElem_[1],-1);
01697 for (int dd = 0 ; dd < nrElem_[1] ; dd++) edgeLeafToLIDMapping_[dd] = -1;
01698
01699 cellLIDToLeafMapping_.resize(nrElem_[2],-1);
01700 for (int dd = 0 ; dd < nrElem_[2] ; dd++) cellLIDToLeafMapping_[dd] = -1;
01701 cellLeafToLIDMapping_.resize(nrElem_[2],-1);
01702 for (int dd = 0 ; dd < nrElem_[2] ; dd++) cellLeafToLIDMapping_[dd] = -1;
01703
01704 SUNDANCE_MSG3(verb() , "HNMesh2D::createLeafNumbering , start assigning leaf numbers");
01705
01706 for (int ind = 0 ; ind < nrElem_[2] ; ind++){
01707 Array<int>& vertexIDs = cellsPoints_[ind];
01708 hasCellLID[ind] = false;
01709 for (int v = 0 ; v < 4 ; v++){
01710 Array<int>& maxCoFacet = pointMaxCoF_[vertexIDs[v]];
01711 hasCellLID[ind] = ( hasCellLID[ind]
01712 || ( (maxCoFacet[0] >= 0) && (elementOwner_[2][maxCoFacet[0]] == myRank_) )
01713 || ( (maxCoFacet[1] >= 0) && (elementOwner_[2][maxCoFacet[1]] == myRank_) )
01714 || ( (maxCoFacet[2] >= 0) && (elementOwner_[2][maxCoFacet[2]] == myRank_) )
01715 || ( (maxCoFacet[3] >= 0) && (elementOwner_[2][maxCoFacet[3]] == myRank_) ) ) ;
01716
01717
01718
01719
01720
01721 if ( (hasCellLID[ind] == false) && (isPointHanging_[vertexIDs[v]] == true)){
01722 int parentID = parentCellLID_[ind];
01723 Array<int>& parentVertexIDs = cellsPoints_[parentID];
01724 hasCellLID[ind] = hasCellLID[ind] || (elementOwner_[0][parentVertexIDs[v]] == myRank_);
01725 }
01726 }
01727 SUNDANCE_MSG3(verb() , "HNMesh2D::createLeafNumbering Cell ID :" << ind << " should be LID: " << hasCellLID[ind] <<
01728 " ,isCellLeaf_[ind]:" << isCellLeaf_[ind]);
01729 }
01730
01731
01732
01733
01734
01735 bool check_Ghost_cells = true;
01736 while (check_Ghost_cells){
01737 check_Ghost_cells = false;
01738 for (int ind = 0 ; ind < nrElem_[2] ; ind++){
01739 if ( (hasCellLID[ind] == true) && (elementOwner_[2][ind] != myRank_ ) ){
01740
01741 Array<int>& edgeIDs = cellsEdges_[ind];
01742
01743 for (int ii = 0 ; ii < 4 ; ii++ ){
01744
01745 if (isEdgeHanging_[edgeIDs[ii]] && ( elementOwner_[1][edgeIDs[ii]] != myRank_)){
01746
01747 int parentCell = parentCellLID_[ind];
01748 Array<int>& parentEdgesIDs = cellsEdges_[parentCell];
01749 for (int f = 0 ; f < 2 ; f++)
01750 if ( ( edgeMaxCoF_[parentEdgesIDs[ii]][f] >= 0 ) &&
01751 ( elementOwner_[2][ edgeMaxCoF_[parentEdgesIDs[ii]][f] ] != myRank_ ) &&
01752 ( hasCellLID[edgeMaxCoF_[parentEdgesIDs[ii]][f]] == false) &&
01753 ( isCellLeaf_[edgeMaxCoF_[parentEdgesIDs[ii]][f]] )
01754 ){
01755 hasCellLID[edgeMaxCoF_[parentEdgesIDs[ii]][f]] = true;
01756 check_Ghost_cells = true;
01757 }
01758 }
01759 }
01760 }
01761 }
01762 }
01763
01764
01765 for (int ind = 0 ; ind < nrElem_[2] ; ind++)
01766 {
01767
01768
01769 if ( (isCellLeaf_[ind] == true) && (!isCellOut_[ind]) )
01770 {
01771 Array<int>& vertexIDs = cellsPoints_[ind];
01772 for (int v = 0; v < 4 ; v++)
01773 {
01774 SUNDANCE_MSG3(verb() , " createLeafGIDNumbering vertexIDs[v]:" << vertexIDs[v] );
01775 if (vertexGIDToLeafMapping_[vertexIDs[v]] < 0)
01776 {
01777 SUNDANCE_MSG3(verb() , " createLeafGIDNumbering -> VertexID:" << vertexIDs[v] << " , nrVertexLeafGID_:" << nrVertexLeafGID_ );
01778 vertexLeafToGIDMapping_[nrVertexLeafGID_] = vertexIDs[v];
01779 vertexGIDToLeafMapping_[vertexIDs[v]] = nrVertexLeafGID_;
01780 nrVertexLeafGID_++;
01781 }
01782 }
01783 Array<int>& edgeIDs = cellsEdges_[ind];
01784
01785 for (int e = 0; e < 4 ; e++)
01786 {
01787
01788 if (edgeGIDToLeafMapping_[edgeIDs[e]] < 0)
01789 {
01790 SUNDANCE_MSG3(verb() , " createLeafGIDNumbering -> edgeID:" << edgeIDs[e] << " , nrEdgeLeafGID_:" << nrEdgeLeafGID_ );
01791
01792 edgeLeafToGIDMapping_[nrEdgeLeafGID_] = edgeIDs[e];
01793 edgeGIDToLeafMapping_[edgeIDs[e]] = nrEdgeLeafGID_;
01794 nrEdgeLeafGID_++;
01795 }
01796 }
01797
01798 SUNDANCE_MSG3(verb() , " createLeafGIDNumbering CELL cellID:" << ind << " , nrCellLeafGID_:" << nrCellLeafGID_ );
01799 cellLeafToGIDMapping_[nrCellLeafGID_] = ind;
01800 cellGIDToLeafMapping_[ind] = nrCellLeafGID_;
01801 nrCellLeafGID_++;
01802
01803
01804
01805 if (hasCellLID[ind]){
01806
01807 for (int v = 0; v < 4 ; v++)
01808 {
01809 if (vertexLIDToLeafMapping_[vertexIDs[v]] < 0)
01810 {
01811 SUNDANCE_MSG3(verb() , " createLeafLIDNumbering -> VertexID:" << vertexIDs[v] << " , nrVertexLeafLID_:" << nrVertexLeafLID_ );
01812 vertexLeafToLIDMapping_[nrVertexLeafLID_] = vertexIDs[v];
01813 vertexLIDToLeafMapping_[vertexIDs[v]] = nrVertexLeafLID_;
01814 nrVertexLeafLID_++;
01815 }
01816 }
01817
01818 for (int e = 0; e < 4 ; e++)
01819 {
01820 if (edgeLIDToLeafMapping_[edgeIDs[e]] < 0)
01821 {
01822 SUNDANCE_MSG3(verb() , " createLeafLIDNumbering -> edgeID:" << edgeIDs[e] << " , nrEdgeLeafLID_:" << nrEdgeLeafLID_ );
01823 edgeLeafToLIDMapping_[nrEdgeLeafLID_] = edgeIDs[e];
01824 edgeLIDToLeafMapping_[edgeIDs[e]] = nrEdgeLeafLID_;
01825 nrEdgeLeafLID_++;
01826 }
01827 }
01828
01829 SUNDANCE_MSG3(verb() , " createLeafLIDNumbering CELL cellID:" << ind << " , nrCellLeafLID_:" << nrCellLeafLID_ );
01830 cellLeafToLIDMapping_[nrCellLeafLID_] = ind;
01831 cellLIDToLeafMapping_[ind] = nrCellLeafLID_;
01832 nrCellLeafLID_++;
01833 }
01834 }
01835 }
01836 SUNDANCE_MSG3(verb() , "HNMesh2D::createLeafNumbering , DONE");
01837 }