SundanceHNMesh3D.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  * SundanceHNMesh3D.cpp
00032  *
00033  *  Created on: May 30, 2009
00034  *      Author: benk
00035  */
00036 
00037 #include "SundanceHNMesh3D.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 HNMesh3D::offs_Points_x_[8] = {0, 1, 0, 1 , 0 , 1 , 0 , 1};
00056 
00057 int HNMesh3D::offs_Points_y_[8] = {0, 0, 1, 1 , 0 , 0 , 1 , 1};
00058 
00059 int HNMesh3D::offs_Points_z_[8] = {0, 0, 0, 0 , 1 , 1 , 1 , 1 };
00060 
00061 int HNMesh3D::edge_Points_localIndex[12][2] = { {0,1} , {0,2} , {0,4} , {1,3} , {1,5} , {2,3} , {2,6} , {3,7} ,
00062                                             {4,5} , {4,6} , {5,7} , {6,7} };
00063 
00064 int HNMesh3D::edge_Orientation[12] = { 0, 1, 2, 1, 2, 0, 2, 2, 0, 1, 1, 0 };
00065 int HNMesh3D::edge_MaxCofacetIndex[3][4] = { {0,5,8,11},{1,3,9,10},{2,4,6,7} };
00066 int HNMesh3D::edge_MaxCof[12] = { 0,0,0, 1, 1, 1, 2, 3, 2, 2, 3, 3 };
00067 
00068 int HNMesh3D::face_Points_localIndex[6][4] = { {0,1,2,3} , {0,1,4,5} , {0,2,4,6} , {1,3,5,7} , {2,3,6,7} , {4,5,6,7} };
00069 
00070 int HNMesh3D::face_Edges_localIndex[6][4]= { {0,1,3,5} , {0,2,4,8} , {1,2,6,9} , {3,4,7,10}, {5,6,7,11}, {8,9,10,11}};
00071 
00072 int HNMesh3D::face_Orientation[6] = { 0,1,2,2,1,0 };
00073 int HNMesh3D::face_MaxCofacetIndex[3][2] = { {0,5},{1,4},{2,3}};
00074 int HNMesh3D::face_MaxCof[6] = { 0,0,0,1,1,1 };
00075 
00076 // -----------------------------------
00077 int HNMesh3D::vInd[8];
00078 int HNMesh3D::eInd[12];
00079 int HNMesh3D::fInd[6];
00080 
00081 // the X and the Y coordinates of the newly
00082 double HNMesh3D::vertex_X[64] =
00083                       { 0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 , 0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 ,
00084                         0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 , 0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 ,
00085                         0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 , 0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 ,
00086                         0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 , 0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 ,
00087                         0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 , 0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 ,
00088                         0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 , 0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 ,
00089                         0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 , 0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 ,
00090                         0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 , 0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 };
00091 
00092 double HNMesh3D::vertex_Y[64] =
00093                       { 0.0 , 0.0 , 0.0 , 0.0 , 1.0/3.0 , 1.0/3.0 , 1.0/3.0 , 1.0/3.0 ,
00094                         2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 1.0 , 1.0 , 1.0 , 1.0 ,
00095                         0.0 , 0.0 , 0.0 , 0.0 , 1.0/3.0 , 1.0/3.0 , 1.0/3.0 , 1.0/3.0 ,
00096                         2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 1.0 , 1.0 , 1.0 , 1.0 ,
00097                         0.0 , 0.0 , 0.0 , 0.0 , 1.0/3.0 , 1.0/3.0 , 1.0/3.0 , 1.0/3.0 ,
00098                         2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 1.0 , 1.0 , 1.0 , 1.0 ,
00099                         0.0 , 0.0 , 0.0 , 0.0 , 1.0/3.0 , 1.0/3.0 , 1.0/3.0 , 1.0/3.0 ,
00100                         2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 1.0 , 1.0 , 1.0 , 1.0 };
00101 double HNMesh3D::vertex_Z[64] =
00102                       { 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0  , 0.0 , 0.0 ,
00103                     0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0  , 0.0 , 0.0 ,
00104                         1.0/3.0 , 1.0/3.0 , 1.0/3.0 , 1.0/3.0 , 1.0/3.0 , 1.0/3.0 , 1.0/3.0 , 1.0/3.0 ,
00105                         1.0/3.0 , 1.0/3.0 , 1.0/3.0 , 1.0/3.0 , 1.0/3.0 , 1.0/3.0 , 1.0/3.0 , 1.0/3.0 ,
00106                         2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 2.0/3.0 ,
00107                         2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 2.0/3.0 ,
00108                         1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0  , 1.0 , 1.0 ,
00109                         1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0  , 1.0 , 1.0 };
00110 // face index is above 20
00111 int HNMesh3D::vertexToParentEdge[64]  =
00112                       { -1,  0,  0, -1,  1, 20, 20,  3,  1, 20, 20,  3, -1,  5,  5, -1,  2, 21, 21,  4,
00113                         22, -1, -1, 23, 22, -1, -1, 23,  6, 24, 24,  7,  2, 21, 21,  4, 22, -1, -1, 23,
00114                         22, -1, -1, 23,  6, 24, 24,  7, -1,  8,  8, -1,  9, 25, 25, 10,  9, 25, 25, 10,
00115                         -1, 11, 11, -1  };
00116 //
00117 int HNMesh3D::vertexInParentIndex[64]  =
00118                       { -1,  0,  1, -1,  0, 20, 21,  0,  1, 22, 23,  1, -1,  0,  1, -1,  0, 20, 21,  0,
00119                       20, -1, -1, 20, 21, -1, -1, 21,  0, 20, 21,  0,  1, 22, 23,  1, 22, -1, -1, 22,
00120                       23, -1, -1, 23,  1, 22, 23,  1, -1,  0,  1, -1,  0, 20, 21,  0,  1, 22, 23,  1,
00121                         -1,  0,  1, -1  };
00122 //
00123 int HNMesh3D::edgeToParentEdge[144]  =
00124                       {  0,  0,  0,  1, 20, 20,  3, 20, 20, 20,  1, 20, 20,  3, 20, 20, 20,  1, 20, 20,
00125                          3,  5,  5,  5,  2, 21, 21,  4, 22, -1, -1, 23, 22, -1, -1, 23,  6, 24, 24,  7,
00126                         21, 21, 21, 22, -1, -1, 23, -1, -1, -1, 22, -1, -1, 23, -1, -1, -1, 22, -1, -1,
00127                         23, 24, 24, 24,  2, 21, 21,  4, 22, -1, -1, 23, 22, -1, -1, 23,  6, 24, 24,  7,
00128                         21, 21, 21, 22, -1, -1, 23, -1, -1, -1, 22, -1, -1, 23, -1, -1, -1, 22, -1, -1,
00129                         23, 24, 24, 24,  2, 21, 21,  4, 22, -1, -1, 23, 22, -1, -1, 23,  6, 24, 24,  7,
00130                          8,  8,  8,  9, 25, 25, 10, 25, 25, 25,  9, 25, 25, 10, 25, 25, 25,  9, 25, 25,
00131                         10, 11, 11, 11  };
00132 //
00133 int HNMesh3D::edgeInParentIndex[144]  =
00134                       {  0,  1,  2,  0, 20, 21,  0, 22, 23, 24,  1, 25, 26,  1, 27, 28, 29,  2, 30, 31,
00135                        2,  0,  1,  2,  0, 20, 21,  0, 20, -1, -1, 20, 21, -1, -1, 21,  0, 20, 21,  0,
00136                       22, 23, 24, 22, -1, -1, 22, -1, -1, -1, 23, -1, -1, 23, -1, -1, -1, 24, -1, -1,
00137                       24, 22, 23, 24,  1, 25, 26,  1, 25, -1, -1, 25, 26, -1, -1, 26,  1, 25, 26,  1,
00138                         27, 28, 29, 27, -1, -1, 27, -1, -1, -1, 28, -1, -1, 28, -1, -1, -1, 29, -1, -1,
00139                       29, 27, 28, 29,  2, 30, 31,  2, 30, -1, -1, 30, 31, -1, -1, 31,  2, 30, 31,  2,
00140                        0,  1,  2,  0, 20, 21,  0, 22, 23, 24,  1, 25, 26,  1, 27, 28, 29,  2, 30, 31,
00141                          2,  0,  1,  2  };
00142 //
00143 int HNMesh3D::faceToParentFace[108]  =
00144                       {  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  2, -1, -1,  3, -1, -1, -1,  2,
00145                         -1, -1,  3, -1, -1, -1,  2, -1, -1,  3,  4,  4,  4, -1, -1, -1, -1, -1, -1, -1,
00146                         -1, -1,  1,  1,  1,  2, -1, -1,  3, -1, -1, -1,  2, -1, -1,  3, -1, -1, -1,  2,
00147                         -1, -1,  3,  4,  4,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1,  1,  1,  1,  2, -1,
00148                         -1,  3, -1, -1, -1,  2, -1, -1,  3, -1, -1, -1,  2, -1, -1,  3,  4,  4,  4,  5,
00149                          5,  5,  5,  5,  5,  5,  5,  5  };
00150 //
00151 int HNMesh3D::faceInParentIndex[108]  =
00152                       {  0,  1,  2,  3,  4,  5,  6,  7,  8,  0,  1,  2,  0, -1, -1,  0, -1, -1, -1,  1,
00153                       -1, -1,  1, -1, -1, -1,  2, -1, -1,  2,  0,  1,  2, -1, -1, -1, -1, -1, -1, -1,
00154                       -1, -1,  3,  4,  5,  3, -1, -1,  3, -1, -1, -1,  4, -1, -1,  4, -1, -1, -1,  5,
00155                       -1, -1,  5,  3,  4,  5, -1, -1, -1, -1, -1, -1, -1, -1, -1,  6,  7,  8,  6, -1,
00156                         -1,  6, -1, -1, -1,  7, -1, -1,  7, -1, -1, -1,  8, -1, -1,  8,  6,  7,  8,  0,
00157                        1,  2,  3,  4,  5,  6,  7,  8 };
00158 
00159 
00160 HNMesh3D::HNMesh3D(int dim, const MPIComm& comm ,
00161       const MeshEntityOrder& order)
00162 : MeshBase(dim, comm , order), _comm(comm)
00163 {
00164   setVerbosity(0);
00165 
00166   // get the number of processors
00167   nrProc_ = MPIComm::world().getNProc();
00168   myRank_ = MPIComm::world().getRank();
00169   //------ Point storage ----
00170   points_.resize(0);
00171     nrElem_.resize(4,0);
00172   nrElemOwned_.resize(4,0);
00173   //----- Facets -----
00174     cellsPoints_.resize(0);
00175     cellsEdges_.resize(0);
00176     cellsFaces_.resize(0);
00177     isCellOut_.resize(0);
00178     faceEdges_.resize(0);
00179     facePoints_.resize(0);
00180   edgePoints_.resize(0);
00181   edgeOrientation_.resize(0);
00182   faceOrientation_.resize(0);
00183   // ----- MaxCofacets ----
00184   faceMaxCoF_.resize(0);
00185   edgeMaxCoF_.resize(0);
00186     pointMaxCoF_.resize(0);
00187     //------ Element (processor) ownership -----
00188   elementOwner_.resize(4); elementOwner_[0].resize(0); elementOwner_[1].resize(0); elementOwner_[2].resize(0); elementOwner_[3].resize(0);
00189     //---- hierarchical storage -----
00190     indexInParent_.resize(0);
00191     parentCellLID_.resize(0);
00192   cellLevel_.resize(0);
00193   isCellLeaf_.resize(0);
00194   // ---- "hanging" info storage ---
00195   isPointHanging_.resize(0);
00196   isEdgeHanging_.resize(0);
00197   // ---- hanging element and refinement (temporary) storage ---
00198   edgeHangingElmStore_ = Hashtable< int, Array<int> >();
00199   hangingAccessCount_.resize(0);
00200   faceHangingElmStore_ = Hashtable< int, Array<int> >();
00201   refineCell_.resize(0);
00202     // set the leaf counter to zero
00203   nrCellLeafGID_ = 0; nrEdgeLeafGID_ = 0; nrFaceLeafGID_ = 0; nrVertexLeafGID_ = 0;
00204   nrVertexLeafLID_ = 0; nrCellLeafLID_ = 0; nrFaceLeafLID_ = 0; nrEdgeLeafLID_ = 0;
00205 }
00206 
00207 int HNMesh3D::numCells(int dim) const  {
00208   SUNDANCE_MSG3(verb(),"HNMesh3D::numCells(int dim):   dim:" << dim );
00209   switch (dim){
00210   case 0: return nrVertexLeafLID_;
00211   case 1: return nrEdgeLeafLID_;
00212   case 2: return nrFaceLeafLID_;
00213   case 3: return nrCellLeafLID_;
00214   }
00215   return 0;
00216 }
00217 
00218 Point HNMesh3D::nodePosition(int i) const {
00219   SUNDANCE_MSG3(verb(),"HNMesh3D::nodePosition(int i)   i:"<< i);
00220     // point do not need leaf indexing
00221   return points_[vertexLeafToLIDMapping_[i]];
00222 }
00223 
00224 const double* HNMesh3D::nodePositionView(int i) const {
00225   SUNDANCE_MSG3(verb(),"HNMesh3D::nodePositionView(int i)   i:" << i);
00226   //SUNDANCE_VERB_HIGH("nodePosition(int i)");
00227   return &(points_[vertexLeafToLIDMapping_[i]][0]);;
00228 }
00229 
00230 void HNMesh3D::getJacobians(int cellDim, const Array<int>& cellLID,
00231                           CellJacobianBatch& jBatch) const
00232 {
00233 
00234     SUNDANCE_MSG3(verb(),"HNMesh3D::getJacobians  cellDim:"<<cellDim<<" _x:"<<_ofs_x<<" _y:"<<_ofs_y<<" _z:"<<_ofs_z);
00235     SUNDANCE_VERB_HIGH("getJacobians()");
00236     TEST_FOR_EXCEPTION(cellDim < 0 || cellDim > spatialDim(), InternalError,
00237       "cellDim=" << cellDim << " is not in expected range [0, " << spatialDim() << "]");
00238     int nCells = cellLID.size();
00239     int LID;
00240     Point pnt(0.0,0.0,0.0);
00241     jBatch.resize(cellLID.size(), spatialDim(), cellDim);
00242     if (cellDim < spatialDim()) // they need the Jacobian of a lower dinemsional element
00243     {
00244        for (int i=0; i<nCells; i++)
00245         {
00246           double* detJ = jBatch.detJ(i);
00247           switch(cellDim)
00248           {
00249             case 0:{ *detJ = 1.0;
00250               break;}
00251             case 1:{
00252           LID = edgeLeafToLIDMapping_[cellLID[i]];
00253             pnt = (points_[edgePoints_[LID][1]] - points_[edgePoints_[LID][0]]);
00254               *detJ = sqrt(pnt * pnt); // the length of the edge
00255             break;}
00256             case 2:{
00257               LID = faceLeafToLIDMapping_[cellLID[i]];
00258               int a = facePoints_[LID][0];
00259               int b = facePoints_[LID][1];
00260               int c = facePoints_[LID][2];
00261               const Point& pa = points_[a];
00262               const Point& pb = points_[b];
00263               const Point& pc = points_[c];
00264             Point directedArea = cross( pb - pa , pc - pa );
00265               *detJ = sqrt(directedArea * directedArea); // the area of the face
00266             break;}
00267             default:
00268               TEST_FOR_EXCEPTION(true, InternalError, "impossible switch value "  "cellDim=" << cellDim << " in HNMesh3D::getJacobians()");
00269           }
00270         }
00271     }else{ // they request the complete Jacoby matrix for this bunch of elements
00272         //Array<double> J(cellDim*cellDim);
00273         SUNDANCE_VERB_HIGH("cellDim == spatialDim()");
00274         for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00275         {
00276           double* J = jBatch.jVals(i);
00277           switch(cellDim)
00278           {
00279             case 3:{
00280           LID = cellLeafToLIDMapping_[cellLID[i]];
00281           // Jacobi for unstructured brick this will not work, but because of linear Jacoby we only have structured brick
00282               J[0] = points_[cellsPoints_[LID][1]][0] - points_[cellsPoints_[LID][0]][0];
00283               J[1] = 0.0; J[2] = 0.0; J[3] = 0.0;
00284               J[4] = points_[cellsPoints_[LID][2]][1] - points_[cellsPoints_[LID][0]][1];
00285               J[5] = 0.0; J[6] = 0.0; J[7] = 0.0;
00286               J[8] = points_[cellsPoints_[LID][4]][2] - points_[cellsPoints_[LID][0]][2]; // the Jacobi of the brick cell
00287             SUNDANCE_MSG3(verb() , "HNMesh3D::getJacobians LID:" << LID << " X:" << J[0] << " Y:" << J[4] << " Z:" << J[8]);
00288             //SUNDANCE_MSG3(verb() , "HNMesh3D::getJacobians P0:" << points_[cellsPoints_[LID][0]] );
00289             //SUNDANCE_MSG3(verb() , "HNMesh3D::getJacobians P1:" << points_[cellsPoints_[LID][1]] );
00290             //SUNDANCE_MSG3(verb() , "HNMesh3D::getJacobians P2:" << points_[cellsPoints_[LID][2]] );
00291             //SUNDANCE_MSG3(verb() , "HNMesh3D::getJacobians P4:" << points_[cellsPoints_[LID][4]] );
00292             break;}
00293             default:
00294               TEST_FOR_EXCEPTION(true, InternalError, "impossible switch value " "cellDim=" << cellDim << " in HNMesh3D::getJacobians()");
00295           }
00296         }
00297     }
00298 }
00299 
00300 void HNMesh3D::getCellDiameters(int cellDim, const Array<int>& cellLID,
00301                               Array<double>& cellDiameters) const {
00302 
00303    TEST_FOR_EXCEPTION(cellDim < 0 || cellDim > spatialDim(), InternalError,
00304       "cellDim=" << cellDim << " is not in expected range [0, " << spatialDim() << "]");
00305    SUNDANCE_VERB_HIGH("getCellDiameters()");
00306     cellDiameters.resize(cellLID.size());
00307     Point pnt(0.0 , 0.0 , 0.0 );
00308     int LID;
00309     if (cellDim < spatialDim())
00310     {
00311     SUNDANCE_MSG3(verb(),"HNMesh3D::getCellDiameters(), cellDim < spatialDim() ");
00312       for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00313       {
00314         switch(cellDim)
00315         {
00316           case 0:
00317                cellDiameters[i] = 1.0;
00318             break;
00319           case 1:  //length of the edge
00320           LID = edgeLeafToLIDMapping_[cellLID[i]];
00321             pnt = (points_[edgePoints_[LID][1]] - points_[edgePoints_[LID][0]]);
00322             cellDiameters[i] = sqrt(pnt * pnt); // the length of the edge
00323           break;
00324           case 2:  //length of the edge
00325           LID = faceLeafToLIDMapping_[cellLID[i]];
00326             pnt = (points_[facePoints_[LID][3]] - points_[facePoints_[LID][0]]);
00327             cellDiameters[i] = sqrt(pnt * pnt); // the diameter of the face
00328           break;
00329           default:
00330             TEST_FOR_EXCEPTION(true, InternalError, "impossible switch value "  "cellDim=" << cellDim << " in HNMesh3D::getCellDiameters()");
00331         }
00332       }
00333     }
00334     else
00335     {
00336     SUNDANCE_MSG3(verb(),"HNMesh3D::getCellDiameters(), cellDim == spatialDim() ");
00337       for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00338       {
00339         switch(cellDim)
00340         {
00341           case 3:
00342             LID = cellLeafToLIDMapping_[cellLID[i]];
00343             pnt = points_[cellsPoints_[LID][7]] - points_[cellsPoints_[LID][0]];
00344             cellDiameters[i] = sqrt(pnt * pnt);
00345           break;
00346           default:
00347             TEST_FOR_EXCEPTION(true, InternalError, "impossible switch value "
00348              "cellDim=" << cellDim  << " in HNMesh3D::getCellDiameters()");
00349         }
00350       }
00351     }
00352 }
00353 
00354 void HNMesh3D::pushForward(int cellDim, const Array<int>& cellLID,
00355                          const Array<Point>& refQuadPts,
00356                          Array<Point>& physQuadPts) const {
00357 
00358     SUNDANCE_MSG3(verb(),"HNMesh3D::pushForward cellDim:"<<cellDim);
00359     TEST_FOR_EXCEPTION(cellDim < 0 || cellDim > spatialDim(), InternalError,
00360       "cellDim=" << cellDim << " is not in expected range [0, " << spatialDim() << "]");
00361 
00362     int nQuad = refQuadPts.size();
00363     Point pnt( 0.0 , 0.0 , 0.0);
00364     Point pnt1( 0.0 , 0.0 , 0.0);
00365 
00366     if (physQuadPts.size() > 0) physQuadPts.resize(0);
00367     physQuadPts.reserve(cellLID.size() * refQuadPts.size());
00368     for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00369     {
00370       switch(cellDim)
00371       {
00372         case 0: // integrate one point
00373                physQuadPts.append(pnt);
00374         break;
00375         case 1:{ // integrate on one line
00376            int LID = edgeLeafToLIDMapping_[cellLID[i]];
00377              pnt = points_[edgePoints_[LID][0]];
00378              pnt1 = points_[edgePoints_[LID][1]] - points_[edgePoints_[LID][0]];
00379                for (int q=0; q<nQuad; q++) {
00380                  physQuadPts.append(pnt + (pnt1)*refQuadPts[q][0]);
00381             }
00382         break;}
00383         case 2:{
00384                int LID = faceLeafToLIDMapping_[cellLID[i]];
00385                pnt = points_[facePoints_[LID][0]];
00386                // this works only for structured, but we only work on structured quads
00387                pnt1 = points_[facePoints_[LID][3]] - points_[facePoints_[LID][0]];
00388              for (int q=0; q<nQuad; q++) {
00389                   physQuadPts.append( pnt + Point( refQuadPts[q][0] * pnt1[0] , refQuadPts[q][1] * pnt1[1] , refQuadPts[q][2] * pnt1[2]) );
00390              }
00391              break;}
00392         case 3:{
00393                int LID = cellLeafToLIDMapping_[cellLID[i]];
00394                pnt = points_[cellsPoints_[LID][0]];
00395                // this works only for structured, but we only work on structured quads
00396                pnt1 = points_[cellsPoints_[LID][7]] - points_[cellsPoints_[LID][0]];
00397              for (int q=0; q<nQuad; q++) {
00398                   physQuadPts.append( pnt + Point( refQuadPts[q][0] * pnt1[0] , refQuadPts[q][1] * pnt1[1] , refQuadPts[q][2] * pnt1[2] ) );
00399              }
00400         break;}
00401         default:
00402           TEST_FOR_EXCEPTION(true, InternalError, "impossible switch value " "in HNMesh3D::getJacobians()");
00403       }
00404     }
00405 }
00406 
00407 int HNMesh3D::ownerProcID(int cellDim, int cellLID) const  {
00408    int ID = -1;
00409    if (cellDim == 0) ID = vertexLeafToLIDMapping_[cellLID];
00410      if (cellDim == 1) ID = edgeLeafToLIDMapping_[cellLID];
00411      if (cellDim == 2) ID = faceLeafToLIDMapping_[cellLID];
00412      if (cellDim == 3) ID = cellLeafToLIDMapping_[cellLID];
00413      SUNDANCE_MSG3(verb() , " HNMesh3D::ownerProcID ,cellDim:" << cellDim << ", cellLID:"
00414          << cellLID <<" ,ID:" << ID << ", ret:"<< elementOwner_[cellDim][ID] );
00415    return elementOwner_[cellDim][ID];
00416 }
00417 
00418 
00419 int HNMesh3D::numFacets(int cellDim, int cellLID,
00420                       int facetDim) const  {
00421   //SUNDANCE_VERB_HIGH("numFacets()");
00422   if (cellDim==1) { // 1 dimension
00423          return 2; //one line has 2 points
00424     }
00425     else if (cellDim==2) { // 2 dimensions
00426          return 4; //one quad has 4 edges and 4 points
00427     }
00428     else if (cellDim==3) { // brick cell
00429       if (facetDim == 0) return 8;
00430       if (facetDim == 1) return 12;
00431       if (facetDim == 2) return 6;
00432     }
00433   return -1;
00434 }
00435 
00436 int HNMesh3D::facetLID(int cellDim, int cellLID,
00437                      int facetDim, int facetIndex,
00438                      int& facetOrientation) const  {
00439 
00440   // todo: check weather facet orientation is right
00441   facetOrientation = 1;
00442   SUNDANCE_MSG3(verb(),"HNMesh3D::facetLID  cellDim:"<<cellDim<<", cellLID:"<<cellLID<<", facetDim:"<<facetDim<< ", facetIndex:" << facetIndex);
00443   int rnt = -1 , LID=-1 , tmp=-1;
00444   if (facetDim == 0){ // return the Number/ID of a Vertex
00445     if (cellDim == 3 ){
00446         LID = cellLeafToLIDMapping_[cellLID];
00447         rnt = cellsPoints_[LID][facetIndex]; tmp = rnt;
00448         rnt = vertexLIDToLeafMapping_[rnt];
00449       }
00450       else if ((cellDim==2)){
00451         LID = faceLeafToLIDMapping_[cellLID];
00452         rnt = facePoints_[LID][facetIndex]; tmp = rnt;
00453         rnt = vertexLIDToLeafMapping_[rnt];
00454       }
00455       else if ((cellDim==1)){
00456           LID = edgeLeafToLIDMapping_[cellLID];
00457           rnt = edgePoints_[LID][facetIndex]; tmp = rnt;
00458           rnt = vertexLIDToLeafMapping_[rnt];
00459       }
00460   } else if (facetDim == 1){
00461     if (cellDim == 3 ){
00462           LID = cellLeafToLIDMapping_[cellLID];
00463           rnt = cellsEdges_[LID][facetIndex]; tmp = rnt;
00464       rnt = edgeLIDToLeafMapping_[rnt];
00465       } else if ((cellDim==2)){
00466           LID = faceLeafToLIDMapping_[cellLID];
00467           rnt = faceEdges_[LID][facetIndex]; tmp = rnt;
00468       rnt = edgeLIDToLeafMapping_[rnt];
00469       }
00470   } else if (facetDim == 2){
00471     if (cellDim == 3 ){
00472           LID = cellLeafToLIDMapping_[cellLID];
00473           rnt = cellsFaces_[LID][facetIndex]; tmp = rnt;
00474       rnt = faceLIDToLeafMapping_[rnt];
00475       }
00476   }
00477   SUNDANCE_MSG3(verb()," RET = " << rnt << ", LID:" << LID << ", tmp:" <<  tmp);
00478   return rnt;
00479 }
00480 
00481 
00482 void HNMesh3D::getFacetLIDs(int cellDim,
00483                           const Array<int>& cellLID,
00484                           int facetDim,
00485                           Array<int>& facetLID,
00486                           Array<int>& facetSign) const {
00487 
00488   SUNDANCE_MSG3(verb(),"HNMesh3D::getFacetLIDs()  cellDim:"<<cellDim<<"  cellLID.size():"<<cellLID.size()<<"  facetDim:" <<facetDim);
00489     int LID = 0 , cLID , facetOrientation ;
00490     int ptr = 0;
00491 
00492     int nf = numFacets(cellDim, cellLID[0], facetDim);
00493     facetLID.resize(cellLID.size() * nf);
00494     facetSign.resize(cellLID.size() * nf);
00495     // At this moment we just use the previous function
00496   for (unsigned int i = 0 ; i < (unsigned int)cellLID.size() ; i++){
00497       cLID = cellLID[i];
00498         for (int f=0; f<nf; f++, ptr++) {
00499           // we use this->facetLID caz facetLID is already used as variable
00500         LID = this->facetLID( cellDim, cLID, facetDim, f , facetOrientation);
00501             facetLID[ptr] = LID;
00502             facetSign[ptr] = facetOrientation;
00503         }
00504   }
00505   SUNDANCE_MSG3(verb() ,"HNMesh3D::getFacetLIDs()  DONE. ");
00506 }
00507 
00508 
00509 const int* HNMesh3D::elemZeroFacetView(int cellLID) const {
00510     int LID = cellLeafToLIDMapping_[cellLID];
00511     SUNDANCE_MSG3(verb() , "HNMesh3D::elemZeroFacetView ");
00512   return (const int*)(&cellsPoints_[LID]);
00513 }
00514 
00515 
00516 int HNMesh3D::numMaxCofacets(int cellDim, int cellLID) const  {
00517   //SUNDANCE_VERB_HIGH("numMaxCofacets()");
00518   SUNDANCE_MSG3(verb() , "HNMesh3D::numMaxCofacets():  cellDim:"<<cellDim<<" cellLID:"<<cellLID );
00519   int rnt = -1;
00520 
00521   if (cellDim==0) { // point MaxCoFacet
00522     int LID = vertexLeafToLIDMapping_[cellLID];
00523         int sum = 0;
00524         SUNDANCE_MSG3(verb() ," pointMaxCoF_[LID] = " << pointMaxCoF_[LID] );
00525         for (int i = 0 ; i < 8 ; i++)
00526           if ( (pointMaxCoF_[LID][i] >= 0) && ( cellLIDToLeafMapping_[pointMaxCoF_[LID][i]] >= 0) )
00527             sum++;
00528         // return the value, how many cells has this point, on the leaf level
00529         rnt = sum;
00530     }
00531     else if (cellDim==1) { // edge MaxCoFacet
00532         int LID = edgeLeafToLIDMapping_[cellLID];
00533         int sum = 0;
00534         SUNDANCE_MSG3(verb() ," edgeMaxCoF_[LID] = " << edgeMaxCoF_[LID] );
00535         for (int i = 0 ; i < 4 ; i++)
00536           if ( (edgeMaxCoF_[LID][i] >= 0) && ( cellLIDToLeafMapping_[edgeMaxCoF_[LID][i]] >= 0) )
00537             sum++;
00538         // return the value, how many cells has this point, on the leaf level
00539         rnt = sum;
00540     }
00541     else if (cellDim==2) { // face MaxCoFacet
00542         int LID = faceLeafToLIDMapping_[cellLID];
00543         int sum = 0;
00544         SUNDANCE_MSG3(verb() ," faceMaxCoF_[LID] = " << faceMaxCoF_[LID] );
00545         for (int i = 0 ; i < 2 ; i++)
00546           if ( (faceMaxCoF_[LID][i] >= 0) && ( cellLIDToLeafMapping_[faceMaxCoF_[LID][i]] >= 0) )
00547             sum++;
00548         // return the value, how many cells has this point, on the leaf level
00549         rnt = sum;
00550     }
00551   SUNDANCE_MSG3(verb() ," RET = " << rnt );
00552   return rnt;
00553 }
00554 
00555 
00556 int HNMesh3D::maxCofacetLID(int cellDim, int cellLID,
00557                        int cofacetIndex,
00558                        int& facetIndex) const  {
00559 
00560   SUNDANCE_MSG3(verb() ,"HNMesh3D::maxCofacetLID() cellDim:"<<cellDim<<" cellLID:"<<cellLID<<" cofacetIndex:"<<cofacetIndex<< " facetIndex:"
00561       << facetIndex);
00562   int rnt =-1;
00563 
00564   if (cellDim==0) { // 0 dimension
00565     //facetIndex = cofacetIndex;
00566     int actCoFacetIndex = 0;
00567       int LID = vertexLeafToLIDMapping_[cellLID];
00568     for (int ii = 0 ; ii < 8 ; ii++){
00569       // take this maxCoFacet only if that exist and is inside
00570       if ( (pointMaxCoF_[LID][ii] >= 0) && (cellLIDToLeafMapping_[pointMaxCoF_[LID][ii]] >= 0) ){
00571         if ( actCoFacetIndex < cofacetIndex ){
00572           actCoFacetIndex++;
00573         }else{
00574           facetIndex = ii;
00575           rnt = pointMaxCoF_[LID][ii];
00576           break;
00577         }
00578       }
00579     }
00580     }
00581     else if (cellDim==1) { // 1 dimensions
00582       int maxCoFacet = 0;
00583         int LID = edgeLeafToLIDMapping_[cellLID];
00584       int orientation = edgeOrientation_[LID];
00585     SUNDANCE_MSG3(verb() ," HNMesh3D::maxCofacetLID() 1 , orientation:" << orientation );
00586         // return the index in the vector, which later will be corrected later
00587     int actCoFacetIndex = 0;
00588     for (int ii = 0 ; ii < 4 ; ii++){
00589       // take this maxCoFacet only if that exist and is inside
00590       if ( (edgeMaxCoF_[LID][ii] >= 0) && (cellLIDToLeafMapping_[edgeMaxCoF_[LID][ii]] >= 0) ){
00591         if ( actCoFacetIndex < cofacetIndex ){
00592           actCoFacetIndex++;
00593         }else{
00594           facetIndex = ii;
00595           maxCoFacet = edgeMaxCoF_[LID][ii];
00596           break;
00597         }
00598       }
00599     }
00600     // calculate the correct facetIndex of the edge in the cell of cofacetIndex
00601     facetIndex = edge_MaxCofacetIndex[orientation][facetIndex];
00602     SUNDANCE_MSG3(verb() ,"HNMesh3D::maxCofacetLID() 1 , facetIndex:" << facetIndex << " maxCoFacet = " << maxCoFacet );
00603     rnt = ( maxCoFacet );
00604     }
00605     else if (cellDim==2) { // 2 dimensions
00606       int maxCoFacet = 0;
00607         int LID = faceLeafToLIDMapping_[cellLID];
00608       int orientation = faceOrientation_[LID];
00609     SUNDANCE_MSG3(verb() ," HNMesh3D::maxCofacetLID() 2 , orientation:" << orientation );
00610         // return the index in the vector, which later will be corrected later
00611     int actCoFacetIndex = 0;
00612     for (int ii = 0 ; ii < 2 ; ii++){
00613       // take this maxCoFacet only if that exist and is inside
00614       if ( (faceMaxCoF_[LID][ii] >= 0) && (cellLIDToLeafMapping_[faceMaxCoF_[LID][ii]] >= 0) ){
00615         if ( actCoFacetIndex < cofacetIndex ){
00616           actCoFacetIndex++;
00617         }else{
00618           facetIndex = ii;
00619           maxCoFacet = faceMaxCoF_[LID][ii];
00620           break;
00621         }
00622       }
00623     }
00624     // calculate the correct facetIndex of the edge in the cell of cofacetIndex
00625     facetIndex = face_MaxCofacetIndex[orientation][facetIndex];
00626     SUNDANCE_MSG3(verb() ,"HNMesh3D::maxCofacetLID() 2 , facetIndex:" << facetIndex << " maxCoFacet = " << maxCoFacet );
00627     rnt = ( maxCoFacet );
00628     }
00629   // transform back to leaf indexing
00630   rnt = cellLIDToLeafMapping_[ rnt ];
00631 
00632   SUNDANCE_MSG3(verb() ," RET = " << rnt << ",  facetIndex:" << facetIndex);
00633   return rnt;
00634 }
00635 
00636 void HNMesh3D::getCofacets(int cellDim, int cellLID,
00637                  int cofacetDim, Array<int>& cofacetLIDs) const {
00638   // Nothing to do
00639     TEST_FOR_EXCEPTION(true, InternalError," HNMesh3D::getCofacets() not implemented");
00640 }
00641 
00642 
00643 void HNMesh3D::getMaxCofacetLIDs(const Array<int>& cellLIDs,
00644   MaximalCofacetBatch& cofacets) const {
00645   // nothing to do here
00646     TEST_FOR_EXCEPTION(true, InternalError," HNMesh3D::getMaxCofacetLIDs() not implemented");
00647 }
00648 
00649 
00650 int HNMesh3D::mapGIDToLID(int cellDim, int globalIndex) const  {
00651   //SUNDANCE_VERB_HIGH("mapGIDToLID()");
00652   switch (cellDim){
00653   case 0:{
00654            int ID = vertexLeafToGIDMapping_[globalIndex];
00655          SUNDANCE_MSG3(verb() , " HNMesh3D::mapGIDToLID 0 , globalIndex:" << globalIndex << " ,ID:" << ID << ", ret:"<< vertexLIDToLeafMapping_[ID]);
00656            return vertexLIDToLeafMapping_[ID];
00657         break;}
00658   case 1:{
00659          int ID = edgeLeafToGIDMapping_[globalIndex];
00660          SUNDANCE_MSG3(verb() , " HNMesh3D::mapGIDToLID 1 , globalIndex:" << globalIndex << " ,ID:" << ID << ", ret:"<< edgeLIDToLeafMapping_[ID]);
00661          return edgeLIDToLeafMapping_[ID];
00662         break;}
00663   case 2:{
00664              int ID = faceLeafToGIDMapping_[globalIndex];
00665              SUNDANCE_MSG3(verb() , " HNMesh3D::mapGIDToLID 2 , globalIndex:" << globalIndex << " ,ID:" << ID << ", ret:"<< faceLIDToLeafMapping_[ID]);
00666              return faceLIDToLeafMapping_[ID];
00667         break;}
00668   case 3:{
00669              int ID = cellLeafToGIDMapping_[globalIndex];
00670              SUNDANCE_MSG3(verb() , " HNMesh3D::mapGIDToLID 3 , globalIndex:" << globalIndex << " ,ID:" << ID << ", ret:"<< cellLIDToLeafMapping_[ID]);
00671              return cellLIDToLeafMapping_[ID];
00672         break;}
00673   }
00674   return -1; //Wall
00675 }
00676 
00677 
00678 bool HNMesh3D::hasGID(int cellDim, int globalIndex) const {
00679   //SUNDANCE_VERB_HIGH("hasGID()");
00680   // we should always have all GIDs
00681   return true;
00682 }
00683 
00684 
00685 int HNMesh3D::mapLIDToGID(int cellDim, int localIndex) const  {
00686   //SUNDANCE_VERB_HIGH("mapLIDToGID()");
00687   switch (cellDim){
00688   case 0:{
00689            int ID = vertexLeafToLIDMapping_[localIndex];
00690          SUNDANCE_MSG3(verb() , " HNMesh3D::mapLIDToGID 0 , localIndex:" << localIndex << " ,ID:" << ID << ", ret:"<< vertexGIDToLeafMapping_[ID]);
00691            return vertexGIDToLeafMapping_[ID];
00692         break;}
00693   case 1:{
00694          int ID = edgeLeafToLIDMapping_[localIndex];
00695          SUNDANCE_MSG3(verb() , " HNMesh3D::mapLIDToGID 1 , localIndex:" << localIndex << " ,ID:" << ID << ", ret:"<< edgeGIDToLeafMapping_[ID]);
00696          return edgeGIDToLeafMapping_[ID];
00697         break;}
00698   case 2:{
00699              int ID = faceLeafToLIDMapping_[localIndex];
00700              SUNDANCE_MSG3(verb() , " HNMesh3D::mapLIDToGID 2 , localIndex:" << localIndex << " ,ID:" << ID << ", ret:"<< faceGIDToLeafMapping_[ID]);
00701              return faceGIDToLeafMapping_[ID];
00702         break;}
00703   case 3:{
00704              int ID = cellLeafToLIDMapping_[localIndex];
00705              SUNDANCE_MSG3(verb() , " HNMesh3D::mapLIDToGID 3 , localIndex:" << localIndex << " ,ID:" << ID << ", ret:"<< cellGIDToLeafMapping_[ID]);
00706              return cellGIDToLeafMapping_[ID];
00707         break;}
00708   }
00709   return -1; //Wall
00710 }
00711 
00712 
00713 CellType HNMesh3D::cellType(int cellDim) const  {
00714    switch(cellDim)
00715     {
00716       case 0:  return PointCell;
00717       case 1:  return LineCell;
00718       case 2:  return QuadCell;
00719       case 3:  return BrickCell;
00720       default:
00721         return NullCell; // -Wall
00722     }
00723 }
00724 
00725 
00726 int HNMesh3D::label(int cellDim, int cellLID) const {
00727    // not used
00728    TEST_FOR_EXCEPTION(true, InternalError," HNMesh3D::label() not implemented yet");
00729    return 0;
00730 }
00731 
00732 
00733 void HNMesh3D::getLabels(int cellDim, const Array<int>& cellLID,
00734     Array<int>& labels) const {
00735    // not used
00736    TEST_FOR_EXCEPTION(true, InternalError," HNMesh3D::getLabels() not implemented yet");
00737 }
00738 
00739 Set<int> HNMesh3D::getAllLabelsForDimension(int cellDim) const {
00740    Set<int>                 rtn;
00741    // not used
00742    TEST_FOR_EXCEPTION(true, InternalError," HNMesh3D::getAllLabelsForDimension() not implemented yet");
00743    return rtn;
00744 }
00745 
00746 void HNMesh3D::getLIDsForLabel(int cellDim, int label, Array<int>& cellLIDs) const {
00747     // not used
00748   TEST_FOR_EXCEPTION(true, InternalError," HNMesh3D::getLIDsForLabel() not implemented yet");
00749 }
00750 
00751 void HNMesh3D::setLabel(int cellDim, int cellLID, int label) {
00752    // not used
00753    TEST_FOR_EXCEPTION(true, InternalError," HNMesh3D::setLabel() not implemented yet");
00754 }
00755 
00756 
00757 void HNMesh3D::assignIntermediateCellGIDs(int cellDim) {
00758   // The GIDs are assigned
00759 }
00760 
00761 
00762 bool HNMesh3D::hasIntermediateGIDs(int dim) const {
00763   // the mesh always has intermediate cells
00764   return true; // true means they have been synchronized ... not used now
00765 }
00766 
00767 
00768 // =============================== HANGING NODE FUNCTIONS ==========================
00769 bool HNMesh3D::isElementHangingNode(int cellDim , int cellLID) const {
00770   SUNDANCE_MSG3(verb() ,"HNMesh3D::isElementHangingNode  cellDim:"<<cellDim<<" LID:"<< cellLID);
00771   if (cellDim==0) { // 1 dimension
00772       int LID = vertexLeafToLIDMapping_[cellLID];
00773     return (isPointHanging_[LID]);
00774     }
00775     else if (cellDim==1) { // 2 dimensions
00776       int LID = edgeLeafToLIDMapping_[cellLID];
00777         return (isEdgeHanging_[LID]);
00778     }
00779     else if (cellDim==2)
00780     {
00781       int LID = faceLeafToLIDMapping_[cellLID];
00782         return (isFaceHanging_[LID] );
00783         // todo:
00784         //|| isEdgeHanging_[faceEdges_[LID][0]] || isEdgeHanging_[faceEdges_[LID][1]]
00785         //|| isEdgeHanging_[faceEdges_[LID][2]] || isEdgeHanging_[faceEdges_[LID][3]] );
00786     }
00787   return false; //Wall
00788 }
00789 
00790 int HNMesh3D::indexInParent(int maxCellLID) const {
00791   int ID = cellLeafToLIDMapping_[maxCellLID];
00792   int indexInPar = indexInParent_[ID];
00793   return indexInPar;
00794 
00795 }
00796 
00797 void HNMesh3D::returnParentFacets(  int childCellLID , int dimFacets ,
00798                              Array<int> &facetsLIDs , int &parentCellLIDs ) const {
00799   int LID = cellLeafToLIDMapping_[childCellLID];
00800   parentCellLIDs = parentCellLID_[LID];
00801 
00802   SUNDANCE_MSG3( verb() , "HNMesh3D::returnParentFacets  childCellLID:"<<childCellLID<<" dimFacets:"<<dimFacets<<
00803       "  parentCellLIDs:"<< parentCellLIDs);
00804   //SUNDANCE_MSG3( verb() , "LID:"<<LID<<" parentCellLID_:"<<parentCellLID_);
00805   // this is the same for edges and for points
00806   if (dimFacets == 0){
00807     facetsLIDs.resize(8);
00808     for (int kuku = 0; kuku < 8 ; kuku++)
00809     facetsLIDs[kuku] = facetLID_tree( 3 , parentCellLIDs ,  dimFacets , kuku );
00810   }
00811   else if (dimFacets == 1){
00812     facetsLIDs.resize(12);
00813     for (int kuku = 0; kuku < 12 ; kuku++)
00814     facetsLIDs[kuku] = facetLID_tree( 3 , parentCellLIDs ,  dimFacets , kuku );
00815   }
00816   else if (dimFacets == 2){
00817     facetsLIDs.resize(6);
00818     for (int kuku = 0; kuku < 6 ; kuku++)
00819     facetsLIDs[kuku] = facetLID_tree( 3 , parentCellLIDs ,  dimFacets , kuku );
00820   }
00821   // map parent cell ID back to leaf indexing
00822   //parentCellLIDs = cellLIDToLeafMapping_[parentCellLIDs];
00823 
00824 }
00825 
00826 // only used in determining the parents
00827 int HNMesh3D::facetLID_tree(int cellDim, int cellLID,
00828                      int facetDim, int facetIndex) const{
00829     int rnt = -1;
00830   if (facetDim == 0){ // return the Number/ID of a Vertex
00831        rnt = cellsPoints_[cellLID][facetIndex];
00832        rnt = vertexLIDToLeafMapping_[rnt];
00833        // rnt must be greater than 0
00834   } else if (facetDim == 1){
00835        rnt = cellsEdges_[cellLID][facetIndex];
00836        rnt = edgeLIDToLeafMapping_[rnt];
00837        // rnt must be greater than 0
00838   } else if (facetDim == 2){
00839          rnt = cellsFaces_[cellLID][facetIndex];
00840        rnt = faceLIDToLeafMapping_[rnt];
00841        // rnt must be greater than 0
00842   }
00843   SUNDANCE_MSG3(verb() , "HNMesh3D::facetLID_tree cellDim:"<<cellDim<<", cellLID:"<<cellLID<<", facetDim:"<<facetDim<<
00844       ", facetIndex:"<<facetIndex<<" RET = " << rnt );
00845   return rnt;
00846 }
00847 
00848 // =========================== MESH CREATION ========================================
00849 
00850 /** adds one vertex to the mesh */
00851 void HNMesh3D::addVertex(int vertexLID , int ownerProc , bool isHanging ,
00852      double coordx , double coordy , double coordz , const Array<int> &maxCoF){
00853   // add only when the LID is new
00854   if (points_.size() <= vertexLID){
00855    TEST_FOR_EXCEPTION(vertexLID != nrElem_[0] , InternalError ,"HNMesh3D::addVertex " <<
00856        " vertexLID:" << vertexLID << " nrElem_[0]:" << nrElem_[0] );
00857      Point pt(coordx, coordy, coordz );
00858      points_.append( pt );
00859      pointMaxCoF_.append( maxCoF );
00860      isPointHanging_.append( isHanging );
00861      elementOwner_[0].append( (short int)ownerProc );
00862      SUNDANCE_MSG3(verb() , "HNMesh3D::addVertex: " << nrElem_[0] << " P:" << pt << " ,  maxCoF:" << maxCoF);
00863      SUNDANCE_MSG3(verb() , " ownerProc:" << ownerProc << " , isHanging:" << isHanging);
00864      nrElem_[0]++;
00865   }
00866 }
00867 
00868 /** adds one edge to the mesh */
00869 void HNMesh3D::addEdge(int edgeLID , int ownerProc , bool isHanging , int edgeOrientation ,
00870         const Array<int> &vertexLIDs , const Array<int> &maxCoF){
00871     // add only when the edgeLID is new
00872     SUNDANCE_MSG3(verb() , "HNMesh3D -- addEdge: " << edgeLID << " nrElem_[1]: " << nrElem_[1] << " edgePoints_.size():" << edgePoints_.size() );
00873     if (edgePoints_.size() <= edgeLID ){
00874      TEST_FOR_EXCEPTION(edgeLID != nrElem_[1], InternalError, "HNMesh3D::addEdge edgeLID != nrElem_[1]");
00875      edgePoints_.append( vertexLIDs );
00876      edgeOrientation_.append( (short int)edgeOrientation );
00877      edgeMaxCoF_.append( maxCoF );
00878      isEdgeHanging_.append(isHanging);
00879      hangingAccessCount_.append( (short int)0);
00880        elementOwner_[1].append( (short int)ownerProc );
00881        SUNDANCE_MSG3(verb() , "HNMesh3D::addEdge: " << nrElem_[1] << " vertexLIDs:" << vertexLIDs << " ,  maxCoF:" << maxCoF );
00882        SUNDANCE_MSG3(verb() , "          ownerProc:" << ownerProc << ", isHanging:" << isHanging << ", edgeOrientation:" << edgeOrientation );
00883        nrElem_[1]++;
00884     }
00885 }
00886 
00887 void HNMesh3D::addFace(int faceLID , int ownerProc , bool isHanging , int faceOrientation ,
00888             const Array<int> &vertexLIDs , const Array<int> &edgeLIDs ,
00889             const Array<int> &maxCoF){
00890 
00891     // add only when the edgeLID is new
00892     if (facePoints_.size() <= faceLID ){
00893      TEST_FOR_EXCEPTION(faceLID != nrElem_[2], InternalError, "HNMesh3D::addFace faceLID != nrElem_[2]");
00894      facePoints_.append( vertexLIDs );
00895      faceEdges_.append( edgeLIDs );
00896      faceOrientation_.append( (short int)faceOrientation );
00897      faceMaxCoF_.append( maxCoF );
00898      isFaceHanging_.append(isHanging);
00899        SUNDANCE_MSG3(verb() , "HNMesh3D::addFace: " << nrElem_[2] << " vertexLIDs:" << vertexLIDs << " ,  maxCoF:" << maxCoF );
00900        SUNDANCE_MSG3(verb() , "HNMesh3D::addFace ,  edgeLIDs:" << edgeLIDs );
00901        SUNDANCE_MSG3(verb() , "          ownerProc:" << ownerProc << ", isHanging:" << isHanging << ", faceOrientation:" << faceOrientation);
00902        elementOwner_[2].append( (short int)ownerProc );
00903        nrElem_[2]++;
00904     }
00905 }
00906 
00907 /** adds one cell(3D) to the mesh */
00908 void HNMesh3D::addCell(int cellLID , int ownerProc ,
00909         int indexInParent , int parentCellLID , int level ,
00910         const Array<int> &faceLIDs , const Array<int> &edgeLIDs ,
00911         const Array<int> &vertexLIDs)
00912 {
00913     // add only when the edgeLID is new
00914     if (cellsPoints_.size() <= cellLID ) {
00915      TEST_FOR_EXCEPTION(cellLID != nrElem_[3], InternalError, "HNMesh3D::cellLID cellLID != nrElem_[3]");
00916      cellsFaces_.append( faceLIDs );
00917      cellsEdges_.append( edgeLIDs );
00918      cellsPoints_.append( vertexLIDs );
00919        indexInParent_.append( indexInParent );
00920        parentCellLID_.append( parentCellLID );
00921        cellLevel_.append( level );
00922        isCellLeaf_.append( true );
00923        refineCell_.append( 0 );
00924        cellsChildren_.append( tuple(1) );
00925        elementOwner_[3].append( (short int)ownerProc );
00926      // calculate if the cell is complete outside the mesh domain
00927      isCellOut_.append( !( meshDomain_.isInsideComputationalDomain(points_[vertexLIDs[0]]) ||
00928                        meshDomain_.isInsideComputationalDomain(points_[vertexLIDs[1]]) ||
00929                        meshDomain_.isInsideComputationalDomain(points_[vertexLIDs[2]]) ||
00930                        meshDomain_.isInsideComputationalDomain(points_[vertexLIDs[3]]) ||
00931                        meshDomain_.isInsideComputationalDomain(points_[vertexLIDs[4]]) ||
00932                        meshDomain_.isInsideComputationalDomain(points_[vertexLIDs[5]]) ||
00933                        meshDomain_.isInsideComputationalDomain(points_[vertexLIDs[6]]) ||
00934                        meshDomain_.isInsideComputationalDomain(points_[vertexLIDs[7]]) ) );
00935        SUNDANCE_MSG3(verb() , "HNMesh3D::addCell: " << nrElem_[3] <<
00936            " vertexLIDs:" << vertexLIDs << " edgeLIDs:" << edgeLIDs << " faceLIDs:" << faceLIDs);
00937        SUNDANCE_MSG3(verb() , "HNMesh3D::addCell p0:" << points_[vertexLIDs[0]] );
00938        SUNDANCE_MSG3(verb() , "HNMesh3D::addCell p1:" << points_[vertexLIDs[1]] );
00939        SUNDANCE_MSG3(verb() , "HNMesh3D::addCell p2:" << points_[vertexLIDs[2]] );
00940        SUNDANCE_MSG3(verb() , "HNMesh3D::addCell p3:" << points_[vertexLIDs[3]] );
00941        SUNDANCE_MSG3(verb() , "HNMesh3D::addCell p4:" << points_[vertexLIDs[4]] );
00942        SUNDANCE_MSG3(verb() , "HNMesh3D::addCell p5:" << points_[vertexLIDs[5]] );
00943        SUNDANCE_MSG3(verb() , "HNMesh3D::addCell p6:" << points_[vertexLIDs[6]] );
00944        SUNDANCE_MSG3(verb() , "HNMesh3D::addCell p7:" << points_[vertexLIDs[7]] );
00945      SUNDANCE_MSG3(verb() , "HNMesh3D::addCell IN DOMAIN:" <<  isCellOut_[nrElem_[3]] );
00946        nrElem_[3]++;
00947     }
00948 }
00949 
00950 /** creates one regular mesh without refinement. With a different function the
00951  * refinement can start later , independently from this function. <br>
00952  * The structure of this mesh also supports unstructured storage of the cells,
00953  * so we might create unstructured mesh and later refine in the same way */
00954 void HNMesh3D::createMesh(
00955                       double position_x,
00956                 double position_y,
00957                 double position_z,
00958                 double offset_x,
00959                 double offset_y,
00960                 double offset_z,
00961                 int resolution_x,
00962                 int resolution_y,
00963                 int resolution_z,
00964                 const RefinementClass& refineClass ,
00965                 const MeshDomainDef& meshDomain
00966 ){
00967 
00968   setVerbosity(0);
00969 
00970   // initialize object fields
00971   _pos_x = position_x; _pos_y = position_y; _pos_z = position_z;
00972   _ofs_x = offset_x; _ofs_y = offset_y;  _ofs_z = offset_z;
00973   _res_x = resolution_x; _res_y = resolution_y; _res_z = resolution_z;
00974   refineClass_ = refineClass;
00975   meshDomain_ = meshDomain;
00976 
00977   // create coarsest mesh
00978   createCoarseMesh();
00979 
00980   // loop as long there is no refinement
00981     bool doRefinement = true;
00982     while (doRefinement){
00983       doRefinement = oneRefinementIteration();
00984     }
00985 
00986   // calculate global IDs and create leaf Numbering
00987     createLeafNumbering();
00988 
00989 }
00990 
00991 void HNMesh3D::updateLocalCoarseNumbering(int ix, int iy , int iz , int Nx , int Ny){
00992 /* ==== vertex indexing =====*/
00993   vInd[0] = (Nx+1)*(Ny+1)*iz + (Nx+1)*iy + ix;
00994   vInd[1] = vInd[0] + 1;
00995   vInd[2] = vInd[0] + Nx+1;
00996   vInd[3] = vInd[0] + Nx+2;
00997   vInd[4] = vInd[0] + (Nx+1)*(Ny+1);
00998   vInd[5] = vInd[4] + 1;
00999   vInd[6] = vInd[4] + Nx+1;
01000   vInd[7] = vInd[4] + Nx+2;
01001 /*  ===== edge indexing ====== */
01002   eInd[0] = (Nx*(Ny+1) + Ny*(Nx+1) + (Nx+1)*(Ny+1))*iz + (Nx+1+Nx)*iy + ix;
01003   eInd[1] = eInd[0] + Nx;
01004   eInd[3] = eInd[0] + Nx+1;
01005   eInd[5] = eInd[0] + 2*Nx+1;
01006   int ed5 = (2*Nx+1)*(iy+1)+ix;
01007   eInd[2] = eInd[5]+(Nx*(Ny+1)+Ny*(Nx+1)  - ed5) + (Nx+1)*iy+ix;
01008   eInd[4] = eInd[2]+1;
01009   eInd[6] = eInd[2]+Nx+1;
01010   eInd[7] = eInd[2]+Nx+2;
01011   int ed7 = (Nx+1)*(iy+1)+ix+1;
01012   eInd[8] = eInd[7] + ( (Nx+1)*(Ny+1) - ed7) + (2*Nx+1)*iy+ix;
01013   eInd[9] = eInd[8] + Nx;
01014   eInd[10] = eInd[8] + Nx+1;
01015   eInd[11] = eInd[8] + 2*Nx+1;
01016 /* ======== face numbering ======== */
01017   fInd[0] = (Nx*Ny+Nx*(Ny+1)+ Ny*(Nx+1))*iz+Nx*iy+ix;
01018   fInd[1] = fInd[0] + (Nx*Ny - (Nx*iy+ix)) + (iy*(2*Nx+1) + ix);
01019   fInd[2] = fInd[1] + Nx;
01020   fInd[3] = fInd[2] + 1;
01021   fInd[4] = fInd[3] + Nx;
01022   fInd[5] = fInd[4] + ((Nx+1)*Ny + (Ny+1)*Nx - (2*Nx+1)*(iy+1) - (ix)  + Nx*iy + ix);
01023 }
01024 
01025 void HNMesh3D::createCoarseMesh(){
01026 
01027   // estimate load for parallel case,
01028   // assign cells to each processors, based on the load and the domain
01029   // we assign cells to processors, (y,x) (optimal for vertical channel flow)
01030   // the estimation is done in each processor, globally but then only the local mesh will be build
01031   int nrCoarseCell = _res_x * _res_y * _res_z;
01032   int nrCoarsePoints = (_res_x+1)*(_res_y+1)*(_res_z+1);
01033   int nrCoarseEdge = (_res_x+1)*(_res_y+1)*_res_z + _res_x*(_res_y+1)*(_res_z+1) + (_res_x+1)*_res_y*(_res_z+1);
01034   int nrCoarseFace = (_res_x+1)*_res_y*_res_z + _res_x*(_res_y+1)*_res_z+ + _res_x*_res_y*(_res_z+1);
01035   Array<int> coarseCellOwner( nrCoarseCell , -1 );
01036   Array<int> coarsePointOwner( nrCoarsePoints , -1 );
01037   Array<int> coarseEdgeOwner( nrCoarseEdge , -1 );
01038   Array<int> coarseFaceOwner( nrCoarseFace , -1 );
01039   Array<int> coarseCellLID( nrCoarseCell , -1 );
01040   Array<int> coarsePointLID( nrCoarsePoints , -1 );
01041   Array<int> coarseEdgeLID( nrCoarseEdge , -1 );
01042   Array<int> coarseFaceLID( nrCoarseFace , -1 );
01043   Array<int> coarseCellsLoad( nrCoarseCell , 0 );
01044   int totalLoad = 0;
01045 
01046   SUNDANCE_MSG3(verb() , "HNMesh3D::createMesh nrCoarseCell:" << nrCoarseCell << " nrCoarsePoints:" << nrCoarsePoints
01047                 << " nrCoarseEdge:" << nrCoarseEdge <<  " nrCoarseFace:" << nrCoarseFace << " nrProc_:" << nrProc_ << " myRank_:" << myRank_);
01048   TEST_FOR_EXCEPTION( nrCoarseCell < nrProc_ , InternalError," HNMesh3D::createMesh nrCoarseCell < nrProc_ ");
01049   // now always divide as a flow channel , no resolution driven division
01050 
01051     // calculate total load and load per coarse cell
01052   double h[3];
01053   Array<int>  ind(3);
01054   h[0] = _ofs_x/(double)_res_x; h[1] = _ofs_y/(double)_res_y; h[2] = _ofs_z/(double)_res_z;
01055   Point pos(h[0],h[1],h[2]);
01056   Point res(h[0],h[1],h[2]);
01057   // estimate total estimated load of the mesh
01058   for (int i=0; i < nrCoarseCell; i++){
01059     // midpoint of the cell
01060     ind[0] = ((i % (_res_x*_res_y)) % _res_x);
01061     ind[1] = ((i % (_res_x*_res_y)) / _res_x);
01062     ind[2] = (i / (_res_x*_res_y));
01063     pos[0] = _pos_x + (double)(ind[0])*h[0] + 0.5*h[0];
01064     pos[1] = _pos_y + (double)(ind[1])*h[1] + 0.5*h[1];
01065     pos[2] = _pos_z + (double)(ind[2])*h[2] + 0.5*h[2];
01066     // todo: take the domain in consideration (take the 8 points) (when cells are turned off)
01067     coarseCellsLoad[i] = refineClass_.estimateRefinementLevel( pos , res );
01068     totalLoad += coarseCellsLoad[i];
01069   }
01070 
01071   // calculate average load per cell
01072   double loadPerProc = (double)totalLoad / (double)nrProc_;
01073   int actualProc=0;
01074   totalLoad = 0;
01075   // assign owners to the cells, edges, vertexes , greedy method
01076   SUNDANCE_MSG3(verb() , "Processor asign, loadPerProc:" << loadPerProc );
01077   double diff_load = 0.0;
01078   for (int i=0; i < nrCoarseCell; i++){
01079     ind[0] = ((i % (_res_x*_res_y)) % _res_x);
01080     ind[1] = ((i % (_res_x*_res_y)) / _res_x);
01081     ind[2] = (i / (_res_x*_res_y));
01082     // call the function to update
01083     updateLocalCoarseNumbering( ind[0] , ind[1] , ind[2] , _res_x , _res_y);
01084     //SUNDANCE_MSG3(verb() , "Cell ID:" << i << " vertexInd:" <<vertexInd << " edgeInd:" << edgeInd );
01085     //SUNDANCE_MSG3(verb() , "Cell, actual index" << ind  );
01086     // assign ownership for vertexes
01087     for (int jj = 0 ; jj < 8 ; jj++){
01088       if (coarsePointOwner[vInd[jj]] < 0){
01089         coarsePointOwner[vInd[jj]] = actualProc;
01090         SUNDANCE_MSG3(verb() , "Vertex CPU assign " << vInd[jj] << " ->" << actualProc );
01091       }
01092     }
01093     // assign ownership for edges
01094     for (int jj = 0 ; jj < 12 ; jj++){
01095       if (coarseEdgeOwner[eInd[jj]] < 0){
01096         coarseEdgeOwner[eInd[jj]] = actualProc;
01097         SUNDANCE_MSG3(verb() , "Edge CPU assign " << eInd[jj] << " ->" << actualProc );
01098       }
01099     }
01100     // assign ownership for faces
01101     for (int jj = 0 ; jj < 6 ; jj++){
01102       if (coarseFaceOwner[fInd[jj]] < 0){
01103         coarseFaceOwner[fInd[jj]] = actualProc;
01104         SUNDANCE_MSG3(verb() , "Face CPU assign " << fInd[jj] << " ->" << actualProc );
01105       }
01106     }
01107     // assign ownership for the cell
01108     coarseCellOwner[i] = actualProc;
01109     totalLoad += coarseCellsLoad[i];
01110     SUNDANCE_MSG3(verb() , "Cell CPU assign " << i << " ->" << actualProc <<
01111         ", totalLoad:" << totalLoad << " loadPerProc:" << loadPerProc);
01112     // the rounding of the load estimator is in favor to late earlier
01113     if (((double)totalLoad >= (loadPerProc - 1e-8 - diff_load)) && ( actualProc < nrProc_-1 )){
01114       SUNDANCE_MSG3(verb() , "Increase CPU , totalLoad:" << totalLoad << " loadPerProc:" << loadPerProc );
01115       // compensate the load difference for the next CPU
01116       diff_load = totalLoad - loadPerProc;
01117       actualProc = actualProc + 1;
01118       totalLoad = 0;
01119     }
01120   }
01121 
01122   // now go trough all cells which have to be added to this processor
01123   SUNDANCE_MSG3(verb() , " Process Cells:" << nrCoarseCell );
01124   for (int i=0; i < nrCoarseCell; i++)
01125   {
01126     ind[0] = ((i % (_res_x*_res_y)) % _res_x);
01127     ind[1] = ((i % (_res_x*_res_y)) / _res_x);
01128     ind[2] = (i / (_res_x*_res_y));
01129     // calculate the local index
01130     updateLocalCoarseNumbering( ind[0] , ind[1] , ind[2] , _res_x , _res_y );
01131     pos[0] = _pos_x + (double)(ind[0])*h[0];
01132     pos[1] = _pos_y + (double)(ind[1])*h[1];
01133     pos[2] = _pos_z + (double)(ind[2])*h[2];
01134     SUNDANCE_MSG3(verb() , "PCell ID:" << i <<" pos:"<<pos<<" _res_x:"<<_res_x<<" _res_y:"<<_res_y<<" _res_z:"<<_res_z);
01135     SUNDANCE_MSG3(verb() , "PCell, actual index" << ind  );
01136     // this condition is so that remote cells will be added
01137     int cellLID = coarseCellLID[i];
01138     Array<int> vLID(8,-1) , vertexMaxCoF(8,-1) ;
01139     Array<int> edgeLID(12,-1) , edgeVert(2,-1) , edgeMaxCoef(4,-1);
01140     Array<int> faceLID(6,-1) , faceVert(4,-1) , faceEdge(4,-1) , faceMaxCoef(2,-1);
01141     //SUNDANCE_MSG3(verb() , "Cell ID:" << i << " vertexInd:" <<vertexInd << " edgeInd:" << edgeInd << " cellLID:" << cellLID);
01142     //SUNDANCE_MSG3(verb() , "Cell, actual index" << ind << " pos:" << pos);
01143     // assign new cellID if necessary
01144     if (coarseCellLID[i] < 0 ){
01145       coarseCellLID[i] = nrElem_[3];
01146       cellLID = coarseCellLID[i];
01147     }
01148     // add all Vertexes , ignoring neighbor cells (maxcofacets)
01149         for (int jj = 0 ; jj < 8 ; jj++){
01150             if (coarsePointLID[vInd[jj]] < 0){
01151               coarsePointLID[vInd[jj]] = nrElem_[0];
01152             }
01153             vLID[jj] = coarsePointLID[vInd[jj]];
01154             // add vertex with -1 maxCOfacets
01155             //SUNDANCE_MSG3(verb() , "Vertex  X:" << ((double)offs_Points_x_[jj])*h[0] << "  Y:" << pos[1] + ((double)offs_Points_y_[jj])*h[1]);
01156             //SUNDANCE_MSG3(verb() , "Vertex  vLID[jj]:" << vLID[jj] << "  , coarsePointOwner[vertexInd+vertexOffs[jj]]" << coarsePointOwner[vertexInd+vertexOffs[jj]] );
01157             addVertex( vLID[jj] , coarsePointOwner[vInd[jj]] , false ,
01158                    pos[0] + ((double)offs_Points_x_[jj])*h[0] , pos[1] + ((double)offs_Points_y_[jj])*h[1] ,
01159                    pos[2] + ((double)offs_Points_z_[jj])*h[2] ,
01160                        vertexMaxCoF );
01161         }
01162     // add all Edges , ignoring neighbor cells (maxcofacets)
01163         for (int jj = 0 ; jj < 12 ; jj++){
01164             if (coarseEdgeLID[eInd[jj]] < 0){
01165               coarseEdgeLID[eInd[jj]] = nrElem_[1];
01166             }
01167             edgeLID[jj] = coarseEdgeLID[eInd[jj]];
01168             edgeVert[0] = vLID[edge_Points_localIndex[jj][0]];
01169             edgeVert[1] = vLID[edge_Points_localIndex[jj][1]];
01170             SUNDANCE_MSG3(verb() , "Edge local Index:" << eInd[jj] );
01171             // add edge with -1 maxCOfacets
01172             addEdge( edgeLID[jj] , coarseEdgeOwner[eInd[jj]] , false , edge_Orientation[jj] , edgeVert , edgeMaxCoef );
01173         }
01174     // add all Faces , ignoring neighbor cells (maxcofacets)
01175         for (int jj = 0 ; jj < 6 ; jj++){
01176             if (coarseFaceLID[fInd[jj]] < 0){
01177               coarseFaceLID[fInd[jj]] = nrElem_[2];
01178             }
01179             faceLID[jj] = coarseFaceLID[fInd[jj]];
01180             //
01181             faceVert[0] = vLID[face_Points_localIndex[jj][0]];
01182             faceVert[1] = vLID[face_Points_localIndex[jj][1]];
01183             faceVert[2] = vLID[face_Points_localIndex[jj][2]];
01184             faceVert[3] = vLID[face_Points_localIndex[jj][3]];
01185             faceEdge[0] = edgeLID[face_Edges_localIndex[jj][0]];
01186             faceEdge[1] = edgeLID[face_Edges_localIndex[jj][1]];
01187             faceEdge[2] = edgeLID[face_Edges_localIndex[jj][2]];
01188             faceEdge[3] = edgeLID[face_Edges_localIndex[jj][3]];
01189             // add face with -1 maxCOfacets
01190             addFace( faceLID[jj] , coarseFaceOwner[fInd[jj]] , false , face_Orientation[jj] ,
01191                        faceVert , faceEdge , faceMaxCoef );
01192         }
01193     // add the Cell
01194         addCell( cellLID , coarseCellOwner[i] , 0 , cellLID , 0 , faceLID , edgeLID , vLID);
01195   } // --- end from for loop
01196 
01197   // next is maxCoFacet and boundary info update for vertexes and edges
01198   SUNDANCE_MSG3(verb() , " Process maxCofacets:" << nrCoarseCell );
01199   for (int i=0; i < nrCoarseCell; i++){
01200     Array<int> vLID(8,-1) , eLID(12,-1) ,fLID(6,-1) ;
01201     ind[0] = ((i % (_res_x*_res_y)) % _res_x);
01202     ind[1] = ((i % (_res_x*_res_y)) / _res_x);
01203     ind[2] = (i / (_res_x*_res_y));
01204     // calculate the local index
01205     updateLocalCoarseNumbering( ind[0] , ind[1] , ind[2] , _res_x , _res_y );
01206     int cellLID = coarseCellLID[i];
01207     SUNDANCE_MSG3(verb() , " MaxCoFs in Cell cellLID:" << cellLID  );
01208     //SUNDANCE_MSG3(verb() , "MaxCoFs in Cell ID:" << i << " vertexInd:" <<vertexInd << " edgeInd:" << edgeInd );
01209     //SUNDANCE_MSG3(verb() , "MaxCoFs, actual index" << ind  );
01210     // vertex maxCoFac
01211         for (int jj = 0 ; jj < 8 ; jj++){
01212             vLID[jj] = coarsePointLID[vInd[jj]];
01213             // if all elements are added then this is OK
01214             pointMaxCoF_[vLID[jj]][jj] = cellLID;
01215             SUNDANCE_MSG3(verb() , "Vertex MaxCoFacet vLID[jj]:" << vLID[jj] << " jj:" << jj << " cellLID:" << cellLID );
01216         }
01217         // edge maxCoFac
01218         for (int jj = 0 ; jj < 12 ; jj++){
01219             eLID[jj] = coarseEdgeLID[eInd[jj]];
01220             // if all elements are added then this is OK
01221             edgeMaxCoF_[eLID[jj]][edge_MaxCof[jj]] = cellLID;
01222             SUNDANCE_MSG3(verb() , "Edge MaxCoFacet eLID[jj]:" << eLID[jj] << " edge_MaxCof[jj]:" << edge_MaxCof[jj] << " cellLID:" << cellLID );
01223         }
01224         // face maxCoFac
01225         for (int jj = 0 ; jj < 6 ; jj++){
01226           fLID[jj] = coarseFaceLID[fInd[jj]];
01227             // if all elements are added then this is OK
01228             faceMaxCoF_[fLID[jj]][face_MaxCof[jj]] = cellLID;
01229             SUNDANCE_MSG3(verb() , "Face MaxCoFacet fLID[jj]:" << fLID[jj] << " face_MaxCof[jj]:" << face_MaxCof[jj] << " cellLID:" << cellLID );
01230         }
01231   }
01232   // basic rectangular mesh is build
01233 }
01234 
01235 // -----------
01236 bool HNMesh3D::oneRefinementIteration(){
01237 
01238     int nrActualCell = nrElem_[3];
01239     bool rtn = false;
01240     SUNDANCE_MSG3(verb() , " HNMesh3D::oneRefinementIteration, start one refinement iteration cycle ");
01241     // we iterate only over the existing cells (not the ones which will be later created)
01242   for (int i=0 ; i < nrActualCell ; i++){
01243     // cell is owned by the current processor, and is leaf and is inside the mesh domain
01244       SUNDANCE_MSG3(verb() , " Test cell " << i << ", elementOwner_[3][i]:" << elementOwner_[3][i] <<
01245                          ", isCellLeaf_[i]:" << isCellLeaf_[i] << ", out:" << (!isCellOut_[i]));
01246 
01247     if ( (isCellLeaf_[i] == true) )
01248       //  mark neighbors for refinements if because of the hanging nodes a refinement is not possible, regardless of the IN or OUT of Mesh domain
01249     {
01250       // check if refinement is needed and possible, none of the edges can be hanging (we could check also vertexes and faces as well)
01251       Array<int>& cellsEdges = cellsEdges_[i];
01252             bool doRefined = true;
01253             bool refFunction = false;
01254             for (int jj = 0 ; jj < cellsEdges.size() ; jj++){
01255               SUNDANCE_MSG3(verb() , " eLID: " << cellsEdges[jj] << ", isHanging:" << isEdgeHanging_[cellsEdges[jj]]);
01256               doRefined = ( doRefined && ((isEdgeHanging_[cellsEdges[jj]]) == false) );
01257             }
01258             // --- if refinement is possible
01259             SUNDANCE_MSG3(verb() , " is possible to refine cell nr: " << i << ", doRefined:" << doRefined);
01260             // call refinement function
01261       Array<int>& cellsVertex = cellsPoints_[i];
01262       Point h = points_[cellsVertex[7]] - points_[cellsVertex[0]];
01263       Point p2 = points_[cellsVertex[0]] + 0.5*h;
01264       SUNDANCE_MSG3(verb() , " points_[cellsVertex[0]]: " << points_[cellsVertex[0]]);
01265       SUNDANCE_MSG3(verb() , " points_[cellsVertex[7]]: " << points_[cellsVertex[7]]);
01266       refFunction = ( (refineCell_[i] == 1) || refineClass_.refine( cellLevel_[i] , p2 , h ) );
01267 
01268             // decide if we refine this cell
01269             SUNDANCE_MSG3(verb() , " execute refinement on cell nr: " << i << ", refFunction:" << refFunction);
01270             if (doRefined && refFunction)
01271             {
01272               // -- call the function to refine the actual cell ---
01273               refineCell(i);
01274               rtn = true;
01275               refineCell_[i] = 0;
01276             }
01277             else
01278             {
01279               // Cell can not be refined
01280                 // we might use only edges
01281               if (refFunction) {
01282                     // now take all hanging edge neighbors
01283                     for (int jj = 0 ; jj < cellsEdges.size() ; jj++)
01284                       if (isEdgeHanging_[cellsEdges[jj]]){
01285                         // get the parent cell
01286                         int cLevel = cellLevel_[i];
01287                         int parentID = parentCellLID_[i];
01288                         int parentCEdge = cellsEdges_[parentID][jj];
01289                         int refCell = -1;
01290                         // take all maxCoFacets
01291                         for (int coF = 0 ; coF < 4 ; coF++){
01292                           refCell = edgeMaxCoF_[parentCEdge][coF];
01293                 // refCell should be refined and mark for refinement
01294                 if ( (refCell >= 0) && (cellLevel_[refCell] < cLevel) && (isCellLeaf_[refCell])){
01295                   // todo: in some particular case this leads to error, (debug that error)
01296                   // when in one points 2 different level meet (so we do a conservative refinement in 3D)
01297                   refineCell_[refCell] = 1;
01298                   rtn = true;
01299                   //SUNDANCE_MSG3( verb() , " HNMesh3D::oneRefinementIteration refineCell_[refCell] = 1" << refCell);
01300                 }
01301                         }
01302                       }
01303               }
01304             }
01305     }
01306   }
01307 
01308   SUNDANCE_MSG3(verb() , " HNMesh3D::oneRefinementIteration DONE with one refinement iteration");
01309   // return if there was refinement or attempt to refine
01310   return rtn;
01311 }
01312 
01313 // -------- refine cell cellID (assuming all conditions are satisfied)--
01314 void HNMesh3D::refineCell(int cellLID){
01315 
01316     // data initialization
01317   int cellOwner = elementOwner_[3][cellLID];
01318   Point p = points_[cellsPoints_[cellLID][0]];
01319   Point h = points_[cellsPoints_[cellLID][7]] - points_[cellsPoints_[cellLID][0]];
01320 
01321     // the created vertex, edge and cell LIDs
01322     Array<int> vertexLIDs(64,-1);
01323     // some of the vertexes already exist
01324     vertexLIDs[0] = cellsPoints_[cellLID][0];  vertexLIDs[3] = cellsPoints_[cellLID][1];
01325     vertexLIDs[12] = cellsPoints_[cellLID][2]; vertexLIDs[15] = cellsPoints_[cellLID][3];
01326     vertexLIDs[48] = cellsPoints_[cellLID][4]; vertexLIDs[51] = cellsPoints_[cellLID][5];
01327     vertexLIDs[60] = cellsPoints_[cellLID][6]; vertexLIDs[63] = cellsPoints_[cellLID][7];
01328     Array<int> edgeLIDs(144,-1);
01329     Array<int> faceLIDs(108,-1);
01330     // the cell IDs can be determined in advance
01331     Array<int> cellLIDs(27,-1);
01332     for (int c = 0; c < 27 ; cellLIDs[c] = nrElem_[3] + c , c++);
01333 
01334     // the parent cell is no leaf any more
01335   isCellLeaf_[cellLID] = false;
01336 
01337     SUNDANCE_MSG3(verb() , " ========== HNMesh3D::refineCell, cellLID:" << cellLID << " ==========");
01338 
01339     Array<int> ind(3,-1);
01340     for (int childCell = 0 ; childCell < 27 ; childCell++){
01341         Array<int> currCellV(8,-1);
01342         Array<int> currCellE(12,-1);
01343         Array<int> currCellF(6,-1);
01344 
01345       // calculate index
01346       ind[0] = ( (childCell % 9) % 3);
01347       ind[1] = ( (childCell % 9) / 3);
01348       ind[2] = ( childCell / 9);
01349       // calculate all index
01350       updateLocalCoarseNumbering( ind[0] , ind[1] , ind[2] , 3 , 3);
01351 
01352       // ------------ VERTEX ----------------
01353       for (int v = 0; v < 8 ; v++){
01354         int  vertexOwner = cellOwner;
01355         bool vertexIsHanging = false;
01356         bool useEdge = true;
01357         int pIndex = 0 , pOffset = 0 , pID = 0;
01358         // look for existing vertex
01359         if ( vertexToParentEdge[vInd[v]] >= 0){
01360           if ( vertexToParentEdge[vInd[v]] > 19){
01361           useEdge = false;
01362           pIndex = vertexToParentEdge[vInd[v]] - 20;
01363           pID = cellsFaces_[cellLID][ pIndex ];
01364           pOffset = vertexInParentIndex[vInd[v]] - 20;
01365           SUNDANCE_MSG3(verb() , "Vertex -> Face vInd[v]:" << vInd[v] << " pIndex: " << pIndex << " pID:" << pID << " pOffset:" << pOffset);
01366           SUNDANCE_MSG3(verb() , " cellsFaces:" << cellsFaces_[cellLID] << " elementOwner_[2][pID]:" << elementOwner_[2][pID]);
01367           vertexOwner = elementOwner_[2][pID];
01368           vertexIsHanging = ( numMaxCofacets_ID( 2 , pID ) > 1);
01369           } else {
01370           pIndex = vertexToParentEdge[vInd[v]];
01371           pID = cellsEdges_[cellLID][ pIndex ];
01372           pOffset = vertexInParentIndex[vInd[v]];
01373           SUNDANCE_MSG3(verb() , "Vertex -> Edge vInd[v]:" << vInd[v] << " pIndex: " << pIndex << " pID:" << pID << " pOffset:" << pOffset);
01374           SUNDANCE_MSG3(verb() , " cellsEdges:" << cellsEdges_[cellLID] << " elementOwner_[1][pID]:" << elementOwner_[1][pID]);
01375           vertexOwner = elementOwner_[1][pID];
01376           vertexIsHanging = ( numMaxCofacets_ID( 1 , pID ) > 1);
01377           }
01378         }
01379         // see if the vertex already exists
01380         if ( (vertexLIDs[vInd[v]] < 0) && (vertexToParentEdge[vInd[v]] >= 0) ){
01381                vertexLIDs[vInd[v]] = getHangingElement(0, useEdge, pID , pOffset );
01382         }
01383       SUNDANCE_MSG3(verb() , "Vertex vInd[v]:" << vInd[v] << " pIndex: " << pIndex << " pID:" << pID << " pOffset:" << pOffset);
01384             // create vertex if is not already created
01385         if ( vertexLIDs[vInd[v]] < 0){
01386           Array<int> maxCoF(8,-1);
01387           addVertex( nrElem_[0] , vertexOwner , vertexIsHanging ,
01388                  p[0] + h[0]*vertex_X[vInd[v]] , p[1] + h[1]*vertex_Y[vInd[v]] , p[2] + h[2]*vertex_Z[vInd[v]] , maxCoF);
01389           vertexLIDs[vInd[v]] = nrElem_[0] - 1;
01390           // add to parent elem if this is hanging
01391           if (vertexIsHanging)
01392              addHangingElement(0 , vertexLIDs[vInd[v]] , useEdge , pID , pOffset);
01393         }
01394         currCellV[v] = vertexLIDs[vInd[v]];
01395       // set MaxCoFacet
01396         SUNDANCE_MSG3(verb() , " vertexLIDs[vInd[v]]: " << vertexLIDs[vInd[v]] );
01397         pointMaxCoF_[ vertexLIDs[vInd[v]] ][v] = cellLIDs[childCell];
01398         // set maxCofacet also in other directions  ... not necessary
01399       }
01400 
01401       // ------------ EDGES ----------------
01402       for (int e = 0; e < 12 ; e++){
01403         int  edgeOwner = cellOwner;
01404         bool edgeIsHanging = false;
01405         bool useEdge = true;
01406         int pIndex = 0 , pOffset = 0 , pID = 0;
01407         // look for existing edge
01408         if ( edgeToParentEdge[eInd[e]] >= 0){
01409           if ( edgeToParentEdge[eInd[e]] > 19){
01410           useEdge = false;
01411           pIndex = edgeToParentEdge[eInd[e]] - 20;
01412           pID = cellsFaces_[cellLID][ pIndex ];
01413           pOffset = edgeInParentIndex[eInd[e]] - 20;
01414           SUNDANCE_MSG3(verb() , "Edge -> Face eInd[e]:" << eInd[e] <<" pIndex: " << pIndex << " pID:" << pID << " pOffset:" << pOffset);
01415           SUNDANCE_MSG3(verb() , " cellsFaces:" << cellsFaces_[cellLID] );
01416           edgeOwner = elementOwner_[2][pID];
01417           edgeIsHanging = ( numMaxCofacets_ID( 2 , pID ) > 1);
01418           } else {
01419           pIndex = edgeToParentEdge[eInd[e]];
01420           pID = cellsEdges_[cellLID][ pIndex ];
01421           pOffset = edgeInParentIndex[eInd[e]];
01422           SUNDANCE_MSG3(verb() , "Edge -> Edge eInd[e]:" << eInd[e] <<" pIndex: " << pIndex << " pID:" << pID << " pOffset:" << pOffset);
01423           //SUNDANCE_MSG3(verb() , " cellsEdges:" << cellsEdges_[cellLID] );
01424           edgeOwner = elementOwner_[1][pID];
01425           edgeIsHanging = ( numMaxCofacets_ID( 1 , pID ) > 1);
01426           }
01427         }
01428         // see if the edge already exists
01429         if ( (edgeLIDs[eInd[e]] < 0) && ( edgeToParentEdge[eInd[e]] >= 0) ){
01430           edgeLIDs[eInd[e]] = getHangingElement( 1 , useEdge, pID , pOffset );
01431         }
01432         SUNDANCE_MSG3(verb() , "Edge eInd[e]:" << eInd[e] <<" pIndex: " << pIndex << " pID:" << pID << " pOffset:" << pOffset);
01433         if ( edgeLIDs[eInd[e]] < 0){
01434           Array<int> maxCoF(4,-1);
01435           Array<int> edgeVertexs(2,-1);
01436           edgeVertexs[0] = currCellV[edge_Points_localIndex[e][0]]; edgeVertexs[1] = currCellV[edge_Points_localIndex[e][1]];
01437             // create edges for the current cell
01438           addEdge( nrElem_[1] , edgeOwner , edgeIsHanging , edge_Orientation[e] , edgeVertexs , maxCoF );
01439           edgeLIDs[eInd[e]] = nrElem_[1] - 1;
01440           // add to parent elem if this is hanging
01441           if (edgeIsHanging)
01442             addHangingElement(1 , edgeLIDs[eInd[e]] , useEdge , pID , pOffset);
01443         }
01444         currCellE[e] = edgeLIDs[eInd[e]];
01445         // set MaXCoFacet
01446         edgeMaxCoF_[edgeLIDs[eInd[e]]][edge_MaxCof[e]] = cellLIDs[childCell];
01447         SUNDANCE_MSG3(verb() , " edgeLIDs[eInd[e]]: " << edgeLIDs[eInd[e]] );
01448         // set maxCofacet also in other directions  ... not necessary
01449       }
01450 
01451       // ------------ FACES ----------------
01452       for (int f = 0; f < 6 ; f++){
01453         int  faceOwner = cellOwner;
01454         bool faceIsHanging = false;
01455         bool useEdge = false;
01456         int pIndex = 0 , pOffset = 0 , pID = 0;
01457         // look for existing face
01458         if ( faceToParentFace[fInd[f]] >= 0 ){
01459           pIndex = faceToParentFace[fInd[f]];
01460           pID = cellsFaces_[cellLID][ pIndex ];
01461           pOffset = faceInParentIndex[fInd[f]];
01462           SUNDANCE_MSG3(verb() , " cellsFaces:" << cellsFaces_[cellLID] );
01463           faceOwner = elementOwner_[2][pID];
01464           faceIsHanging = ( numMaxCofacets_ID( 2 , pID ) > 1);
01465         }
01466         // see if the face already exists
01467         if ( (faceLIDs[fInd[f]] < 0) && ( faceToParentFace[fInd[f]] >= 0 )){
01468           faceLIDs[fInd[f]] = getHangingElement( 2 , useEdge, pID , pOffset );
01469         }
01470           SUNDANCE_MSG3(verb() , "Face -> Face pIndex: " << pIndex << " pID:" << pID << " pOffset:" << pOffset);
01471         // add face if necessary
01472         if ( faceLIDs[fInd[f]] < 0){
01473           Array<int> maxCoF(2,-1);
01474           Array<int> faceVertexs(4,-1);
01475           faceVertexs[0] = currCellV[face_Points_localIndex[f][0]]; faceVertexs[1] = currCellV[face_Points_localIndex[f][1]];
01476           faceVertexs[2] = currCellV[face_Points_localIndex[f][2]]; faceVertexs[3] = currCellV[face_Points_localIndex[f][3]];
01477           Array<int> faceEdges(4,-1);
01478           faceEdges[0] = currCellE[face_Edges_localIndex[f][0]]; faceEdges[1] = currCellE[face_Edges_localIndex[f][1]];
01479           faceEdges[2] = currCellE[face_Edges_localIndex[f][2]]; faceEdges[3] = currCellE[face_Edges_localIndex[f][3]];
01480             //create all faces for the current cell
01481           addFace( nrElem_[2] , faceOwner , faceIsHanging , face_Orientation[f] , faceVertexs , faceEdges , maxCoF );
01482           faceLIDs[fInd[f]] = nrElem_[2] - 1;
01483           // add to parent elem if this is hanging
01484           if (faceIsHanging)
01485             addHangingElement(2 , faceLIDs[fInd[f]] , useEdge , pID , pOffset);
01486         }
01487         // set MaxCoFacet
01488         currCellF[f] = faceLIDs[fInd[f]];
01489         faceMaxCoF_[ currCellF[f] ][face_MaxCof[f]] = cellLIDs[childCell];
01490         SUNDANCE_MSG3(verb() , " faceLIDs[fInd[f]]: " << faceLIDs[fInd[f]] );
01491         // set maxCofacet also in other directions  ... not necessary
01492       }
01493 
01494       // ------------ CELL ----------------
01495       addCell( nrElem_[3] , cellOwner , childCell , cellLID ,
01496           cellLevel_[cellLID] + 1 , currCellF , currCellE , currCellV );
01497       // append this child to the father list
01498       cellsChildren_[cellLID].append(cellLIDs[childCell]);
01499     }
01500 }
01501 
01502 void HNMesh3D::addHangingElement(int cellDim, int cellID ,bool useEdge,
01503     int parentID , int parentOffset){
01504   // store in edge
01505   if (useEdge){
01506     if (!edgeHangingElmStore_.containsKey(parentID)){
01507       Array<int> hnInfo(6,-1);
01508       hnInfo[5] = numMaxCofacets_ID( 1 , parentID );
01509       hangingAccessCount_[parentID] = hnInfo[5];
01510       edgeHangingElmStore_.put( parentID , hnInfo );
01511     }
01512     const Array<int>& hnInfo = edgeHangingElmStore_.get(parentID);
01513     Array<int> tmp_vect(hnInfo.size());
01514     for (int ii = 0; ii < hnInfo.size() ; ii++) tmp_vect[ii] = hnInfo[ii];
01515         int realOffset = 0;
01516     // point in edge
01517     if (cellDim == 0){ realOffset = 0;}
01518     // edge in edge
01519     else{ realOffset = 2; }
01520     // store hanging element
01521         SUNDANCE_MSG3(verb() ,"HNMesh3D::addHangingElement EDGE  realOffset:" << realOffset << " parentOffset:" << parentOffset);
01522         SUNDANCE_MSG3(verb() ,"HNMesh3D::addHangingElement EDGE i:" << realOffset+parentOffset <<" hnInfo:" << hnInfo);
01523     tmp_vect[realOffset+parentOffset] = cellID;
01524     // store the new vector (with the updated information)
01525     edgeHangingElmStore_.remove( parentID );
01526     edgeHangingElmStore_.put( parentID , tmp_vect );
01527   }
01528   // store in face
01529   else{
01530     if (!faceHangingElmStore_.containsKey(parentID)){
01531       Array<int> hnInfo(25,-1);
01532       faceHangingElmStore_.put( parentID , hnInfo );
01533     }
01534     const Array<int>& hnInfo = faceHangingElmStore_.get(parentID);
01535     Array<int> tmp_vect(hnInfo.size());
01536         for (int ii = 0; ii < hnInfo.size() ; ii++) tmp_vect[ii] = hnInfo[ii];
01537         int realOffset = 0;
01538         // vertex in face
01539     if (cellDim == 0) { realOffset = 0; }
01540     // edge in face
01541     else if (cellDim == 1) { realOffset = 4; }
01542     // face in face
01543     else { realOffset = 16; }
01544     // store hanging element
01545         SUNDANCE_MSG3(verb() ,"HNMesh3D::addHangingElement FACE  realOffset:" << realOffset << " parentOffset:" << parentOffset);
01546         SUNDANCE_MSG3(verb() ,"HNMesh3D::addHangingElement FACE i:" << realOffset+parentOffset <<" hnInfo:" << hnInfo);
01547     tmp_vect[realOffset+parentOffset] = cellID;
01548     // store the new vector with the updated information
01549     faceHangingElmStore_.remove( parentID );
01550     faceHangingElmStore_.put( parentID , tmp_vect );
01551   }
01552 }
01553 
01554 int HNMesh3D::getHangingElement(int cellDim, bool useEdge, int parentID , int parentOffset){
01555   int rtn = -1;
01556   int realOffset = 0;
01557   if (useEdge){
01558     // get point from edge
01559     if (cellDim == 0){ realOffset = 0;}
01560     // get edge from edge
01561     else{ realOffset = 2; }
01562         if (edgeHangingElmStore_.containsKey(parentID)){
01563          const Array<int>& hnInfo = edgeHangingElmStore_.get(parentID);
01564          rtn = hnInfo[realOffset+parentOffset];
01565          SUNDANCE_MSG3(verb() ,"HNMesh3D::getHangingElement EDGE rtn = " << rtn << " realOffset:" << realOffset << " parentOffset:" << parentOffset);
01566          SUNDANCE_MSG3(verb() ,"HNMesh3D::getHangingElement EDGE i:" << realOffset+parentOffset <<" hnInfo:" << hnInfo);
01567          // mark stored elements as not hanging
01568          if ( rtn >= 0){
01569            if ((cellDim == 0) && (parentOffset == 1)) {
01570             if (hangingAccessCount_[parentID] <= 2){
01571             isPointHanging_[hnInfo[0]] = false; isPointHanging_[hnInfo[1]] = false;
01572             } else {
01573              //the edge will we accessed at the last time so that has to decrement
01574             }
01575            }
01576          if ((cellDim == 1) && (parentOffset == 2)) {
01577             if (hangingAccessCount_[parentID] <= 2){
01578             isEdgeHanging_[hnInfo[2]] = false; isEdgeHanging_[hnInfo[3]] = false;
01579             isEdgeHanging_[hnInfo[4]] = false;
01580             } else {
01581              hangingAccessCount_[parentID]--;
01582             }
01583          }
01584          }
01585         }
01586   }
01587   else
01588   {
01589     // get point from face
01590     if (cellDim == 0) { realOffset = 0; }
01591     // get edge from face
01592     else if (cellDim == 1) { realOffset = 4; }
01593     // get face from face
01594     else { realOffset = 16; }
01595         if (faceHangingElmStore_.containsKey(parentID)){
01596          const Array<int>& hnInfo = faceHangingElmStore_.get(parentID);
01597          rtn = hnInfo[realOffset+parentOffset];
01598          SUNDANCE_MSG3(verb() ,"HNMesh3D::getHangingElement FACE rtn = " << rtn << " realOffset:" << realOffset << " parentOffset:" << parentOffset);
01599          SUNDANCE_MSG3(verb() ,"HNMesh3D::getHangingElement FACE i:" << realOffset+parentOffset <<" hnInfo:" << hnInfo);
01600          // mark element as not hanging
01601          if ( rtn >= 0){
01602            if (cellDim == 0) {  isPointHanging_[rtn] = false; }
01603          else if (cellDim == 1) { isEdgeHanging_[rtn] = false; }
01604          else { isFaceHanging_[rtn] = false; }
01605          }
01606         }
01607   }
01608   return rtn; // Wall
01609 }
01610 
01611 int HNMesh3D::numMaxCofacets_ID(int cellDim, int cellID)
01612 {
01613   int rtn = -1;
01614     if (cellDim==1) { // edge MaxCoFacet
01615         int LID = cellID;
01616         int sum = 0;
01617         SUNDANCE_MSG3(verb() ,"HNMesh3D::numMaxCofacets_ID ID:" << LID << " edgeMaxCoF_[LID] = " << edgeMaxCoF_[LID] );
01618         for (int i = 0 ; i < 4 ; i++){
01619           if (edgeMaxCoF_[LID][i] >= 0)
01620             sum++;
01621         }
01622         // return the value, how many cells has this point, on the leaf level
01623         rtn = sum;
01624     }
01625     else if (cellDim==2) { // face MaxCoFacet
01626         int LID = cellID;
01627         int sum = 0;
01628         SUNDANCE_MSG3(verb() ,"HNMesh3D::numMaxCofacets_ID ID:" << LID << " faceMaxCoF_[LID] = " << faceMaxCoF_[LID] );
01629         for (int i = 0 ; i < 2 ; i++){
01630           if (faceMaxCoF_[LID][i] >= 0)
01631             sum++;
01632         }
01633         // return the value, how many cells has this point, on the leaf level
01634         rtn = sum;
01635     }
01636     return rtn;
01637 }
01638 
01639 // -----------
01640 void HNMesh3D::createLeafNumbering(){
01641 
01642   // set all leaf numbers to -1
01643 
01644   // - iterate trough the mesh and in the leaf cells , distribute leaf numbering
01645   // , detect if one cell is leaf ()
01646   // , have a tree similar tree traversal ... todo: later
01647 
01648   SUNDANCE_MSG3(verb() , "HNMesh3D::createLeafNumbering nrPoint:" << nrElem_[0] << " , nrEdge:"
01649       << nrElem_[1] << ", nrFace:" << nrElem_[2] << ", nrCell:" << nrElem_[3]);
01650   // we resize the leafID - > global
01651   vertexGIDToLeafMapping_.resize(nrElem_[0],-1);
01652   for (int dd = 0 ; dd < nrElem_[0] ; dd++) vertexGIDToLeafMapping_[dd] = -1;
01653   vertexLeafToGIDMapping_.resize(nrElem_[0],-1);
01654   for (int dd = 0 ; dd < nrElem_[0] ; dd++) vertexLeafToGIDMapping_[dd] = -1;
01655 
01656   edgeGIDToLeafMapping_.resize(nrElem_[1],-1);
01657   for (int dd = 0 ; dd < nrElem_[1] ; dd++) edgeGIDToLeafMapping_[dd] = -1;
01658   edgeLeafToGIDMapping_.resize(nrElem_[1],-1);
01659   for (int dd = 0 ; dd < nrElem_[1] ; dd++) edgeLeafToGIDMapping_[dd] = -1;
01660 
01661   faceGIDToLeafMapping_.resize(nrElem_[2],-1);
01662   for (int dd = 0 ; dd < nrElem_[2] ; dd++) faceGIDToLeafMapping_[dd] = -1;
01663   faceLeafToGIDMapping_.resize(nrElem_[2],-1);
01664   for (int dd = 0 ; dd < nrElem_[2] ; dd++) faceLeafToGIDMapping_[dd] = -1;
01665 
01666   cellGIDToLeafMapping_.resize(nrElem_[3],-1);
01667   for (int dd = 0 ; dd < nrElem_[3] ; dd++) cellGIDToLeafMapping_[dd] = -1;
01668   cellLeafToGIDMapping_.resize(nrElem_[3],-1);
01669   for (int dd = 0 ; dd < nrElem_[3] ; dd++) cellLeafToGIDMapping_[dd] = -1;
01670 
01671   nrVertexLeafGID_ = 0; nrCellLeafGID_ = 0; nrEdgeLeafGID_ = 0; nrFaceLeafGID_ = 0;
01672 
01673   nrVertexLeafLID_ = 0; nrCellLeafLID_ = 0; nrEdgeLeafLID_ = 0;
01674   vertexLIDToLeafMapping_.resize(nrElem_[0],-1);
01675   for (int dd = 0 ; dd < nrElem_[0] ; dd++) vertexLIDToLeafMapping_[dd] = -1;
01676   vertexLeafToLIDMapping_.resize(nrElem_[0],-1);
01677   for (int dd = 0 ; dd < nrElem_[0] ; dd++) vertexLeafToLIDMapping_[dd] = -1;
01678 
01679   edgeLIDToLeafMapping_.resize(nrElem_[1],-1);
01680   for (int dd = 0 ; dd < nrElem_[1] ; dd++) edgeLIDToLeafMapping_[dd] = -1;
01681   edgeLeafToLIDMapping_.resize(nrElem_[1],-1);
01682   for (int dd = 0 ; dd < nrElem_[1] ; dd++) edgeLeafToLIDMapping_[dd] = -1;
01683 
01684   faceLIDToLeafMapping_.resize(nrElem_[2],-1);
01685   for (int dd = 0 ; dd < nrElem_[2] ; dd++) faceLIDToLeafMapping_[dd] = -1;
01686   faceLeafToLIDMapping_.resize(nrElem_[2],-1);
01687   for (int dd = 0 ; dd < nrElem_[2] ; dd++) faceLeafToLIDMapping_[dd] = -1;
01688 
01689   cellLIDToLeafMapping_.resize(nrElem_[3],-1);
01690   for (int dd = 0 ; dd < nrElem_[3] ; dd++) cellLIDToLeafMapping_[dd] = -1;
01691   cellLeafToLIDMapping_.resize(nrElem_[3],-1);
01692   for (int dd = 0 ; dd < nrElem_[3] ; dd++) cellLeafToLIDMapping_[dd] = -1;
01693 
01694   SUNDANCE_MSG3(verb() , "HNMesh3D::createLeafNumbering , start assigning leaf numbers");
01695 
01696   // look for those leaf cells which points have a cell which maxCoFacet owner = myRank_
01697   // only those will have an LID
01698   Array<bool> hasCellLID(nrElem_[3],false);
01699 
01700   for (int ind = 0 ; ind < nrElem_[3] ; ind++){
01701     Array<int>& vertexIDs = cellsPoints_[ind];
01702     hasCellLID[ind] = false;
01703     for (int v = 0 ; v < 8 ; v++){
01704       Array<int>& maxCoFacet = pointMaxCoF_[vertexIDs[v]];
01705       hasCellLID[ind] =  ( hasCellLID[ind]
01706           || ( (maxCoFacet[0] >= 0) && (elementOwner_[3][maxCoFacet[0]] == myRank_) )
01707                     || ( (maxCoFacet[1] >= 0) && (elementOwner_[3][maxCoFacet[1]] == myRank_) )
01708                     || ( (maxCoFacet[2] >= 0) && (elementOwner_[3][maxCoFacet[2]] == myRank_) )
01709                     || ( (maxCoFacet[3] >= 0) && (elementOwner_[3][maxCoFacet[3]] == myRank_) )
01710                     || ( (maxCoFacet[4] >= 0) && (elementOwner_[3][maxCoFacet[4]] == myRank_) )
01711                     || ( (maxCoFacet[5] >= 0) && (elementOwner_[3][maxCoFacet[5]] == myRank_) )
01712                     || ( (maxCoFacet[6] >= 0) && (elementOwner_[3][maxCoFacet[6]] == myRank_) )
01713                     || ( (maxCoFacet[7] >= 0) && (elementOwner_[3][maxCoFacet[7]] == myRank_) )) ;
01714 
01715       // add cells with hanging nodes which have contribution to element which are owned by this processor
01716       // if vertex is hanging look into the parent cell at the same index and if the owner is myRank_ then add
01717       // to the cells which should be processed
01718       if ( (hasCellLID[ind] == false) && (isPointHanging_[vertexIDs[v]] == true)){
01719         int parentID = parentCellLID_[ind];
01720         Array<int>& parentVertexIDs = cellsPoints_[parentID];
01721         hasCellLID[ind] = hasCellLID[ind] || (elementOwner_[0][parentVertexIDs[v]] == myRank_);
01722       }
01723     }
01724     SUNDANCE_MSG3(verb() , "HNMesh3D::createLeafNumbering Cell ID :" << ind << " should be LID: " << hasCellLID[ind] <<
01725         " ,isCellLeaf_[ind]:" << isCellLeaf_[ind]);
01726   }
01727 
01728   //  treat special case, so that each hanging element has its parents
01729   // if we add one cell check hanging face, then add the maxCoF from the parent face if is leaf
01730   // if this is not successful then do the same thing for edges
01731   // - from each hanging edge there should be at least one cell on this processor which contains that parent edge !
01732   bool check_Ghost_cells = true;
01733   while (check_Ghost_cells){
01734     check_Ghost_cells = false;
01735       for (int ind = 0 ; ind < nrElem_[3] ; ind++){
01736        if ( (hasCellLID[ind] == true) && (elementOwner_[3][ind] != myRank_ ) ){
01737         bool lookforEdges = true;
01738         // check faces
01739         Array<int>& faceIDs = cellsFaces_[ind];
01740         for (int ii = 0 ; ii < 6 ; ii++ ){
01741           // if the face is hanging and does not belong to me
01742           if (isFaceHanging_[faceIDs[ii]] && ( elementOwner_[2][faceIDs[ii]] != myRank_)){
01743                     // get parent cells same face
01744           int parentCell = parentCellLID_[ind];
01745           Array<int>& parentfaceIDs = cellsFaces_[parentCell];
01746           for (int f = 0 ; f < 2 ; f++)
01747           if ( ( faceMaxCoF_[parentfaceIDs[ii]][f] >= 0 ) &&
01748              ( elementOwner_[3][ faceMaxCoF_[parentfaceIDs[ii]][f] ] != myRank_ ) &&
01749              ( hasCellLID[faceMaxCoF_[parentfaceIDs[ii]][f]] == false)  &&
01750              ( isCellLeaf_[faceMaxCoF_[parentfaceIDs[ii]][f]] ) ){
01751             hasCellLID[faceMaxCoF_[parentfaceIDs[ii]][f]] = true;
01752             check_Ghost_cells = true;
01753             lookforEdges = false;
01754           }
01755           }
01756         }
01757         // check edges
01758         Array<int>& edgeIDs = cellsEdges_[ind];
01759         // we have this if only
01760         if (lookforEdges){
01761           for (int ii = 0 ; ii < 12 ; ii++ ){
01762           // if the face is hanging and does not belong to me
01763           if (isEdgeHanging_[edgeIDs[ii]] && ( elementOwner_[1][edgeIDs[ii]] != myRank_)){
01764                     // get parent cells same face
01765           int parentCell = parentCellLID_[ind];
01766           Array<int>& parentEdgesIDs = cellsEdges_[parentCell];
01767           for (int f = 0 ; f < 4 ; f++)
01768           if ( ( edgeMaxCoF_[parentEdgesIDs[ii]][f] >= 0 ) &&
01769              ( elementOwner_[3][ edgeMaxCoF_[parentEdgesIDs[ii]][f] ] != myRank_ ) &&
01770              ( hasCellLID[edgeMaxCoF_[parentEdgesIDs[ii]][f]] == false)   &&
01771              ( isCellLeaf_[edgeMaxCoF_[parentEdgesIDs[ii]][f]] )
01772              ){
01773             hasCellLID[edgeMaxCoF_[parentEdgesIDs[ii]][f]] = true;
01774             check_Ghost_cells = true;
01775           }
01776           }
01777           } // from loop
01778         }// from lookforEdges IF
01779        }
01780       }
01781   }
01782 
01783   // we also have to list the cells which are not owned by the processor
01784   for (int ind = 0 ; ind < nrElem_[3] ; ind++)
01785   {
01786      // --------- GID numbering -----------
01787      // if cell is leaf and if is inside the computational domain
01788          if ( (isCellLeaf_[ind] == true) && (!isCellOut_[ind]) )
01789          {
01790            Array<int>& vertexIDs = cellsPoints_[ind];
01791              for (int v = 0; v < 8 ; v++)
01792              {
01793               SUNDANCE_MSG3(verb() , " createLeafGIDNumbering  vertexIDs[v]:" << vertexIDs[v] );
01794               if (vertexGIDToLeafMapping_[vertexIDs[v]] < 0)
01795               {
01796                  SUNDANCE_MSG3(verb() , " createLeafGIDNumbering -> VertexID:" << vertexIDs[v] << " , nrVertexLeafGID_:" << nrVertexLeafGID_ );
01797                  vertexLeafToGIDMapping_[nrVertexLeafGID_] = vertexIDs[v];
01798                  vertexGIDToLeafMapping_[vertexIDs[v]] = nrVertexLeafGID_;
01799                  nrVertexLeafGID_++;
01800               }
01801              }
01802            Array<int>& edgeIDs = cellsEdges_[ind];
01803            // for each edge check weather it already has a leaf index, if not create one
01804            for (int e = 0; e < 12 ; e++)
01805            {
01806              //SUNDANCE_MSG3(verb() , " createLeafNumbering  edgeLIDs[e]:" << edgeLIDs[e] );
01807              if (edgeGIDToLeafMapping_[edgeIDs[e]] < 0)
01808              {
01809                SUNDANCE_MSG3(verb() , " createLeafGIDNumbering -> edgeID:" << edgeIDs[e] << " , nrEdgeLeafGID_:" << nrEdgeLeafGID_ );
01810                //SUNDANCE_MSG3(verb() , " MaxCoFacet:" << edgeMaxCoF_[edgeLIDs[e]] << " edgeVertex:" << edgeVertex_[edgeLIDs[e]]);
01811                edgeLeafToGIDMapping_[nrEdgeLeafGID_] = edgeIDs[e];
01812                edgeGIDToLeafMapping_[edgeIDs[e]] = nrEdgeLeafGID_;
01813                nrEdgeLeafGID_++;
01814              }
01815            }
01816            Array<int>& faceIDs = cellsFaces_[ind];
01817            // for each face check weather it already has a leaf index, if not create one
01818            for (int f = 0; f < 6 ; f++)
01819            {
01820              //SUNDANCE_MSG3(verb() , " createLeafNumbering  edgeLIDs[e]:" << edgeLIDs[e] );
01821              if (faceGIDToLeafMapping_[faceIDs[f]] < 0)
01822              {
01823                SUNDANCE_MSG3(verb() , " createLeafGIDNumbering -> faceID:" << faceIDs[f] << " , nrFaceLeafGID_:" << nrFaceLeafGID_ );
01824                //SUNDANCE_MSG3(verb() , " MaxCoFacet:" << faceMaxCoF_[faceLIDs[e]] << " edgeVertex:" << faceVertex_[edgeLIDs[e]]);
01825                faceLeafToGIDMapping_[nrFaceLeafGID_] = faceIDs[f];
01826                faceGIDToLeafMapping_[faceIDs[f]] = nrFaceLeafGID_;
01827                nrFaceLeafGID_++;
01828              }
01829            }
01830            // create leaf index for the leaf cell
01831        SUNDANCE_MSG3(verb() , " createLeafGIDNumbering CELL cellID:" << ind << " , nrCellLeafGID_:" << nrCellLeafGID_ );
01832            cellLeafToGIDMapping_[nrCellLeafGID_] = ind;
01833            cellGIDToLeafMapping_[ind] = nrCellLeafGID_;
01834            nrCellLeafGID_++;
01835 
01836            // --------- LID numbering -----------
01837            // create leaf LID numbering , if this cell needs to be processed
01838            if (hasCellLID[ind]){
01839              // vertex
01840                  for (int v = 0; v < 8 ; v++)
01841                  {
01842                   if (vertexLIDToLeafMapping_[vertexIDs[v]] < 0)
01843                   {
01844                      SUNDANCE_MSG3(verb() , " createLeafLIDNumbering -> VertexID:" << vertexIDs[v] << " , nrVertexLeafLID_:" << nrVertexLeafLID_ );
01845                      vertexLeafToLIDMapping_[nrVertexLeafLID_] = vertexIDs[v];
01846                      vertexLIDToLeafMapping_[vertexIDs[v]] = nrVertexLeafLID_;
01847                      nrVertexLeafLID_++;
01848                   }
01849                  }
01850                // for each edge check weather it already has a leaf index, if not create one
01851                for (int e = 0; e < 12 ; e++)
01852                {
01853                  if (edgeLIDToLeafMapping_[edgeIDs[e]] < 0)
01854                  {
01855                    SUNDANCE_MSG3(verb() , " createLeafLIDNumbering -> edgeID:" << edgeIDs[e] << " , nrEdgeLeafLID_:" << nrEdgeLeafLID_ );
01856                    edgeLeafToLIDMapping_[nrEdgeLeafLID_] = edgeIDs[e];
01857                    edgeLIDToLeafMapping_[edgeIDs[e]] = nrEdgeLeafLID_;
01858                    nrEdgeLeafLID_++;
01859                  }
01860                }
01861                // face LID
01862                for (int f = 0; f < 6 ; f++)
01863                {
01864                  if (faceLIDToLeafMapping_[faceIDs[f]] < 0)
01865                  {
01866                    SUNDANCE_MSG3(verb() , " createLeafLIDNumbering -> faceID:" << faceIDs[f] << " , nrFaceLeafLID_:" << nrFaceLeafLID_ );
01867                    faceLeafToLIDMapping_[nrFaceLeafLID_] = faceIDs[f];
01868                    faceLIDToLeafMapping_[faceIDs[f]] = nrFaceLeafLID_;
01869                    nrFaceLeafLID_++;
01870                  }
01871                }
01872                // create leaf index for the leaf cell
01873                SUNDANCE_MSG3(verb() , " createLeafLIDNumbering CELL cellID:" << ind << " , nrCellLeafLID_:" << nrCellLeafLID_ );
01874                cellLeafToLIDMapping_[nrCellLeafLID_] = ind;
01875                cellLIDToLeafMapping_[ind] = nrCellLeafLID_;
01876                nrCellLeafLID_++;
01877            }
01878          }
01879   }
01880   SUNDANCE_MSG3(verb() , " nrVertexLeafGID_:" << nrVertexLeafGID_ << " nrEdgeLeafGID_:" << nrEdgeLeafGID_
01881       << " nrFaceLeafGID_:" << nrFaceLeafGID_ << " nrCellLeafGID_:" << nrCellLeafGID_ );
01882   SUNDANCE_MSG3(verb() , " nrVertexLeafLID_:" << nrVertexLeafLID_ << " nrEdgeLeafLID_:" << nrEdgeLeafLID_
01883       << " nrFaceLeafLID_:" <<nrFaceLeafLID_ << " nrCellLeafLID_:" << nrCellLeafLID_);
01884   SUNDANCE_MSG3(verb() , " vertexLIDToLeafMapping_: " << vertexLIDToLeafMapping_);
01885   SUNDANCE_MSG3(verb() , "HNMesh3D::createLeafNumbering , DONE");
01886 }

Site Contact