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
00052
00054 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00055 class AbstractConductivityTensors;
00056
00061 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00062 class AbstractTetrahedralMesh : public AbstractMesh<ELEMENT_DIM, SPACE_DIM>
00063 {
00064 friend class AbstractConductivityTensors<ELEMENT_DIM, SPACE_DIM>;
00065
00066 protected:
00070 bool mMeshIsLinear;
00071
00072 private:
00080 virtual unsigned SolveElementMapping(unsigned index) const = 0;
00081
00089 virtual unsigned SolveBoundaryElementMapping(unsigned index) const = 0;
00090
00092 friend class boost::serialization::access;
00093
00105 template<class Archive>
00106 void save(Archive & archive, const unsigned int version) const
00107 {
00108 archive & boost::serialization::base_object<AbstractMesh<ELEMENT_DIM,SPACE_DIM> >(*this);
00109 archive & mMeshIsLinear;
00110
00111 TrianglesMeshWriter<ELEMENT_DIM,SPACE_DIM> mesh_writer(ArchiveLocationInfo::GetArchiveRelativePath(),
00112 ArchiveLocationInfo::GetMeshFilename(),
00113 false);
00114
00115 mesh_writer.SetWriteFilesAsBinary();
00116
00117
00118 bool permutation_available = (this->rGetNodePermutation().size() != 0);
00119 archive & permutation_available;
00120
00121 if (permutation_available)
00122 {
00123 const std::vector<unsigned>& rPermutation = this->rGetNodePermutation();
00124 archive & rPermutation;
00125 }
00126
00127 if (!this->IsMeshOnDisk())
00128 {
00129 mesh_writer.WriteFilesUsingMesh(*(const_cast<AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>*>(this)));
00130 }
00131 else
00132 {
00133 unsigned order_of_element = (mMeshIsLinear?1:2);
00134 unsigned& order_of_boundary_element = order_of_element;
00135
00136
00137 std::string original_file=this->GetMeshFileBaseName();
00138 std::auto_ptr<AbstractMeshReader<ELEMENT_DIM, SPACE_DIM> > p_original_mesh_reader
00139 = GenericMeshReader<ELEMENT_DIM, SPACE_DIM>(original_file, order_of_element, order_of_boundary_element);
00140
00141 if (p_original_mesh_reader->IsFileFormatBinary())
00142 {
00143
00144 std::stringstream cp_command;
00145 cp_command << "for filename in `ls " << this->GetMeshFileBaseName() << ".*`; do " <<
00146 "extension=${filename##*.};" <<
00147 "cp $filename " << ArchiveLocationInfo::GetArchiveDirectory() << ArchiveLocationInfo::GetMeshFilename() <<".$extension;" <<
00148 "done";
00149
00150 if (PetscTools::AmMaster())
00151 {
00152 ABORT_IF_NON0(system, cp_command.str());
00153 }
00154 }
00155 else
00156 {
00157
00158 mesh_writer.WriteFilesUsingMeshReaderAndMesh(*p_original_mesh_reader,
00159 *(const_cast<AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>*>(this)));
00160 }
00161 }
00162
00163
00164 PetscTools::Barrier("AbstractTetrahedralMesh::save");
00165 }
00166
00173 template<class Archive>
00174 void load(Archive & archive, const unsigned int version)
00175 {
00176 archive & boost::serialization::base_object<AbstractMesh<ELEMENT_DIM,SPACE_DIM> >(*this);
00177 archive & mMeshIsLinear;
00178
00179 bool permutation_available=false;
00180 std::vector<unsigned> permutation;
00181
00182 if (version > 0)
00183 {
00184 archive & permutation_available;
00185
00186 if (permutation_available)
00187 {
00188 archive & permutation;
00189 }
00190 }
00191
00192
00193 DistributedVectorFactory* p_factory = this->mpDistributedVectorFactory;
00194 this->mpDistributedVectorFactory = NULL;
00195
00196
00197 DistributedVectorFactory* p_our_factory = NULL;
00198 if (p_factory)
00199 {
00200 p_our_factory = p_factory->GetOriginalFactory();
00201 }
00202 if (p_our_factory && p_our_factory->GetNumProcs() == p_factory->GetNumProcs())
00203 {
00204
00205 this->SetDistributedVectorFactory(p_our_factory);
00206 }
00207 else
00208 {
00209
00211 p_our_factory = NULL;
00212 }
00213
00214 if (mMeshIsLinear)
00215 {
00216
00217 TrianglesMeshReader<ELEMENT_DIM,SPACE_DIM> mesh_reader(ArchiveLocationInfo::GetArchiveDirectory() + ArchiveLocationInfo::GetMeshFilename());
00218
00219 if (permutation_available)
00220 {
00221 mesh_reader.SetNodePermutation(permutation);
00222 }
00223
00224 this->ConstructFromMeshReader(mesh_reader);
00225 }
00226 else
00227 {
00228
00229 TrianglesMeshReader<ELEMENT_DIM,SPACE_DIM> mesh_reader(ArchiveLocationInfo::GetArchiveDirectory() + ArchiveLocationInfo::GetMeshFilename(), 2, 2);
00230 this->ConstructFromMeshReader(mesh_reader);
00231 }
00232
00233
00234 if (p_factory)
00235 {
00236 if (!this->mpDistributedVectorFactory)
00237 {
00238
00239
00240 this->mpDistributedVectorFactory = p_factory;
00241 }
00242 else
00243 {
00244
00245
00246 p_factory->SetFromFactory(this->mpDistributedVectorFactory);
00247 if (p_our_factory != this->mpDistributedVectorFactory)
00248 {
00249
00250 delete this->mpDistributedVectorFactory;
00251 }
00252 this->mpDistributedVectorFactory = p_factory;
00253 }
00254 }
00255 }
00256 BOOST_SERIALIZATION_SPLIT_MEMBER()
00257
00258 protected:
00259
00261 std::vector<Element<ELEMENT_DIM, SPACE_DIM> *> mElements;
00262
00264 std::vector<BoundaryElement<ELEMENT_DIM-1, SPACE_DIM> *> mBoundaryElements;
00265
00273 void SetElementOwnerships();
00274
00275 public:
00276
00278
00280
00282 typedef typename std::vector<BoundaryElement<ELEMENT_DIM-1, SPACE_DIM> *>::const_iterator BoundaryElementIterator;
00283
00285 class ElementIterator;
00286
00292 inline ElementIterator GetElementIteratorBegin(bool skipDeletedElements=true);
00293
00297 inline ElementIterator GetElementIteratorEnd();
00298
00300
00302
00306 AbstractTetrahedralMesh();
00307
00311 virtual ~AbstractTetrahedralMesh();
00312
00313
00317 virtual unsigned GetNumElements() const;
00318
00322 virtual unsigned GetNumLocalElements() const;
00323
00327 virtual unsigned GetNumBoundaryElements() const;
00328
00332 unsigned GetNumAllElements() const;
00333
00337 unsigned GetNumAllBoundaryElements() const;
00338
00344 virtual unsigned GetNumCableElements() const;
00345
00352 Element<ELEMENT_DIM, SPACE_DIM>* GetElement(unsigned index) const;
00353
00360 BoundaryElement<ELEMENT_DIM-1, SPACE_DIM>* GetBoundaryElement(unsigned index) const;
00361
00362
00369 virtual void ConstructFromMeshReader(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader)=0;
00370
00379 void ConstructFromMesh(AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>& rOtherMesh);
00380
00381
00385 BoundaryElementIterator GetBoundaryElementIteratorBegin() const;
00386
00391 BoundaryElementIterator GetBoundaryElementIteratorEnd() const;
00392
00401 virtual void GetInverseJacobianForElement(unsigned elementIndex, c_matrix<double, SPACE_DIM, ELEMENT_DIM>& rJacobian,
00402 double& rJacobianDeterminant,
00403 c_matrix<double, ELEMENT_DIM, SPACE_DIM>& rInverseJacobian) const;
00404
00413 virtual void GetWeightedDirectionForBoundaryElement(unsigned elementIndex,
00414 c_vector<double, SPACE_DIM>& rWeightedDirection,
00415 double& rJacobianDeterminant) const;
00416
00424 void CheckOutwardNormals();
00425
00438 virtual void ConstructLinearMesh(unsigned width);
00439
00440
00441
00457 virtual void ConstructRectangularMesh(unsigned width, unsigned height, bool stagger=true);
00458
00459
00460
00472 virtual void ConstructCuboid(unsigned width, unsigned height, unsigned depth);
00473
00474
00475
00486 void ConstructRegularSlabMesh(double spaceStep, double width, double height=0, double depth=0);
00487
00488
00489
00496 virtual bool CalculateDesignatedOwnershipOfBoundaryElement( unsigned faceIndex );
00497
00504 virtual bool CalculateDesignatedOwnershipOfElement( unsigned elementIndex );
00505
00513 unsigned CalculateMaximumNodeConnectivityPerProcess() const;
00514
00521 virtual void GetHaloNodeIndices(std::vector<unsigned>& rHaloIndices) const;
00522
00536 void CalculateNodeExchange( std::vector<std::vector<unsigned> >& rNodesToSendPerProcess,
00537 std::vector<std::vector<unsigned> >& rNodesToReceivePerProcess);
00538
00539
00541
00543
00544
00548 class ElementIterator
00549 {
00550 public:
00556 inline Element<ELEMENT_DIM, SPACE_DIM>& operator*();
00557
00561 inline Element<ELEMENT_DIM, SPACE_DIM>* operator->();
00562
00568 inline bool operator!=(const AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator& rOther);
00569
00573 inline ElementIterator& operator++();
00574
00585 ElementIterator(AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00586 typename std::vector<Element<ELEMENT_DIM, SPACE_DIM> *>::iterator elementIter,
00587 bool skipDeletedElements=true);
00588
00589 private:
00591 AbstractTetrahedralMesh& mrMesh;
00592
00594 typename std::vector<Element<ELEMENT_DIM, SPACE_DIM> *>::iterator mElementIter;
00595
00597 bool mSkipDeletedElements;
00598
00602 inline bool IsAtEnd();
00603
00607 inline bool IsAllowedElement();
00608 };
00609
00610 };
00611
00612 TEMPLATED_CLASS_IS_ABSTRACT_2_UNSIGNED(AbstractTetrahedralMesh)
00613
00614 namespace boost {
00615 namespace serialization {
00622 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00623 struct version<AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM> >
00624 {
00626 CHASTE_VERSION_CONTENT(1);
00627 };
00628 }
00629 }
00630
00631
00633
00635
00636 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00637 typename AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorBegin(
00638 bool skipDeletedElements)
00639 {
00640 return ElementIterator(*this, mElements.begin(), skipDeletedElements);
00641 }
00642
00643 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00644 typename AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorEnd()
00645 {
00646 return ElementIterator(*this, mElements.end());
00647 }
00648
00649 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00650 Element<ELEMENT_DIM, SPACE_DIM>& AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::operator*()
00651 {
00652 assert(!IsAtEnd());
00653 return **mElementIter;
00654 }
00655
00656 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00657 Element<ELEMENT_DIM, SPACE_DIM>* AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::operator->()
00658 {
00659 assert(!IsAtEnd());
00660 return *mElementIter;
00661 }
00662
00663 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00664 bool AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::operator!=(const AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator& rOther)
00665 {
00666 return mElementIter != rOther.mElementIter;
00667 }
00668
00669 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00670 typename AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator& AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::operator++()
00671 {
00672 do
00673 {
00674 ++mElementIter;
00675 }
00676 while (!IsAtEnd() && !IsAllowedElement());
00677
00678 return (*this);
00679 }
00680
00681 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00682 AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::ElementIterator(
00683 AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00684 typename std::vector<Element<ELEMENT_DIM, SPACE_DIM> *>::iterator elementIter,
00685 bool skipDeletedElements)
00686 : mrMesh(rMesh),
00687 mElementIter(elementIter),
00688 mSkipDeletedElements(skipDeletedElements)
00689 {
00690 if (mrMesh.mElements.size() == 0)
00691 {
00692
00693 mElementIter = mrMesh.mElements.end();
00694 }
00695 else
00696 {
00697
00698 if (mElementIter == mrMesh.mElements.begin() && !IsAllowedElement())
00699 {
00700 ++(*this);
00701 }
00702 }
00703 }
00704
00705 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00706 bool AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::IsAtEnd()
00707 {
00708 return mElementIter == mrMesh.mElements.end();
00709 }
00710
00711 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00712 bool AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::IsAllowedElement()
00713 {
00714 return !(mSkipDeletedElements && (*this)->IsDeleted());
00715 }
00716
00717
00718 #endif