AbstractTetrahedralMesh.hpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2009
00004 
00005 University of Oxford means the Chancellor, Masters and Scholars of the
00006 University of Oxford, having an administrative office at Wellington
00007 Square, Oxford OX1 2JD, UK.
00008 
00009 This file is part of Chaste.
00010 
00011 Chaste is free software: you can redistribute it and/or modify it
00012 under the terms of the GNU Lesser General Public License as published
00013 by the Free Software Foundation, either version 2.1 of the License, or
00014 (at your option) any later version.
00015 
00016 Chaste is distributed in the hope that it will be useful, but WITHOUT
00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00019 License for more details. The offer of Chaste under the terms of the
00020 License is subject to the License being interpreted in accordance with
00021 English Law and subject to any action against the University of Oxford
00022 being under the jurisdiction of the English Courts.
00023 
00024 You should have received a copy of the GNU Lesser General Public License
00025 along with Chaste. If not, see <http://www.gnu.org/licenses/>.
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         // Create a mesh writer pointing to the correct file and directory.
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                 // If this mesh object has been constructed from a mesh reader we can get reference to it
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:  // Give access of these variables to subclasses
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     //                            Iterators                             //
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     //                             Methods                              //
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     //                         Nested classes                           //
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 //      ElementIterator class implementation - most methods are inlined     //
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         // Cope with empty meshes
00440         mElementIter = mrMesh.mElements.end();
00441     }
00442     else
00443     {
00444         // Make sure we start at an allowed element
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 /*ABSTRACTTETRAHEDRALMESH_HPP_*/

Generated on Tue Aug 4 16:10:22 2009 for Chaste by  doxygen 1.5.5