VertexElement.cpp

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 #include "VertexElement.hpp"
00029 #include "RandomNumberGenerator.hpp"
00030 
00031 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00032 VertexElement<ELEMENT_DIM, SPACE_DIM>::VertexElement(unsigned index,
00033                                                      const std::vector<VertexElement<ELEMENT_DIM-1,SPACE_DIM>*>& rFaces,
00034                                                      const std::vector<bool>& rOrientations)
00035     : AbstractElement<ELEMENT_DIM, SPACE_DIM>(index),
00036       mFaces(rFaces),
00037       mOrientations(rOrientations)
00038 {
00039     assert(mFaces.size() == mOrientations.size());
00040 
00041     // Make a set of nodes with mFaces
00042     std::set<Node<SPACE_DIM>* > nodes_set;
00043     for (unsigned face_index=0; face_index<mFaces.size(); face_index++)
00044     {
00045         for (unsigned node_index=0; node_index<mFaces[face_index]->GetNumNodes(); node_index++)
00046         {
00047             nodes_set.insert(mFaces[face_index]->GetNode(node_index));
00048         }
00049     }
00050 
00051     // Populate mNodes
00052     for (typename std::set< Node<SPACE_DIM>* >::iterator node_iter = nodes_set.begin();
00053          node_iter != nodes_set.end();
00054          ++node_iter)
00055     {
00056          this->mNodes.push_back(*node_iter);
00057     }
00058 
00059     // Register element with nodes
00060     RegisterWithNodes();
00061 }
00062 
00063 
00064 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00065 VertexElement<ELEMENT_DIM, SPACE_DIM>::VertexElement(unsigned index)
00066     : AbstractElement<ELEMENT_DIM, SPACE_DIM>(index)
00067 {
00068 }
00069 
00070 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00071 VertexElement<ELEMENT_DIM, SPACE_DIM>::VertexElement(unsigned index,
00072                                                      const std::vector<Node<SPACE_DIM>*>& rNodes)
00073     : AbstractElement<ELEMENT_DIM, SPACE_DIM>(index, rNodes)
00074 {
00075     // \todo this would stop 2d meshes in 3d space (#1304)
00076     if (SPACE_DIM == ELEMENT_DIM)
00077     {
00078         RegisterWithNodes();
00079     }
00080 }
00081 
00082 
00083 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00084 VertexElement<ELEMENT_DIM, SPACE_DIM>::~VertexElement()
00085 {
00086 }
00087 
00088 
00089 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00090 unsigned VertexElement<ELEMENT_DIM, SPACE_DIM>::GetNumFaces() const
00091 {
00092     return mFaces.size();
00093 }
00094 
00095 
00096 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00097 void VertexElement<ELEMENT_DIM, SPACE_DIM>::RegisterWithNodes()
00098 {
00099     for (unsigned i=0; i<this->mNodes.size(); i++)
00100     {
00101         this->mNodes[i]->AddElement(this->mIndex);
00102     }
00103 }
00104 
00105 
00106 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00107 void VertexElement<ELEMENT_DIM, SPACE_DIM>::MarkAsDeleted()
00108 {
00109     // Mark element as deleted
00110     this->mIsDeleted = true;
00111 
00112     // Update nodes in the element so they know they are not contained by it
00113     for (unsigned i=0; i<this->GetNumNodes(); i++)
00114     {
00115         this->mNodes[i]->RemoveElement(this->mIndex);
00116     }
00117 }
00118 
00119 
00120 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00121 void VertexElement<ELEMENT_DIM, SPACE_DIM>::ResetIndex(unsigned index)
00122 {
00123     for (unsigned i=0; i<this->GetNumNodes(); i++)
00124     {
00125        this->mNodes[i]->RemoveElement(this->mIndex);
00126     }
00127     this->mIndex = index;
00128     RegisterWithNodes();
00129 }
00130 
00131 
00132 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00133 void VertexElement<ELEMENT_DIM, SPACE_DIM>::UpdateNode(const unsigned& rIndex, Node<SPACE_DIM>* pNode)
00134 {
00135     assert(rIndex < this->mNodes.size());
00136 
00137     // Remove it from the node at this location
00138     this->mNodes[rIndex]->RemoveElement(this->mIndex);
00139 
00140     // Update the node at this location
00141     this->mNodes[rIndex] = pNode;
00142 
00143     // Add element to this node
00144     this->mNodes[rIndex]->AddElement(this->mIndex);
00145 }
00146 
00147 
00148 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00149 void VertexElement<ELEMENT_DIM, SPACE_DIM>::DeleteNode(const unsigned& rIndex)
00150 {
00151     assert(rIndex < this->mNodes.size());
00152 
00153     // Remove element from the node at this location
00154     this->mNodes[rIndex]->RemoveElement(this->mIndex);
00155 
00156     // Remove the node at rIndex (removes node from element)
00157     this->mNodes.erase(this->mNodes.begin() + rIndex);
00158 }
00159 
00160 
00161 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00162 void VertexElement<ELEMENT_DIM, SPACE_DIM>::AddNode(const unsigned& rIndex, Node<SPACE_DIM>* pNode)
00163 {
00169     if (this->mNodes.size() > 0)
00170     {
00171         assert(rIndex < this->mNodes.size());
00172 
00173         // Add pNode to rIndex+1 element of mNodes pushing the others up
00174         this->mNodes.insert(this->mNodes.begin() + rIndex+1,  pNode);
00175 
00176         // Add element to this node
00177         this->mNodes[rIndex+1]->AddElement(this->mIndex);
00178     }
00179     else
00180     {
00181         // Populate mNodes with pNode
00182         this->mNodes.push_back(pNode);
00183 
00184         // Add element to this node
00185         this->mNodes[0]->AddElement(this->mIndex);
00186     }
00187 }
00188 
00189 
00190 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00191 void VertexElement<ELEMENT_DIM, SPACE_DIM>::AddFace(VertexElement<ELEMENT_DIM-1,SPACE_DIM>* pFace)
00192 {
00193     // Add pFace to the end of mFaces
00194     this->mFaces.push_back(pFace);
00195 
00196     // Create a set of indices of nodes currently owned by this element
00197     std::set<unsigned> node_indices;
00198     for (unsigned local_index=0; local_index<this->GetNumNodes(); local_index++)
00199     {
00200         node_indices.insert(this->GetNodeGlobalIndex(local_index));
00201     }
00202 
00203     // Loop over nodes owned by pFace
00204     unsigned end_index = this->GetNumNodes()-1;
00205     for (unsigned local_index=0; local_index<pFace->GetNumNodes(); local_index++)
00206     {
00207         // If this node is not already owned by this element...
00208         if (std::find(node_indices.begin(), node_indices.end(), pFace->GetNodeGlobalIndex(local_index))
00209             == node_indices.end())
00210         {
00211             // ... then add it to the element (and vice versa)
00212             this->AddNode(end_index, pFace->GetNode(local_index));
00213             end_index++;
00214         }
00215     }
00216 }
00217 
00218 
00219 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00220 unsigned VertexElement<ELEMENT_DIM, SPACE_DIM>::GetNodeLocalIndex(unsigned globalIndex)
00221 {
00222     unsigned local_index= UINT_MAX;
00223     for (unsigned i=0; i<this->mNodes.size(); i++)
00224     {
00225         if (this->GetNodeGlobalIndex(i) == globalIndex)
00226         {
00227             local_index = i;
00228         }
00229     }
00230     return local_index;
00231 }
00232 
00233 
00234 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00235 VertexElement<ELEMENT_DIM-1,  SPACE_DIM>* VertexElement<ELEMENT_DIM, SPACE_DIM>::GetFace(unsigned index) const
00236 {
00237     assert(index < mFaces.size());
00238     return mFaces[index];
00239 }
00240 
00241 
00242 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00243 bool VertexElement<ELEMENT_DIM, SPACE_DIM>::FaceIsOrientatedClockwise(unsigned index) const
00244 {
00245     assert(index < mOrientations.size());
00246     return mOrientations[index];
00247 }
00248 
00249 
00251 // Explicit instantiation
00253 
00254 template class VertexElement<1,1>;
00255 template class VertexElement<1,2>;
00256 template class VertexElement<1,3>;
00257 template class VertexElement<2,2>;
00258 template class VertexElement<2,3>;
00259 template class VertexElement<3,3>;

Generated by  doxygen 1.6.2