37 #include "NodesOnlyMesh.hpp"
38 #include "ChasteCuboid.hpp"
40 template<
unsigned SPACE_DIM>
43 mMaximumInteractionDistance(1.0),
45 mMinimumNodeDomainBoundarySeparation(1.0),
46 mMaxAddedNodeIndex(0u),
47 mpBoxCollection(nullptr),
48 mCalculateNodeNeighbours(true)
52 template<
unsigned SPACE_DIM>
59 template<
unsigned SPACE_DIM>
62 assert(maxInteractionDistance > 0.0 && maxInteractionDistance < DBL_MAX);
63 mMaximumInteractionDistance = maxInteractionDistance;
65 mMinimumNodeDomainBoundarySeparation = mMaximumInteractionDistance;
69 SetUpBoxCollection(rNodes);
71 mLocalInitialNodes.resize(rNodes.size(),
false);
73 for (
unsigned i=0; i<rNodes.size(); i++)
75 if (mpBoxCollection->IsOwned(rNodes[i]))
77 assert(!rNodes[i]->IsDeleted());
79 mLocalInitialNodes[i] =
true;
82 c_vector<double, SPACE_DIM> location = rNodes[i]->rGetLocation();
88 if (rNodes[i]->HasNodeAttributes())
93 this->mNodes.push_back(p_node_copy);
96 mNodesMapping[p_node_copy->
GetIndex()] = this->mNodes.size()-1;
101 template<
unsigned SPACE_DIM>
105 std::vector<Node<SPACE_DIM>*> temp_nodes(rNodes.size());
106 for(
unsigned idx=0; idx<rNodes.size(); idx++)
108 temp_nodes[idx] = rNodes[idx].get();
111 ConstructNodesWithoutMesh(temp_nodes, maxInteractionDistance);
114 template<
unsigned SPACE_DIM>
117 ConstructNodesWithoutMesh(rGeneratingMesh.
mNodes, maxInteractionDistance);
120 template<
unsigned SPACE_DIM>
123 return mLocalInitialNodes;
126 template<
unsigned SPACE_DIM>
129 std::map<unsigned, unsigned>::const_iterator node_position = mNodesMapping.find(index);
131 if (node_position == mNodesMapping.end())
136 return node_position->second;
139 template<
unsigned SPACE_DIM>
146 mNodesMapping.clear();
151 template<
unsigned SPACE_DIM>
154 return mpBoxCollection;
157 template <
unsigned SPACE_DIM>
162 std::map<unsigned, unsigned>::const_iterator node_position = mHaloNodesMapping.find(index);
164 if (node_position != mHaloNodesMapping.end())
166 p_node = mHaloNodes[node_position->second].get();
170 p_node = this->GetNode(index);
173 assert(p_node !=
nullptr);
178 template<
unsigned SPACE_DIM>
181 return mpBoxCollection->IsOwned(location);
184 template<
unsigned SPACE_DIM>
187 return this->mNodes.size() - this->mDeletedNodeIndices.size();
190 template<
unsigned SPACE_DIM>
196 template<
unsigned SPACE_DIM>
199 mMaximumInteractionDistance = maxDistance;
202 template<
unsigned SPACE_DIM>
205 return mMaximumInteractionDistance;
208 template<
unsigned SPACE_DIM>
219 template<
unsigned SPACE_DIM>
222 mCalculateNodeNeighbours = calculateNodeNeighbours;
225 template<
unsigned SPACE_DIM>
228 assert(mpBoxCollection);
230 mpBoxCollection->CalculateInteriorNodePairs(this->mNodes, rNodePairs);
233 template<
unsigned SPACE_DIM>
236 assert(mpBoxCollection);
238 mpBoxCollection->CalculateBoundaryNodePairs(this->mNodes, rNodePairs);
241 template<
unsigned SPACE_DIM>
246 RemoveDeletedNodes(map);
248 this->mDeletedNodeIndices.clear();
249 this->mAddedNodes =
false;
253 this->SetMeshHasChangedSinceLoading();
256 template<
unsigned SPACE_DIM>
259 typename std::vector<Node<SPACE_DIM>* >::iterator node_iter = this->mNodes.begin();
260 while (node_iter != this->mNodes.end())
262 if ((*node_iter)->IsDeleted())
266 mNodesMapping.erase((*node_iter)->GetIndex());
270 node_iter = this->mNodes.erase(node_iter);
279 template<
unsigned SPACE_DIM>
282 mNodesMapping.clear();
283 for (
unsigned location_in_vector=0; location_in_vector < this->mNodes.size(); location_in_vector++)
285 unsigned global_index = this->mNodes[location_in_vector]->GetIndex();
286 mNodesMapping[global_index] = location_in_vector;
290 template<
unsigned SPACE_DIM>
293 mNodesToSendRight.clear();
294 mNodesToSendLeft.clear();
297 node_iter != this->GetNodeIteratorEnd();
300 unsigned owning_process = mpBoxCollection->GetProcessOwningNode(&(*node_iter));
307 mNodesToSendRight.push_back(node_iter->GetIndex());
311 mNodesToSendLeft.push_back(node_iter->GetIndex());
316 template<
unsigned SPACE_DIM>
319 return mNodesToSendLeft;
322 template<
unsigned SPACE_DIM>
325 return mNodesToSendRight;
328 template<
unsigned SPACE_DIM>
331 return mpBoxCollection->rGetHaloNodesRight();
334 template<
unsigned SPACE_DIM>
337 return mpBoxCollection->rGetHaloNodesLeft();
340 template<
unsigned SPACE_DIM>
343 unsigned location_in_nodes_vector = 0;
345 if (this->mDeletedNodeIndices.empty())
347 this->mNodes.push_back(pNewNode);
348 location_in_nodes_vector = this->mNodes.size() - 1;
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;
358 this->mAddedNodes =
true;
360 mMaxAddedNodeIndex = (pNewNode->
GetIndex() > mMaxAddedNodeIndex) ? pNewNode->
GetIndex() : mMaxAddedNodeIndex;
363 mNodesMapping[pNewNode->
GetIndex()] = location_in_nodes_vector;
369 template<
unsigned SPACE_DIM>
372 mHaloNodes.push_back(pNewNode);
373 mHaloNodesMapping[pNewNode->GetIndex()] = mHaloNodes.size() - 1;
376 template<
unsigned SPACE_DIM>
381 mHaloNodesMapping.clear();
384 template<
unsigned SPACE_DIM>
387 unsigned fresh_global_index = GetNextAvailableIndex();
388 pNewNode->
SetIndex(fresh_global_index);
390 AddNodeWithFixedIndex(pNewNode);
392 return fresh_global_index;
395 template<
unsigned SPACE_DIM>
399 assert(!concreteMove);
402 this->GetNode(nodeIndex)->SetPoint(point);
405 template<
unsigned SPACE_DIM>
409 unsigned index = pMovedNode->GetIndex();
410 c_vector<double, SPACE_DIM> location = pMovedNode->rGetLocation();
414 if (pMovedNode->HasNodeAttributes())
419 unsigned region = pMovedNode->GetRegion();
422 bool is_particle = pMovedNode->IsParticle();
425 for (
unsigned i=0; i<pMovedNode->GetNumNodeAttributes(); i++)
427 double attribute = pMovedNode->rGetNodeAttributes()[i];
432 AddNodeWithFixedIndex(p_node);
435 template<
unsigned SPACE_DIM>
438 if (this->GetNode(index)->IsDeleted())
440 EXCEPTION(
"Trying to delete a deleted node");
443 unsigned local_index = SolveNodeMapping(index);
445 this->mNodes[local_index]->MarkAsDeleted();
446 this->mDeletedNodeIndices.push_back(local_index);
447 mDeletedGlobalNodeIndices.push_back(index);
450 template<
unsigned SPACE_DIM>
456 mDeletedGlobalNodeIndices.pop_back();
459 template<
unsigned SPACE_DIM>
462 assert(!(separation < 0.0));
464 mMinimumNodeDomainBoundarySeparation = separation;
467 template<
unsigned SPACE_DIM>
472 if (!this->mDeletedGlobalNodeIndices.empty())
474 index = this->mDeletedGlobalNodeIndices.back();
475 this->mDeletedGlobalNodeIndices.pop_back();
479 unsigned counter = mIndexCounter;
487 template<
unsigned SPACE_DIM>
490 assert(mpBoxCollection);
492 int num_local_rows = mpBoxCollection->GetNumLocalRows();
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;
498 double fudge = 1e-14;
500 unsigned d0 = ( mpBoxCollection->GetIsPeriodicInX() ) ? 1 : 0;
501 for (
unsigned d=d0; d < SPACE_DIM; d++)
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);
506 SetUpBoxCollection(mMaximumInteractionDistance, new_domain_size, new_local_rows);
509 template<
unsigned SPACE_DIM>
512 assert(mpBoxCollection);
514 int is_local_node_close = 0;
515 c_vector<double, 2*SPACE_DIM> domain_boundary = mpBoxCollection->rGetDomainSize();
518 unsigned d0 = ( mpBoxCollection->GetIsPeriodicInX() ) ? 1 : 0;
521 node_iter != this->GetNodeIteratorEnd();
525 c_vector<double, SPACE_DIM> location;
526 location = node_iter->rGetLocation();
528 for (
unsigned d=d0; d<SPACE_DIM; d++)
530 if (location[d] < (domain_boundary[2*d] + mMinimumNodeDomainBoundarySeparation) || location[d] > (domain_boundary[2*d+1] - mMinimumNodeDomainBoundarySeparation))
532 is_local_node_close = 1;
536 if (is_local_node_close)
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());
546 return (is_any_node_close > 0);
549 template<
unsigned SPACE_DIM>
554 delete mpBoxCollection;
556 mpBoxCollection =
nullptr;
559 template<
unsigned SPACE_DIM>
562 this->SetUpBoxCollection(maxInteractionDistance, domainSize);
565 template<
unsigned SPACE_DIM>
568 ClearBoxCollection();
572 c_vector<double, 2*SPACE_DIM> domain_size;
573 for (
unsigned i=0; i < SPACE_DIM; i++)
579 SetUpBoxCollection(mMaximumInteractionDistance, domain_size);
582 template<
unsigned SPACE_DIM>
585 ClearBoxCollection();
589 mpBoxCollection->SetCalculateNodeNeighbours(mCalculateNodeNeighbours);
592 template<
unsigned SPACE_DIM>
597 node_iter != this->GetNodeIteratorEnd();
600 unsigned box_index = mpBoxCollection->CalculateContainingBox(&(*node_iter));
601 mpBoxCollection->rGetBox(box_index).AddNode(&(*node_iter));
605 template<
unsigned SPACE_DIM>
609 for (
typename std::vector<boost::shared_ptr<
Node<SPACE_DIM> > >::iterator halo_node_iter = mHaloNodes.begin();
610 halo_node_iter != mHaloNodes.end();
613 unsigned box_index = mpBoxCollection->CalculateContainingBox((*halo_node_iter).get());
614 mpBoxCollection->rGetHaloBox(box_index).AddNode((*halo_node_iter).get());
618 template<
unsigned SPACE_DIM>
621 assert(mpBoxCollection);
624 mpBoxCollection->EmptyBoxes();
628 mpBoxCollection->UpdateHaloBoxes();
631 template<
unsigned SPACE_DIM>
634 if (!mpBoxCollection)
636 SetUpBoxCollection(this->mNodes);
639 while (IsANodeCloseToDomainBoundary())
641 EnlargeBoxCollection();
645 template<
unsigned SPACE_DIM>
648 std::vector<int> local_node_distribution = mpBoxCollection->CalculateNumberOfNodesInEachStrip();
650 unsigned new_rows = mpBoxCollection->LoadBalance(local_node_distribution);
652 c_vector<double, 2*SPACE_DIM> current_domain_size = mpBoxCollection->rGetDomainSize();
655 double fudge = 1e-14;
656 for (
unsigned d=0; d < SPACE_DIM; d++)
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;
661 SetUpBoxCollection(mMaximumInteractionDistance, current_domain_size, new_rows);
664 template<
unsigned SPACE_DIM>
670 for (
unsigned i=0; i<this->mNodes.size(); i++)
672 this->mNodes[i]->SetIndex(GetNextAvailableIndex());
676 template<
unsigned SPACE_DIM>
679 std::vector<unsigned> indices(GetNumNodes());
680 unsigned live_index=0;
681 for (
unsigned i=0; i<this->mNodes.size(); i++)
684 if (!this->mNodes[i]->IsDeleted())
686 indices[live_index] = this->mNodes[i]->GetIndex();
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)
void AddNodeAttribute(double attribute)
void SetRadius(double radius)
std::vector< bool > & rGetInitiallyOwnedNodes()
#define EXCEPTION(message)
Node< SPACE_DIM > * GetNodeOrHaloNode(unsigned index) const
std::vector< unsigned > GetAllNodeIndices() const
void ConstructFromMeshReader(AbstractMeshReader< SPACE_DIM, SPACE_DIM > &rMeshReader)
void ConstructFromMeshReader(AbstractMeshReader< ELEMENT_DIM, SPACE_DIM > &rMeshReader)
void AddNodeWithFixedIndex(Node< SPACE_DIM > *pNewNode)
void SetIndex(unsigned index)
std::vector< double > & rGetNodeAttributes()
void SetUpBoxCollection(const std::vector< Node< SPACE_DIM > * > &rNodes)
void SetupLocalBoxesHalfOnly()
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)
double GetMaximumInteractionDistance()
void DeleteMovedNode(unsigned index)
unsigned GetNextAvailableIndex()
void RemoveDeletedNodes(NodeMap &map)
void ResizeBoxCollection()
void SetDeleted(unsigned index)
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)
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)
bool IsOwned(c_vector< double, SPACE_DIM > &location)
void ClearBoxCollection()
unsigned GetIndex() const
void AddMovedNode(boost::shared_ptr< Node< SPACE_DIM > > pMovedNode)
unsigned GetNumNodes() const
const ChastePoint< SPACE_DIM > & rGetLowerCorner() const