Chaste Release::3.1
MutableElement.cpp
00001 /*
00002 
00003 Copyright (c) 2005-2012, University of Oxford.
00004 All rights reserved.
00005 
00006 University of Oxford means the Chancellor, Masters and Scholars of the
00007 University of Oxford, having an administrative office at Wellington
00008 Square, Oxford OX1 2JD, UK.
00009 
00010 This file is part of Chaste.
00011 
00012 Redistribution and use in source and binary forms, with or without
00013 modification, are permitted provided that the following conditions are met:
00014  * Redistributions of source code must retain the above copyright notice,
00015    this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright notice,
00017    this list of conditions and the following disclaimer in the documentation
00018    and/or other materials provided with the distribution.
00019  * Neither the name of the University of Oxford nor the names of its
00020    contributors may be used to endorse or promote products derived from this
00021    software without specific prior written permission.
00022 
00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033 
00034 */
00035 #include "MutableElement.hpp"
00036 #include "RandomNumberGenerator.hpp"
00037 #include <cassert>
00038 
00039 
00040 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00041 MutableElement<ELEMENT_DIM, SPACE_DIM>::MutableElement(unsigned index)
00042     : AbstractElement<ELEMENT_DIM, SPACE_DIM>(index)
00043 {
00044 }
00045 
00046 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00047 MutableElement<ELEMENT_DIM, SPACE_DIM>::MutableElement(unsigned index,
00048                                                      const std::vector<Node<SPACE_DIM>*>& rNodes)
00049     : AbstractElement<ELEMENT_DIM, SPACE_DIM>(index, rNodes)
00050 {
00051     if (SPACE_DIM == ELEMENT_DIM)
00052     {
00053         RegisterWithNodes();
00054     }
00055 }
00056 
00057 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00058 MutableElement<ELEMENT_DIM, SPACE_DIM>::~MutableElement()
00059 {
00060 }
00061 
00062 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00063 void MutableElement<ELEMENT_DIM, SPACE_DIM>::RegisterWithNodes()
00064 {
00065     for (unsigned i=0; i<this->mNodes.size(); i++)
00066     {
00067         this->mNodes[i]->AddElement(this->mIndex);
00068     }
00069 }
00070 
00071 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00072 void MutableElement<ELEMENT_DIM, SPACE_DIM>::MarkAsDeleted()
00073 {
00074     // Mark element as deleted
00075     this->mIsDeleted = true;
00076 
00077     // Update nodes in the element so they know they are not contained by it
00078     for (unsigned i=0; i<this->GetNumNodes(); i++)
00079     {
00080         this->mNodes[i]->RemoveElement(this->mIndex);
00081     }
00082 }
00083 
00084 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00085 void MutableElement<ELEMENT_DIM, SPACE_DIM>::ResetIndex(unsigned index)
00086 {
00087     for (unsigned i=0; i<this->GetNumNodes(); i++)
00088     {
00089        this->mNodes[i]->RemoveElement(this->mIndex);
00090     }
00091     this->mIndex = index;
00092     RegisterWithNodes();
00093 }
00094 
00095 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00096 void MutableElement<ELEMENT_DIM, SPACE_DIM>::UpdateNode(const unsigned& rIndex, Node<SPACE_DIM>* pNode)
00097 {
00098     assert(rIndex < this->mNodes.size());
00099 
00100     // Remove it from the node at this location
00101     this->mNodes[rIndex]->RemoveElement(this->mIndex);
00102 
00103     // Update the node at this location
00104     this->mNodes[rIndex] = pNode;
00105 
00106     // Add element to this node
00107     this->mNodes[rIndex]->AddElement(this->mIndex);
00108 }
00109 
00110 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00111 void MutableElement<ELEMENT_DIM, SPACE_DIM>::DeleteNode(const unsigned& rIndex)
00112 {
00113     assert(rIndex < this->mNodes.size());
00114 
00115     // Remove element from the node at this location
00116     this->mNodes[rIndex]->RemoveElement(this->mIndex);
00117 
00118     // Remove the node at rIndex (removes node from element)
00119     this->mNodes.erase(this->mNodes.begin() + rIndex);
00120 }
00121 
00122 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00123 void MutableElement<ELEMENT_DIM, SPACE_DIM>::AddNode(Node<SPACE_DIM>* pNode, const unsigned& rIndex)
00124 {
00130     if (this->mNodes.empty())
00131     {
00132         // Populate mNodes with pNode
00133         this->mNodes.push_back(pNode);
00134 
00135         // Add element to this node
00136         this->mNodes[0]->AddElement(this->mIndex);
00137     }
00138     else
00139     {
00140         assert(rIndex < this->mNodes.size());
00141 
00142         // Add pNode to rIndex+1 element of mNodes pushing the others up
00143         this->mNodes.insert(this->mNodes.begin() + rIndex+1,  pNode);
00144 
00145         // Add element to this node
00146         this->mNodes[rIndex+1]->AddElement(this->mIndex);
00147     }
00148 }
00149 
00150 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00151 unsigned MutableElement<ELEMENT_DIM, SPACE_DIM>::GetNodeLocalIndex(unsigned globalIndex) const
00152 {
00153     unsigned local_index = UINT_MAX;
00154     for (unsigned i=0; i<this->mNodes.size(); i++)
00155     {
00156         if (this->GetNodeGlobalIndex(i) == globalIndex)
00157         {
00158             local_index = i;
00159         }
00160     }
00161     return local_index;
00162 }
00163 
00164 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00165 bool MutableElement<ELEMENT_DIM, SPACE_DIM>::IsElementOnBoundary() const
00166 {
00167     bool is_element_on_boundary = false;
00168     for (unsigned i=0; i<this->mNodes.size(); i++)
00169     {
00170         if (this->GetNode(i)->IsBoundaryNode())
00171         {
00172             is_element_on_boundary = true;
00173             break;
00174         }
00175     }
00176     return is_element_on_boundary;
00177 }
00178 
00180 //                  Specialization for 1d elements                  //
00181 //                                                                  //
00182 //                 1d elements are just edges (lines)               //
00184 
00189 template<unsigned SPACE_DIM>
00190 MutableElement<1, SPACE_DIM>::MutableElement(unsigned index, const std::vector<Node<SPACE_DIM>*>& rNodes)
00191     : AbstractElement<1, SPACE_DIM>(index, rNodes)
00192 {
00193     // Sanity checking
00194     assert(this->mNodes.size() == 2);
00195     assert(SPACE_DIM > 0);
00196 }
00197 
00198 template<unsigned SPACE_DIM>
00199 MutableElement<1, SPACE_DIM>::~MutableElement()
00200 {
00201 }
00202 
00203 template<unsigned SPACE_DIM>
00204 void MutableElement<1, SPACE_DIM>::RegisterWithNodes()
00205 {
00206     for (unsigned i=0; i<this->mNodes.size(); i++)
00207     {
00208         this->mNodes[i]->AddElement(this->mIndex);
00209     }
00210 }
00211 
00212 template<unsigned SPACE_DIM>
00213 void MutableElement<1, SPACE_DIM>::MarkAsDeleted()
00214 {
00215     // Mark element as deleted
00216     this->mIsDeleted = true;
00217 
00218     // Update nodes in the element so they know they are not contained by it
00219     for (unsigned i=0; i<this->GetNumNodes(); i++)
00220     {
00221         this->mNodes[i]->RemoveElement(this->mIndex);
00222     }
00223 }
00224 
00225 template <unsigned SPACE_DIM>
00226 void MutableElement<1, SPACE_DIM>::ResetIndex(unsigned index)
00227 {
00228     for (unsigned i=0; i<this->GetNumNodes(); i++)
00229     {
00230        this->mNodes[i]->RemoveElement(this->mIndex);
00231     }
00232     this->mIndex = index;
00233     RegisterWithNodes();
00234 }
00235 
00236 template<unsigned SPACE_DIM>
00237 void MutableElement<1, SPACE_DIM>::UpdateNode(const unsigned& rIndex, Node<SPACE_DIM>* pNode)
00238 {
00239     assert(rIndex < this->mNodes.size());
00240 
00241     // Remove it from the node at this location
00242     this->mNodes[rIndex]->RemoveElement(this->mIndex);
00243 
00244     // Update the node at this location
00245     this->mNodes[rIndex] = pNode;
00246 
00247     // Add element to this node
00248     this->mNodes[rIndex]->AddElement(this->mIndex);
00249 }
00250 
00251 template<unsigned SPACE_DIM>
00252 void MutableElement<1, SPACE_DIM>::DeleteNode(const unsigned& rIndex)
00253 {
00254     assert(rIndex < this->mNodes.size());
00255 
00256     // Remove element from the node at this location
00257     this->mNodes[rIndex]->RemoveElement(this->mIndex);
00258 
00259     // Remove the node at rIndex (removes node from element)
00260     this->mNodes.erase(this->mNodes.begin() + rIndex);
00261 }
00262 
00263 template<unsigned SPACE_DIM>
00264 void MutableElement<1, SPACE_DIM>::AddNode(Node<SPACE_DIM>* pNode, const unsigned& rIndex)
00265 {
00266     assert(rIndex < this->mNodes.size());
00267 
00268     // Add pNode to rIndex+1 element of mNodes pushing the others up
00269     this->mNodes.insert(this->mNodes.begin() + rIndex+1,  pNode);
00270 
00271     // Add element to this node
00272     this->mNodes[rIndex+1]->AddElement(this->mIndex);
00273 }
00274 
00275 template<unsigned SPACE_DIM>
00276 unsigned MutableElement<1, SPACE_DIM>::GetNodeLocalIndex(unsigned globalIndex) const
00277 {
00278     unsigned local_index = UINT_MAX;
00279     for (unsigned i=0; i<this->mNodes.size(); i++)
00280     {
00281         if (this->GetNodeGlobalIndex(i) == globalIndex)
00282         {
00283             local_index = i;
00284         }
00285     }
00286     return local_index;
00287 }
00288 
00289 template<unsigned SPACE_DIM>
00290 bool MutableElement<1, SPACE_DIM>::IsElementOnBoundary() const
00291 {
00292     bool is_element_on_boundary = false;
00293     for (unsigned i=0; i<this->mNodes.size(); i++)
00294     {
00295         if (this->GetNode(i)->IsBoundaryNode())
00296         {
00297             is_element_on_boundary = true;
00298             break;
00299         }
00300     }
00301     return is_element_on_boundary;
00302 }
00303 
00305 // Explicit instantiation
00307 
00308 template class MutableElement<1,1>;
00309 template class MutableElement<1,2>;
00310 template class MutableElement<1,3>;
00311 template class MutableElement<2,2>;
00312 template class MutableElement<2,3>;
00313 template class MutableElement<3,3>;