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 #include <boost/serialization/split_member.hpp>
00036
00037 #include <vector>
00038 #include <string>
00039 #include <cassert>
00040
00041 #include "AbstractMesh.hpp"
00042 #include "BoundaryElement.hpp"
00043 #include "Element.hpp"
00044 #include "AbstractMeshReader.hpp"
00045 #include "TrianglesMeshReader.hpp"
00046 #include "TrianglesMeshWriter.hpp"
00047 #include "ArchiveLocationInfo.hpp"
00048
00050 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00051 class AbstractConductivityTensors;
00052
00057 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00058 class AbstractTetrahedralMesh : public AbstractMesh<ELEMENT_DIM, SPACE_DIM>
00059 {
00060 friend class AbstractConductivityTensors<ELEMENT_DIM, SPACE_DIM>;
00061
00062 protected:
00066 bool mMeshIsLinear;
00067
00068 private:
00076 virtual unsigned SolveElementMapping(unsigned index) const = 0;
00077
00085 virtual unsigned SolveBoundaryElementMapping(unsigned index) const = 0;
00086
00088 friend class boost::serialization::access;
00089
00101 template<class Archive>
00102 void save(Archive & archive, const unsigned int version) const
00103 {
00104 archive & boost::serialization::base_object<AbstractMesh<ELEMENT_DIM,SPACE_DIM> >(*this);
00105 archive & mMeshIsLinear;
00106
00107 TrianglesMeshWriter<ELEMENT_DIM,SPACE_DIM> mesh_writer(ArchiveLocationInfo::GetArchiveRelativePath(),
00108 ArchiveLocationInfo::GetMeshFilename(),
00109 false);
00110
00111 mesh_writer.SetWriteFilesAsBinary();
00118 mesh_writer.WriteFilesUsingMesh(*(const_cast<AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>*>(this)));
00119
00120 PetscTools::Barrier("AbstractTetrahedralMesh::save");
00121 }
00122
00129 template<class Archive>
00130 void load(Archive & archive, const unsigned int version)
00131 {
00132 archive & boost::serialization::base_object<AbstractMesh<ELEMENT_DIM,SPACE_DIM> >(*this);
00133 archive & mMeshIsLinear;
00134
00135
00136 DistributedVectorFactory* p_factory = this->mpDistributedVectorFactory;
00137 this->mpDistributedVectorFactory = NULL;
00138
00139 DistributedVectorFactory* p_our_factory = NULL;
00140 if (p_factory)
00141 {
00142 p_our_factory = p_factory->GetOriginalFactory();
00143 }
00144 if (p_our_factory && p_our_factory->GetNumProcs() == p_factory->GetNumProcs())
00145 {
00146
00147 this->SetDistributedVectorFactory(p_our_factory);
00148 }
00149 else
00150 {
00151
00153 p_our_factory = NULL;
00154 }
00155
00156 if (mMeshIsLinear)
00157 {
00158
00159 TrianglesMeshReader<ELEMENT_DIM,SPACE_DIM> mesh_reader(ArchiveLocationInfo::GetArchiveDirectory() + ArchiveLocationInfo::GetMeshFilename());
00160 this->ConstructFromMeshReader(mesh_reader);
00161 }
00162 else
00163 {
00164
00165 TrianglesMeshReader<ELEMENT_DIM,SPACE_DIM> mesh_reader(ArchiveLocationInfo::GetArchiveDirectory() + ArchiveLocationInfo::GetMeshFilename(), 2, 2);
00166 this->ConstructFromMeshReader(mesh_reader);
00167 }
00168
00169
00170 if (p_factory)
00171 {
00172 if (!this->mpDistributedVectorFactory)
00173 {
00174
00175
00176 this->mpDistributedVectorFactory = p_factory;
00177 }
00178 else
00179 {
00180
00181
00182 p_factory->SetFromFactory(this->mpDistributedVectorFactory);
00183 if (p_our_factory != this->mpDistributedVectorFactory)
00184 {
00185
00186 delete this->mpDistributedVectorFactory;
00187 }
00188 this->mpDistributedVectorFactory = p_factory;
00189 }
00190 }
00191 }
00192 BOOST_SERIALIZATION_SPLIT_MEMBER()
00193
00194
00195 protected:
00196
00198 std::vector<Element<ELEMENT_DIM, SPACE_DIM> *> mElements;
00199
00201 std::vector<BoundaryElement<ELEMENT_DIM-1, SPACE_DIM> *> mBoundaryElements;
00202
00203 public:
00204
00206
00208
00210 typedef typename std::vector<BoundaryElement<ELEMENT_DIM-1, SPACE_DIM> *>::const_iterator BoundaryElementIterator;
00211
00213 class ElementIterator;
00214
00220 inline ElementIterator GetElementIteratorBegin(bool skipDeletedElements=true);
00221
00225 inline ElementIterator GetElementIteratorEnd();
00226
00228
00230
00234 AbstractTetrahedralMesh();
00235
00239 virtual ~AbstractTetrahedralMesh();
00240
00241
00245 virtual unsigned GetNumElements() const;
00246
00250 virtual unsigned GetNumLocalElements() const;
00251
00255 virtual unsigned GetNumBoundaryElements() const;
00256
00260 unsigned GetNumAllElements() const;
00261
00265 unsigned GetNumAllBoundaryElements() const;
00266
00273 Element<ELEMENT_DIM, SPACE_DIM>* GetElement(unsigned index) const;
00274
00281 BoundaryElement<ELEMENT_DIM-1, SPACE_DIM>* GetBoundaryElement(unsigned index) const;
00282
00292 virtual void SetElementOwnerships(unsigned lo, unsigned hi);
00293
00300 virtual void ConstructFromMeshReader(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader)=0;
00301
00310 void ConstructFromMesh(AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>& rOtherMesh);
00311
00312
00316 BoundaryElementIterator GetBoundaryElementIteratorBegin() const;
00317
00322 BoundaryElementIterator GetBoundaryElementIteratorEnd() const;
00323
00332 virtual void GetInverseJacobianForElement(unsigned elementIndex, c_matrix<double, SPACE_DIM, ELEMENT_DIM>& rJacobian,
00333 double& rJacobianDeterminant,
00334 c_matrix<double, ELEMENT_DIM, SPACE_DIM>& rInverseJacobian) const;
00335
00344 virtual void GetWeightedDirectionForBoundaryElement(unsigned elementIndex,
00345 c_vector<double, SPACE_DIM>& rWeightedDirection,
00346 double& rJacobianDeterminant) const;
00347
00348
00361 virtual void ConstructLinearMesh(unsigned width);
00362
00363
00364
00380 virtual void ConstructRectangularMesh(unsigned width, unsigned height, bool stagger=true);
00381
00382
00383
00395 virtual void ConstructCuboid(unsigned width, unsigned height, unsigned depth);
00396
00397
00398
00409 void ConstructRegularSlabMesh(double spaceStep, double width, double height=0, double depth=0);
00410
00411
00412
00419 virtual bool CalculateDesignatedOwnershipOfBoundaryElement( unsigned faceIndex );
00420
00427 virtual bool CalculateDesignatedOwnershipOfElement( unsigned elementIndex );
00428
00436 unsigned CalculateMaximumNodeConnectivityPerProcess() const;
00437
00444 virtual void GetHaloNodeIndices(std::vector<unsigned>& rHaloIndices) const;
00445
00446
00447
00449
00451
00452
00456 class ElementIterator
00457 {
00458 public:
00464 inline Element<ELEMENT_DIM, SPACE_DIM>& operator*();
00465
00469 inline Element<ELEMENT_DIM, SPACE_DIM>* operator->();
00470
00476 inline bool operator!=(const AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator& rOther);
00477
00481 inline ElementIterator& operator++();
00482
00493 ElementIterator(AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00494 typename std::vector<Element<ELEMENT_DIM, SPACE_DIM> *>::iterator elementIter,
00495 bool skipDeletedElements=true);
00496
00497 private:
00499 AbstractTetrahedralMesh& mrMesh;
00500
00502 typename std::vector<Element<ELEMENT_DIM, SPACE_DIM> *>::iterator mElementIter;
00503
00505 bool mSkipDeletedElements;
00506
00510 inline bool IsAtEnd();
00511
00515 inline bool IsAllowedElement();
00516 };
00517
00518 };
00519
00520 TEMPLATED_CLASS_IS_ABSTRACT_2_UNSIGNED(AbstractTetrahedralMesh)
00521
00522
00523
00525
00526 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00527 typename AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorBegin(
00528 bool skipDeletedElements)
00529 {
00530 return ElementIterator(*this, mElements.begin(), skipDeletedElements);
00531 }
00532
00533 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00534 typename AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorEnd()
00535 {
00536 return ElementIterator(*this, mElements.end());
00537 }
00538
00539 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00540 Element<ELEMENT_DIM, SPACE_DIM>& AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::operator*()
00541 {
00542 assert(!IsAtEnd());
00543 return **mElementIter;
00544 }
00545
00546 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00547 Element<ELEMENT_DIM, SPACE_DIM>* AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::operator->()
00548 {
00549 assert(!IsAtEnd());
00550 return *mElementIter;
00551 }
00552
00553 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00554 bool AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::operator!=(const AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator& rOther)
00555 {
00556 return mElementIter != rOther.mElementIter;
00557 }
00558
00559 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00560 typename AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator& AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::operator++()
00561 {
00562 do
00563 {
00564 ++mElementIter;
00565 }
00566 while (!IsAtEnd() && !IsAllowedElement());
00567
00568 return (*this);
00569 }
00570
00571 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00572 AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::ElementIterator(
00573 AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00574 typename std::vector<Element<ELEMENT_DIM, SPACE_DIM> *>::iterator elementIter,
00575 bool skipDeletedElements)
00576 : mrMesh(rMesh),
00577 mElementIter(elementIter),
00578 mSkipDeletedElements(skipDeletedElements)
00579 {
00580 if (mrMesh.mElements.size() == 0)
00581 {
00582
00583 mElementIter = mrMesh.mElements.end();
00584 }
00585 else
00586 {
00587
00588 if (mElementIter == mrMesh.mElements.begin() && !IsAllowedElement())
00589 {
00590 ++(*this);
00591 }
00592 }
00593 }
00594
00595 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00596 bool AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::IsAtEnd()
00597 {
00598 return mElementIter == mrMesh.mElements.end();
00599 }
00600
00601 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00602 bool AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::IsAllowedElement()
00603 {
00604 return !(mSkipDeletedElements && (*this)->IsDeleted());
00605 }
00606
00607
00608 #endif