Chaste Release::3.1
|
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>;