36 #include "MutableVertexMesh.hpp"
38 #include "LogFile.hpp"
40 #include "Warnings.hpp"
42 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
45 double cellRearrangementThreshold,
47 double cellRearrangementRatio,
48 double protorosetteFormationProbability,
49 double protorosetteResolutionProbabilityPerTimestep,
50 double rosetteResolutionProbabilityPerTimestep)
51 : mCellRearrangementThreshold(cellRearrangementThreshold),
52 mCellRearrangementRatio(cellRearrangementRatio),
53 mT2Threshold(t2Threshold),
54 mProtorosetteFormationProbability(protorosetteFormationProbability),
55 mProtorosetteResolutionProbabilityPerTimestep(protorosetteResolutionProbabilityPerTimestep),
56 mRosetteResolutionProbabilityPerTimestep(rosetteResolutionProbabilityPerTimestep),
57 mCheckForInternalIntersections(false),
58 mDistanceForT3SwapChecking(5.0)
61 assert(cellRearrangementThreshold > 0.0);
62 assert(t2Threshold > 0.0);
63 assert(protorosetteFormationProbability >= 0.0);
64 assert(protorosetteFormationProbability <= 1.0);
65 assert(protorosetteResolutionProbabilityPerTimestep >= 0.0);
66 assert(protorosetteResolutionProbabilityPerTimestep <= 1.0);
67 assert(rosetteResolutionProbabilityPerTimestep >= 0.0);
68 assert(rosetteResolutionProbabilityPerTimestep <= 1.0);
74 for (
unsigned node_index=0; node_index<nodes.size(); node_index++)
77 this->
mNodes.push_back(p_temp_node);
79 for (
unsigned elem_index=0; elem_index<vertexElements.size(); elem_index++)
82 this->
mElements.push_back(p_temp_vertex_element);
89 std::set<unsigned> faces_counted;
92 for (
unsigned elem_index=0; elem_index<this->
mElements.size(); elem_index++)
95 for (
unsigned face_index=0; face_index<this->
mElements[elem_index]->GetNumFaces(); face_index++)
100 if (faces_counted.find(p_face->GetIndex()) == faces_counted.end())
102 this->
mFaces.push_back(p_face);
103 faces_counted.insert(p_face->GetIndex());
110 for (
unsigned index=0; index<this->
mElements.size(); index++)
113 for (
unsigned node_index=0; node_index<p_temp_vertex_element->
GetNumNodes(); node_index++)
123 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
125 : mCellRearrangementThreshold(0.01),
126 mCellRearrangementRatio(1.5),
128 mProtorosetteFormationProbability(0.0),
129 mProtorosetteResolutionProbabilityPerTimestep(0.0),
130 mRosetteResolutionProbabilityPerTimestep(0.0),
131 mCheckForInternalIntersections(false),
132 mDistanceForT3SwapChecking(5.0)
139 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
145 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
148 return mCellRearrangementThreshold;
151 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
157 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
160 return mCellRearrangementRatio;
163 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
166 return this->mProtorosetteFormationProbability;
169 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
172 return this->mProtorosetteResolutionProbabilityPerTimestep;
175 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
178 return this->mRosetteResolutionProbabilityPerTimestep;
181 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
184 mDistanceForT3SwapChecking = distanceForT3SwapChecking;
187 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
190 return mDistanceForT3SwapChecking;
195 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
198 return mCheckForInternalIntersections;
201 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
204 mCellRearrangementThreshold = cellRearrangementThreshold;
207 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
210 mT2Threshold = t2Threshold;
213 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
216 mCellRearrangementRatio = cellRearrangementRatio;
219 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
223 if (protorosetteFormationProbability < 0.0)
225 EXCEPTION(
"Attempting to assign a negative probability.");
227 if (protorosetteFormationProbability > 1.0)
229 EXCEPTION(
"Attempting to assign a probability greater than one.");
233 mProtorosetteFormationProbability = protorosetteFormationProbability;
236 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
240 if (protorosetteResolutionProbabilityPerTimestep < 0.0)
242 EXCEPTION(
"Attempting to assign a negative probability.");
244 if (protorosetteResolutionProbabilityPerTimestep > 1.0)
246 EXCEPTION(
"Attempting to assign a probability greater than one.");
250 mProtorosetteResolutionProbabilityPerTimestep = protorosetteResolutionProbabilityPerTimestep;
253 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
257 if (rosetteResolutionProbabilityPerTimestep < 0.0)
259 EXCEPTION(
"Attempting to assign a negative probability.");
261 if (rosetteResolutionProbabilityPerTimestep > 1.0)
263 EXCEPTION(
"Attempting to assign a probability greater than one.");
267 mRosetteResolutionProbabilityPerTimestep = rosetteResolutionProbabilityPerTimestep;
270 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
273 mCheckForInternalIntersections = checkForInternalIntersections;
276 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
279 mDeletedNodeIndices.clear();
280 mDeletedElementIndices.clear();
285 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
288 return this->mNodes.size() - mDeletedNodeIndices.size();
291 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
294 return this->mElements.size() - mDeletedElementIndices.size();
297 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
300 return mLocationsOfT1Swaps;
303 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
306 return mLastT2SwapLocation;
309 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
312 return mLocationsOfT3Swaps;
315 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
318 mLocationsOfT1Swaps.clear();
321 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
324 mLocationsOfT3Swaps.clear();
327 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
330 if (mDeletedNodeIndices.empty())
332 pNewNode->
SetIndex(this->mNodes.size());
333 this->mNodes.push_back(pNewNode);
337 unsigned index = mDeletedNodeIndices.back();
339 mDeletedNodeIndices.pop_back();
340 delete this->mNodes[index];
341 this->mNodes[index] = pNewNode;
346 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
349 unsigned new_element_index = pNewElement->
GetIndex();
351 if (new_element_index == this->mElements.size())
353 this->mElements.push_back(pNewElement);
357 this->mElements[new_element_index] = pNewElement;
363 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
366 this->mNodes[nodeIndex]->SetPoint(point);
369 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
371 c_vector<double, SPACE_DIM> axisOfDivision,
372 bool placeOriginalElementBelow)
374 assert(SPACE_DIM == 2);
375 assert(ELEMENT_DIM == SPACE_DIM);
378 c_vector<double, SPACE_DIM> centroid = this->GetCentroidOfElement(pElement->
GetIndex());
381 c_vector<double, SPACE_DIM> perp_axis;
382 perp_axis(0) = -axisOfDivision(1);
383 perp_axis(1) = axisOfDivision(0);
391 std::vector<unsigned> intersecting_nodes;
392 bool is_current_node_on_left = (inner_prod(this->GetVectorFromAtoB(pElement->
GetNodeLocation(0), centroid), perp_axis) >= 0);
393 for (
unsigned i=0; i<num_nodes; i++)
395 bool is_next_node_on_left = (inner_prod(this->GetVectorFromAtoB(pElement->
GetNodeLocation((i+1)%num_nodes), centroid), perp_axis) >= 0);
396 if (is_current_node_on_left != is_next_node_on_left)
398 intersecting_nodes.push_back(i);
400 is_current_node_on_left = is_next_node_on_left;
404 if (intersecting_nodes.size() != 2)
406 EXCEPTION(
"Cannot proceed with element division: the given axis of division does not cross two edges of the element");
409 std::vector<unsigned> division_node_global_indices;
410 unsigned nodes_added = 0;
413 for (
unsigned i=0; i<intersecting_nodes.size(); i++)
429 c_vector<double, SPACE_DIM> position_a = p_node_A->
rGetLocation();
430 c_vector<double, SPACE_DIM> position_b = p_node_B->
rGetLocation();
431 c_vector<double, SPACE_DIM> a_to_b = this->GetVectorFromAtoB(position_a, position_b);
433 c_vector<double, SPACE_DIM> intersection;
435 if (norm_2(a_to_b) < 2.0*mCellRearrangementRatio*mCellRearrangementThreshold)
437 WARNING(
"Edge is too small for normal division; putting node in the middle of a and b. There may be T1 swaps straight away.");
439 intersection = position_a + 0.5*a_to_b;
444 double determinant = a_to_b[0]*axisOfDivision[1] - a_to_b[1]*axisOfDivision[0];
447 c_vector<double, SPACE_DIM> moved_centroid;
448 moved_centroid = position_a + this->GetVectorFromAtoB(position_a, centroid);
450 double alpha = (moved_centroid[0]*a_to_b[1] - position_a[0]*a_to_b[1]
451 -moved_centroid[1]*a_to_b[0] + position_a[1]*a_to_b[0])/determinant;
453 intersection = moved_centroid + alpha*axisOfDivision;
459 c_vector<double, SPACE_DIM> a_to_intersection = this->GetVectorFromAtoB(position_a, intersection);
460 if (norm_2(a_to_intersection) < mCellRearrangementThreshold)
462 intersection = position_a + mCellRearrangementRatio*mCellRearrangementThreshold*a_to_b/norm_2(a_to_b);
465 c_vector<double, SPACE_DIM> b_to_intersection = this->GetVectorFromAtoB(position_b, intersection);
466 if (norm_2(b_to_intersection) < mCellRearrangementThreshold)
468 assert(norm_2(a_to_intersection) > mCellRearrangementThreshold);
470 intersection = position_b - mCellRearrangementRatio*mCellRearrangementThreshold*a_to_b/norm_2(a_to_b);
481 bool is_boundary =
false;
484 if (elems_containing_node_A.size() != 2 ||
485 elems_containing_node_B.size() != 2 ||
486 elems_containing_node_A != elems_containing_node_B)
493 unsigned new_node_global_index = this->AddNode(
new Node<SPACE_DIM>(0, is_boundary, intersection[0], intersection[1]));
499 std::set<unsigned> shared_elements;
500 std::set_intersection(elems_containing_node_A.begin(),
501 elems_containing_node_A.end(),
502 elems_containing_node_B.begin(),
503 elems_containing_node_B.end(),
504 std::inserter(shared_elements, shared_elements.begin()));
507 unsigned node_A_index = p_node_A->
GetIndex();
508 unsigned node_B_index = p_node_B->
GetIndex();
509 for (std::set<unsigned>::iterator iter = shared_elements.begin();
510 iter != shared_elements.end();
519 unsigned index = local_indexB;
522 if (local_indexB > local_indexA)
524 index = local_indexA;
527 if ((local_indexA == 0) && (local_indexB == p_element->
GetNumNodes()-1))
529 index = local_indexB;
532 else if ((local_indexB == 0) && (local_indexA == p_element->
GetNumNodes()-1))
535 index = local_indexA;
539 this->GetElement(*iter)->AddNode(this->GetNode(new_node_global_index), index);
543 division_node_global_indices.push_back(new_node_global_index);
547 unsigned new_element_index = DivideElement(pElement,
550 placeOriginalElementBelow);
552 return new_element_index;
555 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
557 bool placeOriginalElementBelow)
559 assert(SPACE_DIM == 2);
560 assert(ELEMENT_DIM == SPACE_DIM);
562 c_vector<double, SPACE_DIM> short_axis = this->GetShortAxisOfElement(pElement->
GetIndex());
564 unsigned new_element_index = DivideElementAlongGivenAxis(pElement, short_axis, placeOriginalElementBelow);
565 return new_element_index;
568 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
572 bool placeOriginalElementBelow)
574 assert(SPACE_DIM == 2);
575 assert(ELEMENT_DIM == SPACE_DIM);
578 assert(nodeBIndex != nodeAIndex);
579 unsigned node1_index = (nodeAIndex < nodeBIndex) ? nodeAIndex : nodeBIndex;
580 unsigned node2_index = (nodeAIndex < nodeBIndex) ? nodeBIndex : nodeAIndex;
586 std::vector<Node<SPACE_DIM>*> nodes_elem;
587 for (
unsigned i=0; i<num_nodes; i++)
589 nodes_elem.push_back(pElement->
GetNode(i));
593 unsigned new_element_index;
594 if (mDeletedElementIndices.empty())
596 new_element_index = this->mElements.size();
600 new_element_index = mDeletedElementIndices.back();
601 mDeletedElementIndices.pop_back();
602 delete this->mElements[new_element_index];
616 double height_midpoint_1 = 0.0;
617 double height_midpoint_2 = 0.0;
618 unsigned counter_1 = 0;
619 unsigned counter_2 = 0;
621 for (
unsigned i=0; i<num_nodes; i++)
623 if (i>=node1_index && i<=node2_index)
625 height_midpoint_1 += pElement->
GetNode(i)->rGetLocation()[1];
628 if (i<=node1_index || i>=node2_index)
630 height_midpoint_2 += pElement->
GetNode(i)->rGetLocation()[1];
634 height_midpoint_1 /= (
double)counter_1;
635 height_midpoint_2 /= (
double)counter_2;
637 for (
unsigned i=num_nodes; i>0; i--)
639 if (i-1 < node1_index || i-1 > node2_index)
641 if (height_midpoint_1 < height_midpoint_2)
643 if (placeOriginalElementBelow)
649 this->mElements[new_element_index]->DeleteNode(i-1);
654 if (placeOriginalElementBelow)
656 this->mElements[new_element_index]->DeleteNode(i-1);
664 else if (i-1 > node1_index && i-1 < node2_index)
666 if (height_midpoint_1 < height_midpoint_2)
668 if (placeOriginalElementBelow)
670 this->mElements[new_element_index]->DeleteNode(i-1);
679 if (placeOriginalElementBelow)
685 this->mElements[new_element_index]->DeleteNode(i-1);
691 return new_element_index;
694 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
697 assert(SPACE_DIM == 2);
700 for (
unsigned i=0; i<this->mElements[index]->GetNumNodes(); i++)
706 DeleteNodePriorToReMesh(p_node->
GetIndex());
714 this->mElements[index]->MarkAsDeleted();
715 mDeletedElementIndices.push_back(index);
718 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
721 this->mNodes[index]->MarkAsDeleted();
722 mDeletedNodeIndices.push_back(index);
725 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
733 std::set<unsigned> shared_elements;
734 std::set_intersection(elements_containing_nodeA.begin(),
735 elements_containing_nodeA.end(),
736 elements_containing_nodeB.begin(),
737 elements_containing_nodeB.end(),
738 std::inserter(shared_elements, shared_elements.begin()));
741 assert(!shared_elements.empty());
742 assert(shared_elements.size()<=2u);
745 bool is_boundary_node =
false;
746 if (shared_elements.size()==1u)
750 is_boundary_node =
true;
759 p_new_node->
SetPoint(new_node_position);
762 this->mNodes.push_back(p_new_node);
765 unsigned node_A_index = pNodeA->
GetIndex();
766 unsigned node_B_index = pNodeB->
GetIndex();
767 for (std::set<unsigned>::iterator iter = shared_elements.begin();
768 iter != shared_elements.end();
777 unsigned index = local_indexB;
780 if (local_indexB > local_indexA)
782 index = local_indexA;
785 if ((local_indexA == 0) && (local_indexB == p_element->
GetNumNodes()-1))
787 index = local_indexB;
790 else if ((local_indexB == 0) && (local_indexA == p_element->
GetNumNodes()-1))
793 index = local_indexA;
797 this->GetElement(*iter)->AddNode(p_new_node, index);
801 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
805 rElementMap.
Resize(this->GetNumAllElements());
808 std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM>*> live_elements;
809 for (
unsigned i=0; i<this->mElements.size(); i++)
811 if (this->mElements[i]->IsDeleted())
813 delete this->mElements[i];
818 live_elements.push_back(this->mElements[i]);
819 rElementMap.
SetNewIndex(i, (
unsigned)(live_elements.size()-1));
824 assert(mDeletedElementIndices.size() == this->mElements.size() - live_elements.size());
827 mDeletedElementIndices.clear();
828 this->mElements = live_elements;
831 for (
unsigned i=0; i<this->mElements.size(); i++)
833 this->mElements[i]->ResetIndex(i);
837 RemoveDeletedNodes();
840 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
844 std::vector<Node<SPACE_DIM>*> live_nodes;
845 for (
unsigned i=0; i<this->mNodes.size(); i++)
847 if (this->mNodes[i]->IsDeleted())
849 delete this->mNodes[i];
853 live_nodes.push_back(this->mNodes[i]);
858 assert(mDeletedNodeIndices.size() == this->mNodes.size() - live_nodes.size());
861 this->mNodes = live_nodes;
862 mDeletedNodeIndices.clear();
865 for (
unsigned i=0; i<this->mNodes.size(); i++)
867 this->mNodes[i]->SetIndex(i);
871 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
875 assert(SPACE_DIM==2 || SPACE_DIM==3);
876 assert(ELEMENT_DIM == SPACE_DIM);
882 rElementMap.
Resize(this->GetNumAllElements());
889 RemoveDeletedNodesAndElements(rElementMap);
890 bool recheck_mesh =
true;
891 while (recheck_mesh ==
true)
894 recheck_mesh = CheckForSwapsFromShortEdges();
899 while (recheck_mesh ==
true)
902 recheck_mesh = CheckForIntersections();
905 RemoveDeletedNodes();
911 this->CheckForRosettes();
916 EXCEPTION(
"Remeshing has not been implemented in 3D (see #827 and #860)\n");
922 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
929 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
934 elem_iter != this->GetElementIteratorEnd();
939 unsigned num_nodes = elem_iter->GetNumNodes();
940 assert(num_nodes > 0);
943 for (
unsigned local_index=0; local_index<num_nodes; local_index++)
947 unsigned local_index_plus_one = (local_index+1)%num_nodes;
948 Node<SPACE_DIM>* p_anticlockwise_node = elem_iter->GetNode(local_index_plus_one);
951 double distance_between_nodes = this->GetDistanceBetweenNodes(p_current_node->
GetIndex(), p_anticlockwise_node->
GetIndex());
954 if (distance_between_nodes < mCellRearrangementThreshold)
960 std::set<unsigned> shared_elements;
961 std::set_intersection(elements_of_node_a.begin(), elements_of_node_a.end(),
962 elements_of_node_b.begin(), elements_of_node_b.end(),
963 std::inserter(shared_elements, shared_elements.begin()));
965 bool both_nodes_share_triangular_element =
false;
966 for (std::set<unsigned>::const_iterator it = shared_elements.begin();
967 it != shared_elements.end();
970 if (this->GetElement(*it)->GetNumNodes() <= 3)
972 both_nodes_share_triangular_element =
true;
978 if (!both_nodes_share_triangular_element)
980 IdentifySwapType(p_current_node, p_anticlockwise_node);
990 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
995 elem_iter != this->GetElementIteratorEnd();
999 if (elem_iter->GetNumNodes() == 3)
1002 if (this->GetVolumeOfElement(elem_iter->GetIndex()) < GetT2Threshold())
1005 PerformT2Swap(*elem_iter);
1007 rElementMap.
SetDeleted(elem_iter->GetIndex());
1015 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1019 if (mCheckForInternalIntersections)
1023 node_iter != this->GetNodeIteratorEnd();
1026 assert(!(node_iter->IsDeleted()));
1029 elem_iter != this->GetElementIteratorEnd();
1032 unsigned elem_index = elem_iter->GetIndex();
1035 if (node_iter->rGetContainingElementIndices().count(elem_index) == 0)
1037 if (this->ElementIncludesPoint(node_iter->rGetLocation(), elem_index))
1039 PerformIntersectionSwap(&(*node_iter), elem_index);
1050 std::vector<unsigned> boundary_element_indices;
1051 std::vector< c_vector<double, SPACE_DIM> > boundary_element_centroids;
1053 elem_iter != this->GetElementIteratorEnd();
1056 if (elem_iter->IsElementOnBoundary())
1058 unsigned element_index = elem_iter->GetIndex();
1059 boundary_element_indices.push_back(element_index);
1061 boundary_element_centroids.push_back(this->GetCentroidOfElement(element_index));
1068 node_iter != this->GetNodeIteratorEnd();
1071 if (node_iter->IsBoundaryNode())
1073 assert(!(node_iter->IsDeleted()));
1076 unsigned boundary_element_index = 0;
1077 for (std::vector<unsigned>::iterator elem_iter = boundary_element_indices.begin();
1078 elem_iter != boundary_element_indices.end();
1082 if (node_iter->rGetContainingElementIndices().count(*elem_iter) == 0)
1084 c_vector<double, SPACE_DIM> node_location = node_iter->rGetLocation();
1085 c_vector<double, SPACE_DIM> element_centroid = boundary_element_centroids[boundary_element_index];
1086 double node_element_distance = norm_2(this->GetVectorFromAtoB(node_location, element_centroid));
1088 if ( node_element_distance < mDistanceForT3SwapChecking )
1090 if (this->ElementIncludesPoint(node_iter->rGetLocation(), *elem_iter))
1092 this->PerformT3Swap(&(*node_iter), *elem_iter);
1098 boundary_element_index +=1u;
1107 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1115 std::set<unsigned> all_indices, temp_union_set;
1116 std::set_union(nodeA_elem_indices.begin(), nodeA_elem_indices.end(),
1117 nodeB_elem_indices.begin(), nodeB_elem_indices.end(),
1118 std::inserter(temp_union_set, temp_union_set.begin()));
1119 all_indices.swap(temp_union_set);
1122 if ((nodeA_elem_indices.size()>3) || (nodeB_elem_indices.size()>3))
1139 this->HandleHighOrderJunctions(pNodeA, pNodeB);
1143 switch (all_indices.size())
1158 PerformNodeMerge(pNodeA, pNodeB);
1159 RemoveDeletedNodes();
1164 if (nodeA_elem_indices.size()==2 && nodeB_elem_indices.size()==2)
1178 PerformT1Swap(pNodeA, pNodeB,all_indices);
1193 EXCEPTION(
"There is a non-boundary node contained only in two elements; something has gone wrong.");
1205 EXCEPTION(
"There are non-boundary nodes contained only in two elements; something has gone wrong.");
1224 PerformNodeMerge(pNodeA, pNodeB);
1225 RemoveDeletedNodes();
1231 if (nodeA_elem_indices.size()==1 || nodeB_elem_indices.size()==1)
1249 EXCEPTION(
"There is a boundary node contained in three elements something has gone wrong.");
1251 else if (nodeA_elem_indices.size()==2 && nodeB_elem_indices.size()==2)
1259 std::set<unsigned> element_A_not_B, temp_set;
1260 std::set_difference(all_indices.begin(), all_indices.end(), nodeB_elem_indices.begin(),
1261 nodeB_elem_indices.end(), std::inserter(temp_set, temp_set.begin()));
1262 element_A_not_B.swap(temp_set);
1265 assert(element_A_not_B.size() == 1);
1267 std::set<unsigned> element_B_not_A;
1268 std::set_difference(all_indices.begin(), all_indices.end(), nodeA_elem_indices.begin(),
1269 nodeA_elem_indices.end(), std::inserter(temp_set, temp_set.begin()));
1270 element_B_not_A.swap(temp_set);
1273 assert(element_B_not_A.size() == 1);
1279 unsigned next_node_1 = p_element_A_not_B->GetNodeGlobalIndex((local_index_1 + 1)%(p_element_A_not_B->GetNumNodes()));
1280 unsigned previous_node_1 = p_element_A_not_B->GetNodeGlobalIndex(
1281 (local_index_1 + p_element_A_not_B->GetNumNodes() - 1)%(p_element_A_not_B->GetNumNodes()));
1284 (local_index_2 + 1)%(p_element_B_not_A->
GetNumNodes()));
1288 if (next_node_1 == previous_node_2 || next_node_2 == previous_node_1)
1307 unsigned nodeC_index;
1308 if (next_node_1 == previous_node_2 && next_node_2 != previous_node_1)
1310 nodeC_index = next_node_1;
1312 else if (next_node_2 == previous_node_1 && next_node_1 != previous_node_2)
1314 nodeC_index = next_node_2;
1318 assert(next_node_1 == previous_node_2 && next_node_2 == previous_node_1);
1326 EXCEPTION(
"Triangular element next to triangular void, not implemented yet.");
1329 if (p_element_A_not_B->GetNumNodes() == 3u || p_element_B_not_A->
GetNumNodes() == 3u)
1338 EXCEPTION(
"Triangular element next to triangular void, not implemented yet.");
1341 PerformVoidRemoval(pNodeA, pNodeB, this->mNodes[nodeC_index]);
1359 PerformT1Swap(pNodeA, pNodeB, all_indices);
1365 assert ( (nodeA_elem_indices.size()==2 && nodeB_elem_indices.size()==3)
1366 || (nodeA_elem_indices.size()==3 && nodeB_elem_indices.size()==2) );
1383 PerformT1Swap(pNodeA, pNodeB, all_indices);
1398 EXCEPTION(
"There are non-boundary nodes contained only in two elements; something has gone wrong.");
1421 this->PerformNodeMerge(pNodeA, pNodeB);
1422 this->RemoveDeletedNodes();
1426 this->PerformT1Swap(pNodeA, pNodeB, all_indices);
1437 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1448 unsigned node_B_index = pNodeB->
GetIndex();
1449 for (std::set<unsigned>::const_iterator it = nodeB_elem_indices.begin(); it != nodeB_elem_indices.end(); ++it)
1452 unsigned node_B_local_index = this->mElements[*it]->GetNodeLocalIndex(node_B_index);
1453 assert(node_B_local_index < UINT_MAX);
1459 if (nodeA_elem_indices.count(*it) != 0)
1461 this->mElements[*it]->DeleteNode(node_B_local_index);
1466 this->mElements[*it]->UpdateNode(node_B_local_index, pNodeA);
1470 assert(!(this->mNodes[node_B_index]->IsDeleted()));
1471 this->mNodes[node_B_index]->MarkAsDeleted();
1472 mDeletedNodeIndices.push_back(node_B_index);
1475 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1478 std::set<unsigned>& rElementsContainingNodes)
1481 double distance_between_nodes_CD = mCellRearrangementRatio*mCellRearrangementThreshold;
1483 c_vector<double, SPACE_DIM> nodeA_location = pNodeA->
rGetLocation();
1484 c_vector<double, SPACE_DIM> nodeB_location = pNodeB->
rGetLocation();
1485 c_vector<double, SPACE_DIM> vector_AB = this->GetVectorFromAtoB(nodeA_location, nodeB_location);
1486 mLocationsOfT1Swaps.push_back(nodeA_location + 0.5*vector_AB);
1488 double distance_AB = norm_2(vector_AB);
1489 if (distance_AB < 1e-10)
1491 EXCEPTION(
"Nodes are too close together, this shouldn't happen");
1523 c_vector<double, SPACE_DIM> vector_CD;
1524 vector_CD(0) = -vector_AB(1) * distance_between_nodes_CD / distance_AB;
1525 vector_CD(1) = vector_AB(0) * distance_between_nodes_CD / distance_AB;
1527 c_vector<double, SPACE_DIM> nodeC_location = nodeA_location + 0.5*vector_AB - 0.5*vector_CD;
1528 c_vector<double, SPACE_DIM> nodeD_location = nodeC_location + vector_CD;
1537 for (std::set<unsigned>::const_iterator it = rElementsContainingNodes.begin();
1538 it != rElementsContainingNodes.end();
1542 if (nodeA_elem_indices.find(*it) == nodeA_elem_indices.end())
1545 unsigned nodeB_local_index = this->mElements[*it]->GetNodeLocalIndex(pNodeB->
GetIndex());
1546 assert(nodeB_local_index < UINT_MAX);
1548 this->mElements[*it]->AddNode(pNodeA, nodeB_local_index);
1550 else if (nodeB_elem_indices.find(*it) == nodeB_elem_indices.end())
1553 unsigned nodeA_local_index = this->mElements[*it]->GetNodeLocalIndex(pNodeA->
GetIndex());
1554 assert(nodeA_local_index < UINT_MAX);
1556 this->mElements[*it]->AddNode(pNodeB, nodeA_local_index);
1561 unsigned nodeA_local_index = this->mElements[*it]->GetNodeLocalIndex(pNodeA->
GetIndex());
1562 unsigned nodeB_local_index = this->mElements[*it]->GetNodeLocalIndex(pNodeB->
GetIndex());
1564 assert(nodeA_local_index < UINT_MAX);
1565 assert(nodeB_local_index < UINT_MAX);
1572 unsigned nodeB_local_index_plus_one = (nodeB_local_index + 1)%(this->mElements[*it]->GetNumNodes());
1574 if (nodeA_local_index == nodeB_local_index_plus_one)
1580 this->mElements[*it]->DeleteNode(nodeB_local_index);
1584 assert(nodeB_local_index == (nodeA_local_index + 1)%(this->mElements[*it]->GetNumNodes()));
1589 this->mElements[*it]->DeleteNode(nodeA_local_index);
1616 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1619 assert(SPACE_DIM == 2);
1620 assert(ELEMENT_DIM == SPACE_DIM);
1626 std::set<unsigned> elements_containing_intersecting_node;
1628 for (
unsigned node_local_index=0; node_local_index<num_nodes; node_local_index++)
1632 std::set<unsigned> node_elem_indices = this->GetNode(node_global_index)->rGetContainingElementIndices();
1634 for (std::set<unsigned>::const_iterator elem_iter = node_elem_indices.begin();
1635 elem_iter != node_elem_indices.end();
1639 unsigned num_nodes_in_neighbouring_element = p_neighbouring_element->
GetNumNodes();
1642 for (
unsigned node_index_2 = 0; node_index_2 < num_nodes_in_neighbouring_element; node_index_2++)
1646 elements_containing_intersecting_node.insert(p_neighbouring_element->
GetIndex());
1655 assert(elements_containing_intersecting_node.size() == 2);
1659 std::set<unsigned> intersecting_element;
1661 std::set_difference(all_elements_containing_intersecting_node.begin(), all_elements_containing_intersecting_node.end(),
1662 elements_containing_intersecting_node.begin(), elements_containing_intersecting_node.end(),
1663 std::inserter(intersecting_element, intersecting_element.begin()));
1675 unsigned node_A_index = pNode->
GetIndex();
1676 unsigned node_B_index;
1677 unsigned element_1_index = *(intersecting_element.begin());
1678 unsigned element_2_index;
1679 unsigned element_3_index = elementIndex;
1680 unsigned element_4_index;
1682 std::set<unsigned>::iterator iter = elements_containing_intersecting_node.begin();
1683 unsigned element_a_index = *(iter);
1685 unsigned element_b_index = *(iter);
1690 std::set<unsigned> element_a_nodes;
1691 for (
unsigned node_index = 0; node_index < p_element_a->
GetNumNodes(); node_index++)
1696 std::set<unsigned> element_b_nodes;
1697 for (
unsigned node_index = 0; node_index < p_element_b->
GetNumNodes(); node_index++)
1702 std::set<unsigned> switching_nodes;
1703 std::set_intersection(element_a_nodes.begin(), element_a_nodes.end(),
1704 element_b_nodes.begin(), element_b_nodes.end(),
1705 std::inserter(switching_nodes, switching_nodes.begin()));
1707 assert(switching_nodes.size() == 2);
1710 assert(switching_nodes.find(node_A_index) != switching_nodes.end());
1711 switching_nodes.erase(node_A_index);
1713 assert(switching_nodes.size() == 1);
1715 node_B_index = *(switching_nodes.begin());
1718 unsigned node_A_local_index_in_a = p_element_a->
GetNodeLocalIndex(node_A_index);
1719 unsigned node_B_local_index_in_a = p_element_a->
GetNodeLocalIndex(node_B_index);
1721 if ((node_B_local_index_in_a+1)%p_element_a->
GetNumNodes() == node_A_local_index_in_a)
1727 element_2_index = element_a_index;
1728 element_4_index = element_b_index;
1736 element_2_index = element_b_index;
1737 element_4_index = element_a_index;
1740 unsigned intersected_edge = this->GetLocalIndexForElementEdgeClosestToPoint(pNode->
rGetLocation(), elementIndex);
1742 unsigned node_A_local_index_in_1 = this->GetElement(element_1_index)->GetNodeLocalIndex(node_A_index);
1744 unsigned node_A_local_index_in_2 = this->GetElement(element_2_index)->GetNodeLocalIndex(node_A_index);
1745 unsigned node_B_local_index_in_2 = this->GetElement(element_2_index)->GetNodeLocalIndex(node_B_index);
1747 unsigned node_B_local_index_in_3 = this->GetElement(elementIndex)->GetNodeLocalIndex(node_B_index);
1749 unsigned node_A_local_index_in_4 = this->GetElement(element_4_index)->GetNodeLocalIndex(node_A_index);
1750 unsigned node_B_local_index_in_4 = this->GetElement(element_4_index)->GetNodeLocalIndex(node_B_index);
1752 if (intersected_edge==node_B_local_index_in_3)
1761 this->mElements[element_1_index]->AddNode(this->mNodes[node_B_index], node_A_local_index_in_1);
1762 this->mElements[element_3_index]->AddNode(this->mNodes[node_A_index], node_B_local_index_in_3);
1764 this->mElements[element_2_index]->DeleteNode(node_B_local_index_in_2);
1765 this->mElements[element_4_index]->DeleteNode(node_A_local_index_in_4);
1769 assert((intersected_edge+1)%num_nodes==node_B_local_index_in_3);
1772 unsigned node_before_A_in_1 = (node_A_local_index_in_1 - 1)%this->GetElement(element_1_index)->GetNumNodes();
1773 unsigned node_before_B_in_3 = (node_B_local_index_in_3 - 1)%this->GetElement(element_3_index)->GetNumNodes();
1774 this->mElements[element_1_index]->AddNode(this->mNodes[node_B_index], node_before_A_in_1);
1775 this->mElements[element_3_index]->AddNode(this->mNodes[node_A_index], node_before_B_in_3);
1778 this->mElements[element_2_index]->DeleteNode(node_A_local_index_in_2);
1779 this->mElements[element_4_index]->DeleteNode(node_B_local_index_in_4);
1783 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1790 c_vector<double, SPACE_DIM> new_node_location;
1791 new_node_location = this->GetCentroidOfElement(rElement.
GetIndex());
1792 mLastT2SwapLocation = new_node_location;
1795 bool is_node_on_boundary =
false;
1796 for (
unsigned i=0; i<3; i++)
1798 if (rElement.
GetNode(i)->IsBoundaryNode())
1800 is_node_on_boundary =
true;
1804 unsigned new_node_global_index = this->AddNode(
new Node<SPACE_DIM>(GetNumNodes(), new_node_location, is_node_on_boundary));
1808 for (
unsigned i=0; i<3; i++)
1813 containing_elements.erase(rElement.
GetIndex());
1816 for (std::set<unsigned>::iterator elem_iter = containing_elements.begin(); elem_iter != containing_elements.end(); ++elem_iter)
1823 EXCEPTION(
"One of the neighbours of a small triangular element is also a triangle - dealing with this has not been implemented yet");
1843 rElement.
GetNode(0)->MarkAsDeleted();
1844 rElement.
GetNode(1)->MarkAsDeleted();
1845 rElement.
GetNode(2)->MarkAsDeleted();
1847 mDeletedElementIndices.push_back(rElement.
GetIndex());
1851 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1854 assert(SPACE_DIM == 2);
1855 assert(ELEMENT_DIM == SPACE_DIM);
1863 unsigned node_A_local_index = this->GetLocalIndexForElementEdgeClosestToPoint(pNode->
rGetLocation(), elementIndex);
1866 c_vector<double, SPACE_DIM> node_location;
1875 unsigned vertexB_index = p_element->
GetNodeGlobalIndex((node_A_local_index+1)%num_nodes);
1878 if (!this->mNodes[vertexA_index]->IsBoundaryNode() || !this->mNodes[vertexB_index]->IsBoundaryNode())
1880 EXCEPTION(
"A boundary node has intersected a non-boundary edge; this is because the boundary element has become concave. You need to rerun the simulation with a smaller time step to prevent this.");
1884 c_vector<double, SPACE_DIM> vertexA = p_element->
GetNodeLocation(node_A_local_index);
1885 c_vector<double, SPACE_DIM> vertexB = p_element->
GetNodeLocation((node_A_local_index+1)%num_nodes);
1886 c_vector<double, SPACE_DIM> vector_a_to_point = this->GetVectorFromAtoB(vertexA, node_location);
1888 c_vector<double, SPACE_DIM> vector_a_to_b = this->GetVectorFromAtoB(vertexA, vertexB);
1890 c_vector<double, SPACE_DIM> edge_ab_unit_vector = vector_a_to_b/norm_2(vector_a_to_b);
1891 c_vector<double, SPACE_DIM> intersection = vertexA + edge_ab_unit_vector*inner_prod(vector_a_to_point, edge_ab_unit_vector);
1897 mLocationsOfT3Swaps.push_back(intersection);
1902 unsigned intersecting_element_index = *elements_containing_intersecting_node.begin();
1912 if (next_node == vertexA_index || previous_node == vertexA_index || next_node == vertexB_index || previous_node == vertexB_index)
1914 unsigned common_vertex_index;
1916 if (next_node == vertexA_index || previous_node == vertexA_index)
1918 common_vertex_index = vertexA_index;
1922 common_vertex_index = vertexB_index;
1925 assert(this->mNodes[common_vertex_index]->GetNumContainingElements()>1);
1927 std::set<unsigned> elements_containing_common_vertex = this->mNodes[common_vertex_index]->rGetContainingElementIndices();
1928 std::set<unsigned>::const_iterator it = elements_containing_common_vertex.begin();
1934 unsigned num_common_vertices = 0;
1935 std::vector<unsigned> common_vertex_indices;
1936 for (
unsigned i=0; i<p_element_common_1->
GetNumNodes(); i++)
1938 for (
unsigned j=0; j<p_element_common_2->
GetNumNodes(); j++)
1942 num_common_vertices++;
1948 if (num_common_vertices == 1 || this->mNodes[common_vertex_index]->GetNumContainingElements() > 2)
1964 intersection = this->WidenEdgeOrCorrectIntersectionLocationIfNecessary(vertexA_index, vertexB_index, intersection);
1970 this->GetElement(elementIndex)->AddNode(pNode, node_A_local_index);
1975 else if (num_common_vertices == 2)
1980 if ((common_vertex_indices[0]==vertexA_index && common_vertex_indices[1]==vertexB_index) ||
1981 (common_vertex_indices[1]==vertexA_index && common_vertex_indices[0]==vertexB_index))
1999 unsigned p_node_local_index = this->
2000 GetElement(intersecting_element_index)->GetNodeLocalIndex(pNode->
GetIndex());
2001 this->GetElement(intersecting_element_index)->DeleteNode(p_node_local_index);
2005 mDeletedNodeIndices.push_back(pNode->
GetIndex());
2026 intersection = this->WidenEdgeOrCorrectIntersectionLocationIfNecessary(vertexA_index, vertexB_index, intersection);
2032 this->GetElement(elementIndex)->ReplaceNode(this->mNodes[common_vertex_index], pNode);
2035 unsigned common_vertex_local_index = this->GetElement(intersecting_element_index)->GetNodeLocalIndex(common_vertex_index);
2036 this->GetElement(intersecting_element_index)->DeleteNode(common_vertex_local_index);
2037 assert(this->mNodes[common_vertex_index]->GetNumContainingElements() == 0);
2039 this->mNodes[common_vertex_index]->MarkAsDeleted();
2040 mDeletedNodeIndices.push_back(common_vertex_index);
2046 else if (num_common_vertices == 4)
2064 this->GetElement(elementIndex)->DeleteNode(node_A_local_index);
2065 unsigned node_B_local_index = this->
2066 GetElement(elementIndex)->GetNodeLocalIndex(vertexB_index);
2067 this->GetElement(elementIndex)->DeleteNode(node_B_local_index);
2070 unsigned node_A_local_index_intersecting_element = this->
2071 GetElement(intersecting_element_index)->GetNodeLocalIndex(vertexA_index);
2072 this->GetElement(intersecting_element_index)->DeleteNode(node_A_local_index_intersecting_element);
2073 unsigned node_B_local_index_intersecting_element = this->
2074 GetElement(intersecting_element_index)->GetNodeLocalIndex(vertexB_index);
2075 this->GetElement(intersecting_element_index)->DeleteNode(node_B_local_index_intersecting_element);
2078 unsigned p_node_local_index = this->
2079 GetElement(intersecting_element_index)->GetNodeLocalIndex(pNode->
GetIndex());
2080 this->GetElement(intersecting_element_index)->DeleteNode(p_node_local_index);
2084 mDeletedNodeIndices.push_back(pNode->
GetIndex());
2085 this->mNodes[vertexA_index]->MarkAsDeleted();
2086 mDeletedNodeIndices.push_back(vertexA_index);
2087 this->mNodes[vertexB_index]->MarkAsDeleted();
2088 mDeletedNodeIndices.push_back(vertexB_index);
2109 intersection = this->WidenEdgeOrCorrectIntersectionLocationIfNecessary(vertexA_index, vertexB_index, intersection);
2110 edge_ab_unit_vector = this->GetPreviousEdgeGradientOfElementAtNode(p_element, (node_A_local_index+1)%num_nodes);
2113 pNode->
rGetModifiableLocation() = intersection + 0.5*mCellRearrangementRatio*mCellRearrangementThreshold*edge_ab_unit_vector;
2116 c_vector<double, SPACE_DIM> new_node_location;
2117 new_node_location = intersection - 0.5*mCellRearrangementRatio*mCellRearrangementThreshold*edge_ab_unit_vector;
2120 unsigned new_node_global_index = this->AddNode(
new Node<SPACE_DIM>(0,
true, new_node_location[0], new_node_location[1]));
2123 this->GetElement(elementIndex)->AddNode(pNode, node_A_local_index);
2124 this->GetElement(elementIndex)->AddNode(this->mNodes[new_node_global_index], node_A_local_index);
2127 this->GetElement(intersecting_element_index)->AddNode(this->mNodes[new_node_global_index], this->GetElement(intersecting_element_index)->GetNodeLocalIndex(pNode->
GetIndex()));
2131 assert(this->mNodes[new_node_global_index]->GetNumContainingElements() == 2);
2137 std::set<unsigned>::const_iterator it = elements_containing_intersecting_node.begin();
2140 unsigned num_nodes_elem_1 = p_element_1->
GetNumNodes();
2144 unsigned num_nodes_elem_2 = p_element_2->
GetNumNodes();
2146 unsigned node_global_index = pNode->
GetIndex();
2149 unsigned next_node_1 = p_element_1->
GetNodeGlobalIndex((local_index_1 + 1)%num_nodes_elem_1);
2150 unsigned previous_node_1 = p_element_1->
GetNodeGlobalIndex((local_index_1 + num_nodes_elem_1 - 1)%num_nodes_elem_1);
2153 unsigned next_node_2 = p_element_2->
GetNodeGlobalIndex((local_index_2 + 1)%num_nodes_elem_2);
2154 unsigned previous_node_2 = p_element_2->
GetNodeGlobalIndex((local_index_2 + num_nodes_elem_2 - 1)%num_nodes_elem_2);
2157 if ((next_node_1 == vertexA_index || previous_node_1 == vertexA_index || next_node_2 == vertexA_index || previous_node_2 == vertexA_index) &&
2158 (next_node_1 == vertexB_index || previous_node_1 == vertexB_index || next_node_2 == vertexB_index || previous_node_2 == vertexB_index))
2174 intersection = this->WidenEdgeOrCorrectIntersectionLocationIfNecessary(vertexA_index, vertexB_index, intersection);
2175 edge_ab_unit_vector = this->GetPreviousEdgeGradientOfElementAtNode(p_element, (node_A_local_index+1)%num_nodes);
2179 assert(this->mNodes[vertexA_index]->IsBoundaryNode());
2180 assert(this->mNodes[vertexB_index]->IsBoundaryNode());
2187 this->GetElement(elementIndex)->AddNode(pNode, node_A_local_index);
2190 std::set<unsigned> elements_containing_vertex_A = this->mNodes[vertexA_index]->rGetContainingElementIndices();
2191 for (std::set<unsigned>::const_iterator iter = elements_containing_vertex_A.begin();
2192 iter != elements_containing_vertex_A.end();
2195 this->GetElement(*iter)->DeleteNode(this->GetElement(*iter)->GetNodeLocalIndex(vertexA_index));
2199 assert(this->mNodes[vertexA_index]->GetNumContainingElements() == 0);
2200 this->mNodes[vertexA_index]->MarkAsDeleted();
2201 mDeletedNodeIndices.push_back(vertexA_index);
2204 std::set<unsigned> elements_containing_vertex_B = this->mNodes[vertexB_index]->rGetContainingElementIndices();
2205 for (std::set<unsigned>::const_iterator iter = elements_containing_vertex_B.begin();
2206 iter != elements_containing_vertex_B.end();
2209 this->GetElement(*iter)->DeleteNode(this->GetElement(*iter)->GetNodeLocalIndex(vertexB_index));
2213 assert(this->mNodes[vertexB_index]->GetNumContainingElements()==0);
2214 this->mNodes[vertexB_index]->MarkAsDeleted();
2215 mDeletedNodeIndices.push_back(vertexB_index);
2219 if (next_node_1 == vertexA_index || previous_node_1 == vertexA_index || next_node_2 == vertexA_index || previous_node_2 == vertexA_index)
2223 assert(this->mNodes[vertexA_index]->GetNumContainingElements() > 1);
2225 std::set<unsigned> elements_containing_vertex_A = this->mNodes[vertexA_index]->rGetContainingElementIndices();
2226 std::set<unsigned>::const_iterator iter = elements_containing_vertex_A.begin();
2232 unsigned num_common_vertices = 0;
2233 for (
unsigned i=0; i<p_element_common_1->
GetNumNodes(); i++)
2235 for (
unsigned j=0; j<p_element_common_2->
GetNumNodes(); j++)
2239 num_common_vertices++;
2244 if (num_common_vertices == 1 || this->mNodes[vertexA_index]->GetNumContainingElements() > 2)
2260 intersection = this->WidenEdgeOrCorrectIntersectionLocationIfNecessary(vertexA_index, vertexB_index, intersection);
2261 edge_ab_unit_vector = this->GetPreviousEdgeGradientOfElementAtNode(p_element, (node_A_local_index+1)%num_nodes);
2264 pNode->
rGetModifiableLocation() = intersection - 0.5*mCellRearrangementRatio*mCellRearrangementThreshold*edge_ab_unit_vector;
2268 c_vector<double, SPACE_DIM> new_node_location;
2269 new_node_location = intersection + 0.5*mCellRearrangementRatio*mCellRearrangementThreshold*edge_ab_unit_vector;
2272 unsigned new_node_global_index = this->AddNode(
new Node<SPACE_DIM>(0,
true, new_node_location[0], new_node_location[1]));
2275 this->GetElement(elementIndex)->AddNode(this->mNodes[new_node_global_index], node_A_local_index);
2276 this->GetElement(elementIndex)->AddNode(pNode, node_A_local_index);
2279 if (next_node_1 == previous_node_2)
2285 assert(next_node_2 == previous_node_1);
2292 assert(this->mNodes[new_node_global_index]->GetNumContainingElements() == 2);
2294 else if (num_common_vertices == 2)
2311 intersection = this->WidenEdgeOrCorrectIntersectionLocationIfNecessary(vertexA_index, vertexB_index, intersection);
2312 edge_ab_unit_vector = this->GetPreviousEdgeGradientOfElementAtNode(p_element, (node_A_local_index+1)%num_nodes);
2315 pNode->
rGetModifiableLocation() = intersection - 0.5*mCellRearrangementRatio*mCellRearrangementThreshold*edge_ab_unit_vector;
2319 c_vector<double, SPACE_DIM> new_node_location;
2320 new_node_location = intersection + 0.5*mCellRearrangementRatio*mCellRearrangementThreshold*edge_ab_unit_vector;
2323 unsigned new_node_global_index = this->AddNode(
new Node<SPACE_DIM>(0,
true, new_node_location[0], new_node_location[1]));
2326 this->GetElement(elementIndex)->AddNode(this->mNodes[new_node_global_index], node_A_local_index);
2327 this->GetElement(elementIndex)->AddNode(pNode, node_A_local_index);
2330 if (next_node_1 == previous_node_2)
2336 assert(next_node_2 == previous_node_1);
2344 assert(this->mNodes[vertexA_index]->GetNumContainingElements()==0);
2346 this->mNodes[vertexA_index]->MarkAsDeleted();
2347 mDeletedNodeIndices.push_back(vertexA_index);
2351 assert(this->mNodes[new_node_global_index]->GetNumContainingElements() == 2);
2359 else if (next_node_1 == vertexB_index || previous_node_1 == vertexB_index || next_node_2 == vertexB_index || previous_node_2 == vertexB_index)
2363 assert(this->mNodes[vertexB_index]->GetNumContainingElements()>1);
2365 std::set<unsigned> elements_containing_vertex_B = this->mNodes[vertexB_index]->rGetContainingElementIndices();
2366 std::set<unsigned>::const_iterator iter = elements_containing_vertex_B.begin();
2372 unsigned num_common_vertices = 0;
2373 for (
unsigned i=0; i<p_element_common_1->
GetNumNodes(); i++)
2375 for (
unsigned j=0; j<p_element_common_2->
GetNumNodes(); j++)
2379 num_common_vertices++;
2384 if (num_common_vertices == 1 || this->mNodes[vertexB_index]->GetNumContainingElements() > 2)
2400 intersection = this->WidenEdgeOrCorrectIntersectionLocationIfNecessary(vertexA_index, vertexB_index, intersection);
2401 edge_ab_unit_vector = this->GetPreviousEdgeGradientOfElementAtNode(p_element, (node_A_local_index+1)%num_nodes);
2404 pNode->
rGetModifiableLocation() = intersection + 0.5*mCellRearrangementRatio*mCellRearrangementThreshold*edge_ab_unit_vector;
2408 c_vector<double, SPACE_DIM> new_node_location;
2409 new_node_location = intersection - 0.5*mCellRearrangementRatio*mCellRearrangementThreshold*edge_ab_unit_vector;
2412 unsigned new_node_global_index = this->AddNode(
new Node<SPACE_DIM>(0,
true, new_node_location[0], new_node_location[1]));
2415 this->GetElement(elementIndex)->AddNode(pNode, node_A_local_index);
2416 this->GetElement(elementIndex)->AddNode(this->mNodes[new_node_global_index], node_A_local_index);
2419 if (next_node_1 == previous_node_2)
2421 p_element_2->
AddNode(this->mNodes[new_node_global_index], local_index_2);
2425 assert(next_node_2 == previous_node_1);
2426 p_element_1->
AddNode(this->mNodes[new_node_global_index], local_index_1);
2431 assert(this->mNodes[new_node_global_index]->GetNumContainingElements() == 2);
2433 else if (num_common_vertices == 2)
2450 intersection = this->WidenEdgeOrCorrectIntersectionLocationIfNecessary(vertexA_index, vertexB_index, intersection);
2451 edge_ab_unit_vector = this->GetPreviousEdgeGradientOfElementAtNode(p_element, (node_A_local_index+1)%num_nodes);
2454 pNode->
rGetModifiableLocation() = intersection + 0.5*mCellRearrangementRatio*mCellRearrangementThreshold*edge_ab_unit_vector;
2458 c_vector<double, SPACE_DIM> new_node_location;
2459 new_node_location = intersection - 0.5*mCellRearrangementRatio*mCellRearrangementThreshold*edge_ab_unit_vector;
2462 unsigned new_node_global_index = this->AddNode(
new Node<SPACE_DIM>(0,
true, new_node_location[0], new_node_location[1]));
2465 this->GetElement(elementIndex)->AddNode(pNode, node_A_local_index);
2466 this->GetElement(elementIndex)->AddNode(this->mNodes[new_node_global_index], node_A_local_index);
2469 if (next_node_1 == previous_node_2)
2471 p_element_2->
AddNode(this->mNodes[new_node_global_index], local_index_2);
2475 assert(next_node_2 == previous_node_1);
2476 p_element_1->
AddNode(this->mNodes[new_node_global_index], local_index_1);
2483 assert(this->mNodes[vertexB_index]->GetNumContainingElements()==0);
2485 this->mNodes[vertexB_index]->MarkAsDeleted();
2486 mDeletedNodeIndices.push_back(vertexB_index);
2490 assert(this->mNodes[new_node_global_index]->GetNumContainingElements() == 2);
2511 intersection = this->WidenEdgeOrCorrectIntersectionLocationIfNecessary(vertexA_index, vertexB_index, intersection);
2512 edge_ab_unit_vector = this->GetPreviousEdgeGradientOfElementAtNode(p_element, (node_A_local_index+1)%num_nodes);
2518 c_vector<double, SPACE_DIM> new_node_1_location;
2519 new_node_1_location = intersection - mCellRearrangementRatio*mCellRearrangementThreshold*edge_ab_unit_vector;
2520 c_vector<double, SPACE_DIM> new_node_2_location;
2521 new_node_2_location = intersection + mCellRearrangementRatio*mCellRearrangementThreshold*edge_ab_unit_vector;
2524 unsigned new_node_1_global_index = this->AddNode(
new Node<SPACE_DIM>(0,
true, new_node_1_location[0], new_node_1_location[1]));
2525 unsigned new_node_2_global_index = this->AddNode(
new Node<SPACE_DIM>(0,
true, new_node_2_location[0], new_node_2_location[1]));
2528 this->GetElement(elementIndex)->AddNode(this->mNodes[new_node_2_global_index], node_A_local_index);
2529 this->GetElement(elementIndex)->AddNode(pNode, node_A_local_index);
2530 this->GetElement(elementIndex)->AddNode(this->mNodes[new_node_1_global_index], node_A_local_index);
2533 if (next_node_1 == previous_node_2)
2536 p_element_2->
AddNode(this->mNodes[new_node_1_global_index], local_index_2);
2540 assert(next_node_2 == previous_node_1);
2542 p_element_1->
AddNode(this->mNodes[new_node_1_global_index], local_index_1);
2548 assert(this->mNodes[new_node_1_global_index]->GetNumContainingElements() == 2);
2549 assert(this->mNodes[new_node_2_global_index]->GetNumContainingElements() == 2);
2555 EXCEPTION(
"Trying to merge a node, contained in more than 2 elements, into another element, this is not possible with the vertex mesh.");
2559 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
2563 c_vector<double, SPACE_DIM> nodes_midpoint = pNodeA->
rGetLocation()
2572 PerformNodeMerge(pNodeA, pNodeB);
2578 p_merged_node = pNodeA;
2581 PerformNodeMerge(pNodeC, p_merged_node);
2585 p_merged_node = pNodeC;
2594 RemoveDeletedNodes();
2597 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
2603 if ((node_a_rank > 3) && (node_b_rank > 3))
2606 EXCEPTION(
"Both nodes involved in a swap event are contained in more than three elements");
2610 assert(node_a_rank > 3 || node_b_rank > 3);
2611 this->PerformRosetteRankIncrease(pNodeA, pNodeB);
2612 this->RemoveDeletedNodes();
2616 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
2624 unsigned node_a_index = pNodeA->
GetIndex();
2625 unsigned node_b_index = pNodeB->
GetIndex();
2630 unsigned lo_rank_index = (node_a_rank < node_b_rank) ? node_a_index : node_b_index;
2631 unsigned hi_rank_index = (node_a_rank < node_b_rank) ? node_b_index : node_a_index;
2667 for (std::set<unsigned>::const_iterator it = lo_rank_elem_indices.begin();
2668 it != lo_rank_elem_indices.end();
2672 unsigned lo_rank_local_index = this->mElements[*it]->GetNodeLocalIndex(lo_rank_index);
2673 assert(lo_rank_local_index < UINT_MAX);
2685 if (hi_rank_elem_indices.count(*it) > 0)
2688 this->mElements[*it]->DeleteNode(lo_rank_local_index);
2693 this->mElements[*it]->UpdateNode(lo_rank_local_index, p_hi_rank_node);
2698 assert(!(this->mNodes[lo_rank_index]->IsDeleted()));
2699 this->mNodes[lo_rank_index]->MarkAsDeleted();
2700 this->mDeletedNodeIndices.push_back(lo_rank_index);
2703 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
2716 std::set<unsigned>::const_iterator elem_index_iter(protorosette_node_containing_elem_indices.begin());
2717 advance(elem_index_iter, random_elem_increment);
2750 unsigned elem_a_idx = *elem_index_iter;
2751 unsigned elem_b_idx = UINT_MAX;
2752 unsigned elem_c_idx = UINT_MAX;
2753 unsigned elem_d_idx = UINT_MAX;
2759 unsigned num_nodes_elem_a = p_elem_a->
GetNumNodes();
2760 unsigned protorosette_node_global_idx = pProtorosetteNode->
GetIndex();
2761 unsigned protorosette_node_local_idx = p_elem_a->
GetNodeLocalIndex(protorosette_node_global_idx);
2764 unsigned prev_node_global_idx = p_elem_a->
GetNodeGlobalIndex((protorosette_node_local_idx + num_nodes_elem_a - 1) % num_nodes_elem_a);
2765 unsigned next_node_global_idx = p_elem_a->
GetNodeGlobalIndex((protorosette_node_local_idx + 1) % num_nodes_elem_a);
2774 std::set<unsigned> intersection_with_prev;
2775 std::set<unsigned> intersection_with_next;
2778 std::set_intersection(protorosette_node_containing_elem_indices.begin(),
2779 protorosette_node_containing_elem_indices.end(),
2780 prev_node_elem_indices.begin(),
2781 prev_node_elem_indices.end(),
2782 std::inserter(intersection_with_prev, intersection_with_prev.begin()));
2785 std::set_intersection(protorosette_node_containing_elem_indices.begin(),
2786 protorosette_node_containing_elem_indices.end(),
2787 next_node_elem_indices.begin(),
2788 next_node_elem_indices.end(),
2789 std::inserter(intersection_with_next, intersection_with_next.begin()));
2791 assert(intersection_with_prev.size() == 2);
2792 assert(intersection_with_next.size() == 2);
2795 if (*intersection_with_prev.begin() != elem_a_idx)
2797 elem_b_idx = *(intersection_with_prev.begin());
2801 elem_b_idx = *(++(intersection_with_prev.begin()));
2803 assert(elem_b_idx < UINT_MAX);
2806 if (*intersection_with_next.begin() != elem_a_idx)
2808 elem_d_idx = *(intersection_with_next.begin());
2812 elem_d_idx = *(++(intersection_with_next.begin()));
2814 assert(elem_d_idx < UINT_MAX);
2817 for (elem_index_iter = protorosette_node_containing_elem_indices.begin();
2818 elem_index_iter != protorosette_node_containing_elem_indices.end();
2821 if ((*elem_index_iter != elem_a_idx) && (*elem_index_iter != elem_b_idx) && (*elem_index_iter != elem_d_idx))
2823 elem_c_idx = *elem_index_iter;
2826 assert(elem_c_idx < UINT_MAX);
2846 double swap_distance = (this->mCellRearrangementRatio) * (this->mCellRearrangementThreshold);
2849 c_vector<double, SPACE_DIM> node_to_elem_a_centre = this->GetCentroidOfElement(elem_a_idx) - pProtorosetteNode->
rGetLocation();
2850 node_to_elem_a_centre /= norm_2(node_to_elem_a_centre);
2852 c_vector<double, SPACE_DIM> node_to_elem_c_centre = this->GetCentroidOfElement(elem_c_idx) - pProtorosetteNode->
rGetLocation();
2853 node_to_elem_c_centre /= norm_2(node_to_elem_c_centre);
2856 c_vector<double, SPACE_DIM> new_location_of_protorosette_node = pProtorosetteNode->
rGetLocation() + (0.5 * swap_distance) * node_to_elem_a_centre;
2857 c_vector<double, SPACE_DIM> location_of_new_node = pProtorosetteNode->
rGetLocation() + (0.5 * swap_distance) * node_to_elem_c_centre;
2863 unsigned new_node_global_index = this->AddNode(
new Node<SPACE_DIM>(this->GetNumNodes(), location_of_new_node,
false));
2876 unsigned local_idx_elem_b = p_elem_b->
GetNodeLocalIndex(protorosette_node_global_idx);
2878 unsigned local_idx_elem_c = p_elem_c->
GetNodeLocalIndex(protorosette_node_global_idx);
2879 unsigned local_idx_elem_d = p_elem_d->
GetNodeLocalIndex(protorosette_node_global_idx);
2881 p_elem_b->
AddNode(p_new_node, local_idx_elem_b);
2882 p_elem_c->
AddNode(p_new_node, local_idx_elem_c);
2883 p_elem_d->
AddNode(p_new_node, local_idx_elem_d);
2889 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
2895 assert(rosette_rank > 4);
2904 std::set<unsigned>::const_iterator elem_index_iter(rosette_node_containing_elem_indices.begin());
2905 advance(elem_index_iter, random_elem_increment);
2950 unsigned elem_s_idx = *elem_index_iter;
2953 unsigned elem_n_idx = UINT_MAX;
2954 unsigned elem_p_idx = UINT_MAX;
2957 unsigned num_nodes_elem_s = p_elem_s->
GetNumNodes();
2958 unsigned rosette_node_global_idx = pRosetteNode->
GetIndex();
2959 unsigned rosette_node_local_idx = p_elem_s->
GetNodeLocalIndex(rosette_node_global_idx);
2962 unsigned prev_node_global_idx = p_elem_s->
GetNodeGlobalIndex((rosette_node_local_idx + num_nodes_elem_s - 1) % num_nodes_elem_s);
2963 unsigned next_node_global_idx = p_elem_s->
GetNodeGlobalIndex((rosette_node_local_idx + 1) % num_nodes_elem_s);
2972 std::set<unsigned> intersection_with_prev;
2973 std::set<unsigned> intersection_with_next;
2976 std::set_intersection(rosette_node_containing_elem_indices.begin(),
2977 rosette_node_containing_elem_indices.end(),
2978 prev_node_elem_indices.begin(),
2979 prev_node_elem_indices.end(),
2980 std::inserter(intersection_with_prev, intersection_with_prev.begin()));
2983 std::set_intersection(rosette_node_containing_elem_indices.begin(),
2984 rosette_node_containing_elem_indices.end(),
2985 next_node_elem_indices.begin(),
2986 next_node_elem_indices.end(),
2987 std::inserter(intersection_with_next, intersection_with_next.begin()));
2989 assert(intersection_with_prev.size() == 2);
2990 assert(intersection_with_next.size() == 2);
2993 if (*intersection_with_prev.begin() != elem_s_idx)
2995 elem_n_idx = *intersection_with_prev.begin();
2999 elem_n_idx = *(++(intersection_with_prev.begin()));
3001 assert(elem_n_idx < UINT_MAX);
3004 if (*intersection_with_next.begin() != elem_s_idx)
3006 elem_p_idx = *intersection_with_next.begin();
3010 elem_p_idx = *(++(intersection_with_next.begin()));
3012 assert(elem_p_idx < UINT_MAX);
3027 double swap_distance = (this->mCellRearrangementRatio) * (this->mCellRearrangementThreshold);
3030 c_vector<double, 2> node_to_selected_elem = this->GetCentroidOfElement(elem_s_idx) - pRosetteNode->
rGetLocation();
3031 node_to_selected_elem /= norm_2(node_to_selected_elem);
3032 c_vector<double, 2> new_node_location = pRosetteNode->
rGetLocation() + (swap_distance * node_to_selected_elem);
3035 unsigned new_node_global_index = this->AddNode(
new Node<SPACE_DIM>(this->GetNumNodes(), new_node_location,
false));
3050 unsigned node_local_idx_in_elem_s = p_elem_s->
GetNodeLocalIndex(rosette_node_global_idx);
3051 p_elem_s->
AddNode(p_new_node, node_local_idx_in_elem_s);
3052 p_elem_s->
DeleteNode(node_local_idx_in_elem_s);
3055 unsigned node_local_idx_in_elem_n = p_elem_n->
GetNodeLocalIndex(rosette_node_global_idx);
3056 node_local_idx_in_elem_n = (node_local_idx_in_elem_n + p_elem_n->
GetNumNodes() - 1) % p_elem_n->
GetNumNodes();
3057 p_elem_n->
AddNode(p_new_node, node_local_idx_in_elem_n);
3060 unsigned node_local_idx_in_elem_p = p_elem_p->
GetNodeLocalIndex(rosette_node_global_idx);
3061 p_elem_p->
AddNode(p_new_node, node_local_idx_in_elem_p);
3064 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
3076 std::vector<Node<SPACE_DIM>* > protorosette_nodes;
3077 std::vector<Node<SPACE_DIM>* > rosette_nodes;
3080 unsigned num_nodes = this->GetNumAllNodes();
3081 for (
unsigned node_idx = 0 ; node_idx < num_nodes ; node_idx++)
3091 else if (node_rank == 4)
3096 protorosette_nodes.push_back(current_node);
3104 rosette_nodes.push_back(current_node);
3117 for (
unsigned node_idx = 0 ; node_idx < protorosette_nodes.size() ; node_idx++)
3126 this->PerformProtorosetteResolution(current_node);
3130 for (
unsigned node_idx = 0 ; node_idx < rosette_nodes.size() ; node_idx++)
3139 this->PerformRosetteRankDecrease(current_node);
3143 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
3145 unsigned indexA,
unsigned indexB, c_vector<double,2> intersection)
3156 c_vector<double, SPACE_DIM> vertexA = this->GetNode(indexA)->rGetLocation();
3157 c_vector<double, SPACE_DIM> vertexB = this->GetNode(indexB)->rGetLocation();
3158 c_vector<double, SPACE_DIM> vector_a_to_b = this->GetVectorFromAtoB(vertexA, vertexB);
3160 if (norm_2(vector_a_to_b) < 4.0*mCellRearrangementRatio*mCellRearrangementThreshold)
3162 WARNING(
"Trying to merge a node onto an edge which is too small.");
3164 c_vector<double, SPACE_DIM> centre_a_and_b = vertexA + 0.5*vector_a_to_b;
3166 vertexA = centre_a_and_b - 2.0*mCellRearrangementRatio*mCellRearrangementThreshold*vector_a_to_b/norm_2(vector_a_to_b);
3168 SetNode(indexA, vertex_A_point);
3170 vertexB = centre_a_and_b + 2.0*mCellRearrangementRatio*mCellRearrangementThreshold*vector_a_to_b/norm_2(vector_a_to_b);
3172 SetNode(indexB, vertex_B_point);
3174 intersection = centre_a_and_b;
3178 vector_a_to_b = this->GetVectorFromAtoB(vertexA, vertexB);
3179 c_vector<double,2> edge_ab_unit_vector = vector_a_to_b/norm_2(vector_a_to_b);
3190 if (norm_2(intersection - vertexA) < 2.0*mCellRearrangementRatio*mCellRearrangementThreshold)
3192 intersection = vertexA + 2.0*mCellRearrangementRatio*mCellRearrangementThreshold*edge_ab_unit_vector;
3194 if (norm_2(intersection - vertexB) < 2.0*mCellRearrangementRatio*mCellRearrangementThreshold)
3196 intersection = vertexB - 2.0*mCellRearrangementRatio*mCellRearrangementThreshold*edge_ab_unit_vector;
3198 return intersection;
unsigned DivideElement(VertexElement< ELEMENT_DIM, SPACE_DIM > *pElement, unsigned nodeAIndex, unsigned nodeBIndex, bool placeOriginalElementBelow=false)
void SetRosetteResolutionProbabilityPerTimestep(double rosetteResolutionProbabilityPerTimestep)
double GetRosetteResolutionProbabilityPerTimestep() const
void PerformIntersectionSwap(Node< SPACE_DIM > *pNode, unsigned elementIndex)
double GetCellRearrangementRatio() const
void SetDistanceForT3SwapChecking(double distanceForT3SwapChecking)
c_vector< double, 2 > WidenEdgeOrCorrectIntersectionLocationIfNecessary(unsigned indexA, unsigned indexB, c_vector< double, 2 > intersection)
std::vector< c_vector< double, SPACE_DIM > > GetLocationsOfT3Swaps()
void RemoveDeletedNodesAndElements(VertexElementMap &rElementMap)
void SetPoint(ChastePoint< SPACE_DIM > point)
void PerformRosetteRankDecrease(Node< SPACE_DIM > *pRosetteNode)
unsigned DivideElementAlongGivenAxis(VertexElement< ELEMENT_DIM, SPACE_DIM > *pElement, c_vector< double, SPACE_DIM > axisOfDivision, bool placeOriginalElementBelow=false)
unsigned randMod(unsigned base)
void SetAsBoundaryNode(bool value=true)
bool CheckForT2Swaps(VertexElementMap &rElementMap)
unsigned GetNodeGlobalIndex(unsigned localIndex) const
std::vector< c_vector< double, SPACE_DIM > > GetLocationsOfT1Swaps()
unsigned DivideElementAlongShortAxis(VertexElement< ELEMENT_DIM, SPACE_DIM > *pElement, bool placeOriginalElementBelow=false)
void PerformNodeMerge(Node< SPACE_DIM > *pNodeA, Node< SPACE_DIM > *pNodeB)
virtual bool CheckForSwapsFromShortEdges()
void SetProtorosetteResolutionProbabilityPerTimestep(double protorosetteResolutionProbabilityPerTimestep)
bool IsBoundaryNode() const
std::vector< VertexElement< ELEMENT_DIM-1, SPACE_DIM > * > mFaces
#define EXCEPTION(message)
double GetT2Threshold() const
unsigned AddNode(Node< SPACE_DIM > *pNewNode)
void ReplaceNode(Node< SPACE_DIM > *pOldNode, Node< SPACE_DIM > *pNewNode)
double GetCellRearrangementThreshold() const
void PerformVoidRemoval(Node< SPACE_DIM > *pNodeA, Node< SPACE_DIM > *pNodeB, Node< SPACE_DIM > *pNodeC)
std::set< unsigned > & rGetContainingElementIndices()
void SetIndex(unsigned index)
void ClearLocationsOfT1Swaps()
bool GetCheckForInternalIntersections() const
Node< SPACE_DIM > * GetNode(unsigned localIndex) const
void SetCellRearrangementThreshold(double cellRearrangementThreshold)
bool mMeshChangesDuringSimulation
double GetProtorosetteResolutionProbabilityPerTimestep() const
void PerformT3Swap(Node< SPACE_DIM > *pNode, unsigned elementIndex)
void AddNode(Node< SPACE_DIM > *pNode, const unsigned &rIndex)
std::vector< Node< SPACE_DIM > * > mNodes
virtual void SetNode(unsigned nodeIndex, ChastePoint< SPACE_DIM > point)
unsigned AddElement(VertexElement< ELEMENT_DIM, SPACE_DIM > *pNewElement)
void PerformProtorosetteResolution(Node< SPACE_DIM > *pProtorosetteNode)
bool CheckForIntersections()
void SetDeleted(unsigned index)
double GetDistanceForT3SwapChecking() const
unsigned GetNumNodes() const
void PerformRosetteRankIncrease(Node< SPACE_DIM > *pNodeA, Node< SPACE_DIM > *pNodeB)
unsigned GetNumNodes() const
void DeleteNodePriorToReMesh(unsigned index)
double GetProtorosetteFormationProbability() const
void SetNewIndex(unsigned oldIndex, unsigned newIndex)
static RandomNumberGenerator * Instance()
void ClearLocationsOfT3Swaps()
#define EXPORT_TEMPLATE_CLASS_ALL_DIMS(CLASS)
void SetProtorosetteFormationProbability(double protorosetteFormationProbability)
std::vector< VertexElement< ELEMENT_DIM, SPACE_DIM > * > mElements
virtual void HandleHighOrderJunctions(Node< SPACE_DIM > *pNodeA, Node< SPACE_DIM > *pNodeB)
void DivideEdge(Node< SPACE_DIM > *pNodeA, Node< SPACE_DIM > *pNodeB)
void SetCheckForInternalIntersections(bool checkForInternalIntersections)
const c_vector< double, SPACE_DIM > & rGetLocation() const
void AddElement(unsigned index)
void DeleteElementPriorToReMesh(unsigned index)
unsigned GetIndex() const
unsigned GetNumElements() const
void SetCellRearrangementRatio(double cellRearrangementRatio)
void RemoveDeletedNodes()
virtual ~MutableVertexMesh()
void DeleteNode(const unsigned &rIndex)
unsigned GetNumContainingElements() const
double GetNodeLocation(unsigned localIndex, unsigned dimension) const
void PerformT1Swap(Node< SPACE_DIM > *pNodeA, Node< SPACE_DIM > *pNodeB, std::set< unsigned > &rElementsContainingNodes)
unsigned GetIndex() const
unsigned GetNodeLocalIndex(unsigned globalIndex) const
void SetT2Threshold(double t2Threshold)
virtual void IdentifySwapType(Node< SPACE_DIM > *pNodeA, Node< SPACE_DIM > *pNodeB)
c_vector< double, SPACE_DIM > & rGetModifiableLocation()
c_vector< double, SPACE_DIM > GetLastT2SwapLocation()
void PerformT2Swap(VertexElement< ELEMENT_DIM, SPACE_DIM > &rElement)
void Resize(unsigned size)