SundanceHNMesh2D.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 //
00004 //                              Sundance
00005 //                 Copyright (2005) Sandia Corporation
00006 //
00007 // Copyright (year first published) Sandia Corporation.  Under the terms
00008 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
00009 // retains certain rights in this software.
00010 //
00011 // This library is free software; you can redistribute it and/or modify
00012 // it under the terms of the GNU Lesser General Public License as
00013 // published by the Free Software Foundation; either version 2.1 of the
00014 // License, or (at your option) any later version.
00015 //
00016 // This library is distributed in the hope that it will be useful, but
00017 // WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019 // Lesser General Public License for more details.
00020 //
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License along with this library; if not, write to the Free Software
00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00024 // USA
00025 // Questions? Contact Kevin Long (krlong@sandia.gov),
00026 // Sandia National Laboratories, Livermore, California, USA
00027 //
00028 // ************************************************************************
00029 /* @HEADER@ */
00030 /*
00031  * SundanceHNMesh2D.cpp
00032  *
00033  *  Created on: April 30, 2009
00034  *      Author: benk
00035  */
00036 
00037 #include "SundanceHNMesh2D.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 using namespace Sundance;
00052 using namespace Teuchos;
00053 using namespace std;
00054 
00055 int HNMesh2D::offs_Points_x_[4] = {0, 1, 0, 1};
00056 
00057 int HNMesh2D::offs_Points_y_[4] = {0, 0, 1, 1};
00058 
00059 int HNMesh2D::edge_Points_localIndex[4][2] = { {0,1} , {0,2} , {1,3} , {2,3} };
00060 
00061 
00062 HNMesh2D::HNMesh2D(int dim, const MPIComm& comm ,
00063       const MeshEntityOrder& order)
00064 : MeshBase(dim, comm , order),_dimension(dim), _comm(comm)
00065 {
00066   setVerbosity(0);
00067   // get the number of processors
00068   nrProc_ = MPIComm::world().getNProc();
00069   myRank_ = MPIComm::world().getRank();
00070   //------ Point storage ----
00071   points_.resize(0);
00072     nrElem_.resize(3,0);
00073   nrElemOwned_.resize(3,0);
00074   //----- Facets -----
00075     cellsPoints_.resize(0);
00076     cellsEdges_.resize(0);
00077     isCellOut_.resize(0);
00078   edgePoints_.resize(0);
00079   edgeVertex_.resize(0);
00080   // ----- MaxCofacets ----
00081   edgeMaxCoF_.resize(0);
00082     pointMaxCoF_.resize(0);
00083     //------ Element (processor) ownership -----
00084   elementOwner_.resize(3); elementOwner_[0].resize(0); elementOwner_[1].resize(0); elementOwner_[2].resize(0);
00085   // ------------- different boundary ---------
00086     edgeIsProcBonudary_.resize(0);
00087     edgeIsMeshDomainBonudary_.resize(0);
00088     //---- hierarchical storage -----
00089     indexInParent_.resize(0);
00090     parentCellLID_.resize(0);
00091   cellLevel_.resize(0);
00092   isCellLeaf_.resize(0);
00093   // ---- "hanging" info storage ---
00094   isPointHanging_.resize(0);
00095   isEdgeHanging_.resize(0);
00096   // ---- hanging element and refinement (temporary) storage ---
00097   hangElmStore_.resize(2);
00098   hangElmStore_[0] = Hashtable< int, Array<int> >();
00099   hangElmStore_[1] = Hashtable< int, Array<int> >();
00100   refineCell_.resize(0);
00101     // set the leaf counter to zero
00102   nrCellLeafGID_ = 0; nrEdgeLeafGID_ = 0; nrVertexLeafGID_ = 0;
00103   nrVertexLeafLID_ = 0; nrCellLeafLID_ = 0; nrEdgeLeafLID_ = 0;
00104 }
00105 
00106 int HNMesh2D::numCells(int dim) const  {
00107   SUNDANCE_MSG3(verb(),"HNMesh2D::numCells(int dim):   dim:" << dim );
00108   switch (dim){
00109   case 0: return nrVertexLeafLID_;
00110   case 1: return nrEdgeLeafLID_;
00111   case 2: return nrCellLeafLID_;
00112   }
00113   return 0;
00114 }
00115 
00116 Point HNMesh2D::nodePosition(int i) const {
00117   SUNDANCE_MSG3(verb(),"HNMesh2D::nodePosition(int i)   i:"<< i);
00118     // point do not need leaf indexing
00119   return points_[vertexLeafToLIDMapping_[i]];
00120 }
00121 
00122 const double* HNMesh2D::nodePositionView(int i) const {
00123   SUNDANCE_MSG3(verb(),"HNMesh2D::nodePositionView(int i)   i:" << i);
00124   //SUNDANCE_VERB_HIGH("nodePosition(int i)");
00125   return &(points_[vertexLeafToLIDMapping_[i]][0]);;
00126 }
00127 
00128 void HNMesh2D::getJacobians(int cellDim, const Array<int>& cellLID,
00129                           CellJacobianBatch& jBatch) const
00130 {
00131     SUNDANCE_MSG3(verb(),"HNMesh2D::getJacobians  cellDim:"<<cellDim<<" _x:"<<_ofs_x<<" _y:"<<_ofs_y);
00132     SUNDANCE_VERB_HIGH("getJacobians()");
00133     TEST_FOR_EXCEPTION(cellDim < 0 || cellDim > spatialDim(), InternalError,
00134       "cellDim=" << cellDim << " is not in expected range [0, " << spatialDim() << "]");
00135     int nCells = cellLID.size();
00136     int LID;
00137     Point pnt(0.0,0.0);
00138     jBatch.resize(cellLID.size(), spatialDim(), cellDim);
00139     if (cellDim < spatialDim()) // they need the Jacobian of a lower dinemsional element
00140     {
00141        for (int i=0; i<nCells; i++)
00142         {
00143           double* detJ = jBatch.detJ(i);
00144           switch(cellDim)
00145           {
00146             case 0: *detJ = 1.0;
00147               break;
00148             case 1:
00149           LID = edgeLeafToLIDMapping_[cellLID[i]];
00150             pnt = (points_[edgePoints_[LID][1]] - points_[edgePoints_[LID][0]]);
00151               *detJ = sqrt(pnt * pnt); // the length of the edge
00152             break;
00153             default:
00154               TEST_FOR_EXCEPTION(true, InternalError, "impossible switch value "  "cellDim=" << cellDim << " in HNMesh2D::getJacobians()");
00155           }
00156         }
00157     }else{ // they request the complete Jacoby matrix for this bunch of elements
00158         //Array<double> J(cellDim*cellDim);
00159         SUNDANCE_VERB_HIGH("cellDim == spatialDim()");
00160         for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00161         {
00162           double* J = jBatch.jVals(i);
00163           switch(cellDim)
00164           {
00165             case 2:
00166           LID = cellLeafToLIDMapping_[cellLID[i]];
00167           // Jacobi for unstructured quad this will not work, but because of linear Jacoby we only have structured quads
00168               J[0] = points_[cellsPoints_[LID][1]][0] - points_[cellsPoints_[LID][0]][0];
00169               J[1] = 0.0;
00170               J[2] = 0.0;
00171               J[3] = points_[cellsPoints_[LID][2]][1] - points_[cellsPoints_[LID][0]][1];
00172             SUNDANCE_MSG3(verb() , "HNMesh2D::getJacobians X:" << J[0] << " Y:" << J[3] );
00173             break;
00174             default:
00175               TEST_FOR_EXCEPTION(true, InternalError, "impossible switch value " "cellDim=" << cellDim << " in HNMesh2D::getJacobians()");
00176           }
00177         }
00178     }
00179 }
00180 
00181 void HNMesh2D::getCellDiameters(int cellDim, const Array<int>& cellLID,
00182                               Array<double>& cellDiameters) const {
00183    TEST_FOR_EXCEPTION(cellDim < 0 || cellDim > spatialDim(), InternalError,
00184       "cellDim=" << cellDim << " is not in expected range [0, " << spatialDim() << "]");
00185    SUNDANCE_VERB_HIGH("getCellDiameters()");
00186     cellDiameters.resize(cellLID.size());
00187     Point pnt(0.0,0.0);
00188     int LID;
00189     if (cellDim < spatialDim())
00190     {
00191     SUNDANCE_MSG3(verb(),"HNMesh2D::getCellDiameters(), cellDim < spatialDim() ");
00192       for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00193       {
00194         switch(cellDim)
00195         {
00196           case 0:
00197                cellDiameters[i] = 1.0;
00198             break;
00199           case 1:  //length of the edge
00200           LID = edgeLeafToLIDMapping_[cellLID[i]];
00201             pnt = (points_[edgePoints_[LID][1]] - points_[edgePoints_[LID][0]]);
00202             cellDiameters[i] = sqrt(pnt * pnt); // the length of the edge
00203           break;
00204           default:
00205             TEST_FOR_EXCEPTION(true, InternalError, "impossible switch value "  "cellDim=" << cellDim << " in HNMesh2D::getCellDiameters()");
00206         }
00207       }
00208     }
00209     else
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 2:
00217             LID = cellLeafToLIDMapping_[cellLID[i]];
00218             pnt = points_[cellsPoints_[LID][3]] - points_[cellsPoints_[LID][0]];
00219             cellDiameters[i] = sqrt(pnt * pnt);
00220           break;
00221           default:
00222             TEST_FOR_EXCEPTION(true, InternalError, "impossible switch value "
00223              "cellDim=" << cellDim  << " in HNMesh2D::getCellDiameters()");
00224         }
00225       }
00226     }
00227 }
00228 
00229 void HNMesh2D::pushForward(int cellDim, const Array<int>& cellLID,
00230                          const Array<Point>& refQuadPts,
00231                          Array<Point>& physQuadPts) const {
00232 
00233     SUNDANCE_MSG3(verb(),"HNMesh2D::pushForward cellDim:"<<cellDim);
00234     TEST_FOR_EXCEPTION(cellDim < 0 || cellDim > spatialDim(), InternalError,
00235       "cellDim=" << cellDim << " is not in expected range [0, " << spatialDim() << "]");
00236 
00237     int nQuad = refQuadPts.size();
00238     Point pnt( 0.0 , 0.0 );
00239     Point pnt1( 0.0 , 0.0 );
00240 
00241     if (physQuadPts.size() > 0) physQuadPts.resize(0);
00242     physQuadPts.reserve(cellLID.size() * refQuadPts.size());
00243     for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00244     {
00245       switch(cellDim)
00246       {
00247         case 0: // integrate one point
00248            physQuadPts.append(pnt);
00249           break;
00250         case 1:{ // integrate on one line
00251            int LID = edgeLeafToLIDMapping_[cellLID[i]];
00252              pnt = points_[edgePoints_[LID][0]];
00253              pnt1 = points_[edgePoints_[LID][1]] - points_[edgePoints_[LID][0]];
00254                for (int q=0; q<nQuad; q++) {
00255                  physQuadPts.append(pnt + (pnt1)*refQuadPts[q][0]);
00256             }
00257         break;}
00258         case 2:{
00259                int LID = cellLeafToLIDMapping_[cellLID[i]];
00260                pnt = points_[cellsPoints_[LID][0]];
00261                // this works only for structured, but we only work on structured quads
00262                pnt1 = points_[cellsPoints_[LID][3]] - points_[cellsPoints_[LID][0]];
00263              for (int q=0; q<nQuad; q++) {
00264                   physQuadPts.append( pnt + Point( refQuadPts[q][0] * pnt1[0] , refQuadPts[q][1] * pnt1[1] ) );
00265              }
00266         break;}
00267         default:
00268           TEST_FOR_EXCEPTION(true, InternalError, "impossible switch value " "in HNMesh2D::getJacobians()");
00269       }
00270     }
00271 }
00272 
00273 int HNMesh2D::ownerProcID(int cellDim, int cellLID) const  {
00274    int ID = -1;
00275    if (cellDim == 0) ID = vertexLeafToLIDMapping_[cellLID];
00276      if (cellDim == 1) ID = edgeLeafToLIDMapping_[cellLID];
00277      if (cellDim == 2) ID = cellLeafToLIDMapping_[cellLID];
00278      SUNDANCE_MSG3(verb() , " HNMesh2D::ownerProcID ,cellDim:" << cellDim << ", cellLID:"
00279          << cellLID <<" ,ID:" << ID << ", ret:"<< elementOwner_[cellDim][ID] );
00280    return elementOwner_[cellDim][ID];
00281 }
00282 
00283 
00284 int HNMesh2D::numFacets(int cellDim, int cellLID,
00285                       int facetDim) const  {
00286   //SUNDANCE_VERB_HIGH("numFacets()");
00287   if (cellDim==1) { // 1 dimension
00288          return 2; //one line has 2 points
00289     }
00290     else if (cellDim==2) { // 2 dimensions
00291          return 4; //one quad has 4 edges and 4 points
00292     }
00293   return -1;
00294 }
00295 
00296 int HNMesh2D::facetLID(int cellDim, int cellLID,
00297                      int facetDim, int facetIndex,
00298                      int& facetOrientation) const  {
00299   // todo: check weather facet orientation is right
00300   facetOrientation = 1;
00301   SUNDANCE_MSG3(verb(),"HNMesh2D::facetLID  cellDim:"<<cellDim<<", cellLID:"<<cellLID<<", facetDim:"<<facetDim<< ", facetIndex:" << facetIndex);
00302   int rnt = -1 , LID=-1 , tmp=-1;
00303   if (facetDim == 0){ // return the Number/ID of a Vertex
00304     if (cellDim == 2 ){
00305         LID = cellLeafToLIDMapping_[cellLID];
00306         rnt = cellsPoints_[LID][facetIndex]; tmp = rnt;
00307         rnt = vertexLIDToLeafMapping_[rnt];
00308       }
00309       else if ((cellDim==1)){
00310           LID = edgeLeafToLIDMapping_[cellLID];
00311           rnt = edgePoints_[LID][facetIndex]; tmp = rnt;
00312           rnt = vertexLIDToLeafMapping_[rnt];
00313       }
00314   } else if (facetDim == 1){
00315           LID = cellLeafToLIDMapping_[cellLID];
00316           rnt = cellsEdges_[LID][facetIndex]; tmp = rnt;
00317       rnt = edgeLIDToLeafMapping_[rnt];
00318          }
00319   SUNDANCE_MSG3(verb()," RET = " << rnt << ", LID:" << LID << ", tmp:" <<  tmp);
00320   return rnt;
00321 }
00322 
00323 
00324 void HNMesh2D::getFacetLIDs(int cellDim,
00325                           const Array<int>& cellLID,
00326                           int facetDim,
00327                           Array<int>& facetLID,
00328                           Array<int>& facetSign) const {
00329 
00330   SUNDANCE_MSG3(verb(),"HNMesh2D::getFacetLIDs()  cellDim:"<<cellDim<<"  cellLID.size():"<<cellLID.size()<<"  facetDim:" <<facetDim);
00331     int LID = 0 , cLID , facetOrientation ;
00332     int ptr = 0;
00333 
00334     int nf = numFacets(cellDim, cellLID[0], facetDim);
00335     facetLID.resize(cellLID.size() * nf);
00336     facetSign.resize(cellLID.size() * nf);
00337     // At this moment we just use the previous function
00338   for (unsigned int i = 0 ; i < (unsigned int)cellLID.size() ; i++){
00339       cLID = cellLID[i];
00340         for (int f=0; f<nf; f++, ptr++) {
00341           // we use this->facetLID caz facetLID is already used as variable
00342         LID = this->facetLID( cellDim, cLID, facetDim, f , facetOrientation);
00343             facetLID[ptr] = LID;
00344             facetSign[ptr] = facetOrientation;
00345         }
00346   }
00347   SUNDANCE_MSG3(verb() ,"HNMesh2D::getFacetLIDs()  DONE. ");
00348 }
00349 
00350 
00351 const int* HNMesh2D::elemZeroFacetView(int cellLID) const {
00352     int LID = cellLeafToLIDMapping_[cellLID];
00353     SUNDANCE_MSG3(verb() , "HNMesh2D::elemZeroFacetView ");
00354   return (const int*)(&cellsPoints_[LID]);
00355 }
00356 
00357 
00358 int HNMesh2D::numMaxCofacets(int cellDim, int cellLID) const  {
00359   //SUNDANCE_VERB_HIGH("numMaxCofacets()");
00360   SUNDANCE_MSG3(verb() , "HNMesh2D::numMaxCofacets():  cellDim:"<<cellDim<<" cellLID:"<<cellLID );
00361   int rnt = -1;
00362   if (cellDim==0) { // 1 dimension
00363     int LID = vertexLeafToLIDMapping_[cellLID];
00364         int sum = 0;
00365         for (int i = 0 ; i < 4 ; i++)
00366           if ( (pointMaxCoF_[LID][i] >= 0) && ( cellLIDToLeafMapping_[pointMaxCoF_[LID][i]] >= 0) )
00367             sum++;
00368         // return the value, how many cells has this point, on the leaf level
00369         rnt = sum;
00370     }
00371     else if (cellDim==1) { // 2 dimensions
00372         int LID = edgeLeafToLIDMapping_[cellLID];
00373     if ((edgeMaxCoF_[LID][0] >= 0) && ( cellLIDToLeafMapping_[edgeMaxCoF_[LID][0]] >= 0) &&
00374       (edgeMaxCoF_[LID][1] >= 0) && ( cellLIDToLeafMapping_[edgeMaxCoF_[LID][1]] >= 0))
00375       rnt = 2;
00376     else
00377       rnt = 1;
00378     }
00379   SUNDANCE_MSG3(verb() ," RET = " << rnt );
00380   return rnt;
00381 }
00382 
00383 
00384 int HNMesh2D::maxCofacetLID(int cellDim, int cellLID,
00385                        int cofacetIndex,
00386                        int& facetIndex) const  {
00387 
00388   SUNDANCE_MSG3(verb() ,"HNMesh2D::maxCofacetLID() cellDim:"<<cellDim<<" cellLID:"<<cellLID<<" cofacetIndex:"<<cofacetIndex<< " facetIndex:"
00389       << facetIndex);
00390   int rnt =-1;
00391   if (cellDim==0) { // 1 dimension
00392     //facetIndex = cofacetIndex;
00393     int actCoFacetIndex = 0;
00394       int LID = vertexLeafToLIDMapping_[cellLID];
00395     for (int ii = 0 ; ii < 4 ; ii++){
00396       // take this maxCoFacet only if that exist and is inside
00397       if ( (pointMaxCoF_[LID][ii] >= 0) && (cellLIDToLeafMapping_[pointMaxCoF_[LID][ii]] >= 0) ){
00398         if ( actCoFacetIndex < cofacetIndex ){
00399           actCoFacetIndex++;
00400         }else{
00401           facetIndex = ii;
00402           rnt = pointMaxCoF_[LID][ii];
00403           break;
00404         }
00405       }
00406     }
00407     }
00408     else if (cellDim==1) { // 2 dimensions
00409       int orientation = 0;
00410       int addFakt = 0;
00411       int maxCoFacet = 0;
00412         int LID = edgeLeafToLIDMapping_[cellLID];
00413         // this works only in structured mesh case, but we will only use structured quads because of the Jacoby
00414     if ( edgeVertex_[LID] == 0 ){
00415       orientation = 0;   addFakt = 2;
00416     }else{
00417       orientation = 1;   addFakt = 1;
00418     }
00419     SUNDANCE_MSG3(verb() ," HNMesh2D::maxCofacetLID() , orientation:" <<orientation<< " addFakt:" << addFakt );
00420         // return the index in the vector, which later will be corrected later
00421     int actCoFacetIndex = 0;
00422     for (int ii = 0 ; ii < 2 ; ii++){
00423       // take this maxCoFacet only if that exist and is inside
00424       if ( (edgeMaxCoF_[LID][ii] >= 0) && (cellLIDToLeafMapping_[edgeMaxCoF_[LID][ii]] >= 0) ){
00425         if ( actCoFacetIndex < cofacetIndex ){
00426           actCoFacetIndex++;
00427         }else{
00428           facetIndex = 1-ii;
00429           maxCoFacet = edgeMaxCoF_[LID][ii];
00430           break;
00431         }
00432       }
00433     }
00434     SUNDANCE_MSG3(verb() ,"HNMesh2D::maxCofacetLID() , facetIndex:" << facetIndex <<", _edgeMaxCoFacet[0]:" << edgeMaxCoF_[LID][0] <<
00435         "_edgeMaxCoFacet[1]:" <<  edgeMaxCoF_[LID][1] );
00436     // calculate the correct facetIndex of the edge in the cell of cofacetIndex
00437     if ( orientation == 0 ){
00438       facetIndex = facetIndex + facetIndex*addFakt; // this should be eighter 0 or 3
00439     } else {
00440       facetIndex = facetIndex + addFakt; // this should be eighter 1 or 2
00441     }
00442     SUNDANCE_MSG3(verb() ," maxCoFacet = " << maxCoFacet );
00443     rnt = ( maxCoFacet );
00444     }
00445   // transform back to leaf indexing
00446   rnt = cellLIDToLeafMapping_[ rnt ];
00447   SUNDANCE_MSG3(verb() ," RET = " << rnt << ",  facetIndex:" << facetIndex);
00448   return rnt;
00449 }
00450 
00451 void HNMesh2D::getCofacets(int cellDim, int cellLID,
00452                  int cofacetDim, Array<int>& cofacetLIDs) const {
00453   // Nothing to do
00454     TEST_FOR_EXCEPTION(true, InternalError," HNMesh2D::getCofacets() not implemented");
00455 }
00456 
00457 
00458 void HNMesh2D::getMaxCofacetLIDs(const Array<int>& cellLIDs,
00459   MaximalCofacetBatch& cofacets) const {
00460   // nothing to do here
00461     TEST_FOR_EXCEPTION(true, InternalError," HNMesh2D::getMaxCofacetLIDs() not implemented");
00462 }
00463 
00464 
00465 int HNMesh2D::mapGIDToLID(int cellDim, int globalIndex) const  {
00466   //SUNDANCE_VERB_HIGH("mapGIDToLID()");
00467   switch (cellDim){
00468   case 0:{
00469            int ID = vertexLeafToGIDMapping_[globalIndex];
00470          SUNDANCE_MSG3(verb() , " HNMesh2D::mapGIDToLID 0 , globalIndex:" << globalIndex << " ,ID:" << ID << ", ret:"<< vertexLIDToLeafMapping_[ID]);
00471            return vertexLIDToLeafMapping_[ID];
00472         break;}
00473   case 1:{
00474          int ID = edgeLeafToGIDMapping_[globalIndex];
00475          SUNDANCE_MSG3(verb() , " HNMesh2D::mapGIDToLID 1 , globalIndex:" << globalIndex << " ,ID:" << ID << ", ret:"<< edgeLIDToLeafMapping_[ID]);
00476          return edgeLIDToLeafMapping_[ID];
00477         break;}
00478   case 2:{
00479              int ID = cellLeafToGIDMapping_[globalIndex];
00480              SUNDANCE_MSG3(verb() , " HNMesh2D::mapGIDToLID 2 , globalIndex:" << globalIndex << " ,ID:" << ID << ", ret:"<< cellLIDToLeafMapping_[ID]);
00481              return cellLIDToLeafMapping_[ID];
00482         break;}
00483   }
00484   return -1; //Wall
00485 }
00486 
00487 
00488 bool HNMesh2D::hasGID(int cellDim, int globalIndex) const {
00489   //SUNDANCE_VERB_HIGH("hasGID()");
00490   // we should always have all GIDs
00491   return true;
00492 }
00493 
00494 
00495 int HNMesh2D::mapLIDToGID(int cellDim, int localIndex) const  {
00496   //SUNDANCE_VERB_HIGH("mapLIDToGID()");
00497   switch (cellDim){
00498   case 0:{
00499            int ID = vertexLeafToLIDMapping_[localIndex];
00500          SUNDANCE_MSG3(verb() , " HNMesh2D::mapLIDToGID 0 , localIndex:" << localIndex << " ,ID:" << ID << ", ret:"<< vertexGIDToLeafMapping_[ID]);
00501            return vertexGIDToLeafMapping_[ID];
00502         break;}
00503   case 1:{
00504          int ID = edgeLeafToLIDMapping_[localIndex];
00505          SUNDANCE_MSG3(verb() , " HNMesh2D::mapLIDToGID 1 , localIndex:" << localIndex << " ,ID:" << ID << ", ret:"<< edgeGIDToLeafMapping_[ID]);
00506          return edgeGIDToLeafMapping_[ID];
00507         break;}
00508   case 2:{
00509              int ID = cellLeafToLIDMapping_[localIndex];
00510              SUNDANCE_MSG3(verb() , " HNMesh2D::mapLIDToGID 2 , localIndex:" << localIndex << " ,ID:" << ID << ", ret:"<< cellGIDToLeafMapping_[ID]);
00511              return cellGIDToLeafMapping_[ID];
00512         break;}
00513   }
00514   return -1; //Wall
00515 }
00516 
00517 
00518 CellType HNMesh2D::cellType(int cellDim) const  {
00519    switch(cellDim)
00520     {
00521       case 0:  return PointCell;
00522       case 1:  return LineCell;
00523       case 2:  return QuadCell;
00524       default:
00525         return NullCell; // -Wall
00526     }
00527 }
00528 
00529 
00530 int HNMesh2D::label(int cellDim, int cellLID) const {
00531    // not used
00532    TEST_FOR_EXCEPTION(true, InternalError," HNMesh2D::label() not implemented yet");
00533    return 0;
00534 }
00535 
00536 
00537 void HNMesh2D::getLabels(int cellDim, const Array<int>& cellLID,
00538     Array<int>& labels) const {
00539    // not used
00540    TEST_FOR_EXCEPTION(true, InternalError," HNMesh2D::getLabels() not implemented yet");
00541 }
00542 
00543 Set<int> HNMesh2D::getAllLabelsForDimension(int cellDim) const {
00544    Set<int>                 rtn;
00545    // not used
00546    TEST_FOR_EXCEPTION(true, InternalError," HNMesh2D::getAllLabelsForDimension() not implemented yet");
00547    return rtn;
00548 }
00549 
00550 void HNMesh2D::getLIDsForLabel(int cellDim, int label, Array<int>& cellLIDs) const {
00551     // not used
00552   TEST_FOR_EXCEPTION(true, InternalError," HNMesh2D::getLIDsForLabel() not implemented yet");
00553 }
00554 
00555 void HNMesh2D::setLabel(int cellDim, int cellLID, int label) {
00556    // not used
00557    TEST_FOR_EXCEPTION(true, InternalError," HNMesh2D::setLabel() not implemented yet");
00558 }
00559 
00560 
00561 void HNMesh2D::assignIntermediateCellGIDs(int cellDim) {
00562   // The GIDs are assigned
00563   //SUNDANCE_VERB_HIGH("assignIntermediateCellGIDs()");
00564 }
00565 
00566 
00567 bool HNMesh2D::hasIntermediateGIDs(int dim) const {
00568   //SUNDANCE_VERB_HIGH("hasIntermediateGIDs()");
00569   // the mesh always has intermediate cells
00570   return true; // true means they have been synchronized ... not used now
00571 }
00572 
00573 
00574 // =============================== HANGING NODE FUNCTIONS ==========================
00575 bool HNMesh2D::isElementHangingNode(int cellDim , int cellLID) const {
00576   SUNDANCE_MSG3(verb() ,"HNMesh2D::isElementHangingNode  cellDim:"<<cellDim<<" LID:"<< cellLID);
00577   if (cellDim==0) { // 1 dimension
00578       int LID = vertexLeafToLIDMapping_[cellLID];
00579     return (isPointHanging_[LID]);
00580     }
00581     else if (cellDim==1) { // 2 dimensions
00582       int LID = edgeLeafToLIDMapping_[cellLID];
00583         return (isEdgeHanging_[LID]);
00584     } else {
00585   return false; //Wall
00586     }
00587   return false; //Wall
00588 }
00589 
00590 int HNMesh2D::indexInParent(int maxCellLID) const {
00591   // this is just a mapping from the HNMesh2D child numbering to the DoFMapHN child numbering in 3D
00592   int mapMyChilderIndexToStandardDoFMAP[9] = {0,5,6,1,4,7,2,3,8};
00593   int LID = cellLeafToLIDMapping_[maxCellLID];
00594   int indexInPar = indexInParent_[LID];
00595   //map to the trisection standard which is used to the DoFMaps STANDARD NUMBERING(PEANO CURVE) !
00596   return mapMyChilderIndexToStandardDoFMAP[indexInPar];
00597 }
00598 
00599 void HNMesh2D::returnParentFacets(  int childCellLID , int dimFacets ,
00600                              Array<int> &facetsLIDs , int &parentCellLIDs ) const {
00601   int LID = cellLeafToLIDMapping_[childCellLID];
00602   parentCellLIDs = parentCellLID_[LID];
00603   facetsLIDs.resize(4);
00604   SUNDANCE_MSG3(verb() , "HNMesh2D::returnParentFacets  childCellLID:"<<childCellLID<<" dimFacets:"<<dimFacets<<
00605       "  parentCellLIDs:"<< parentCellLIDs);
00606   // this is the same for edges and for points
00607   facetsLIDs[0] = facetLID_tree( 2 , parentCellLIDs ,  dimFacets , 0 );
00608   facetsLIDs[1] = facetLID_tree( 2 , parentCellLIDs ,  dimFacets , 1 );
00609   facetsLIDs[2] = facetLID_tree( 2 , parentCellLIDs ,  dimFacets , 2 );
00610   facetsLIDs[3] = facetLID_tree( 2 , parentCellLIDs ,  dimFacets , 3 );
00611   // map parent cell ID back to leaf indexing
00612   parentCellLIDs = cellLIDToLeafMapping_[parentCellLIDs];
00613 }
00614 
00615 // only used in determining the parents
00616 int HNMesh2D::facetLID_tree(int cellDim, int cellLID,
00617                      int facetDim, int facetIndex) const{
00618     int rnt = -1;
00619   if (facetDim == 0){ // return the Number/ID of a Vertex
00620        rnt = cellsPoints_[cellLID][facetIndex];
00621        rnt = vertexLIDToLeafMapping_[rnt];
00622        // rnt must be greater than 0
00623   } else if (facetDim == 1){
00624        rnt = cellsEdges_[cellLID][facetIndex];
00625        rnt = edgeLIDToLeafMapping_[rnt];
00626        // rnt must be greater than 0
00627   }
00628   SUNDANCE_MSG3(verb() , "HNMesh2D::facetLID_tree cellDim:"<<cellDim<<", cellLID:"<<cellLID<<", facetDim:"<<facetDim<<
00629       ", facetIndex:"<<facetIndex<<" RET = " << rnt );
00630   return rnt;
00631 }
00632 
00633 // =========================== MESH CREATION ========================================
00634 
00635 /** adds one vertex to the mesh */
00636 void HNMesh2D::addVertex(int vertexLID , int ownerProc , bool isHanging ,
00637      double coordx , double coordy , const Array<int> &maxCoF){
00638   // add only when the LID is new
00639   // WE ASSUME THAT THE "vertexLID" will come in increasing manner
00640   if (points_.size() <= vertexLID){
00641    TEST_FOR_EXCEPTION(vertexLID != nrElem_[0] , InternalError ,"HNMesh2D::addVertex " <<
00642        " vertexLID:" << vertexLID << " nrElem_[0]:" << nrElem_[0] );
00643      Point pt(coordx,coordy);
00644      points_.append( pt );
00645      pointMaxCoF_.append( maxCoF );
00646      isPointHanging_.append( isHanging );
00647      elementOwner_[0].append( ownerProc );
00648      SUNDANCE_MSG3(verb() , "HNMesh2D::addVertex: " << nrElem_[0] << " P:" << pt << " ,  maxCoF:" << maxCoF);
00649      SUNDANCE_MSG3(verb() , " ownerProc:" << ownerProc << " , isHanging:" << isHanging);
00650      nrElem_[0]++;
00651   }
00652 }
00653 
00654 /** adds one edge to the mesh */
00655 void HNMesh2D::addEdge(int edgeLID , int ownerProc , bool isHanging , int edgeVertex ,
00656                    bool isProcBoundary , bool isMeshBoundary ,
00657                    const Array<int> &vertexLIDs , const Array<int> &maxCoF){
00658     // add only when the edgeLID is new
00659     if (edgePoints_.size() <= edgeLID ){
00660      TEST_FOR_EXCEPTION(edgeLID != nrElem_[1], InternalError, "HNMesh2D::addEdge edgeLID != nrElem_[1]");
00661      edgePoints_.append( vertexLIDs );
00662      edgeVertex_.append( edgeVertex );
00663      edgeMaxCoF_.append( maxCoF );
00664      edgeIsProcBonudary_.append( isProcBoundary );
00665      edgeIsMeshDomainBonudary_.append( isMeshBoundary );
00666      isEdgeHanging_.append(isHanging);
00667        elementOwner_[1].append( ownerProc );
00668        SUNDANCE_MSG3(verb() , "HNMesh2D::addEdge: " << nrElem_[1] << " vertexLIDs:" << vertexLIDs << " ,  maxCoF:" << maxCoF );
00669        SUNDANCE_MSG3(verb() , "          ownerProc:" << ownerProc << ", isHanging:" << isHanging << ", edgeVertex:" << edgeVertex <<
00670            ", isProcBoundary:" << isProcBoundary << ", isMeshBoundary:" << isMeshBoundary);
00671        nrElem_[1]++;
00672     }
00673 }
00674 
00675 /** adds one cell(2D) to the mesh */
00676 void HNMesh2D::addCell(int cellLID , int ownerProc ,
00677                    int indexInParent , int parentCellLID , int level ,
00678                    const Array<int> &edgeLIDs , const Array<int> &vertexLIDs){
00679     // add only when the edgeLID is new
00680     if (cellsPoints_.size() <= cellLID ) {
00681      TEST_FOR_EXCEPTION(cellLID != nrElem_[2], InternalError, "HNMesh2D::cellLID cellLID != nrElem_[2]");
00682      cellsPoints_.append( vertexLIDs );
00683      cellsEdges_.append( edgeLIDs );
00684        indexInParent_.append( indexInParent );
00685        parentCellLID_.append( parentCellLID );
00686        cellLevel_.append( level );
00687        isCellLeaf_.append( true );
00688        refineCell_.append( 0 );
00689        cellsChildren_.append( tuple(1) );
00690        elementOwner_[2].append( ownerProc );
00691        SUNDANCE_MSG3(verb() , "HNMesh2D::addCell: " << nrElem_[2] << " vertexLIDs:" << vertexLIDs << " edgeLIDs:" << edgeLIDs);
00692        SUNDANCE_MSG3(verb() , "HNMesh2D::addCell p0:" << points_[vertexLIDs[0]] );
00693        SUNDANCE_MSG3(verb() , "HNMesh2D::addCell p1:" << points_[vertexLIDs[1]] );
00694        SUNDANCE_MSG3(verb() , "HNMesh2D::addCell p2:" << points_[vertexLIDs[2]] );
00695        SUNDANCE_MSG3(verb() , "HNMesh2D::addCell p3:" << points_[vertexLIDs[3]] );
00696      // calculate if the cell is complete outside the mesh domain
00697      isCellOut_.append( !( meshDomain_.isInsideComputationalDomain(points_[vertexLIDs[0]]) ||
00698                        meshDomain_.isInsideComputationalDomain(points_[vertexLIDs[1]]) ||
00699                        meshDomain_.isInsideComputationalDomain(points_[vertexLIDs[2]]) ||
00700                        meshDomain_.isInsideComputationalDomain(points_[vertexLIDs[3]]) ) );
00701      SUNDANCE_MSG3(verb() , "HNMesh2D::addCell IN DOMAIN:" <<  isCellOut_[nrElem_[2]] );
00702        nrElem_[2]++;
00703     }
00704 }
00705 
00706 /** creates one regular mesh without refinement. With a different function the
00707  * refinement can start later , independently from this function. <br>
00708  * The structure of this mesh also supports unstructured storage of the cells,
00709  * so we might create unstructured mesh and later refine in the same way */
00710 void HNMesh2D::createMesh(
00711                       double position_x,
00712                 double position_y,
00713                 double offset_x,
00714                 double offset_y,
00715                 int resolution_x,
00716                 int resolution_y,
00717                 const RefinementClass& refineClass ,
00718                 const MeshDomainDef& meshDomain
00719 ){
00720 
00721   setVerbosity(0);
00722 
00723   // initialize object fields
00724   _pos_x = position_x; _pos_y = position_y;
00725   _ofs_x = offset_x; _ofs_y = offset_y;
00726   _res_x = resolution_x; _res_y = resolution_y;
00727   refineClass_ = refineClass;
00728   meshDomain_ = meshDomain;
00729 
00730   // create coarsest mesh
00731   createCoarseMesh();
00732 
00733   // loop as long there is no refinement
00734     bool doRefinement = true;
00735     while (doRefinement){
00736       doRefinement = oneRefinementIteration();
00737     }
00738 
00739   // calculate global IDs and create leaf Numbering
00740     createLeafNumbering();
00741 
00742 }
00743 
00744 void HNMesh2D::createCoarseMesh(){
00745   // estimate load for parallel case,
00746   // assign cells to each processors, based on the load and the domain
00747   // we assign cells to processors, (y,x) (optimal for vertical channel flow)
00748   // the estimation is done in each processor, globally but then only the local mesh will be build
00749   int nrCoarseCell = _res_x*_res_y;
00750   int nrCoarsePoints = (_res_x+1)*(_res_y+1);
00751   int nrCoarseEdge = (_res_x+1)*_res_y + _res_x*(_res_y+1);
00752   Array<int> coarseProcessCell( nrCoarseCell , -1 );
00753   Array<int> coarseCellOwner( nrCoarseCell , -1 );
00754   Array<int> coarsePointOwner( nrCoarsePoints , -1 );
00755   Array<int> coarseEdgeOwner( nrCoarseEdge , -1 );
00756   Array<int> coarseCellLID( nrCoarseCell , -1 );
00757   Array<int> coarsePointLID( nrCoarsePoints , -1 );
00758   Array<int> coarseEdgeLID( nrCoarseEdge , -1 );
00759   Array<int> coarseCellsLoad( nrCoarseCell , 0 );
00760   int totalLoad = 0;
00761 
00762   SUNDANCE_MSG3(verb() , "HNMesh2D::createMesh nrCoarseCell:" << nrCoarseCell << " nrCoarsePoints:" << nrCoarsePoints
00763                 << " nrCoarseEdge:" << nrCoarseEdge << " nrProc_:" << nrProc_ << " myRank_:" << myRank_);
00764   TEST_FOR_EXCEPTION( nrCoarseCell < nrProc_ , InternalError," HNMesh2D::createMesh nrCoarseCell < nrProc_ ");
00765   // now always divide as a flow channel , no resolution driven division
00766 
00767     // calculate total load and load per coarse cell
00768   double h[2];
00769   h[0] = _ofs_x/(double)_res_x; h[1] = _ofs_y/(double)_res_y;
00770   Point pos(h[0],h[1]);
00771   Point res(h[0],h[1]);
00772   // estimate total estimated load of the mesh
00773   for (int i=0; i < nrCoarseCell; i++){
00774     // midpoint of the cell
00775     pos[0] = _pos_x + (double)(i / _res_y)*h[0] + 0.5*h[0];
00776     pos[1] = _pos_y + (double)(i % _res_y)*h[1] + 0.5*h[1];
00777     // todo: take the domain in consideration (take the 4 points) (when cells are turned off)
00778     coarseCellsLoad[i] = refineClass_.estimateRefinementLevel( pos , res );
00779     totalLoad += coarseCellsLoad[i];
00780   }
00781   // calculate average load per cell
00782   double loadPerProc = (double)totalLoad / (double)nrProc_;
00783   int actualProc=0;
00784   totalLoad = 0;
00785   Array<int>  ind(2); // vertex is mesh boundary
00786   // offsets for vertex and edge index
00787   int vertexOffs[4] = {0 , _res_y + 1 , 1 ,  _res_y + 2};
00788   int edgeOffs[4] = {_res_y , 0 , 2*_res_y + 1 , _res_y + 1};
00789 
00790   // assign owners to the cells, edges, vertexes , greedy method
00791   SUNDANCE_MSG3(verb() , "Processor asign, loadPerProc:" << loadPerProc );
00792   double diff_load = 0.0;
00793   for (int i=0; i < nrCoarseCell; i++){
00794     ind[0] = (i / _res_y);
00795     ind[1] = (i % _res_y);
00796     int vertexInd = (_res_y+1)*ind[0] + ind[1];
00797     int edgeInd = (2*_res_y+1)*ind[0] + ind[1];
00798     //SUNDANCE_MSG3(verb() , "Cell ID:" << i << " vertexInd:" <<vertexInd << " edgeInd:" << edgeInd );
00799     //SUNDANCE_MSG3(verb() , "Cell, actual index" << ind  );
00800     // assign ownership for vertexes
00801     for (int jj = 0 ; jj < 4 ; jj++){
00802       if (coarsePointOwner[vertexInd+vertexOffs[jj]] < 0){
00803         coarsePointOwner[vertexInd+vertexOffs[jj]] = actualProc;
00804         SUNDANCE_MSG3(verb() , "Vertex CPU assign " << vertexInd+vertexOffs[jj] << " ->" << actualProc );
00805       }
00806     }
00807     // assign ownership for edges
00808     for (int jj = 0 ; jj < 4 ; jj++){
00809       if (coarseEdgeOwner[edgeInd+edgeOffs[jj]] < 0){
00810         coarseEdgeOwner[edgeInd+edgeOffs[jj]] = actualProc;
00811         //SUNDANCE_MSG3(verb() , "Edge CPU assign " << edgeInd+edgeOffs[jj] << " ->" << actualProc );
00812       }
00813     }
00814     // assign ownership for the cell
00815     coarseCellOwner[i] = actualProc;
00816     totalLoad += coarseCellsLoad[i];
00817     SUNDANCE_MSG3(verb() , "Cell CPU assign " << i << " ->" << actualProc <<
00818         ", totalLoad:" << totalLoad << " loadPerProc:" << loadPerProc);
00819     // the rounding of the load estimator is in favor to late earlier
00820     if (((double)totalLoad >= (loadPerProc - 1e-8 - diff_load)) && ( actualProc < nrProc_-1 )){
00821       SUNDANCE_MSG3(verb() , "Increase CPU , totalLoad:" << totalLoad << " loadPerProc:" << loadPerProc );
00822       // compensate the load difference for the next CPU
00823       diff_load = totalLoad - loadPerProc;
00824       actualProc = actualProc + 1;
00825       totalLoad = 0;
00826     }
00827   }
00828 
00829   // next step is to see which cell we will process (we also have to add the remote cells)
00830   for (int i=0; i < nrCoarseCell; i++){
00831     ind[0] = (i / _res_y);
00832     ind[1] = (i % _res_y);
00833     coarseProcessCell[i] = 1;
00834   }
00835 
00836   // now go trough all cells which have to be added to this processor
00837   SUNDANCE_MSG3(verb() , " Process Cells:" << nrCoarseCell );
00838   for (int i=0; i < nrCoarseCell; i++){
00839     ind[0] = (i / _res_y);
00840     ind[1] = (i % _res_y);
00841     pos[0] = _pos_x + (double)(ind[0])*h[0];
00842     pos[1] = _pos_y + (double)(ind[1])*h[1];
00843     SUNDANCE_MSG3(verb() , "PCell ID:" << i << " coarseProcessCell[i]:" <<coarseProcessCell[i] << " pos:" << pos );
00844     SUNDANCE_MSG3(verb() , "PCell, actual index" << ind  );
00845     // this condition is so that remote cells will be added
00846     if (coarseProcessCell[i] > 0){
00847       int vertexInd = (_res_y+1)*ind[0] + ind[1];
00848       int edgeInd = (2*_res_y+1)*ind[0] + ind[1];
00849       int cellLID = coarseCellLID[i];
00850       Array<int> vertexLID(4,-1) , vertexMaxCoF(4,-1) , vLID(4,-1);;
00851       Array<int> edgeLID(4,-1) , edgeVert(2,-1) , edgeMaxCoef(2,-1);
00852       //SUNDANCE_MSG3(verb() , "Cell ID:" << i << " vertexInd:" <<vertexInd << " edgeInd:" << edgeInd << " cellLID:" << cellLID);
00853       //SUNDANCE_MSG3(verb() , "Cell, actual index" << ind << " pos:" << pos);
00854       // assign new cellID if necessary
00855       if (coarseCellLID[i] < 0 ){
00856         coarseCellLID[i] = nrElem_[2];
00857         cellLID = coarseCellLID[i];
00858       }
00859       // add all Vertexes , ignoring neighbor cells (maxcofacets)
00860             for (int jj = 0 ; jj < 4 ; jj++){
00861               vLID[jj] = coarsePointLID[vertexInd+vertexOffs[jj]];
00862               //SUNDANCE_MSG3(verb() , "Vertex  vertexInd:" << vertexInd);
00863               //SUNDANCE_MSG3(verb() , "Vertex  vertexOffs[jj]:" << vertexOffs[jj]);
00864               //SUNDANCE_MSG3(verb() , "Vertex  index:" << vertexInd+vertexOffs[jj]);
00865               if (coarsePointLID[vertexInd+vertexOffs[jj]] < 0){
00866                 coarsePointLID[vertexInd+vertexOffs[jj]] = nrElem_[0];
00867               }
00868               vLID[jj] = coarsePointLID[vertexInd+vertexOffs[jj]];
00869                 // add vertex with -1 maxCOfacets
00870               //SUNDANCE_MSG3(verb() , "Vertex  X:" << ((double)offs_Points_x_[jj])*h[0] << "  Y:" << pos[1] + ((double)offs_Points_y_[jj])*h[1]);
00871               //SUNDANCE_MSG3(verb() , "Vertex  vLID[jj]:" << vLID[jj] << "  , coarsePointOwner[vertexInd+vertexOffs[jj]]" << coarsePointOwner[vertexInd+vertexOffs[jj]] );
00872               addVertex( vLID[jj] , coarsePointOwner[vertexInd+vertexOffs[jj]] , false ,
00873                      pos[0] + ((double)offs_Points_x_[jj])*h[0] , pos[1] + ((double)offs_Points_y_[jj])*h[1] ,
00874                          vertexMaxCoF );
00875             }
00876       // add all Edges , ignoring neighbor cells (maxcofacets)
00877             for (int jj = 0 ; jj < 4 ; jj++){
00878               edgeLID[jj] = coarseEdgeLID[edgeInd+edgeOffs[jj]];
00879               if (coarseEdgeLID[edgeInd+edgeOffs[jj]] < 0){
00880                 coarseEdgeLID[edgeInd+edgeOffs[jj]] = nrElem_[1];
00881               }
00882               edgeLID[jj] = coarseEdgeLID[edgeInd+edgeOffs[jj]];
00883               edgeVert[0] = vLID[edge_Points_localIndex[jj][0]];
00884               edgeVert[1] = vLID[edge_Points_localIndex[jj][1]];
00885                 // add edge with -1 maxCOfacets
00886               addEdge( edgeLID[jj] , coarseEdgeOwner[edgeInd+edgeOffs[jj]] , false , (jj==0 || jj==3) ? 0 : 1 ,
00887                             false , false , // these two flags later need to be updated
00888                           edgeVert , edgeMaxCoef );
00889             }
00890       // add the Cell
00891             addCell( cellLID , coarseCellOwner[i] , 0 , cellLID , 0 , edgeLID , vLID);
00892     }
00893   } // --- end from for loop
00894 
00895   // next is maxCoFacet and boundary info update for vertexes and edges
00896   SUNDANCE_MSG3(verb() , " Process maxCofacets:" << nrCoarseCell );
00897   for (int i=0; i < nrCoarseCell; i++){
00898     // this condition is so that remote cells will be added
00899     if (coarseProcessCell[i] > 0){
00900       Array<int> vLID(4,-1) , eLID(4,-1) , maxVertexCoF(4,-1);
00901       ind[0] = (i / _res_y);
00902       ind[1] = (i % _res_y);
00903       int vertexInd = (_res_y+1)*ind[0] + ind[1];
00904       int edgeInd = (2*_res_y+1)*ind[0] + ind[1];
00905       int cellLID = coarseCellLID[i];
00906       SUNDANCE_MSG3(verb() , "MCell cellLID:" << cellLID << " coarseProcessCell[i]:" <<coarseProcessCell[i] );
00907       //SUNDANCE_MSG3(verb() , "MCell ID:" << i << " vertexInd:" <<vertexInd << " edgeInd:" << edgeInd );
00908       //SUNDANCE_MSG3(verb() , "MCell, actual index" << ind  );
00909       // vertex maxCoFac
00910             for (int jj = 0 ; jj < 4 ; jj++){
00911               vLID[jj] = coarsePointLID[vertexInd+vertexOffs[jj]];
00912               // if all elements are added then this is OK
00913               pointMaxCoF_[vLID[jj]][jj] = cellLID;
00914               SUNDANCE_MSG3(verb() , "Vertex MaxCoFacet vLID[jj]:" << vLID[jj] << " jj:" << jj << " cellLID:" << cellLID );
00915             }
00916             // edge maxCoFac
00917             for (int jj = 0 ; jj < 4 ; jj++){
00918               eLID[jj] = coarseEdgeLID[edgeInd+edgeOffs[jj]];
00919               // if all elements are added then this is OK
00920               edgeMaxCoF_[eLID[jj]][(3-jj)/2] = cellLID;
00921               SUNDANCE_MSG3(verb() , "Edge MaxCoFacet eLID[jj]:" << eLID[jj] << " (3-jj)/2:" << (3-jj)/2 << " cellLID:" << cellLID );
00922               // update boundary info of the edge
00923               int orientation = ( (jj==0) || (jj==3)) ? 1 : 0;
00924 
00925               if (orientation == 0){ // vertical edge
00926                  // mesh boundary
00927                    if ( (ind[0] == 0) && (jj==1))   edgeIsMeshDomainBonudary_[eLID[jj]] = true;
00928                    if ( (ind[0] == _res_x - 1 ) && (jj==2))   edgeIsMeshDomainBonudary_[eLID[jj]] = true;
00929                    // process boundary
00930                    if ( edgeIsMeshDomainBonudary_[eLID[jj]] != true){
00931                      // now here is dummy implementation
00932                        edgeIsProcBonudary_[eLID[jj]] = false; //(bool)(edgeOwner != edgeOwnerN);
00933                    }
00934               }else{ // horizontal edge
00935                  // mesh boundary
00936                    if ( (ind[1] == 0) && (jj==0))  { edgeIsMeshDomainBonudary_[eLID[jj]] = true; }
00937                    if ( (ind[1] == _res_y - 1 ) && (jj==3))  { edgeIsMeshDomainBonudary_[eLID[jj]] = true; }
00938                    // process boundary
00939                    if ( edgeIsMeshDomainBonudary_[eLID[jj]] != true){
00940                      // now there is only the dummy implementation
00941                        edgeIsProcBonudary_[eLID[jj]] = false; //(bool)(edgeOwner != edgeOwnerN);
00942                    }
00943                    SUNDANCE_MSG3(verb() , "Neighb. H  Cell DONE ");
00944               }
00945             }
00946     }
00947   }
00948   // basic rectangular mesh is build
00949 }
00950 
00951 // -----------
00952 bool HNMesh2D::oneRefinementIteration(){
00953 
00954   Array<int> ind(2);
00955     int nrActualCell = nrElem_[2];
00956     bool rtn = false;
00957     SUNDANCE_MSG3(verb() , " HNMesh2D::oneRefinementIteration, start one refinement iteration cycle ");
00958     // we iterate only over the existing cells (not the ones which will be later created)
00959   for (int i=0 ; i < nrActualCell ; i++){
00960 
00961     ind[0] = (i / _res_y);
00962     ind[1] = (i % _res_y);
00963 
00964     // cell is owned by the current processor, and is leaf and is inside the mesh domain
00965       SUNDANCE_MSG3(verb() , " Test cell " << i << ", elementOwner_[2][i]:" << elementOwner_[2][i] <<
00966                          ", isCellLeaf_[i]:" << isCellLeaf_[i] << ", out:" << (!isCellOut_[i]));
00967 
00968     if ( (isCellLeaf_[i] == true) )
00969       //(elementOwner_[2][i] == myRank_) && (isCellLeaf_[i] == true) )
00970       //( (elementOwner_[2][i] == myRank_) && (isCellLeaf_[i] == true) && (!isCellOut_[i]))
00971       //  mark neighbors for refinements if because of the hanging nodes a refinement is not possible, regardless of the IN or OUT of Mesh domain
00972     {
00973       // check if refinement is needed and possible, none of the vertexes can be hanging
00974       Array<int>& cellsEdges = cellsEdges_[i];
00975             bool doRefined = true;
00976             bool refFunction = false;
00977             for (int jj = 0 ; jj < cellsEdges.size() ; jj++){
00978               SUNDANCE_MSG3(verb() , " eLID: " << cellsEdges[jj] << ", isHanging:" << isEdgeHanging_[cellsEdges[jj]]);
00979               doRefined = ( doRefined && ((isEdgeHanging_[cellsEdges[jj]]) == false) );
00980             }
00981             // --- if refinement is possible
00982             SUNDANCE_MSG3(verb() , " is possible to refine cell nr: " << i << ", doRefined:" << doRefined);
00983             // call refinement function
00984       Array<int>& cellsVertex = cellsPoints_[i];
00985       Point h = points_[cellsVertex[3]] - points_[cellsVertex[0]];
00986       Point p2 = points_[cellsVertex[0]] + 0.5*h;
00987       refFunction = ((refineCell_[i] == 1) || refineClass_.refine( cellLevel_[i] , p2 , h ));
00988 
00989             // decide if we refine this cell
00990             SUNDANCE_MSG3( verb() , " execute refinement on cell nr: " << i << ", refFunction:" << refFunction);
00991             if (doRefined && refFunction)
00992             {
00993               // -- call the function to refine the actual cell ---
00994               refineCell(i);
00995               rtn = true;
00996               refineCell_[i] = 0;
00997             }
00998             else
00999             {
01000               // Cell can not be refined
01001                 // we mark neighbor cells, based on "refFunction"
01002               if (refFunction){
01003                 //SUNDANCE_MSG3( verb() , " HNMesh2D::oneRefinementIteration mark neighbor cells ");
01004                     for (int jj = 0 ; jj < cellsEdges.size() ; jj++){
01005                       if (isEdgeHanging_[cellsEdges[jj]]){
01006                         //SUNDANCE_MSG3( verb() , " HNMesh2D::oneRefinementIteration isEdgeHanging_[cellsEdges[jj]] == true , " << jj);
01007                         // get the parent cell
01008                         int cLevel = cellLevel_[i];
01009                         int parentID = parentCellLID_[i];
01010                         int parentCEdge = cellsEdges_[parentID][jj];
01011                         int refCell = -1;
01012                         // look for maxCoFacets
01013                         if ( (jj == 0) || ( jj == 1) )
01014                           refCell = edgeMaxCoF_[parentCEdge][0];
01015                         else
01016                           refCell = edgeMaxCoF_[parentCEdge][1];
01017                         // refCell should be refined and mark for refinement
01018                         //SUNDANCE_MSG3( verb() , " cLevel:" << cLevel << " parentID:" << parentID << " parentCEdge:" << parentCEdge
01019                         //    << " refCell:" << refCell );
01020                         //SUNDANCE_MSG3( verb() ," edgeMaxCoF_[parentCEdge]:" << edgeMaxCoF_[parentCEdge]);
01021                             if ( (refCell >= 0) && (cellLevel_[refCell] < cLevel) && (isCellLeaf_[refCell])){
01022 
01023                               refineCell_[refCell] = 1;
01024                               rtn = true;
01025                               //SUNDANCE_MSG3( verb() , " HNMesh2D::oneRefinementIteration refineCell_[refCell] = 1 , " << refCell
01026                               //    << ", cellLevel_[refCell]:" << cellLevel_[refCell]);
01027                             }
01028                       }
01029                     }
01030               }
01031             }
01032     }
01033   }
01034 
01035   //  -> communicate with neighbor processor
01036   //     not needed if the mesh exist globally
01037 
01038   SUNDANCE_MSG3(verb() , " HNMesh2D::oneRefinementIteration DONE with one refinement iteration");
01039   // return if there was refinement or attempt to refine
01040   return rtn;
01041 }
01042 
01043 // -------- refine cell cellID (assuming all conditions are satisfied)--
01044 void HNMesh2D::refineCell(int cellLID){
01045     // data initialization
01046   Array<int>& cellsEdges = cellsEdges_[cellLID];
01047   Array<int>& cellsVertex = cellsPoints_[cellLID];
01048   int cellOwner = elementOwner_[2][cellLID];
01049   Point p = points_[cellsVertex[0]];
01050   Point h = points_[cellsVertex[3]] - points_[cellsVertex[0]];
01051     // the X and the Y coordinates of the newly
01052   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 ,
01053                       2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 1.0 , 1.0 , 1.0 , 1.0 };
01054   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 ,
01055                       0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 , 0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 };
01056     // if we have pre stored  hanging edge , we might just load them and these are the indexes (in 3X3 refinement)
01057   int hanginEdgeI[4][3] = { {3,10,17} , {0,1,2} , {21,22,23} , {6,13,20} };
01058   // existing vertexes and their index in the 3X3 cell refinement
01059   int hanginVertexI[4][2] = { {4,8} , {1,2} , {13,14} , {7,11} };
01060   // orientation of the newly (or existing) edges
01061   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};
01062   // the index in the vertex for one edge where the existing elements are stored
01063   int VertexIndex[4] = { 0 , 1 , 1 , 0 };
01064   // for each edge (where the existing vertexes are stored)
01065   int VertexI[4] = { 0 , 0 , 1 , 2 };
01066 
01067     // vertex info , owner of the new vertexes
01068   int vertexOwner[16] = { elementOwner_[0][cellsVertex[0]] , elementOwner_[1][cellsEdges[1]] ,
01069                       elementOwner_[1][cellsEdges[1]]  , elementOwner_[0][cellsVertex[2]] ,
01070                       elementOwner_[1][cellsEdges[0]]  , cellOwner , cellOwner , elementOwner_[1][cellsEdges[3]] ,
01071                       elementOwner_[1][cellsEdges[0]]  , cellOwner , cellOwner , elementOwner_[1][cellsEdges[3]] ,
01072                       elementOwner_[0][cellsVertex[1]] , elementOwner_[1][cellsEdges[2]] ,
01073                       elementOwner_[1][cellsEdges[2]]  , elementOwner_[0][cellsVertex[3]]  };
01074   // if vertex is hanging
01075   bool vertexIsHanging[16] = { false , !edgeIsMeshDomainBonudary_[cellsEdges[1]] , !edgeIsMeshDomainBonudary_[cellsEdges[1]], false ,
01076                            !edgeIsMeshDomainBonudary_[cellsEdges[0]] , false , false , !edgeIsMeshDomainBonudary_[cellsEdges[3]] ,
01077                            !edgeIsMeshDomainBonudary_[cellsEdges[0]] , false , false , !edgeIsMeshDomainBonudary_[cellsEdges[3]] ,
01078                                false , !edgeIsMeshDomainBonudary_[cellsEdges[2]] , !edgeIsMeshDomainBonudary_[cellsEdges[2]], false };
01079   // edge info
01080   int edgeOwner[24] = { elementOwner_[1][cellsEdges[1]] , elementOwner_[1][cellsEdges[1]] , elementOwner_[1][cellsEdges[1]] ,
01081                     elementOwner_[1][cellsEdges[0]] , cellOwner , cellOwner , elementOwner_[1][cellsEdges[3]] ,
01082                     cellOwner , cellOwner , cellOwner ,
01083                     elementOwner_[1][cellsEdges[0]] , cellOwner , cellOwner , elementOwner_[1][cellsEdges[3]] ,
01084                     cellOwner , cellOwner , cellOwner ,
01085                     elementOwner_[1][cellsEdges[0]] , cellOwner , cellOwner , elementOwner_[1][cellsEdges[3]] ,
01086                     elementOwner_[1][cellsEdges[2]] , elementOwner_[1][cellsEdges[2]] , elementOwner_[1][cellsEdges[2]]  };
01087   // edge hanging
01088   bool edgeIsHanging[24] = { !edgeIsMeshDomainBonudary_[cellsEdges[1]] , !edgeIsMeshDomainBonudary_[cellsEdges[1]] , !edgeIsMeshDomainBonudary_[cellsEdges[1]] ,
01089                          !edgeIsMeshDomainBonudary_[cellsEdges[0]] , false , false , !edgeIsMeshDomainBonudary_[cellsEdges[3]] ,
01090                              false , false , false ,
01091                              !edgeIsMeshDomainBonudary_[cellsEdges[0]] , false , false , !edgeIsMeshDomainBonudary_[cellsEdges[3]] ,
01092                              false , false , false ,
01093                              !edgeIsMeshDomainBonudary_[cellsEdges[0]] , false , false , !edgeIsMeshDomainBonudary_[cellsEdges[3]] ,
01094                              !edgeIsMeshDomainBonudary_[cellsEdges[2]] , !edgeIsMeshDomainBonudary_[cellsEdges[2]] , !edgeIsMeshDomainBonudary_[cellsEdges[2]] };
01095   // vertexes which form the new (or existing) edges
01096   int edgeVertexes[24][2] = { {0,1} , {1,2} , {2,3} , {0,4} , {1,5} , {2,6} , {3,7} , {4,5} , {5,6} , {6,7} ,
01097                         {4,8} , {5,9} , {6,10} , {7,11} , {8,9} , {9,10} , {10,11} ,
01098                         {8,12} , {9,13} , {10,14} , {11,15} , {12,13} , {13,14} , {14,15}};
01099   // if edge is processor boundary
01100   bool edgePBnd[24] = { edgeIsProcBonudary_[cellsEdges[1]] , edgeIsProcBonudary_[cellsEdges[1]] , edgeIsProcBonudary_[cellsEdges[1]] ,
01101                     edgeIsProcBonudary_[cellsEdges[0]] , false , false , edgeIsProcBonudary_[cellsEdges[3]] ,
01102                         false , false , false ,
01103                         edgeIsProcBonudary_[cellsEdges[0]] , false , false , edgeIsProcBonudary_[cellsEdges[3]] ,
01104                         false , false , false ,
01105                         edgeIsProcBonudary_[cellsEdges[0]] , false , false , edgeIsProcBonudary_[cellsEdges[3]] ,
01106                         edgeIsProcBonudary_[cellsEdges[2]] , edgeIsProcBonudary_[cellsEdges[2]] , edgeIsProcBonudary_[cellsEdges[2]] };
01107   // if edge is mesh boundary
01108   bool edgeMBnd[24] = { edgeIsMeshDomainBonudary_[cellsEdges[1]] , edgeIsMeshDomainBonudary_[cellsEdges[1]] , edgeIsMeshDomainBonudary_[cellsEdges[1]] ,
01109                     edgeIsMeshDomainBonudary_[cellsEdges[0]] , false , false , edgeIsMeshDomainBonudary_[cellsEdges[3]] ,
01110               false , false , false ,
01111               edgeIsMeshDomainBonudary_[cellsEdges[0]] , false , false , edgeIsMeshDomainBonudary_[cellsEdges[3]] ,
01112                           false , false , false ,
01113                           edgeIsMeshDomainBonudary_[cellsEdges[0]] , false , false , edgeIsMeshDomainBonudary_[cellsEdges[3]] ,
01114                           edgeIsMeshDomainBonudary_[cellsEdges[2]] , edgeIsMeshDomainBonudary_[cellsEdges[2]] , edgeIsMeshDomainBonudary_[cellsEdges[2]] };
01115   // vertex index in the 3X3 context which is needed for the cell creation
01116   int refinedCellsVertexes[9][4] = { {0,4,1,5} , {1,5,2,6} , {2,6,3,7} ,
01117                         {4,8,5,9} , {5,9,6,10} , {6,10,7,11} ,
01118                         {8,12,9,13} , {9,13,10,14} , {10,14,11,15} };
01119   // edge context in the 3X3 context, for cell creation
01120   int refinedCellsEdges[9][4] =   { {3,0,7,4} , {4,1,8,5} , {5,2,9,6} ,
01121                         {10,7,14,11} , {11,8,15,12} , {12,9,16,13} ,
01122                         {17,14,21,18} , {18,15,22,19} , {19,16,23,20} };
01123   // the index and offset to store the hanging nodes
01124   int hVertexIndex[16]       = { -1 , 0 , 1 , -1 , 0 , -1 , -1 , 0 , 1 , -1 , -1 , 1 , -1 , 0 , 1 , -1 };
01125   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 };
01126   int hVertexVertexIndex[16] = { -1 , 1 , 1 , -1 , 0 , -1 , -1 , 3 , 0 , -1 , -1 , 3 , -1 , 2 , 2 , -1 };
01127   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 };
01128 
01129   // cell index in the 3X3 for vertex maxCoFacets
01130   int vertexMaxCoFacet[16][4] = { {0,-1,-1,-1} , {1,-1,0,-1} , {2 ,-1,1,-1} , {-1,-1,2,-1} ,
01131                               {3,0,-1,-1} , {4,1,3,0}    , {5 ,2,4,1} , {-1,-1,5,2}    ,
01132                               {6,3,-1,-1} , {7,4,6,3}    , {8 ,5,7,4} , {-1,-1,8,5}    ,
01133                               {-1,6,-1,-1} , {-1,7,-1,6} , {-1,8,-1,7} , {-1,-1,-1,8}  };
01134   // there will be 9 newly created cells, these should be maxCoFactes in the vertexes and the edges
01135   int edgeMaxCoFacet[24][2] = { {-1,0} , {-1,1} , {-1,2} ,
01136                             {-1,0} , {0,1} , {1,2} , {2,-1} ,
01137                              {0,3} , {1,4} , {2,5} ,
01138                             {-1,3} , {3,4} , {4,5} , {5,-1} ,
01139                              {3,6} , {4,7} , {5,8} ,
01140                             {-1,6} , {6,7} , {7,8} , {8,-1} ,
01141                             {6,-1} , {7,-1} , {8,-1} };
01142   // we might need to copy the MaxCoFacet from the parent edge
01143   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 };
01144   // in which direction to look
01145   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 };
01146 
01147     // hanging elements information
01148   Array< Array<int> > hangingInfo(4);
01149   hangingInfo[0].resize(0); hangingInfo[1].resize(0); hangingInfo[2].resize(0); hangingInfo[3].resize(0);
01150 
01151     // the created vertex, edge and cell LIDs
01152     Array<int> vertexLIDs(16,-1);
01153     Array<int> edgeLIDs(24,-1);
01154     Array<int> cellLIDs(9,-1);
01155 
01156     SUNDANCE_MSG3(verb() , " ========== HNMesh2D::refineCell, cellLID:" << cellLID << " ==========");
01157     //SUNDANCE_MSG3( verb() , " cellsVertex:" << cellsVertex );
01158     // the 4 "corner" points are already created (according to refinement numbering!)
01159     vertexLIDs[0] = cellsVertex[0]; vertexLIDs[3] = cellsVertex[2];
01160     vertexLIDs[12] = cellsVertex[1]; vertexLIDs[15] = cellsVertex[3];
01161 
01162     // look for existing elements
01163     for (int v = 0 ; v < 4 ; v++){
01164       // look for already stored elements
01165       //SUNDANCE_MSG3( verb() , " Test vertex VertexIndex[v]:" << VertexIndex[v] << ", cellsVertex[VertexI[v]]:" << cellsVertex[VertexI[v]] );
01166       //SUNDANCE_MSG3( verb() , " hangElmStore_[VertexIndex[v]].size()" << hangElmStore_[VertexIndex[v]].size() );
01167       if (hangElmStore_[VertexIndex[v]].containsKey(cellsVertex[VertexI[v]])){
01168            const Array<int>& hnInfo = hangElmStore_[VertexIndex[v]].get(cellsVertex[VertexI[v]]);
01169            // this is the convention how we store the hanging info
01170            // these elements are not hanging after this
01171            //SUNDANCE_MSG3( verb() , " Found key: " << cellsVertex[VertexI[v]] << ", size:" << hnInfo.size() << " , array:" << hnInfo );
01172            vertexLIDs[hanginVertexI[v][0]] = hnInfo[0];  isPointHanging_[hnInfo[0]] = false;
01173            vertexLIDs[hanginVertexI[v][1]] = hnInfo[1];  isPointHanging_[hnInfo[1]] = false;
01174            edgeLIDs[hanginEdgeI[v][0]] = hnInfo[2];
01175            isEdgeHanging_[hnInfo[2]] = false;
01176            edgeLIDs[hanginEdgeI[v][1]] = hnInfo[3];
01177            isEdgeHanging_[hnInfo[3]] = false;
01178            edgeLIDs[hanginEdgeI[v][2]] = hnInfo[4];  isEdgeHanging_[hnInfo[4]] = false;
01179            // remove this from the tmp storage
01180            hangElmStore_[VertexIndex[v]].remove(cellsVertex[VertexI[v]]);
01181       }
01182     }
01183     SUNDANCE_MSG3(verb() , " refineCell bef. vertexLIDs:" << vertexLIDs );
01184     SUNDANCE_MSG3(verb() , " refineCell bef. edgeLIDs:" << edgeLIDs );
01185 
01186     // create all vertexes, those which are not created
01187     for (int v = 0 ; v < 16 ; v++){
01188       // create vertex if necessary
01189       if (vertexLIDs[v] < 0){
01190         // this means vertex is not created we create now
01191         Array<int> maxCoFacets(4,-1);
01192         // add the hanging node
01193         int vLID = nrElem_[0];
01194           addVertex( nrElem_[0] , vertexOwner[v] , vertexIsHanging[v] ,
01195                      p[0] + vertex_X[v]*h[0] , p[1] + vertex_Y[v]*h[1] , maxCoFacets );
01196           vertexLIDs[v] = vLID;
01197         // if vertex is hanging add to hangElmStore_
01198           if (vertexIsHanging[v]){
01199             Array<int>& hinf = hangingInfo[hVertexVertexIndex[v]];
01200             if (hinf.size() < 1) hinf.resize(5,-1);
01201             hinf[hVertexIndex[v]] = vLID;
01202             // for hanging Vertexes we might add the parent neighbor cell twice as maxCoFacet
01203             if ( (v == 1) || ( v==2 )) {  pointMaxCoF_[vertexLIDs[v]][1] = edgeMaxCoF_[cellsEdges[1]][0];
01204                                           pointMaxCoF_[vertexLIDs[v]][3] = edgeMaxCoF_[cellsEdges[1]][0]; }
01205             if ( (v == 4) || ( v==8 )) {  pointMaxCoF_[vertexLIDs[v]][2] = edgeMaxCoF_[cellsEdges[0]][0];
01206                                           pointMaxCoF_[vertexLIDs[v]][3] = edgeMaxCoF_[cellsEdges[0]][0]; }
01207             if ( (v == 7) || ( v==11 )) {  pointMaxCoF_[vertexLIDs[v]][0] = edgeMaxCoF_[cellsEdges[3]][1];
01208                                            pointMaxCoF_[vertexLIDs[v]][1] = edgeMaxCoF_[cellsEdges[3]][1]; }
01209             if ( (v == 13) || ( v==14 )) {  pointMaxCoF_[vertexLIDs[v]][0] = edgeMaxCoF_[cellsEdges[2]][1];
01210                                             pointMaxCoF_[vertexLIDs[v]][2] = edgeMaxCoF_[cellsEdges[2]][1]; }
01211             //SUNDANCE_MSG3(verb() , " ParentEdgeMaxCofacet 0 v:" << v << "," << edgeMaxCoF_[cellsEdges[0]]);
01212             //SUNDANCE_MSG3(verb() , " ParentEdgeMaxCofacet 1 v:" << v << "," << edgeMaxCoF_[cellsEdges[1]]);
01213             //SUNDANCE_MSG3(verb() , " ParentEdgeMaxCofacet 2 v:" << v << "," << edgeMaxCoF_[cellsEdges[2]]);
01214             //SUNDANCE_MSG3(verb() , " ParentEdgeMaxCofacet 3 v:" << v << "," << edgeMaxCoF_[cellsEdges[3]]);
01215             //SUNDANCE_MSG3(verb() , " vertexLIDs[v]:" << vertexLIDs[v] << ", Maxcof:" << pointMaxCoF_[vertexLIDs[v]] );
01216             //pointMaxCoF_[vertexLIDs[v]][0] = -1;
01217           }
01218       }
01219       // update maxCoFacet info (no additional information is needed)
01220       for (int hh = 0 ; hh < 4 ; hh++){
01221         SUNDANCE_MSG3(verb() , " vertexMaxCoFacet[v][hh]:" << vertexMaxCoFacet[v][hh] << " , vertexLIDs[v]:"<< vertexLIDs[v] );
01222         if (vertexMaxCoFacet[v][hh] >= 0)
01223           pointMaxCoF_[vertexLIDs[v]][hh] = nrElem_[2] + vertexMaxCoFacet[v][hh];
01224       }
01225       SUNDANCE_MSG3(verb() , " MaxCoFac point:" << vertexLIDs[v] << " , MaxCoFac:"<< pointMaxCoF_[vertexLIDs[v]] );
01226     }
01227     SUNDANCE_MSG3(verb() , " refineCell after Vertex creation vertexLIDs:" << vertexLIDs );
01228 
01229     // create all edges , those which are not created
01230     for (int e = 0 ; e < 24 ; e++){
01231       // create edge if necessary
01232       if (edgeLIDs[e] < 0){
01233         Array<int> maxCoFacets(2,-1);
01234         Array<int> edgeVertexLIDs(2,-1);
01235         edgeVertexLIDs[0] = vertexLIDs[edgeVertexes[e][0]];
01236         edgeVertexLIDs[1] = vertexLIDs[edgeVertexes[e][1]];
01237         int eLID = nrElem_[1];
01238         addEdge( nrElem_[1] , edgeOwner[e] , edgeIsHanging[e] , edgeVertex[e] ,
01239             edgePBnd[e] , edgeMBnd[e] ,  edgeVertexLIDs , maxCoFacets );
01240         edgeLIDs[e] = eLID;
01241       //if edge is hanging add to hangElmStore_
01242         if (edgeIsHanging[e]){
01243             Array<int>& hinf = hangingInfo[hEdgeVertexIndex[e]];
01244             if (hinf.size() < 1) hinf.resize(5,-1);
01245             SUNDANCE_MSG3(verb() , " HNI e:" << e << ", hEdgeIndex[e]:" << hEdgeIndex[e] );
01246             hinf[2+hEdgeIndex[e]] = eLID;
01247             // assign MaxCoefs only when is not Mesh boundary
01248             if ( edgeMBnd[e] == false){
01249                 // add maxCoFs from parent edge, so that hanging edges will have also 2 maxCoFs (for boundary)
01250               edgeMaxCoF_[edgeLIDs[e]][offsEdgeParentMaxCoFacet[e]] =
01251                   edgeMaxCoF_[cellsEdges[indexEdgeParentMaxCoFacet[e]]][offsEdgeParentMaxCoFacet[e]];
01252             }
01253         }
01254       }
01255       // update maxCoFacet info for this edge
01256       for (int hh = 0 ; hh < 2 ; hh++){
01257         //SUNDANCE_MSG3(verb() , " edgeMaxCoFacet[e][hh]:" << edgeMaxCoFacet[e][hh] << " , edgeLIDs[e]:"<< edgeLIDs[e] );
01258         if (edgeMaxCoFacet[e][hh] >= 0)
01259           edgeMaxCoF_[edgeLIDs[e]][hh] = nrElem_[2] + edgeMaxCoFacet[e][hh];
01260       }
01261       //SUNDANCE_MSG3(verb() , " MaxCoFac edge:" << edgeLIDs[e] << " , MaxCoFac:"<< edgeMaxCoF_[edgeLIDs[e]] );
01262     }
01263     SUNDANCE_MSG3(verb() , " refineCell after Edges creation edgeLIDs:" << edgeLIDs );
01264 
01265     // add all 9 cells
01266     for (int c = 0 ; c < 9 ; c++){
01267       Array<int> eLIDs(4,-1);
01268       Array<int> vLIDs(4,-1);
01269       vLIDs[0] = vertexLIDs[refinedCellsVertexes[c][0]];  vLIDs[1] = vertexLIDs[refinedCellsVertexes[c][1]];
01270       vLIDs[2] = vertexLIDs[refinedCellsVertexes[c][2]];  vLIDs[3] = vertexLIDs[refinedCellsVertexes[c][3]];
01271       eLIDs[0] = edgeLIDs[refinedCellsEdges[c][0]]; eLIDs[1] = edgeLIDs[refinedCellsEdges[c][1]];
01272       eLIDs[2] = edgeLIDs[refinedCellsEdges[c][2]]; eLIDs[3] = edgeLIDs[refinedCellsEdges[c][3]];
01273       // add cell
01274       cellLIDs[c] = nrElem_[2];
01275         addCell( nrElem_[2] , cellOwner , c , cellLID , cellLevel_[cellLID] + 1 , eLIDs , vLIDs );
01276     }
01277 
01278     SUNDANCE_MSG3(verb() , " ---- Adding hanging node information ----- " );
01279 
01280     if ( (hangElmStore_[0].containsKey(cellsPoints_[cellLID][0]) == false) && ( hangingInfo[0].size() > 0 ))
01281     {
01282       hangElmStore_[0].put(cellsPoints_[cellLID][0],hangingInfo[0]);
01283       //SUNDANCE_MSG3( verb() , " Store array 1 : " << hangingInfo[0] );
01284     }
01285     if ( (hangElmStore_[1].containsKey(cellsPoints_[cellLID][0]) == false) && ( hangingInfo[1].size() > 0 ))
01286     {
01287       hangElmStore_[1].put(cellsPoints_[cellLID][0],hangingInfo[1]);
01288       //SUNDANCE_MSG3( verb() , " Store array 2 : " << hangingInfo[1] );
01289     }
01290     if ( (hangElmStore_[1].containsKey(cellsPoints_[cellLID][1]) == false) && ( hangingInfo[2].size() > 0 ))
01291     {
01292       hangElmStore_[1].put(cellsPoints_[cellLID][1],hangingInfo[2]);
01293       //SUNDANCE_MSG3( verb() , " Store array 3 : " << hangingInfo[2] );
01294     }
01295     if ( (hangElmStore_[0].containsKey(cellsPoints_[cellLID][2]) == false) && ( hangingInfo[3].size() > 0 ))
01296     {
01297       hangElmStore_[0].put(cellsPoints_[cellLID][2],hangingInfo[3]);
01298       //SUNDANCE_MSG3( verb() , " Store array 4 : " << hangingInfo[3] );
01299     }
01300 
01301     SUNDANCE_MSG3(verb() , " ---- Refinement cell DONE , mark cell as not leaf and store children LID ----");
01302     isCellLeaf_[cellLID] = false;
01303     // store the children of the parent cell
01304     cellsChildren_[cellLID] = cellLIDs;
01305 }
01306 
01307 // -----------
01308 void HNMesh2D::createLeafNumbering(){
01309 
01310   // set all leaf numbers to -1
01311 
01312   // - iterate trough the mesh and in the leaf cells , distribute leaf numbering
01313   // , detect if one cell is leaf ()
01314   // , have a tree similar tree traversal ... todo: later
01315 
01316   SUNDANCE_MSG3(verb() , "HNMesh2D::createLeafNumbering nrPoint:" << nrElem_[0] << " , nrEdge:" << nrElem_[1] << ", nrCell:" << nrElem_[2]);
01317   // we resize the leafID - > global
01318   vertexGIDToLeafMapping_.resize(nrElem_[0],-1);
01319   for (int dd = 0 ; dd < nrElem_[0] ; dd++) vertexGIDToLeafMapping_[dd] = -1;
01320   vertexLeafToGIDMapping_.resize(nrElem_[0],-1);
01321   for (int dd = 0 ; dd < nrElem_[0] ; dd++) vertexLeafToGIDMapping_[dd] = -1;
01322 
01323   edgeGIDToLeafMapping_.resize(nrElem_[1],-1);
01324   for (int dd = 0 ; dd < nrElem_[1] ; dd++) edgeGIDToLeafMapping_[dd] = -1;
01325   edgeLeafToGIDMapping_.resize(nrElem_[1],-1);
01326   for (int dd = 0 ; dd < nrElem_[1] ; dd++) edgeLeafToGIDMapping_[dd] = -1;
01327 
01328   cellGIDToLeafMapping_.resize(nrElem_[2],-1);
01329   for (int dd = 0 ; dd < nrElem_[2] ; dd++) cellGIDToLeafMapping_[dd] = -1;
01330   cellLeafToGIDMapping_.resize(nrElem_[2],-1);
01331   for (int dd = 0 ; dd < nrElem_[2] ; dd++) cellLeafToGIDMapping_[dd] = -1;
01332 
01333   nrVertexLeafGID_ = 0; nrCellLeafGID_ = 0; nrEdgeLeafGID_ = 0;
01334 
01335   nrVertexLeafLID_ = 0; nrCellLeafLID_ = 0; nrEdgeLeafLID_ = 0;
01336   vertexLIDToLeafMapping_.resize(nrElem_[0],-1);
01337   for (int dd = 0 ; dd < nrElem_[0] ; dd++) vertexLIDToLeafMapping_[dd] = -1;
01338   vertexLeafToLIDMapping_.resize(nrElem_[0],-1);
01339   for (int dd = 0 ; dd < nrElem_[0] ; dd++) vertexLeafToLIDMapping_[dd] = -1;
01340 
01341   edgeLIDToLeafMapping_.resize(nrElem_[1],-1);
01342   for (int dd = 0 ; dd < nrElem_[1] ; dd++) edgeLIDToLeafMapping_[dd] = -1;
01343   edgeLeafToLIDMapping_.resize(nrElem_[1],-1);
01344   for (int dd = 0 ; dd < nrElem_[1] ; dd++) edgeLeafToLIDMapping_[dd] = -1;
01345 
01346   cellLIDToLeafMapping_.resize(nrElem_[2],-1);
01347   for (int dd = 0 ; dd < nrElem_[2] ; dd++) cellLIDToLeafMapping_[dd] = -1;
01348   cellLeafToLIDMapping_.resize(nrElem_[2],-1);
01349   for (int dd = 0 ; dd < nrElem_[2] ; dd++) cellLeafToLIDMapping_[dd] = -1;
01350 
01351   SUNDANCE_MSG3(verb() , "HNMesh2D::createLeafNumbering , start assigning leaf numbers");
01352 
01353   for (int ind = 0 ; ind < nrElem_[0] ; ind++){
01354     //SUNDANCE_MSG3(verb() , "HNMesh2D::createLeafNumbering point TID :" << ind << " maxCoFac: " << pointMaxCoF_[ind]);
01355   }
01356 
01357   // look for those leaf cells which points have a cell which maxCoFacet owner = myRank_
01358   // only those will have an LID
01359   Array<bool> hasCellLID(nrElem_[2],false);
01360 
01361   for (int ind = 0 ; ind < nrElem_[2] ; ind++){
01362     Array<int>& vertexIDs = cellsPoints_[ind];
01363     hasCellLID[ind] = false;
01364     for (int v = 0 ; v < 4 ; v++){
01365       Array<int>& maxCoFacet = pointMaxCoF_[vertexIDs[v]];
01366       hasCellLID[ind] =  ( hasCellLID[ind]
01367           || ( (maxCoFacet[0] >= 0) && (elementOwner_[2][maxCoFacet[0]] == myRank_) )
01368                     || ( (maxCoFacet[1] >= 0) && (elementOwner_[2][maxCoFacet[1]] == myRank_) )
01369                     || ( (maxCoFacet[2] >= 0) && (elementOwner_[2][maxCoFacet[2]] == myRank_) )
01370                     || ( (maxCoFacet[3] >= 0) && (elementOwner_[2][maxCoFacet[3]] == myRank_) ) ) ;
01371       //SUNDANCE_MSG3(verb() , " Point ID"<< vertexIDs[v] << ", MacCoFacet:" << maxCoFacet);
01372 
01373       // add cells with hanging nodes which have contribution to element which are owned by this processor
01374       // if vertex is hanging look into the parent cell at the same index and if the owner is myRank_ then add
01375       // to the cells which should be processed
01376       if ( (hasCellLID[ind] == false) && (isPointHanging_[vertexIDs[v]] == true)){
01377         int parentID = parentCellLID_[ind];
01378         Array<int>& parentVertexIDs = cellsPoints_[parentID];
01379         hasCellLID[ind] = hasCellLID[ind] || (elementOwner_[0][parentVertexIDs[v]] == myRank_);
01380       }
01381     }
01382     SUNDANCE_MSG3(verb() , "HNMesh2D::createLeafNumbering Cell ID :" << ind << " should be LID: " << hasCellLID[ind] <<
01383         " ,isCellLeaf_[ind]:" << isCellLeaf_[ind]);
01384   }
01385 
01386   //  treat special case, so that each hanging element has its parents
01387   // if we add one cell check hanging face, then add the maxCoF from the parent face if is leaf
01388   // if this is not successful then do the same thing for edges
01389   // - from each hanging edge there should be at least one cell on this processor which contains that parent edge !
01390   bool check_Ghost_cells = true;
01391   while (check_Ghost_cells){
01392     check_Ghost_cells = false;
01393       for (int ind = 0 ; ind < nrElem_[2] ; ind++){
01394        if ( (hasCellLID[ind] == true) && (elementOwner_[2][ind] != myRank_ ) ){
01395         // check edges
01396         Array<int>& edgeIDs = cellsEdges_[ind];
01397         // we have this if only
01398           for (int ii = 0 ; ii < 4 ; ii++ ){
01399           // if the face is hanging and does not belong to me
01400           if (isEdgeHanging_[edgeIDs[ii]] && ( elementOwner_[1][edgeIDs[ii]] != myRank_)){
01401                     // get parent cells same face
01402           int parentCell = parentCellLID_[ind];
01403           Array<int>& parentEdgesIDs = cellsEdges_[parentCell];
01404           for (int f = 0 ; f < 2 ; f++)
01405           if ( ( edgeMaxCoF_[parentEdgesIDs[ii]][f] >= 0 ) &&
01406              ( elementOwner_[2][ edgeMaxCoF_[parentEdgesIDs[ii]][f] ] != myRank_ ) &&
01407              ( hasCellLID[edgeMaxCoF_[parentEdgesIDs[ii]][f]] == false)   &&
01408              ( isCellLeaf_[edgeMaxCoF_[parentEdgesIDs[ii]][f]] )
01409              ){
01410             hasCellLID[edgeMaxCoF_[parentEdgesIDs[ii]][f]] = true;
01411             check_Ghost_cells = true;
01412           }
01413           }
01414          } // from loop
01415        }
01416       }
01417   }
01418 
01419   // we also have to list the cells which are not owned by the processor
01420   for (int ind = 0 ; ind < nrElem_[2] ; ind++)
01421   {
01422      // GID numbering
01423      // if cell is leaf and if is inside the computational domain
01424          if ( (isCellLeaf_[ind] == true) && (!isCellOut_[ind]) )
01425          {
01426            Array<int>& vertexIDs = cellsPoints_[ind];
01427              for (int v = 0; v < 4 ; v++)
01428              {
01429               SUNDANCE_MSG3(verb() , " createLeafGIDNumbering  vertexIDs[v]:" << vertexIDs[v] );
01430               if (vertexGIDToLeafMapping_[vertexIDs[v]] < 0)
01431               {
01432                  SUNDANCE_MSG3(verb() , " createLeafGIDNumbering -> VertexID:" << vertexIDs[v] << " , nrVertexLeafGID_:" << nrVertexLeafGID_ );
01433                  vertexLeafToGIDMapping_[nrVertexLeafGID_] = vertexIDs[v];
01434                  vertexGIDToLeafMapping_[vertexIDs[v]] = nrVertexLeafGID_;
01435                  nrVertexLeafGID_++;
01436               }
01437              }
01438            Array<int>& edgeIDs = cellsEdges_[ind];
01439            // for each edge check weather it already has a leaf index, if not create one
01440            for (int e = 0; e < 4 ; e++)
01441            {
01442              //SUNDANCE_MSG3(verb() , " createLeafNumbering  edgeLIDs[e]:" << edgeLIDs[e] );
01443              if (edgeGIDToLeafMapping_[edgeIDs[e]] < 0)
01444              {
01445                SUNDANCE_MSG3(verb() , " createLeafGIDNumbering -> edgeID:" << edgeIDs[e] << " , nrEdgeLeafGID_:" << nrEdgeLeafGID_ );
01446                //SUNDANCE_MSG3(verb() , " MaxCoFacet:" << edgeMaxCoF_[edgeLIDs[e]] << " edgeVertex:" << edgeVertex_[edgeLIDs[e]]);
01447                edgeLeafToGIDMapping_[nrEdgeLeafGID_] = edgeIDs[e];
01448                edgeGIDToLeafMapping_[edgeIDs[e]] = nrEdgeLeafGID_;
01449                nrEdgeLeafGID_++;
01450              }
01451            }
01452            // create leaf index for the leaf cell
01453        SUNDANCE_MSG3(verb() , " createLeafGIDNumbering CELL cellID:" << ind << " , nrCellLeafGID_:" << nrCellLeafGID_ );
01454            cellLeafToGIDMapping_[nrCellLeafGID_] = ind;
01455            cellGIDToLeafMapping_[ind] = nrCellLeafGID_;
01456            nrCellLeafGID_++;
01457 
01458            // LID numbering
01459            // create leaf LID numbering , if this cell needs to be processed
01460            if (hasCellLID[ind]){
01461              // vertex
01462                  for (int v = 0; v < 4 ; v++)
01463                  {
01464                   if (vertexLIDToLeafMapping_[vertexIDs[v]] < 0)
01465                   {
01466                      SUNDANCE_MSG3(verb() , " createLeafLIDNumbering -> VertexID:" << vertexIDs[v] << " , nrVertexLeafLID_:" << nrVertexLeafLID_ );
01467                      vertexLeafToLIDMapping_[nrVertexLeafLID_] = vertexIDs[v];
01468                      vertexLIDToLeafMapping_[vertexIDs[v]] = nrVertexLeafLID_;
01469                      nrVertexLeafLID_++;
01470                   }
01471                  }
01472                // for each edge check weather it already has a leaf index, if not create one
01473                for (int e = 0; e < 4 ; e++)
01474                {
01475                  if (edgeLIDToLeafMapping_[edgeIDs[e]] < 0)
01476                  {
01477                    SUNDANCE_MSG3(verb() , " createLeafLIDNumbering -> edgeID:" << edgeIDs[e] << " , nrEdgeLeafLID_:" << nrEdgeLeafLID_ );
01478                    edgeLeafToLIDMapping_[nrEdgeLeafLID_] = edgeIDs[e];
01479                    edgeLIDToLeafMapping_[edgeIDs[e]] = nrEdgeLeafLID_;
01480                    nrEdgeLeafLID_++;
01481                  }
01482                }
01483                // create leaf index for the leaf cell
01484                SUNDANCE_MSG3(verb() , " createLeafLIDNumbering CELL cellID:" << ind << " , nrCellLeafLID_:" << nrCellLeafLID_ );
01485                cellLeafToLIDMapping_[nrCellLeafLID_] = ind;
01486                cellLIDToLeafMapping_[ind] = nrCellLeafLID_;
01487                nrCellLeafLID_++;
01488            }
01489          }
01490   }
01491   SUNDANCE_MSG3(verb() , "HNMesh2D::createLeafNumbering , DONE");
01492 }

Site Contact