Chaste  Release::2024.1
NodesOnlyMesh.cpp
1 /*
2 
3 Copyright (c) 2005-2021, 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 <map>
37 #include "NodesOnlyMesh.hpp"
38 #include "ChasteCuboid.hpp"
39 
40 template<unsigned SPACE_DIM>
42  : MutableMesh<SPACE_DIM, SPACE_DIM>(),
43  mMaximumInteractionDistance(1.0),
44  mIndexCounter(0u),
45  mMinimumNodeDomainBoundarySeparation(1.0),
46  mMaxAddedNodeIndex(0u),
47  mpBoxCollection(nullptr),
48  mCalculateNodeNeighbours(true)
49 {
50 }
51 
52 template<unsigned SPACE_DIM>
54 {
55  Clear();
57 }
58 
59 template<unsigned SPACE_DIM>
60 void NodesOnlyMesh<SPACE_DIM>::ConstructNodesWithoutMesh(const std::vector<Node<SPACE_DIM>*>& rNodes, double maxInteractionDistance)
61 {
62  assert(maxInteractionDistance > 0.0 && maxInteractionDistance < DBL_MAX);
63  mMaximumInteractionDistance = maxInteractionDistance;
64 
66 
67  Clear();
68 
69  SetUpBoxCollection(rNodes);
70 
71  mLocalInitialNodes.resize(rNodes.size(), false);
72 
73  for (unsigned i=0; i<rNodes.size(); i++)
74  {
75  if (mpBoxCollection->IsOwned(rNodes[i]))
76  {
77  assert(!rNodes[i]->IsDeleted());
78 
79  mLocalInitialNodes[i] = true;
80 
81  // Create a copy of the node, sharing its location
82  c_vector<double, SPACE_DIM> location = rNodes[i]->rGetLocation();
83  Node<SPACE_DIM>* p_node_copy = new Node<SPACE_DIM>(GetNextAvailableIndex(), location);
84 
85  p_node_copy->SetRadius(0.5);
86 
87  // If the original node has attributes, then copy these
88  if (rNodes[i]->HasNodeAttributes())
89  {
90  p_node_copy->rGetNodeAttributes() = rNodes[i]->rGetNodeAttributes();
91  }
92 
93  this->mNodes.push_back(p_node_copy);
94 
95  // Update the node map
96  mNodesMapping[p_node_copy->GetIndex()] = this->mNodes.size()-1;
97  }
98  }
99 }
100 
101 template<unsigned SPACE_DIM>
102 void NodesOnlyMesh<SPACE_DIM>::ConstructNodesWithoutMesh(const std::vector<boost::shared_ptr<Node<SPACE_DIM> > >& rNodes, double maxInteractionDistance)
103 {
104  // This is not efficient. It should replace the corresponding raw ptr method if SetUpBoxCollection and Chaste Cuboid methods are changed to take shared ptrs.
105  std::vector<Node<SPACE_DIM>*> temp_nodes(rNodes.size());
106  for(unsigned idx=0; idx<rNodes.size(); idx++)
107  {
108  temp_nodes[idx] = rNodes[idx].get();
109  }
110 
111  ConstructNodesWithoutMesh(temp_nodes, maxInteractionDistance);
112 }
113 
114 template<unsigned SPACE_DIM>
115 void NodesOnlyMesh<SPACE_DIM>::ConstructNodesWithoutMesh(const AbstractMesh<SPACE_DIM,SPACE_DIM>& rGeneratingMesh, double maxInteractionDistance)
116 {
117  ConstructNodesWithoutMesh(rGeneratingMesh.mNodes, maxInteractionDistance);
118 }
119 
120 template<unsigned SPACE_DIM>
122 {
123  return mLocalInitialNodes;
124 }
125 
126 template<unsigned SPACE_DIM>
127 unsigned NodesOnlyMesh<SPACE_DIM>::SolveNodeMapping(unsigned index) const
128 {
129  std::map<unsigned, unsigned>::const_iterator node_position = mNodesMapping.find(index);
130 
131  if (node_position == mNodesMapping.end())
132  {
133  EXCEPTION("Requested node " << index << " does not belong to process " << PetscTools::GetMyRank());
134  }
135 
136  return node_position->second;
137 }
138 
139 template<unsigned SPACE_DIM>
141 {
142  // Call Clear() on the parent class
144 
145  // Clear the nodes mapping
146  mNodesMapping.clear();
147 
148  mIndexCounter = 0;
149 }
150 
151 template<unsigned SPACE_DIM>
153 {
154  return mpBoxCollection;
155 }
156 
157 template <unsigned SPACE_DIM>
159 {
160  Node<SPACE_DIM>* p_node;
161 
162  std::map<unsigned, unsigned>::const_iterator node_position = mHaloNodesMapping.find(index);
163 
164  if (node_position != mHaloNodesMapping.end())
165  {
166  p_node = mHaloNodes[node_position->second].get();
167  }
168  else
169  {
170  p_node = this->GetNode(index);
171  }
172 
173  assert(p_node != nullptr);
174 
175  return p_node;
176 }
177 
178 template<unsigned SPACE_DIM>
179 bool NodesOnlyMesh<SPACE_DIM>::IsOwned(c_vector<double, SPACE_DIM>& location)
180 {
181  return mpBoxCollection->IsOwned(location);
182 }
183 
184 template<unsigned SPACE_DIM>
186 {
187  return this->mNodes.size() - this->mDeletedNodeIndices.size();
188 }
189 
190 template<unsigned SPACE_DIM>
192 {
194 }
195 
196 template<unsigned SPACE_DIM>
198 {
199  mMaximumInteractionDistance = maxDistance;
200 }
201 
202 template<unsigned SPACE_DIM>
204 {
206 }
207 
208 template<unsigned SPACE_DIM>
209 double NodesOnlyMesh<SPACE_DIM>::GetWidth(const unsigned& rDimension) const
210 {
211  double local_width = AbstractMesh<SPACE_DIM, SPACE_DIM>::GetWidth(rDimension);
212  double global_width;
213 
214  MPI_Allreduce(&local_width, &global_width, 1, MPI_DOUBLE, MPI_MAX, PetscTools::GetWorld());
215 
216  return global_width;
217 }
218 
219 template<unsigned SPACE_DIM>
221 {
222  mCalculateNodeNeighbours = calculateNodeNeighbours;
223 }
224 
225 template<unsigned SPACE_DIM>
227 {
228  assert(mpBoxCollection);
229 
231 }
232 
233 template<unsigned SPACE_DIM>
235 {
236  assert(mpBoxCollection);
237 
239 }
240 
241 template<unsigned SPACE_DIM>
243 {
244  map.ResetToIdentity();
245 
246  RemoveDeletedNodes(map);
247 
248  this->mDeletedNodeIndices.clear();
249  this->mAddedNodes = false;
250 
252 
254 }
255 
256 template<unsigned SPACE_DIM>
258 {
259  typename std::vector<Node<SPACE_DIM>* >::iterator node_iter = this->mNodes.begin();
260  while (node_iter != this->mNodes.end())
261  {
262  if ((*node_iter)->IsDeleted())
263  {
264  map.SetDeleted((*node_iter)->GetIndex());
265 
266  mNodesMapping.erase((*node_iter)->GetIndex());
267 
268  // Free memory before erasing the pointer from the list of nodes.
269  delete (*node_iter);
270  node_iter = this->mNodes.erase(node_iter);
271  }
272  else
273  {
274  ++node_iter;
275  }
276  }
277 }
278 
279 template<unsigned SPACE_DIM>
281 {
282  mNodesMapping.clear();
283  for (unsigned location_in_vector=0; location_in_vector < this->mNodes.size(); location_in_vector++)
284  {
285  unsigned global_index = this->mNodes[location_in_vector]->GetIndex();
286  mNodesMapping[global_index] = location_in_vector;
287  }
288 }
289 
290 template<unsigned SPACE_DIM>
292 {
293  mNodesToSendRight.clear();
294  mNodesToSendLeft.clear();
295 
297  node_iter != this->GetNodeIteratorEnd();
298  ++node_iter)
299  {
300  unsigned owning_process = mpBoxCollection->GetProcessOwningNode(&(*node_iter));
301  if (owning_process == PetscTools::GetMyRank())
302  {
303  // Do nothing.
304  }
305  else if (owning_process == PetscTools::GetMyRank() + 1)
306  {
307  mNodesToSendRight.push_back(node_iter->GetIndex());
308  }
309  else if (owning_process == PetscTools::GetMyRank() - 1)
310  {
311  mNodesToSendLeft.push_back(node_iter->GetIndex());
312  }
313  // Periodic cases
314 
315  // LCOV_EXCL_START
316  /* This block cannot be covered by regular testing,
317  * but it is covered by the Nightly -np 3 builder
318  * See TestGetNodesOutsideLocalDomainwithPeriodicMesh
319  */
320  else if ( owning_process == (PetscTools::GetNumProcs()-1) )
321  {
322  // We are on the base and need to send to the top (i.e. left)
323  mNodesToSendLeft.push_back(node_iter->GetIndex());
324  }
325  else if ( owning_process == 0 )
326  {
327  // We are on the top and need to send to the bottom process (i.e. right)
328  mNodesToSendRight.push_back(node_iter->GetIndex());
329  }
330  // LCOV_EXCL_STOP
331  }
332 }
333 
334 template<unsigned SPACE_DIM>
336 {
337  return mNodesToSendLeft;
338 }
339 
340 template<unsigned SPACE_DIM>
342 {
343  return mNodesToSendRight;
344 }
345 
346 template<unsigned SPACE_DIM>
348 {
350 }
351 
352 template<unsigned SPACE_DIM>
354 {
356 }
357 
358 template<unsigned SPACE_DIM>
360 {
361  unsigned location_in_nodes_vector = 0;
362 
363  if (this->mDeletedNodeIndices.empty())
364  {
365  this->mNodes.push_back(pNewNode);
366  location_in_nodes_vector = this->mNodes.size() - 1;
367  }
368  else
369  {
370  location_in_nodes_vector = this->mDeletedNodeIndices.back();
371  this->mDeletedNodeIndices.pop_back();
372  delete this->mNodes[location_in_nodes_vector];
373  this->mNodes[location_in_nodes_vector] = pNewNode;
374  }
375 
376  this->mAddedNodes = true;
377 
379 
380  // Update mNodesMapping
381  mNodesMapping[pNewNode->GetIndex()] = location_in_nodes_vector;
382 
383  // Then update cell radius to default.
384  pNewNode->SetRadius(0.5);
385 }
386 
387 template<unsigned SPACE_DIM>
388 void NodesOnlyMesh<SPACE_DIM>::AddHaloNode(boost::shared_ptr<Node<SPACE_DIM> > pNewNode)
389 {
390  mHaloNodes.push_back(pNewNode);
391  mHaloNodesMapping[pNewNode->GetIndex()] = mHaloNodes.size() - 1;
392 }
393 
394 template<unsigned SPACE_DIM>
396 {
397  mHaloNodes.clear();
398 
399  mHaloNodesMapping.clear();
400 }
401 
402 template<unsigned SPACE_DIM>
404 {
405  unsigned fresh_global_index = GetNextAvailableIndex();
406  pNewNode->SetIndex(fresh_global_index);
407 
408  AddNodeWithFixedIndex(pNewNode);
409 
410  return fresh_global_index;
411 }
412 
413 template<unsigned SPACE_DIM>
414 void NodesOnlyMesh<SPACE_DIM>::SetNode(unsigned nodeIndex, ChastePoint<SPACE_DIM> point, bool concreteMove)
415 {
416  // concreteMove should always be false for a NodesOnlyMesh as there are no elements to check
417  assert(!concreteMove);
418 
419  // Update the node's location
420  this->GetNode(nodeIndex)->SetPoint(point);
421 }
422 
423 template<unsigned SPACE_DIM>
424 void NodesOnlyMesh<SPACE_DIM>::AddMovedNode(boost::shared_ptr<Node<SPACE_DIM> > pMovedNode)
425 {
426  // Make a deep copy of this node pointer so that it isn't accidentally deleted.
427  unsigned index = pMovedNode->GetIndex();
428  c_vector<double, SPACE_DIM> location = pMovedNode->rGetLocation();
429 
430  Node<SPACE_DIM>* p_node = new Node<SPACE_DIM>(index, location);
431 
432  if (pMovedNode->HasNodeAttributes())
433  {
434  double radius = pMovedNode->GetRadius();
435  p_node->SetRadius(radius);
436 
437  unsigned region = pMovedNode->GetRegion();
438  p_node->SetRegion(region);
439 
440  bool is_particle = pMovedNode->IsParticle();
441  p_node->SetIsParticle(is_particle);
442 
443  for (unsigned i=0; i<pMovedNode->GetNumNodeAttributes(); i++)
444  {
445  double attribute = pMovedNode->rGetNodeAttributes()[i];
446  p_node->AddNodeAttribute(attribute);
447  }
448  }
449 
450  AddNodeWithFixedIndex(p_node);
451 }
452 
453 template<unsigned SPACE_DIM>
455 {
456  if (this->GetNode(index)->IsDeleted())
457  {
458  EXCEPTION("Trying to delete a deleted node");
459  }
460 
461  unsigned local_index = SolveNodeMapping(index);
462 
463  this->mNodes[local_index]->MarkAsDeleted();
464  this->mDeletedNodeIndices.push_back(local_index);
465  mDeletedGlobalNodeIndices.push_back(index);
466 }
467 
468 template<unsigned SPACE_DIM>
470 {
471  DeleteNode(index);
472 
473  // Remove index from deleted indices, as moved indices must not be re-used.
474  mDeletedGlobalNodeIndices.pop_back();
475 }
476 
477 template<unsigned SPACE_DIM>
479 {
480  assert(!(separation < 0.0));
481 
483 }
484 
485 template<unsigned SPACE_DIM>
487 {
488  unsigned index;
489 
490  if (!this->mDeletedGlobalNodeIndices.empty())
491  {
492  index = this->mDeletedGlobalNodeIndices.back();
493  this->mDeletedGlobalNodeIndices.pop_back();
494  }
495  else
496  {
497  unsigned counter = mIndexCounter;
498  mIndexCounter++;
499  index = counter * PetscTools::GetNumProcs() + PetscTools::GetMyRank();
500  }
501 
502  return index;
503 }
504 
505 template<unsigned SPACE_DIM>
507 {
508  assert(mpBoxCollection);
509 
510  int num_local_rows = mpBoxCollection->GetNumLocalRows();
511  int new_local_rows = num_local_rows + (int)(PetscTools::AmTopMost()) + (int)(PetscTools::AmMaster());
512 
513  c_vector<double, 2*SPACE_DIM> current_domain_size = mpBoxCollection->rGetDomainSize();
514  c_vector<double, 2*SPACE_DIM> new_domain_size = current_domain_size;
515 
516  double fudge = 1e-14;
517  c_vector<bool, SPACE_DIM> is_periodic = mpBoxCollection->GetIsPeriodicAllDims();
518  for (unsigned d=0; d < SPACE_DIM; d++)
519  {
520  // We don't enlarge in periodic directions
521  if ( !is_periodic(d) )
522  {
523  new_domain_size[2*d] = current_domain_size[2*d] - (mMaximumInteractionDistance - fudge);
524  new_domain_size[2*d+1] = current_domain_size[2*d+1] + (mMaximumInteractionDistance - fudge);
525  }
526  }
527  SetUpBoxCollection(mMaximumInteractionDistance, new_domain_size, new_local_rows);
528 }
529 
530 template<unsigned SPACE_DIM>
532 {
533  assert(mpBoxCollection);
534 
535  int is_local_node_close = 0;
536  c_vector<double, 2*SPACE_DIM> domain_boundary = mpBoxCollection->rGetDomainSize();
537 
539  node_iter != this->GetNodeIteratorEnd();
540  ++node_iter)
541  {
542  // Note that we define this vector before setting it as otherwise the profiling build will break (see #2367)
543  c_vector<double, SPACE_DIM> location;
544  location = node_iter->rGetLocation();
545  // We need to ignore periodic dimensions
546  c_vector<bool, SPACE_DIM> is_periodic = mpBoxCollection->GetIsPeriodicAllDims();
547  for (unsigned d=0; d<SPACE_DIM; d++)
548  {
549  if ( !is_periodic(d) &&
550  ( location[d] < (domain_boundary[2*d] + mMinimumNodeDomainBoundarySeparation) || location[d] > (domain_boundary[2*d+1] - mMinimumNodeDomainBoundarySeparation) ) )
551  {
552  is_local_node_close = 1;
553  break;
554  }
555  }
556  if (is_local_node_close)
557  {
558  break; // Saves checking every node if we find one close to the boundary
559  }
560  }
561 
562  // Synchronise between processes
563  int is_any_node_close = 0;
564  MPI_Allreduce(&is_local_node_close, &is_any_node_close, 1, MPI_INT, MPI_SUM, PetscTools::GetWorld());
565 
566  return (is_any_node_close > 0);
567 }
568 
569 template<unsigned SPACE_DIM>
571 {
572  if (mpBoxCollection)
573  {
574  delete mpBoxCollection;
575  }
576  mpBoxCollection = nullptr;
577 }
578 
579 template<unsigned SPACE_DIM>
580 void NodesOnlyMesh<SPACE_DIM>::SetInitialBoxCollection(const c_vector<double, 2*SPACE_DIM> domainSize, double maxInteractionDistance)
581 {
582  this->SetUpBoxCollection(maxInteractionDistance, domainSize);
583 }
584 
585 template<unsigned SPACE_DIM>
587 {
589 
590  ChasteCuboid<SPACE_DIM> bounding_box = this->CalculateBoundingBox(rNodes);
591 
592  c_vector<double, 2*SPACE_DIM> domain_size;
593  for (unsigned i=0; i < SPACE_DIM; i++)
594  {
595  domain_size[2*i] = bounding_box.rGetLowerCorner()[i] - 1e-14;
596  domain_size[2*i+1] = bounding_box.rGetUpperCorner()[i] + 1e-14;
597  }
599 }
600 
601 template<unsigned SPACE_DIM>
602 void NodesOnlyMesh<SPACE_DIM>::SetUpBoxCollection(double cutOffLength, c_vector<double, 2*SPACE_DIM> domainSize, int numLocalRows, c_vector<bool,SPACE_DIM> isDimPeriodic)
603 {
605 
606  bool isPeriodicInX = false;
607  bool isPeriodicInY = false;
608  bool isPeriodicInZ = false;
609 
610  for ( unsigned i=0; i<SPACE_DIM; i++ )
611  {
612  if ( i==0 )
613  {
614  isPeriodicInX = isDimPeriodic(i);
615  }
616  if ( i==1 )
617  {
618  isPeriodicInY = isDimPeriodic(i);
619  }
620  if ( i==2 )
621  {
622  isPeriodicInZ = isDimPeriodic(i);
623  }
624  }
625  mpBoxCollection = new DistributedBoxCollection<SPACE_DIM>(cutOffLength, domainSize, isPeriodicInX, isPeriodicInY, isPeriodicInZ, numLocalRows);
628 }
629 
630 template<unsigned SPACE_DIM>
632 {
633  // Put the nodes in the boxes.
635  node_iter != this->GetNodeIteratorEnd();
636  ++node_iter)
637  {
638  unsigned box_index = mpBoxCollection->CalculateContainingBox(&(*node_iter));
639  mpBoxCollection->rGetBox(box_index).AddNode(&(*node_iter));
640  }
641 }
642 
643 template<unsigned SPACE_DIM>
645 {
646  // Add halo nodes
647  for (typename std::vector<boost::shared_ptr<Node<SPACE_DIM> > >::iterator halo_node_iter = mHaloNodes.begin();
648  halo_node_iter != mHaloNodes.end();
649  ++halo_node_iter)
650  {
651  unsigned box_index = mpBoxCollection->CalculateContainingBox((*halo_node_iter).get());
652  mpBoxCollection->rGetHaloBox(box_index).AddNode((*halo_node_iter).get());
653  }
654 }
655 
656 template<unsigned SPACE_DIM>
658 {
659  assert(mpBoxCollection);
660 
661  // Remove node pointers from boxes in BoxCollection.
663 
664  AddNodesToBoxes();
665 
667 }
668 
669 template<unsigned SPACE_DIM>
671 {
672  if (!mpBoxCollection)
673  {
674  SetUpBoxCollection(this->mNodes);
675  }
676 
678  {
680  }
681 }
682 
683 template<unsigned SPACE_DIM>
685 {
687 }
688 
689 template<unsigned SPACE_DIM>
691 {
692  std::vector<int> local_node_distribution = mpBoxCollection->CalculateNumberOfNodesInEachStrip();
693 
694  unsigned new_rows = mpBoxCollection->LoadBalance(local_node_distribution);
695 
696  c_vector<double, 2*SPACE_DIM> current_domain_size = mpBoxCollection->rGetDomainSize();
697 
698  // This ensures the domain will stay the same size.
699  double fudge = 1e-14;
700  for (unsigned d=0; d < SPACE_DIM; d++)
701  {
702  current_domain_size[2*d] = current_domain_size[2*d] + fudge;
703  current_domain_size[2*d+1] = current_domain_size[2*d+1] - fudge;
704  }
705  SetUpBoxCollection(mMaximumInteractionDistance, current_domain_size, new_rows);
706 }
707 
708 template<unsigned SPACE_DIM>
710 {
712 
713  // Set the correct global node indices
714  for (unsigned i=0; i<this->mNodes.size(); i++)
715  {
716  this->mNodes[i]->SetIndex(GetNextAvailableIndex());
717  }
718 }
719 
720 template<unsigned SPACE_DIM>
721 std::vector<unsigned> NodesOnlyMesh<SPACE_DIM>::GetAllNodeIndices() const
722 {
723  std::vector<unsigned> indices(GetNumNodes()); // GetNumNodes = mNodes - mDeletedNodes
724  unsigned live_index=0;
725  for (unsigned i=0; i<this->mNodes.size(); i++)
726  {
727  // Only use nodes which are not deleted
728  if (!this->mNodes[i]->IsDeleted())
729  {
730  indices[live_index] = this->mNodes[i]->GetIndex();
731  live_index++;
732  }
733  }
734  return indices;
735 }
736 
737 // Explicit instantiation
738 template class NodesOnlyMesh<1>;
739 template class NodesOnlyMesh<2>;
740 template class NodesOnlyMesh<3>;
741 
742 // Serialization for Boost >= 1.36
std::vector< unsigned > & rGetHaloNodesRight()
bool IsANodeCloseToDomainBoundary()
unsigned CalculateContainingBox(Node< DIM > *pNode)
bool mCalculateNodeNeighbours
std::vector< unsigned > & rGetNodesToSendLeft()
virtual unsigned GetMaximumNodeIndex()
std::vector< unsigned > & rGetHaloNodesToSendLeft()
void EnlargeBoxCollection()
void SetNode(unsigned nodeIndex, ChastePoint< SPACE_DIM > point, bool concreteMove=false)
Definition: Node.hpp:58
unsigned mIndexCounter
void LoadBalanceMesh()
void CalculateBoundaryNodePairs(std::vector< Node< DIM > *> &rNodes, std::vector< std::pair< Node< DIM > *, Node< DIM > *> > &rNodePairs)
void AddNodeAttribute(double attribute)
Definition: Node.cpp:170
void SetRadius(double radius)
Definition: Node.cpp:256
const ChastePoint< SPACE_DIM > & rGetUpperCorner() const
c_vector< double, 2 *DIM > rGetDomainSize() const
virtual ChasteCuboid< SPACE_DIM > CalculateBoundingBox() const
std::vector< bool > & rGetInitiallyOwnedNodes()
#define EXCEPTION(message)
Definition: Exception.hpp:143
double mMaximumInteractionDistance
void SetCalculateNodeNeighbours(bool calculateNodeNeighbours)
unsigned GetNumNodes() const
static bool AmMaster()
Definition: PetscTools.cpp:120
void ConstructFromMeshReader(AbstractMeshReader< SPACE_DIM, SPACE_DIM > &rMeshReader)
NodeIterator GetNodeIteratorEnd()
void ConstructFromMeshReader(AbstractMeshReader< ELEMENT_DIM, SPACE_DIM > &rMeshReader)
std::vector< int > CalculateNumberOfNodesInEachStrip()
void AddNodeWithFixedIndex(Node< SPACE_DIM > *pNewNode)
void ResetToIdentity()
Definition: NodeMap.cpp:57
static MPI_Comm GetWorld()
Definition: PetscTools.cpp:178
void SetIndex(unsigned index)
Definition: Node.cpp:121
unsigned GetIndex() const
Definition: Node.cpp:158
Node< SPACE_DIM > * GetNodeOrHaloNode(unsigned index) const
std::vector< double > & rGetNodeAttributes()
Definition: Node.cpp:178
void SetUpBoxCollection(const std::vector< Node< SPACE_DIM > * > &rNodes)
Node< SPACE_DIM > * GetNode(unsigned index) const
unsigned GetProcessOwningNode(Node< DIM > *pNode)
std::vector< unsigned > & rGetHaloNodesToSendRight()
std::vector< unsigned > mDeletedNodeIndices
virtual double GetWidth(const unsigned &rDimension) const
void SetCalculateNodeNeighbours(bool calculateNodeNeighbours)
void AddHaloNodesToBoxes()
void CalculateInteriorNodePairs(std::vector< std::pair< Node< SPACE_DIM > *, Node< SPACE_DIM > *> > &rNodePairs)
std::vector< Node< SPACE_DIM > * > mNodes
#define EXPORT_TEMPLATE_CLASS_SAME_DIMS(CLASS)
void DeleteNode(unsigned index)
void SetIsParticle(bool isParticle)
Definition: Node.cpp:240
double GetMaximumInteractionDistance()
unsigned SolveNodeMapping(unsigned index) const
void DeleteMovedNode(unsigned index)
std::vector< unsigned > & rGetHaloNodesLeft()
unsigned GetNextAvailableIndex()
void RemoveDeletedNodes(NodeMap &map)
void ResizeBoxCollection()
void SetDeleted(unsigned index)
Definition: NodeMap.cpp:76
bool IsOwned(Node< DIM > *pNode)
void SetInitialBoxCollection(const c_vector< double, 2 *SPACE_DIM > domainSize, double maxInteractionDistance)
DistributedBoxCollection< SPACE_DIM > * mpBoxCollection
void SetMaximumInteractionDistance(double maxDistance)
NodeIterator GetNodeIteratorBegin(bool skipDeletedNodes=true)
void UpdateBoxCollection()
int LoadBalance(std::vector< int > localDistribution)
void CalculateInteriorNodePairs(std::vector< Node< DIM > *> &rNodes, std::vector< std::pair< Node< DIM > *, Node< DIM > *> > &rNodePairs)
void AddHaloNode(boost::shared_ptr< Node< SPACE_DIM > > pNewNode)
void CalculateNodesOutsideLocalDomain()
std::vector< unsigned > mNodesToSendLeft
void SetRegion(unsigned region)
Definition: Node.cpp:430
void SetMeshHasChangedSinceLoading()
void SetMinimumNodeDomainBoundarySeparation(double separation)
unsigned AddNode(Node< SPACE_DIM > *pNewNode)
DistributedBoxCollection< SPACE_DIM > * GetBoxCollection()
bool GetIsPeriodicAcrossProcsFromBoxCollection() const
std::vector< unsigned > & rGetNodesToSendRight()
unsigned mMaxAddedNodeIndex
std::vector< unsigned > GetAllNodeIndices() const
std::vector< boost::shared_ptr< Node< SPACE_DIM > > > mHaloNodes
std::vector< bool > mLocalInitialNodes
double mMinimumNodeDomainBoundarySeparation
std::vector< unsigned > mDeletedGlobalNodeIndices
Box< DIM > & rGetHaloBox(unsigned boxIndex)
static bool AmTopMost()
Definition: PetscTools.cpp:126
void AddNodesToBoxes()
std::map< unsigned, unsigned > mNodesMapping
bool IsOwned(c_vector< double, SPACE_DIM > &location)
static unsigned GetNumProcs()
Definition: PetscTools.cpp:108
void ClearBoxCollection()
const ChastePoint< SPACE_DIM > & rGetLowerCorner() const
static unsigned GetMyRank()
Definition: PetscTools.cpp:114
void ConstructNodesWithoutMesh(const std::vector< Node< SPACE_DIM > *> &rNodes, double maxInteractionDistance)
void UpdateNodeIndices()
void AddMovedNode(boost::shared_ptr< Node< SPACE_DIM > > pMovedNode)
Box< DIM > & rGetBox(unsigned boxIndex)
std::map< unsigned, unsigned > mHaloNodesMapping
c_vector< bool, DIM > GetIsPeriodicAllDims() const
void CalculateBoundaryNodePairs(std::vector< std::pair< Node< SPACE_DIM > *, Node< SPACE_DIM > *> > &rNodePairs)
double GetWidth(const unsigned &rDimension) const
virtual ~NodesOnlyMesh()
double GetRadius()
Definition: Node.cpp:248
std::vector< unsigned > mNodesToSendRight