VertexElement.hpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2010
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 VERTEXELEMENT_HPP_
00029 #define VERTEXELEMENT_HPP_
00030 
00031 #include "AbstractElement.hpp"
00032 
00033 #include "ChasteSerialization.hpp"
00034 #include <boost/serialization/base_object.hpp>
00035 #include <boost/serialization/vector.hpp>
00036 
00043 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00044 class VertexElement : public AbstractElement<ELEMENT_DIM, SPACE_DIM>
00045 {
00046 private:
00047 
00051     std::vector<VertexElement<ELEMENT_DIM-1,SPACE_DIM>*> mFaces;
00052 
00063     std::vector<bool> mOrientations;
00064 
00066     friend class boost::serialization::access;
00078     template<class Archive>
00079     void serialize(Archive & archive, const unsigned int version)
00080     {
00081         // This needs to be first so that MeshBasedTissue::Validate() doesn't go mental.
00082         archive & mFaces;
00083         archive & mOrientations;
00084         archive & boost::serialization::base_object<AbstractElement<ELEMENT_DIM,SPACE_DIM> >(*this);
00085     }
00086 
00087 public:
00088 
00096     VertexElement(unsigned index,
00097                   const std::vector<VertexElement<ELEMENT_DIM-1,SPACE_DIM>*>& rFaces,
00098                   const std::vector<bool>& rOrientations);
00099 
00109     VertexElement(unsigned index);
00110 
00117     VertexElement(unsigned index,
00118                   const std::vector<Node<SPACE_DIM>*>& rNodes);
00122     ~VertexElement();
00123 
00127     unsigned GetNumFaces() const;
00128 
00134     void RegisterWithNodes();
00135 
00142     void MarkAsDeleted();
00143 
00149     void ResetIndex(unsigned index);
00150 
00157     void UpdateNode(const unsigned& rIndex, Node<SPACE_DIM>* pNode);
00158 
00164     void DeleteNode(const unsigned& rIndex);
00165 
00172     void AddNode(const unsigned& rIndex, Node<SPACE_DIM>* pNode);
00173 
00179     void AddFace(VertexElement<ELEMENT_DIM-1,SPACE_DIM>* pFace);
00180 
00190     unsigned GetNodeLocalIndex(unsigned globalIndex);
00191 
00197     VertexElement<ELEMENT_DIM-1,SPACE_DIM>* GetFace(unsigned index) const;
00198 
00204     bool FaceIsOrientatedClockwise(unsigned index) const;
00205 
00206 };
00207 
00209 //                  Specialization for 1d elements                  //
00210 //                                                                  //
00211 //                 1d elements are just edges (lines)               //
00213 
00215 
00220 template<unsigned SPACE_DIM>
00221 class VertexElement<1, SPACE_DIM> : public AbstractElement<1,SPACE_DIM>
00222 {
00223 public:
00224 
00231     VertexElement(unsigned index, const std::vector<Node<SPACE_DIM>*>& rNodes);
00232 
00236     virtual ~VertexElement();
00237 
00241     unsigned GetNumFaces() const;
00242 
00249     void UpdateNode(const unsigned& rIndex, Node<SPACE_DIM>* pNode);
00250 
00256     void RegisterWithNodes();
00257 
00264     void MarkAsDeleted();
00265 
00271     void ResetIndex(unsigned index);
00272 
00278     void DeleteNode(const unsigned& rIndex);
00279 
00286     void AddNode(const unsigned& rIndex, Node<SPACE_DIM>* pNode);
00287 
00297     unsigned GetNodeLocalIndex(unsigned globalIndex);
00298 
00304     VertexElement<0,SPACE_DIM>* GetFace(unsigned index) const;
00305 
00311     bool FaceIsOrientatedClockwise(unsigned index) const;
00312 
00313 };
00314 
00315 #include <cassert>
00316 
00317 template<unsigned SPACE_DIM>
00318 VertexElement<1, SPACE_DIM>::VertexElement(unsigned index, const std::vector<Node<SPACE_DIM>*>& rNodes)
00319     : AbstractElement<1, SPACE_DIM>(index, rNodes)
00320 {
00321     // Sanity checking
00322     assert(this->mNodes.size() == 2);
00323     assert(SPACE_DIM > 0);
00324 }
00325 
00326 template<unsigned SPACE_DIM>
00327 VertexElement<1, SPACE_DIM>::~VertexElement()
00328 {
00329 }
00330 
00331 template<unsigned SPACE_DIM>
00332 unsigned VertexElement<1, SPACE_DIM>::GetNumFaces() const
00333 {
00334     return 0;
00335 }
00336 
00337 template<unsigned SPACE_DIM>
00338 void VertexElement<1, SPACE_DIM>::RegisterWithNodes()
00339 {
00340     for (unsigned i=0; i<this->mNodes.size(); i++)
00341     {
00342         this->mNodes[i]->AddElement(this->mIndex);
00343     }
00344 }
00345 
00346 template<unsigned SPACE_DIM>
00347 void VertexElement<1, SPACE_DIM>::MarkAsDeleted()
00348 {
00349     // Mark element as deleted
00350     this->mIsDeleted = true;
00351 
00352     // Update nodes in the element so they know they are not contained by it
00353     for (unsigned i=0; i<this->GetNumNodes(); i++)
00354     {
00355         this->mNodes[i]->RemoveElement(this->mIndex);
00356     }
00357 }
00358 
00359 template <unsigned SPACE_DIM>
00360 void VertexElement<1, SPACE_DIM>::ResetIndex(unsigned index)
00361 {
00362     for (unsigned i=0; i<this->GetNumNodes(); i++)
00363     {
00364        this->mNodes[i]->RemoveElement(this->mIndex);
00365     }
00366     this->mIndex = index;
00367     RegisterWithNodes();
00368 }
00369 
00370 template<unsigned SPACE_DIM>
00371 void VertexElement<1, SPACE_DIM>::UpdateNode(const unsigned& rIndex, Node<SPACE_DIM>* pNode)
00372 {
00373     assert(rIndex < this->mNodes.size());
00374 
00375     // Remove it from the node at this location
00376     this->mNodes[rIndex]->RemoveElement(this->mIndex);
00377 
00378     // Update the node at this location
00379     this->mNodes[rIndex] = pNode;
00380 
00381     // Add element to this node
00382     this->mNodes[rIndex]->AddElement(this->mIndex);
00383 }
00384 
00385 template<unsigned SPACE_DIM>
00386 void VertexElement<1, SPACE_DIM>::DeleteNode(const unsigned& rIndex)
00387 {
00388     assert(rIndex < this->mNodes.size());
00389 
00390     // Remove element from the node at this location
00391     this->mNodes[rIndex]->RemoveElement(this->mIndex);
00392 
00393     // Remove the node at rIndex (removes node from element)
00394     this->mNodes.erase(this->mNodes.begin() + rIndex);
00395 }
00396 
00397 template<unsigned SPACE_DIM>
00398 void VertexElement<1, SPACE_DIM>::AddNode(const unsigned& rIndex, Node<SPACE_DIM>* pNode)
00399 {
00400     assert(rIndex < this->mNodes.size());
00401 
00402     // Add pNode to rIndex+1 element of mNodes pushing the others up
00403     this->mNodes.insert(this->mNodes.begin() + rIndex+1,  pNode);
00404 
00405     // Add element to this node
00406     this->mNodes[rIndex+1]->AddElement(this->mIndex);
00407 }
00408 
00409 template<unsigned SPACE_DIM>
00410 unsigned VertexElement<1, SPACE_DIM>::GetNodeLocalIndex(unsigned globalIndex)
00411 {
00412     unsigned local_index = UINT_MAX;
00413     for (unsigned i=0; i<this->mNodes.size(); i++)
00414     {
00415         if (this->GetNodeGlobalIndex(i) == globalIndex)
00416         {
00417             local_index = i;
00418         }
00419     }
00420     return local_index;
00421 }
00422 
00423 template<unsigned SPACE_DIM>
00424 VertexElement<0, SPACE_DIM>* VertexElement<1, SPACE_DIM>::GetFace(unsigned index) const
00425 {
00426     return NULL;
00427 }
00428 
00429 template<unsigned SPACE_DIM>
00430 bool VertexElement<1, SPACE_DIM>::FaceIsOrientatedClockwise(unsigned index) const
00431 {
00432     return false;
00433 }
00434 
00435 #endif /*VERTEXELEMENT_HPP_*/

Generated by  doxygen 1.6.2