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 <boost/serialization/access.hpp>
00033 #include <boost/serialization/is_abstract.hpp>
00034 #include <boost/serialization/base_object.hpp>
00035
00036 #include <vector>
00037 #include <string>
00038 #include <cassert>
00039
00040 #include "AbstractMesh.hpp"
00041 #include "BoundaryElement.hpp"
00042 #include "Element.hpp"
00043 #include "AbstractMeshReader.hpp"
00044 #include "TrianglesMeshReader.hpp"
00045 #include "TrianglesMeshWriter.hpp"
00046 #include "ArchiveLocationInfo.hpp"
00047
00048 #include <boost/serialization/split_member.hpp>
00049
00053 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00054 class AbstractTetrahedralMesh : public AbstractMesh<ELEMENT_DIM, SPACE_DIM>
00055 {
00056 private:
00064 virtual unsigned SolveElementMapping(unsigned index) const = 0;
00065
00073 virtual unsigned SolveBoundaryElementMapping(unsigned index) const = 0;
00074
00076 friend class boost::serialization::access;
00077
00089 template<class Archive>
00090 void save(Archive & archive, const unsigned int version) const
00091 {
00092 archive & boost::serialization::base_object<AbstractMesh<ELEMENT_DIM,SPACE_DIM> >(*this);
00093
00094
00095 TrianglesMeshWriter<ELEMENT_DIM,SPACE_DIM> mesh_writer(ArchiveLocationInfo::GetArchiveRelativePath(),
00096 ArchiveLocationInfo::GetMeshFilename(),
00097 false);
00098 if (this->IsMeshChanging())
00099 {
00100 mesh_writer.WriteFilesUsingMesh(*this);
00101 }
00102 else
00103 {
00104 try
00105 {
00106
00112 TrianglesMeshReader<ELEMENT_DIM,SPACE_DIM> mesh_reader(this->GetMeshFileBaseName());
00113 mesh_writer.WriteFilesUsingMeshReader(mesh_reader, this->rGetNodePermutation());
00114 }
00115 catch(Exception& e)
00116 {
00124 NEVER_REACHED;
00125 }
00126 }
00127 }
00128
00135 template<class Archive>
00136 void load(Archive & archive, const unsigned int version)
00137 {
00138 archive & boost::serialization::base_object<AbstractMesh<ELEMENT_DIM,SPACE_DIM> >(*this);
00139 TrianglesMeshReader<ELEMENT_DIM,SPACE_DIM> mesh_reader(ArchiveLocationInfo::GetArchiveDirectory() + ArchiveLocationInfo::GetMeshFilename());
00140 this->ConstructFromMeshReader(mesh_reader);
00141 }
00142 BOOST_SERIALIZATION_SPLIT_MEMBER()
00143
00144
00145 protected:
00146
00148 std::vector<Element<ELEMENT_DIM, SPACE_DIM> *> mElements;
00149
00151 std::vector<BoundaryElement<ELEMENT_DIM-1, SPACE_DIM> *> mBoundaryElements;
00152
00153 public:
00154
00156
00158
00160 typedef typename std::vector<BoundaryElement<ELEMENT_DIM-1, SPACE_DIM> *>::const_iterator BoundaryElementIterator;
00161
00163 class ElementIterator;
00164
00170 inline ElementIterator GetElementIteratorBegin(bool skipDeletedElements=true);
00171
00175 inline ElementIterator GetElementIteratorEnd();
00176
00178
00180
00184 AbstractTetrahedralMesh();
00185
00189 virtual ~AbstractTetrahedralMesh();
00190
00191
00195 virtual unsigned GetNumElements() const;
00196
00200 virtual unsigned GetNumBoundaryElements() const;
00201
00205 unsigned GetNumAllElements() const;
00206
00210 unsigned GetNumAllBoundaryElements() const;
00211
00218 Element<ELEMENT_DIM, SPACE_DIM>* GetElement(unsigned index) const;
00219
00226 BoundaryElement<ELEMENT_DIM-1, SPACE_DIM>* GetBoundaryElement(unsigned index) const;
00227
00237 virtual void SetElementOwnerships(unsigned lo, unsigned hi);
00238
00246 virtual void ConstructFromMeshReader(AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>& rMeshReader,
00247 bool cullInternalFaces=false)=0;
00248
00252 BoundaryElementIterator GetBoundaryElementIteratorBegin() const;
00253
00258 BoundaryElementIterator GetBoundaryElementIteratorEnd() const;
00259
00268 virtual void GetInverseJacobianForElement(unsigned elementIndex, c_matrix<double, SPACE_DIM, ELEMENT_DIM>& rJacobian,
00269 double& rJacobianDeterminant,
00270 c_matrix<double, ELEMENT_DIM, SPACE_DIM>& rInverseJacobian) const;
00271
00281 virtual void GetWeightedDirectionForBoundaryElement(unsigned elementIndex,
00282 c_vector<double, SPACE_DIM>& rWeightedDirection,
00283 double& rJacobianDeterminant) const;
00284
00285
00287
00289
00290
00294 class ElementIterator
00295 {
00296 public:
00302 inline Element<ELEMENT_DIM, SPACE_DIM>& operator*();
00303
00307 inline Element<ELEMENT_DIM, SPACE_DIM>* operator->();
00308
00314 inline bool operator!=(const AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator& rOther);
00315
00319 inline ElementIterator& operator++();
00320
00331 ElementIterator(AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00332 typename std::vector<Element<ELEMENT_DIM, SPACE_DIM> *>::iterator elementIter,
00333 bool skipDeletedElements=true);
00334
00335 private:
00337 AbstractTetrahedralMesh& mrMesh;
00338
00340 typename std::vector<Element<ELEMENT_DIM, SPACE_DIM> *>::iterator mElementIter;
00341
00343 bool mSkipDeletedElements;
00344
00348 inline bool IsAtEnd();
00349
00353 inline bool IsAllowedElement();
00354 };
00355
00356 };
00357
00358 namespace boost
00359 {
00360 namespace serialization
00361 {
00367 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00368 struct is_abstract<AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM> >
00369 {
00371 typedef mpl::bool_<true> type;
00373 BOOST_STATIC_CONSTANT(bool, value=true);
00374 };
00375 }
00376 }
00377
00378
00380
00382
00383 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00384 typename AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorBegin(
00385 bool skipDeletedElements)
00386 {
00387 return ElementIterator(*this, mElements.begin(), skipDeletedElements);
00388 }
00389
00390 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00391 typename AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorEnd()
00392 {
00393 return ElementIterator(*this, mElements.end());
00394 }
00395
00396 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00397 Element<ELEMENT_DIM, SPACE_DIM>& AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::operator*()
00398 {
00399 assert(!IsAtEnd());
00400 return **mElementIter;
00401 }
00402
00403 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00404 Element<ELEMENT_DIM, SPACE_DIM>* AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::operator->()
00405 {
00406 assert(!IsAtEnd());
00407 return *mElementIter;
00408 }
00409
00410 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00411 bool AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::operator!=(const AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator& rOther)
00412 {
00413 return mElementIter != rOther.mElementIter;
00414 }
00415
00416 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00417 typename AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator& AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::operator++()
00418 {
00419 do
00420 {
00421 ++mElementIter;
00422 }
00423 while (!IsAtEnd() && !IsAllowedElement());
00424
00425 return (*this);
00426 }
00427
00428 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00429 AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::ElementIterator(
00430 AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00431 typename std::vector<Element<ELEMENT_DIM, SPACE_DIM> *>::iterator elementIter,
00432 bool skipDeletedElements)
00433 : mrMesh(rMesh),
00434 mElementIter(elementIter),
00435 mSkipDeletedElements(skipDeletedElements)
00436 {
00437 if (mrMesh.mElements.size() == 0)
00438 {
00439
00440 mElementIter = mrMesh.mElements.end();
00441 }
00442 else
00443 {
00444
00445 if (mElementIter == mrMesh.mElements.begin() && !IsAllowedElement())
00446 {
00447 ++(*this);
00448 }
00449 }
00450 }
00451
00452 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00453 bool AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::IsAtEnd()
00454 {
00455 return mElementIter == mrMesh.mElements.end();
00456 }
00457
00458 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00459 bool AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator::IsAllowedElement()
00460 {
00461 return !(mSkipDeletedElements && (*this)->IsDeleted());
00462 }
00463
00464
00465 #endif