Chaste  Release::2017.1
Node.cpp
1 /*
2 
3 Copyright (c) 2005-2017, University of Oxford.
4 All rights reserved.
5 
6 University of Oxford means the Chancellor, Masters and Scholars of the
7 University of Oxford, having an administrative office at Wellington
8 Square, Oxford OX1 2JD, UK.
9 
10 This file is part of Chaste.
11 
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions are met:
14  * Redistributions of source code must retain the above copyright notice,
15  this list of conditions and the following disclaimer.
16  * Redistributions in binary form must reproduce the above copyright notice,
17  this list of conditions and the following disclaimer in the documentation
18  and/or other materials provided with the distribution.
19  * Neither the name of the University of Oxford nor the names of its
20  contributors may be used to endorse or promote products derived from this
21  software without specific prior written permission.
22 
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 
34 */
35 
36 #include <cassert>
37 
38 #include "Node.hpp"
39 #include "Exception.hpp"
40 
42 // Constructors
44 
45 template<unsigned SPACE_DIM>
46 void Node<SPACE_DIM>::CommonConstructor(unsigned index, bool isBoundaryNode)
47 {
48  mIndex = index;
49  mIsBoundaryNode = isBoundaryNode;
50  mIsInternal = false;
51  mIsDeleted = false;
52  mpNodeAttributes = nullptr;
53 }
54 
55 template<unsigned SPACE_DIM>
56 Node<SPACE_DIM>::Node(unsigned index, ChastePoint<SPACE_DIM> point, bool isBoundaryNode)
57 {
58  mLocation = point.rGetLocation();
59  CommonConstructor(index, isBoundaryNode);
60 }
61 
62 template<unsigned SPACE_DIM>
63 Node<SPACE_DIM>::Node(unsigned index, std::vector<double> coords, bool isBoundaryNode)
64 {
65  for (unsigned i=0; i<SPACE_DIM; i++)
66  {
67  mLocation(i) = coords.at(i);
68  }
69  CommonConstructor(index, isBoundaryNode);
70 }
71 
72 template<unsigned SPACE_DIM>
73 Node<SPACE_DIM>::Node(unsigned index, c_vector<double, SPACE_DIM> location, bool isBoundaryNode)
74 {
75  mLocation = location;
76  CommonConstructor(index, isBoundaryNode);
77 }
78 
79 template<unsigned SPACE_DIM>
80 Node<SPACE_DIM>::Node(unsigned index, bool isBoundaryNode, double v1, double v2, double v3)
81 {
82  mLocation[0] = v1;
83  if (SPACE_DIM > 1)
84  {
85  mLocation[1] = v2;
86  if (SPACE_DIM > 2)
87  {
88  mLocation[2] = v3;
89  }
90  }
91  CommonConstructor(index, isBoundaryNode);
92 }
93 
94 template<unsigned SPACE_DIM>
95 Node<SPACE_DIM>::Node(unsigned index, double *location, bool isBoundaryNode)
96 {
97  for (unsigned i=0; i<SPACE_DIM; i++)
98  {
99  mLocation(i) = location[i];
100  }
101  CommonConstructor(index, isBoundaryNode);
102 }
103 
104 template<unsigned SPACE_DIM>
106 {
107  delete mpNodeAttributes;
108 }
109 
111 // Methods dealing with node location
113 
114 template<unsigned SPACE_DIM>
116 {
117  mLocation = point.rGetLocation();
118 }
119 
120 template<unsigned SPACE_DIM>
121 void Node<SPACE_DIM>::SetIndex(unsigned index)
122 {
123  mIndex = index;
124 }
125 
126 template<unsigned SPACE_DIM>
128 {
129  mIsBoundaryNode = value;
130 }
131 
132 template<unsigned SPACE_DIM>
134 {
135  return ChastePoint<SPACE_DIM>(mLocation);
136 }
137 
138 template<unsigned SPACE_DIM>
139 const c_vector<double, SPACE_DIM>& Node<SPACE_DIM>::rGetLocation() const
140 {
141  // This assert statement is a useful warning: when new nodes are created we overwrite previously deleted nodes if there are any.
142  // This means that we can not use this method to interrogate deleted nodes about their position before deletion because we can't
143  // guarantee that the node has not been overwritten already. Hence, when implementing new functionality we need to make sure
144  // that this functionality does not rely on being able to interrogate deleted nodes for their location.
145  // \todo #2401: make this an exception.
146  assert(!mIsDeleted);
147  return mLocation;
148 }
149 
150 template<unsigned SPACE_DIM>
151 c_vector<double, SPACE_DIM>& Node<SPACE_DIM>::rGetModifiableLocation()
152 {
153  assert(!mIsDeleted);
154  return mLocation;
155 }
156 
157 template<unsigned SPACE_DIM>
159 {
160  return mIndex;
161 }
162 
163 template<unsigned SPACE_DIM>
165 {
166  return mIsBoundaryNode;
167 }
168 
169 template<unsigned SPACE_DIM>
170 void Node<SPACE_DIM>::AddNodeAttribute(double attribute)
171 {
172  ConstructNodeAttributes();
173 
174  mpNodeAttributes->AddAttribute(attribute);
175 }
176 
177 template<unsigned SPACE_DIM>
179 {
180  CheckForNodeAttributes();
181 
182  return mpNodeAttributes->rGetAttributes();
183 }
184 
185 template<unsigned SPACE_DIM>
187 {
188  unsigned num_attributes;
189  if (!mpNodeAttributes)
190  {
191  num_attributes = 0u;
192  }
193  else
194  {
195  num_attributes = mpNodeAttributes->rGetAttributes().size();
196  }
197 
198  return num_attributes;
199 }
200 
201 template<unsigned SPACE_DIM>
203 {
204  return (mpNodeAttributes != nullptr);
205 }
206 
207 template<unsigned SPACE_DIM>
208 c_vector<double, SPACE_DIM>& Node<SPACE_DIM>::rGetAppliedForce()
209 {
210  CheckForNodeAttributes();
211 
212  return mpNodeAttributes->rGetAppliedForce();
213 }
214 
215 template<unsigned SPACE_DIM>
217 {
218  ConstructNodeAttributes();
219 
220  mpNodeAttributes->ClearAppliedForce();
221 }
222 
223 template<unsigned SPACE_DIM>
224 void Node<SPACE_DIM>::AddAppliedForceContribution(const c_vector<double, SPACE_DIM>& rForceContribution)
225 {
226  ConstructNodeAttributes();
227 
228  mpNodeAttributes->AddAppliedForceContribution(rForceContribution);
229 }
230 
231 template<unsigned SPACE_DIM>
233 {
234  CheckForNodeAttributes();
235 
236  return mpNodeAttributes->IsParticle();
237 }
238 
239 template<unsigned SPACE_DIM>
240 void Node<SPACE_DIM>::SetIsParticle(bool isParticle)
241 {
242  ConstructNodeAttributes();
243 
244  mpNodeAttributes->SetIsParticle(isParticle);
245 }
246 
247 template<unsigned SPACE_DIM>
249 {
250  CheckForNodeAttributes();
251 
252  return mpNodeAttributes->GetRadius();
253 }
254 
255 template<unsigned SPACE_DIM>
256 void Node<SPACE_DIM>::SetRadius(double radius)
257 {
258  ConstructNodeAttributes();
259 
260  mpNodeAttributes->SetRadius(radius);
261 }
262 
264 // Tracking (boundary) elements which contain this node as a vertex
266 
267 template<unsigned SPACE_DIM>
268 void Node<SPACE_DIM>::AddElement(unsigned index)
269 {
270  mElementIndices.insert(index);
271 }
272 
273 template<unsigned SPACE_DIM>
274 void Node<SPACE_DIM>::RemoveElement(unsigned index)
275 {
276  unsigned count = mElementIndices.erase(index);
277  if (count == 0)
278  {
279  EXCEPTION("Tried to remove an index which was not in the set");
280  }
281 }
282 
283 template<unsigned SPACE_DIM>
285 {
286  unsigned count = mBoundaryElementIndices.erase(index);
287  if (count == 0)
288  {
289  EXCEPTION("Tried to remove an index which was not in the set");
290  }
291 }
292 
293 template<unsigned SPACE_DIM>
295 {
296  mBoundaryElementIndices.insert(index);
297 }
298 
299 template<unsigned SPACE_DIM>
301 {
302  return mElementIndices;
303 }
304 
305 template<unsigned SPACE_DIM>
307 {
308  return mBoundaryElementIndices;
309 }
310 
311 template<unsigned SPACE_DIM>
313 {
314  return mElementIndices.size();
315 }
316 
317 template<unsigned SPACE_DIM>
319 {
320  return mBoundaryElementIndices.size();
321 }
322 
324 // Tracking neighbours of the node
326 
327 template<unsigned SPACE_DIM>
328 void Node<SPACE_DIM>::AddNeighbour(unsigned index)
329 {
330  ConstructNodeAttributes();
331 
332  return mpNodeAttributes->AddNeighbour(index);
333 }
334 
335 template<unsigned SPACE_DIM>
337 {
338  ConstructNodeAttributes();
339 
340  mpNodeAttributes->ClearNeighbours();
341 }
342 
343 template<unsigned SPACE_DIM>
345 {
346  CheckForNodeAttributes();
347 
348  mpNodeAttributes->RemoveDuplicateNeighbours();
349 }
350 
351 template<unsigned SPACE_DIM>
353 {
354  CheckForNodeAttributes();
355 
356  return mpNodeAttributes->NeighboursIsEmpty();
357 }
358 
359 template<unsigned SPACE_DIM>
361 {
362  ConstructNodeAttributes();
363 
364  mpNodeAttributes->SetNeighboursSetUp(flag);
365 };
366 
367 template<unsigned SPACE_DIM>
369 {
370  CheckForNodeAttributes();
371 
372  return mpNodeAttributes->GetNeighboursSetUp();
373 };
374 
375 template<unsigned SPACE_DIM>
376 std::vector<unsigned>& Node<SPACE_DIM>::rGetNeighbours()
377 {
378  CheckForNodeAttributes();
379 
380  return mpNodeAttributes->rGetNeighbours();
381 };
382 
384 // Methods dealing with some node flags (deleted, region)
386 
387 template<unsigned SPACE_DIM>
389 {
390  if (mpNodeAttributes == nullptr)
391  {
392  EXCEPTION("Node has no attributes associated with it. Construct attributes first");
393  }
394 }
395 
396 template<unsigned SPACE_DIM>
398 {
399  if (mpNodeAttributes == nullptr)
400  {
401  mpNodeAttributes = new NodeAttributes<SPACE_DIM>();
402  }
403 }
404 
405 template<unsigned SPACE_DIM>
407 {
408  mIsDeleted = true;
409 }
410 
411 template<unsigned SPACE_DIM>
413 {
414  return mIsDeleted;
415 }
416 
417 template<unsigned SPACE_DIM>
419 {
420  mIsInternal = true;
421 }
422 
423 template<unsigned SPACE_DIM>
425 {
426  return mIsInternal;
427 }
428 
429 template<unsigned SPACE_DIM>
430 void Node<SPACE_DIM>::SetRegion(unsigned region)
431 {
432  ConstructNodeAttributes();
433  mpNodeAttributes->SetRegion(region);
434 }
435 
436 template<unsigned SPACE_DIM>
438 {
439  unsigned region = 0;
440 
441  if (mpNodeAttributes)
442  {
443  region = mpNodeAttributes->GetRegion();
444  }
445 
446  return region;
447 }
448 
449 // Explicit instantiation
450 template class Node<1>;
451 template class Node<2>;
452 template class Node<3>;
void CheckForNodeAttributes() const
Definition: Node.cpp:388
bool IsInternal() const
Definition: Node.cpp:424
void SetPoint(ChastePoint< SPACE_DIM > point)
Definition: Node.cpp:115
Node(unsigned index, ChastePoint< SPACE_DIM > point, bool isBoundaryNode=false)
Definition: Node.cpp:56
void ConstructNodeAttributes()
Definition: Node.cpp:397
Definition: Node.hpp:58
c_vector< double, DIM > & rGetLocation()
Definition: ChastePoint.cpp:76
void SetAsBoundaryNode(bool value=true)
Definition: Node.cpp:127
void MarkAsInternal()
Definition: Node.cpp:418
void RemoveElement(unsigned index)
Definition: Node.cpp:274
void CommonConstructor(unsigned index, bool isBoundaryNode)
Definition: Node.cpp:46
void AddNodeAttribute(double attribute)
Definition: Node.cpp:170
void SetRadius(double radius)
Definition: Node.cpp:256
bool IsBoundaryNode() const
Definition: Node.cpp:164
#define EXCEPTION(message)
Definition: Exception.hpp:143
unsigned GetNumBoundaryElements() const
Definition: Node.cpp:318
void RemoveBoundaryElement(unsigned index)
Definition: Node.cpp:284
void ClearNeighbours()
Definition: Node.cpp:336
std::set< unsigned > & rGetContainingElementIndices()
Definition: Node.cpp:300
void SetIndex(unsigned index)
Definition: Node.cpp:121
bool IsParticle()
Definition: Node.cpp:232
std::vector< double > & rGetNodeAttributes()
Definition: Node.cpp:178
void ClearAppliedForce()
Definition: Node.cpp:216
unsigned GetNumNodeAttributes()
Definition: Node.cpp:186
unsigned GetRegion() const
Definition: Node.cpp:437
bool HasNodeAttributes()
Definition: Node.cpp:202
void SetNeighboursSetUp(bool flag)
Definition: Node.cpp:360
void AddAppliedForceContribution(const c_vector< double, SPACE_DIM > &rForceContribution)
Definition: Node.cpp:224
void SetIsParticle(bool isParticle)
Definition: Node.cpp:240
std::set< unsigned > & rGetContainingBoundaryElementIndices()
Definition: Node.cpp:306
void AddNeighbour(unsigned index)
Definition: Node.cpp:328
void SetRegion(unsigned region)
Definition: Node.cpp:430
std::vector< unsigned > & rGetNeighbours()
Definition: Node.cpp:376
const c_vector< double, SPACE_DIM > & rGetLocation() const
Definition: Node.cpp:139
void AddElement(unsigned index)
Definition: Node.cpp:268
bool GetNeighboursSetUp()
Definition: Node.cpp:368
ChastePoint< SPACE_DIM > GetPoint() const
Definition: Node.cpp:133
void RemoveDuplicateNeighbours()
Definition: Node.cpp:344
void AddBoundaryElement(unsigned index)
Definition: Node.cpp:294
c_vector< double, SPACE_DIM > & rGetAppliedForce()
Definition: Node.cpp:208
unsigned GetNumContainingElements() const
Definition: Node.cpp:312
unsigned GetIndex() const
Definition: Node.cpp:158
c_vector< double, SPACE_DIM > & rGetModifiableLocation()
Definition: Node.cpp:151
void MarkAsDeleted()
Definition: Node.cpp:406
bool IsDeleted() const
Definition: Node.cpp:412
~Node()
Definition: Node.cpp:105
bool NeighboursIsEmpty()
Definition: Node.cpp:352
double GetRadius()
Definition: Node.cpp:248