Node.cpp

00001 /*
00002 
00003 Copyright (c) 2005-2015, 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 
00036 #include <cassert>
00037 
00038 #include "Node.hpp"
00039 #include "Exception.hpp"
00040 
00042 // Constructors
00044 
00045 template<unsigned SPACE_DIM>
00046 void Node<SPACE_DIM>::CommonConstructor(unsigned index, bool isBoundaryNode)
00047 {
00048     mIndex = index;
00049     mIsBoundaryNode = isBoundaryNode;
00050     mIsInternal = false;
00051     mIsDeleted = false;
00052     mpNodeAttributes = NULL;
00053 }
00054 
00055 template<unsigned SPACE_DIM>
00056 Node<SPACE_DIM>::Node(unsigned index, ChastePoint<SPACE_DIM> point, bool isBoundaryNode)
00057 {
00058     mLocation = point.rGetLocation();
00059     CommonConstructor(index, isBoundaryNode);
00060 }
00061 
00062 template<unsigned SPACE_DIM>
00063 Node<SPACE_DIM>::Node(unsigned index, std::vector<double> coords, bool isBoundaryNode)
00064 {
00065     for (unsigned i=0; i<SPACE_DIM; i++)
00066     {
00067         mLocation(i) = coords.at(i);
00068     }
00069     CommonConstructor(index, isBoundaryNode);
00070 }
00071 
00072 template<unsigned SPACE_DIM>
00073 Node<SPACE_DIM>::Node(unsigned index, c_vector<double, SPACE_DIM> location, bool isBoundaryNode)
00074 {
00075     mLocation = location;
00076     CommonConstructor(index, isBoundaryNode);
00077 }
00078 
00079 template<unsigned SPACE_DIM>
00080 Node<SPACE_DIM>::Node(unsigned index, bool isBoundaryNode, double v1, double v2, double v3)
00081 {
00082     mLocation[0] = v1;
00083     if (SPACE_DIM > 1)
00084     {
00085         mLocation[1] = v2;
00086         if (SPACE_DIM > 2)
00087         {
00088             mLocation[2] = v3;
00089         }
00090     }
00091     CommonConstructor(index, isBoundaryNode);
00092 }
00093 
00094 template<unsigned SPACE_DIM>
00095 Node<SPACE_DIM>::Node(unsigned index, double *location, bool isBoundaryNode)
00096 {
00097     for (unsigned i=0; i<SPACE_DIM; i++)
00098     {
00099         mLocation(i) = location[i];
00100     }
00101     CommonConstructor(index, isBoundaryNode);
00102 }
00103 
00104 template<unsigned SPACE_DIM>
00105 Node<SPACE_DIM>::~Node()
00106 {
00107     delete mpNodeAttributes;
00108 }
00109 
00111 // Methods dealing with node location
00113 
00114 template<unsigned SPACE_DIM>
00115 void Node<SPACE_DIM>::SetPoint(ChastePoint<SPACE_DIM> point)
00116 {
00117     mLocation = point.rGetLocation();
00118 }
00119 
00120 template<unsigned SPACE_DIM>
00121 void Node<SPACE_DIM>::SetIndex(unsigned index)
00122 {
00123     mIndex = index;
00124 }
00125 
00126 template<unsigned SPACE_DIM>
00127 void Node<SPACE_DIM>::SetAsBoundaryNode(bool value)
00128 {
00129     mIsBoundaryNode = value;
00130 }
00131 
00132 
00133 template<unsigned SPACE_DIM>
00134 ChastePoint<SPACE_DIM> Node<SPACE_DIM>::GetPoint() const
00135 {
00136     return ChastePoint<SPACE_DIM>(mLocation);
00137 }
00138 
00139 template<unsigned SPACE_DIM>
00140 const c_vector<double, SPACE_DIM>& Node<SPACE_DIM>::rGetLocation() const
00141 {
00142     // This assert statement is a useful warning: when new nodes are created we overwrite previously deleted nodes if there are any.
00143     // This means that we can not use this method to interrogate deleted nodes about their position before deletion because we can't
00144     // guarantee that the node has not been overwritten already. Hence, when implementing new functionality we need to make sure
00145     // that this functionality does not rely on being able to interrogate deleted nodes for their location.
00146     // \todo #2401: make this an exception.
00147     assert(!mIsDeleted);
00148     return mLocation;
00149 }
00150 
00151 template<unsigned SPACE_DIM>
00152 c_vector<double, SPACE_DIM>& Node<SPACE_DIM>::rGetModifiableLocation()
00153 {
00154     assert(!mIsDeleted);
00155     return mLocation;
00156 }
00157 
00158 template<unsigned SPACE_DIM>
00159 unsigned Node<SPACE_DIM>::GetIndex() const
00160 {
00161     return mIndex;
00162 }
00163 
00164 template<unsigned SPACE_DIM>
00165 bool Node<SPACE_DIM>::IsBoundaryNode() const
00166 {
00167     return mIsBoundaryNode;
00168 }
00169 
00170 template<unsigned SPACE_DIM>
00171 void Node<SPACE_DIM>::AddNodeAttribute(double attribute)
00172 {
00173     ConstructNodeAttributes();
00174 
00175     mpNodeAttributes->AddAttribute(attribute);
00176 }
00177 
00178 template<unsigned SPACE_DIM>
00179 std::vector<double>& Node<SPACE_DIM>::rGetNodeAttributes()
00180 {
00181     CheckForNodeAttributes();
00182 
00183     return mpNodeAttributes->rGetAttributes();
00184 }
00185 
00186 template<unsigned SPACE_DIM>
00187 unsigned Node<SPACE_DIM>::GetNumNodeAttributes()
00188 {
00189     unsigned num_attributes;
00190     if (!mpNodeAttributes)
00191     {
00192         num_attributes = 0u;
00193     }
00194     else
00195     {
00196         num_attributes = mpNodeAttributes->rGetAttributes().size();
00197     }
00198 
00199     return num_attributes;
00200 }
00201 
00202 template<unsigned SPACE_DIM>
00203 bool Node<SPACE_DIM>::HasNodeAttributes()
00204 {
00205     return (mpNodeAttributes != NULL);
00206 }
00207 
00208 template<unsigned SPACE_DIM>
00209 c_vector<double, SPACE_DIM>& Node<SPACE_DIM>::rGetAppliedForce()
00210 {
00211     CheckForNodeAttributes();
00212 
00213     return mpNodeAttributes->rGetAppliedForce();
00214 }
00215 
00216 template<unsigned SPACE_DIM>
00217 void Node<SPACE_DIM>::ClearAppliedForce()
00218 {
00219     ConstructNodeAttributes();
00220 
00221     mpNodeAttributes->ClearAppliedForce();
00222 }
00223 
00224 template<unsigned SPACE_DIM>
00225 void Node<SPACE_DIM>::AddAppliedForceContribution(c_vector<double, SPACE_DIM>& forceContribution)
00226 {
00227     ConstructNodeAttributes();
00228 
00229     mpNodeAttributes->AddAppliedForceContribution(forceContribution);
00230 }
00231 
00232 template<unsigned SPACE_DIM>
00233 bool Node<SPACE_DIM>::IsParticle()
00234 {
00235     CheckForNodeAttributes();
00236 
00237     return mpNodeAttributes->IsParticle();
00238 }
00239 
00240 template<unsigned SPACE_DIM>
00241 void Node<SPACE_DIM>::SetIsParticle(bool isParticle)
00242 {
00243     ConstructNodeAttributes();
00244 
00245     mpNodeAttributes->SetIsParticle(isParticle);
00246 }
00247 
00248 template<unsigned SPACE_DIM>
00249 double Node<SPACE_DIM>::GetRadius()
00250 {
00251     CheckForNodeAttributes();
00252 
00253     return mpNodeAttributes->GetRadius();
00254 }
00255 
00256 template<unsigned SPACE_DIM>
00257 void Node<SPACE_DIM>::SetRadius(double radius)
00258 {
00259     ConstructNodeAttributes();
00260 
00261     mpNodeAttributes->SetRadius(radius);
00262 }
00263 
00265 // Tracking (boundary) elements which contain this node as a vertex
00267 
00268 template<unsigned SPACE_DIM>
00269 void Node<SPACE_DIM>::AddElement(unsigned index)
00270 {
00271     mElementIndices.insert(index);
00272 }
00273 
00274 template<unsigned SPACE_DIM>
00275 void Node<SPACE_DIM>::RemoveElement(unsigned index)
00276 {
00277     unsigned count = mElementIndices.erase(index);
00278     if (count == 0)
00279     {
00280         EXCEPTION("Tried to remove an index which was not in the set");
00281     }
00282 }
00283 
00284 template<unsigned SPACE_DIM>
00285 void Node<SPACE_DIM>::RemoveBoundaryElement(unsigned index)
00286 {
00287     unsigned count = mBoundaryElementIndices.erase(index);
00288     if (count == 0)
00289     {
00290         EXCEPTION("Tried to remove an index which was not in the set");
00291     }
00292 }
00293 
00294 template<unsigned SPACE_DIM>
00295 void Node<SPACE_DIM>::AddBoundaryElement(unsigned index)
00296 {
00297     mBoundaryElementIndices.insert(index);
00298 }
00299 
00300 template<unsigned SPACE_DIM>
00301 std::set<unsigned>& Node<SPACE_DIM>::rGetContainingElementIndices()
00302 {
00303     return mElementIndices;
00304 }
00305 
00306 template<unsigned SPACE_DIM>
00307 std::set<unsigned>& Node<SPACE_DIM>::rGetContainingBoundaryElementIndices()
00308 {
00309     return mBoundaryElementIndices;
00310 }
00311 
00312 template<unsigned SPACE_DIM>
00313 unsigned Node<SPACE_DIM>::GetNumContainingElements() const
00314 {
00315     return mElementIndices.size();
00316 }
00317 
00318 template<unsigned SPACE_DIM>
00319 unsigned Node<SPACE_DIM>::GetNumBoundaryElements() const
00320 {
00321     return mBoundaryElementIndices.size();
00322 }
00323 
00325 // Methods dealing with some node flags (deleted, region)
00327 
00328 template<unsigned SPACE_DIM>
00329 void Node<SPACE_DIM>::CheckForNodeAttributes() const
00330 {
00331     if (mpNodeAttributes == NULL)
00332     {
00333         EXCEPTION("Node has no attributes associated with it. Construct attributes first");
00334     }
00335 }
00336 
00337 template<unsigned SPACE_DIM>
00338 void Node<SPACE_DIM>::ConstructNodeAttributes()
00339 {
00340     if (mpNodeAttributes == NULL)
00341     {
00342         mpNodeAttributes = new NodeAttributes<SPACE_DIM>();
00343     }
00344 }
00345 
00346 template<unsigned SPACE_DIM>
00347 void Node<SPACE_DIM>::MarkAsDeleted()
00348 {
00349     mIsDeleted = true;
00350 }
00351 
00352 template<unsigned SPACE_DIM>
00353 bool Node<SPACE_DIM>::IsDeleted() const
00354 {
00355     return mIsDeleted;
00356 }
00357 
00358 template<unsigned SPACE_DIM>
00359 void Node<SPACE_DIM>::MarkAsInternal()
00360 {
00361     mIsInternal = true;
00362 }
00363 
00364 template<unsigned SPACE_DIM>
00365 bool Node<SPACE_DIM>::IsInternal() const
00366 {
00367     return mIsInternal;
00368 }
00369 
00370 template<unsigned SPACE_DIM>
00371 void Node<SPACE_DIM>::SetRegion(unsigned region)
00372 {
00373     ConstructNodeAttributes();
00374     mpNodeAttributes->SetRegion(region);
00375 }
00376 
00377 template<unsigned SPACE_DIM>
00378 unsigned Node<SPACE_DIM>::GetRegion() const
00379 {
00380     unsigned region = 0;
00381 
00382     if (mpNodeAttributes)
00383     {
00384         region = mpNodeAttributes->GetRegion();
00385     }
00386 
00387     return region;
00388 }
00389 
00390 
00392 // Explicit instantiation
00394 
00395 template class Node<1>;
00396 template class Node<2>;
00397 template class Node<3>;

Generated by  doxygen 1.6.2