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 #ifndef ABSTRACTTETRAHEDRALMESH_HPP_
00030 #define ABSTRACTTETRAHEDRALMESH_HPP_
00031
00032 #include "ChasteSerialization.hpp"
00033 #include "ClassIsAbstract.hpp"
00034 #include <boost/serialization/base_object.hpp>
00035
00036 #include <vector>
00037 #include <string>
00038 #include <cassert>
00039
00040 #include "AbstractMesh.hpp"
00041 #include "BoundaryElement.hpp"
00042 #include "Element.hpp"
00043 #include "AbstractMeshReader.hpp"
00044 #include "TrianglesMeshReader.hpp"
00045 #include "TrianglesMeshWriter.hpp"
00046 #include "ArchiveLocationInfo.hpp"
00047
00048 #include <boost/serialization/split_member.hpp>
00049
00053 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00054 class AbstractTetrahedralMesh : public AbstractMesh<ELEMENT_DIM, SPACE_DIM>
00055 {
00056 protected:
00060 bool mMeshIsLinear;
00061
00062 private:
00070 virtual unsigned SolveElementMapping(unsigned index) const = 0;
00071
00079 virtual unsigned SolveBoundaryElementMapping(unsigned index) const = 0;
00080
00082 friend class boost::serialization::access;
00083
00095 template<class Archive>
00096 void save(Archive & archive, const unsigned int version) const
00097 {
00098 archive & boost::serialization::base_object<AbstractMesh<ELEMENT_DIM,SPACE_DIM> >(*this);
00099 archive & mMeshIsLinear;
00100
00101 TrianglesMeshWriter<ELEMENT_DIM,SPACE_DIM> mesh_writer(ArchiveLocationInfo::GetArchiveRelativePath(),
00102 ArchiveLocationInfo::GetMeshFilename(),
00103 false);
00104
00105 mesh_writer.SetWriteFilesAsBinary();
00112 mesh_writer.WriteFilesUsingMesh(*(const_cast<AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>*>(this)));
00113
00114 PetscTools::Barrier("AbstractTetrahedralMesh::save");
00115 }
00116
00123 template<class Archive>
00124 void load(Archive & archive, const unsigned int version)
00125 {
00126 archive & boost::serialization::base_object<AbstractMesh<ELEMENT_DIM,SPACE_DIM> >(*this);
00127 archive & mMeshIsLinear;
00128
00129
00130 DistributedVectorFactory* p_factory = this->mpDistributedVectorFactory;
00131 this->mpDistributedVectorFactory = NULL;
00132
00133 DistributedVectorFactory* p_our_factory = NULL;
00134 if (p_factory)
00135 {
00136 p_our_factory = p_factory->GetOriginalFactory();
00137 }
00138 if (p_our_factory && p_our_factory->GetNumProcs() == p_factory->GetNumProcs())
00139 {
00140
00141 this->SetDistributedVectorFactory(p_our_factory);
00142 }
00143 else
00144 {
00145
00147 p_our_factory = NULL;
00148 }
00149
00150 if (mMeshIsLinear)
00151 {
00152
00153 TrianglesMeshReader<ELEMENT_DIM,SPACE_DIM> mesh_reader(ArchiveLocationInfo::GetArchiveDirectory() + ArchiveLocationInfo::GetMeshFilename());
00154 this->ConstructFromMeshReader(mesh_reader);
00155 }
00156 else
00157 {
00158
00159 TrianglesMeshReader<ELEMENT_DIM,SPACE_DIM> mesh_reader(ArchiveLocationInfo::GetArchiveDirectory() + ArchiveLocationInfo::GetMeshFilename(), 2, 2);
00160 this->ConstructFromMeshReader(mesh_reader);
00161 }
00162
00163
00164 if (p_factory)
00165 {
00166 if (!this->mpDistributedVectorFactory)
00167 {
00168
00169
00170 this->mpDistributedVectorFactory = p_factory;
00171 }
00172 else
00173 {
00174
00175
00176 p_factory->SetFromFactory(this->mpDistributedVectorFactory);
00177 if (p_our_factory != this->mpDistributedVectorFactory)
00178 {
00179
00180 delete this->mpDistributedVectorFactory;
00181 }
00182 this->mpDistributedVectorFactory = p_factory;
00183 }
00184 }
00185 }
00186 BOOST_SERIALIZATION_SPLIT_MEMBER()
00187
00188
00189 protected:
00190
00192 std::vector<Element<ELEMENT_DIM, SPACE_DIM> *> mElements;
00193
00195 std::vector<BoundaryElement<ELEMENT_DIM-1, SPACE_DIM> *> mBoundaryElements;
00196
00197 public:
00198
00200
00202
00204 typedef typename std::vector<BoundaryElement<ELEMENT_DIM-1, SPACE_DIM> *>::const_iterator BoundaryElementIterator;
00205
00207 class ElementIterator;
00208
00214 inline ElementIterator GetElementIteratorBegin(bool skipDeletedElements=true);
00215
00219 inline ElementIterator GetElementIteratorEnd();
00220
00222
00224
00228 AbstractTetrahedralMesh();
00229
00233 virtual ~AbstractTetrahedralMesh();
00234
00235
00239 virtual unsigned GetNumElements() const;
00240
00244 virtual unsigned GetNumBoundaryElements() const;
00245
00249 unsigned GetNumAllElements() const;
00250
00254 unsigned GetNumAllBoundaryElements() const;
00255
00262 Element<ELEMENT_DIM, SPACE_DIM>* GetElement(unsigned index) const;
00263
00270 BoundaryElement<ELEMENT_DIM-1, SPACE_DIM>* GetBoundaryElement(unsigned index) const;
00271
00281 virtual void SetElementOwnerships(unsigned lo, unsigned hi);
00282
00289 virtual void ConstructFromMeshReader(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader)=0;
00290
00294 BoundaryElementIterator GetBoundaryElementIteratorBegin() const;
00295
00300 BoundaryElementIterator GetBoundaryElementIteratorEnd() const;
00301
00310 virtual void GetInverseJacobianForElement(unsigned elementIndex, c_matrix<double, SPACE_DIM, ELEMENT_DIM>& rJacobian,
00311 double& rJacobianDeterminant,
00312 c_matrix<double, ELEMENT_DIM, SPACE_DIM>& rInverseJacobian) const;
00313
00322 virtual void GetWeightedDirectionForBoundaryElement(unsigned elementIndex,
00323 c_vector<double, SPACE_DIM>& rWeightedDirection,
00324 double& rJacobianDeterminant) const;
00325
00326
00327
00336 virtual void ConstructLinearMesh(unsigned width);
00337
00349 virtual void ConstructRectangularMesh(unsigned width, unsigned height, bool stagger=true);
00350
00359 virtual void ConstructCuboid(unsigned width, unsigned height, unsigned depth);
00360
00367 virtual bool CalculateDesignatedOwnershipOfBoundaryElement( unsigned faceIndex );
00368
00375 virtual bool CalculateDesignatedOwnershipOfElement( unsigned elementIndex );
00376
00377
00379
00381
00382
00386 class ElementIterator
00387 {
00388 public:
00394 inline Element<ELEMENT_DIM, SPACE_DIM>& operator*();
00395
00399 inline Element<ELEMENT_DIM, SPACE_DIM>* operator->();
00400
00406 inline bool operator!=(const AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator& rOther);
00407
00411 inline ElementIterator& operator++();
00412
00423 ElementIterator(AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00424 typename std::vector<Element<ELEMENT_DIM, SPACE_DIM> *>::iterator elementIter,
00425 bool skipDeletedElements=true);
00426
00427 private:
00429 AbstractTetrahedralMesh& mrMesh;
00430
00432 typename std::vector<Element<ELEMENT_DIM, SPACE_DIM> *>::iterator mElementIter;
00433
00435 bool mSkipDeletedElements;
00436
00440 inline bool IsAtEnd();
00441
00445 inline bool IsAllowedElement();
00446 };
00447
00448 };
00449
00450 TEMPLATED_CLASS_IS_ABSTRACT_2_UNSIGNED(AbstractTetrahedralMesh);
00451
00453
00455
00456 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00457 typename AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorBegin(
00458 bool skipDeletedElements)
00459 {
00460 return ElementIterator(*this, mElements.begin(), skipDeletedElements);
00461 }
00462
00463 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00464 typename AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorEnd()
00465 {
00466 return ElementIterator(*this, mElements.end());
00467 }
00468
00469 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00470 Element<ELEMENT_DIM, SPACE_DIM>& AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::operator*()
00471 {
00472 assert(!IsAtEnd());
00473 return **mElementIter;
00474 }
00475
00476 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00477 Element<ELEMENT_DIM, SPACE_DIM>* AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::operator->()
00478 {
00479 assert(!IsAtEnd());
00480 return *mElementIter;
00481 }
00482
00483 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00484 bool AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::operator!=(const AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator& rOther)
00485 {
00486 return mElementIter != rOther.mElementIter;
00487 }
00488
00489 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00490 typename AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator& AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::operator++()
00491 {
00492 do
00493 {
00494 ++mElementIter;
00495 }
00496 while (!IsAtEnd() && !IsAllowedElement());
00497
00498 return (*this);
00499 }
00500
00501 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00502 AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::ElementIterator(
00503 AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00504 typename std::vector<Element<ELEMENT_DIM, SPACE_DIM> *>::iterator elementIter,
00505 bool skipDeletedElements)
00506 : mrMesh(rMesh),
00507 mElementIter(elementIter),
00508 mSkipDeletedElements(skipDeletedElements)
00509 {
00510 if (mrMesh.mElements.size() == 0)
00511 {
00512
00513 mElementIter = mrMesh.mElements.end();
00514 }
00515 else
00516 {
00517
00518 if (mElementIter == mrMesh.mElements.begin() && !IsAllowedElement())
00519 {
00520 ++(*this);
00521 }
00522 }
00523 }
00524
00525 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00526 bool AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::IsAtEnd()
00527 {
00528 return mElementIter == mrMesh.mElements.end();
00529 }
00530
00531 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00532 bool AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::IsAllowedElement()
00533 {
00534 return !(mSkipDeletedElements && (*this)->IsDeleted());
00535 }
00536
00537
00538 #endif