Chaste  Release::2018.1
NodesOnlyMesh.cpp
1 /*
2 
3 Copyright (c) 2005-2018, 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();
56  ClearBoxCollection();
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 
65  mMinimumNodeDomainBoundarySeparation = mMaximumInteractionDistance;
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 {
193  return std::max(mIndexCounter* PetscTools::GetNumProcs() + PetscTools::GetMyRank(), mMaxAddedNodeIndex);
194 }
195 
196 template<unsigned SPACE_DIM>
198 {
199  mMaximumInteractionDistance = maxDistance;
200 }
201 
202 template<unsigned SPACE_DIM>
204 {
205  return mMaximumInteractionDistance;
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 
230  mpBoxCollection->CalculateInteriorNodePairs(this->mNodes, rNodePairs);
231 }
232 
233 template<unsigned SPACE_DIM>
235 {
236  assert(mpBoxCollection);
237 
238  mpBoxCollection->CalculateBoundaryNodePairs(this->mNodes, rNodePairs);
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 
251  UpdateNodeIndices();
252 
253  this->SetMeshHasChangedSinceLoading();
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 
296  for (typename AbstractMesh<SPACE_DIM, SPACE_DIM>::NodeIterator node_iter = this->GetNodeIteratorBegin();
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  }
314 }
315 
316 template<unsigned SPACE_DIM>
318 {
319  return mNodesToSendLeft;
320 }
321 
322 template<unsigned SPACE_DIM>
324 {
325  return mNodesToSendRight;
326 }
327 
328 template<unsigned SPACE_DIM>
330 {
331  return mpBoxCollection->rGetHaloNodesRight();
332 }
333 
334 template<unsigned SPACE_DIM>
336 {
337  return mpBoxCollection->rGetHaloNodesLeft();
338 }
339 
340 template<unsigned SPACE_DIM>
342 {
343  unsigned location_in_nodes_vector = 0;
344 
345  if (this->mDeletedNodeIndices.empty())
346  {
347  this->mNodes.push_back(pNewNode);
348  location_in_nodes_vector = this->mNodes.size() - 1;
349  }
350  else
351  {
352  location_in_nodes_vector = this->mDeletedNodeIndices.back();
353  this->mDeletedNodeIndices.pop_back();
354  delete this->mNodes[location_in_nodes_vector];
355  this->mNodes[location_in_nodes_vector] = pNewNode;
356  }
357 
358  this->mAddedNodes = true;
359 
360  mMaxAddedNodeIndex = (pNewNode->GetIndex() > mMaxAddedNodeIndex) ? pNewNode->GetIndex() : mMaxAddedNodeIndex;
361 
362  // Update mNodesMapping
363  mNodesMapping[pNewNode->GetIndex()] = location_in_nodes_vector;
364 
365  // Then update cell radius to default.
366  pNewNode->SetRadius(0.5);
367 }
368 
369 template<unsigned SPACE_DIM>
370 void NodesOnlyMesh<SPACE_DIM>::AddHaloNode(boost::shared_ptr<Node<SPACE_DIM> > pNewNode)
371 {
372  mHaloNodes.push_back(pNewNode);
373  mHaloNodesMapping[pNewNode->GetIndex()] = mHaloNodes.size() - 1;
374 }
375 
376 template<unsigned SPACE_DIM>
378 {
379  mHaloNodes.clear();
380 
381  mHaloNodesMapping.clear();
382 }
383 
384 template<unsigned SPACE_DIM>
386 {
387  unsigned fresh_global_index = GetNextAvailableIndex();
388  pNewNode->SetIndex(fresh_global_index);
389 
390  AddNodeWithFixedIndex(pNewNode);
391 
392  return fresh_global_index;
393 }
394 
395 template<unsigned SPACE_DIM>
396 void NodesOnlyMesh<SPACE_DIM>::SetNode(unsigned nodeIndex, ChastePoint<SPACE_DIM> point, bool concreteMove)
397 {
398  // concreteMove should always be false for a NodesOnlyMesh as there are no elements to check
399  assert(!concreteMove);
400 
401  // Update the node's location
402  this->GetNode(nodeIndex)->SetPoint(point);
403 }
404 
405 template<unsigned SPACE_DIM>
406 void NodesOnlyMesh<SPACE_DIM>::AddMovedNode(boost::shared_ptr<Node<SPACE_DIM> > pMovedNode)
407 {
408  // Make a deep copy of this node pointer so that it isn't accidentally deleted.
409  unsigned index = pMovedNode->GetIndex();
410  c_vector<double, SPACE_DIM> location = pMovedNode->rGetLocation();
411 
412  Node<SPACE_DIM>* p_node = new Node<SPACE_DIM>(index, location);
413 
414  if (pMovedNode->HasNodeAttributes())
415  {
416  double radius = pMovedNode->GetRadius();
417  p_node->SetRadius(radius);
418 
419  unsigned region = pMovedNode->GetRegion();
420  p_node->SetRegion(region);
421 
422  bool is_particle = pMovedNode->IsParticle();
423  p_node->SetIsParticle(is_particle);
424 
425  for (unsigned i=0; i<pMovedNode->GetNumNodeAttributes(); i++)
426  {
427  double attribute = pMovedNode->rGetNodeAttributes()[i];
428  p_node->AddNodeAttribute(attribute);
429  }
430  }
431 
432  AddNodeWithFixedIndex(p_node);
433 }
434 
435 template<unsigned SPACE_DIM>
437 {
438  if (this->GetNode(index)->IsDeleted())
439  {
440  EXCEPTION("Trying to delete a deleted node");
441  }
442 
443  unsigned local_index = SolveNodeMapping(index);
444 
445  this->mNodes[local_index]->MarkAsDeleted();
446  this->mDeletedNodeIndices.push_back(local_index);
447  mDeletedGlobalNodeIndices.push_back(index);
448 }
449 
450 template<unsigned SPACE_DIM>
452 {
453  DeleteNode(index);
454 
455  // Remove index from deleted indices, as moved indices must not be re-used.
456  mDeletedGlobalNodeIndices.pop_back();
457 }
458 
459 template<unsigned SPACE_DIM>
461 {
462  assert(!(separation < 0.0));
463 
464  mMinimumNodeDomainBoundarySeparation = separation;
465 }
466 
467 template<unsigned SPACE_DIM>
469 {
470  unsigned index;
471 
472  if (!this->mDeletedGlobalNodeIndices.empty())
473  {
474  index = this->mDeletedGlobalNodeIndices.back();
475  this->mDeletedGlobalNodeIndices.pop_back();
476  }
477  else
478  {
479  unsigned counter = mIndexCounter;
480  mIndexCounter++;
481  index = counter * PetscTools::GetNumProcs() + PetscTools::GetMyRank();
482  }
483 
484  return index;
485 }
486 
487 template<unsigned SPACE_DIM>
489 {
490  assert(mpBoxCollection);
491 
492  int num_local_rows = mpBoxCollection->GetNumLocalRows();
493  int new_local_rows = num_local_rows + (int)(PetscTools::AmTopMost()) + (int)(PetscTools::AmMaster());
494 
495  c_vector<double, 2*SPACE_DIM> current_domain_size = mpBoxCollection->rGetDomainSize();
496  c_vector<double, 2*SPACE_DIM> new_domain_size = current_domain_size;
497 
498  double fudge = 1e-14;
499  // We don't enlarge the x direction if periodic
500  unsigned d0 = ( mpBoxCollection->GetIsPeriodicInX() ) ? 1 : 0;
501  for (unsigned d=d0; d < SPACE_DIM; d++)
502  {
503  new_domain_size[2*d] = current_domain_size[2*d] - (mMaximumInteractionDistance - fudge);
504  new_domain_size[2*d+1] = current_domain_size[2*d+1] + (mMaximumInteractionDistance - fudge);
505  }
506  SetUpBoxCollection(mMaximumInteractionDistance, new_domain_size, new_local_rows);
507 }
508 
509 template<unsigned SPACE_DIM>
511 {
512  assert(mpBoxCollection);
513 
514  int is_local_node_close = 0;
515  c_vector<double, 2*SPACE_DIM> domain_boundary = mpBoxCollection->rGetDomainSize();
516 
517  // We ignore the x direction if the domain is periodic in x
518  unsigned d0 = ( mpBoxCollection->GetIsPeriodicInX() ) ? 1 : 0;
519 
520  for (typename AbstractMesh<SPACE_DIM, SPACE_DIM>::NodeIterator node_iter = this->GetNodeIteratorBegin();
521  node_iter != this->GetNodeIteratorEnd();
522  ++node_iter)
523  {
524  // Note that we define this vector before setting it as otherwise the profiling build will break (see #2367)
525  c_vector<double, SPACE_DIM> location;
526  location = node_iter->rGetLocation();
527 
528  for (unsigned d=d0; d<SPACE_DIM; d++)
529  {
530  if (location[d] < (domain_boundary[2*d] + mMinimumNodeDomainBoundarySeparation) || location[d] > (domain_boundary[2*d+1] - mMinimumNodeDomainBoundarySeparation))
531  {
532  is_local_node_close = 1;
533  break;
534  }
535  }
536  if (is_local_node_close)
537  {
538  break; // Saves checking every node if we find one close to the boundary
539  }
540  }
541 
542  // Synchronise between processes
543  int is_any_node_close = 0;
544  MPI_Allreduce(&is_local_node_close, &is_any_node_close, 1, MPI_INT, MPI_SUM, PetscTools::GetWorld());
545 
546  return (is_any_node_close > 0);
547 }
548 
549 template<unsigned SPACE_DIM>
551 {
552  if (mpBoxCollection)
553  {
554  delete mpBoxCollection;
555  }
556  mpBoxCollection = nullptr;
557 }
558 
559 template<unsigned SPACE_DIM>
560 void NodesOnlyMesh<SPACE_DIM>::SetInitialBoxCollection(const c_vector<double, 2*SPACE_DIM> domainSize, double maxInteractionDistance)
561 {
562  this->SetUpBoxCollection(maxInteractionDistance, domainSize);
563 }
564 
565 template<unsigned SPACE_DIM>
567 {
568  ClearBoxCollection();
569 
570  ChasteCuboid<SPACE_DIM> bounding_box = this->CalculateBoundingBox(rNodes);
571 
572  c_vector<double, 2*SPACE_DIM> domain_size;
573  for (unsigned i=0; i < SPACE_DIM; i++)
574  {
575  domain_size[2*i] = bounding_box.rGetLowerCorner()[i] - 1e-14;
576  domain_size[2*i+1] = bounding_box.rGetUpperCorner()[i] + 1e-14;
577  }
578 
579  SetUpBoxCollection(mMaximumInteractionDistance, domain_size);
580 }
581 
582 template<unsigned SPACE_DIM>
583 void NodesOnlyMesh<SPACE_DIM>::SetUpBoxCollection(double cutOffLength, c_vector<double, 2*SPACE_DIM> domainSize, int numLocalRows, bool isPeriodic)
584 {
585  ClearBoxCollection();
586 
587  mpBoxCollection = new DistributedBoxCollection<SPACE_DIM>(cutOffLength, domainSize, isPeriodic, numLocalRows);
588  mpBoxCollection->SetupLocalBoxesHalfOnly();
589  mpBoxCollection->SetCalculateNodeNeighbours(mCalculateNodeNeighbours);
590 }
591 
592 template<unsigned SPACE_DIM>
594 {
595  // Put the nodes in the boxes.
596  for (typename AbstractMesh<SPACE_DIM, SPACE_DIM>::NodeIterator node_iter = this->GetNodeIteratorBegin();
597  node_iter != this->GetNodeIteratorEnd();
598  ++node_iter)
599  {
600  unsigned box_index = mpBoxCollection->CalculateContainingBox(&(*node_iter));
601  mpBoxCollection->rGetBox(box_index).AddNode(&(*node_iter));
602  }
603 }
604 
605 template<unsigned SPACE_DIM>
607 {
608  // Add halo nodes
609  for (typename std::vector<boost::shared_ptr<Node<SPACE_DIM> > >::iterator halo_node_iter = mHaloNodes.begin();
610  halo_node_iter != mHaloNodes.end();
611  ++halo_node_iter)
612  {
613  unsigned box_index = mpBoxCollection->CalculateContainingBox((*halo_node_iter).get());
614  mpBoxCollection->rGetHaloBox(box_index).AddNode((*halo_node_iter).get());
615  }
616 }
617 
618 template<unsigned SPACE_DIM>
620 {
621  assert(mpBoxCollection);
622 
623  // Remove node pointers from boxes in BoxCollection.
624  mpBoxCollection->EmptyBoxes();
625 
626  AddNodesToBoxes();
627 
628  mpBoxCollection->UpdateHaloBoxes();
629 }
630 
631 template<unsigned SPACE_DIM>
633 {
634  if (!mpBoxCollection)
635  {
636  SetUpBoxCollection(this->mNodes);
637  }
638 
639  while (IsANodeCloseToDomainBoundary())
640  {
641  EnlargeBoxCollection();
642  }
643 }
644 
645 template<unsigned SPACE_DIM>
647 {
648  std::vector<int> local_node_distribution = mpBoxCollection->CalculateNumberOfNodesInEachStrip();
649 
650  unsigned new_rows = mpBoxCollection->LoadBalance(local_node_distribution);
651 
652  c_vector<double, 2*SPACE_DIM> current_domain_size = mpBoxCollection->rGetDomainSize();
653 
654  // This ensures the domain will stay the same size.
655  double fudge = 1e-14;
656  for (unsigned d=0; d < SPACE_DIM; d++)
657  {
658  current_domain_size[2*d] = current_domain_size[2*d] + fudge;
659  current_domain_size[2*d+1] = current_domain_size[2*d+1] - fudge;
660  }
661  SetUpBoxCollection(mMaximumInteractionDistance, current_domain_size, new_rows);
662 }
663 
664 template<unsigned SPACE_DIM>
666 {
668 
669  // Set the correct global node indices
670  for (unsigned i=0; i<this->mNodes.size(); i++)
671  {
672  this->mNodes[i]->SetIndex(GetNextAvailableIndex());
673  }
674 }
675 
676 template<unsigned SPACE_DIM>
677 std::vector<unsigned> NodesOnlyMesh<SPACE_DIM>::GetAllNodeIndices() const
678 {
679  std::vector<unsigned> indices(GetNumNodes()); // GetNumNodes = mNodes - mDeletedNodes
680  unsigned live_index=0;
681  for (unsigned i=0; i<this->mNodes.size(); i++)
682  {
683  // Only use nodes which are not deleted
684  if (!this->mNodes[i]->IsDeleted())
685  {
686  indices[live_index] = this->mNodes[i]->GetIndex();
687  live_index++;
688  }
689  }
690  return indices;
691 }
692 
693 // Explicit instantiation
694 template class NodesOnlyMesh<1>;
695 template class NodesOnlyMesh<2>;
696 template class NodesOnlyMesh<3>;
697 
698 // Serialization for Boost >= 1.36
bool IsANodeCloseToDomainBoundary()
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
void LoadBalanceMesh()
void AddNodeAttribute(double attribute)
Definition: Node.cpp:170
void SetRadius(double radius)
Definition: Node.cpp:256
std::vector< bool > & rGetInitiallyOwnedNodes()
#define EXCEPTION(message)
Definition: Exception.hpp:143
Node< SPACE_DIM > * GetNodeOrHaloNode(unsigned index) const
std::vector< unsigned > GetAllNodeIndices() const
static bool AmMaster()
Definition: PetscTools.cpp:120
void ConstructFromMeshReader(AbstractMeshReader< SPACE_DIM, SPACE_DIM > &rMeshReader)
void ConstructFromMeshReader(AbstractMeshReader< ELEMENT_DIM, SPACE_DIM > &rMeshReader)
void AddNodeWithFixedIndex(Node< SPACE_DIM > *pNewNode)
void ResetToIdentity()
Definition: NodeMap.cpp:57
static MPI_Comm GetWorld()
Definition: PetscTools.cpp:174
void SetIndex(unsigned index)
Definition: Node.cpp:121
std::vector< double > & rGetNodeAttributes()
Definition: Node.cpp:178
void SetUpBoxCollection(const std::vector< Node< SPACE_DIM > * > &rNodes)
std::vector< unsigned > & rGetHaloNodesToSendRight()
const ChastePoint< SPACE_DIM > & rGetUpperCorner() 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)
double GetWidth(const unsigned &rDimension) const
void SetIsParticle(bool isParticle)
Definition: Node.cpp:240
double GetMaximumInteractionDistance()
void DeleteMovedNode(unsigned index)
unsigned GetNextAvailableIndex()
void RemoveDeletedNodes(NodeMap &map)
void ResizeBoxCollection()
void SetDeleted(unsigned index)
Definition: NodeMap.cpp:76
unsigned SolveNodeMapping(unsigned index) const
void SetInitialBoxCollection(const c_vector< double, 2 *SPACE_DIM > domainSize, double maxInteractionDistance)
void SetMaximumInteractionDistance(double maxDistance)
void UpdateBoxCollection()
void AddHaloNode(boost::shared_ptr< Node< SPACE_DIM > > pNewNode)
void CalculateNodesOutsideLocalDomain()
void ConstructNodesWithoutMesh(const std::vector< Node< SPACE_DIM > * > &rNodes, double maxInteractionDistance)
void SetRegion(unsigned region)
Definition: Node.cpp:430
void SetMinimumNodeDomainBoundarySeparation(double separation)
unsigned AddNode(Node< SPACE_DIM > *pNewNode)
DistributedBoxCollection< SPACE_DIM > * GetBoxCollection()
std::vector< unsigned > & rGetNodesToSendRight()
virtual double GetWidth(const unsigned &rDimension) const
void CalculateBoundaryNodePairs(std::vector< std::pair< Node< SPACE_DIM > *, Node< SPACE_DIM > * > > &rNodePairs)
static bool AmTopMost()
Definition: PetscTools.cpp:126
void AddNodesToBoxes()
bool IsOwned(c_vector< double, SPACE_DIM > &location)
static unsigned GetNumProcs()
Definition: PetscTools.cpp:108
void ClearBoxCollection()
unsigned GetIndex() const
Definition: Node.cpp:158
static unsigned GetMyRank()
Definition: PetscTools.cpp:114
void UpdateNodeIndices()
void AddMovedNode(boost::shared_ptr< Node< SPACE_DIM > > pMovedNode)
virtual ~NodesOnlyMesh()
double GetRadius()
Definition: Node.cpp:248
unsigned GetNumNodes() const
const ChastePoint< SPACE_DIM > & rGetLowerCorner() const