39 #include "MutableMesh.hpp"
40 #include "OutputFileHandler.hpp"
51 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
58 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
61 this->mMeshChangesDuringSimulation =
true;
63 for (
unsigned index=0; index<nodes.size(); index++)
66 this->mNodes.push_back(p_temp_node);
73 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
79 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
82 if (mDeletedNodeIndices.empty())
84 pNewNode->
SetIndex(this->mNodes.size());
85 this->mNodes.push_back(pNewNode);
89 unsigned index = mDeletedNodeIndices.back();
91 mDeletedNodeIndices.pop_back();
92 delete this->mNodes[index];
93 this->mNodes[index] = pNewNode;
99 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
102 unsigned new_elt_index;
104 if (mDeletedElementIndices.empty())
106 new_elt_index = this->mElements.size();
107 this->mElements.push_back(pNewElement);
112 unsigned index = mDeletedElementIndices.back();
114 mDeletedElementIndices.pop_back();
115 delete this->mElements[index];
116 this->mElements[index] = pNewElement;
123 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
126 mDeletedElementIndices.clear();
127 mDeletedBoundaryElementIndices.clear();
128 mDeletedNodeIndices.clear();
134 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
137 return this->mBoundaryElements.size() - mDeletedBoundaryElementIndices.size();
140 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
143 return this->mElements.size() - mDeletedElementIndices.size();
146 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
149 return this->mNodes.size() - mDeletedNodeIndices.size();
161 assert(this->GetNode(boundaryNodeIndex)->IsBoundaryNode());
162 double scaleFactor = updatedPoint[0] / this->GetNode(boundaryNodeIndex)->GetPoint()[0];
164 for (
unsigned i=0; i < boundaryNodeIndex+1; i++)
166 temp = scaleFactor * this->mNodes[i]->GetPoint()[0];
168 this->mNodes[i]->SetPoint(newPoint);
173 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
178 this->mNodes[index]->SetPoint(point);
183 it != this->mNodes[index]->ContainingBoundaryElementsEnd();
188 this->GetBoundaryElement(*it)->CalculateWeightedDirection(this->mBoundaryElementWeightedDirections[ (*it) ],
189 this->mBoundaryElementJacobianDeterminants[ (*it) ]);
193 EXCEPTION(
"Moving node caused a boundary element to have a non-positive Jacobian determinant");
197 it != this->mNodes[index]->ContainingElementsEnd();
200 if (ELEMENT_DIM == SPACE_DIM)
204 this->GetElement(*it)->CalculateInverseJacobian(this->mElementJacobians[ (*it) ],
205 this->mElementJacobianDeterminants[ (*it) ],
206 this->mElementInverseJacobians[ (*it) ]);
210 EXCEPTION(
"Moving node caused an element to have a non-positive Jacobian determinant");
215 c_vector<double,SPACE_DIM> previous_direction = this->mElementWeightedDirections[ (*it) ];
217 this->GetElement(*it)->CalculateWeightedDirection(this->mElementWeightedDirections[ (*it) ],
218 this->mElementJacobianDeterminants[ (*it) ]);
220 if (inner_prod(previous_direction, this->mElementWeightedDirections[ (*it) ]) < 0)
222 EXCEPTION(
"Moving node caused an subspace element to change direction");
230 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
233 if (this->mNodes[index]->IsDeleted())
235 EXCEPTION(
"Trying to delete a deleted node");
237 unsigned target_index = (
unsigned)(-1);
238 bool found_target=
false;
240 !found_target && it != this->mNodes[index]->ContainingElementsEnd();
244 for (
unsigned i=0; i<=ELEMENT_DIM && !found_target; i++)
249 MoveMergeNode(index, target_index,
false);
263 MoveMergeNode(index, target_index);
266 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
269 assert(!this->mElements[index]->IsDeleted());
270 this->mElements[index]->MarkAsDeleted();
271 mDeletedElementIndices.push_back(index);
274 for (
unsigned node_index = 0; node_index < this->mElements[index]->GetNumNodes(); ++node_index)
276 if (this->mElements[index]->GetNode(node_index)->GetNumContainingElements() == 0u)
278 if (this->mElements[index]->GetNode(node_index)->GetNumBoundaryElements() == 0u)
280 this->mElements[index]->GetNode(node_index)->MarkAsDeleted();
281 mDeletedNodeIndices.push_back(this->mElements[index]->GetNode(node_index)->GetIndex());
283 else if (this->mElements[index]->GetNode(node_index)->GetNumBoundaryElements() == 1u && ELEMENT_DIM == 1)
285 std::set<unsigned> indices = this->mElements[index]->GetNode(node_index)->rGetContainingBoundaryElementIndices();
286 assert(indices.size() == 1u);
287 this->mBoundaryElements[*indices.begin()]->MarkAsDeleted();
288 mDeletedBoundaryElementIndices.push_back(*indices.begin());
290 this->mElements[index]->GetNode(node_index)->MarkAsDeleted();
291 mDeletedNodeIndices.push_back(this->mElements[index]->GetNode(node_index)->GetIndex());
297 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
300 this->mNodes[index]->MarkAsDeleted();
301 mDeletedNodeIndices.push_back(index);
304 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
306 unsigned targetIndex,
309 if (this->mNodes[index]->IsDeleted())
311 EXCEPTION(
"Trying to move a deleted node");
314 if (index == targetIndex)
316 EXCEPTION(
"Trying to merge a node with itself");
318 if (this->mNodes[index]->IsBoundaryNode())
320 if (!this->mNodes[targetIndex]->IsBoundaryNode())
322 EXCEPTION(
"A boundary node can only be moved on to another boundary node");
325 std::set<unsigned> unshared_element_indices;
326 std::set_difference(this->mNodes[index]->rGetContainingElementIndices().begin(),
327 this->mNodes[index]->rGetContainingElementIndices().end(),
328 this->mNodes[targetIndex]->rGetContainingElementIndices().begin(),
329 this->mNodes[targetIndex]->rGetContainingElementIndices().end(),
330 std::inserter(unshared_element_indices, unshared_element_indices.begin()));
333 if (unshared_element_indices.size() == this->mNodes[index]->rGetContainingElementIndices().size())
335 EXCEPTION(
"These nodes cannot be merged since they are not neighbours");
338 std::set<unsigned> unshared_boundary_element_indices;
339 std::set_difference(this->mNodes[index]->rGetContainingBoundaryElementIndices().begin(),
340 this->mNodes[index]->rGetContainingBoundaryElementIndices().end(),
341 this->mNodes[targetIndex]->rGetContainingBoundaryElementIndices().begin(),
342 this->mNodes[targetIndex]->rGetContainingBoundaryElementIndices().end(),
343 std::inserter(unshared_boundary_element_indices, unshared_boundary_element_indices.begin()));
346 if (this->mNodes[index]->IsBoundaryNode())
348 if (unshared_boundary_element_indices.size()
349 == this->mNodes[index]->rGetContainingBoundaryElementIndices().size())
352 EXCEPTION(
"These nodes cannot be merged since they are not neighbours on the boundary");
356 this->mNodes[index]->rGetModifiableLocation() = this->mNodes[targetIndex]->rGetLocation();
358 for (std::set<unsigned>::const_iterator element_iter=unshared_element_indices.begin();
359 element_iter != unshared_element_indices.end();
364 if (SPACE_DIM == ELEMENT_DIM)
366 this->GetElement(*element_iter)->CalculateInverseJacobian(this->mElementJacobians[(*element_iter)],
367 this->mElementJacobianDeterminants[(*element_iter)],
368 this->mElementInverseJacobians[ (*element_iter) ]);
372 this->GetElement(*element_iter)->CalculateWeightedDirection(this->mElementWeightedDirections[(*element_iter)],
373 this->mElementJacobianDeterminants[(*element_iter)]);
378 this->GetElement(*element_iter)->ReplaceNode(this->mNodes[index], this->mNodes[targetIndex]);
384 EXCEPTION(
"Moving node caused an element to have a non-positive Jacobian determinant");
388 for (std::set<unsigned>::const_iterator boundary_element_iter=
389 unshared_boundary_element_indices.begin();
390 boundary_element_iter != unshared_boundary_element_indices.end();
391 boundary_element_iter++)
394 this->GetBoundaryElement(*boundary_element_iter)->CalculateWeightedDirection(this->mBoundaryElementWeightedDirections[(*boundary_element_iter)],
395 this->mBoundaryElementJacobianDeterminants[(*boundary_element_iter)]);
399 this->GetBoundaryElement(*boundary_element_iter)->ReplaceNode(this->mNodes[index], this->mNodes[targetIndex]);
403 std::set<unsigned> shared_element_indices;
404 std::set_intersection(this->mNodes[index]->rGetContainingElementIndices().begin(),
405 this->mNodes[index]->rGetContainingElementIndices().end(),
406 this->mNodes[targetIndex]->rGetContainingElementIndices().begin(),
407 this->mNodes[targetIndex]->rGetContainingElementIndices().end(),
408 std::inserter(shared_element_indices, shared_element_indices.begin()));
410 for (std::set<unsigned>::const_iterator element_iter=shared_element_indices.begin();
411 element_iter != shared_element_indices.end();
416 this->GetElement(*element_iter)->MarkAsDeleted();
417 this->mElementJacobianDeterminants[ (*element_iter) ] = 0.0;
418 mDeletedElementIndices.push_back(*element_iter);
422 this->mElementJacobianDeterminants[ (*element_iter) ] = 0.0;
427 std::set<unsigned> shared_boundary_element_indices;
428 std::set_intersection(this->mNodes[index]->rGetContainingBoundaryElementIndices().begin(),
429 this->mNodes[index]->rGetContainingBoundaryElementIndices().end(),
430 this->mNodes[targetIndex]->rGetContainingBoundaryElementIndices().begin(),
431 this->mNodes[targetIndex]->rGetContainingBoundaryElementIndices().end(),
432 std::inserter(shared_boundary_element_indices, shared_boundary_element_indices.begin()));
434 for (std::set<unsigned>::const_iterator boundary_element_iter=shared_boundary_element_indices.begin();
435 boundary_element_iter != shared_boundary_element_indices.end();
436 boundary_element_iter++)
440 this->GetBoundaryElement(*boundary_element_iter)->MarkAsDeleted();
441 this->mBoundaryElementJacobianDeterminants[ (*boundary_element_iter) ] = 0.0;
442 mDeletedBoundaryElementIndices.push_back(*boundary_element_iter);
446 this->mBoundaryElementJacobianDeterminants[ (*boundary_element_iter) ] = 0.0;
447 this->mBoundaryElementWeightedDirections[ (*boundary_element_iter) ] = zero_vector<double>(SPACE_DIM);
453 this->mNodes[index]->MarkAsDeleted();
454 mDeletedNodeIndices.push_back(index);
458 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
466 EXCEPTION(
"RefineElement could not be started (point is not in element)");
475 for (
unsigned i = 0; i < ELEMENT_DIM; i++)
479 unsigned new_elt_index;
480 if (mDeletedElementIndices.empty())
482 new_elt_index = this->mElements.size();
486 new_elt_index = mDeletedElementIndices.back();
487 mDeletedElementIndices.pop_back();
494 p_new_element->
UpdateNode(ELEMENT_DIM-1-i, this->mNodes[new_node_index]);
497 if ((
unsigned) new_elt_index == this->mElements.size())
499 this->mElements.push_back(p_new_element);
503 delete this->mElements[new_elt_index];
504 this->mElements[new_elt_index] = p_new_element;
509 pElement->
UpdateNode(ELEMENT_DIM, this->mNodes[new_node_index]);
511 return new_node_index;
514 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
517 if (!this->mNodes[index]->IsBoundaryNode() )
519 EXCEPTION(
" You may only delete a boundary node ");
522 this->mNodes[index]->MarkAsDeleted();
523 mDeletedNodeIndices.push_back(index);
526 typename std::vector<Node<SPACE_DIM>*>::iterator b_node_iter
527 = std::find(this->mBoundaryNodes.begin(), this->mBoundaryNodes.end(), this->mNodes[index]);
528 this->mBoundaryNodes.erase(b_node_iter);
531 std::set<unsigned> boundary_element_indices = this->mNodes[index]->rGetContainingBoundaryElementIndices();
532 std::set<unsigned>::const_iterator boundary_element_indices_iterator = boundary_element_indices.begin();
533 while (boundary_element_indices_iterator != boundary_element_indices.end())
535 BoundaryElement<ELEMENT_DIM-1, SPACE_DIM>* p_boundary_element = this->GetBoundaryElement(*boundary_element_indices_iterator);
536 p_boundary_element->MarkAsDeleted();
537 mDeletedBoundaryElementIndices.push_back(*boundary_element_indices_iterator);
538 boundary_element_indices_iterator++;
542 std::set<unsigned> element_indices = this->mNodes[index]->rGetContainingElementIndices();
543 std::set<unsigned>::const_iterator element_indices_iterator = element_indices.begin();
544 while (element_indices_iterator != element_indices.end())
547 for (
unsigned i=0; i<p_element->
GetNumNodes(); i++)
554 this->mBoundaryNodes.push_back(p_node);
558 mDeletedElementIndices.push_back(p_element->
GetIndex());
559 element_indices_iterator++;
563 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
566 assert(!mAddedNodes);
567 map.
Resize(this->GetNumAllNodes());
569 std::vector<Element<ELEMENT_DIM, SPACE_DIM> *> live_elements;
571 for (
unsigned i=0; i<this->mElements.size(); i++)
573 assert(i==this->mElements[i]->GetIndex());
574 if (this->mElements[i]->IsDeleted())
576 delete this->mElements[i];
580 live_elements.push_back(this->mElements[i]);
582 unsigned this_element_index = this->mElements[i]->GetIndex();
583 if (SPACE_DIM == ELEMENT_DIM)
585 this->mElementJacobians[live_elements.size()-1] = this->mElementJacobians[this_element_index];
586 this->mElementInverseJacobians[live_elements.size()-1] = this->mElementInverseJacobians[this_element_index];
590 this->mElementWeightedDirections[live_elements.size()-1] = this->mElementWeightedDirections[this_element_index];
592 this->mElementJacobianDeterminants[live_elements.size()-1] = this->mElementJacobianDeterminants[this_element_index];
596 assert(mDeletedElementIndices.size() == this->mElements.size()-live_elements.size());
597 mDeletedElementIndices.clear();
598 this->mElements = live_elements;
599 unsigned num_elements = this->mElements.size();
601 if (SPACE_DIM == ELEMENT_DIM)
603 this->mElementJacobians.resize(num_elements);
604 this->mElementInverseJacobians.resize(num_elements);
608 this->mElementWeightedDirections.resize(num_elements);
610 this->mElementJacobianDeterminants.resize(num_elements);
612 std::vector<Node<SPACE_DIM> *> live_nodes;
613 for (
unsigned i=0; i<this->mNodes.size(); i++)
615 if (this->mNodes[i]->IsDeleted())
617 delete this->mNodes[i];
622 live_nodes.push_back(this->mNodes[i]);
625 map.
SetNewIndex(i, (
unsigned)(live_nodes.size()-1));
629 assert(mDeletedNodeIndices.size() == this->mNodes.size()-live_nodes.size());
630 this->mNodes = live_nodes;
631 mDeletedNodeIndices.clear();
633 std::vector<
BoundaryElement<ELEMENT_DIM-1, SPACE_DIM> *> live_boundary_elements;
634 for (
unsigned i=0; i<this->mBoundaryElements.size(); i++)
636 if (this->mBoundaryElements[i]->IsDeleted())
638 delete this->mBoundaryElements[i];
642 live_boundary_elements.push_back(this->mBoundaryElements[i]);
644 this->mBoundaryElementWeightedDirections[live_boundary_elements.size()-1] = this->mBoundaryElementWeightedDirections[this->mBoundaryElements[i]->GetIndex()];
645 this->mBoundaryElementJacobianDeterminants[live_boundary_elements.size()-1] = this->mBoundaryElementJacobianDeterminants[this->mBoundaryElements[i]->GetIndex()];
649 assert(mDeletedBoundaryElementIndices.size() == this->mBoundaryElements.size()-live_boundary_elements.size());
650 this->mBoundaryElements = live_boundary_elements;
651 mDeletedBoundaryElementIndices.clear();
653 unsigned num_boundary_elements = this->mBoundaryElements.size();
655 this->mBoundaryElementWeightedDirections.resize(num_boundary_elements);
656 this->mBoundaryElementJacobianDeterminants.resize(num_boundary_elements);
658 for (
unsigned i=0; i<this->mNodes.size(); i++)
663 for (
unsigned i=0; i<this->mElements.size(); i++)
666 this->mElements[i]->ResetIndex(i);
669 for (
unsigned i=0; i<this->mBoundaryElements.size(); i++)
671 this->mBoundaryElements[i]->ResetIndex(i);
675 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
679 assert( ELEMENT_DIM == SPACE_DIM );
683 if (GetNumNodes() <= SPACE_DIM)
685 EXCEPTION(
"The number of nodes must exceed the spatial dimension.");
689 map.
Resize(this->GetNumAllNodes());
690 if (mAddedNodes || !mDeletedNodeIndices.empty())
693 if (this->mpDistributedVectorFactory)
695 delete this->mpDistributedVectorFactory;
702 std::vector<c_vector<double, SPACE_DIM> > old_node_locations;
703 unsigned new_index = 0;
704 for (
unsigned i=0; i<this->GetNumAllNodes(); i++)
706 if (this->mNodes[i]->IsDeleted())
713 old_node_locations.push_back(this->mNodes[i]->rGetLocation());
722 for (
unsigned node_index=0; node_index<old_node_locations.size(); node_index++)
725 bool is_boundary_node = (node_index==0 || node_index==old_node_locations.size()-1);
728 this->mNodes.push_back(p_node);
730 if (is_boundary_node)
732 this->mBoundaryNodes.push_back(p_node);
737 std::map<double, unsigned> location_index_map;
738 for (
unsigned i=0; i<this->mNodes.size(); i++)
740 location_index_map[this->mNodes[i]->rGetLocation()[0]] = this->mNodes[i]->
GetIndex();
744 std::vector<unsigned> node_indices_ordered_spatially;
745 for (std::map<double, unsigned>::iterator iter = location_index_map.begin();
746 iter != location_index_map.end();
749 node_indices_ordered_spatially.push_back(iter->second);
753 this->mElements.reserve(old_node_locations.size()-1);
754 for (
unsigned element_index=0; element_index<old_node_locations.size()-1; element_index++)
756 std::vector<Node<SPACE_DIM>*> nodes;
757 for (
unsigned j=0; j<2; j++)
759 unsigned global_node_index = node_indices_ordered_spatially[element_index + j];
760 assert(global_node_index < this->mNodes.size());
761 nodes.push_back(this->mNodes[global_node_index]);
767 std::vector<Node<SPACE_DIM>*> nodes;
768 nodes.push_back(this->mNodes[0]);
772 nodes.push_back(this->mNodes[old_node_locations.size()-1]);
775 this->RefreshJacobianCachedData();
777 else if (SPACE_DIM==2)
779 struct triangulateio mesher_input, mesher_output;
780 this->InitialiseTriangulateIo(mesher_input);
781 this->InitialiseTriangulateIo(mesher_output);
783 this->ExportToMesher(map, mesher_input);
786 triangulate((
char*)
"Qze", &mesher_input, &mesher_output,
nullptr);
788 this->ImportFromMesher(mesher_output, mesher_output.numberoftriangles, mesher_output.trianglelist, mesher_output.numberofedges, mesher_output.edgelist, mesher_output.edgemarkerlist);
791 this->FreeTriangulateIo(mesher_input);
792 this->FreeTriangulateIo(mesher_output);
797 class tetgen::tetgenio mesher_input, mesher_output;
799 this->ExportToMesher(map, mesher_input);
802 tetgen::tetrahedralize((
char*)
"Qz", &mesher_input, &mesher_output);
804 this->ImportFromMesher(mesher_output, mesher_output.numberoftetrahedra, mesher_output.tetrahedronlist, mesher_output.numberoftrifaces, mesher_output.trifacelist,
nullptr);
808 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
815 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
818 assert(ELEMENT_DIM == 2);
819 assert(SPACE_DIM == 3);
821 std::vector<c_vector<unsigned, 5> > history;
823 bool long_edge_exists =
true;
825 while (long_edge_exists)
827 std::set<std::pair<unsigned, unsigned> > long_edges;
831 elem_iter != this->GetElementIteratorEnd();
834 unsigned num_nodes = ELEMENT_DIM+1;
837 for (
unsigned local_index=0; local_index<num_nodes; local_index++)
841 unsigned local_index_plus_one = (local_index+1)%num_nodes;
845 double distance_between_nodes = this->GetDistanceBetweenNodes(p_node_a->
GetIndex(), p_node_b->
GetIndex());
847 if (distance_between_nodes > cutoffLength)
851 std::pair<unsigned, unsigned> long_edge(p_node_a->
GetIndex(),p_node_b->
GetIndex());
852 long_edges.insert(long_edge);
856 std::pair<unsigned, unsigned> long_edge(p_node_b->
GetIndex(),p_node_a->
GetIndex());
857 long_edges.insert(long_edge);
863 if (long_edges.size() > 0)
865 while (long_edges.size() > 0)
867 double longest_edge = 0.0;
868 std::set<std::pair<unsigned, unsigned> >::iterator longest_edge_iter;
871 for (std::set<std::pair<unsigned, unsigned> >::iterator edge_iter = long_edges.begin();
872 edge_iter != long_edges.end();
875 unsigned node_a_global_index = edge_iter->first;
876 unsigned node_b_global_index = edge_iter->second;
878 double distance_between_nodes = this->GetDistanceBetweenNodes(node_a_global_index, node_b_global_index);
880 if (distance_between_nodes > longest_edge)
882 longest_edge = distance_between_nodes;
883 longest_edge_iter = edge_iter;
886 assert(longest_edge >0);
888 c_vector<unsigned, 3> new_node_index = SplitEdge(this->GetNode(longest_edge_iter->first), this->GetNode(longest_edge_iter->second));
890 c_vector<unsigned, 5> node_set;
891 node_set(0) = new_node_index[0];
892 node_set(1) = longest_edge_iter->first;
893 node_set(2) = longest_edge_iter->second;
894 node_set(3) = new_node_index[1];
895 node_set(4) = new_node_index[2];
896 history.push_back(node_set);
899 long_edges.erase(*longest_edge_iter);
904 long_edge_exists =
false;
911 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
914 c_vector<unsigned, 3> new_node_index_vector;
919 std::set<unsigned> intersection_elements;
920 std::set_intersection(elements_of_node_a.begin(), elements_of_node_a.end(),
921 elements_of_node_b.begin(), elements_of_node_b.end(),
922 std::inserter(intersection_elements, intersection_elements.begin()));
927 bool is_boundary_node = intersection_elements.size() == 1;
931 unsigned new_node_index = this->AddNode(p_new_node);
933 new_node_index_vector[0] = new_node_index;
935 unsigned counter = 1;
937 for (std::set<unsigned>::const_iterator it = intersection_elements.begin(); it != intersection_elements.end(); ++it)
939 unsigned elementIndex = *it;
947 AddElement(p_new_element);
950 p_new_element->
ReplaceNode(pNodeA, this->mNodes[new_node_index]);
953 p_original_element->
ReplaceNode(pNodeB, this->mNodes[new_node_index]);
977 new_node_index_vector[counter] = other_node_index;
989 return new_node_index_vector;
992 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
995 assert(ELEMENT_DIM == SPACE_DIM);
997 std::set<unsigned> neighbouring_elements_indices;
998 std::set< Element<ELEMENT_DIM,SPACE_DIM> *> neighbouring_elements;
999 std::set<unsigned> neighbouring_nodes_indices;
1002 for (
unsigned i=0; i<num_nodes; i++)
1006 for (std::set<unsigned>::const_iterator it = neighbouring_elements_indices.begin();
1007 it != neighbouring_elements_indices.end();
1010 neighbouring_elements.insert(this->GetElement(*it));
1013 neighbouring_elements.erase(pElement);
1016 typedef typename std::set<Element<ELEMENT_DIM,SPACE_DIM> *>::const_iterator
ElementIterator;
1018 for (ElementIterator it = neighbouring_elements.begin();
1019 it != neighbouring_elements.end();
1022 for (
unsigned i=0; i<num_nodes; i++)
1024 neighbouring_nodes_indices.insert((*it)->GetNodeGlobalIndex(i));
1029 for (
unsigned i = 0; i < num_nodes; i++)
1035 c_vector<double, SPACE_DIM+1> this_circum_centre;
1040 c_vector<double, ELEMENT_DIM> circum_centre;
1041 for (
unsigned i=0; i<ELEMENT_DIM; i++)
1043 circum_centre[i] = this_circum_centre[i];
1046 for (std::set<unsigned>::const_iterator it = neighbouring_nodes_indices.begin();
1047 it != neighbouring_nodes_indices.end();
1050 c_vector<double, ELEMENT_DIM> node_location;
1051 node_location = this->GetNode(*it)->rGetLocation();
1054 node_location -= circum_centre;
1057 double squared_distance = inner_prod(node_location, node_location);
1061 if (squared_distance < this_circum_centre[ELEMENT_DIM])
1064 double radius = sqrt(this_circum_centre[ELEMENT_DIM]);
1065 double distance = radius - sqrt(squared_distance);
1068 if (distance/radius > maxPenetration)
1077 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1082 for (
unsigned i=0; i<this->mElements.size(); i++)
1085 if (!this->mElements[i]->IsDeleted())
1088 if (CheckIsVoronoi(this->mElements[i], maxPenetration) ==
false)
std::vector< c_vector< unsigned, 5 > > SplitLongEdges(double cutoffLength)
c_vector< double, SPACE_DIM+1 > CalculateCircumsphere(c_matrix< double, SPACE_DIM, ELEMENT_DIM > &rJacobian, c_matrix< double, ELEMENT_DIM, SPACE_DIM > &rInverseJacobian)
c_vector< double, DIM > & rGetLocation()
void SetAsBoundaryNode(bool value=true)
unsigned GetNodeGlobalIndex(unsigned localIndex) const
void DeleteNodePriorToReMesh(unsigned index)
void SetIndex(unsigned index)
void UpdateNode(const unsigned &rIndex, Node< SPACE_DIM > *pNode)
void ResetIndex(unsigned index)
#define EXCEPTION(message)
unsigned RefineElement(Element< ELEMENT_DIM, SPACE_DIM > *pElement, ChastePoint< SPACE_DIM > point)
void RescaleMeshFromBoundaryNode(ChastePoint< 1 > updatedPoint, unsigned boundaryNodeIndex)
void ReplaceNode(Node< SPACE_DIM > *pOldNode, Node< SPACE_DIM > *pNewNode)
void ReIndex(NodeMap &map)
bool CheckIsVoronoi(Element< ELEMENT_DIM, SPACE_DIM > *pElement, double maxPenetration)
std::set< unsigned > & rGetContainingElementIndices()
void SetIndex(unsigned index)
virtual void SetNode(unsigned index, ChastePoint< SPACE_DIM > point, bool concreteMove=true)
unsigned GetNumElements() const
virtual unsigned AddNode(Node< SPACE_DIM > *pNewNode)
void SetNewIndex(unsigned oldIndex, unsigned newIndex)
Node< SPACE_DIM > * GetNode(unsigned localIndex) const
unsigned GetNumNodes() const
virtual void DeleteNode(unsigned index)
bool mMeshChangesDuringSimulation
unsigned GetNumNodes() const
void SetDeleted(unsigned index)
const unsigned UNSIGNED_UNSET
virtual void DeleteElement(unsigned index)
#define EXPORT_TEMPLATE_CLASS_ALL_DIMS(CLASS)
unsigned AddElement(Element< ELEMENT_DIM, SPACE_DIM > *pNewElement)
const c_vector< double, SPACE_DIM > & rGetLocation() const
void MoveMergeNode(unsigned index, unsigned targetIndex, bool concreteMove=true)
unsigned GetIndex() const
bool IncludesPoint(const ChastePoint< SPACE_DIM > &rTestPoint, bool strict=false)
unsigned GetNumBoundaryElements() const
unsigned GetIndex() const
c_vector< unsigned, 3 > SplitEdge(Node< SPACE_DIM > *pNodeA, Node< SPACE_DIM > *pNodeB)
void DeleteBoundaryNodeAt(unsigned index)
void Resize(unsigned size)