36 #include "PottsMesh.hpp"
37 #include "RandomNumberGenerator.hpp"
42 template<
unsigned DIM>
45 std::vector< std::set<unsigned> > vonNeumannNeighbouringNodeIndices,
46 std::vector< std::set<unsigned> > mooreNeighbouringNodeIndices)
52 if ( (vonNeumannNeighbouringNodeIndices.size() != nodes.size()) || (mooreNeighbouringNodeIndices.size() != nodes.size()) )
54 EXCEPTION(
"Nodes and neighbour information for a Potts mesh need to be the same length.");
56 mVonNeumannNeighbouringNodeIndices = vonNeumannNeighbouringNodeIndices;
57 mMooreNeighbouringNodeIndices = mooreNeighbouringNodeIndices;
60 for (
unsigned node_index=0; node_index<nodes.size(); node_index++)
62 Node<DIM>* p_temp_node = nodes[node_index];
63 this->mNodes.push_back(p_temp_node);
65 for (
unsigned elem_index=0; elem_index<pottsElements.size(); elem_index++)
68 mElements.push_back(p_temp_element);
72 for (
unsigned index=0; index<mElements.size(); index++)
76 unsigned element_index = p_element->
GetIndex();
77 unsigned num_nodes_in_element = p_element->
GetNumNodes();
79 for (
unsigned node_index=0; node_index<num_nodes_in_element; node_index++)
81 p_element->
GetNode(node_index)->AddElement(element_index);
85 this->mMeshChangesDuringSimulation =
true;
88 template<
unsigned DIM>
91 this->mMeshChangesDuringSimulation =
true;
95 template<
unsigned DIM>
101 template<
unsigned DIM>
104 assert(index < this->mNodes.size());
108 template<
unsigned DIM>
111 assert(index < this->mElements.size());
115 template<
unsigned DIM>
121 template<
unsigned DIM>
125 for (
unsigned i=0; i<mElements.size(); i++)
132 for (
unsigned i=0; i<this->mNodes.size(); i++)
134 delete this->mNodes[i];
136 this->mNodes.clear();
138 mDeletedElementIndices.clear();
145 template<
unsigned DIM>
148 return this->mNodes.size();
151 template<
unsigned DIM>
154 return mElements.size() - mDeletedElementIndices.size();
157 template<
unsigned DIM>
160 return mElements.size();
163 template<
unsigned DIM>
166 assert(index < mElements.size());
167 return mElements[index];
170 template<
unsigned DIM>
174 unsigned num_nodes_in_element = p_element->
GetNumNodes();
177 c_vector<double, DIM> centroid = zero_vector<double>(DIM);
179 for (
unsigned local_index=0; local_index<num_nodes_in_element; local_index++)
185 centroid /= num_nodes_in_element;
190 template<
unsigned DIM>
196 return element_volume;
199 template<
unsigned DIM>
203 assert(DIM==2 || DIM==3);
208 double surface_area = 0.0;
209 for (
unsigned node_index=0; node_index< p_element->
GetNumNodes(); node_index++)
211 std::set<unsigned> neighbouring_node_indices = GetVonNeumannNeighbouringNodeIndices(p_element->
GetNode(node_index)->GetIndex());
212 unsigned local_edges = 2*DIM;
213 for (std::set<unsigned>::iterator iter = neighbouring_node_indices.begin();
214 iter != neighbouring_node_indices.end();
217 std::set<unsigned> neighbouring_node_element_indices = this->mNodes[*iter]->rGetContainingElementIndices();
219 if (!(neighbouring_node_element_indices.empty()) && (local_edges!=0))
221 unsigned neighbouring_node_element_index = *(neighbouring_node_element_indices.begin());
222 if (neighbouring_node_element_index == index)
228 surface_area += local_edges;
233 template<
unsigned DIM>
236 return mMooreNeighbouringNodeIndices[nodeIndex];
239 template<
unsigned DIM>
242 return mVonNeumannNeighbouringNodeIndices[nodeIndex];
245 template<
unsigned DIM>
249 this->mElements[index]->MarkAsDeleted();
250 mDeletedElementIndices.push_back(index);
253 template<
unsigned DIM>
257 unsigned num_deleted_elements = mDeletedElementIndices.size();
259 for (
unsigned index = num_deleted_elements; index>0; index--)
261 unsigned deleted_elem_index = mDeletedElementIndices[index-1];
262 delete mElements[deleted_elem_index];
263 mElements.erase(mElements.begin()+deleted_elem_index);
264 for (
unsigned elem_index=deleted_elem_index; elem_index<mElements.size(); elem_index++)
266 mElements[elem_index]->ResetIndex(elem_index);
269 mDeletedElementIndices.clear();
273 template<
unsigned DIM>
277 this->mNodes[index]->MarkAsDeleted();
280 std::set<unsigned> containing_element_indices = this->mNodes[index]->rGetContainingElementIndices();
282 for (std::set<unsigned>::iterator iter = containing_element_indices.begin();
283 iter != containing_element_indices.end();
286 assert(mElements[*iter]->GetNumNodes() > 0);
287 if (mElements[*iter]->GetNumNodes() == 1)
289 DeleteElement(*iter);
293 this->mElements[*iter]->DeleteNode(this->mElements[*iter]->GetNodeLocalIndex(index));
298 mVonNeumannNeighbouringNodeIndices[index].clear();
299 mMooreNeighbouringNodeIndices[index].clear();
301 assert(mVonNeumannNeighbouringNodeIndices.size()==mMooreNeighbouringNodeIndices.size());
302 for (
unsigned node_index = 0;
303 node_index < mVonNeumannNeighbouringNodeIndices.size();
307 mVonNeumannNeighbouringNodeIndices[node_index].erase(index);
308 mMooreNeighbouringNodeIndices[node_index].erase(index);
311 if (!this->mNodes[node_index]->IsDeleted())
313 assert(!mVonNeumannNeighbouringNodeIndices[node_index].empty());
314 assert(!mMooreNeighbouringNodeIndices[node_index].empty());
319 delete this->mNodes[index];
320 this->mNodes.erase(this->mNodes.begin()+index);
321 unsigned num_nodes = GetNumNodes();
322 mVonNeumannNeighbouringNodeIndices.erase(mVonNeumannNeighbouringNodeIndices.begin()+index);
323 mMooreNeighbouringNodeIndices.erase(mMooreNeighbouringNodeIndices.begin()+index);
325 assert(mVonNeumannNeighbouringNodeIndices.size()==num_nodes);
326 assert(mMooreNeighbouringNodeIndices.size()==num_nodes);
328 for (
unsigned node_index = 0; node_index < num_nodes; node_index++)
331 if (node_index >= index)
333 assert(this->mNodes[node_index]->GetIndex() == node_index+1);
334 this->mNodes[node_index]->SetIndex(node_index);
336 assert(this->mNodes[node_index]->GetIndex() == node_index);
340 std::set<unsigned> von_neuman = mVonNeumannNeighbouringNodeIndices[node_index];
341 mVonNeumannNeighbouringNodeIndices[node_index].clear();
342 for (std::set<unsigned>::iterator iter = von_neuman.begin();
343 iter != von_neuman.end();
348 mVonNeumannNeighbouringNodeIndices[node_index].insert(*iter-1);
352 mVonNeumannNeighbouringNodeIndices[node_index].insert(*iter);
355 std::set<unsigned> moore = mMooreNeighbouringNodeIndices[node_index];
356 mMooreNeighbouringNodeIndices[node_index].clear();
357 for (std::set<unsigned>::iterator iter = moore.begin();
363 mMooreNeighbouringNodeIndices[node_index].insert(*iter-1);
367 mMooreNeighbouringNodeIndices[node_index].insert(*iter);
372 assert(mDeletedElementIndices.size() <= 1);
373 if (mDeletedElementIndices.size() == 1)
375 unsigned deleted_elem_index = mDeletedElementIndices[0];
376 delete mElements[deleted_elem_index];
377 mElements.erase(mElements.begin()+deleted_elem_index);
378 mDeletedElementIndices.clear();
380 for (
unsigned elem_index=deleted_elem_index; elem_index<GetNumElements(); elem_index++)
382 mElements[elem_index]->ResetIndex(elem_index);
387 template<
unsigned DIM>
389 bool placeOriginalElementBelow)
392 assert(DIM==2 || DIM==3);
399 EXCEPTION(
"Tried to divide a Potts element with only one node. Cell dividing too often given dynamic parameters.");
403 std::vector<Node<DIM>*> nodes_elem;
404 for (
unsigned i=0; i<num_nodes; i++)
406 nodes_elem.push_back(pElement->
GetNode(i));
410 unsigned new_element_index;
411 if (mDeletedElementIndices.empty())
413 new_element_index = this->mElements.size();
417 new_element_index = mDeletedElementIndices.back();
418 mDeletedElementIndices.pop_back();
419 delete this->mElements[new_element_index];
430 unsigned half_num_nodes = num_nodes/2;
431 assert(half_num_nodes > 0);
432 assert(half_num_nodes < num_nodes);
436 double height_midpoint_1 = 0.0;
437 double height_midpoint_2 = 0.0;
438 unsigned counter_1 = 0;
439 unsigned counter_2 = 0;
441 for (
unsigned i=0; i<num_nodes; i++)
443 if (i<half_num_nodes)
445 height_midpoint_1 += pElement->
GetNode(i)->rGetLocation()[DIM - 1];
450 height_midpoint_2 += pElement->
GetNode(i)->rGetLocation()[DIM -1];
454 height_midpoint_1 /= (
double)counter_1;
455 height_midpoint_2 /= (
double)counter_2;
457 for (
unsigned i=num_nodes; i>0; i--)
459 if (i-1 >= half_num_nodes)
461 if (height_midpoint_1 < height_midpoint_2)
463 if (placeOriginalElementBelow)
469 this->mElements[new_element_index]->DeleteNode(i-1);
474 if (placeOriginalElementBelow)
476 this->mElements[new_element_index]->DeleteNode(i-1);
486 if (height_midpoint_1 < height_midpoint_2)
488 if (placeOriginalElementBelow)
490 this->mElements[new_element_index]->DeleteNode(i-1);
499 if (placeOriginalElementBelow)
505 this->mElements[new_element_index]->DeleteNode(i-1);
511 return new_element_index;
514 template<
unsigned DIM>
517 unsigned new_element_index = pNewElement->
GetIndex();
519 if (new_element_index == this->mElements.size())
521 this->mElements.push_back(pNewElement);
525 this->mElements[new_element_index] = pNewElement;
531 template<
unsigned DIM>
538 std::set<unsigned> neighbouring_element_indices;
541 for (
unsigned local_index=0; local_index<p_element->
GetNumNodes(); local_index++)
549 std::set<unsigned> neighbouring_node_indices = GetVonNeumannNeighbouringNodeIndices(p_node->
GetIndex());
552 for (std::set<unsigned>::iterator neighbour_iter = neighbouring_node_indices.begin();
553 neighbour_iter != neighbouring_node_indices.end();
556 std::set<unsigned> neighbouring_node_containing_elem_indices = this->GetNode(*neighbour_iter)->rGetContainingElementIndices();
558 assert(neighbouring_node_containing_elem_indices.size()<2);
560 if (neighbouring_node_containing_elem_indices.size()==1)
563 neighbouring_element_indices.insert(*(neighbouring_node_containing_elem_indices.begin()));
569 neighbouring_element_indices.erase(elementIndex);
571 return neighbouring_element_indices;
574 template<
unsigned DIM>
584 this->mNodes.reserve(num_nodes);
589 std::vector<double> node_data;
590 for (
unsigned i=0; i<num_nodes; i++)
593 unsigned is_boundary_node = (
bool) node_data[DIM];
594 node_data.pop_back();
595 this->mNodes.push_back(
new Node<DIM>(i, node_data, is_boundary_node));
604 for (
unsigned elem_index=0; elem_index<num_elements; elem_index++)
610 std::vector<Node<DIM>*> nodes;
611 unsigned num_nodes_in_element = element_data.
NodeIndices.size();
612 for (
unsigned j=0; j<num_nodes_in_element; j++)
614 assert(element_data.
NodeIndices[j] < this->mNodes.size());
615 nodes.push_back(this->mNodes[element_data.
NodeIndices[j]]);
620 mElements.push_back(p_element);
631 if (mVonNeumannNeighbouringNodeIndices.empty())
633 mVonNeumannNeighbouringNodeIndices.resize(num_nodes);
635 if (mMooreNeighbouringNodeIndices.empty())
637 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