SundanceHNMesh3D.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                             Sundance
00005 //                 Copyright 2011 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Kevin Long (kevin.long@ttu.edu)
00038 // 
00039 
00040 /* @HEADER@ */
00041 /*
00042  * SundanceHNMesh3D.cpp
00043  *
00044  *  Created on: May 30, 2009
00045  *      Author: benk
00046  */
00047 
00048 #include "SundanceHNMesh3D.hpp"
00049 
00050 #include "SundanceMeshType.hpp"
00051 #include "SundanceCellJacobianBatch.hpp"
00052 #include "SundanceMaximalCofacetBatch.hpp"
00053 #include "SundanceMeshSource.hpp"
00054 #include "SundanceDebug.hpp"
00055 #include "SundanceOut.hpp"
00056 #include "PlayaMPIContainerComm.hpp"
00057 #include "Teuchos_Time.hpp"
00058 #include "Teuchos_TimeMonitor.hpp"
00059 #include "SundanceObjectWithVerbosity.hpp"
00060 #include "SundanceCollectiveExceptionCheck.hpp"
00061 
00062 #ifdef _MSC_VER
00063 static double log2(double x)
00064 {  
00065     return log(x)/log(2.0);  
00066 }
00067 #endif
00068 
00069 using namespace Sundance;
00070 using namespace Teuchos;
00071 using namespace std;
00072 using Playa::MPIComm;
00073 using Playa::MPIContainerComm;
00074 
00075 int HNMesh3D::offs_Points_x_[8] = {0, 1, 0, 1 , 0 , 1 , 0 , 1};
00076 
00077 int HNMesh3D::offs_Points_y_[8] = {0, 0, 1, 1 , 0 , 0 , 1 , 1};
00078 
00079 int HNMesh3D::offs_Points_z_[8] = {0, 0, 0, 0 , 1 , 1 , 1 , 1 };
00080 
00081 int HNMesh3D::edge_Points_localIndex[12][2] = { {0,1} , {0,2} , {0,4} , {1,3} , {1,5} , {2,3} , {2,6} , {3,7} ,
00082                                             {4,5} , {4,6} , {5,7} , {6,7} };
00083 
00084 int HNMesh3D::edge_Orientation[12] = { 0, 1, 2, 1, 2, 0, 2, 2, 0, 1, 1, 0 };
00085 int HNMesh3D::edge_MaxCofacetIndex[3][4] = { {0,5,8,11},{1,3,9,10},{2,4,6,7} };
00086 int HNMesh3D::edge_MaxCof[12] = { 0,0,0, 1, 1, 1, 2, 3, 2, 2, 3, 3 };
00087 
00088 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} };
00089 
00090 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}};
00091 
00092 int HNMesh3D::face_Orientation[6] = { 0,1,2,2,1,0 };
00093 int HNMesh3D::face_MaxCofacetIndex[3][2] = { {0,5},{1,4},{2,3}};
00094 int HNMesh3D::face_MaxCof[6] = { 0,0,0,1,1,1 };
00095 
00096 // -----------------------------------
00097 int HNMesh3D::vInd[8];
00098 int HNMesh3D::eInd[12];
00099 int HNMesh3D::fInd[6];
00100 
00101 // the X and the Y coordinates of the newly
00102 double HNMesh3D::vertex_X[64] =
00103                       { 0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 , 0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 ,
00104                         0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 , 0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 ,
00105                         0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 , 0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 ,
00106                         0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 , 0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 ,
00107                         0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 , 0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 ,
00108                         0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 , 0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 ,
00109                         0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 , 0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 ,
00110                         0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 , 0.0 , 1.0/3.0 , 2.0/3.0 , 1.0 };
00111 
00112 double HNMesh3D::vertex_Y[64] =
00113                       { 0.0 , 0.0 , 0.0 , 0.0 , 1.0/3.0 , 1.0/3.0 , 1.0/3.0 , 1.0/3.0 ,
00114                         2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 1.0 , 1.0 , 1.0 , 1.0 ,
00115                         0.0 , 0.0 , 0.0 , 0.0 , 1.0/3.0 , 1.0/3.0 , 1.0/3.0 , 1.0/3.0 ,
00116                         2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 1.0 , 1.0 , 1.0 , 1.0 ,
00117                         0.0 , 0.0 , 0.0 , 0.0 , 1.0/3.0 , 1.0/3.0 , 1.0/3.0 , 1.0/3.0 ,
00118                         2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 1.0 , 1.0 , 1.0 , 1.0 ,
00119                         0.0 , 0.0 , 0.0 , 0.0 , 1.0/3.0 , 1.0/3.0 , 1.0/3.0 , 1.0/3.0 ,
00120                         2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 2.0/3.0 , 1.0 , 1.0 , 1.0 , 1.0 };
00121 double HNMesh3D::vertex_Z[64] =
00122                       { 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0  , 0.0 , 0.0 ,
00123                     0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0  , 0.0 , 0.0 ,
00124                         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 ,
00125                         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 ,
00126                         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 ,
00127                         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 ,
00128                         1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0  , 1.0 , 1.0 ,
00129                         1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0  , 1.0 , 1.0 };
00130 // face index is above 20
00131 int HNMesh3D::vertexToParentEdge[64]  =
00132                       { -1,  0,  0, -1,  1, 20, 20,  3,  1, 20, 20,  3, -1,  5,  5, -1,  2, 21, 21,  4,
00133                         22, -1, -1, 23, 22, -1, -1, 23,  6, 24, 24,  7,  2, 21, 21,  4, 22, -1, -1, 23,
00134                         22, -1, -1, 23,  6, 24, 24,  7, -1,  8,  8, -1,  9, 25, 25, 10,  9, 25, 25, 10,
00135                         -1, 11, 11, -1  };
00136 //
00137 int HNMesh3D::vertexInParentIndex[64]  =
00138                       { -1,  0,  1, -1,  0, 20, 21,  0,  1, 22, 23,  1, -1,  0,  1, -1,  0, 20, 21,  0,
00139                       20, -1, -1, 20, 21, -1, -1, 21,  0, 20, 21,  0,  1, 22, 23,  1, 22, -1, -1, 22,
00140                       23, -1, -1, 23,  1, 22, 23,  1, -1,  0,  1, -1,  0, 20, 21,  0,  1, 22, 23,  1,
00141                         -1,  0,  1, -1  };
00142 //
00143 int HNMesh3D::edgeToParentEdge[144]  =
00144                       {  0,  0,  0,  1, 20, 20,  3, 20, 20, 20,  1, 20, 20,  3, 20, 20, 20,  1, 20, 20,
00145                          3,  5,  5,  5,  2, 21, 21,  4, 22, -1, -1, 23, 22, -1, -1, 23,  6, 24, 24,  7,
00146                         21, 21, 21, 22, -1, -1, 23, -1, -1, -1, 22, -1, -1, 23, -1, -1, -1, 22, -1, -1,
00147                         23, 24, 24, 24,  2, 21, 21,  4, 22, -1, -1, 23, 22, -1, -1, 23,  6, 24, 24,  7,
00148                         21, 21, 21, 22, -1, -1, 23, -1, -1, -1, 22, -1, -1, 23, -1, -1, -1, 22, -1, -1,
00149                         23, 24, 24, 24,  2, 21, 21,  4, 22, -1, -1, 23, 22, -1, -1, 23,  6, 24, 24,  7,
00150                          8,  8,  8,  9, 25, 25, 10, 25, 25, 25,  9, 25, 25, 10, 25, 25, 25,  9, 25, 25,
00151                         10, 11, 11, 11  };
00152 //
00153 int HNMesh3D::edgeInParentIndex[144]  =
00154                       {  0,  1,  2,  0, 20, 21,  0, 22, 23, 24,  1, 25, 26,  1, 27, 28, 29,  2, 30, 31,
00155                        2,  0,  1,  2,  0, 20, 21,  0, 20, -1, -1, 20, 21, -1, -1, 21,  0, 20, 21,  0,
00156                       22, 23, 24, 22, -1, -1, 22, -1, -1, -1, 23, -1, -1, 23, -1, -1, -1, 24, -1, -1,
00157                       24, 22, 23, 24,  1, 25, 26,  1, 25, -1, -1, 25, 26, -1, -1, 26,  1, 25, 26,  1,
00158                         27, 28, 29, 27, -1, -1, 27, -1, -1, -1, 28, -1, -1, 28, -1, -1, -1, 29, -1, -1,
00159                       29, 27, 28, 29,  2, 30, 31,  2, 30, -1, -1, 30, 31, -1, -1, 31,  2, 30, 31,  2,
00160                        0,  1,  2,  0, 20, 21,  0, 22, 23, 24,  1, 25, 26,  1, 27, 28, 29,  2, 30, 31,
00161                          2,  0,  1,  2  };
00162 //
00163 int HNMesh3D::faceToParentFace[108]  =
00164                       {  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  2, -1, -1,  3, -1, -1, -1,  2,
00165                         -1, -1,  3, -1, -1, -1,  2, -1, -1,  3,  4,  4,  4, -1, -1, -1, -1, -1, -1, -1,
00166                         -1, -1,  1,  1,  1,  2, -1, -1,  3, -1, -1, -1,  2, -1, -1,  3, -1, -1, -1,  2,
00167                         -1, -1,  3,  4,  4,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1,  1,  1,  1,  2, -1,
00168                         -1,  3, -1, -1, -1,  2, -1, -1,  3, -1, -1, -1,  2, -1, -1,  3,  4,  4,  4,  5,
00169                          5,  5,  5,  5,  5,  5,  5,  5  };
00170 //
00171 int HNMesh3D::faceInParentIndex[108]  =
00172                       {  0,  1,  2,  3,  4,  5,  6,  7,  8,  0,  1,  2,  0, -1, -1,  0, -1, -1, -1,  1,
00173                       -1, -1,  1, -1, -1, -1,  2, -1, -1,  2,  0,  1,  2, -1, -1, -1, -1, -1, -1, -1,
00174                       -1, -1,  3,  4,  5,  3, -1, -1,  3, -1, -1, -1,  4, -1, -1,  4, -1, -1, -1,  5,
00175                       -1, -1,  5,  3,  4,  5, -1, -1, -1, -1, -1, -1, -1, -1, -1,  6,  7,  8,  6, -1,
00176                         -1,  6, -1, -1, -1,  7, -1, -1,  7, -1, -1, -1,  8, -1, -1,  8,  6,  7,  8,  0,
00177                        1,  2,  3,  4,  5,  6,  7,  8 };
00178 
00179 
00180 HNMesh3D::HNMesh3D(int dim, const MPIComm& comm ,
00181       const MeshEntityOrder& order)
00182 : MeshBase(dim, comm , order), _comm(comm)
00183 {
00184   setVerb(0);
00185 
00186   // get the number of processors
00187   nrProc_ = MPIComm::world().getNProc();
00188   myRank_ = MPIComm::world().getRank();
00189   //------ Point storage ----
00190   points_.resize(0);
00191     nrElem_.resize(4,0);
00192   nrElemOwned_.resize(4,0);
00193   //----- Facets -----
00194     cellsPoints_.resize(0);
00195     cellsEdges_.resize(0);
00196     cellsFaces_.resize(0);
00197     isCellOut_.resize(0);
00198     faceEdges_.resize(0);
00199     facePoints_.resize(0);
00200   edgePoints_.resize(0);
00201   edgeOrientation_.resize(0);
00202   faceOrientation_.resize(0);
00203   // ----- MaxCofacets ----
00204   faceMaxCoF_.resize(0);
00205   edgeMaxCoF_.resize(0);
00206     pointMaxCoF_.resize(0);
00207     //------ Element (processor) ownership -----
00208   elementOwner_.resize(4); elementOwner_[0].resize(0); elementOwner_[1].resize(0); elementOwner_[2].resize(0); elementOwner_[3].resize(0);
00209     //---- hierarchical storage -----
00210     indexInParent_.resize(0);
00211     parentCellLID_.resize(0);
00212   cellLevel_.resize(0);
00213   isCellLeaf_.resize(0);
00214   // ---- "hanging" info storage ---
00215   isPointHanging_.resize(0);
00216   isEdgeHanging_.resize(0);
00217   // ---- hanging element and refinement (temporary) storage ---
00218   edgeHangingElmStore_ = Hashtable< int, Array<int> >();
00219   hangingAccessCount_.resize(0);
00220   faceHangingElmStore_ = Hashtable< int, Array<int> >();
00221   refineCell_.resize(0);
00222     // set the leaf counter to zero
00223   nrCellLeafGID_ = 0; nrEdgeLeafGID_ = 0; nrFaceLeafGID_ = 0; nrVertexLeafGID_ = 0;
00224   nrVertexLeafLID_ = 0; nrCellLeafLID_ = 0; nrFaceLeafLID_ = 0; nrEdgeLeafLID_ = 0;
00225 }
00226 
00227 int HNMesh3D::numCells(int dim) const  {
00228   SUNDANCE_MSG3(verb(),"HNMesh3D::numCells(int dim):   dim:" << dim );
00229   switch (dim){
00230   case 0: return nrVertexLeafLID_;
00231   case 1: return nrEdgeLeafLID_;
00232   case 2: return nrFaceLeafLID_;
00233   case 3: return nrCellLeafLID_;
00234   }
00235   return 0;
00236 }
00237 
00238 Point HNMesh3D::nodePosition(int i) const {
00239   SUNDANCE_MSG3(verb(),"HNMesh3D::nodePosition(int i)   i:"<< i);
00240     // point do not need leaf indexing
00241   return points_[vertexLeafToLIDMapping_[i]];
00242 }
00243 
00244 const double* HNMesh3D::nodePositionView(int i) const {
00245   SUNDANCE_MSG3(verb(),"HNMesh3D::nodePositionView(int i)   i:" << i);
00246   //SUNDANCE_VERB_HIGH("nodePosition(int i)");
00247   return &(points_[vertexLeafToLIDMapping_[i]][0]);;
00248 }
00249 
00250 void HNMesh3D::getJacobians(int cellDim, const Array<int>& cellLID,
00251                           CellJacobianBatch& jBatch) const
00252 {
00253 
00254     SUNDANCE_MSG3(verb(),"HNMesh3D::getJacobians  cellDim:"<<cellDim<<" _x:"<<_ofs_x<<" _y:"<<_ofs_y<<" _z:"<<_ofs_z);
00255     SUNDANCE_VERB_HIGH("getJacobians()");
00256     TEUCHOS_TEST_FOR_EXCEPTION(cellDim < 0 || cellDim > spatialDim(), std::logic_error,
00257       "cellDim=" << cellDim << " is not in expected range [0, " << spatialDim() << "]");
00258     int nCells = cellLID.size();
00259     int LID;
00260     Point pnt(0.0,0.0,0.0);
00261     jBatch.resize(cellLID.size(), spatialDim(), cellDim);
00262     if (cellDim < spatialDim()) // they need the Jacobian of a lower dinemsional element
00263     {
00264        for (int i=0; i<nCells; i++)
00265         {
00266           double* detJ = jBatch.detJ(i);
00267           switch(cellDim)
00268           {
00269             case 0:{ *detJ = 1.0;
00270               break;}
00271             case 1:{
00272           LID = edgeLeafToLIDMapping_[cellLID[i]];
00273             pnt = (points_[edgePoints_[LID][1]] - points_[edgePoints_[LID][0]]);
00274               *detJ = sqrt(pnt * pnt); // the length of the edge
00275             break;}
00276             case 2:{
00277               LID = faceLeafToLIDMapping_[cellLID[i]];
00278               int a = facePoints_[LID][0];
00279               int b = facePoints_[LID][1];
00280               int c = facePoints_[LID][2];
00281               const Point& pa = points_[a];
00282               const Point& pb = points_[b];
00283               const Point& pc = points_[c];
00284             Point directedArea = cross( pb - pa , pc - pa );
00285               *detJ = sqrt(directedArea * directedArea); // the area of the face
00286             break;}
00287             default:
00288               TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "impossible switch value "  "cellDim=" << cellDim << " in HNMesh3D::getJacobians()");
00289           }
00290         }
00291     }else{ // they request the complete Jacoby matrix for this bunch of elements
00292         //Array<double> J(cellDim*cellDim);
00293         SUNDANCE_VERB_HIGH("cellDim == spatialDim()");
00294         for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00295         {
00296           double* J = jBatch.jVals(i);
00297           switch(cellDim)
00298           {
00299             case 3:{
00300           LID = cellLeafToLIDMapping_[cellLID[i]];
00301           // Jacobi for unstructured brick this will not work, but because of linear Jacoby we only have structured brick
00302               J[0] = points_[cellsPoints_[LID][1]][0] - points_[cellsPoints_[LID][0]][0];
00303               J[1] = 0.0; J[2] = 0.0; J[3] = 0.0;
00304               J[4] = points_[cellsPoints_[LID][2]][1] - points_[cellsPoints_[LID][0]][1];
00305               J[5] = 0.0; J[6] = 0.0; J[7] = 0.0;
00306               J[8] = points_[cellsPoints_[LID][4]][2] - points_[cellsPoints_[LID][0]][2]; // the Jacobi of the brick cell
00307             SUNDANCE_MSG3(verb() , "HNMesh3D::getJacobians LID:" << LID << " X:" << J[0] << " Y:" << J[4] << " Z:" << J[8]);
00308             //SUNDANCE_MSG3(verb() , "HNMesh3D::getJacobians P0:" << points_[cellsPoints_[LID][0]] );
00309             //SUNDANCE_MSG3(verb() , "HNMesh3D::getJacobians P1:" << points_[cellsPoints_[LID][1]] );
00310             //SUNDANCE_MSG3(verb() , "HNMesh3D::getJacobians P2:" << points_[cellsPoints_[LID][2]] );
00311             //SUNDANCE_MSG3(verb() , "HNMesh3D::getJacobians P4:" << points_[cellsPoints_[LID][4]] );
00312             break;}
00313             default:
00314               TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "impossible switch value " "cellDim=" << cellDim << " in HNMesh3D::getJacobians()");
00315           }
00316         }
00317     }
00318 }
00319 
00320 void HNMesh3D::getCellDiameters(int cellDim, const Array<int>& cellLID,
00321                               Array<double>& cellDiameters) const {
00322 
00323    TEUCHOS_TEST_FOR_EXCEPTION(cellDim < 0 || cellDim > spatialDim(), std::logic_error,
00324       "cellDim=" << cellDim << " is not in expected range [0, " << spatialDim() << "]");
00325    SUNDANCE_VERB_HIGH("getCellDiameters()");
00326     cellDiameters.resize(cellLID.size());
00327     Point pnt(0.0 , 0.0 , 0.0 );
00328     int LID;
00329     if (cellDim < spatialDim())
00330     {
00331     SUNDANCE_MSG3(verb(),"HNMesh3D::getCellDiameters(), cellDim < spatialDim() ");
00332       for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00333       {
00334         switch(cellDim)
00335         {
00336           case 0:
00337                cellDiameters[i] = 1.0;
00338             break;
00339           case 1:  //length of the edge
00340           LID = edgeLeafToLIDMapping_[cellLID[i]];
00341             pnt = (points_[edgePoints_[LID][1]] - points_[edgePoints_[LID][0]]);
00342             cellDiameters[i] = sqrt(pnt * pnt); // the length of the edge
00343           break;
00344           case 2:  //length of the edge
00345           LID = faceLeafToLIDMapping_[cellLID[i]];
00346             pnt = (points_[facePoints_[LID][3]] - points_[facePoints_[LID][0]]);
00347             cellDiameters[i] = sqrt(pnt * pnt); // the diameter of the face
00348           break;
00349           default:
00350             TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "impossible switch value "  "cellDim=" << cellDim << " in HNMesh3D::getCellDiameters()");
00351         }
00352       }
00353     }
00354     else
00355     {
00356     SUNDANCE_MSG3(verb(),"HNMesh3D::getCellDiameters(), cellDim == spatialDim() ");
00357       for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00358       {
00359         switch(cellDim)
00360         {
00361           case 3:
00362             LID = cellLeafToLIDMapping_[cellLID[i]];
00363             pnt = points_[cellsPoints_[LID][7]] - points_[cellsPoints_[LID][0]];
00364             cellDiameters[i] = sqrt(pnt * pnt);
00365           break;
00366           default:
00367             TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "impossible switch value "
00368              "cellDim=" << cellDim  << " in HNMesh3D::getCellDiameters()");
00369         }
00370       }
00371     }
00372 }
00373 
00374 void HNMesh3D::pushForward(int cellDim, const Array<int>& cellLID,
00375                          const Array<Point>& refQuadPts,
00376                          Array<Point>& physQuadPts) const {
00377 
00378     SUNDANCE_MSG3(verb(),"HNMesh3D::pushForward cellDim:"<<cellDim);
00379     TEUCHOS_TEST_FOR_EXCEPTION(cellDim < 0 || cellDim > spatialDim(), std::logic_error,
00380       "cellDim=" << cellDim << " is not in expected range [0, " << spatialDim() << "]");
00381 
00382     int nQuad = refQuadPts.size();
00383     Point pnt( 0.0 , 0.0 , 0.0);
00384     Point pnt1( 0.0 , 0.0 , 0.0);
00385 
00386     if (physQuadPts.size() > 0) physQuadPts.resize(0);
00387     physQuadPts.reserve(cellLID.size() * refQuadPts.size());
00388     for (unsigned int i=0; i<(unsigned int)cellLID.size(); i++)
00389     {
00390       switch(cellDim)
00391       {
00392         case 0: // integrate one point
00393                physQuadPts.append(pnt);
00394         break;
00395         case 1:{ // integrate on one line
00396            int LID = edgeLeafToLIDMapping_[cellLID[i]];
00397              pnt = points_[edgePoints_[LID][0]];
00398              pnt1 = points_[edgePoints_[LID][1]] - points_[edgePoints_[LID][0]];
00399                for (int q=0; q<nQuad; q++) {
00400                  physQuadPts.append(pnt + (pnt1)*refQuadPts[q][0]);
00401             }
00402         break;}
00403         case 2:{
00404                int LID = faceLeafToLIDMapping_[cellLID[i]];
00405                pnt = points_[facePoints_[LID][0]];
00406                // this works only for structured, but we only work on structured quads
00407                pnt1 = points_[facePoints_[LID][3]] - points_[facePoints_[LID][0]];
00408              for (int q=0; q<nQuad; q++) {
00409                   physQuadPts.append( pnt + Point( refQuadPts[q][0] * pnt1[0] , refQuadPts[q][1] * pnt1[1] , refQuadPts[q][2] * pnt1[2]) );
00410              }
00411              break;}
00412         case 3:{
00413                int LID = cellLeafToLIDMapping_[cellLID[i]];
00414                pnt = points_[cellsPoints_[LID][0]];
00415                // this works only for structured, but we only work on structured quads
00416                pnt1 = points_[cellsPoints_[LID][7]] - points_[cellsPoints_[LID][0]];
00417              for (int q=0; q<nQuad; q++) {
00418                   physQuadPts.append( pnt + Point( refQuadPts[q][0] * pnt1[0] , refQuadPts[q][1] * pnt1[1] , refQuadPts[q][2] * pnt1[2] ) );
00419              }
00420         break;}
00421         default:
00422         TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "impossible switch value " "in HNMesh3D::getJacobians()");
00423       }
00424     }
00425 }
00426 
00427 int HNMesh3D::ownerProcID(int cellDim, int cellLID) const  {
00428    int ID = -1;
00429    if (cellDim == 0) ID = vertexLeafToLIDMapping_[cellLID];
00430      if (cellDim == 1) ID = edgeLeafToLIDMapping_[cellLID];
00431      if (cellDim == 2) ID = faceLeafToLIDMapping_[cellLID];
00432      if (cellDim == 3) ID = cellLeafToLIDMapping_[cellLID];
00433      SUNDANCE_MSG3(verb() , " HNMesh3D::ownerProcID ,cellDim:" << cellDim << ", cellLID:"
00434          << cellLID <<" ,ID:" << ID << ", ret:"<< elementOwner_[cellDim][ID] );
00435    return elementOwner_[cellDim][ID];
00436 }
00437 
00438 
00439 int HNMesh3D::numFacets(int cellDim, int cellLID,
00440                       int facetDim) const  {
00441   //SUNDANCE_VERB_HIGH("numFacets()");
00442   if (cellDim==1) { // 1 dimension
00443          return 2; //one line has 2 points
00444     }
00445     else if (cellDim==2) { // 2 dimensions
00446          return 4; //one quad has 4 edges and 4 points
00447     }
00448     else if (cellDim==3) { // brick cell
00449       if (facetDim == 0) return 8;
00450       if (facetDim == 1) return 12;
00451       if (facetDim == 2) return 6;
00452     }
00453   return -1;
00454 }
00455 
00456 int HNMesh3D::facetLID(int cellDim, int cellLID,
00457                      int facetDim, int facetIndex,
00458                      int& facetOrientation) const  {
00459 
00460   // todo: check weather facet orientation is right
00461   facetOrientation = 1;
00462   SUNDANCE_MSG3(verb(),"HNMesh3D::facetLID  cellDim:"<<cellDim<<", cellLID:"<<cellLID<<", facetDim:"<<facetDim<< ", facetIndex:" << facetIndex);
00463   int rnt = -1 , LID=-1 , tmp=-1;
00464   if (facetDim == 0){ // return the Number/ID of a Vertex
00465     if (cellDim == 3 ){
00466         LID = cellLeafToLIDMapping_[cellLID];
00467         rnt = cellsPoints_[LID][facetIndex]; tmp = rnt;
00468         rnt = vertexLIDToLeafMapping_[rnt];
00469       }
00470       else if ((cellDim==2)){
00471         LID = faceLeafToLIDMapping_[cellLID];
00472         rnt = facePoints_[LID][facetIndex]; tmp = rnt;
00473         rnt = vertexLIDToLeafMapping_[rnt];
00474       }
00475       else if ((cellDim==1)){
00476           LID = edgeLeafToLIDMapping_[cellLID];
00477           rnt = edgePoints_[LID][facetIndex]; tmp = rnt;
00478           rnt = vertexLIDToLeafMapping_[rnt];
00479       }
00480   } else if (facetDim == 1){
00481     if (cellDim == 3 ){
00482           LID = cellLeafToLIDMapping_[cellLID];
00483           rnt = cellsEdges_[LID][facetIndex]; tmp = rnt;
00484       rnt = edgeLIDToLeafMapping_[rnt];
00485       } else if ((cellDim==2)){
00486           LID = faceLeafToLIDMapping_[cellLID];
00487           rnt = faceEdges_[LID][facetIndex]; tmp = rnt;
00488       rnt = edgeLIDToLeafMapping_[rnt];
00489       }
00490   } else if (facetDim == 2){
00491     if (cellDim == 3 ){
00492           LID = cellLeafToLIDMapping_[cellLID];
00493           rnt = cellsFaces_[LID][facetIndex]; tmp = rnt;
00494       rnt = faceLIDToLeafMapping_[rnt];
00495       }
00496   }
00497   SUNDANCE_MSG3(verb()," RET = " << rnt << ", LID:" << LID << ", tmp:" <<  tmp);
00498   return rnt;
00499 }
00500 
00501 
00502 void HNMesh3D::getFacetLIDs(int cellDim,
00503                           const Array<int>& cellLID,
00504                           int facetDim,
00505                           Array<int>& facetLID,
00506                           Array<int>& facetSign) const {
00507 
00508   SUNDANCE_MSG3(verb(),"HNMesh3D::getFacetLIDs()  cellDim:"<<cellDim<<"  cellLID.size():"<<cellLID.size()<<"  facetDim:" <<facetDim);
00509     int LID = 0 , cLID , facetOrientation ;
00510     int ptr = 0;
00511 
00512     int nf = numFacets(cellDim, cellLID[0], facetDim);
00513     facetLID.resize(cellLID.size() * nf);
00514     facetSign.resize(cellLID.size() * nf);
00515     // At this moment we just use the previous function
00516   for (unsigned int i = 0 ; i < (unsigned int)cellLID.size() ; i++){
00517       cLID = cellLID[i];
00518         for (int f=0; f<nf; f++, ptr++) {
00519           // we use this->facetLID caz facetLID is already used as variable
00520         LID = this->facetLID( cellDim, cLID, facetDim, f , facetOrientation);
00521             facetLID[ptr] = LID;
00522             facetSign[ptr] = facetOrientation;
00523         }
00524   }
00525   SUNDANCE_MSG3(verb() ,"HNMesh3D::getFacetLIDs()  DONE. ");
00526 }
00527 
00528 
00529 const int* HNMesh3D::elemZeroFacetView(int cellLID) const {
00530     int LID = cellLeafToLIDMapping_[cellLID];
00531     SUNDANCE_MSG3(verb() , "HNMesh3D::elemZeroFacetView ");
00532   return (const int*)(&cellsPoints_[LID]);
00533 }
00534 
00535 
00536 int HNMesh3D::numMaxCofacets(int cellDim, int cellLID) const  {
00537   //SUNDANCE_VERB_HIGH("numMaxCofacets()");
00538   SUNDANCE_MSG3(verb() , "HNMesh3D::numMaxCofacets():  cellDim:"<<cellDim<<" cellLID:"<<cellLID );
00539   int rnt = -1;
00540 
00541   if (cellDim==0) { // point MaxCoFacet
00542     int LID = vertexLeafToLIDMapping_[cellLID];
00543         int sum = 0;
00544         SUNDANCE_MSG3(verb() ," pointMaxCoF_[LID] = " << pointMaxCoF_[LID] );
00545         for (int i = 0 ; i < 8 ; i++)
00546           if ( (pointMaxCoF_[LID][i] >= 0) && ( cellLIDToLeafMapping_[pointMaxCoF_[LID][i]] >= 0) )
00547             sum++;
00548         // return the value, how many cells has this point, on the leaf level
00549         rnt = sum;
00550     }
00551     else if (cellDim==1) { // edge MaxCoFacet
00552         int LID = edgeLeafToLIDMapping_[cellLID];
00553         int sum = 0;
00554         SUNDANCE_MSG3(verb() ," edgeMaxCoF_[LID] = " << edgeMaxCoF_[LID] );
00555         for (int i = 0 ; i < 4 ; i++)
00556           if ( (edgeMaxCoF_[LID][i] >= 0) && ( cellLIDToLeafMapping_[edgeMaxCoF_[LID][i]] >= 0) )
00557             sum++;
00558         // return the value, how many cells has this point, on the leaf level
00559         rnt = sum;
00560     }
00561     else if (cellDim==2) { // face MaxCoFacet
00562         int LID = faceLeafToLIDMapping_[cellLID];
00563         int sum = 0;
00564         SUNDANCE_MSG3(verb() ," faceMaxCoF_[LID] = " << faceMaxCoF_[LID] );
00565         for (int i = 0 ; i < 2 ; i++)
00566           if ( (faceMaxCoF_[LID][i] >= 0) && ( cellLIDToLeafMapping_[faceMaxCoF_[LID][i]] >= 0) )
00567             sum++;
00568         // return the value, how many cells has this point, on the leaf level
00569         rnt = sum;
00570     }
00571   SUNDANCE_MSG3(verb() ," RET = " << rnt );
00572   return rnt;
00573 }
00574 
00575 
00576 int HNMesh3D::maxCofacetLID(int cellDim, int cellLID,
00577                        int cofacetIndex,
00578                        int& facetIndex) const  {
00579 
00580   SUNDANCE_MSG3(verb() ,"HNMesh3D::maxCofacetLID() cellDim:"<<cellDim<<" cellLID:"<<cellLID<<" cofacetIndex:"<<cofacetIndex<< " facetIndex:"
00581       << facetIndex);
00582   int rnt =-1;
00583 
00584   if (cellDim==0) { // 0 dimension
00585     //facetIndex = cofacetIndex;
00586     int actCoFacetIndex = 0;
00587       int LID = vertexLeafToLIDMapping_[cellLID];
00588     for (int ii = 0 ; ii < 8 ; ii++){
00589       // take this maxCoFacet only if that exist and is inside
00590       if ( (pointMaxCoF_[LID][ii] >= 0) && (cellLIDToLeafMapping_[pointMaxCoF_[LID][ii]] >= 0) ){
00591         if ( actCoFacetIndex < cofacetIndex ){
00592           actCoFacetIndex++;
00593         }else{
00594           facetIndex = ii;
00595           rnt = pointMaxCoF_[LID][ii];
00596           break;
00597         }
00598       }
00599     }
00600     }
00601     else if (cellDim==1) { // 1 dimensions
00602       int maxCoFacet = 0;
00603         int LID = edgeLeafToLIDMapping_[cellLID];
00604       int orientation = edgeOrientation_[LID];
00605     SUNDANCE_MSG3(verb() ," HNMesh3D::maxCofacetLID() 1 , orientation:" << orientation );
00606         // return the index in the vector, which later will be corrected later
00607     int actCoFacetIndex = 0;
00608     for (int ii = 0 ; ii < 4 ; ii++){
00609       // take this maxCoFacet only if that exist and is inside
00610       if ( (edgeMaxCoF_[LID][ii] >= 0) && (cellLIDToLeafMapping_[edgeMaxCoF_[LID][ii]] >= 0) ){
00611         if ( actCoFacetIndex < cofacetIndex ){
00612           actCoFacetIndex++;
00613         }else{
00614           facetIndex = ii;
00615           maxCoFacet = edgeMaxCoF_[LID][ii];
00616           break;
00617         }
00618       }
00619     }
00620     // calculate the correct facetIndex of the edge in the cell of cofacetIndex
00621     facetIndex = edge_MaxCofacetIndex[orientation][facetIndex];
00622     SUNDANCE_MSG3(verb() ,"HNMesh3D::maxCofacetLID() 1 , facetIndex:" << facetIndex << " maxCoFacet = " << maxCoFacet );
00623     rnt = ( maxCoFacet );
00624     }
00625     else if (cellDim==2) { // 2 dimensions
00626       int maxCoFacet = 0;
00627         int LID = faceLeafToLIDMapping_[cellLID];
00628       int orientation = faceOrientation_[LID];
00629     SUNDANCE_MSG3(verb() ," HNMesh3D::maxCofacetLID() 2 , orientation:" << orientation );
00630         // return the index in the vector, which later will be corrected later
00631     int actCoFacetIndex = 0;
00632     for (int ii = 0 ; ii < 2 ; ii++){
00633       // take this maxCoFacet only if that exist and is inside
00634       if ( (faceMaxCoF_[LID][ii] >= 0) && (cellLIDToLeafMapping_[faceMaxCoF_[LID][ii]] >= 0) ){
00635         if ( actCoFacetIndex < cofacetIndex ){
00636           actCoFacetIndex++;
00637         }else{
00638           facetIndex = ii;
00639           maxCoFacet = faceMaxCoF_[LID][ii];
00640           break;
00641         }
00642       }
00643     }
00644     // calculate the correct facetIndex of the edge in the cell of cofacetIndex
00645     facetIndex = face_MaxCofacetIndex[orientation][facetIndex];
00646     SUNDANCE_MSG3(verb() ,"HNMesh3D::maxCofacetLID() 2 , facetIndex:" << facetIndex << " maxCoFacet = " << maxCoFacet );
00647     rnt = ( maxCoFacet );
00648     }
00649   // transform back to leaf indexing
00650   rnt = cellLIDToLeafMapping_[ rnt ];
00651 
00652   SUNDANCE_MSG3(verb() ," RET = " << rnt << ",  facetIndex:" << facetIndex);
00653   return rnt;
00654 }
00655 
00656 void HNMesh3D::getCofacets(int cellDim, int cellLID,
00657                  int cofacetDim, Array<int>& cofacetLIDs) const {
00658   // Nothing to do
00659   TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error," HNMesh3D::getCofacets() not implemented");
00660 }
00661 
00662 
00663 void HNMesh3D::getMaxCofacetLIDs(const Array<int>& cellLIDs,
00664   MaximalCofacetBatch& cofacets) const {
00665   // nothing to do here
00666   TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error," HNMesh3D::getMaxCofacetLIDs() not implemented");
00667 }
00668 
00669 
00670 int HNMesh3D::mapGIDToLID(int cellDim, int globalIndex) const  {
00671   //SUNDANCE_VERB_HIGH("mapGIDToLID()");
00672   switch (cellDim){
00673   case 0:{
00674            int ID = vertexLeafToGIDMapping_[globalIndex];
00675          SUNDANCE_MSG3(verb() , " HNMesh3D::mapGIDToLID 0 , globalIndex:" << globalIndex << " ,ID:" << ID << ", ret:"<< vertexLIDToLeafMapping_[ID]);
00676            return vertexLIDToLeafMapping_[ID];
00677         break;}
00678   case 1:{
00679          int ID = edgeLeafToGIDMapping_[globalIndex];
00680          SUNDANCE_MSG3(verb() , " HNMesh3D::mapGIDToLID 1 , globalIndex:" << globalIndex << " ,ID:" << ID << ", ret:"<< edgeLIDToLeafMapping_[ID]);
00681          return edgeLIDToLeafMapping_[ID];
00682         break;}
00683   case 2:{
00684              int ID = faceLeafToGIDMapping_[globalIndex];
00685              SUNDANCE_MSG3(verb() , " HNMesh3D::mapGIDToLID 2 , globalIndex:" << globalIndex << " ,ID:" << ID << ", ret:"<< faceLIDToLeafMapping_[ID]);
00686              return faceLIDToLeafMapping_[ID];
00687         break;}
00688   case 3:{
00689              int ID = cellLeafToGIDMapping_[globalIndex];
00690              SUNDANCE_MSG3(verb() , " HNMesh3D::mapGIDToLID 3 , globalIndex:" << globalIndex << " ,ID:" << ID << ", ret:"<< cellLIDToLeafMapping_[ID]);
00691              return cellLIDToLeafMapping_[ID];
00692         break;}
00693   }
00694   return -1; //Wall
00695 }
00696 
00697 
00698 bool HNMesh3D::hasGID(int cellDim, int globalIndex) const {
00699   //SUNDANCE_VERB_HIGH("hasGID()");
00700   // we should always have all GIDs
00701   return true;
00702 }
00703 
00704 
00705 int HNMesh3D::mapLIDToGID(int cellDim, int localIndex) const  {
00706   //SUNDANCE_VERB_HIGH("mapLIDToGID()");
00707   switch (cellDim){
00708   case 0:{
00709            int ID = vertexLeafToLIDMapping_[localIndex];
00710          SUNDANCE_MSG3(verb() , " HNMesh3D::mapLIDToGID 0 , localIndex:" << localIndex << " ,ID:" << ID << ", ret:"<< vertexGIDToLeafMapping_[ID]);
00711            return vertexGIDToLeafMapping_[ID];
00712         break;}
00713   case 1:{
00714          int ID = edgeLeafToLIDMapping_[localIndex];
00715          SUNDANCE_MSG3(verb() , " HNMesh3D::mapLIDToGID 1 , localIndex:" << localIndex << " ,ID:" << ID << ", ret:"<< edgeGIDToLeafMapping_[ID]);
00716          return edgeGIDToLeafMapping_[ID];
00717         break;}
00718   case 2:{
00719              int ID = faceLeafToLIDMapping_[localIndex];
00720              SUNDANCE_MSG3(verb() , " HNMesh3D::mapLIDToGID 2 , localIndex:" << localIndex << " ,ID:" << ID << ", ret:"<< faceGIDToLeafMapping_[ID]);
00721              return faceGIDToLeafMapping_[ID];
00722         break;}
00723   case 3:{
00724              int ID = cellLeafToLIDMapping_[localIndex];
00725              SUNDANCE_MSG3(verb() , " HNMesh3D::mapLIDToGID 3 , localIndex:" << localIndex << " ,ID:" << ID << ", ret:"<< cellGIDToLeafMapping_[ID]);
00726              return cellGIDToLeafMapping_[ID];
00727         break;}
00728   }
00729   return -1; //Wall
00730 }
00731 
00732 
00733 CellType HNMesh3D::cellType(int cellDim) const  {
00734    switch(cellDim)
00735     {
00736       case 0:  return PointCell;
00737       case 1:  return LineCell;
00738       case 2:  return QuadCell;
00739       case 3:  return BrickCell;
00740       default:
00741         return NullCell; // -Wall
00742     }
00743 }
00744 
00745 
00746 int HNMesh3D::label(int cellDim, int cellLID) const {
00747    // not used
00748    TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error," HNMesh3D::label() not implemented yet");
00749    return 0;
00750 }
00751 
00752 
00753 void HNMesh3D::getLabels(int cellDim, const Array<int>& cellLID,
00754     Array<int>& labels) const {
00755    // not used
00756    TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error," HNMesh3D::getLabels() not implemented yet");
00757 }
00758 
00759 Set<int> HNMesh3D::getAllLabelsForDimension(int cellDim) const {
00760    Set<int>                 rtn;
00761    // not used
00762    TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error," HNMesh3D::getAllLabelsForDimension() not implemented yet");
00763    return rtn;
00764 }
00765 
00766 void HNMesh3D::getLIDsForLabel(int cellDim, int label, Array<int>& cellLIDs) const {
00767     // not used
00768   TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error," HNMesh3D::getLIDsForLabel() not implemented yet");
00769 }
00770 
00771 void HNMesh3D::setLabel(int cellDim, int cellLID, int label) {
00772    // not used
00773   TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error," HNMesh3D::setLabel() not implemented yet");
00774 }
00775 
00776 
00777 void HNMesh3D::assignIntermediateCellGIDs(int cellDim) {
00778   // The GIDs are assigned
00779 }
00780 
00781 
00782 bool HNMesh3D::hasIntermediateGIDs(int dim) const {
00783   // the mesh always has intermediate cells
00784   return true; // true means they have been synchronized ... not used now
00785 }
00786 
00787 
00788 // =============================== HANGING NODE FUNCTIONS ==========================
00789 bool HNMesh3D::isElementHangingNode(int cellDim , int cellLID) const {
00790   SUNDANCE_MSG3(verb() ,"HNMesh3D::isElementHangingNode  cellDim:"<<cellDim<<" LID:"<< cellLID);
00791   if (cellDim==0) { // 1 dimension
00792       int LID = vertexLeafToLIDMapping_[cellLID];
00793     return (isPointHanging_[LID]);
00794     }
00795     else if (cellDim==1) { // 2 dimensions
00796       int LID = edgeLeafToLIDMapping_[cellLID];
00797         return (isEdgeHanging_[LID]);
00798     }
00799     else if (cellDim==2)
00800     {
00801       int LID = faceLeafToLIDMapping_[cellLID];
00802         return (isFaceHanging_[LID] );
00803         // todo:
00804         //|| isEdgeHanging_[faceEdges_[LID][0]] || isEdgeHanging_[faceEdges_[LID][1]]
00805         //|| isEdgeHanging_[faceEdges_[LID][2]] || isEdgeHanging_[faceEdges_[LID][3]] );
00806     }
00807   return false; //Wall
00808 }
00809 
00810 int HNMesh3D::indexInParent(int maxCellLID) const {
00811   int ID = cellLeafToLIDMapping_[maxCellLID];
00812   int indexInPar = indexInParent_[ID];
00813   return indexInPar;
00814 
00815 }
00816 
00817 void HNMesh3D::returnParentFacets(  int childCellLID , int dimFacets ,
00818                              Array<int> &facetsLIDs , int &parentCellLIDs ) const {
00819   int LID = cellLeafToLIDMapping_[childCellLID];
00820   parentCellLIDs = parentCellLID_[LID];
00821 
00822   SUNDANCE_MSG3( verb() , "HNMesh3D::returnParentFacets  childCellLID:"<<childCellLID<<" dimFacets:"<<dimFacets<<
00823       "  parentCellLIDs:"<< parentCellLIDs);
00824   //SUNDANCE_MSG3( verb() , "LID:"<<LID<<" parentCellLID_:"<<parentCellLID_);
00825   // this is the same for edges and for points
00826   if (dimFacets == 0){
00827     facetsLIDs.resize(8);
00828     for (int kuku = 0; kuku < 8 ; kuku++)
00829     facetsLIDs[kuku] = facetLID_tree( 3 , parentCellLIDs ,  dimFacets , kuku );
00830   }
00831   else if (dimFacets == 1){
00832     facetsLIDs.resize(12);
00833     for (int kuku = 0; kuku < 12 ; kuku++)
00834     facetsLIDs[kuku] = facetLID_tree( 3 , parentCellLIDs ,  dimFacets , kuku );
00835   }
00836   else if (dimFacets == 2){
00837     facetsLIDs.resize(6);
00838     for (int kuku = 0; kuku < 6 ; kuku++)
00839     facetsLIDs[kuku] = facetLID_tree( 3 , parentCellLIDs ,  dimFacets , kuku );
00840   }
00841   // map parent cell ID back to leaf indexing
00842   //parentCellLIDs = cellLIDToLeafMapping_[parentCellLIDs];
00843 
00844 }
00845 
00846 // only used in determining the parents
00847 int HNMesh3D::facetLID_tree(int cellDim, int cellLID,
00848                      int facetDim, int facetIndex) const{
00849     int rnt = -1;
00850   if (facetDim == 0){ // return the Number/ID of a Vertex
00851        rnt = cellsPoints_[cellLID][facetIndex];
00852        rnt = vertexLIDToLeafMapping_[rnt];
00853        // rnt must be greater than 0
00854   } else if (facetDim == 1){
00855        rnt = cellsEdges_[cellLID][facetIndex];
00856        rnt = edgeLIDToLeafMapping_[rnt];
00857        // rnt must be greater than 0
00858   } else if (facetDim == 2){
00859          rnt = cellsFaces_[cellLID][facetIndex];
00860        rnt = faceLIDToLeafMapping_[rnt];
00861        // rnt must be greater than 0
00862   }
00863   SUNDANCE_MSG3(verb() , "HNMesh3D::facetLID_tree cellDim:"<<cellDim<<", cellLID:"<<cellLID<<", facetDim:"<<facetDim<<
00864       ", facetIndex:"<<facetIndex<<" RET = " << rnt );
00865   return rnt;
00866 }
00867 
00868 // =========================== MESH CREATION ========================================
00869 
00870 /** adds one vertex to the mesh */
00871 void HNMesh3D::addVertex(int vertexLID , int ownerProc , bool isHanging ,
00872      double coordx , double coordy , double coordz , const Array<int> &maxCoF){
00873   // add only when the LID is new
00874   if (points_.size() <= vertexLID){
00875     TEUCHOS_TEST_FOR_EXCEPTION(vertexLID != nrElem_[0] , std::logic_error ,"HNMesh3D::addVertex " <<
00876        " vertexLID:" << vertexLID << " nrElem_[0]:" << nrElem_[0] );
00877      Point pt(coordx, coordy, coordz );
00878      points_.append( pt );
00879      pointMaxCoF_.append( maxCoF );
00880      isPointHanging_.append( isHanging );
00881      elementOwner_[0].append( (short int)ownerProc );
00882      SUNDANCE_MSG3(verb() , "HNMesh3D::addVertex: " << nrElem_[0] << " P:" << pt << " ,  maxCoF:" << maxCoF);
00883      SUNDANCE_MSG3(verb() , " ownerProc:" << ownerProc << " , isHanging:" << isHanging);
00884      nrElem_[0]++;
00885   }
00886 }
00887 
00888 /** adds one edge to the mesh */
00889 void HNMesh3D::addEdge(int edgeLID , int ownerProc , bool isHanging , int edgeOrientation ,
00890         const Array<int> &vertexLIDs , const Array<int> &maxCoF){
00891     // add only when the edgeLID is new
00892     SUNDANCE_MSG3(verb() , "HNMesh3D -- addEdge: " << edgeLID << " nrElem_[1]: " << nrElem_[1] << " edgePoints_.size():" << edgePoints_.size() );
00893     if (edgePoints_.size() <= edgeLID ){
00894       TEUCHOS_TEST_FOR_EXCEPTION(edgeLID != nrElem_[1], std::logic_error, "HNMesh3D::addEdge edgeLID != nrElem_[1]");
00895      edgePoints_.append( vertexLIDs );
00896      edgeOrientation_.append( (short int)edgeOrientation );
00897      edgeMaxCoF_.append( maxCoF );
00898      isEdgeHanging_.append(isHanging);
00899      hangingAccessCount_.append( (short int)0);
00900        elementOwner_[1].append( (short int)ownerProc );
00901        SUNDANCE_MSG3(verb() , "HNMesh3D::addEdge: " << nrElem_[1] << " vertexLIDs:" << vertexLIDs << " ,  maxCoF:" << maxCoF );
00902        SUNDANCE_MSG3(verb() , "          ownerProc:" << ownerProc << ", isHanging:" << isHanging << ", edgeOrientation:" << edgeOrientation );
00903        nrElem_[1]++;
00904     }
00905 }
00906 
00907 void HNMesh3D::addFace(int faceLID , int ownerProc , bool isHanging , int faceOrientation ,
00908             const Array<int> &vertexLIDs , const Array<int> &edgeLIDs ,
00909             const Array<int> &maxCoF){
00910 
00911     // add only when the edgeLID is new
00912     if (facePoints_.size() <= faceLID ){
00913      TEUCHOS_TEST_FOR_EXCEPTION(faceLID != nrElem_[2], std::logic_error, "HNMesh3D::addFace faceLID != nrElem_[2]");
00914      facePoints_.append( vertexLIDs );
00915      faceEdges_.append( edgeLIDs );
00916      faceOrientation_.append( (short int)faceOrientation );
00917      faceMaxCoF_.append( maxCoF );
00918      isFaceHanging_.append(isHanging);
00919        SUNDANCE_MSG3(verb() , "HNMesh3D::addFace: " << nrElem_[2] << " vertexLIDs:" << vertexLIDs << " ,  maxCoF:" << maxCoF );
00920        SUNDANCE_MSG3(verb() , "HNMesh3D::addFace ,  edgeLIDs:" << edgeLIDs );
00921        SUNDANCE_MSG3(verb() , "          ownerProc:" << ownerProc << ", isHanging:" << isHanging << ", faceOrientation:" << faceOrientation);
00922        elementOwner_[2].append( (short int)ownerProc );
00923        nrElem_[2]++;
00924     }
00925 }
00926 
00927 /** adds one cell(3D) to the mesh */
00928 void HNMesh3D::addCell(int cellLID , int ownerProc ,
00929         int indexInParent , int parentCellLID , int level ,
00930         const Array<int> &faceLIDs , const Array<int> &edgeLIDs ,
00931         const Array<int> &vertexLIDs)
00932 {
00933     // add only when the edgeLID is new
00934     if (cellsPoints_.size() <= cellLID ) {
00935      TEUCHOS_TEST_FOR_EXCEPTION(cellLID != nrElem_[3], std::logic_error, "HNMesh3D::cellLID cellLID != nrElem_[3]");
00936      cellsFaces_.append( faceLIDs );
00937      cellsEdges_.append( edgeLIDs );
00938      cellsPoints_.append( vertexLIDs );
00939        indexInParent_.append( indexInParent );
00940        parentCellLID_.append( parentCellLID );
00941        cellLevel_.append( level );
00942        isCellLeaf_.append( true );
00943        refineCell_.append( 0 );
00944        cellsChildren_.append( Teuchos::tuple(1) );
00945        elementOwner_[3].append( (short int)ownerProc );
00946      // calculate if the cell is complete outside the mesh domain
00947      isCellOut_.append( !( meshDomain_.isInsideComputationalDomain(points_[vertexLIDs[0]]) ||
00948                        meshDomain_.isInsideComputationalDomain(points_[vertexLIDs[1]]) ||
00949                        meshDomain_.isInsideComputationalDomain(points_[vertexLIDs[2]]) ||
00950                        meshDomain_.isInsideComputationalDomain(points_[vertexLIDs[3]]) ||
00951                        meshDomain_.isInsideComputationalDomain(points_[vertexLIDs[4]]) ||
00952                        meshDomain_.isInsideComputationalDomain(points_[vertexLIDs[5]]) ||
00953                        meshDomain_.isInsideComputationalDomain(points_[vertexLIDs[6]]) ||
00954                        meshDomain_.isInsideComputationalDomain(points_[vertexLIDs[7]]) ) );
00955        SUNDANCE_MSG3(verb() , "HNMesh3D::addCell: " << nrElem_[3] <<
00956            " vertexLIDs:" << vertexLIDs << " edgeLIDs:" << edgeLIDs << " faceLIDs:" << faceLIDs);
00957        SUNDANCE_MSG3(verb() , "HNMesh3D::addCell p0:" << points_[vertexLIDs[0]] );
00958        SUNDANCE_MSG3(verb() , "HNMesh3D::addCell p1:" << points_[vertexLIDs[1]] );
00959        SUNDANCE_MSG3(verb() , "HNMesh3D::addCell p2:" << points_[vertexLIDs[2]] );
00960        SUNDANCE_MSG3(verb() , "HNMesh3D::addCell p3:" << points_[vertexLIDs[3]] );
00961        SUNDANCE_MSG3(verb() , "HNMesh3D::addCell p4:" << points_[vertexLIDs[4]] );
00962        SUNDANCE_MSG3(verb() , "HNMesh3D::addCell p5:" << points_[vertexLIDs[5]] );
00963        SUNDANCE_MSG3(verb() , "HNMesh3D::addCell p6:" << points_[vertexLIDs[6]] );
00964        SUNDANCE_MSG3(verb() , "HNMesh3D::addCell p7:" << points_[vertexLIDs[7]] );
00965      SUNDANCE_MSG3(verb() , "HNMesh3D::addCell IN DOMAIN:" <<  isCellOut_[nrElem_[3]] );
00966        nrElem_[3]++;
00967     }
00968 }
00969 
00970 /** creates one regular mesh without refinement. With a different function the
00971  * refinement can start later , independently from this function. <br>
00972  * The structure of this mesh also supports unstructured storage of the cells,
00973  * so we might create unstructured mesh and later refine in the same way */
00974 void HNMesh3D::createMesh(
00975                       double position_x,
00976                 double position_y,
00977                 double position_z,
00978                 double offset_x,
00979                 double offset_y,
00980                 double offset_z,
00981                 int resolution_x,
00982                 int resolution_y,
00983                 int resolution_z,
00984                 const RefinementClass& refineClass ,
00985                 const MeshDomainDef& meshDomain
00986 ){
00987 
00988   setVerb(0);
00989 
00990   // initialize object fields
00991   _pos_x = position_x; _pos_y = position_y; _pos_z = position_z;
00992   _ofs_x = offset_x; _ofs_y = offset_y;  _ofs_z = offset_z;
00993   _res_x = resolution_x; _res_y = resolution_y; _res_z = resolution_z;
00994   refineClass_ = refineClass;
00995   meshDomain_ = meshDomain;
00996 
00997   // create coarsest mesh
00998   createCoarseMesh();
00999 
01000   // loop as long there is no refinement
01001     bool doRefinement = true;
01002     while (doRefinement){
01003       doRefinement = oneRefinementIteration();
01004     }
01005 
01006   // calculate global IDs and create leaf Numbering
01007     //createLeafNumbering();
01008     createLeafNumbering_sophisticated();
01009 
01010 }
01011 
01012 void HNMesh3D::updateLocalCoarseNumbering(int ix, int iy , int iz , int Nx , int Ny){
01013 /* ==== vertex indexing =====*/
01014   vInd[0] = (Nx+1)*(Ny+1)*iz + (Nx+1)*iy + ix;
01015   vInd[1] = vInd[0] + 1;
01016   vInd[2] = vInd[0] + Nx+1;
01017   vInd[3] = vInd[0] + Nx+2;
01018   vInd[4] = vInd[0] + (Nx+1)*(Ny+1);
01019   vInd[5] = vInd[4] + 1;
01020   vInd[6] = vInd[4] + Nx+1;
01021   vInd[7] = vInd[4] + Nx+2;
01022 /*  ===== edge indexing ====== */
01023   eInd[0] = (Nx*(Ny+1) + Ny*(Nx+1) + (Nx+1)*(Ny+1))*iz + (Nx+1+Nx)*iy + ix;
01024   eInd[1] = eInd[0] + Nx;
01025   eInd[3] = eInd[0] + Nx+1;
01026   eInd[5] = eInd[0] + 2*Nx+1;
01027   int ed5 = (2*Nx+1)*(iy+1)+ix;
01028   eInd[2] = eInd[5]+(Nx*(Ny+1)+Ny*(Nx+1)  - ed5) + (Nx+1)*iy+ix;
01029   eInd[4] = eInd[2]+1;
01030   eInd[6] = eInd[2]+Nx+1;
01031   eInd[7] = eInd[2]+Nx+2;
01032   int ed7 = (Nx+1)*(iy+1)+ix+1;
01033   eInd[8] = eInd[7] + ( (Nx+1)*(Ny+1) - ed7) + (2*Nx+1)*iy+ix;
01034   eInd[9] = eInd[8] + Nx;
01035   eInd[10] = eInd[8] + Nx+1;
01036   eInd[11] = eInd[8] + 2*Nx+1;
01037 /* ======== face numbering ======== */
01038   fInd[0] = (Nx*Ny+Nx*(Ny+1)+ Ny*(Nx+1))*iz+Nx*iy+ix;
01039   fInd[1] = fInd[0] + (Nx*Ny - (Nx*iy+ix)) + (iy*(2*Nx+1) + ix);
01040   fInd[2] = fInd[1] + Nx;
01041   fInd[3] = fInd[2] + 1;
01042   fInd[4] = fInd[3] + Nx;
01043   fInd[5] = fInd[4] + ((Nx+1)*Ny + (Ny+1)*Nx - (2*Nx+1)*(iy+1) - (ix)  + Nx*iy + ix);
01044 }
01045 
01046 void HNMesh3D::createCoarseMesh(){
01047 
01048   // estimate load for parallel case,
01049   // assign cells to each processors, based on the load and the domain
01050   // we assign cells to processors, (y,x) (optimal for vertical channel flow)
01051   // the estimation is done in each processor, globally but then only the local mesh will be build
01052   int nrCoarseCell = _res_x * _res_y * _res_z;
01053   int nrCoarsePoints = (_res_x+1)*(_res_y+1)*(_res_z+1);
01054   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);
01055   int nrCoarseFace = (_res_x+1)*_res_y*_res_z + _res_x*(_res_y+1)*_res_z+ + _res_x*_res_y*(_res_z+1);
01056   Array<int> coarseCellOwner( nrCoarseCell , -1 );
01057   Array<int> coarsePointOwner( nrCoarsePoints , -1 );
01058   Array<int> coarseEdgeOwner( nrCoarseEdge , -1 );
01059   Array<int> coarseFaceOwner( nrCoarseFace , -1 );
01060   Array<int> coarseCellLID( nrCoarseCell , -1 );
01061   Array<int> coarsePointLID( nrCoarsePoints , -1 );
01062   Array<int> coarseEdgeLID( nrCoarseEdge , -1 );
01063   Array<int> coarseFaceLID( nrCoarseFace , -1 );
01064   Array<int> coarseCellsLoad( nrCoarseCell , 0 );
01065   int totalLoad = 0;
01066 
01067   SUNDANCE_MSG3(verb() , "HNMesh3D::createMesh nrCoarseCell:" << nrCoarseCell << " nrCoarsePoints:" << nrCoarsePoints
01068                 << " nrCoarseEdge:" << nrCoarseEdge <<  " nrCoarseFace:" << nrCoarseFace << " nrProc_:" << nrProc_ << " myRank_:" << myRank_);
01069   TEUCHOS_TEST_FOR_EXCEPTION( nrCoarseCell < nrProc_ , std::logic_error," HNMesh3D::createMesh nrCoarseCell < nrProc_ ");
01070   // now always divide as a flow channel , no resolution driven division
01071 
01072     // calculate total load and load per coarse cell
01073   double h[3];
01074   Array<int>  ind(3);
01075   h[0] = _ofs_x/(double)_res_x; h[1] = _ofs_y/(double)_res_y; h[2] = _ofs_z/(double)_res_z;
01076   Point pos(h[0],h[1],h[2]);
01077   Point res(h[0],h[1],h[2]);
01078   // estimate total estimated load of the mesh
01079   for (int i=0; i < nrCoarseCell; i++){
01080     // midpoint of the cell
01081     ind[0] = ((i % (_res_x*_res_y)) % _res_x);
01082     ind[1] = ((i % (_res_x*_res_y)) / _res_x);
01083     ind[2] = (i / (_res_x*_res_y));
01084     pos[0] = _pos_x + (double)(ind[0])*h[0] + 0.5*h[0];
01085     pos[1] = _pos_y + (double)(ind[1])*h[1] + 0.5*h[1];
01086     pos[2] = _pos_z + (double)(ind[2])*h[2] + 0.5*h[2];
01087     // todo: take the domain in consideration (take the 8 points) (when cells are turned off)
01088     coarseCellsLoad[i] = refineClass_.estimateRefinementLevel( pos , res );
01089     totalLoad += coarseCellsLoad[i];
01090   }
01091 
01092   // calculate average load per cell
01093   double loadPerProc = (double)totalLoad / (double)nrProc_;
01094   int actualProc=0;
01095   totalLoad = 0;
01096   // assign owners to the cells, edges, vertexes , greedy method
01097   SUNDANCE_MSG3(verb() , "Processor asign, loadPerProc:" << loadPerProc );
01098   double diff_load = 0.0;
01099   for (int i=0; i < nrCoarseCell; i++){
01100     ind[0] = ((i % (_res_x*_res_y)) % _res_x);
01101     ind[1] = ((i % (_res_x*_res_y)) / _res_x);
01102     ind[2] = (i / (_res_x*_res_y));
01103     // call the function to update
01104     updateLocalCoarseNumbering( ind[0] , ind[1] , ind[2] , _res_x , _res_y);
01105     //SUNDANCE_MSG3(verb() , "Cell ID:" << i << " vertexInd:" <<vertexInd << " edgeInd:" << edgeInd );
01106     //SUNDANCE_MSG3(verb() , "Cell, actual index" << ind  );
01107     // assign ownership for vertexes
01108     for (int jj = 0 ; jj < 8 ; jj++){
01109       if (coarsePointOwner[vInd[jj]] < 0){
01110         coarsePointOwner[vInd[jj]] = actualProc;
01111         SUNDANCE_MSG3(verb() , "Vertex CPU assign " << vInd[jj] << " ->" << actualProc );
01112       }
01113     }
01114     // assign ownership for edges
01115     for (int jj = 0 ; jj < 12 ; jj++){
01116       if (coarseEdgeOwner[eInd[jj]] < 0){
01117         coarseEdgeOwner[eInd[jj]] = actualProc;
01118         SUNDANCE_MSG3(verb() , "Edge CPU assign " << eInd[jj] << " ->" << actualProc );
01119       }
01120     }
01121     // assign ownership for faces
01122     for (int jj = 0 ; jj < 6 ; jj++){
01123       if (coarseFaceOwner[fInd[jj]] < 0){
01124         coarseFaceOwner[fInd[jj]] = actualProc;
01125         SUNDANCE_MSG3(verb() , "Face CPU assign " << fInd[jj] << " ->" << actualProc );
01126       }
01127     }
01128     // assign ownership for the cell
01129     coarseCellOwner[i] = actualProc;
01130     totalLoad += coarseCellsLoad[i];
01131     SUNDANCE_MSG3(verb() , "Cell CPU assign " << i << " ->" << actualProc <<
01132         ", totalLoad:" << totalLoad << " loadPerProc:" << loadPerProc);
01133     // the rounding of the load estimator is in favor to late earlier
01134     if (((double)totalLoad >= (loadPerProc - 1e-8 - diff_load)) && ( actualProc < nrProc_-1 )){
01135       SUNDANCE_MSG3(verb() , "Increase CPU , totalLoad:" << totalLoad << " loadPerProc:" << loadPerProc );
01136       // compensate the load difference for the next CPU
01137       diff_load = totalLoad - loadPerProc;
01138       actualProc = actualProc + 1;
01139       totalLoad = 0;
01140     }
01141   }
01142 
01143   // now go trough all cells which have to be added to this processor
01144   SUNDANCE_MSG3(verb() , " Process Cells:" << nrCoarseCell );
01145   for (int i=0; i < nrCoarseCell; i++)
01146   {
01147     ind[0] = ((i % (_res_x*_res_y)) % _res_x);
01148     ind[1] = ((i % (_res_x*_res_y)) / _res_x);
01149     ind[2] = (i / (_res_x*_res_y));
01150     // calculate the local index
01151     updateLocalCoarseNumbering( ind[0] , ind[1] , ind[2] , _res_x , _res_y );
01152     pos[0] = _pos_x + (double)(ind[0])*h[0];
01153     pos[1] = _pos_y + (double)(ind[1])*h[1];
01154     pos[2] = _pos_z + (double)(ind[2])*h[2];
01155     SUNDANCE_MSG3(verb() , "PCell ID:" << i <<" pos:"<<pos<<" _res_x:"<<_res_x<<" _res_y:"<<_res_y<<" _res_z:"<<_res_z);
01156     SUNDANCE_MSG3(verb() , "PCell, actual index" << ind  );
01157     // this condition is so that remote cells will be added
01158     int cellLID = coarseCellLID[i];
01159     Array<int> vLID(8,-1) , vertexMaxCoF(8,-1) ;
01160     Array<int> edgeLID(12,-1) , edgeVert(2,-1) , edgeMaxCoef(4,-1);
01161     Array<int> faceLID(6,-1) , faceVert(4,-1) , faceEdge(4,-1) , faceMaxCoef(2,-1);
01162     //SUNDANCE_MSG3(verb() , "Cell ID:" << i << " vertexInd:" <<vertexInd << " edgeInd:" << edgeInd << " cellLID:" << cellLID);
01163     //SUNDANCE_MSG3(verb() , "Cell, actual index" << ind << " pos:" << pos);
01164     // assign new cellID if necessary
01165     if (coarseCellLID[i] < 0 ){
01166       coarseCellLID[i] = nrElem_[3];
01167       cellLID = coarseCellLID[i];
01168     }
01169     // add all Vertexes , ignoring neighbor cells (maxcofacets)
01170         for (int jj = 0 ; jj < 8 ; jj++){
01171             if (coarsePointLID[vInd[jj]] < 0){
01172               coarsePointLID[vInd[jj]] = nrElem_[0];
01173             }
01174             vLID[jj] = coarsePointLID[vInd[jj]];
01175             // add vertex with -1 maxCOfacets
01176             //SUNDANCE_MSG3(verb() , "Vertex  X:" << ((double)offs_Points_x_[jj])*h[0] << "  Y:" << pos[1] + ((double)offs_Points_y_[jj])*h[1]);
01177             //SUNDANCE_MSG3(verb() , "Vertex  vLID[jj]:" << vLID[jj] << "  , coarsePointOwner[vertexInd+vertexOffs[jj]]" << coarsePointOwner[vertexInd+vertexOffs[jj]] );
01178             addVertex( vLID[jj] , coarsePointOwner[vInd[jj]] , false ,
01179                    pos[0] + ((double)offs_Points_x_[jj])*h[0] , pos[1] + ((double)offs_Points_y_[jj])*h[1] ,
01180                    pos[2] + ((double)offs_Points_z_[jj])*h[2] ,
01181                        vertexMaxCoF );
01182         }
01183     // add all Edges , ignoring neighbor cells (maxcofacets)
01184         for (int jj = 0 ; jj < 12 ; jj++){
01185             if (coarseEdgeLID[eInd[jj]] < 0){
01186               coarseEdgeLID[eInd[jj]] = nrElem_[1];
01187             }
01188             edgeLID[jj] = coarseEdgeLID[eInd[jj]];
01189             edgeVert[0] = vLID[edge_Points_localIndex[jj][0]];
01190             edgeVert[1] = vLID[edge_Points_localIndex[jj][1]];
01191             SUNDANCE_MSG3(verb() , "Edge local Index:" << eInd[jj] );
01192             // add edge with -1 maxCOfacets
01193             addEdge( edgeLID[jj] , coarseEdgeOwner[eInd[jj]] , false , edge_Orientation[jj] , edgeVert , edgeMaxCoef );
01194         }
01195     // add all Faces , ignoring neighbor cells (maxcofacets)
01196         for (int jj = 0 ; jj < 6 ; jj++){
01197             if (coarseFaceLID[fInd[jj]] < 0){
01198               coarseFaceLID[fInd[jj]] = nrElem_[2];
01199             }
01200             faceLID[jj] = coarseFaceLID[fInd[jj]];
01201             //
01202             faceVert[0] = vLID[face_Points_localIndex[jj][0]];
01203             faceVert[1] = vLID[face_Points_localIndex[jj][1]];
01204             faceVert[2] = vLID[face_Points_localIndex[jj][2]];
01205             faceVert[3] = vLID[face_Points_localIndex[jj][3]];
01206             faceEdge[0] = edgeLID[face_Edges_localIndex[jj][0]];
01207             faceEdge[1] = edgeLID[face_Edges_localIndex[jj][1]];
01208             faceEdge[2] = edgeLID[face_Edges_localIndex[jj][2]];
01209             faceEdge[3] = edgeLID[face_Edges_localIndex[jj][3]];
01210             // add face with -1 maxCOfacets
01211             addFace( faceLID[jj] , coarseFaceOwner[fInd[jj]] , false , face_Orientation[jj] ,
01212                        faceVert , faceEdge , faceMaxCoef );
01213         }
01214     // add the Cell
01215         addCell( cellLID , coarseCellOwner[i] , 0 , cellLID , 0 , faceLID , edgeLID , vLID);
01216   } // --- end from for loop
01217 
01218   // next is maxCoFacet and boundary info update for vertexes and edges
01219   SUNDANCE_MSG3(verb() , " Process maxCofacets:" << nrCoarseCell );
01220   for (int i=0; i < nrCoarseCell; i++){
01221     Array<int> vLID(8,-1) , eLID(12,-1) ,fLID(6,-1) ;
01222     ind[0] = ((i % (_res_x*_res_y)) % _res_x);
01223     ind[1] = ((i % (_res_x*_res_y)) / _res_x);
01224     ind[2] = (i / (_res_x*_res_y));
01225     // calculate the local index
01226     updateLocalCoarseNumbering( ind[0] , ind[1] , ind[2] , _res_x , _res_y );
01227     int cellLID = coarseCellLID[i];
01228     SUNDANCE_MSG3(verb() , " MaxCoFs in Cell cellLID:" << cellLID  );
01229     //SUNDANCE_MSG3(verb() , "MaxCoFs in Cell ID:" << i << " vertexInd:" <<vertexInd << " edgeInd:" << edgeInd );
01230     //SUNDANCE_MSG3(verb() , "MaxCoFs, actual index" << ind  );
01231     // vertex maxCoFac
01232         for (int jj = 0 ; jj < 8 ; jj++){
01233             vLID[jj] = coarsePointLID[vInd[jj]];
01234             // if all elements are added then this is OK
01235             pointMaxCoF_[vLID[jj]][jj] = cellLID;
01236             SUNDANCE_MSG3(verb() , "Vertex MaxCoFacet vLID[jj]:" << vLID[jj] << " jj:" << jj << " cellLID:" << cellLID );
01237         }
01238         // edge maxCoFac
01239         for (int jj = 0 ; jj < 12 ; jj++){
01240             eLID[jj] = coarseEdgeLID[eInd[jj]];
01241             // if all elements are added then this is OK
01242             edgeMaxCoF_[eLID[jj]][edge_MaxCof[jj]] = cellLID;
01243             SUNDANCE_MSG3(verb() , "Edge MaxCoFacet eLID[jj]:" << eLID[jj] << " edge_MaxCof[jj]:" << edge_MaxCof[jj] << " cellLID:" << cellLID );
01244         }
01245         // face maxCoFac
01246         for (int jj = 0 ; jj < 6 ; jj++){
01247           fLID[jj] = coarseFaceLID[fInd[jj]];
01248             // if all elements are added then this is OK
01249             faceMaxCoF_[fLID[jj]][face_MaxCof[jj]] = cellLID;
01250             SUNDANCE_MSG3(verb() , "Face MaxCoFacet fLID[jj]:" << fLID[jj] << " face_MaxCof[jj]:" << face_MaxCof[jj] << " cellLID:" << cellLID );
01251         }
01252   }
01253   // basic rectangular mesh is build
01254 }
01255 
01256 // -----------
01257 bool HNMesh3D::oneRefinementIteration(){
01258 
01259     int nrActualCell = nrElem_[3];
01260     bool rtn = false;
01261     SUNDANCE_MSG3(verb() , " HNMesh3D::oneRefinementIteration, start one refinement iteration cycle ");
01262     // we iterate only over the existing cells (not the ones which will be later created)
01263   for (int i=0 ; i < nrActualCell ; i++){
01264     // cell is owned by the current processor, and is leaf and is inside the mesh domain
01265       SUNDANCE_MSG3(verb() , " Test cell " << i << ", elementOwner_[3][i]:" << elementOwner_[3][i] <<
01266                          ", isCellLeaf_[i]:" << isCellLeaf_[i] << ", out:" << (!isCellOut_[i]));
01267 
01268     if ( (isCellLeaf_[i] == true) )
01269       //  mark neighbors for refinements if because of the hanging nodes a refinement is not possible, regardless of the IN or OUT of Mesh domain
01270     {
01271       // check if refinement is needed and possible, none of the edges can be hanging (we could check also vertexes and faces as well)
01272       Array<int>& cellsEdges = cellsEdges_[i];
01273             bool doRefined = true;
01274             bool refFunction = false;
01275             for (int jj = 0 ; jj < cellsEdges.size() ; jj++){
01276               SUNDANCE_MSG3(verb() , " eLID: " << cellsEdges[jj] << ", isHanging:" << isEdgeHanging_[cellsEdges[jj]]);
01277               doRefined = ( doRefined && ((isEdgeHanging_[cellsEdges[jj]]) == false) );
01278             }
01279             // --- if refinement is possible
01280             SUNDANCE_MSG3(verb() , " is possible to refine cell nr: " << i << ", doRefined:" << doRefined);
01281             // call refinement function
01282       Array<int>& cellsVertex = cellsPoints_[i];
01283       Point h = points_[cellsVertex[7]] - points_[cellsVertex[0]];
01284       Point p2 = points_[cellsVertex[0]] + 0.5*h;
01285       SUNDANCE_MSG3(verb() , " points_[cellsVertex[0]]: " << points_[cellsVertex[0]]);
01286       SUNDANCE_MSG3(verb() , " points_[cellsVertex[7]]: " << points_[cellsVertex[7]]);
01287       refFunction = ( (refineCell_[i] == 1) || refineClass_.refine( cellLevel_[i] , p2 , h ) );
01288 
01289             // decide if we refine this cell
01290       //SUNDANCE_OUT(cellLevel_[i] < 1 , " execute refinement on cell nr: " << i << ", refFunction:" << refFunction << " , p0:"
01291       //    << points_[cellsVertex[0]] << " , h=" << h);
01292             SUNDANCE_MSG3(verb() , " execute refinement on cell nr: " << i << ", refFunction:" << refFunction);
01293             if (doRefined && refFunction)
01294             {
01295               // -- call the function to refine the actual cell ---
01296               refineCell(i);
01297               rtn = true;
01298               refineCell_[i] = 0;
01299             }
01300             else
01301             {
01302               // Cell can not be refined
01303                 // we might use only edges
01304               if (refFunction) {
01305                     // now take all hanging edge neighbors
01306                     for (int jj = 0 ; jj < cellsEdges.size() ; jj++)
01307                       if (isEdgeHanging_[cellsEdges[jj]]){
01308                         // get the parent cell
01309                         int cLevel = cellLevel_[i];
01310                         int parentID = parentCellLID_[i];
01311                         int parentCEdge = cellsEdges_[parentID][jj];
01312                         int refCell = -1;
01313                         // take all maxCoFacets
01314                         for (int coF = 0 ; coF < 4 ; coF++){
01315                           refCell = edgeMaxCoF_[parentCEdge][coF];
01316                 // refCell should be refined and mark for refinement
01317                 if ( (refCell >= 0) && (cellLevel_[refCell] < cLevel) && (isCellLeaf_[refCell])){
01318                   // todo: in some particular case this leads to error, (debug that error)
01319                   // when in one points 2 different level meet (so we do a conservative refinement in 3D)
01320                   refineCell_[refCell] = 1;
01321                   rtn = true;
01322                   //SUNDANCE_MSG3( verb() , " HNMesh3D::oneRefinementIteration refineCell_[refCell] = 1" << refCell);
01323                 }
01324                         }
01325                       }
01326               }
01327             }
01328     }
01329   }
01330 
01331   SUNDANCE_MSG3(verb() , " HNMesh3D::oneRefinementIteration DONE with one refinement iteration");
01332   // return if there was refinement or attempt to refine
01333   return rtn;
01334 }
01335 
01336 // -------- refine cell cellID (assuming all conditions are satisfied)--
01337 void HNMesh3D::refineCell(int cellLID){
01338 
01339     // data initialization
01340   int cellOwner = elementOwner_[3][cellLID];
01341   Point p = points_[cellsPoints_[cellLID][0]];
01342   Point h = points_[cellsPoints_[cellLID][7]] - points_[cellsPoints_[cellLID][0]];
01343 
01344     // the created vertex, edge and cell LIDs
01345     Array<int> vertexLIDs(64,-1);
01346     // some of the vertexes already exist
01347     vertexLIDs[0] = cellsPoints_[cellLID][0];  vertexLIDs[3] = cellsPoints_[cellLID][1];
01348     vertexLIDs[12] = cellsPoints_[cellLID][2]; vertexLIDs[15] = cellsPoints_[cellLID][3];
01349     vertexLIDs[48] = cellsPoints_[cellLID][4]; vertexLIDs[51] = cellsPoints_[cellLID][5];
01350     vertexLIDs[60] = cellsPoints_[cellLID][6]; vertexLIDs[63] = cellsPoints_[cellLID][7];
01351     Array<int> edgeLIDs(144,-1);
01352     Array<int> faceLIDs(108,-1);
01353     // the cell IDs can be determined in advance
01354     Array<int> cellLIDs(27,-1);
01355     for (int c = 0; c < 27 ; cellLIDs[c] = nrElem_[3] + c , c++);
01356 
01357     // the parent cell is no leaf any more
01358   isCellLeaf_[cellLID] = false;
01359 
01360     SUNDANCE_MSG3(verb() , " ========== HNMesh3D::refineCell, cellLID:" << cellLID << " ==========");
01361 
01362     Array<int> ind(3,-1);
01363     for (int childCell = 0 ; childCell < 27 ; childCell++){
01364         Array<int> currCellV(8,-1);
01365         Array<int> currCellE(12,-1);
01366         Array<int> currCellF(6,-1);
01367 
01368       // calculate index
01369       ind[0] = ( (childCell % 9) % 3);
01370       ind[1] = ( (childCell % 9) / 3);
01371       ind[2] = ( childCell / 9);
01372       // calculate all index
01373       updateLocalCoarseNumbering( ind[0] , ind[1] , ind[2] , 3 , 3);
01374 
01375       // ------------ VERTEX ----------------
01376       for (int v = 0; v < 8 ; v++){
01377         int  vertexOwner = cellOwner;
01378         bool vertexIsHanging = false;
01379         bool useEdge = true;
01380         int pIndex = 0 , pOffset = 0 , pID = 0;
01381         // look for existing vertex
01382         if ( vertexToParentEdge[vInd[v]] >= 0){
01383           if ( vertexToParentEdge[vInd[v]] > 19){
01384           useEdge = false;
01385           pIndex = vertexToParentEdge[vInd[v]] - 20;
01386           pID = cellsFaces_[cellLID][ pIndex ];
01387           pOffset = vertexInParentIndex[vInd[v]] - 20;
01388           SUNDANCE_MSG3(verb() , "Vertex -> Face vInd[v]:" << vInd[v] << " pIndex: " << pIndex << " pID:" << pID << " pOffset:" << pOffset);
01389           SUNDANCE_MSG3(verb() , " cellsFaces:" << cellsFaces_[cellLID] << " elementOwner_[2][pID]:" << elementOwner_[2][pID]);
01390           vertexOwner = elementOwner_[2][pID];
01391           vertexIsHanging = ( numMaxCofacets_ID( 2 , pID ) > 1);
01392           } else {
01393           pIndex = vertexToParentEdge[vInd[v]];
01394           pID = cellsEdges_[cellLID][ pIndex ];
01395           pOffset = vertexInParentIndex[vInd[v]];
01396           SUNDANCE_MSG3(verb() , "Vertex -> Edge vInd[v]:" << vInd[v] << " pIndex: " << pIndex << " pID:" << pID << " pOffset:" << pOffset);
01397           SUNDANCE_MSG3(verb() , " cellsEdges:" << cellsEdges_[cellLID] << " elementOwner_[1][pID]:" << elementOwner_[1][pID]);
01398           vertexOwner = elementOwner_[1][pID];
01399           vertexIsHanging = ( numMaxCofacets_ID( 1 , pID ) > 1);
01400           }
01401         }
01402         // see if the vertex already exists
01403         if ( (vertexLIDs[vInd[v]] < 0) && (vertexToParentEdge[vInd[v]] >= 0) ){
01404                vertexLIDs[vInd[v]] = getHangingElement(0, useEdge, pID , pOffset );
01405         }
01406       SUNDANCE_MSG3(verb() , "Vertex vInd[v]:" << vInd[v] << " pIndex: " << pIndex << " pID:" << pID << " pOffset:" << pOffset);
01407             // create vertex if is not already created
01408         if ( vertexLIDs[vInd[v]] < 0){
01409           Array<int> maxCoF(8,-1);
01410           addVertex( nrElem_[0] , vertexOwner , vertexIsHanging ,
01411                  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);
01412           vertexLIDs[vInd[v]] = nrElem_[0] - 1;
01413           // add to parent elem if this is hanging
01414           if (vertexIsHanging)
01415              addHangingElement(0 , vertexLIDs[vInd[v]] , useEdge , pID , pOffset);
01416         }
01417         currCellV[v] = vertexLIDs[vInd[v]];
01418       // set MaxCoFacet
01419         SUNDANCE_MSG3(verb() , " vertexLIDs[vInd[v]]: " << vertexLIDs[vInd[v]] );
01420         pointMaxCoF_[ vertexLIDs[vInd[v]] ][v] = cellLIDs[childCell];
01421         // set maxCofacet also in other directions  ... not necessary
01422       }
01423 
01424       // ------------ EDGES ----------------
01425       for (int e = 0; e < 12 ; e++){
01426         int  edgeOwner = cellOwner;
01427         bool edgeIsHanging = false;
01428         bool useEdge = true;
01429         int pIndex = 0 , pOffset = 0 , pID = 0;
01430         // look for existing edge
01431         if ( edgeToParentEdge[eInd[e]] >= 0){
01432           if ( edgeToParentEdge[eInd[e]] > 19){
01433           useEdge = false;
01434           pIndex = edgeToParentEdge[eInd[e]] - 20;
01435           pID = cellsFaces_[cellLID][ pIndex ];
01436           pOffset = edgeInParentIndex[eInd[e]] - 20;
01437           SUNDANCE_MSG3(verb() , "Edge -> Face eInd[e]:" << eInd[e] <<" pIndex: " << pIndex << " pID:" << pID << " pOffset:" << pOffset);
01438           SUNDANCE_MSG3(verb() , " cellsFaces:" << cellsFaces_[cellLID] );
01439           edgeOwner = elementOwner_[2][pID];
01440           edgeIsHanging = ( numMaxCofacets_ID( 2 , pID ) > 1);
01441           } else {
01442           pIndex = edgeToParentEdge[eInd[e]];
01443           pID = cellsEdges_[cellLID][ pIndex ];
01444           pOffset = edgeInParentIndex[eInd[e]];
01445           SUNDANCE_MSG3(verb() , "Edge -> Edge eInd[e]:" << eInd[e] <<" pIndex: " << pIndex << " pID:" << pID << " pOffset:" << pOffset);
01446           //SUNDANCE_MSG3(verb() , " cellsEdges:" << cellsEdges_[cellLID] );
01447           edgeOwner = elementOwner_[1][pID];
01448           edgeIsHanging = ( numMaxCofacets_ID( 1 , pID ) > 1);
01449           }
01450         }
01451         // see if the edge already exists
01452         if ( (edgeLIDs[eInd[e]] < 0) && ( edgeToParentEdge[eInd[e]] >= 0) ){
01453           edgeLIDs[eInd[e]] = getHangingElement( 1 , useEdge, pID , pOffset );
01454         }
01455         SUNDANCE_MSG3(verb() , "Edge eInd[e]:" << eInd[e] <<" pIndex: " << pIndex << " pID:" << pID << " pOffset:" << pOffset);
01456         if ( edgeLIDs[eInd[e]] < 0){
01457           Array<int> maxCoF(4,-1);
01458           Array<int> edgeVertexs(2,-1);
01459           edgeVertexs[0] = currCellV[edge_Points_localIndex[e][0]]; edgeVertexs[1] = currCellV[edge_Points_localIndex[e][1]];
01460             // create edges for the current cell
01461           addEdge( nrElem_[1] , edgeOwner , edgeIsHanging , edge_Orientation[e] , edgeVertexs , maxCoF );
01462           edgeLIDs[eInd[e]] = nrElem_[1] - 1;
01463           // add to parent elem if this is hanging
01464           if (edgeIsHanging)
01465             addHangingElement(1 , edgeLIDs[eInd[e]] , useEdge , pID , pOffset);
01466         }
01467         currCellE[e] = edgeLIDs[eInd[e]];
01468         // set MaXCoFacet
01469         edgeMaxCoF_[edgeLIDs[eInd[e]]][edge_MaxCof[e]] = cellLIDs[childCell];
01470         SUNDANCE_MSG3(verb() , " edgeLIDs[eInd[e]]: " << edgeLIDs[eInd[e]] );
01471         // set maxCofacet also in other directions  ... not necessary
01472       }
01473 
01474       // ------------ FACES ----------------
01475       for (int f = 0; f < 6 ; f++){
01476         int  faceOwner = cellOwner;
01477         bool faceIsHanging = false;
01478         bool useEdge = false;
01479         int pIndex = 0 , pOffset = 0 , pID = 0;
01480         // look for existing face
01481         if ( faceToParentFace[fInd[f]] >= 0 ){
01482           pIndex = faceToParentFace[fInd[f]];
01483           pID = cellsFaces_[cellLID][ pIndex ];
01484           pOffset = faceInParentIndex[fInd[f]];
01485           SUNDANCE_MSG3(verb() , " cellsFaces:" << cellsFaces_[cellLID] );
01486           faceOwner = elementOwner_[2][pID];
01487           faceIsHanging = ( numMaxCofacets_ID( 2 , pID ) > 1);
01488         }
01489         // see if the face already exists
01490         if ( (faceLIDs[fInd[f]] < 0) && ( faceToParentFace[fInd[f]] >= 0 )){
01491           faceLIDs[fInd[f]] = getHangingElement( 2 , useEdge, pID , pOffset );
01492         }
01493           SUNDANCE_MSG3(verb() , "Face -> Face pIndex: " << pIndex << " pID:" << pID << " pOffset:" << pOffset);
01494         // add face if necessary
01495         if ( faceLIDs[fInd[f]] < 0){
01496           Array<int> maxCoF(2,-1);
01497           Array<int> faceVertexs(4,-1);
01498           faceVertexs[0] = currCellV[face_Points_localIndex[f][0]]; faceVertexs[1] = currCellV[face_Points_localIndex[f][1]];
01499           faceVertexs[2] = currCellV[face_Points_localIndex[f][2]]; faceVertexs[3] = currCellV[face_Points_localIndex[f][3]];
01500           Array<int> faceEdges(4,-1);
01501           faceEdges[0] = currCellE[face_Edges_localIndex[f][0]]; faceEdges[1] = currCellE[face_Edges_localIndex[f][1]];
01502           faceEdges[2] = currCellE[face_Edges_localIndex[f][2]]; faceEdges[3] = currCellE[face_Edges_localIndex[f][3]];
01503             //create all faces for the current cell
01504           addFace( nrElem_[2] , faceOwner , faceIsHanging , face_Orientation[f] , faceVertexs , faceEdges , maxCoF );
01505           faceLIDs[fInd[f]] = nrElem_[2] - 1;
01506           // add to parent elem if this is hanging
01507           if (faceIsHanging)
01508             addHangingElement(2 , faceLIDs[fInd[f]] , useEdge , pID , pOffset);
01509         }
01510         // set MaxCoFacet
01511         currCellF[f] = faceLIDs[fInd[f]];
01512         faceMaxCoF_[ currCellF[f] ][face_MaxCof[f]] = cellLIDs[childCell];
01513         SUNDANCE_MSG3(verb() , " faceLIDs[fInd[f]]: " << faceLIDs[fInd[f]] );
01514         // set maxCofacet also in other directions  ... not necessary
01515       }
01516 
01517       // ------------ CELL ----------------
01518       addCell( nrElem_[3] , cellOwner , childCell , cellLID ,
01519           cellLevel_[cellLID] + 1 , currCellF , currCellE , currCellV );
01520       // append this child to the father list
01521       cellsChildren_[cellLID].append(cellLIDs[childCell]);
01522     }
01523 }
01524 
01525 void HNMesh3D::addHangingElement(int cellDim, int cellID ,bool useEdge,
01526     int parentID , int parentOffset){
01527   // store in edge
01528   if (useEdge){
01529     if (!edgeHangingElmStore_.containsKey(parentID)){
01530       Array<int> hnInfo(6,-1);
01531       hnInfo[5] = numMaxCofacets_ID( 1 , parentID );
01532       hangingAccessCount_[parentID] = hnInfo[5];
01533       edgeHangingElmStore_.put( parentID , hnInfo );
01534     }
01535     const Array<int>& hnInfo = edgeHangingElmStore_.get(parentID);
01536     Array<int> tmp_vect(hnInfo.size());
01537     for (int ii = 0; ii < hnInfo.size() ; ii++) tmp_vect[ii] = hnInfo[ii];
01538         int realOffset = 0;
01539     // point in edge
01540     if (cellDim == 0){ realOffset = 0;}
01541     // edge in edge
01542     else{ realOffset = 2; }
01543     // store hanging element
01544         SUNDANCE_MSG3(verb() ,"HNMesh3D::addHangingElement EDGE  realOffset:" << realOffset << " parentOffset:" << parentOffset);
01545         SUNDANCE_MSG3(verb() ,"HNMesh3D::addHangingElement EDGE i:" << realOffset+parentOffset <<" hnInfo:" << hnInfo);
01546     tmp_vect[realOffset+parentOffset] = cellID;
01547     // store the new vector (with the updated information)
01548     edgeHangingElmStore_.remove( parentID );
01549     edgeHangingElmStore_.put( parentID , tmp_vect );
01550   }
01551   // store in face
01552   else{
01553     if (!faceHangingElmStore_.containsKey(parentID)){
01554       Array<int> hnInfo(25,-1);
01555       faceHangingElmStore_.put( parentID , hnInfo );
01556     }
01557     const Array<int>& hnInfo = faceHangingElmStore_.get(parentID);
01558     Array<int> tmp_vect(hnInfo.size());
01559         for (int ii = 0; ii < hnInfo.size() ; ii++) tmp_vect[ii] = hnInfo[ii];
01560         int realOffset = 0;
01561         // vertex in face
01562     if (cellDim == 0) { realOffset = 0; }
01563     // edge in face
01564     else if (cellDim == 1) { realOffset = 4; }
01565     // face in face
01566     else { realOffset = 16; }
01567     // store hanging element
01568         SUNDANCE_MSG3(verb() ,"HNMesh3D::addHangingElement FACE  realOffset:" << realOffset << " parentOffset:" << parentOffset);
01569         SUNDANCE_MSG3(verb() ,"HNMesh3D::addHangingElement FACE i:" << realOffset+parentOffset <<" hnInfo:" << hnInfo);
01570     tmp_vect[realOffset+parentOffset] = cellID;
01571     // store the new vector with the updated information
01572     faceHangingElmStore_.remove( parentID );
01573     faceHangingElmStore_.put( parentID , tmp_vect );
01574   }
01575 }
01576 
01577 int HNMesh3D::getHangingElement(int cellDim, bool useEdge, int parentID , int parentOffset){
01578   int rtn = -1;
01579   int realOffset = 0;
01580   if (useEdge){
01581     // get point from edge
01582     if (cellDim == 0){ realOffset = 0;}
01583     // get edge from edge
01584     else{ realOffset = 2; }
01585         if (edgeHangingElmStore_.containsKey(parentID)){
01586          const Array<int>& hnInfo = edgeHangingElmStore_.get(parentID);
01587          rtn = hnInfo[realOffset+parentOffset];
01588          SUNDANCE_MSG3(verb() ,"HNMesh3D::getHangingElement EDGE rtn = " << rtn << " realOffset:" << realOffset << " parentOffset:" << parentOffset);
01589          SUNDANCE_MSG3(verb() ,"HNMesh3D::getHangingElement EDGE i:" << realOffset+parentOffset <<" hnInfo:" << hnInfo);
01590          // mark stored elements as not hanging
01591          if ( rtn >= 0){
01592            if ((cellDim == 0) && (parentOffset == 1)) {
01593             if (hangingAccessCount_[parentID] <= 2){
01594             isPointHanging_[hnInfo[0]] = false; isPointHanging_[hnInfo[1]] = false;
01595             } else {
01596              //the edge will we accessed at the last time so that has to decrement
01597             }
01598            }
01599          if ((cellDim == 1) && (parentOffset == 2)) {
01600             if (hangingAccessCount_[parentID] <= 2){
01601             isEdgeHanging_[hnInfo[2]] = false; isEdgeHanging_[hnInfo[3]] = false;
01602             isEdgeHanging_[hnInfo[4]] = false;
01603             } else {
01604              hangingAccessCount_[parentID]--;
01605             }
01606          }
01607          }
01608         }
01609   }
01610   else
01611   {
01612     // get point from face
01613     if (cellDim == 0) { realOffset = 0; }
01614     // get edge from face
01615     else if (cellDim == 1) { realOffset = 4; }
01616     // get face from face
01617     else { realOffset = 16; }
01618         if (faceHangingElmStore_.containsKey(parentID)){
01619          const Array<int>& hnInfo = faceHangingElmStore_.get(parentID);
01620          rtn = hnInfo[realOffset+parentOffset];
01621          SUNDANCE_MSG3(verb() ,"HNMesh3D::getHangingElement FACE rtn = " << rtn << " realOffset:" << realOffset << " parentOffset:" << parentOffset);
01622          SUNDANCE_MSG3(verb() ,"HNMesh3D::getHangingElement FACE i:" << realOffset+parentOffset <<" hnInfo:" << hnInfo);
01623          // mark element as not hanging
01624          if ( rtn >= 0){
01625            if (cellDim == 0) {  isPointHanging_[rtn] = false; }
01626          else if (cellDim == 1) { isEdgeHanging_[rtn] = false; }
01627          else { isFaceHanging_[rtn] = false; }
01628          }
01629         }
01630   }
01631   return rtn; // Wall
01632 }
01633 
01634 int HNMesh3D::numMaxCofacets_ID(int cellDim, int cellID)
01635 {
01636   int rtn = -1;
01637     if (cellDim==1) { // edge MaxCoFacet
01638         int LID = cellID;
01639         int sum = 0;
01640         SUNDANCE_MSG3(verb() ,"HNMesh3D::numMaxCofacets_ID ID:" << LID << " edgeMaxCoF_[LID] = " << edgeMaxCoF_[LID] );
01641         for (int i = 0 ; i < 4 ; i++){
01642           if (edgeMaxCoF_[LID][i] >= 0)
01643             sum++;
01644         }
01645         // return the value, how many cells has this point, on the leaf level
01646         rtn = sum;
01647     }
01648     else if (cellDim==2) { // face MaxCoFacet
01649         int LID = cellID;
01650         int sum = 0;
01651         SUNDANCE_MSG3(verb() ,"HNMesh3D::numMaxCofacets_ID ID:" << LID << " faceMaxCoF_[LID] = " << faceMaxCoF_[LID] );
01652         for (int i = 0 ; i < 2 ; i++){
01653           if (faceMaxCoF_[LID][i] >= 0)
01654             sum++;
01655         }
01656         // return the value, how many cells has this point, on the leaf level
01657         rtn = sum;
01658     }
01659     return rtn;
01660 }
01661 
01662 // -----------
01663 void HNMesh3D::createLeafNumbering(){
01664 
01665   // set all leaf numbers to -1
01666 
01667   // - iterate trough the mesh and in the leaf cells , distribute leaf numbering
01668   // , detect if one cell is leaf ()
01669   // , have a tree similar tree traversal ... todo: later
01670 
01671   SUNDANCE_MSG3(verb() , "HNMesh3D::createLeafNumbering nrPoint:" << nrElem_[0] << " , nrEdge:"
01672       << nrElem_[1] << ", nrFace:" << nrElem_[2] << ", nrCell:" << nrElem_[3]);
01673   // we resize the leafID - > global
01674   vertexGIDToLeafMapping_.resize(nrElem_[0],-1);
01675   for (int dd = 0 ; dd < nrElem_[0] ; dd++) vertexGIDToLeafMapping_[dd] = -1;
01676   vertexLeafToGIDMapping_.resize(nrElem_[0],-1);
01677   for (int dd = 0 ; dd < nrElem_[0] ; dd++) vertexLeafToGIDMapping_[dd] = -1;
01678 
01679   edgeGIDToLeafMapping_.resize(nrElem_[1],-1);
01680   for (int dd = 0 ; dd < nrElem_[1] ; dd++) edgeGIDToLeafMapping_[dd] = -1;
01681   edgeLeafToGIDMapping_.resize(nrElem_[1],-1);
01682   for (int dd = 0 ; dd < nrElem_[1] ; dd++) edgeLeafToGIDMapping_[dd] = -1;
01683 
01684   faceGIDToLeafMapping_.resize(nrElem_[2],-1);
01685   for (int dd = 0 ; dd < nrElem_[2] ; dd++) faceGIDToLeafMapping_[dd] = -1;
01686   faceLeafToGIDMapping_.resize(nrElem_[2],-1);
01687   for (int dd = 0 ; dd < nrElem_[2] ; dd++) faceLeafToGIDMapping_[dd] = -1;
01688 
01689   cellGIDToLeafMapping_.resize(nrElem_[3],-1);
01690   for (int dd = 0 ; dd < nrElem_[3] ; dd++) cellGIDToLeafMapping_[dd] = -1;
01691   cellLeafToGIDMapping_.resize(nrElem_[3],-1);
01692   for (int dd = 0 ; dd < nrElem_[3] ; dd++) cellLeafToGIDMapping_[dd] = -1;
01693 
01694   nrVertexLeafGID_ = 0; nrCellLeafGID_ = 0; nrEdgeLeafGID_ = 0; nrFaceLeafGID_ = 0;
01695 
01696   nrVertexLeafLID_ = 0; nrCellLeafLID_ = 0; nrEdgeLeafLID_ = 0;
01697   vertexLIDToLeafMapping_.resize(nrElem_[0],-1);
01698   for (int dd = 0 ; dd < nrElem_[0] ; dd++) vertexLIDToLeafMapping_[dd] = -1;
01699   vertexLeafToLIDMapping_.resize(nrElem_[0],-1);
01700   for (int dd = 0 ; dd < nrElem_[0] ; dd++) vertexLeafToLIDMapping_[dd] = -1;
01701 
01702   edgeLIDToLeafMapping_.resize(nrElem_[1],-1);
01703   for (int dd = 0 ; dd < nrElem_[1] ; dd++) edgeLIDToLeafMapping_[dd] = -1;
01704   edgeLeafToLIDMapping_.resize(nrElem_[1],-1);
01705   for (int dd = 0 ; dd < nrElem_[1] ; dd++) edgeLeafToLIDMapping_[dd] = -1;
01706 
01707   faceLIDToLeafMapping_.resize(nrElem_[2],-1);
01708   for (int dd = 0 ; dd < nrElem_[2] ; dd++) faceLIDToLeafMapping_[dd] = -1;
01709   faceLeafToLIDMapping_.resize(nrElem_[2],-1);
01710   for (int dd = 0 ; dd < nrElem_[2] ; dd++) faceLeafToLIDMapping_[dd] = -1;
01711 
01712   cellLIDToLeafMapping_.resize(nrElem_[3],-1);
01713   for (int dd = 0 ; dd < nrElem_[3] ; dd++) cellLIDToLeafMapping_[dd] = -1;
01714   cellLeafToLIDMapping_.resize(nrElem_[3],-1);
01715   for (int dd = 0 ; dd < nrElem_[3] ; dd++) cellLeafToLIDMapping_[dd] = -1;
01716 
01717   SUNDANCE_MSG3(verb() , "HNMesh3D::createLeafNumbering , start assigning leaf numbers");
01718 
01719   // look for those leaf cells which points have a cell which maxCoFacet owner = myRank_
01720   // only those will have an LID
01721   Array<bool> hasCellLID(nrElem_[3],false);
01722 
01723   for (int ind = 0 ; ind < nrElem_[3] ; ind++){
01724     Array<int>& vertexIDs = cellsPoints_[ind];
01725     hasCellLID[ind] = false;
01726     for (int v = 0 ; v < 8 ; v++){
01727       Array<int>& maxCoFacet = pointMaxCoF_[vertexIDs[v]];
01728       hasCellLID[ind] =  ( hasCellLID[ind]
01729           || ( (maxCoFacet[0] >= 0) && (elementOwner_[3][maxCoFacet[0]] == myRank_) )
01730                     || ( (maxCoFacet[1] >= 0) && (elementOwner_[3][maxCoFacet[1]] == myRank_) )
01731                     || ( (maxCoFacet[2] >= 0) && (elementOwner_[3][maxCoFacet[2]] == myRank_) )
01732                     || ( (maxCoFacet[3] >= 0) && (elementOwner_[3][maxCoFacet[3]] == myRank_) )
01733                     || ( (maxCoFacet[4] >= 0) && (elementOwner_[3][maxCoFacet[4]] == myRank_) )
01734                     || ( (maxCoFacet[5] >= 0) && (elementOwner_[3][maxCoFacet[5]] == myRank_) )
01735                     || ( (maxCoFacet[6] >= 0) && (elementOwner_[3][maxCoFacet[6]] == myRank_) )
01736                     || ( (maxCoFacet[7] >= 0) && (elementOwner_[3][maxCoFacet[7]] == myRank_) )) ;
01737 
01738       // add cells with hanging nodes which have contribution to element which are owned by this processor
01739       // if vertex is hanging look into the parent cell at the same index and if the owner is myRank_ then add
01740       // to the cells which should be processed
01741       if ( (hasCellLID[ind] == false) && (isPointHanging_[vertexIDs[v]] == true)){
01742         int parentID = parentCellLID_[ind];
01743         Array<int>& parentVertexIDs = cellsPoints_[parentID];
01744         hasCellLID[ind] = hasCellLID[ind] || (elementOwner_[0][parentVertexIDs[v]] == myRank_);
01745       }
01746     }
01747     SUNDANCE_MSG3(verb() , "HNMesh3D::createLeafNumbering Cell ID :" << ind << " should be LID: " << hasCellLID[ind] <<
01748         " ,isCellLeaf_[ind]:" << isCellLeaf_[ind]);
01749   }
01750 
01751   //  treat special case, so that each hanging element has its parents
01752   // if we add one cell check hanging face, then add the maxCoF from the parent face if is leaf
01753   // if this is not successful then do the same thing for edges
01754   // - from each hanging edge there should be at least one cell on this processor which contains that parent edge !
01755   bool check_Ghost_cells = true;
01756   while (check_Ghost_cells){
01757     check_Ghost_cells = false;
01758       for (int ind = 0 ; ind < nrElem_[3] ; ind++){
01759        if ( (hasCellLID[ind] == true) && (elementOwner_[3][ind] != myRank_ ) ){
01760         bool lookforEdges = true;
01761         // check faces
01762         Array<int>& faceIDs = cellsFaces_[ind];
01763         for (int ii = 0 ; ii < 6 ; ii++ ){
01764           // if the face is hanging and does not belong to me
01765           if (isFaceHanging_[faceIDs[ii]] && ( elementOwner_[2][faceIDs[ii]] != myRank_)){
01766                     // get parent cells same face
01767           int parentCell = parentCellLID_[ind];
01768           Array<int>& parentfaceIDs = cellsFaces_[parentCell];
01769           for (int f = 0 ; f < 2 ; f++)
01770           if ( ( faceMaxCoF_[parentfaceIDs[ii]][f] >= 0 ) &&
01771              ( elementOwner_[3][ faceMaxCoF_[parentfaceIDs[ii]][f] ] != myRank_ ) &&
01772              ( hasCellLID[faceMaxCoF_[parentfaceIDs[ii]][f]] == false)  &&
01773              ( isCellLeaf_[faceMaxCoF_[parentfaceIDs[ii]][f]] ) ){
01774             hasCellLID[faceMaxCoF_[parentfaceIDs[ii]][f]] = true;
01775             check_Ghost_cells = true;
01776             lookforEdges = false;
01777           }
01778           }
01779         }
01780         // check edges
01781         Array<int>& edgeIDs = cellsEdges_[ind];
01782         // we have this if only
01783         if (lookforEdges){
01784           for (int ii = 0 ; ii < 12 ; ii++ ){
01785           // if the face is hanging and does not belong to me
01786           if (isEdgeHanging_[edgeIDs[ii]] && ( elementOwner_[1][edgeIDs[ii]] != myRank_)){
01787                     // get parent cells same face
01788           int parentCell = parentCellLID_[ind];
01789           Array<int>& parentEdgesIDs = cellsEdges_[parentCell];
01790           for (int f = 0 ; f < 4 ; f++)
01791           if ( ( edgeMaxCoF_[parentEdgesIDs[ii]][f] >= 0 ) &&
01792              ( elementOwner_[3][ edgeMaxCoF_[parentEdgesIDs[ii]][f] ] != myRank_ ) &&
01793              ( hasCellLID[edgeMaxCoF_[parentEdgesIDs[ii]][f]] == false)   &&
01794              ( isCellLeaf_[edgeMaxCoF_[parentEdgesIDs[ii]][f]] )
01795              ){
01796             hasCellLID[edgeMaxCoF_[parentEdgesIDs[ii]][f]] = true;
01797             check_Ghost_cells = true;
01798           }
01799           }
01800           } // from loop
01801         }// from lookforEdges IF
01802        }
01803       }
01804   }
01805 
01806   // we also have to list the cells which are not owned by the processor
01807   for (int ind = 0 ; ind < nrElem_[3] ; ind++)
01808   {
01809      // --------- GID numbering -----------
01810      // if cell is leaf and if is inside the computational domain
01811          if ( (isCellLeaf_[ind] == true) && (!isCellOut_[ind]) )
01812          {
01813            Array<int>& vertexIDs = cellsPoints_[ind];
01814              for (int v = 0; v < 8 ; v++)
01815              {
01816               SUNDANCE_MSG3(verb() , " createLeafGIDNumbering  vertexIDs[v]:" << vertexIDs[v] );
01817               if (vertexGIDToLeafMapping_[vertexIDs[v]] < 0)
01818               {
01819                  SUNDANCE_MSG3(verb() , " createLeafGIDNumbering -> VertexID:" << vertexIDs[v] << " , nrVertexLeafGID_:" << nrVertexLeafGID_ );
01820                  vertexLeafToGIDMapping_[nrVertexLeafGID_] = vertexIDs[v];
01821                  vertexGIDToLeafMapping_[vertexIDs[v]] = nrVertexLeafGID_;
01822                  nrVertexLeafGID_++;
01823               }
01824              }
01825            Array<int>& edgeIDs = cellsEdges_[ind];
01826            // for each edge check weather it already has a leaf index, if not create one
01827            for (int e = 0; e < 12 ; e++)
01828            {
01829              //SUNDANCE_MSG3(verb() , " createLeafNumbering  edgeLIDs[e]:" << edgeLIDs[e] );
01830              if (edgeGIDToLeafMapping_[edgeIDs[e]] < 0)
01831              {
01832                SUNDANCE_MSG3(verb() , " createLeafGIDNumbering -> edgeID:" << edgeIDs[e] << " , nrEdgeLeafGID_:" << nrEdgeLeafGID_ );
01833                //SUNDANCE_MSG3(verb() , " MaxCoFacet:" << edgeMaxCoF_[edgeLIDs[e]] << " edgeVertex:" << edgeVertex_[edgeLIDs[e]]);
01834                edgeLeafToGIDMapping_[nrEdgeLeafGID_] = edgeIDs[e];
01835                edgeGIDToLeafMapping_[edgeIDs[e]] = nrEdgeLeafGID_;
01836                nrEdgeLeafGID_++;
01837              }
01838            }
01839            Array<int>& faceIDs = cellsFaces_[ind];
01840            // for each face check weather it already has a leaf index, if not create one
01841            for (int f = 0; f < 6 ; f++)
01842            {
01843              //SUNDANCE_MSG3(verb() , " createLeafNumbering  edgeLIDs[e]:" << edgeLIDs[e] );
01844              if (faceGIDToLeafMapping_[faceIDs[f]] < 0)
01845              {
01846                SUNDANCE_MSG3(verb() , " createLeafGIDNumbering -> faceID:" << faceIDs[f] << " , nrFaceLeafGID_:" << nrFaceLeafGID_ );
01847                //SUNDANCE_MSG3(verb() , " MaxCoFacet:" << faceMaxCoF_[faceLIDs[e]] << " edgeVertex:" << faceVertex_[edgeLIDs[e]]);
01848                faceLeafToGIDMapping_[nrFaceLeafGID_] = faceIDs[f];
01849                faceGIDToLeafMapping_[faceIDs[f]] = nrFaceLeafGID_;
01850                nrFaceLeafGID_++;
01851              }
01852            }
01853            // create leaf index for the leaf cell
01854        SUNDANCE_MSG3(verb() , " createLeafGIDNumbering CELL cellID:" << ind << " , nrCellLeafGID_:" << nrCellLeafGID_ );
01855            cellLeafToGIDMapping_[nrCellLeafGID_] = ind;
01856            cellGIDToLeafMapping_[ind] = nrCellLeafGID_;
01857            nrCellLeafGID_++;
01858 
01859            // --------- LID numbering -----------
01860            // create leaf LID numbering , if this cell needs to be processed
01861            if (hasCellLID[ind]){
01862              // vertex
01863                  for (int v = 0; v < 8 ; v++)
01864                  {
01865                   if (vertexLIDToLeafMapping_[vertexIDs[v]] < 0)
01866                   {
01867                      SUNDANCE_MSG3(verb() , " createLeafLIDNumbering -> VertexID:" << vertexIDs[v] << " , nrVertexLeafLID_:" << nrVertexLeafLID_ );
01868                      vertexLeafToLIDMapping_[nrVertexLeafLID_] = vertexIDs[v];
01869                      vertexLIDToLeafMapping_[vertexIDs[v]] = nrVertexLeafLID_;
01870                      nrVertexLeafLID_++;
01871                   }
01872                  }
01873                // for each edge check weather it already has a leaf index, if not create one
01874                for (int e = 0; e < 12 ; e++)
01875                {
01876                  if (edgeLIDToLeafMapping_[edgeIDs[e]] < 0)
01877                  {
01878                    SUNDANCE_MSG3(verb() , " createLeafLIDNumbering -> edgeID:" << edgeIDs[e] << " , nrEdgeLeafLID_:" << nrEdgeLeafLID_ );
01879                    edgeLeafToLIDMapping_[nrEdgeLeafLID_] = edgeIDs[e];
01880                    edgeLIDToLeafMapping_[edgeIDs[e]] = nrEdgeLeafLID_;
01881                    nrEdgeLeafLID_++;
01882                  }
01883                }
01884                // face LID
01885                for (int f = 0; f < 6 ; f++)
01886                {
01887                  if (faceLIDToLeafMapping_[faceIDs[f]] < 0)
01888                  {
01889                    SUNDANCE_MSG3(verb() , " createLeafLIDNumbering -> faceID:" << faceIDs[f] << " , nrFaceLeafLID_:" << nrFaceLeafLID_ );
01890                    faceLeafToLIDMapping_[nrFaceLeafLID_] = faceIDs[f];
01891                    faceLIDToLeafMapping_[faceIDs[f]] = nrFaceLeafLID_;
01892                    nrFaceLeafLID_++;
01893                  }
01894                }
01895                // create leaf index for the leaf cell
01896                SUNDANCE_MSG3(verb() , " createLeafLIDNumbering CELL cellID:" << ind << " , nrCellLeafLID_:" << nrCellLeafLID_ );
01897                cellLeafToLIDMapping_[nrCellLeafLID_] = ind;
01898                cellLIDToLeafMapping_[ind] = nrCellLeafLID_;
01899                nrCellLeafLID_++;
01900            }
01901          }
01902   }
01903   SUNDANCE_MSG3(verb() , " nrVertexLeafGID_:" << nrVertexLeafGID_ << " nrEdgeLeafGID_:" << nrEdgeLeafGID_
01904       << " nrFaceLeafGID_:" << nrFaceLeafGID_ << " nrCellLeafGID_:" << nrCellLeafGID_ );
01905   SUNDANCE_MSG3(verb() , " nrVertexLeafLID_:" << nrVertexLeafLID_ << " nrEdgeLeafLID_:" << nrEdgeLeafLID_
01906       << " nrFaceLeafLID_:" <<nrFaceLeafLID_ << " nrCellLeafLID_:" << nrCellLeafLID_);
01907   SUNDANCE_MSG3(verb() , " vertexLIDToLeafMapping_: " << vertexLIDToLeafMapping_);
01908   SUNDANCE_MSG3(verb() , "HNMesh3D::createLeafNumbering , DONE");
01909 }
01910 
01911 
01912 // ====================================== OTHER LEAF NUMBERING ALGORITHM ==================
01913 
01914 int HNMesh3D::estimateCellLoad(int ID){
01915   int rtn = 0;
01916   //SUNDANCE_MSG3( 5 , "HNMesh3D::estimateCellLoad , ID:" << ID);
01917   if (isCellLeaf_[ID]){
01918     if (!isCellOut_[ID]) rtn = 1;
01919   } else {
01920     // for each child call recursivly the function
01921     for (int r = 0 ; r < (int)cellsChildren_[ID].size() ; r++){
01922       if (cellLevel_[ID] < cellLevel_[cellsChildren_[ID][r]]){
01923         rtn = rtn + estimateCellLoad(cellsChildren_[ID][r]);
01924       }
01925     }
01926   }
01927     return rtn;
01928 }
01929 
01930 /** mark the cells and its facets for one processor*/
01931 void HNMesh3D::markCellsAndFacets(int cellID , int procID){
01932   // mark the cell and the facets
01933   if (elementOwner_[3][cellID] < 0)  { elementOwner_[3][cellID] = procID; }
01934   //SUNDANCE_MSG3(verb() , "mark cell: " << cellID );
01935   if (elementOwner_[2][cellsFaces_[cellID][0]] < 0 ) { elementOwner_[2][cellsFaces_[cellID][0]] = procID;}
01936   if (elementOwner_[2][cellsFaces_[cellID][1]] < 0 ) { elementOwner_[2][cellsFaces_[cellID][1]] = procID;}
01937   if (elementOwner_[2][cellsFaces_[cellID][2]] < 0 ) { elementOwner_[2][cellsFaces_[cellID][2]] = procID;}
01938   if (elementOwner_[2][cellsFaces_[cellID][3]] < 0 ) { elementOwner_[2][cellsFaces_[cellID][3]] = procID;}
01939   if (elementOwner_[2][cellsFaces_[cellID][4]] < 0 ) { elementOwner_[2][cellsFaces_[cellID][4]] = procID;}
01940   if (elementOwner_[2][cellsFaces_[cellID][5]] < 0 ) { elementOwner_[2][cellsFaces_[cellID][5]] = procID;}
01941 
01942   if (elementOwner_[1][cellsEdges_[cellID][0]] < 0 ) { elementOwner_[1][cellsEdges_[cellID][0]] = procID;}
01943   if (elementOwner_[1][cellsEdges_[cellID][1]] < 0 ) { elementOwner_[1][cellsEdges_[cellID][1]] = procID;}
01944   if (elementOwner_[1][cellsEdges_[cellID][2]] < 0 ) { elementOwner_[1][cellsEdges_[cellID][2]] = procID;}
01945   if (elementOwner_[1][cellsEdges_[cellID][3]] < 0 ) { elementOwner_[1][cellsEdges_[cellID][3]] = procID;}
01946   if (elementOwner_[1][cellsEdges_[cellID][4]] < 0 ) { elementOwner_[1][cellsEdges_[cellID][4]] = procID;}
01947   if (elementOwner_[1][cellsEdges_[cellID][5]] < 0 ) { elementOwner_[1][cellsEdges_[cellID][5]] = procID;}
01948   if (elementOwner_[1][cellsEdges_[cellID][6]] < 0 ) { elementOwner_[1][cellsEdges_[cellID][6]] = procID;}
01949   if (elementOwner_[1][cellsEdges_[cellID][7]] < 0 ) { elementOwner_[1][cellsEdges_[cellID][7]] = procID;}
01950   if (elementOwner_[1][cellsEdges_[cellID][8]] < 0 ) { elementOwner_[1][cellsEdges_[cellID][8]] = procID;}
01951   if (elementOwner_[1][cellsEdges_[cellID][9]] < 0 ) { elementOwner_[1][cellsEdges_[cellID][9]] = procID;}
01952   if (elementOwner_[1][cellsEdges_[cellID][10]] < 0 ) { elementOwner_[1][cellsEdges_[cellID][10]] = procID;}
01953   if (elementOwner_[1][cellsEdges_[cellID][11]] < 0 ) { elementOwner_[1][cellsEdges_[cellID][11]] = procID;}
01954 
01955   if (elementOwner_[0][cellsPoints_[cellID][0]] < 0 ) { elementOwner_[0][cellsPoints_[cellID][0]] = procID;}
01956   if (elementOwner_[0][cellsPoints_[cellID][1]] < 0 ) { elementOwner_[0][cellsPoints_[cellID][1]] = procID;}
01957   if (elementOwner_[0][cellsPoints_[cellID][2]] < 0 ) { elementOwner_[0][cellsPoints_[cellID][2]] = procID;}
01958   if (elementOwner_[0][cellsPoints_[cellID][3]] < 0 ) { elementOwner_[0][cellsPoints_[cellID][3]] = procID;}
01959   if (elementOwner_[0][cellsPoints_[cellID][4]] < 0 ) { elementOwner_[0][cellsPoints_[cellID][4]] = procID;}
01960   if (elementOwner_[0][cellsPoints_[cellID][5]] < 0 ) { elementOwner_[0][cellsPoints_[cellID][5]] = procID;}
01961   if (elementOwner_[0][cellsPoints_[cellID][6]] < 0 ) { elementOwner_[0][cellsPoints_[cellID][6]] = procID;}
01962   if (elementOwner_[0][cellsPoints_[cellID][7]] < 0 ) { elementOwner_[0][cellsPoints_[cellID][7]] = procID;}
01963 
01964   if (!isCellLeaf_[cellID]){
01965     // for each child cell do it recursively
01966     for (int r = 0 ; r < (int)cellsChildren_[cellID].size() ; r++){
01967       if (cellLevel_[cellID] < cellLevel_[cellsChildren_[cellID][r]]){
01968         markCellsAndFacets(cellsChildren_[cellID][r] , procID);
01969       }
01970     }
01971   }
01972 }
01973 
01974 void HNMesh3D::createLeafNumbering_sophisticated(){
01975 
01976   // this array shows which cell will belong to this processor
01977   Array<bool> hasCellLID(nrElem_[3],false);
01978   double total_load = 0.0;
01979   //int nrCoarseCell = _res_x * _res_y * _res_z;
01980   Array<int> coarseCellLoad( _res_x * _res_y * _res_z , 1 );
01981 
01982   // the principle for load is that each cell is one unit load
01983   // count the total number of cells which are inside the computational domain and are leaf cells
01984   // make a space filling curve traversal and assign each cell to one processor
01985   // on the coarser level make a Z-curve traversal, and there for each cell make a recursive traversal
01986   // distribute only the coarsest cells, since the tree traversal is not continuous
01987   // "elementOwner_" has to be changed!!!
01988 
01989   for (int ind = 0 ; ind < nrElem_[3] ; ind++){
01990         if (cellLevel_[ind] < 1) {
01991           // estimate cells load
01992           coarseCellLoad[ind] = estimateCellLoad(ind);
01993         }
01994     if ((isCellLeaf_[ind] == true) && (!isCellOut_[ind]) )
01995     { total_load = total_load + 1 ; }
01996   }
01997 
01998   SUNDANCE_MSG3(verb() , "total_load = " << total_load << " , nrCell = " << nrElem_[3]);
01999 
02000   // generate the space filling curve traversal for a given level and unit square
02001   // and assign the coarsest cells to processors
02002 #ifdef _MSC_VER
02003   int levelM = ::ceil( std::max<double>( std::max<double>( ::log2(_res_x) , ::log2(_res_y ) ) , ::log2(_res_z ) ) );
02004 #else
02005   int levelM = ::ceil( ::fmax( ::fmax( ::log2(_res_x) , ::log2(_res_y ) ) , ::log2(_res_z ) ) );
02006 #endif
02007   //int unitN = (int)::pow(2, levelM );
02008   Array<int> vectX1(8), vectY1(8), vectZ1(8), vectX2(8), vectY2(8), vectZ2(8);
02009   vectX1[0] = 0; vectX1[1] = (int)std::pow(2,levelM-1); vectX1[2] = 0; vectX1[3] = (int)std::pow(2,levelM-1);
02010   vectX1[4] = 0; vectX1[5] = (int)std::pow(2,levelM-1); vectX1[6] = 0; vectX1[7] = (int)std::pow(2,levelM-1);
02011   vectY1[0] = 0; vectY1[1] = 0; vectY1[2] = (int)std::pow(2,levelM-1); vectY1[3] = (int)std::pow(2,levelM-1);
02012   vectY1[4] = 0; vectY1[5] = 0; vectY1[6] = (int)std::pow(2,levelM-1); vectY1[7] = (int)std::pow(2,levelM-1);
02013   vectZ1[0] = 0; vectZ1[1] = 0; vectZ1[2] = 0; vectZ1[3] = 0;
02014   vectZ1[4] = (int)std::pow(2,levelM-1); vectZ1[5] = (int)std::pow(2,levelM-1); vectZ1[6] = (int)std::pow(2,levelM-1); vectZ1[7] = (int)std::pow(2,levelM-1);
02015 
02016   vectX2[0] = 0; vectX2[1] = (int)std::pow(2,levelM-1); vectX2[2] = 0; vectX2[3] = (int)std::pow(2,levelM-1);
02017   vectX2[4] = 0; vectX2[5] = (int)std::pow(2,levelM-1); vectX2[6] = 0; vectX2[7] = (int)std::pow(2,levelM-1);
02018   vectY2[0] = 0; vectY2[1] = 0; vectY2[2] = (int)std::pow(2,levelM-1); vectY2[3] = (int)std::pow(2,levelM-1);
02019   vectY2[4] = 0; vectY2[5] = 0; vectY2[6] = (int)std::pow(2,levelM-1); vectY2[7] = (int)std::pow(2,levelM-1);
02020   vectZ2[0] = 0; vectZ2[1] = 0; vectZ2[2] = 0; vectZ2[3] = 0;
02021   vectZ2[4] = (int)std::pow(2,levelM-1); vectZ2[5] = (int)std::pow(2,levelM-1); vectZ2[6] = (int)std::pow(2,levelM-1); vectZ2[7] = (int)std::pow(2,levelM-1);
02022 
02023   int addX[8] = { 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1};
02024   int addY[8] = { 0 , 0 , 1 , 1 , 0 , 0 , 1 , 1};
02025   int addZ[8] = { 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1};
02026   Array<int> *inX = &vectX1 , *inY = &vectY1 , *inZ = &vectZ1 ,*outX = &vectX2 , *outY = &vectY2 , *outZ = &vectZ2 , *tmpVectP;
02027   int levelActual = levelM - 2;
02028   // this method generates the index for a unit square Z-curve traversal
02029   while (levelActual >= 0){
02030     outX->resize( 8 * inX->size() );
02031     outY->resize( 8 * inY->size() );
02032     outZ->resize( 8 * inZ->size() );
02033     int cI = 0 , addO = (int)std::pow(2,levelActual);
02034     SUNDANCE_MSG3(verb() , " outX->size():" << outX->size() << ", levelActual:" << levelActual << " , addO:" << addO);
02035     // here create the 8 recursive cells
02036     for (int ce = 0 ; ce < inX->size() ; ce++){
02037       (*outX)[cI+0] = (*inX)[ce] + addO*addX[0];  (*outY)[cI+0] = (*inY)[ce] + addO*addY[0];  (*outZ)[cI+0] = (*inZ)[ce] + addO*addZ[0];
02038       (*outX)[cI+1] = (*inX)[ce] + addO*addX[1];  (*outY)[cI+1] = (*inY)[ce] + addO*addY[1];  (*outZ)[cI+1] = (*inZ)[ce] + addO*addZ[1];
02039       (*outX)[cI+2] = (*inX)[ce] + addO*addX[2];  (*outY)[cI+2] = (*inY)[ce] + addO*addY[2];  (*outZ)[cI+2] = (*inZ)[ce] + addO*addZ[2];
02040       (*outX)[cI+3] = (*inX)[ce] + addO*addX[3];  (*outY)[cI+3] = (*inY)[ce] + addO*addY[3];  (*outZ)[cI+3] = (*inZ)[ce] + addO*addZ[3];
02041       (*outX)[cI+4] = (*inX)[ce] + addO*addX[4];  (*outY)[cI+4] = (*inY)[ce] + addO*addY[4];  (*outZ)[cI+4] = (*inZ)[ce] + addO*addZ[4];
02042       (*outX)[cI+5] = (*inX)[ce] + addO*addX[5];  (*outY)[cI+5] = (*inY)[ce] + addO*addY[5];  (*outZ)[cI+5] = (*inZ)[ce] + addO*addZ[5];
02043       (*outX)[cI+6] = (*inX)[ce] + addO*addX[6];  (*outY)[cI+6] = (*inY)[ce] + addO*addY[6];  (*outZ)[cI+6] = (*inZ)[ce] + addO*addZ[6];
02044       (*outX)[cI+7] = (*inX)[ce] + addO*addX[7];  (*outY)[cI+7] = (*inY)[ce] + addO*addY[7];  (*outZ)[cI+7] = (*inZ)[ce] + addO*addZ[7];
02045       cI = cI + 8;
02046     }
02047     SUNDANCE_MSG3(verb() , " EX: " << (*outX)[0] << " , " << (*outX)[1] << " , " << (*outX)[2]);
02048     SUNDANCE_MSG3(verb() , " EY: " << (*outY)[0] << " , " << (*outY)[1] << " , " << (*outY)[2]);
02049     SUNDANCE_MSG3(verb() , " EZ: " << (*outZ)[0] << " , " << (*outZ)[1] << " , " << (*outZ)[2]);
02050     // decrease the level
02051     levelActual = levelActual - 1;
02052     tmpVectP = inX; inX = outX; outX = tmpVectP;
02053     tmpVectP = inY; inY = outY; outY = tmpVectP;
02054     tmpVectP = inZ; inZ = outZ; outZ = tmpVectP;
02055   }
02056   // switch the vectors back once we are finished
02057   tmpVectP = inX; inX = outX; outX = tmpVectP;
02058   tmpVectP = inY; inY = outY; outY = tmpVectP;
02059   tmpVectP = inZ; inZ = outZ; outZ = tmpVectP;
02060 
02061   // unmark the cells owners
02062   for (int tmp = 0 ; tmp < nrElem_[0] ; tmp++ ){ elementOwner_[0][tmp] = -1; }
02063   for (int tmp = 0 ; tmp < nrElem_[1] ; tmp++ ){ elementOwner_[1][tmp] = -1; }
02064   for (int tmp = 0 ; tmp < nrElem_[2] ; tmp++ ){ elementOwner_[2][tmp] = -1; }
02065   for (int tmp = 0 ; tmp < nrElem_[3] ; tmp++ ){ elementOwner_[3][tmp] = -1; }
02066 
02067   //mark the cells, vertex and edge to which cell they belong, recursively for each cell
02068   int coarseCellID , actProcID = 0 , actualLoad = 0;
02069   double loadPerProc = (double)total_load / (double)nrProc_ , diff_load = 0.0;
02070   for (int ind = 0 ; ind < outX->size() ; ind++){
02071     // first test the combinaiton if this is in the range
02072         if ( ((*outX)[ind] < _res_x) && ((*outY)[ind] < _res_y) && ((*outZ)[ind] < _res_z) ){
02073           // !!!! --- here is very important that we compute the right index
02074           coarseCellID = ((*outZ)[ind])*_res_x*_res_y + ((*outY)[ind])*_res_x + ((*outX)[ind]) ;
02075           SUNDANCE_MSG3(verb(),"Z-curve trav. ind:" << ind << " , coarseCellID:" << coarseCellID
02076               << " , indX:" << (*outX)[ind] << " , indY:" << (*outY)[ind] << " , indZ:" << (*outZ)[ind]);
02077           //the level of this cell with the ID should be zero
02078           TEUCHOS_TEST_FOR_EXCEPTION( cellLevel_[coarseCellID] > 0 , std::logic_error, " coarseCellID:" << coarseCellID << " has level:" << cellLevel_[coarseCellID] );
02079           markCellsAndFacets( coarseCellID , actProcID);
02080           actualLoad = actualLoad + coarseCellLoad[coarseCellID];
02081           // increment the processor if necessary
02082         if (((double)actualLoad >= (loadPerProc - 1e-8 - diff_load)) && ( actProcID < nrProc_-1 )){
02083           SUNDANCE_MSG3(verb() , "Increase CPU , actualLoad:" << actualLoad << " loadPerProc:" << loadPerProc );
02084           // compensate the load difference for the next CPU
02085           diff_load = actualLoad - loadPerProc;
02086           actProcID = actProcID + 1;
02087           actualLoad = 0;
02088         }
02089         }
02090   }
02091 
02092   // unmark the cells owners
02093   SUNDANCE_MSG3(verb()," nrElem_[0]:" << nrElem_[0] << " , nrElem_[1]:" << nrElem_[1] << " , nrElem_[2]" << nrElem_[2]);
02094   for (int tmp = 0 ; tmp < nrElem_[0] ; tmp++ ){ TEUCHOS_TEST_FOR_EXCEPTION( elementOwner_[0][tmp] < 0 , std::logic_error, " 0 tmp:" << tmp); }
02095   for (int tmp = 0 ; tmp < nrElem_[1] ; tmp++ ){ TEUCHOS_TEST_FOR_EXCEPTION( elementOwner_[1][tmp] < 0 , std::logic_error, " 1 tmp:" << tmp); }
02096   for (int tmp = 0 ; tmp < nrElem_[2] ; tmp++ ){ TEUCHOS_TEST_FOR_EXCEPTION( elementOwner_[2][tmp] < 0 , std::logic_error, " 2 tmp:" << tmp); }
02097   for (int tmp = 0 ; tmp < nrElem_[3] ; tmp++ ){ TEUCHOS_TEST_FOR_EXCEPTION( elementOwner_[3][tmp] < 0 , std::logic_error, " 3 tmp:" << tmp); }
02098 
02099 // ==== what comes here is a code duplication from the method above ===========
02100 
02101   SUNDANCE_MSG3(verb() , "HNMesh3D::createLeafNumbering nrPoint:" << nrElem_[0] << " , nrEdge:"
02102       << nrElem_[1] << ", nrFace:" << nrElem_[2] << ", nrCell:" << nrElem_[3]);
02103   // we resize the leafID - > global
02104   vertexGIDToLeafMapping_.resize(nrElem_[0],-1);
02105   for (int dd = 0 ; dd < nrElem_[0] ; dd++) vertexGIDToLeafMapping_[dd] = -1;
02106   vertexLeafToGIDMapping_.resize(nrElem_[0],-1);
02107   for (int dd = 0 ; dd < nrElem_[0] ; dd++) vertexLeafToGIDMapping_[dd] = -1;
02108 
02109   edgeGIDToLeafMapping_.resize(nrElem_[1],-1);
02110   for (int dd = 0 ; dd < nrElem_[1] ; dd++) edgeGIDToLeafMapping_[dd] = -1;
02111   edgeLeafToGIDMapping_.resize(nrElem_[1],-1);
02112   for (int dd = 0 ; dd < nrElem_[1] ; dd++) edgeLeafToGIDMapping_[dd] = -1;
02113 
02114   faceGIDToLeafMapping_.resize(nrElem_[2],-1);
02115   for (int dd = 0 ; dd < nrElem_[2] ; dd++) faceGIDToLeafMapping_[dd] = -1;
02116   faceLeafToGIDMapping_.resize(nrElem_[2],-1);
02117   for (int dd = 0 ; dd < nrElem_[2] ; dd++) faceLeafToGIDMapping_[dd] = -1;
02118 
02119   cellGIDToLeafMapping_.resize(nrElem_[3],-1);
02120   for (int dd = 0 ; dd < nrElem_[3] ; dd++) cellGIDToLeafMapping_[dd] = -1;
02121   cellLeafToGIDMapping_.resize(nrElem_[3],-1);
02122   for (int dd = 0 ; dd < nrElem_[3] ; dd++) cellLeafToGIDMapping_[dd] = -1;
02123 
02124   nrVertexLeafGID_ = 0; nrCellLeafGID_ = 0; nrEdgeLeafGID_ = 0; nrFaceLeafGID_ = 0;
02125 
02126   nrVertexLeafLID_ = 0; nrCellLeafLID_ = 0; nrEdgeLeafLID_ = 0;
02127   vertexLIDToLeafMapping_.resize(nrElem_[0],-1);
02128   for (int dd = 0 ; dd < nrElem_[0] ; dd++) vertexLIDToLeafMapping_[dd] = -1;
02129   vertexLeafToLIDMapping_.resize(nrElem_[0],-1);
02130   for (int dd = 0 ; dd < nrElem_[0] ; dd++) vertexLeafToLIDMapping_[dd] = -1;
02131 
02132   edgeLIDToLeafMapping_.resize(nrElem_[1],-1);
02133   for (int dd = 0 ; dd < nrElem_[1] ; dd++) edgeLIDToLeafMapping_[dd] = -1;
02134   edgeLeafToLIDMapping_.resize(nrElem_[1],-1);
02135   for (int dd = 0 ; dd < nrElem_[1] ; dd++) edgeLeafToLIDMapping_[dd] = -1;
02136 
02137   faceLIDToLeafMapping_.resize(nrElem_[2],-1);
02138   for (int dd = 0 ; dd < nrElem_[2] ; dd++) faceLIDToLeafMapping_[dd] = -1;
02139   faceLeafToLIDMapping_.resize(nrElem_[2],-1);
02140   for (int dd = 0 ; dd < nrElem_[2] ; dd++) faceLeafToLIDMapping_[dd] = -1;
02141 
02142   cellLIDToLeafMapping_.resize(nrElem_[3],-1);
02143   for (int dd = 0 ; dd < nrElem_[3] ; dd++) cellLIDToLeafMapping_[dd] = -1;
02144   cellLeafToLIDMapping_.resize(nrElem_[3],-1);
02145   for (int dd = 0 ; dd < nrElem_[3] ; dd++) cellLeafToLIDMapping_[dd] = -1;
02146 
02147   SUNDANCE_MSG3(verb() , "HNMesh3D::createLeafNumbering , start assigning leaf numbers");
02148 
02149   // look for those leaf cells which points have a cell which maxCoFacet owner = myRank_
02150   // only those will have an LID
02151   for (int ind = 0 ; ind < nrElem_[3] ; ind++){
02152     Array<int>& vertexIDs = cellsPoints_[ind];
02153     hasCellLID[ind] = false;
02154     for (int v = 0 ; v < 8 ; v++){
02155       Array<int>& maxCoFacet = pointMaxCoF_[vertexIDs[v]];
02156       hasCellLID[ind] =  ( hasCellLID[ind]
02157           || ( (maxCoFacet[0] >= 0) && (elementOwner_[3][maxCoFacet[0]] == myRank_) )
02158                     || ( (maxCoFacet[1] >= 0) && (elementOwner_[3][maxCoFacet[1]] == myRank_) )
02159                     || ( (maxCoFacet[2] >= 0) && (elementOwner_[3][maxCoFacet[2]] == myRank_) )
02160                     || ( (maxCoFacet[3] >= 0) && (elementOwner_[3][maxCoFacet[3]] == myRank_) )
02161                     || ( (maxCoFacet[4] >= 0) && (elementOwner_[3][maxCoFacet[4]] == myRank_) )
02162                     || ( (maxCoFacet[5] >= 0) && (elementOwner_[3][maxCoFacet[5]] == myRank_) )
02163                     || ( (maxCoFacet[6] >= 0) && (elementOwner_[3][maxCoFacet[6]] == myRank_) )
02164                     || ( (maxCoFacet[7] >= 0) && (elementOwner_[3][maxCoFacet[7]] == myRank_) )) ;
02165 
02166       // add cells with hanging nodes which have contribution to element which are owned by this processor
02167       // if vertex is hanging look into the parent cell at the same index and if the owner is myRank_ then add
02168       // to the cells which should be processed
02169       if ( (hasCellLID[ind] == false) && (isPointHanging_[vertexIDs[v]] == true)){
02170         int parentID = parentCellLID_[ind];
02171         Array<int>& parentVertexIDs = cellsPoints_[parentID];
02172         hasCellLID[ind] = hasCellLID[ind] || (elementOwner_[0][parentVertexIDs[v]] == myRank_);
02173       }
02174     }
02175     SUNDANCE_MSG3(verb() , "HNMesh3D::createLeafNumbering Cell ID :" << ind << " should be LID: " << hasCellLID[ind] <<
02176         " ,isCellLeaf_[ind]:" << isCellLeaf_[ind]);
02177   }
02178 
02179   //  treat special case, so that each hanging element has its parents
02180   // if we add one cell check hanging face, then add the maxCoF from the parent face if is leaf
02181   // if this is not successful then do the same thing for edges
02182   // - from each hanging edge there should be at least one cell on this processor which contains that parent edge !
02183   bool check_Ghost_cells = true;
02184   while (check_Ghost_cells){
02185     check_Ghost_cells = false;
02186       for (int ind = 0 ; ind < nrElem_[3] ; ind++){
02187        if ( (hasCellLID[ind] == true) && (elementOwner_[3][ind] != myRank_ ) ){
02188         bool lookforEdges = true;
02189         // check faces
02190         Array<int>& faceIDs = cellsFaces_[ind];
02191         for (int ii = 0 ; ii < 6 ; ii++ ){
02192           // if the face is hanging and does not belong to me
02193           if (isFaceHanging_[faceIDs[ii]] && ( elementOwner_[2][faceIDs[ii]] != myRank_)){
02194                     // get parent cells same face
02195           int parentCell = parentCellLID_[ind];
02196           Array<int>& parentfaceIDs = cellsFaces_[parentCell];
02197           for (int f = 0 ; f < 2 ; f++)
02198           if ( ( faceMaxCoF_[parentfaceIDs[ii]][f] >= 0 ) &&
02199              ( elementOwner_[3][ faceMaxCoF_[parentfaceIDs[ii]][f] ] != myRank_ ) &&
02200              ( hasCellLID[faceMaxCoF_[parentfaceIDs[ii]][f]] == false)  &&
02201              ( isCellLeaf_[faceMaxCoF_[parentfaceIDs[ii]][f]] ) ){
02202             hasCellLID[faceMaxCoF_[parentfaceIDs[ii]][f]] = true;
02203             check_Ghost_cells = true;
02204             lookforEdges = false;
02205           }
02206           }
02207         }
02208         // check edges
02209         Array<int>& edgeIDs = cellsEdges_[ind];
02210         // we have this if only
02211         if (lookforEdges){
02212           for (int ii = 0 ; ii < 12 ; ii++ ){
02213           // if the face is hanging and does not belong to me
02214           if (isEdgeHanging_[edgeIDs[ii]] && ( elementOwner_[1][edgeIDs[ii]] != myRank_)){
02215                     // get parent cells same face
02216           int parentCell = parentCellLID_[ind];
02217           Array<int>& parentEdgesIDs = cellsEdges_[parentCell];
02218           for (int f = 0 ; f < 4 ; f++)
02219           if ( ( edgeMaxCoF_[parentEdgesIDs[ii]][f] >= 0 ) &&
02220              ( elementOwner_[3][ edgeMaxCoF_[parentEdgesIDs[ii]][f] ] != myRank_ ) &&
02221              ( hasCellLID[edgeMaxCoF_[parentEdgesIDs[ii]][f]] == false)   &&
02222              ( isCellLeaf_[edgeMaxCoF_[parentEdgesIDs[ii]][f]] )
02223              ){
02224             hasCellLID[edgeMaxCoF_[parentEdgesIDs[ii]][f]] = true;
02225             check_Ghost_cells = true;
02226           }
02227           }
02228           } // from loop
02229         }// from lookforEdges IF
02230        }
02231       }
02232   }
02233 
02234   // we also have to list the cells which are not owned by the processor
02235   for (int ind = 0 ; ind < nrElem_[3] ; ind++)
02236   {
02237      // --------- GID numbering -----------
02238      // if cell is leaf and if is inside the computational domain
02239          if ( (isCellLeaf_[ind] == true) && (!isCellOut_[ind]) )
02240          {
02241            Array<int>& vertexIDs = cellsPoints_[ind];
02242              for (int v = 0; v < 8 ; v++)
02243              {
02244               SUNDANCE_MSG3(verb() , " createLeafGIDNumbering  vertexIDs[v]:" << vertexIDs[v] );
02245               if (vertexGIDToLeafMapping_[vertexIDs[v]] < 0)
02246               {
02247                  SUNDANCE_MSG3(verb() , " createLeafGIDNumbering -> VertexID:" << vertexIDs[v] << " , nrVertexLeafGID_:" << nrVertexLeafGID_ );
02248                  vertexLeafToGIDMapping_[nrVertexLeafGID_] = vertexIDs[v];
02249                  vertexGIDToLeafMapping_[vertexIDs[v]] = nrVertexLeafGID_;
02250                  nrVertexLeafGID_++;
02251               }
02252              }
02253            Array<int>& edgeIDs = cellsEdges_[ind];
02254            // for each edge check weather it already has a leaf index, if not create one
02255            for (int e = 0; e < 12 ; e++)
02256            {
02257              //SUNDANCE_MSG3(verb() , " createLeafNumbering  edgeLIDs[e]:" << edgeLIDs[e] );
02258              if (edgeGIDToLeafMapping_[edgeIDs[e]] < 0)
02259              {
02260                SUNDANCE_MSG3(verb() , " createLeafGIDNumbering -> edgeID:" << edgeIDs[e] << " , nrEdgeLeafGID_:" << nrEdgeLeafGID_ );
02261                //SUNDANCE_MSG3(verb() , " MaxCoFacet:" << edgeMaxCoF_[edgeLIDs[e]] << " edgeVertex:" << edgeVertex_[edgeLIDs[e]]);
02262                edgeLeafToGIDMapping_[nrEdgeLeafGID_] = edgeIDs[e];
02263                edgeGIDToLeafMapping_[edgeIDs[e]] = nrEdgeLeafGID_;
02264                nrEdgeLeafGID_++;
02265              }
02266            }
02267            Array<int>& faceIDs = cellsFaces_[ind];
02268            // for each face check weather it already has a leaf index, if not create one
02269            for (int f = 0; f < 6 ; f++)
02270            {
02271              //SUNDANCE_MSG3(verb() , " createLeafNumbering  edgeLIDs[e]:" << edgeLIDs[e] );
02272              if (faceGIDToLeafMapping_[faceIDs[f]] < 0)
02273              {
02274                SUNDANCE_MSG3(verb() , " createLeafGIDNumbering -> faceID:" << faceIDs[f] << " , nrFaceLeafGID_:" << nrFaceLeafGID_ );
02275                //SUNDANCE_MSG3(verb() , " MaxCoFacet:" << faceMaxCoF_[faceLIDs[e]] << " edgeVertex:" << faceVertex_[edgeLIDs[e]]);
02276                faceLeafToGIDMapping_[nrFaceLeafGID_] = faceIDs[f];
02277                faceGIDToLeafMapping_[faceIDs[f]] = nrFaceLeafGID_;
02278                nrFaceLeafGID_++;
02279              }
02280            }
02281            // create leaf index for the leaf cell
02282        SUNDANCE_MSG3(verb() , " createLeafGIDNumbering CELL cellID:" << ind << " , nrCellLeafGID_:" << nrCellLeafGID_ );
02283            cellLeafToGIDMapping_[nrCellLeafGID_] = ind;
02284            cellGIDToLeafMapping_[ind] = nrCellLeafGID_;
02285            nrCellLeafGID_++;
02286 
02287            // --------- LID numbering -----------
02288            // create leaf LID numbering , if this cell needs to be processed
02289            if (hasCellLID[ind]){
02290              // vertex
02291                  for (int v = 0; v < 8 ; v++)
02292                  {
02293                   if (vertexLIDToLeafMapping_[vertexIDs[v]] < 0)
02294                   {
02295                      SUNDANCE_MSG3(verb() , " createLeafLIDNumbering -> VertexID:" << vertexIDs[v] << " , nrVertexLeafLID_:" << nrVertexLeafLID_ );
02296                      vertexLeafToLIDMapping_[nrVertexLeafLID_] = vertexIDs[v];
02297                      vertexLIDToLeafMapping_[vertexIDs[v]] = nrVertexLeafLID_;
02298                      nrVertexLeafLID_++;
02299                   }
02300                  }
02301                // for each edge check weather it already has a leaf index, if not create one
02302                for (int e = 0; e < 12 ; e++)
02303                {
02304                  if (edgeLIDToLeafMapping_[edgeIDs[e]] < 0)
02305                  {
02306                    SUNDANCE_MSG3(verb() , " createLeafLIDNumbering -> edgeID:" << edgeIDs[e] << " , nrEdgeLeafLID_:" << nrEdgeLeafLID_ );
02307                    edgeLeafToLIDMapping_[nrEdgeLeafLID_] = edgeIDs[e];
02308                    edgeLIDToLeafMapping_[edgeIDs[e]] = nrEdgeLeafLID_;
02309                    nrEdgeLeafLID_++;
02310                  }
02311                }
02312                // face LID
02313                for (int f = 0; f < 6 ; f++)
02314                {
02315                  if (faceLIDToLeafMapping_[faceIDs[f]] < 0)
02316                  {
02317                    SUNDANCE_MSG3(verb() , " createLeafLIDNumbering -> faceID:" << faceIDs[f] << " , nrFaceLeafLID_:" << nrFaceLeafLID_ );
02318                    faceLeafToLIDMapping_[nrFaceLeafLID_] = faceIDs[f];
02319                    faceLIDToLeafMapping_[faceIDs[f]] = nrFaceLeafLID_;
02320                    nrFaceLeafLID_++;
02321                  }
02322                }
02323                // create leaf index for the leaf cell
02324                SUNDANCE_MSG3(verb() , " createLeafLIDNumbering CELL cellID:" << ind << " , nrCellLeafLID_:" << nrCellLeafLID_ );
02325                cellLeafToLIDMapping_[nrCellLeafLID_] = ind;
02326                cellLIDToLeafMapping_[ind] = nrCellLeafLID_;
02327                nrCellLeafLID_++;
02328            }
02329          }
02330   }
02331   SUNDANCE_MSG3(verb() , " nrVertexLeafGID_:" << nrVertexLeafGID_ << " nrEdgeLeafGID_:" << nrEdgeLeafGID_
02332       << " nrFaceLeafGID_:" << nrFaceLeafGID_ << " nrCellLeafGID_:" << nrCellLeafGID_ );
02333   SUNDANCE_MSG3(verb() , " nrVertexLeafLID_:" << nrVertexLeafLID_ << " nrEdgeLeafLID_:" << nrEdgeLeafLID_
02334       << " nrFaceLeafLID_:" <<nrFaceLeafLID_ << " nrCellLeafLID_:" << nrCellLeafLID_);
02335   SUNDANCE_MSG3(verb() , " vertexLIDToLeafMapping_: " << vertexLIDToLeafMapping_);
02336   SUNDANCE_MSG3(verb() , "HNMesh3D::createLeafNumbering , DONE");
02337 }

Site Contact