00001 #include "dealorthomesh.h"
00002 #include "numericmethods.h"
00003
00004
00005 DealOrthoMesh::DealOrthoMesh(Triangulation<3> &tria)
00006 :DealBase(tria)
00007 {
00008
00009
00010 Cell cell = getTriangulation().begin_active();
00011 m_dX = DealBase::getDX(cell);
00012 m_dY = DealBase::getDY(cell);
00013 m_dZ = DealBase::getDZ(cell);
00014 m_Vol = m_dX * m_dY * m_dZ;
00015 m_FacesArea[NORMAL_X] = m_dY*m_dZ;
00016 m_FacesArea[NORMAL_Y] = m_dX*m_dZ;
00017 m_FacesArea[NORMAL_Z] = m_dX*m_dY;
00018 P = cell->vertex(VERTEX_000);
00019
00020
00021 m_FacesAreaFromCellDirection[LEFT_FACE]=m_FacesArea[NORMAL_X];
00022 m_FacesAreaFromCellDirection[RIGHT_FACE]=m_FacesArea[NORMAL_X];
00023 m_FacesAreaFromCellDirection[FRONT_FACE]=m_FacesArea[NORMAL_Y];
00024 m_FacesAreaFromCellDirection[BACK_FACE]=m_FacesArea[NORMAL_Y];
00025 m_FacesAreaFromCellDirection[BOTTOM_FACE]=m_FacesArea[NORMAL_Z];
00026 m_FacesAreaFromCellDirection[UP_FACE]=m_FacesArea[NORMAL_Z];
00027
00028 m_FacesAreaPerVolume[NORMAL_X] = 1.0/m_dX;
00029 m_FacesAreaPerVolume[NORMAL_Y] = 1.0/m_dY;
00030 m_FacesAreaPerVolume[NORMAL_Z] = 1.0/m_dZ;
00031
00032 buildFaceInformation(tria);
00033
00034
00035 Face_It end1 = end();
00036 n_boundary_faces=0;
00037 for(Face_It face = begin();face != end1;face++)
00038 {
00039 if (face->at_boundary())
00040 n_boundary_faces++;
00041 }
00042
00043 int nX=0,nY=0,nZ=0;
00044 for (Cell cell = beginCell();cell.state()==IteratorState::valid;cell=cell->neighbor(RIGHT_CELL))
00045 nX++;
00046 for (Cell cell = beginCell();cell.state()==IteratorState::valid;cell=cell->neighbor(BACK_CELL))
00047 nY++;
00048 for (Cell cell = beginCell();cell.state()==IteratorState::valid;cell=cell->neighbor(UP_CELL))
00049 nZ++;
00050 nElems[0]=nX;
00051 nElems[1]=nY;
00052 nElems[2]=nZ;
00053 Q[0] = P[0] + nElems[0]*getDX();
00054 Q[1] = P[1] + nElems[1]*getDY();
00055 Q[2] = P[2] + nElems[2]*getDZ();
00056
00057
00058
00059
00060 }
00061
00062 DealOrthoMesh::~DealOrthoMesh()
00063 {
00064
00065 }
00066
00067
00068
00075 void DealOrthoMesh::buildFaceInformation(Triangulation<3> &tria)
00076 {
00077 m_faces.clear();
00078 m_faces.resize(tria.n_active_faces());
00079
00080 for (Triangulation<3>::active_cell_iterator cell = tria.begin_active(); cell != tria.end(); cell++)
00081 {
00082 m_faces[cell->face_index(LEFT_FACE )].setNegNormalCell(cell->index());
00083 m_faces[cell->face_index(LEFT_FACE )].setNormalDirection(NORMAL_X);
00084
00085 m_faces[cell->face_index(RIGHT_FACE )].setPosNormalCell(cell->index());
00086 m_faces[cell->face_index(RIGHT_FACE )].setNormalDirection(NORMAL_X);
00087
00088 m_faces[cell->face_index(FRONT_FACE )].setNegNormalCell(cell->index());
00089 m_faces[cell->face_index(FRONT_FACE )].setNormalDirection(NORMAL_Y);
00090
00091 m_faces[cell->face_index(BACK_FACE )].setPosNormalCell(cell->index());
00092 m_faces[cell->face_index(BACK_FACE )].setNormalDirection(NORMAL_Y);
00093
00094 m_faces[cell->face_index(BOTTOM_FACE)].setNegNormalCell(cell->index());
00095 m_faces[cell->face_index(BOTTOM_FACE)].setNormalDirection(NORMAL_Z);
00096
00097 m_faces[cell->face_index(UP_FACE )].setPosNormalCell(cell->index());
00098 m_faces[cell->face_index(UP_FACE )].setNormalDirection(NORMAL_Z);
00099
00100 }
00101
00102 }
00103
00104
00110 double FaceInf::normal_multiply(double *v) const
00111 {
00112 return v[this->m_normal];
00113
00114 }
00115
00116
00122 double DealOrthoMesh::faceArea(const Face_It & face)
00123 {
00124 return m_FacesArea[face->getNormalOrientation()];
00125 }
00126
00127
00132 double DealOrthoMesh::faceAreaPerCellVol(const Face_It &face)
00133 {
00134 return m_FacesAreaPerVolume[face->getNormalOrientation()];
00135 }
00136
00137
00138
00139
00140
00141
00148 double DealOrthoMesh::faceValue( const Face_It & face,const VecDouble & fValues)
00149 {
00150 assert( (unsigned) (face-begin()) < fValues.size());
00151 return fValues(face-begin());
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00168 void DealOrthoMesh::projectCentralValuesAtVertices(const VecDouble &cValues,VecDouble &vValues)
00169 {
00170
00171 assert(vValues.size() == numVertices());
00172 assert(cValues.size() == numCells());
00173
00174
00175
00176 std::vector<unsigned> nCellsPerVertice(numVertices(),0);
00177
00178
00179 vValues=0.0;
00180
00181 Cell endc = endCell();
00182 for (Cell cell = beginCell();cell != endc;cell++)
00183 {
00184 vValues(cell->vertex_index(VERTEX_000)) += cValues(cell->index());
00185 vValues(cell->vertex_index(VERTEX_001)) += cValues(cell->index());
00186 vValues(cell->vertex_index(VERTEX_010)) += cValues(cell->index());
00187 vValues(cell->vertex_index(VERTEX_011)) += cValues(cell->index());
00188 vValues(cell->vertex_index(VERTEX_100)) += cValues(cell->index());
00189 vValues(cell->vertex_index(VERTEX_101)) += cValues(cell->index());
00190 vValues(cell->vertex_index(VERTEX_110)) += cValues(cell->index());
00191 vValues(cell->vertex_index(VERTEX_111)) += cValues(cell->index());
00192
00193 nCellsPerVertice[cell->vertex_index(VERTEX_000)]++;
00194 nCellsPerVertice[cell->vertex_index(VERTEX_001)]++;
00195 nCellsPerVertice[cell->vertex_index(VERTEX_010)]++;
00196 nCellsPerVertice[cell->vertex_index(VERTEX_011)]++;
00197 nCellsPerVertice[cell->vertex_index(VERTEX_100)]++;
00198 nCellsPerVertice[cell->vertex_index(VERTEX_101)]++;
00199 nCellsPerVertice[cell->vertex_index(VERTEX_110)]++;
00200 nCellsPerVertice[cell->vertex_index(VERTEX_111)]++;
00201
00202 }
00203
00204
00205
00206
00207
00208 for (unsigned i =0;i<vValues.size();i++)
00209 vValues(i)/=nCellsPerVertice[i];
00210 }
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 double DealOrthoMesh::getL2NormAtCells(const VecDouble &cValues) const
00225 {
00226 assert(cValues.size() == numCells());
00227 double cellArea = getCellMeasure();
00228 Cell endc = endCell();
00229 double acum=0;
00230 for (Cell cell=beginCell();cell!=endc;cell++)
00231 {
00232 acum+=fabs(getCentralValue(cell,cValues));
00233 }
00234 return acum*cellArea;
00235 }
00236
00237
00238
00239
00240
00241
00242 double DealOrthoMesh::getIntegralAtCells(const VecDouble &cValues) const
00243 {
00244 assert(cValues.size() == numCells());
00245 double acum=0.0;
00246 for (unsigned i=0;i<cValues.size();i++)
00247 {
00248 acum+=cValues(i);
00249 }
00250 return acum*getCellMeasure();
00251 }
00252
00260 void FaceInf::getAdjCells(int &posCell,int &negCell)
00261 {
00262 posCell = getPosCellIndex();
00263 negCell = getNegCellIndex();
00264
00265
00266 if (posCell == -1)
00267 posCell=negCell;
00268 else if (negCell == -1)
00269 negCell=posCell;
00270 }
00271
00286 bool DealOrthoMesh::nonZeroInwardNormalComponenentIsPositive(FaceDirection3D face_no)
00287 {
00288
00289 static bool a[] = {1,0,1,0,1,0};
00290 assert(face_no < 6);
00291 return a[face_no];
00292
00293
00294 }
00295
00300 double DealOrthoMesh::faceArea(FaceDirection3D face_no)
00301 {
00302 return m_FacesAreaFromCellDirection[face_no];
00303
00304 }
00305
00306
00328 void DealOrthoMesh::getFacesInYZSlab(double X,VecIndex &fIndices)
00329 {
00330 Cell cell = beginCell();
00331
00332 double x_tol = getDX()/4.0;
00333 fIndices.reserve(numElems(1)*numElems(2));
00334
00335
00336 Face face = cell->face(LEFT_FACE);
00337 FaceDirection3D faceDir;
00338 if (NumericMethods::a_equal(getBarycenter(face)[0],X,x_tol))
00339 faceDir=LEFT_FACE;
00340 else
00341 {
00342 faceDir = RIGHT_FACE;
00343 face=cell->face(RIGHT_FACE);
00344 while (!NumericMethods::a_equal(getBarycenter(face)[0],X,x_tol))
00345 {
00346 cell = cell->neighbor(RIGHT_CELL);
00347 if (cell.state() != IteratorState::valid)
00348 return;
00349 face = cell->face(RIGHT_FACE);
00350 }
00351 }
00352
00353
00354
00355 for (;cell.state()==IteratorState::valid;cell=cell->neighbor(UP_CELL))
00356 {
00357
00358 for(Cell cellY=cell;cellY.state()==IteratorState::valid;cellY=cellY->neighbor(BACK_CELL))
00359 fIndices.push_back(cellY->face_index(faceDir));
00360 }
00361
00362
00363
00364 }
00365
00366
00367 Point3D DealOrthoMesh::getBarycenter(Face &face)
00368 {
00369 Point3D V = face->vertex(BL_VERTEX);
00370 V+=face->vertex(UR_VERTEX);
00371 V/=2.0;
00372 return V;
00373 }
00374
00375