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
00340 virtual unsigned GetNumCableElements() const;
00341
00348 Element<ELEMENT_DIM, SPACE_DIM>* GetElement(unsigned index) const;
00349
00356 BoundaryElement<ELEMENT_DIM-1, SPACE_DIM>* GetBoundaryElement(unsigned index) const;
00357
00358
00365 virtual void ConstructFromMeshReader(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader)=0;
00366
00375 void ConstructFromMesh(AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>& rOtherMesh);
00376
00377
00381 BoundaryElementIterator GetBoundaryElementIteratorBegin() const;
00382
00387 BoundaryElementIterator GetBoundaryElementIteratorEnd() const;
00388
00397 virtual void GetInverseJacobianForElement(unsigned elementIndex, c_matrix<double, SPACE_DIM, ELEMENT_DIM>& rJacobian,
00398 double& rJacobianDeterminant,
00399 c_matrix<double, ELEMENT_DIM, SPACE_DIM>& rInverseJacobian) const;
00400
00409 virtual void GetWeightedDirectionForBoundaryElement(unsigned elementIndex,
00410 c_vector<double, SPACE_DIM>& rWeightedDirection,
00411 double& rJacobianDeterminant) const;
00412
00413
00426 virtual void ConstructLinearMesh(unsigned width);
00427
00428
00429
00445 virtual void ConstructRectangularMesh(unsigned width, unsigned height, bool stagger=true);
00446
00447
00448
00460 virtual void ConstructCuboid(unsigned width, unsigned height, unsigned depth);
00461
00462
00463
00474 void ConstructRegularSlabMesh(double spaceStep, double width, double height=0, double depth=0);
00475
00476
00477
00484 virtual bool CalculateDesignatedOwnershipOfBoundaryElement( unsigned faceIndex );
00485
00492 virtual bool CalculateDesignatedOwnershipOfElement( unsigned elementIndex );
00493
00501 unsigned CalculateMaximumNodeConnectivityPerProcess() const;
00502
00509 virtual void GetHaloNodeIndices(std::vector<unsigned>& rHaloIndices) const;
00510
00524 void CalculateNodeExchange( std::vector<std::vector<unsigned> >& rNodesToSendPerProcess,
00525 std::vector<std::vector<unsigned> >& rNodesToReceivePerProcess);
00526
00527
00529
00531
00532
00536 class ElementIterator
00537 {
00538 public:
00544 inline Element<ELEMENT_DIM, SPACE_DIM>& operator*();
00545
00549 inline Element<ELEMENT_DIM, SPACE_DIM>* operator->();
00550
00556 inline bool operator!=(const AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator& rOther);
00557
00561 inline ElementIterator& operator++();
00562
00573 ElementIterator(AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00574 typename std::vector<Element<ELEMENT_DIM, SPACE_DIM> *>::iterator elementIter,
00575 bool skipDeletedElements=true);
00576
00577 private:
00579 AbstractTetrahedralMesh& mrMesh;
00580
00582 typename std::vector<Element<ELEMENT_DIM, SPACE_DIM> *>::iterator mElementIter;
00583
00585 bool mSkipDeletedElements;
00586
00590 inline bool IsAtEnd();
00591
00595 inline bool IsAllowedElement();
00596 };
00597
00598 };
00599
00600 TEMPLATED_CLASS_IS_ABSTRACT_2_UNSIGNED(AbstractTetrahedralMesh)
00601
00602 namespace boost {
00603 namespace serialization {
00610 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00611 struct version<AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM> >
00612 {
00614 CHASTE_VERSION_CONTENT(1);
00615 };
00616 }
00617 }
00618
00619
00621
00623
00624 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00625 typename AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorBegin(
00626 bool skipDeletedElements)
00627 {
00628 return ElementIterator(*this, mElements.begin(), skipDeletedElements);
00629 }
00630
00631 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00632 typename AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorEnd()
00633 {
00634 return ElementIterator(*this, mElements.end());
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 Element<ELEMENT_DIM, SPACE_DIM>* AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::operator->()
00646 {
00647 assert(!IsAtEnd());
00648 return *mElementIter;
00649 }
00650
00651 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00652 bool AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::operator!=(const AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator& rOther)
00653 {
00654 return mElementIter != rOther.mElementIter;
00655 }
00656
00657 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00658 typename AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator& AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::operator++()
00659 {
00660 do
00661 {
00662 ++mElementIter;
00663 }
00664 while (!IsAtEnd() && !IsAllowedElement());
00665
00666 return (*this);
00667 }
00668
00669 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00670 AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::ElementIterator(
00671 AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00672 typename std::vector<Element<ELEMENT_DIM, SPACE_DIM> *>::iterator elementIter,
00673 bool skipDeletedElements)
00674 : mrMesh(rMesh),
00675 mElementIter(elementIter),
00676 mSkipDeletedElements(skipDeletedElements)
00677 {
00678 if (mrMesh.mElements.size() == 0)
00679 {
00680
00681 mElementIter = mrMesh.mElements.end();
00682 }
00683 else
00684 {
00685
00686 if (mElementIter == mrMesh.mElements.begin() && !IsAllowedElement())
00687 {
00688 ++(*this);
00689 }
00690 }
00691 }
00692
00693 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00694 bool AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::IsAtEnd()
00695 {
00696 return mElementIter == mrMesh.mElements.end();
00697 }
00698
00699 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00700 bool AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::IsAllowedElement()
00701 {
00702 return !(mSkipDeletedElements && (*this)->IsDeleted());
00703 }
00704
00705
00706 #endif