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 "ChasteSerializationVersion.hpp"
00035 #include <boost/serialization/vector.hpp>
00036 #include <boost/serialization/base_object.hpp>
00037 #include <boost/serialization/split_member.hpp>
00038
00039 #include <vector>
00040 #include <string>
00041 #include <cassert>
00042
00043 #include "AbstractMesh.hpp"
00044 #include "BoundaryElement.hpp"
00045 #include "Element.hpp"
00046 #include "AbstractMeshReader.hpp"
00047 #include "TrianglesMeshReader.hpp"
00048 #include "TrianglesMeshWriter.hpp"
00049 #include "ArchiveLocationInfo.hpp"
00050 #include "GenericMeshReader.hpp"
00051
00053 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00054 class AbstractConductivityTensors;
00055
00060 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00061 class AbstractTetrahedralMesh : public AbstractMesh<ELEMENT_DIM, SPACE_DIM>
00062 {
00063 friend class AbstractConductivityTensors<ELEMENT_DIM, SPACE_DIM>;
00064
00065 protected:
00069 bool mMeshIsLinear;
00070
00071 private:
00079 virtual unsigned SolveElementMapping(unsigned index) const = 0;
00080
00088 virtual unsigned SolveBoundaryElementMapping(unsigned index) const = 0;
00089
00091 friend class boost::serialization::access;
00092
00104 template<class Archive>
00105 void save(Archive & archive, const unsigned int version) const
00106 {
00107 archive & boost::serialization::base_object<AbstractMesh<ELEMENT_DIM,SPACE_DIM> >(*this);
00108 archive & mMeshIsLinear;
00109
00110 TrianglesMeshWriter<ELEMENT_DIM,SPACE_DIM> mesh_writer(ArchiveLocationInfo::GetArchiveRelativePath(),
00111 ArchiveLocationInfo::GetMeshFilename(),
00112 false);
00113
00114 mesh_writer.SetWriteFilesAsBinary();
00115
00116
00117 bool permutation_available = (this->rGetNodePermutation().size() != 0);
00118 archive & permutation_available;
00119
00120 if( permutation_available )
00121 {
00122 const std::vector<unsigned>& rPermutation = this->rGetNodePermutation();
00123 archive & rPermutation;
00124 }
00125
00126 if (!this->IsMeshOnDisk())
00127 {
00128 mesh_writer.WriteFilesUsingMesh(*(const_cast<AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>*>(this)));
00129 }
00130 else
00131 {
00132 unsigned order_of_element = (mMeshIsLinear?1:2);
00133 unsigned& order_of_boundary_element = order_of_element;
00134
00135
00136 std::string original_file=this->GetMeshFileBaseName();
00137 GenericMeshReader<ELEMENT_DIM, SPACE_DIM> original_mesh_reader(original_file, order_of_element, order_of_boundary_element);
00138
00139 if (original_mesh_reader.IsFileFormatBinary())
00140 {
00141
00142 std::stringstream cp_command;
00143 cp_command << "for filename in `ls " << this->GetMeshFileBaseName() << ".*`; do " <<
00144 "extension=${filename##*.};" <<
00145 "cp $filename " << ArchiveLocationInfo::GetArchiveDirectory() << ArchiveLocationInfo::GetMeshFilename() <<".$extension;" <<
00146 "done";
00147
00148 if (PetscTools::AmMaster())
00149 {
00150 MPIABORTIFNON0(system, cp_command.str());
00151 }
00152 }
00153 else
00154 {
00155
00156 mesh_writer.WriteFilesUsingMeshReader(original_mesh_reader);
00157 }
00158 }
00159
00160
00161 PetscTools::Barrier("AbstractTetrahedralMesh::save");
00162 }
00163
00170 template<class Archive>
00171 void load(Archive & archive, const unsigned int version)
00172 {
00173 archive & boost::serialization::base_object<AbstractMesh<ELEMENT_DIM,SPACE_DIM> >(*this);
00174 archive & mMeshIsLinear;
00175
00176 bool permutation_available=false;
00177 std::vector<unsigned> permutation;
00178
00179 if(version>0)
00180 {
00181 archive & permutation_available;
00182
00183 if( permutation_available )
00184 {
00185 archive & permutation;
00186 }
00187 }
00188
00189
00190 DistributedVectorFactory* p_factory = this->mpDistributedVectorFactory;
00191 this->mpDistributedVectorFactory = NULL;
00192
00193 DistributedVectorFactory* p_our_factory = NULL;
00194 if (p_factory)
00195 {
00196 p_our_factory = p_factory->GetOriginalFactory();
00197 }
00198 if (p_our_factory && p_our_factory->GetNumProcs() == p_factory->GetNumProcs())
00199 {
00200
00201 this->SetDistributedVectorFactory(p_our_factory);
00202 }
00203 else
00204 {
00205
00207 p_our_factory = NULL;
00208 }
00209
00210 if (mMeshIsLinear)
00211 {
00212
00213 TrianglesMeshReader<ELEMENT_DIM,SPACE_DIM> mesh_reader(ArchiveLocationInfo::GetArchiveDirectory() + ArchiveLocationInfo::GetMeshFilename());
00214
00215 if (permutation_available)
00216 {
00217 mesh_reader.SetNodePermutation(permutation);
00218 }
00219
00220 this->ConstructFromMeshReader(mesh_reader);
00221 }
00222 else
00223 {
00224
00225 TrianglesMeshReader<ELEMENT_DIM,SPACE_DIM> mesh_reader(ArchiveLocationInfo::GetArchiveDirectory() + ArchiveLocationInfo::GetMeshFilename(), 2, 2);
00226 this->ConstructFromMeshReader(mesh_reader);
00227 }
00228
00229
00230 if (p_factory)
00231 {
00232 if (!this->mpDistributedVectorFactory)
00233 {
00234
00235
00236 this->mpDistributedVectorFactory = p_factory;
00237 }
00238 else
00239 {
00240
00241
00242 p_factory->SetFromFactory(this->mpDistributedVectorFactory);
00243 if (p_our_factory != this->mpDistributedVectorFactory)
00244 {
00245
00246 delete this->mpDistributedVectorFactory;
00247 }
00248 this->mpDistributedVectorFactory = p_factory;
00249 }
00250 }
00251 }
00252 BOOST_SERIALIZATION_SPLIT_MEMBER()
00253
00254
00255 protected:
00256
00258 std::vector<Element<ELEMENT_DIM, SPACE_DIM> *> mElements;
00259
00261 std::vector<BoundaryElement<ELEMENT_DIM-1, SPACE_DIM> *> mBoundaryElements;
00262
00270 void SetElementOwnerships();
00271 public:
00272
00274
00276
00278 typedef typename std::vector<BoundaryElement<ELEMENT_DIM-1, SPACE_DIM> *>::const_iterator BoundaryElementIterator;
00279
00281 class ElementIterator;
00282
00288 inline ElementIterator GetElementIteratorBegin(bool skipDeletedElements=true);
00289
00293 inline ElementIterator GetElementIteratorEnd();
00294
00296
00298
00302 AbstractTetrahedralMesh();
00303
00307 virtual ~AbstractTetrahedralMesh();
00308
00309
00313 virtual unsigned GetNumElements() const;
00314
00318 virtual unsigned GetNumLocalElements() const;
00319
00323 virtual unsigned GetNumBoundaryElements() const;
00324
00328 unsigned GetNumAllElements() const;
00329
00333 unsigned GetNumAllBoundaryElements() const;
00334
00341 Element<ELEMENT_DIM, SPACE_DIM>* GetElement(unsigned index) const;
00342
00349 BoundaryElement<ELEMENT_DIM-1, SPACE_DIM>* GetBoundaryElement(unsigned index) const;
00350
00351
00358 virtual void ConstructFromMeshReader(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader)=0;
00359
00368 void ConstructFromMesh(AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>& rOtherMesh);
00369
00370
00374 BoundaryElementIterator GetBoundaryElementIteratorBegin() const;
00375
00380 BoundaryElementIterator GetBoundaryElementIteratorEnd() const;
00381
00390 virtual void GetInverseJacobianForElement(unsigned elementIndex, c_matrix<double, SPACE_DIM, ELEMENT_DIM>& rJacobian,
00391 double& rJacobianDeterminant,
00392 c_matrix<double, ELEMENT_DIM, SPACE_DIM>& rInverseJacobian) const;
00393
00402 virtual void GetWeightedDirectionForBoundaryElement(unsigned elementIndex,
00403 c_vector<double, SPACE_DIM>& rWeightedDirection,
00404 double& rJacobianDeterminant) const;
00405
00406
00419 virtual void ConstructLinearMesh(unsigned width);
00420
00421
00422
00438 virtual void ConstructRectangularMesh(unsigned width, unsigned height, bool stagger=true);
00439
00440
00441
00453 virtual void ConstructCuboid(unsigned width, unsigned height, unsigned depth);
00454
00455
00456
00467 void ConstructRegularSlabMesh(double spaceStep, double width, double height=0, double depth=0);
00468
00469
00470
00477 virtual bool CalculateDesignatedOwnershipOfBoundaryElement( unsigned faceIndex );
00478
00485 virtual bool CalculateDesignatedOwnershipOfElement( unsigned elementIndex );
00486
00494 unsigned CalculateMaximumNodeConnectivityPerProcess() const;
00495
00502 virtual void GetHaloNodeIndices(std::vector<unsigned>& rHaloIndices) const;
00503
00517 void CalculateNodeExchange( std::vector<std::vector<unsigned> >& rNodesToSendPerProcess,
00518 std::vector<std::vector<unsigned> >& rNodesToReceivePerProcess);
00519
00520
00522
00524
00525
00529 class ElementIterator
00530 {
00531 public:
00537 inline Element<ELEMENT_DIM, SPACE_DIM>& operator*();
00538
00542 inline Element<ELEMENT_DIM, SPACE_DIM>* operator->();
00543
00549 inline bool operator!=(const AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator& rOther);
00550
00554 inline ElementIterator& operator++();
00555
00566 ElementIterator(AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00567 typename std::vector<Element<ELEMENT_DIM, SPACE_DIM> *>::iterator elementIter,
00568 bool skipDeletedElements=true);
00569
00570 private:
00572 AbstractTetrahedralMesh& mrMesh;
00573
00575 typename std::vector<Element<ELEMENT_DIM, SPACE_DIM> *>::iterator mElementIter;
00576
00578 bool mSkipDeletedElements;
00579
00583 inline bool IsAtEnd();
00584
00588 inline bool IsAllowedElement();
00589 };
00590
00591 };
00592
00593 TEMPLATED_CLASS_IS_ABSTRACT_2_UNSIGNED(AbstractTetrahedralMesh)
00594
00595 namespace boost {
00596 namespace serialization {
00603 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00604 struct version<AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM> >
00605 {
00607 CHASTE_VERSION_CONTENT(1);
00608 };
00609 }
00610 }
00611
00612
00614
00616
00617 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00618 typename AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorBegin(
00619 bool skipDeletedElements)
00620 {
00621 return ElementIterator(*this, mElements.begin(), skipDeletedElements);
00622 }
00623
00624 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00625 typename AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorEnd()
00626 {
00627 return ElementIterator(*this, mElements.end());
00628 }
00629
00630 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00631 Element<ELEMENT_DIM, SPACE_DIM>& AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::operator*()
00632 {
00633 assert(!IsAtEnd());
00634 return **mElementIter;
00635 }
00636
00637 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00638 Element<ELEMENT_DIM, SPACE_DIM>* AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::operator->()
00639 {
00640 assert(!IsAtEnd());
00641 return *mElementIter;
00642 }
00643
00644 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00645 bool AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::operator!=(const AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator& rOther)
00646 {
00647 return mElementIter != rOther.mElementIter;
00648 }
00649
00650 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00651 typename AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator& AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::operator++()
00652 {
00653 do
00654 {
00655 ++mElementIter;
00656 }
00657 while (!IsAtEnd() && !IsAllowedElement());
00658
00659 return (*this);
00660 }
00661
00662 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00663 AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::ElementIterator(
00664 AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00665 typename std::vector<Element<ELEMENT_DIM, SPACE_DIM> *>::iterator elementIter,
00666 bool skipDeletedElements)
00667 : mrMesh(rMesh),
00668 mElementIter(elementIter),
00669 mSkipDeletedElements(skipDeletedElements)
00670 {
00671 if (mrMesh.mElements.size() == 0)
00672 {
00673
00674 mElementIter = mrMesh.mElements.end();
00675 }
00676 else
00677 {
00678
00679 if (mElementIter == mrMesh.mElements.begin() && !IsAllowedElement())
00680 {
00681 ++(*this);
00682 }
00683 }
00684 }
00685
00686 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00687 bool AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::IsAtEnd()
00688 {
00689 return mElementIter == mrMesh.mElements.end();
00690 }
00691
00692 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00693 bool AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::IsAllowedElement()
00694 {
00695 return !(mSkipDeletedElements && (*this)->IsDeleted());
00696 }
00697
00698
00699 #endif