00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef _TETRAHEDRALMESH_HPP_
00031 #define _TETRAHEDRALMESH_HPP_
00032
00033 #include <iostream>
00034 #include <vector>
00035 #include <map>
00036 #include <set>
00037 #include <algorithm>
00038
00039 #include <boost/serialization/access.hpp>
00040
00041
00042 #define REAL double
00043 #define VOID void
00044 #include "triangle.h"
00045 #undef REAL
00046
00047 #include "AbstractMesh.hpp"
00048 #include "AbstractMeshReader.hpp"
00049 #include "TrianglesMeshReader.hpp"
00050 #include "Element.hpp"
00051 #include "BoundaryElement.hpp"
00052 #include "Node.hpp"
00053 #include "NodeMap.hpp"
00054 #include "Exception.hpp"
00055 #include "OutputFileHandler.hpp"
00056 #include "RandomNumberGenerator.hpp"
00057 #include "PetscTools.hpp"
00058
00059 #include <boost/serialization/export.hpp>
00060
00062
00064
00065 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00066 class TetrahedralMesh : public AbstractMesh< ELEMENT_DIM, SPACE_DIM>
00067 {
00068 friend class TestTetrahedralMesh;
00069 friend class TestCryptSimulation2d;
00070
00071 private:
00072 friend class boost::serialization::access;
00073 template<class Archive>
00074 void serialize(Archive & archive, const unsigned int version)
00075 {
00076
00077 }
00078
00079
00080
00081 unsigned SolveNodeMapping(unsigned index) const;
00082 unsigned SolveElementMapping(unsigned index) const;
00083 unsigned SolveBoundaryElementMapping(unsigned index) const;
00084
00085 protected:
00086
00087 std::vector< c_vector<double, SPACE_DIM> > mElementWeightedDirections;
00088 std::vector< c_matrix<double, SPACE_DIM, SPACE_DIM> > mElementJacobians;
00089 std::vector< c_matrix<double, SPACE_DIM, SPACE_DIM> > mElementInverseJacobians;
00090 std::vector<double> mElementJacobianDeterminants;
00091
00092 std::vector< c_vector<double, SPACE_DIM> > mBoundaryElementWeightedDirections;
00093 std::vector<double> mBoundaryElementJacobianDeterminants;
00094
00095 public:
00096
00097 TetrahedralMesh();
00098 TetrahedralMesh(unsigned numElements);
00099
00100
00101
00102
00103 void ConstructFromMeshReader(AbstractMeshReader<ELEMENT_DIM,SPACE_DIM> &rMeshReader,
00104 bool cullInternalFaces=false);
00105
00106 void ReadNodesPerProcessorFile(const std::string& nodesPerProcessorFile);
00107
00112 double CalculateVolume();
00113 double CalculateSurfaceArea();
00114
00115 void Translate(c_vector<double, SPACE_DIM> displacement);
00116 void Translate(const double xMovement=0.0, const double yMovement=0.0, const double zMovement=0.0);
00117 void Scale(const double xFactor=1.0, const double yFactor=1.0, const double zFactor=1.0);
00118 void Rotate(c_matrix<double , SPACE_DIM, SPACE_DIM> rotation_matrix);
00119 void Rotate(c_vector<double,3> axis, double angle);
00120 void RotateX(const double theta);
00121 void RotateY(const double theta);
00122 void RotateZ(const double theta);
00124 void Rotate(double theta)
00125 {
00126 RotateZ(theta);
00127 }
00128
00129 void RefreshMesh(void);
00130
00136 void PermuteNodes();
00137
00144 void PermuteNodesWithMetisBinaries(unsigned numProcs);
00145
00151 void PermuteNodes(std::vector<unsigned>& perm);
00152
00153 void ConstructLinearMesh(unsigned width);
00154
00160 void ConstructRectangularMesh(unsigned width, unsigned height, bool stagger=true);
00161
00169 void ConstructCuboid(unsigned width, unsigned height, unsigned depth, bool stagger=false);
00170
00179 unsigned GetContainingElementIndex(ChastePoint<SPACE_DIM> testPoint, bool strict=false, std::set<unsigned> testElements=std::set<unsigned>());
00180
00188 unsigned GetNearestElementIndex(ChastePoint<SPACE_DIM> testPoint);
00189
00194 std::vector<unsigned> GetContainingElementIndices(ChastePoint<SPACE_DIM> testPoint);
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00210 virtual void Clear();
00211
00215 std::set<unsigned> CalculateBoundaryOfFlaggedRegion();
00216
00230 double GetDistanceBetweenNodes(unsigned indexA, unsigned indexB);
00231
00244 virtual c_vector<double, SPACE_DIM> GetVectorFromAtoB(const c_vector<double, SPACE_DIM>& rLocationA, const c_vector<double, SPACE_DIM>& rLocationB);
00245
00250 double GetAngleBetweenNodes(unsigned indexA, unsigned indexB);
00251
00260 virtual double GetWidth(const unsigned& rDimension) const;
00261
00269 c_vector<double,2> GetWidthExtremes(const unsigned& rDimension) const;
00270
00271 void UnflagAllElements();
00272
00273
00277 void FlagElementsNotContainingNodes(std::set<unsigned> nodesList);
00278
00279 void RefreshJacobianCachedData();
00280
00281 virtual void GetJacobianForElement(unsigned elementIndex, c_matrix<double, SPACE_DIM, SPACE_DIM>& rJacobian, double &rJacobianDeterminant) const;
00282 virtual void GetInverseJacobianForElement(unsigned elementIndex, c_matrix<double, SPACE_DIM, SPACE_DIM>& rJacobian, double &rJacobianDeterminant, c_matrix<double, SPACE_DIM, SPACE_DIM>& rInverseJacobian) const;
00283 virtual void GetWeightedDirectionForElement(unsigned elementIndex, c_vector<double, SPACE_DIM>& rWeightedDirection, double &rJacobianDeterminant) const;
00284 virtual void GetWeightedDirectionForBoundaryElement(unsigned elementIndex, c_vector<double, SPACE_DIM>& rWeightedDirection, double &rJacobianDeterminant) const;
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00300 class EdgeIterator
00301 {
00302 public:
00306 Node<SPACE_DIM>* GetNodeA();
00310 Node<SPACE_DIM>* GetNodeB();
00311
00312 bool operator!=(const EdgeIterator& other);
00313
00317 EdgeIterator& operator++();
00318
00322 EdgeIterator(TetrahedralMesh& rMesh, unsigned elemIndex);
00323
00324 private:
00326 std::set<std::set<unsigned> > mEdgesVisited;
00327
00328 TetrahedralMesh& mrMesh;
00329
00330 unsigned mElemIndex;
00331 unsigned mNodeALocalIndex;
00332 unsigned mNodeBLocalIndex;
00333 unsigned mCellIndex;
00334 unsigned mNodeIndex;
00335
00336 };
00337
00341 EdgeIterator EdgesBegin();
00342
00347 EdgeIterator EdgesEnd();
00348 };
00349
00350
00351
00352 #endif //_TETRAHEDRALMESH_HPP_