Chaste Commit::1fd4e48e3990e67db148bc1bc4cf6991a0049d0c
Node.cpp
1/*
2
3Copyright (c) 2005-2024, University of Oxford.
4All rights reserved.
5
6University of Oxford means the Chancellor, Masters and Scholars of the
7University of Oxford, having an administrative office at Wellington
8Square, Oxford OX1 2JD, UK.
9
10This file is part of Chaste.
11
12Redistribution and use in source and binary forms, with or without
13modification, 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
23THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32OF 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
45template<unsigned SPACE_DIM>
46void 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
55template<unsigned SPACE_DIM>
56Node<SPACE_DIM>::Node(unsigned index, ChastePoint<SPACE_DIM> point, bool isBoundaryNode)
57{
58 mLocation = point.rGetLocation();
59 CommonConstructor(index, isBoundaryNode);
60}
61
62template<unsigned SPACE_DIM>
63Node<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
72template<unsigned SPACE_DIM>
73Node<SPACE_DIM>::Node(unsigned index, c_vector<double, SPACE_DIM> location, bool isBoundaryNode)
74{
75 mLocation = location;
76 CommonConstructor(index, isBoundaryNode);
77}
78
79template<unsigned SPACE_DIM>
80Node<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
94template<unsigned SPACE_DIM>
95Node<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
104template<unsigned SPACE_DIM>
106{
107 delete mpNodeAttributes;
108}
109
111// Methods dealing with node location
113
114template<unsigned SPACE_DIM>
116{
117 mLocation = point.rGetLocation();
118}
119
120template<unsigned SPACE_DIM>
121void Node<SPACE_DIM>::SetIndex(unsigned index)
123 mIndex = index;
124}
125
126template<unsigned SPACE_DIM>
128{
129 mIsBoundaryNode = value;
130}
131
132template<unsigned SPACE_DIM>
137
138template<unsigned SPACE_DIM>
139const 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
150template<unsigned SPACE_DIM>
151c_vector<double, SPACE_DIM>& Node<SPACE_DIM>::rGetModifiableLocation()
153 assert(!mIsDeleted);
154 return mLocation;
155}
156
157template<unsigned SPACE_DIM>
159{
160 return mIndex;
162
163template<unsigned SPACE_DIM>
165{
166 return mIsBoundaryNode;
167}
168
169template<unsigned SPACE_DIM>
171{
172 ConstructNodeAttributes();
173
174 mpNodeAttributes->AddAttribute(attribute);
175}
176
177template<unsigned SPACE_DIM>
179{
180 CheckForNodeAttributes();
181
182 return mpNodeAttributes->rGetAttributes();
183}
184
185template<unsigned SPACE_DIM>
188 unsigned num_attributes;
189 if (!mpNodeAttributes)
190 {
191 num_attributes = 0u;
192 }
193 else
194 {
195 num_attributes = mpNodeAttributes->rGetAttributes().size();
196 }
198 return num_attributes;
199}
200
201template<unsigned SPACE_DIM>
203{
204 return (mpNodeAttributes != nullptr);
205}
206
207template<unsigned SPACE_DIM>
208c_vector<double, SPACE_DIM>& Node<SPACE_DIM>::rGetAppliedForce()
209{
210 CheckForNodeAttributes();
212 return mpNodeAttributes->rGetAppliedForce();
213}
214
215template<unsigned SPACE_DIM>
217{
218 ConstructNodeAttributes();
219
220 mpNodeAttributes->ClearAppliedForce();
221}
222
223template<unsigned SPACE_DIM>
224void Node<SPACE_DIM>::AddAppliedForceContribution(const c_vector<double, SPACE_DIM>& rForceContribution)
225{
226 ConstructNodeAttributes();
227
228 mpNodeAttributes->AddAppliedForceContribution(rForceContribution);
229}
230
231template<unsigned SPACE_DIM>
233{
234 CheckForNodeAttributes();
235
236 return mpNodeAttributes->IsParticle();
237}
238
239template<unsigned SPACE_DIM>
242 ConstructNodeAttributes();
243
244 mpNodeAttributes->SetIsParticle(isParticle);
245}
247template<unsigned SPACE_DIM>
249{
250 CheckForNodeAttributes();
252 return mpNodeAttributes->GetRadius();
253}
254
255template<unsigned SPACE_DIM>
256void 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
267template<unsigned SPACE_DIM>
268void Node<SPACE_DIM>::AddElement(unsigned index)
269{
270 mElementIndices.insert(index);
271}
273template<unsigned SPACE_DIM>
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
283template<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 }
292
293template<unsigned SPACE_DIM>
295{
296 mBoundaryElementIndices.insert(index);
297}
298
299template<unsigned SPACE_DIM>
301{
302 return mElementIndices;
304
305template<unsigned SPACE_DIM>
307{
308 return mBoundaryElementIndices;
309}
311template<unsigned SPACE_DIM>
313{
314 return mElementIndices.size();
316
317template<unsigned SPACE_DIM>
319{
320 return mBoundaryElementIndices.size();
321}
322
324// Tracking neighbours of the node
326
327template<unsigned SPACE_DIM>
329{
330 ConstructNodeAttributes();
331
332 return mpNodeAttributes->AddNeighbour(index);
333}
334
335template<unsigned SPACE_DIM>
337{
338 ConstructNodeAttributes();
339
340 mpNodeAttributes->ClearNeighbours();
341}
342
343template<unsigned SPACE_DIM>
346 CheckForNodeAttributes();
347
348 mpNodeAttributes->RemoveDuplicateNeighbours();
349}
351template<unsigned SPACE_DIM>
353{
354 CheckForNodeAttributes();
356 return mpNodeAttributes->NeighboursIsEmpty();
357}
358
359template<unsigned SPACE_DIM>
361{
362 ConstructNodeAttributes();
363
364 mpNodeAttributes->SetNeighboursSetUp(flag);
366
367template<unsigned SPACE_DIM>
369{
370 CheckForNodeAttributes();
372 return mpNodeAttributes->GetNeighboursSetUp();
373};
374
375template<unsigned SPACE_DIM>
376std::vector<unsigned>& Node<SPACE_DIM>::rGetNeighbours()
377{
378 CheckForNodeAttributes();
379
380 return mpNodeAttributes->rGetNeighbours();
381};
384// Methods dealing with some node flags (deleted, region)
386
387template<unsigned SPACE_DIM>
389{
390 if (mpNodeAttributes == nullptr)
391 {
392 EXCEPTION("Node has no attributes associated with it. Construct attributes first");
393 }
395
396template<unsigned SPACE_DIM>
398{
399 if (mpNodeAttributes == nullptr)
400 {
401 mpNodeAttributes = new NodeAttributes<SPACE_DIM>();
402 }
403}
405template<unsigned SPACE_DIM>
407{
408 mIsDeleted = true;
410
411template<unsigned SPACE_DIM>
413{
414 return mIsDeleted;
415}
416
417template<unsigned SPACE_DIM>
419{
420 mIsInternal = true;
422
423template<unsigned SPACE_DIM>
425{
426 return mIsInternal;
428
429template<unsigned SPACE_DIM>
430void Node<SPACE_DIM>::SetRegion(unsigned region)
431{
432 ConstructNodeAttributes();
433 mpNodeAttributes->SetRegion(region);
434}
435
436template<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
450
451// Explicit instantiation
452template class Node<1>;
453template class Node<2>;
454template class Node<3>;
#define EXCEPTION(message)
c_vector< double, DIM > & rGetLocation()
Definition Node.hpp:59
void ClearAppliedForce()
Definition Node.cpp:216
void SetPoint(ChastePoint< SPACE_DIM > point)
Definition Node.cpp:115
std::set< unsigned > & rGetContainingElementIndices()
Definition Node.cpp:300
void SetRegion(unsigned region)
Definition Node.cpp:430
void AddNodeAttribute(double attribute)
Definition Node.cpp:170
c_vector< double, SPACE_DIM > & rGetAppliedForce()
Definition Node.cpp:208
std::vector< double > & rGetNodeAttributes()
Definition Node.cpp:178
c_vector< double, SPACE_DIM > & rGetModifiableLocation()
Definition Node.cpp:151
void AddNeighbour(unsigned index)
Definition Node.cpp:328
void SetIndex(unsigned index)
Definition Node.cpp:121
void RemoveDuplicateNeighbours()
Definition Node.cpp:344
void ClearNeighbours()
Definition Node.cpp:336
bool IsInternal() const
Definition Node.cpp:424
void SetRadius(double radius)
Definition Node.cpp:256
bool HasNodeAttributes()
Definition Node.cpp:202
unsigned GetNumContainingElements() const
Definition Node.cpp:312
std::set< unsigned > & rGetContainingBoundaryElementIndices()
Definition Node.cpp:306
void AddElement(unsigned index)
Definition Node.cpp:268
Node(unsigned index, ChastePoint< SPACE_DIM > point, bool isBoundaryNode=false)
Definition Node.cpp:56
~Node()
Definition Node.cpp:105
void CommonConstructor(unsigned index, bool isBoundaryNode)
Definition Node.cpp:46
unsigned GetNumBoundaryElements() const
Definition Node.cpp:318
void MarkAsDeleted()
Definition Node.cpp:406
void AddBoundaryElement(unsigned index)
Definition Node.cpp:294
bool IsDeleted() const
Definition Node.cpp:412
void RemoveBoundaryElement(unsigned index)
Definition Node.cpp:284
const c_vector< double, SPACE_DIM > & rGetLocation() const
Definition Node.cpp:139
bool GetNeighboursSetUp()
Definition Node.cpp:368
bool IsBoundaryNode() const
Definition Node.cpp:164
ChastePoint< SPACE_DIM > GetPoint() const
Definition Node.cpp:133
unsigned GetIndex() const
Definition Node.cpp:158
void SetAsBoundaryNode(bool value=true)
Definition Node.cpp:127
void AddAppliedForceContribution(const c_vector< double, SPACE_DIM > &rForceContribution)
Definition Node.cpp:224
bool IsParticle()
Definition Node.cpp:232
unsigned GetNumNodeAttributes()
Definition Node.cpp:186
void SetIsParticle(bool isParticle)
Definition Node.cpp:240
std::vector< unsigned > & rGetNeighbours()
Definition Node.cpp:376
double GetRadius()
Definition Node.cpp:248
bool NeighboursIsEmpty()
Definition Node.cpp:352
void SetNeighboursSetUp(bool flag)
Definition Node.cpp:360
void ConstructNodeAttributes()
Definition Node.cpp:397
void CheckForNodeAttributes() const
Definition Node.cpp:388
unsigned GetRegion() const
Definition Node.cpp:437
void RemoveElement(unsigned index)
Definition Node.cpp:274
void MarkAsInternal()
Definition Node.cpp:418