00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef SPECTRAL_MESH_HPP
00023 #define SPECTRAL_MESH_HPP
00024
00025 #include <Mesh.hpp>
00026
00027 #include <TinyVector.hpp>
00028
00029 #include <CartesianHexahedron.hpp>
00030
00031 #include <SurfaceMeshOfQuadrangles.hpp>
00032 #include <FacesSet.hpp>
00033
00034 #include <Connectivity.hpp>
00035
00036 #include <Structured3DMeshShape.hpp>
00037
00038 #include <Index.hpp>
00039
00040 class MeshOfHexahedra;
00041
00042 class SpectralMesh
00043 : public Mesh
00044 {
00045 public:
00046 typedef CartesianHexahedron CellType;
00047 typedef Quadrangle FaceType;
00048
00053 typedef MeshOfHexahedra Transformed;
00054 typedef SurfaceMeshOfQuadrangles BorderMeshType;
00055
00056 enum {
00057 family = Mesh::volume
00058 };
00059 private:
00061 const TinyVector<3,size_t> __degrees;
00062
00064 const Structured3DMeshShape __verticesShape;
00065
00067 const Array3DShape __cellShape;
00068
00070 Vector<CartesianHexahedron> __cells;
00071
00072 ReferenceCounting<BorderMeshType>
00073 __borderMesh;
00075 ReferenceCounting<FacesSet<FaceType> >
00076 __facesSet;
00078 Connectivity<SpectralMesh> __connectivity;
00084 SpectralMesh(const SpectralMesh&);
00085
00086 public:
00087 std::string typeName() const
00088 {
00089 return "spectral mesh";
00090 }
00091
00092 const TinyVector<3,size_t>& degrees() const
00093 {
00094 return __degrees;
00095 }
00096
00097 size_t degree(const size_t& i) const
00098 {
00099 return __degrees[i];
00100 }
00101
00102 size_t dofNumber(const size_t& i,
00103 const size_t& j,
00104 const size_t& k) const
00105 {
00106 return __cellShape(i, j, k);
00107 }
00108
00113 void buildEdges();
00114
00115 bool hasBorderMesh() const
00116 {
00117 return (__borderMesh != 0);
00118 }
00119
00120 ConstReferenceCounting<BorderMeshType> borderMesh() const
00121 {
00122 return __borderMesh;
00123 }
00124
00125 ConstReferenceCounting<Mesh> borderBaseMesh() const
00126 {
00127 return static_cast<const BorderMeshType*>(__borderMesh);
00128 }
00129
00134 void buildFaces();
00135
00141 inline bool hasFaces() const
00142 {
00143 return __facesSet != 0;
00144 }
00145
00153 const FaceType& face(const size_t& i) const
00154 {
00155 return (*__facesSet)[i];
00156 }
00157
00158 size_t faceNumber(const FaceType& f) const
00159 {
00160 return (*__facesSet).number(f);
00161 }
00162
00164 inline const size_t& numberOfFaces() const
00165 {
00166 return (*__facesSet).numberOfFaces();
00167 }
00168
00170 inline const size_t& numberOfCells() const
00171 {
00172 return __cells.size();
00173 }
00174
00175 size_t cellNumber(const CartesianHexahedron& h) const
00176 {
00177 return __cells.number(h);
00178 }
00179
00180 typedef Mesh::T_iterator<SpectralMesh, CartesianHexahedron> iterator;
00181 typedef Mesh::T_iterator<const SpectralMesh, const CartesianHexahedron> const_iterator;
00182
00183 inline SpectralMesh::const_iterator find(const double& x,
00184 const double& y,
00185 const double& z) const;
00186
00187 inline SpectralMesh::const_iterator find(const TinyVector<3>& X) const
00188 {
00189 return find(X[0],X[1],X[2]);
00190 }
00191
00193 inline Vertex& vertex(const size_t& i,
00194 const size_t& j,
00195 const size_t& k);
00196
00198 inline const Vertex& vertex(const size_t& i,
00199 const size_t& j,
00200 const size_t& k) const;
00201
00203 inline CartesianHexahedron& cell(const size_t& i,
00204 const size_t& j,
00205 const size_t& k);
00206
00208 inline const CartesianHexahedron& cell(const size_t& i,
00209 const size_t& j,
00210 const size_t& k) const;
00211
00213 inline CartesianHexahedron& cell(const size_t& i)
00214 {
00215 return __cells[i];
00216 }
00217
00223 const Connectivity<SpectralMesh>& connectivity() const
00224 {
00225 return __connectivity;
00226 }
00227
00233 Connectivity<SpectralMesh>& connectivity()
00234 {
00235 return __connectivity;
00236 }
00237
00239 inline const CartesianHexahedron& cell(const size_t& i) const
00240 {
00241 return __cells[i];
00242 }
00243
00245 const Structured3DMeshShape& shape()const
00246 {
00247 return __verticesShape;
00248 }
00249
00254 inline Vertex& vertex(const size_t& i)
00255 {
00256 return Mesh::vertex(i);
00257 }
00258
00263 inline const Vertex& vertex(const size_t& i) const
00264 {
00265 return Mesh::vertex(i);
00266 }
00267
00269 inline Vertex& vertex(const Index& I);
00270
00272 inline const Vertex& vertex(const Index& I) const;
00273
00275 inline CartesianHexahedron& cell(const Index& I);
00276
00278 inline const CartesianHexahedron& cell(const Index& I) const;
00279
00283 inline Index cellIndex(const Vertex& V) const;
00284
00288 inline Index cellIndex(const TinyVector<3>& V) const;
00289
00293 inline Index vertexIndex(const Vertex& V) const;
00294
00296 inline bool inside(const real_t& x, const real_t& y, const real_t& z) const
00297 {
00298 return ((x>=__verticesShape.a(0))&&
00299 (x<=__verticesShape.b(0))&&
00300 (y>=__verticesShape.a(1))&&
00301 (y<=__verticesShape.b(1))&&
00302 (z>=__verticesShape.a(2))&&
00303 (z<=__verticesShape.b(2)));
00304 }
00305
00307 inline bool inside(const TinyVector<3>& p) const
00308 {
00309 return this->inside(p[0], p[1], p[2]);
00310 }
00311
00317 SpectralMesh(const Structured3DMeshShape& s3dM,
00318 ReferenceCounting<VerticesCorrespondance> correspondance);
00319
00320 };
00321
00323 inline Vertex& SpectralMesh::vertex(const size_t& i,
00324 const size_t& j,
00325 const size_t& k)
00326 {
00327 return (*__verticesSet)[__verticesShape(i, j, k)];
00328 }
00329
00331 inline const Vertex& SpectralMesh::vertex(const size_t& i,
00332 const size_t& j,
00333 const size_t& k) const
00334 {
00335 return (*__verticesSet)[__verticesShape(i, j, k)];
00336 }
00337
00339 inline CartesianHexahedron& SpectralMesh::cell(const size_t& i,
00340 const size_t& j,
00341 const size_t& k)
00342 {
00343 return (__cells[__cellShape(i, j, k)]);
00344 }
00345
00347 inline const CartesianHexahedron& SpectralMesh::cell(const size_t& i,
00348 const size_t& j,
00349 const size_t& k) const
00350 {
00351 return (__cells[__cellShape(i, j, k)]);
00352 }
00354 inline Vertex& SpectralMesh::vertex(const Index& I)
00355 {
00356 return (*__verticesSet)[__verticesShape(I[0], I[1], I[2])];
00357 }
00358
00360 inline const Vertex& SpectralMesh::vertex(const Index& I) const
00361 {
00362 return (*__verticesSet)[__verticesShape(I[0], I[1], I[2])];
00363 }
00364
00366 inline CartesianHexahedron& SpectralMesh::cell(const Index& I)
00367 {
00368 return (__cells[__cellShape(I[0], I[1], I[2])]);
00369 }
00370
00372 inline const CartesianHexahedron& SpectralMesh::cell(const Index& I) const
00373 {
00374 return (__cells[__cellShape(I[0], I[1], I[2])]);
00375 }
00376
00380 inline Index SpectralMesh::cellIndex(const TinyVector<3>& V) const
00381 {
00382 const real_t& x = V[0];
00383 const real_t& y = V[1];
00384 const real_t& z = V[2];
00385
00386 const real_t& x0 = __verticesShape.a(0);
00387 const real_t& y0 = __verticesShape.a(1);
00388 const real_t& z0 = __verticesShape.a(2);
00389
00390 int i = int(std::floor((x - x0)/__verticesShape.hx()));
00391 int j = int(std::floor((y - y0)/__verticesShape.hy()));
00392 int k = int(std::floor((z - z0)/__verticesShape.hz()));
00393
00394 i = (i<0) ? 0 : i;
00395 j = (j<0) ? 0 : j;
00396 k = (k<0) ? 0 : k;
00397
00398 int nx_1 = __cellShape.nx() - 1;
00399 int ny_1 = __cellShape.ny() - 1;
00400 int nz_1 = __cellShape.nz() - 1;
00401
00402 i = (i>nx_1) ? nx_1 : i;
00403 j = (j>ny_1) ? ny_1 : j;
00404 k = (k>nz_1) ? nz_1 : k;
00405
00406 Index I(i,j,k);
00407
00408 return I;
00409 }
00410
00414 inline Index SpectralMesh::vertexIndex(const Vertex& V) const
00415 {
00416 const real_t& x = V.x();
00417 const real_t& y = V.y();
00418 const real_t& z = V.z();
00419
00420 const real_t& x0 = __verticesShape.a(0);
00421 const real_t& y0 = __verticesShape.a(1);
00422 const real_t& z0 = __verticesShape.a(2);
00423
00424 int i = int((x - x0)/__verticesShape.hx()+0.5);
00425 int j = int((y - y0)/__verticesShape.hy()+0.5);
00426 int k = int((z - z0)/__verticesShape.hz()+0.5);
00427
00428 bool foundCell = true;
00429 if (((i<0)||(i>static_cast<int>(__verticesShape.nx()-1)))
00430 &&((j<0)||(j>static_cast<int>(__verticesShape.ny()-1)))
00431 &&((k<0)||(k>static_cast<int>(__verticesShape.nz()-1)))) {
00432 foundCell = false;
00433 }
00434
00435 Index I(i,j,k);
00436
00437 return I;
00438 }
00439
00440 inline SpectralMesh::const_iterator
00441 SpectralMesh::find(const double& x,
00442 const double& y,
00443 const double& z) const
00444 {
00445 bool foundCell = inside(x,y,z);
00446
00447 if (!foundCell)
00448 return SpectralMesh::const_iterator(*this,
00449 SpectralMesh::const_iterator::End);
00450
00451 const real_t& x0 = __verticesShape.a(0);
00452 const real_t& y0 = __verticesShape.a(1);
00453 const real_t& z0 = __verticesShape.a(2);
00454
00455 int i = int(std::floor((x - x0)/__verticesShape.hx()));
00456 int j = int(std::floor((y - y0)/__verticesShape.hy()));
00457 int k = int(std::floor((z - z0)/__verticesShape.hz()));
00458
00459 {
00460 int nx_1 = __cellShape.nx() - 1;
00461 int ny_1 = __cellShape.ny() - 1;
00462 int nz_1 = __cellShape.nz() - 1;
00463
00464
00465
00466
00467 i = (i>nx_1) ? nx_1 : i;
00468 j = (j>ny_1) ? ny_1 : j;
00469 k = (k>nz_1) ? nz_1 : k;
00470 }
00471
00472 return SpectralMesh::const_iterator(*this,
00473 __cellShape(i, j, k));
00474 }
00475
00476 #endif // SPECTRAL_MESH_HPP