36 #include "PottsMesh.hpp"
37 #include "RandomNumberGenerator.hpp"
40 template<
unsigned DIM>
43 std::vector<std::set<unsigned> > vonNeumannNeighbouringNodeIndices,
44 std::vector<std::set<unsigned> > mooreNeighbouringNodeIndices)
50 if ((vonNeumannNeighbouringNodeIndices.size() != nodes.size()) || (mooreNeighbouringNodeIndices.size() != nodes.size()))
52 EXCEPTION(
"Nodes and neighbour information for a Potts mesh need to be the same length.");
54 mVonNeumannNeighbouringNodeIndices = vonNeumannNeighbouringNodeIndices;
55 mMooreNeighbouringNodeIndices = mooreNeighbouringNodeIndices;
58 for (
unsigned node_index=0; node_index<nodes.size(); node_index++)
60 Node<DIM>* p_temp_node = nodes[node_index];
61 this->mNodes.push_back(p_temp_node);
63 for (
unsigned elem_index=0; elem_index<pottsElements.size(); elem_index++)
66 mElements.push_back(p_temp_element);
70 for (
unsigned index=0; index<mElements.size(); index++)
74 unsigned element_index = p_element->
GetIndex();
75 unsigned num_nodes_in_element = p_element->
GetNumNodes();
77 for (
unsigned node_index=0; node_index<num_nodes_in_element; node_index++)
79 p_element->
GetNode(node_index)->AddElement(element_index);
83 this->mMeshChangesDuringSimulation =
true;
86 template<
unsigned DIM>
89 this->mMeshChangesDuringSimulation =
true;
93 template<
unsigned DIM>
99 template<
unsigned DIM>
102 assert(index < this->mNodes.size());
106 template<
unsigned DIM>
109 assert(index < this->mElements.size());
113 template<
unsigned DIM>
119 template<
unsigned DIM>
123 for (
unsigned i=0; i<mElements.size(); i++)
130 for (
unsigned i=0; i<this->mNodes.size(); i++)
132 delete this->mNodes[i];
134 this->mNodes.clear();
136 mDeletedElementIndices.clear();
143 template<
unsigned DIM>
146 return this->mNodes.size();
149 template<
unsigned DIM>
152 return mElements.size() - mDeletedElementIndices.size();
155 template<
unsigned DIM>
158 return mElements.size();
161 template<
unsigned DIM>
164 assert(index < mElements.size());
165 return mElements[index];
168 template<
unsigned DIM>
172 unsigned num_nodes_in_element = p_element->
GetNumNodes();
175 c_vector<double, DIM> centroid = zero_vector<double>(DIM);
177 for (
unsigned local_index=0; local_index<num_nodes_in_element; local_index++)
183 centroid /= num_nodes_in_element;
188 template<
unsigned DIM>
194 return element_volume;
197 template<
unsigned DIM>
201 assert(DIM==2 || DIM==3);
207 double surface_area = 0.0;
208 for (
unsigned node_index=0; node_index<num_nodes; node_index++)
210 std::set<unsigned> neighbouring_node_indices = GetVonNeumannNeighbouringNodeIndices(p_element->
GetNode(node_index)->GetIndex());
211 unsigned local_edges = 2*DIM;
212 for (std::set<unsigned>::iterator iter = neighbouring_node_indices.begin();
213 iter != neighbouring_node_indices.end();
216 std::set<unsigned> neighbouring_node_element_indices = this->mNodes[*iter]->rGetContainingElementIndices();
218 if (!(neighbouring_node_element_indices.empty()) && (local_edges!=0))
220 unsigned neighbouring_node_element_index = *(neighbouring_node_element_indices.begin());
221 if (neighbouring_node_element_index == index)
227 surface_area += local_edges;
232 template<
unsigned DIM>
235 return mMooreNeighbouringNodeIndices[nodeIndex];
238 template<
unsigned DIM>
241 return mVonNeumannNeighbouringNodeIndices[nodeIndex];
244 template<
unsigned DIM>
248 this->mElements[index]->MarkAsDeleted();
249 mDeletedElementIndices.push_back(index);
252 template<
unsigned DIM>
256 unsigned num_deleted_elements = mDeletedElementIndices.size();
258 for (
unsigned index = num_deleted_elements; index>0; index--)
260 unsigned deleted_elem_index = mDeletedElementIndices[index-1];
261 delete mElements[deleted_elem_index];
262 mElements.erase(mElements.begin()+deleted_elem_index);
263 for (
unsigned elem_index=deleted_elem_index; elem_index<mElements.size(); elem_index++)
265 mElements[elem_index]->ResetIndex(elem_index);
268 mDeletedElementIndices.clear();
271 template<
unsigned DIM>
275 this->mNodes[index]->MarkAsDeleted();
278 std::set<unsigned> containing_element_indices = this->mNodes[index]->rGetContainingElementIndices();
280 for (std::set<unsigned>::iterator iter = containing_element_indices.begin();
281 iter != containing_element_indices.end();
284 assert(mElements[*iter]->GetNumNodes() > 0);
285 if (mElements[*iter]->GetNumNodes() == 1)
287 DeleteElement(*iter);
291 this->mElements[*iter]->DeleteNode(this->mElements[*iter]->GetNodeLocalIndex(index));
296 mVonNeumannNeighbouringNodeIndices[index].clear();
297 mMooreNeighbouringNodeIndices[index].clear();
299 assert(mVonNeumannNeighbouringNodeIndices.size()==mMooreNeighbouringNodeIndices.size());
300 for (
unsigned node_index = 0;
301 node_index < mVonNeumannNeighbouringNodeIndices.size();
305 mVonNeumannNeighbouringNodeIndices[node_index].erase(index);
306 mMooreNeighbouringNodeIndices[node_index].erase(index);
309 if (!this->mNodes[node_index]->IsDeleted())
311 assert(!mVonNeumannNeighbouringNodeIndices[node_index].empty());
312 assert(!mMooreNeighbouringNodeIndices[node_index].empty());
317 delete this->mNodes[index];
318 this->mNodes.erase(this->mNodes.begin()+index);
319 unsigned num_nodes = GetNumNodes();
320 mVonNeumannNeighbouringNodeIndices.erase(mVonNeumannNeighbouringNodeIndices.begin()+index);
321 mMooreNeighbouringNodeIndices.erase(mMooreNeighbouringNodeIndices.begin()+index);
323 assert(mVonNeumannNeighbouringNodeIndices.size()==num_nodes);
324 assert(mMooreNeighbouringNodeIndices.size()==num_nodes);
326 for (
unsigned node_index = 0; node_index < num_nodes; node_index++)
329 if (node_index >= index)
331 assert(this->mNodes[node_index]->GetIndex() == node_index+1);
332 this->mNodes[node_index]->SetIndex(node_index);
334 assert(this->mNodes[node_index]->GetIndex() == node_index);
338 std::set<unsigned> von_neuman = mVonNeumannNeighbouringNodeIndices[node_index];
339 mVonNeumannNeighbouringNodeIndices[node_index].clear();
340 for (std::set<unsigned>::iterator iter = von_neuman.begin();
341 iter != von_neuman.end();
346 mVonNeumannNeighbouringNodeIndices[node_index].insert(*iter-1);
350 mVonNeumannNeighbouringNodeIndices[node_index].insert(*iter);
353 std::set<unsigned> moore = mMooreNeighbouringNodeIndices[node_index];
354 mMooreNeighbouringNodeIndices[node_index].clear();
355 for (std::set<unsigned>::iterator iter = moore.begin();
361 mMooreNeighbouringNodeIndices[node_index].insert(*iter-1);
365 mMooreNeighbouringNodeIndices[node_index].insert(*iter);
370 assert(mDeletedElementIndices.size() <= 1);
371 if (mDeletedElementIndices.size() == 1)
373 unsigned deleted_elem_index = mDeletedElementIndices[0];
374 delete mElements[deleted_elem_index];
375 mElements.erase(mElements.begin()+deleted_elem_index);
376 mDeletedElementIndices.clear();
378 for (
unsigned elem_index=deleted_elem_index; elem_index<GetNumElements(); elem_index++)
380 mElements[elem_index]->ResetIndex(elem_index);
385 template<
unsigned DIM>
387 bool placeOriginalElementBelow)
390 assert(DIM==2 || DIM==3);
397 EXCEPTION(
"Tried to divide a Potts element with only one node. Cell dividing too often given dynamic parameters.");
401 std::vector<Node<DIM>*> nodes_elem;
402 for (
unsigned i=0; i<num_nodes; i++)
404 nodes_elem.push_back(pElement->
GetNode(i));
408 unsigned new_element_index;
409 if (mDeletedElementIndices.empty())
411 new_element_index = this->mElements.size();
415 new_element_index = mDeletedElementIndices.back();
416 mDeletedElementIndices.pop_back();
417 delete this->mElements[new_element_index];
428 unsigned half_num_nodes = num_nodes/2;
429 assert(half_num_nodes > 0);
430 assert(half_num_nodes < num_nodes);
434 double height_midpoint_1 = 0.0;
435 double height_midpoint_2 = 0.0;
436 unsigned counter_1 = 0;
437 unsigned counter_2 = 0;
439 for (
unsigned i=0; i<num_nodes; i++)
441 if (i<half_num_nodes)
443 height_midpoint_1 += pElement->
GetNode(i)->rGetLocation()[DIM - 1];
448 height_midpoint_2 += pElement->
GetNode(i)->rGetLocation()[DIM -1];
452 height_midpoint_1 /= (
double)counter_1;
453 height_midpoint_2 /= (
double)counter_2;
455 for (
unsigned i=num_nodes; i>0; i--)
457 if (i-1 >= half_num_nodes)
459 if (height_midpoint_1 < height_midpoint_2)
461 if (placeOriginalElementBelow)
467 this->mElements[new_element_index]->DeleteNode(i-1);
472 if (placeOriginalElementBelow)
474 this->mElements[new_element_index]->DeleteNode(i-1);
484 if (height_midpoint_1 < height_midpoint_2)
486 if (placeOriginalElementBelow)
488 this->mElements[new_element_index]->DeleteNode(i-1);
497 if (placeOriginalElementBelow)
503 this->mElements[new_element_index]->DeleteNode(i-1);
509 return new_element_index;
512 template<
unsigned DIM>
515 unsigned new_element_index = pNewElement->
GetIndex();
517 if (new_element_index == this->mElements.size())
519 this->mElements.push_back(pNewElement);
523 this->mElements[new_element_index] = pNewElement;
529 template<
unsigned DIM>
537 std::set<unsigned> neighbouring_element_indices;
540 for (
unsigned local_index=0; local_index<num_nodes; local_index++)
548 std::set<unsigned> neighbouring_node_indices = GetVonNeumannNeighbouringNodeIndices(p_node->
GetIndex());
551 for (std::set<unsigned>::iterator neighbour_iter = neighbouring_node_indices.begin();
552 neighbour_iter != neighbouring_node_indices.end();
555 std::set<unsigned> neighbouring_node_containing_elem_indices = this->GetNode(*neighbour_iter)->rGetContainingElementIndices();
557 assert(neighbouring_node_containing_elem_indices.size()<2);
559 if (neighbouring_node_containing_elem_indices.size()==1)
562 neighbouring_element_indices.insert(*(neighbouring_node_containing_elem_indices.begin()));
568 neighbouring_element_indices.erase(elementIndex);
570 return neighbouring_element_indices;
573 template<
unsigned DIM>
583 this->mNodes.reserve(num_nodes);
588 std::vector<double> node_data;
589 for (
unsigned i=0; i<num_nodes; i++)
592 unsigned is_boundary_node = (
bool) node_data[DIM];
593 node_data.pop_back();
594 this->mNodes.push_back(
new Node<DIM>(i, node_data, is_boundary_node));
603 for (
unsigned elem_index=0; elem_index<num_elements; elem_index++)
609 std::vector<Node<DIM>*> nodes;
610 unsigned num_nodes_in_element = element_data.
NodeIndices.size();
611 for (
unsigned j=0; j<num_nodes_in_element; j++)
613 assert(element_data.
NodeIndices[j] < this->mNodes.size());
614 nodes.push_back(this->mNodes[element_data.
NodeIndices[j]]);
619 mElements.push_back(p_element);
630 if (mVonNeumannNeighbouringNodeIndices.empty())
632 mVonNeumannNeighbouringNodeIndices.resize(num_nodes);
634 if (mMooreNeighbouringNodeIndices.empty())
636 mMooreNeighbouringNodeIndices.resize(num_nodes);
unsigned AddElement(PottsElement< DIM > *pNewElement)
unsigned SolveBoundaryElementMapping(unsigned index) const
void SetAttribute(double attribute)
virtual ElementData GetNextElementData()=0
void DeleteNode(unsigned index)
void DeleteElement(unsigned index)
virtual double GetVolumeOfElement(unsigned index)
void ConstructFromMeshReader(AbstractMeshReader< DIM, DIM > &rMeshReader)
#define EXCEPTION(message)
void RemoveDeletedElements()
std::set< unsigned > GetVonNeumannNeighbouringNodeIndices(unsigned nodeIndex)
unsigned GetNumAllElements() const
std::set< unsigned > GetMooreNeighbouringNodeIndices(unsigned nodeIndex)
unsigned SolveElementMapping(unsigned index) const
unsigned DivideElement(PottsElement< DIM > *pElement, bool placeOriginalElementBelow=false)
std::vector< unsigned > NodeIndices
Node< SPACE_DIM > * GetNode(unsigned localIndex) const
virtual bool HasNodePermutation()
virtual c_vector< double, DIM > GetCentroidOfElement(unsigned index)
virtual unsigned GetNumNodes() const
#define EXPORT_TEMPLATE_CLASS_SAME_DIMS(CLASS)
virtual unsigned GetNumElements() const =0
unsigned GetNumNodes() const
virtual double GetSurfaceAreaOfElement(unsigned index)
std::set< unsigned > GetNeighbouringElementIndices(unsigned elementIndex)
virtual unsigned GetNumElementAttributes() const
PottsElement< DIM > * GetElement(unsigned index) const
virtual unsigned GetNumElements() const
unsigned GetIndex() const
unsigned SolveNodeMapping(unsigned index) const
void DeleteNode(const unsigned &rIndex)
double GetNodeLocation(unsigned localIndex, unsigned dimension) const
virtual std::vector< double > GetNextNode()=0
unsigned GetIndex() const
virtual unsigned GetNumNodes() const =0