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
00031
00032
00033
00034
00035
00036 #ifndef ABSTRACTTETRAHEDRALMESH_HPP_
00037 #define ABSTRACTTETRAHEDRALMESH_HPP_
00038
00039 #include "ChasteSerialization.hpp"
00040 #include "ClassIsAbstract.hpp"
00041 #include "ChasteSerializationVersion.hpp"
00042 #include <boost/serialization/vector.hpp>
00043 #include <boost/serialization/base_object.hpp>
00044 #include <boost/serialization/split_member.hpp>
00045
00046 #include <vector>
00047 #include <string>
00048 #include <cassert>
00049 #include <boost/foreach.hpp>
00050
00051 #include "AbstractMesh.hpp"
00052 #include "BoundaryElement.hpp"
00053 #include "Element.hpp"
00054 #include "GenericMeshReader.hpp"
00055 #include "AbstractMeshReader.hpp"
00056 #include "TrianglesMeshReader.hpp"
00057 #include "TrianglesMeshWriter.hpp"
00058 #include "ArchiveLocationInfo.hpp"
00059 #include "FileFinder.hpp"
00060
00061
00063 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00064 class AbstractConductivityTensors;
00065
00070 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00071 class AbstractTetrahedralMesh : public AbstractMesh<ELEMENT_DIM, SPACE_DIM>
00072 {
00073 friend class AbstractConductivityTensors<ELEMENT_DIM, SPACE_DIM>;
00074 friend class CentroidWriter;
00075 protected:
00079 bool mMeshIsLinear;
00080
00081 private:
00091 virtual unsigned SolveElementMapping(unsigned index) const = 0;
00092
00101 virtual unsigned SolveBoundaryElementMapping(unsigned index) const = 0;
00102
00104 friend class boost::serialization::access;
00105
00117 template<class Archive>
00118 void save(Archive & archive, const unsigned int version) const
00119 {
00120 archive & boost::serialization::base_object<AbstractMesh<ELEMENT_DIM,SPACE_DIM> >(*this);
00121 archive & mMeshIsLinear;
00122
00123 TrianglesMeshWriter<ELEMENT_DIM,SPACE_DIM> mesh_writer(ArchiveLocationInfo::GetArchiveRelativePath(),
00124 ArchiveLocationInfo::GetMeshFilename(),
00125 false);
00126
00127 mesh_writer.SetWriteFilesAsBinary();
00128
00129
00130 bool permutation_available = (this->rGetNodePermutation().size() != 0);
00131 archive & permutation_available;
00132
00133 if (permutation_available)
00134 {
00135 const std::vector<unsigned>& rPermutation = this->rGetNodePermutation();
00136 archive & rPermutation;
00137 }
00138
00139 if (!this->IsMeshOnDisk() || this->mMeshChangesDuringSimulation)
00140 {
00141 mesh_writer.WriteFilesUsingMesh(*(const_cast<AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>*>(this)));
00142 }
00143 else
00144 {
00145 unsigned order_of_element = (mMeshIsLinear?1:2);
00146 unsigned& order_of_boundary_element = order_of_element;
00147
00148
00149 std::string original_file=this->GetMeshFileBaseName();
00150 std::auto_ptr<AbstractMeshReader<ELEMENT_DIM, SPACE_DIM> > p_original_mesh_reader
00151 = GenericMeshReader<ELEMENT_DIM, SPACE_DIM>(original_file, order_of_element, order_of_boundary_element);
00152
00153 if (p_original_mesh_reader->IsFileFormatBinary())
00154 {
00155
00156 if (PetscTools::AmMaster())
00157 {
00158 FileFinder mesh_base(this->GetMeshFileBaseName());
00159 FileFinder mesh_folder = mesh_base.GetParent();
00160 std::string mesh_leaf_name = mesh_base.GetLeafNameNoExtension();
00161 std::vector<FileFinder> mesh_files = mesh_folder.FindMatches(mesh_leaf_name + ".*");
00162 FileFinder dest_dir(ArchiveLocationInfo::GetArchiveDirectory());
00163 BOOST_FOREACH(const FileFinder& r_mesh_file, mesh_files)
00164 {
00165 FileFinder dest_file(ArchiveLocationInfo::GetMeshFilename() + r_mesh_file.GetExtension(),
00166 dest_dir);
00167 ABORT_IF_THROWS(r_mesh_file.CopyTo(dest_file));
00168 }
00169 }
00170 }
00171 else
00172 {
00173
00174 mesh_writer.WriteFilesUsingMeshReaderAndMesh(*p_original_mesh_reader,
00175 *(const_cast<AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>*>(this)));
00176 }
00177 }
00178
00179
00180 PetscTools::Barrier("AbstractTetrahedralMesh::save");
00181 }
00182
00189 template<class Archive>
00190 void load(Archive & archive, const unsigned int version)
00191 {
00192 archive & boost::serialization::base_object<AbstractMesh<ELEMENT_DIM,SPACE_DIM> >(*this);
00193 archive & mMeshIsLinear;
00194
00195 bool permutation_available=false;
00196 std::vector<unsigned> permutation;
00197
00198 if (version > 0)
00199 {
00200 archive & permutation_available;
00201
00202 if (permutation_available)
00203 {
00204 archive & permutation;
00205 }
00206 }
00207
00208
00209 DistributedVectorFactory* p_factory = this->mpDistributedVectorFactory;
00210 this->mpDistributedVectorFactory = NULL;
00211
00212
00213 DistributedVectorFactory* p_our_factory = NULL;
00214 if (p_factory)
00215 {
00216 p_our_factory = p_factory->GetOriginalFactory();
00217 }
00218 if (p_our_factory && p_our_factory->GetNumProcs() == p_factory->GetNumProcs())
00219 {
00220
00221 this->SetDistributedVectorFactory(p_our_factory);
00222 }
00223 else
00224 {
00225
00227 p_our_factory = NULL;
00228 }
00229
00230 if (mMeshIsLinear)
00231 {
00232
00233 TrianglesMeshReader<ELEMENT_DIM,SPACE_DIM> mesh_reader(ArchiveLocationInfo::GetArchiveDirectory() + ArchiveLocationInfo::GetMeshFilename());
00234
00235 if (permutation_available)
00236 {
00237 mesh_reader.SetNodePermutation(permutation);
00238 }
00239
00240 this->ConstructFromMeshReader(mesh_reader);
00241 }
00242 else
00243 {
00244
00245 TrianglesMeshReader<ELEMENT_DIM,SPACE_DIM> mesh_reader(ArchiveLocationInfo::GetArchiveDirectory() + ArchiveLocationInfo::GetMeshFilename(), 2, 2);
00246 this->ConstructFromMeshReader(mesh_reader);
00247 }
00248
00249
00250 if (p_factory)
00251 {
00252 if (!this->mpDistributedVectorFactory)
00253 {
00254
00255
00256 this->mpDistributedVectorFactory = p_factory;
00257 }
00258 else
00259 {
00260
00261
00262 p_factory->SetFromFactory(this->mpDistributedVectorFactory);
00263 if (p_our_factory != this->mpDistributedVectorFactory)
00264 {
00265
00266 delete this->mpDistributedVectorFactory;
00267 }
00268 this->mpDistributedVectorFactory = p_factory;
00269 }
00270 }
00271 }
00272 BOOST_SERIALIZATION_SPLIT_MEMBER()
00273
00274 protected:
00275
00277 std::vector<Element<ELEMENT_DIM, SPACE_DIM> *> mElements;
00278
00280 std::vector<BoundaryElement<ELEMENT_DIM-1, SPACE_DIM> *> mBoundaryElements;
00281
00289 void SetElementOwnerships();
00290
00291 public:
00292
00294
00296
00298 typedef typename std::vector<BoundaryElement<ELEMENT_DIM-1, SPACE_DIM> *>::const_iterator BoundaryElementIterator;
00299
00301 class ElementIterator;
00302
00308 inline ElementIterator GetElementIteratorBegin(bool skipDeletedElements=true);
00309
00313 inline ElementIterator GetElementIteratorEnd();
00314
00316
00318
00322 AbstractTetrahedralMesh();
00323
00327 virtual ~AbstractTetrahedralMesh();
00328
00329
00333 virtual unsigned GetNumElements() const;
00334
00338 virtual unsigned GetNumLocalElements() const;
00339
00343 virtual unsigned GetNumBoundaryElements() const;
00344
00348 virtual unsigned GetNumLocalBoundaryElements() const;
00349
00353 unsigned GetNumAllElements() const;
00354
00358 unsigned GetNumAllBoundaryElements() const;
00359
00365 virtual unsigned GetNumCableElements() const;
00366
00371 virtual unsigned GetNumVertices() const;
00372
00379 virtual unsigned GetMaximumNodeIndex();
00380
00387 Element<ELEMENT_DIM, SPACE_DIM>* GetElement(unsigned index) const;
00388
00395 BoundaryElement<ELEMENT_DIM-1, SPACE_DIM>* GetBoundaryElement(unsigned index) const;
00396
00397
00404 virtual void ConstructFromMeshReader(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader)=0;
00405
00414 void ConstructFromMesh(AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>& rOtherMesh);
00415
00416
00420 BoundaryElementIterator GetBoundaryElementIteratorBegin() const;
00421
00426 BoundaryElementIterator GetBoundaryElementIteratorEnd() const;
00427
00436 virtual void GetInverseJacobianForElement(unsigned elementIndex, c_matrix<double, SPACE_DIM, ELEMENT_DIM>& rJacobian,
00437 double& rJacobianDeterminant,
00438 c_matrix<double, ELEMENT_DIM, SPACE_DIM>& rInverseJacobian) const;
00439
00448 virtual void GetWeightedDirectionForBoundaryElement(unsigned elementIndex,
00449 c_vector<double, SPACE_DIM>& rWeightedDirection,
00450 double& rJacobianDeterminant) const;
00451
00459 void CheckOutwardNormals();
00460
00473 virtual void ConstructLinearMesh(unsigned width);
00474
00475
00476
00492 virtual void ConstructRectangularMesh(unsigned width, unsigned height, bool stagger=true);
00493
00494
00495
00507 virtual void ConstructCuboid(unsigned width, unsigned height, unsigned depth);
00508
00509
00510
00521 void ConstructRegularSlabMesh(double spaceStep, double width, double height=0, double depth=0);
00522
00523
00524
00532 virtual bool CalculateDesignatedOwnershipOfBoundaryElement( unsigned faceIndex );
00533
00541 virtual bool CalculateDesignatedOwnershipOfElement( unsigned elementIndex );
00542
00552 unsigned CalculateMaximumNodeConnectivityPerProcess() const;
00553
00560 virtual void GetHaloNodeIndices(std::vector<unsigned>& rHaloIndices) const;
00561
00575 void CalculateNodeExchange( std::vector<std::vector<unsigned> >& rNodesToSendPerProcess,
00576 std::vector<std::vector<unsigned> >& rNodesToReceivePerProcess);
00577
00578
00587 virtual c_vector<double, 2> CalculateMinMaxEdgeLengths();
00588
00602 unsigned GetContainingElementIndex(const ChastePoint<SPACE_DIM>& rTestPoint,
00603 bool strict=false,
00604 std::set<unsigned> testElements=std::set<unsigned>(),
00605 bool onlyTryWithTestElements = false);
00606
00612 unsigned GetNearestElementIndexFromTestElements(const ChastePoint<SPACE_DIM>& rTestPoint,
00613 std::set<unsigned> testElements);
00614
00615
00616
00618
00620
00621
00625 class ElementIterator
00626 {
00627 public:
00633 inline Element<ELEMENT_DIM, SPACE_DIM>& operator*();
00634
00639 inline Element<ELEMENT_DIM, SPACE_DIM>* operator->();
00640
00646 inline bool operator!=(const typename AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator& rOther);
00647
00652 inline ElementIterator& operator++();
00653
00664 ElementIterator(AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00665 typename std::vector<Element<ELEMENT_DIM, SPACE_DIM> *>::iterator elementIter,
00666 bool skipDeletedElements=true);
00667
00668 private:
00670 AbstractTetrahedralMesh& mrMesh;
00671
00673 typename std::vector<Element<ELEMENT_DIM, SPACE_DIM> *>::iterator mElementIter;
00674
00676 bool mSkipDeletedElements;
00677
00682 inline bool IsAtEnd();
00683
00688 inline bool IsAllowedElement();
00689 };
00690
00691 };
00692
00693 TEMPLATED_CLASS_IS_ABSTRACT_2_UNSIGNED(AbstractTetrahedralMesh)
00694
00695 namespace boost {
00696 namespace serialization {
00703 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00704 struct version<AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM> >
00705 {
00707 CHASTE_VERSION_CONTENT(1);
00708 };
00709 }
00710 }
00711
00712
00714
00716
00717 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00718 typename AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorBegin(
00719 bool skipDeletedElements)
00720 {
00721 return ElementIterator(*this, mElements.begin(), skipDeletedElements);
00722 }
00723
00724 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00725 typename AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorEnd()
00726 {
00727 return ElementIterator(*this, mElements.end());
00728 }
00729
00730 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00731 Element<ELEMENT_DIM, SPACE_DIM>& AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::operator*()
00732 {
00733 assert(!IsAtEnd());
00734 return **mElementIter;
00735 }
00736
00737 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00738 Element<ELEMENT_DIM, SPACE_DIM>* AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::operator->()
00739 {
00740 assert(!IsAtEnd());
00741 return *mElementIter;
00742 }
00743
00744 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00745 bool AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::operator!=(const typename AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator& rOther)
00746 {
00747 return mElementIter != rOther.mElementIter;
00748 }
00749
00750 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00751 typename AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator& AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::operator++()
00752 {
00753 do
00754 {
00755 ++mElementIter;
00756 }
00757 while (!IsAtEnd() && !IsAllowedElement());
00758
00759 return (*this);
00760 }
00761
00762 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00763 AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::ElementIterator(
00764 AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00765 typename std::vector<Element<ELEMENT_DIM, SPACE_DIM> *>::iterator elementIter,
00766 bool skipDeletedElements)
00767 : mrMesh(rMesh),
00768 mElementIter(elementIter),
00769 mSkipDeletedElements(skipDeletedElements)
00770 {
00771 if (mrMesh.mElements.size() == 0)
00772 {
00773
00774 mElementIter = mrMesh.mElements.end();
00775 }
00776 else
00777 {
00778
00779 if (mElementIter == mrMesh.mElements.begin() && !IsAllowedElement())
00780 {
00781 ++(*this);
00782 }
00783 }
00784 }
00785
00786 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00787 bool AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::IsAtEnd()
00788 {
00789 return mElementIter == mrMesh.mElements.end();
00790 }
00791
00792 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00793 bool AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::IsAllowedElement()
00794 {
00795 return !(mSkipDeletedElements && (*this)->IsDeleted());
00796 }
00797
00798
00799
00800 #endif