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(NULL),
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 mLocalInitialNodes[i] =
true;
79 assert(!rNodes[i]->IsDeleted());
80 c_vector<double, SPACE_DIM> location = rNodes[i]->rGetLocation();
85 this->mNodes.push_back(p_node_copy);
88 mNodesMapping[p_node_copy->
GetIndex()] = this->mNodes.size()-1;
93 template<
unsigned SPACE_DIM>
96 ConstructNodesWithoutMesh(rGeneratingMesh.
mNodes, maxInteractionDistance);
99 template<
unsigned SPACE_DIM>
102 return mLocalInitialNodes;
105 template<
unsigned SPACE_DIM>
108 std::map<unsigned, unsigned>::const_iterator node_position = mNodesMapping.find(index);
110 if (node_position == mNodesMapping.end())
115 return node_position->second;
118 template<
unsigned SPACE_DIM>
125 mNodesMapping.clear();
130 template<
unsigned SPACE_DIM>
133 return mpBoxCollection;
136 template <
unsigned SPACE_DIM>
141 std::map<unsigned, unsigned>::const_iterator node_position = mHaloNodesMapping.find(index);
143 if (node_position != mHaloNodesMapping.end())
145 p_node = mHaloNodes[node_position->second].get();
149 p_node = this->GetNode(index);
152 assert(p_node != NULL);
157 template<
unsigned SPACE_DIM>
160 return mpBoxCollection->IsOwned(location);
163 template<
unsigned SPACE_DIM>
166 return this->mNodes.size() - this->mDeletedNodeIndices.size();
169 template<
unsigned SPACE_DIM>
175 template<
unsigned SPACE_DIM>
178 mMaximumInteractionDistance = maxDistance;
181 template<
unsigned SPACE_DIM>
184 return mMaximumInteractionDistance;
187 template<
unsigned SPACE_DIM>
198 template<
unsigned SPACE_DIM>
201 mCalculateNodeNeighbours = calculateNodeNeighbours;
204 template<
unsigned SPACE_DIM>
207 assert(mpBoxCollection);
209 mpBoxCollection->CalculateInteriorNodePairs(this->mNodes, rNodePairs, rNodeNeighbours);
212 template<
unsigned SPACE_DIM>
215 assert(mpBoxCollection);
217 mpBoxCollection->CalculateBoundaryNodePairs(this->mNodes, rNodePairs, rNodeNeighbours);
220 template<
unsigned SPACE_DIM>
225 RemoveDeletedNodes(map);
227 this->mDeletedNodeIndices.clear();
228 this->mAddedNodes =
false;
232 this->SetMeshHasChangedSinceLoading();
235 template<
unsigned SPACE_DIM>
238 typename std::vector<Node<SPACE_DIM>* >::iterator node_iter = this->mNodes.begin();
239 while (node_iter != this->mNodes.end())
241 if ((*node_iter)->IsDeleted())
245 mNodesMapping.erase((*node_iter)->GetIndex());
249 node_iter = this->mNodes.erase(node_iter);
258 template<
unsigned SPACE_DIM>
261 mNodesMapping.clear();
262 for (
unsigned location_in_vector=0; location_in_vector < this->mNodes.size(); location_in_vector++)
264 unsigned global_index = this->mNodes[location_in_vector]->GetIndex();
265 mNodesMapping[global_index] = location_in_vector;
269 template<
unsigned SPACE_DIM>
272 mNodesToSendRight.clear();
273 mNodesToSendLeft.clear();
276 node_iter != this->GetNodeIteratorEnd();
279 unsigned owning_process = mpBoxCollection->GetProcessOwningNode(&(*node_iter));
286 mNodesToSendRight.push_back(node_iter->GetIndex());
290 mNodesToSendLeft.push_back(node_iter->GetIndex());
295 template<
unsigned SPACE_DIM>
298 return mNodesToSendLeft;
301 template<
unsigned SPACE_DIM>
304 return mNodesToSendRight;
307 template<
unsigned SPACE_DIM>
310 return mpBoxCollection->rGetHaloNodesRight();
313 template<
unsigned SPACE_DIM>
316 return mpBoxCollection->rGetHaloNodesLeft();
319 template<
unsigned SPACE_DIM>
322 unsigned location_in_nodes_vector = 0;
324 if (this->mDeletedNodeIndices.empty())
326 this->mNodes.push_back(pNewNode);
327 location_in_nodes_vector = this->mNodes.size() - 1;
331 location_in_nodes_vector = this->mDeletedNodeIndices.back();
332 this->mDeletedNodeIndices.pop_back();
333 delete this->mNodes[location_in_nodes_vector];
334 this->mNodes[location_in_nodes_vector] = pNewNode;
337 this->mAddedNodes =
true;
339 mMaxAddedNodeIndex = (pNewNode->
GetIndex() > mMaxAddedNodeIndex) ? pNewNode->
GetIndex() : mMaxAddedNodeIndex;
342 mNodesMapping[pNewNode->
GetIndex()] = location_in_nodes_vector;
348 template<
unsigned SPACE_DIM>
351 mHaloNodes.push_back(pNewNode);
352 mHaloNodesMapping[pNewNode->GetIndex()] = mHaloNodes.size() - 1;
355 template<
unsigned SPACE_DIM>
360 mHaloNodesMapping.clear();
363 template<
unsigned SPACE_DIM>
366 unsigned fresh_global_index = GetNextAvailableIndex();
367 pNewNode->
SetIndex(fresh_global_index);
369 AddNodeWithFixedIndex(pNewNode);
371 return fresh_global_index;
374 template<
unsigned SPACE_DIM>
378 assert(!concreteMove);
381 this->GetNode(nodeIndex)->SetPoint(point);
384 template<
unsigned SPACE_DIM>
388 unsigned index = pMovedNode->GetIndex();
389 c_vector<double, SPACE_DIM> location = pMovedNode->rGetLocation();
393 if (pMovedNode->HasNodeAttributes())
398 unsigned region = pMovedNode->GetRegion();
401 bool is_particle = pMovedNode->IsParticle();
404 for (
unsigned i=0; i<pMovedNode->GetNumNodeAttributes(); i++)
406 double attribute = pMovedNode->rGetNodeAttributes()[i];
411 AddNodeWithFixedIndex(p_node);
414 template<
unsigned SPACE_DIM>
417 if (this->GetNode(index)->IsDeleted())
419 EXCEPTION(
"Trying to delete a deleted node");
422 unsigned local_index = SolveNodeMapping(index);
424 this->mNodes[local_index]->MarkAsDeleted();
425 this->mDeletedNodeIndices.push_back(local_index);
426 mDeletedGlobalNodeIndices.push_back(index);
429 template<
unsigned SPACE_DIM>
435 mDeletedGlobalNodeIndices.pop_back();
438 template<
unsigned SPACE_DIM>
441 assert(!(separation < 0.0));
443 mMinimumNodeDomainBoundarySeparation = separation;
446 template<
unsigned SPACE_DIM>
451 if (!this->mDeletedGlobalNodeIndices.empty())
453 index = this->mDeletedGlobalNodeIndices.back();
454 this->mDeletedGlobalNodeIndices.pop_back();
458 unsigned counter = mIndexCounter;
466 template<
unsigned SPACE_DIM>
469 assert(mpBoxCollection);
471 int num_local_rows = mpBoxCollection->GetNumLocalRows();
474 c_vector<double, 2*SPACE_DIM> current_domain_size = mpBoxCollection->rGetDomainSize();
475 c_vector<double, 2*SPACE_DIM> new_domain_size;
477 double fudge = 1e-14;
478 for (
unsigned d=0; d < SPACE_DIM; d++)
480 new_domain_size[2*d] = current_domain_size[2*d] - (mMaximumInteractionDistance - fudge);
481 new_domain_size[2*d+1] = current_domain_size[2*d+1] + (mMaximumInteractionDistance - fudge);
484 SetUpBoxCollection(mMaximumInteractionDistance, new_domain_size, new_local_rows);
487 template<
unsigned SPACE_DIM>
490 assert(mpBoxCollection);
492 int is_local_node_close = 0;
493 c_vector<double, 2*SPACE_DIM> domain_boundary = mpBoxCollection->rGetDomainSize();
496 node_iter != this->GetNodeIteratorEnd();
500 c_vector<double, SPACE_DIM> location;
501 location = node_iter->rGetLocation();
503 for (
unsigned d=0; d<SPACE_DIM; d++)
505 if (location[d] < (domain_boundary[2*d] + mMinimumNodeDomainBoundarySeparation) || location[d] > (domain_boundary[2*d+1] - mMinimumNodeDomainBoundarySeparation))
507 is_local_node_close = 1;
511 if (is_local_node_close)
518 int is_any_node_close = 0;
519 MPI_Allreduce(&is_local_node_close, &is_any_node_close, 1, MPI_INT, MPI_SUM,
PetscTools::GetWorld());
521 return (is_any_node_close > 0);
524 template<
unsigned SPACE_DIM>
529 delete mpBoxCollection;
531 mpBoxCollection = NULL;
534 template<
unsigned SPACE_DIM>
537 this->SetUpBoxCollection(maxInteractionDistance, domainSize);
540 template<
unsigned SPACE_DIM>
543 ClearBoxCollection();
547 c_vector<double, 2*SPACE_DIM> domain_size;
548 for (
unsigned i=0; i < SPACE_DIM; i++)
554 SetUpBoxCollection(mMaximumInteractionDistance, domain_size);
557 template<
unsigned SPACE_DIM>
560 ClearBoxCollection();
564 mpBoxCollection->SetupHaloBoxes();
565 mpBoxCollection->SetCalculateNodeNeighbours(mCalculateNodeNeighbours);
568 template<
unsigned SPACE_DIM>
573 node_iter != this->GetNodeIteratorEnd();
576 unsigned box_index = mpBoxCollection->CalculateContainingBox(&(*node_iter));
577 mpBoxCollection->rGetBox(box_index).AddNode(&(*node_iter));
581 template<
unsigned SPACE_DIM>
585 for (
typename std::vector<boost::shared_ptr<
Node<SPACE_DIM> > >::iterator halo_node_iter = mHaloNodes.begin();
586 halo_node_iter != mHaloNodes.end();
589 unsigned box_index = mpBoxCollection->CalculateContainingBox((*halo_node_iter).get());
590 mpBoxCollection->rGetHaloBox(box_index).AddNode((*halo_node_iter).get());
594 template<
unsigned SPACE_DIM>
597 assert(mpBoxCollection);
600 mpBoxCollection->EmptyBoxes();
604 mpBoxCollection->UpdateHaloBoxes();
607 template<
unsigned SPACE_DIM>
610 if (!mpBoxCollection)
612 SetUpBoxCollection(this->mNodes);
615 while (IsANodeCloseToDomainBoundary())
617 EnlargeBoxCollection();
621 template<
unsigned SPACE_DIM>
624 std::vector<int> local_node_distribution = mpBoxCollection->CalculateNumberOfNodesInEachStrip();
626 unsigned new_rows = mpBoxCollection->LoadBalance(local_node_distribution);
628 c_vector<double, 2*SPACE_DIM> current_domain_size = mpBoxCollection->rGetDomainSize();
631 double fudge = 1e-14;
632 for (
unsigned d=0; d < SPACE_DIM; d++)
634 current_domain_size[2*d] = current_domain_size[2*d] + fudge;
635 current_domain_size[2*d+1] = current_domain_size[2*d+1] - fudge;
637 SetUpBoxCollection(mMaximumInteractionDistance, current_domain_size, new_rows);
640 template<
unsigned SPACE_DIM>
646 for (
unsigned i=0; i<this->mNodes.size(); i++)
648 this->mNodes[i]->SetIndex(GetNextAvailableIndex());
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
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)
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()
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()
void CalculateBoundaryNodePairs(std::vector< std::pair< Node< SPACE_DIM > *, Node< SPACE_DIM > * > > &rNodePairs, std::map< unsigned, std::set< unsigned > > &rNodeNeighbours)
std::vector< unsigned > & rGetNodesToSendRight()
virtual double GetWidth(const unsigned &rDimension) const
void CalculateInteriorNodePairs(std::vector< std::pair< Node< SPACE_DIM > *, Node< SPACE_DIM > * > > &rNodePairs, std::map< unsigned, std::set< unsigned > > &rNodeNeighbours)
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