AbstractMesh.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 #ifndef ABSTRACTMESH_HPP_
00029 #define ABSTRACTMESH_HPP_
00030 
00031 #include "Node.hpp"
00032 #include "BoundaryElement.hpp"
00033 #include "Element.hpp"
00034 #include "AbstractMeshReader.hpp"
00035 
00036 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00037 class AbstractMesh
00038 {
00039 private:
00040     virtual unsigned SolveNodeMapping(unsigned index) const = 0;
00041     virtual unsigned SolveElementMapping(unsigned index) const = 0;        
00042     virtual unsigned SolveBoundaryElementMapping(unsigned index) const = 0; 
00043     
00044 protected:  // Give access of these variables to subclasses
00045     std::vector<Node<SPACE_DIM> *> mNodes;
00046     std::vector<Node<SPACE_DIM> *> mBoundaryNodes;
00047 
00048     std::vector<Element<ELEMENT_DIM, SPACE_DIM> *> mElements;
00049     std::vector<BoundaryElement<ELEMENT_DIM-1, SPACE_DIM> *> mBoundaryElements;
00050     
00051     std::vector<unsigned> mNodesPerProcessor;
00052 
00053     std::vector<unsigned> mNodesPermutation;
00054     
00055     std::string mMeshFileBaseName;
00056 
00057 public:
00058     typedef typename std::vector<Element<ELEMENT_DIM, SPACE_DIM> *>::const_iterator ElementIterator;
00059     typedef typename std::vector<BoundaryElement<ELEMENT_DIM-1, SPACE_DIM> *>::const_iterator BoundaryElementIterator;
00060     typedef typename std::vector<Node<SPACE_DIM> *>::const_iterator BoundaryNodeIterator;
00061 
00062     AbstractMesh();
00063 
00064     virtual ~AbstractMesh();
00065 
00066     virtual unsigned GetNumNodes() const;
00067     virtual unsigned GetNumElements() const;
00068     virtual unsigned GetNumBoundaryElements() const;
00069     unsigned GetNumBoundaryNodes();// should this be overloaded and virtual too?
00070 
00071     unsigned GetNumAllNodes() const;
00072     unsigned GetNumAllElements();
00073     unsigned GetNumAllBoundaryElements();
00074 
00075     Node<SPACE_DIM> *GetNode(unsigned index) const;    
00076     Element<ELEMENT_DIM, SPACE_DIM>* GetElement(unsigned index) const;
00077     BoundaryElement<ELEMENT_DIM-1, SPACE_DIM>* GetBoundaryElement(unsigned index) const;
00078     
00087     virtual void SetElementOwnerships(unsigned lo, unsigned hi);
00088     
00089     virtual void ConstructFromMeshReader(AbstractMeshReader<ELEMENT_DIM,SPACE_DIM> &rMeshReader,
00090                                          bool cullInternalFaces=false)=0;
00091     
00092     virtual void ReadNodesPerProcessorFile(const std::string& nodesPerProcessorFile);
00093 
00094     std::vector<unsigned>& rGetNodesPerProcessor();
00095     
00096     virtual void PermuteNodes();      
00097     
00101     ElementIterator GetElementIteratorBegin() const;
00102 
00107     ElementIterator GetElementIteratorEnd() const;
00108 
00112     BoundaryElementIterator GetBoundaryElementIteratorBegin() const;
00113 
00118     BoundaryElementIterator GetBoundaryElementIteratorEnd() const;
00119 
00123     BoundaryNodeIterator GetBoundaryNodeIteratorBegin() const;
00124 
00129     BoundaryNodeIterator GetBoundaryNodeIteratorEnd() const;
00130 
00131     virtual void GetInverseJacobianForElement(unsigned elementIndex, c_matrix<double, SPACE_DIM, SPACE_DIM>& rJacobian, double &rJacobianDeterminant, c_matrix<double, SPACE_DIM, SPACE_DIM>& rInverseJacobian) const;
00132 
00133     virtual void GetWeightedDirectionForBoundaryElement(unsigned elementIndex, c_vector<double, SPACE_DIM>& rWeightedDirection, double &rJacobianDeterminant) const;
00134     
00135     std::string GetMeshFileBaseName() const;
00136     
00137     std::vector<unsigned>& rGetNodePermutation();
00138 };
00139 
00140 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00141 void AbstractMesh<ELEMENT_DIM, SPACE_DIM>::SetElementOwnerships(unsigned lo, unsigned hi)
00142 {
00143     assert(hi>=lo);
00144     for (unsigned element_index=0; element_index<this->mElements.size(); element_index++)
00145     {
00146         Element<ELEMENT_DIM, SPACE_DIM>* p_element=this->mElements[element_index];
00147         p_element->SetOwnership(false);
00148         for (unsigned local_node_index=0; local_node_index< p_element->GetNumNodes(); local_node_index++)
00149         {
00150             unsigned global_node_index = p_element->GetNodeGlobalIndex(local_node_index);
00151             if (lo<=global_node_index && global_node_index<hi)
00152             {
00153                 p_element->SetOwnership(true);
00154                 break;
00155             }
00156         }
00157 
00158     }
00159 }
00160 
00161 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00162 AbstractMesh<ELEMENT_DIM, SPACE_DIM>::AbstractMesh()
00163 : mMeshFileBaseName("")
00164 {
00165 }
00166 
00167 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00168 AbstractMesh<ELEMENT_DIM, SPACE_DIM>::~AbstractMesh()
00169 {
00170     // Iterate over nodes and free the memory
00171     for (unsigned i=0; i<this->mNodes.size(); i++)
00172     {
00173         delete this->mNodes[i];
00174     }
00175     // Iterate over elements and free the memory
00176     for (unsigned i=0; i<this->mElements.size(); i++)
00177     {
00178         delete this->mElements[i];
00179     }
00180     // Iterate over boundary elements and free the memory
00181     for (unsigned i=0; i<this->mBoundaryElements.size(); i++)
00182     {
00183         delete this->mBoundaryElements[i];
00184     }
00185 }
00186 
00187 
00189 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00190 unsigned AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetNumNodes() const
00191 {
00192     return this->mNodes.size();
00193 }
00194 
00195 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00196 unsigned AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetNumElements() const
00197 {
00198     return this->mElements.size();
00199 }
00200 
00201 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00202 unsigned AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetNumBoundaryNodes()
00203 {
00204     return this->mBoundaryNodes.size();
00205 }
00206 
00207 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00208 unsigned AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetNumAllNodes() const
00209 {
00210     return this->mNodes.size();
00211 }
00212 
00213 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00214 unsigned AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetNumAllElements()
00215 {
00216     return this->mElements.size();
00217 }
00218 
00219 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00220 unsigned AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetNumAllBoundaryElements()
00221 {
00222     return this->mBoundaryElements.size();
00223 }
00224 
00225 
00226 
00227 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00228 unsigned AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetNumBoundaryElements() const
00229 {
00230     return this->mBoundaryElements.size();
00231 }
00232 
00233 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00234 Node<SPACE_DIM>* AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetNode(unsigned index) const
00235 {
00236     unsigned local_index = SolveNodeMapping(index);
00237     return this->mNodes[local_index];
00238 }
00239     
00240 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00241 Element<ELEMENT_DIM, SPACE_DIM>* AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetElement(unsigned index) const
00242 {
00243     unsigned local_index = SolveElementMapping(index);
00244     return this->mElements[local_index];
00245 }
00246 
00247 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00248 BoundaryElement<ELEMENT_DIM-1, SPACE_DIM>* AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetBoundaryElement(unsigned index) const
00249 {
00250     unsigned local_index = SolveBoundaryElementMapping(index);
00251     return this->mBoundaryElements[local_index];
00252 }    
00253 
00254 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00255 void AbstractMesh<ELEMENT_DIM, SPACE_DIM>::ReadNodesPerProcessorFile(const std::string& nodesPerProcessorFile)
00256 {
00257     NEVER_REACHED;
00258 }
00259 
00260 
00261 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00262 std::vector<unsigned>& AbstractMesh<ELEMENT_DIM, SPACE_DIM>::rGetNodesPerProcessor()
00263 {
00264     return mNodesPerProcessor;
00265 }
00266 
00267 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00268 void AbstractMesh<ELEMENT_DIM, SPACE_DIM>::PermuteNodes()
00269 {
00270     NEVER_REACHED;
00271 }
00272 
00273 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00274 typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorBegin() const
00275 {
00276     return mElements.begin();
00277 }
00278 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00279 typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorEnd() const
00280 {
00281     return mElements.end();
00282 }
00283 
00284 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00285 typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::BoundaryElementIterator AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetBoundaryElementIteratorBegin() const
00286 {
00287     return mBoundaryElements.begin();
00288 }
00289 
00290 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00291 typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::BoundaryElementIterator AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetBoundaryElementIteratorEnd() const
00292 {
00293     return mBoundaryElements.end();
00294 }
00295 
00296 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00297 typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::BoundaryNodeIterator AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetBoundaryNodeIteratorBegin() const
00298 {
00299     return mBoundaryNodes.begin();
00300 }
00301 
00302 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00303 typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::BoundaryNodeIterator AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetBoundaryNodeIteratorEnd() const
00304 {
00305     return mBoundaryNodes.end();
00306 }
00307 
00308 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00309 void AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetInverseJacobianForElement(unsigned elementIndex, c_matrix<double, SPACE_DIM, SPACE_DIM>& rJacobian, double &rJacobianDeterminant, c_matrix<double, SPACE_DIM, SPACE_DIM>& rInverseJacobian) const
00310 {
00311     mElements[SolveElementMapping(elementIndex)]->CalculateInverseJacobian(rJacobian, rJacobianDeterminant, rInverseJacobian);
00312 }    
00313 
00314 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00315 void AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetWeightedDirectionForBoundaryElement(unsigned elementIndex, c_vector<double, SPACE_DIM>& rWeightedDirection, double &rJacobianDeterminant) const
00316 {
00317     mBoundaryElements[SolveBoundaryElementMapping(elementIndex)]->CalculateWeightedDirection(rWeightedDirection, rJacobianDeterminant );
00318 }    
00319 
00320 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00321 std::string AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetMeshFileBaseName() const
00322 {
00323     if (mMeshFileBaseName == "")
00324     {
00325         EXCEPTION("This mesh was not constructed from a file.");
00326     }
00327     
00328     return mMeshFileBaseName;
00329 }
00330 
00331 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00332 std::vector<unsigned>& AbstractMesh<ELEMENT_DIM, SPACE_DIM>::rGetNodePermutation()
00333 {
00334     return mNodesPermutation;
00335 }
00336 
00337 #endif /*ABSTRACTMESH_HPP_*/

Generated on Wed Mar 18 12:51:52 2009 for Chaste by  doxygen 1.5.5