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());
298 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
301 this->mNodes[index]->MarkAsDeleted();
302 mDeletedNodeIndices.push_back(index);
305 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
307 unsigned targetIndex,
310 if (this->mNodes[index]->IsDeleted())
312 EXCEPTION(
"Trying to move a deleted node");
315 if (index == targetIndex)
317 EXCEPTION(
"Trying to merge a node with itself");
319 if (this->mNodes[index]->IsBoundaryNode())
321 if (!this->mNodes[targetIndex]->IsBoundaryNode())
323 EXCEPTION(
"A boundary node can only be moved on to another boundary node");
326 std::set<unsigned> unshared_element_indices;
327 std::set_difference(this->mNodes[index]->rGetContainingElementIndices().begin(),
328 this->mNodes[index]->rGetContainingElementIndices().end(),
329 this->mNodes[targetIndex]->rGetContainingElementIndices().begin(),
330 this->mNodes[targetIndex]->rGetContainingElementIndices().end(),
331 std::inserter(unshared_element_indices, unshared_element_indices.begin()));
334 if (unshared_element_indices.size() == this->mNodes[index]->rGetContainingElementIndices().size())
336 EXCEPTION(
"These nodes cannot be merged since they are not neighbours");
339 std::set<unsigned> unshared_boundary_element_indices;
340 std::set_difference(this->mNodes[index]->rGetContainingBoundaryElementIndices().begin(),
341 this->mNodes[index]->rGetContainingBoundaryElementIndices().end(),
342 this->mNodes[targetIndex]->rGetContainingBoundaryElementIndices().begin(),
343 this->mNodes[targetIndex]->rGetContainingBoundaryElementIndices().end(),
344 std::inserter(unshared_boundary_element_indices, unshared_boundary_element_indices.begin()));
347 if (this->mNodes[index]->IsBoundaryNode())
349 if (unshared_boundary_element_indices.size()
350 == this->mNodes[index]->rGetContainingBoundaryElementIndices().size())
353 EXCEPTION(
"These nodes cannot be merged since they are not neighbours on the boundary");
357 this->mNodes[index]->rGetModifiableLocation() = this->mNodes[targetIndex]->rGetLocation();
359 for (std::set<unsigned>::const_iterator element_iter=unshared_element_indices.begin();
360 element_iter != unshared_element_indices.end();
365 if (SPACE_DIM == ELEMENT_DIM)
367 this->GetElement(*element_iter)->CalculateInverseJacobian(this->mElementJacobians[(*element_iter)],
368 this->mElementJacobianDeterminants[(*element_iter)],
369 this->mElementInverseJacobians[ (*element_iter) ]);
373 this->GetElement(*element_iter)->CalculateWeightedDirection(this->mElementWeightedDirections[(*element_iter)],
374 this->mElementJacobianDeterminants[(*element_iter)]);
379 this->GetElement(*element_iter)->ReplaceNode(this->mNodes[index], this->mNodes[targetIndex]);
385 EXCEPTION(
"Moving node caused an element to have a non-positive Jacobian determinant");
389 for (std::set<unsigned>::const_iterator boundary_element_iter=
390 unshared_boundary_element_indices.begin();
391 boundary_element_iter != unshared_boundary_element_indices.end();
392 boundary_element_iter++)
395 this->GetBoundaryElement(*boundary_element_iter)->CalculateWeightedDirection(this->mBoundaryElementWeightedDirections[(*boundary_element_iter)],
396 this->mBoundaryElementJacobianDeterminants[(*boundary_element_iter)]);
400 this->GetBoundaryElement(*boundary_element_iter)->ReplaceNode(this->mNodes[index], this->mNodes[targetIndex]);
404 std::set<unsigned> shared_element_indices;
405 std::set_intersection(this->mNodes[index]->rGetContainingElementIndices().begin(),
406 this->mNodes[index]->rGetContainingElementIndices().end(),
407 this->mNodes[targetIndex]->rGetContainingElementIndices().begin(),
408 this->mNodes[targetIndex]->rGetContainingElementIndices().end(),
409 std::inserter(shared_element_indices, shared_element_indices.begin()));
411 for (std::set<unsigned>::const_iterator element_iter=shared_element_indices.begin();
412 element_iter != shared_element_indices.end();
417 this->GetElement(*element_iter)->MarkAsDeleted();
418 this->mElementJacobianDeterminants[ (*element_iter) ] = 0.0;
419 mDeletedElementIndices.push_back(*element_iter);
423 this->mElementJacobianDeterminants[ (*element_iter) ] = 0.0;
428 std::set<unsigned> shared_boundary_element_indices;
429 std::set_intersection(this->mNodes[index]->rGetContainingBoundaryElementIndices().begin(),
430 this->mNodes[index]->rGetContainingBoundaryElementIndices().end(),
431 this->mNodes[targetIndex]->rGetContainingBoundaryElementIndices().begin(),
432 this->mNodes[targetIndex]->rGetContainingBoundaryElementIndices().end(),
433 std::inserter(shared_boundary_element_indices, shared_boundary_element_indices.begin()));
435 for (std::set<unsigned>::const_iterator boundary_element_iter=shared_boundary_element_indices.begin();
436 boundary_element_iter != shared_boundary_element_indices.end();
437 boundary_element_iter++)
441 this->GetBoundaryElement(*boundary_element_iter)->MarkAsDeleted();
442 this->mBoundaryElementJacobianDeterminants[ (*boundary_element_iter) ] = 0.0;
443 mDeletedBoundaryElementIndices.push_back(*boundary_element_iter);
447 this->mBoundaryElementJacobianDeterminants[ (*boundary_element_iter) ] = 0.0;
448 this->mBoundaryElementWeightedDirections[ (*boundary_element_iter) ] = zero_vector<double>(SPACE_DIM);
454 this->mNodes[index]->MarkAsDeleted();
455 mDeletedNodeIndices.push_back(index);
459 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
467 EXCEPTION(
"RefineElement could not be started (point is not in element)");
476 for (
unsigned i = 0; i < ELEMENT_DIM; i++)
480 unsigned new_elt_index;
481 if (mDeletedElementIndices.empty())
483 new_elt_index = this->mElements.size();
487 new_elt_index = mDeletedElementIndices.back();
488 mDeletedElementIndices.pop_back();
495 p_new_element->
UpdateNode(ELEMENT_DIM-1-i, this->mNodes[new_node_index]);
498 if ((
unsigned) new_elt_index == this->mElements.size())
500 this->mElements.push_back(p_new_element);
504 delete this->mElements[new_elt_index];
505 this->mElements[new_elt_index] = p_new_element;
510 pElement->
UpdateNode(ELEMENT_DIM, this->mNodes[new_node_index]);
512 return new_node_index;
515 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
518 if (!this->mNodes[index]->IsBoundaryNode() )
520 EXCEPTION(
" You may only delete a boundary node ");
523 this->mNodes[index]->MarkAsDeleted();
524 mDeletedNodeIndices.push_back(index);
527 typename std::vector<Node<SPACE_DIM>*>::iterator b_node_iter
528 = std::find(this->mBoundaryNodes.begin(), this->mBoundaryNodes.end(), this->mNodes[index]);
529 this->mBoundaryNodes.erase(b_node_iter);
532 std::set<unsigned> boundary_element_indices = this->mNodes[index]->rGetContainingBoundaryElementIndices();
533 std::set<unsigned>::const_iterator boundary_element_indices_iterator = boundary_element_indices.begin();
534 while (boundary_element_indices_iterator != boundary_element_indices.end())
536 BoundaryElement<ELEMENT_DIM-1, SPACE_DIM>* p_boundary_element = this->GetBoundaryElement(*boundary_element_indices_iterator);
537 p_boundary_element->MarkAsDeleted();
538 mDeletedBoundaryElementIndices.push_back(*boundary_element_indices_iterator);
539 boundary_element_indices_iterator++;
543 std::set<unsigned> element_indices = this->mNodes[index]->rGetContainingElementIndices();
544 std::set<unsigned>::const_iterator element_indices_iterator = element_indices.begin();
545 while (element_indices_iterator != element_indices.end())
548 for (
unsigned i=0; i<p_element->
GetNumNodes(); i++)
555 this->mBoundaryNodes.push_back(p_node);
559 mDeletedElementIndices.push_back(p_element->
GetIndex());
560 element_indices_iterator++;
564 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
567 assert(!mAddedNodes);
568 map.
Resize(this->GetNumAllNodes());
570 std::vector<Element<ELEMENT_DIM, SPACE_DIM> *> live_elements;
572 for (
unsigned i=0; i<this->mElements.size(); i++)
574 assert(i==this->mElements[i]->GetIndex());
575 if (this->mElements[i]->IsDeleted())
577 delete this->mElements[i];
581 live_elements.push_back(this->mElements[i]);
583 unsigned this_element_index = this->mElements[i]->GetIndex();
584 if (SPACE_DIM == ELEMENT_DIM)
586 this->mElementJacobians[live_elements.size()-1] = this->mElementJacobians[this_element_index];
587 this->mElementInverseJacobians[live_elements.size()-1] = this->mElementInverseJacobians[this_element_index];
591 this->mElementWeightedDirections[live_elements.size()-1] = this->mElementWeightedDirections[this_element_index];
593 this->mElementJacobianDeterminants[live_elements.size()-1] = this->mElementJacobianDeterminants[this_element_index];
597 assert(mDeletedElementIndices.size() == this->mElements.size()-live_elements.size());
598 mDeletedElementIndices.clear();
599 this->mElements = live_elements;
600 unsigned num_elements = this->mElements.size();
602 if (SPACE_DIM == ELEMENT_DIM)
604 this->mElementJacobians.resize(num_elements);
605 this->mElementInverseJacobians.resize(num_elements);
609 this->mElementWeightedDirections.resize(num_elements);
611 this->mElementJacobianDeterminants.resize(num_elements);
613 std::vector<Node<SPACE_DIM> *> live_nodes;
614 for (
unsigned i=0; i<this->mNodes.size(); i++)
616 if (this->mNodes[i]->IsDeleted())
618 delete this->mNodes[i];
623 live_nodes.push_back(this->mNodes[i]);
626 map.
SetNewIndex(i, (
unsigned)(live_nodes.size()-1));
630 assert(mDeletedNodeIndices.size() == this->mNodes.size()-live_nodes.size());
631 this->mNodes = live_nodes;
632 mDeletedNodeIndices.clear();
634 std::vector<
BoundaryElement<ELEMENT_DIM-1, SPACE_DIM> *> live_boundary_elements;
635 for (
unsigned i=0; i<this->mBoundaryElements.size(); i++)
637 if (this->mBoundaryElements[i]->IsDeleted())
639 delete this->mBoundaryElements[i];
643 live_boundary_elements.push_back(this->mBoundaryElements[i]);
645 this->mBoundaryElementWeightedDirections[live_boundary_elements.size()-1] = this->mBoundaryElementWeightedDirections[this->mBoundaryElements[i]->GetIndex()];
646 this->mBoundaryElementJacobianDeterminants[live_boundary_elements.size()-1] = this->mBoundaryElementJacobianDeterminants[this->mBoundaryElements[i]->GetIndex()];
650 assert(mDeletedBoundaryElementIndices.size() == this->mBoundaryElements.size()-live_boundary_elements.size());
651 this->mBoundaryElements = live_boundary_elements;
652 mDeletedBoundaryElementIndices.clear();
654 unsigned num_boundary_elements = this->mBoundaryElements.size();
656 this->mBoundaryElementWeightedDirections.resize(num_boundary_elements);
657 this->mBoundaryElementJacobianDeterminants.resize(num_boundary_elements);
659 for (
unsigned i=0; i<this->mNodes.size(); i++)
664 for (
unsigned i=0; i<this->mElements.size(); i++)
667 this->mElements[i]->ResetIndex(i);
670 for (
unsigned i=0; i<this->mBoundaryElements.size(); i++)
672 this->mBoundaryElements[i]->ResetIndex(i);
676 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
680 #define COVERAGE_IGNORE
681 assert( ELEMENT_DIM == SPACE_DIM );
682 #undef COVERAGE_IGNORE
686 if (GetNumNodes() <= SPACE_DIM)
688 EXCEPTION(
"The number of nodes must exceed the spatial dimension.");
692 map.
Resize(this->GetNumAllNodes());
693 if (mAddedNodes || !mDeletedNodeIndices.empty())
696 if (this->mpDistributedVectorFactory)
698 delete this->mpDistributedVectorFactory;
705 std::vector<c_vector<double, SPACE_DIM> > old_node_locations;
706 unsigned new_index = 0;
707 for (
unsigned i=0; i<this->GetNumAllNodes(); i++)
709 if (this->mNodes[i]->IsDeleted())
716 old_node_locations.push_back(this->mNodes[i]->rGetLocation());
725 for (
unsigned node_index=0; node_index<old_node_locations.size(); node_index++)
728 this->mNodes.push_back(p_node);
731 if ( node_index==0 || node_index==old_node_locations.size()-1 )
733 this->mBoundaryNodes.push_back(p_node);
738 std::map<double, unsigned> location_index_map;
739 for (
unsigned i=0; i<this->mNodes.size(); i++)
741 location_index_map[this->mNodes[i]->rGetLocation()[0]] = this->mNodes[i]->
GetIndex();
745 std::vector<unsigned> node_indices_ordered_spatially;
746 for (std::map<double, unsigned>::iterator iter = location_index_map.begin();
747 iter != location_index_map.end();
750 node_indices_ordered_spatially.push_back(iter->second);
754 this->mElements.reserve(old_node_locations.size()-1);
755 for (
unsigned element_index=0; element_index<old_node_locations.size()-1; element_index++)
757 std::vector<Node<SPACE_DIM>*> nodes;
758 for (
unsigned j=0; j<2; j++)
760 unsigned global_node_index = node_indices_ordered_spatially[element_index + j];
761 assert(global_node_index < this->mNodes.size());
762 nodes.push_back(this->mNodes[global_node_index]);
768 std::vector<Node<SPACE_DIM>*> nodes;
769 nodes.push_back(this->mNodes[0]);
773 nodes.push_back(this->mNodes[old_node_locations.size()-1]);
776 this->RefreshJacobianCachedData();
778 else if (SPACE_DIM==2)
780 struct triangulateio mesher_input, mesher_output;
781 this->InitialiseTriangulateIo(mesher_input);
782 this->InitialiseTriangulateIo(mesher_output);
784 this->ExportToMesher(map, mesher_input);
787 triangulate((
char*)
"Qze", &mesher_input, &mesher_output, NULL);
789 this->ImportFromMesher(mesher_output, mesher_output.numberoftriangles, mesher_output.trianglelist, mesher_output.numberofedges, mesher_output.edgelist, mesher_output.edgemarkerlist);
792 this->FreeTriangulateIo(mesher_input);
793 this->FreeTriangulateIo(mesher_output);
798 class tetgen::tetgenio mesher_input, mesher_output;
800 this->ExportToMesher(map, mesher_input);
803 tetgen::tetrahedralize((
char*)
"Qz", &mesher_input, &mesher_output);
805 this->ImportFromMesher(mesher_output, mesher_output.numberoftetrahedra, mesher_output.tetrahedronlist, mesher_output.numberoftrifaces, mesher_output.trifacelist, NULL);
809 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
816 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
819 assert(ELEMENT_DIM == 2);
820 assert(SPACE_DIM == 3);
822 std::vector<c_vector<unsigned, 5> > history;
825 bool long_edge_exists =
true;
827 while(long_edge_exists)
829 std::set<std::pair<unsigned, unsigned> > long_edges;
833 elem_iter != this->GetElementIteratorEnd();
836 unsigned num_nodes = ELEMENT_DIM+1;
839 for (
unsigned local_index=0; local_index<num_nodes; local_index++)
843 unsigned local_index_plus_one = (local_index+1)%num_nodes;
847 double distance_between_nodes = this->GetDistanceBetweenNodes(p_node_a->
GetIndex(), p_node_b->
GetIndex());
849 if (distance_between_nodes > cutoffLength)
853 std::pair<unsigned, unsigned> long_edge(p_node_a->
GetIndex(),p_node_b->
GetIndex());
854 long_edges.insert(long_edge);
858 std::pair<unsigned, unsigned> long_edge(p_node_b->
GetIndex(),p_node_a->
GetIndex());
859 long_edges.insert(long_edge);
865 if (long_edges.size() > 0)
867 while (long_edges.size() > 0)
869 double longest_edge = 0.0;
870 std::set<std::pair<unsigned, unsigned> >::iterator longest_edge_iter;
873 for (std::set<std::pair<unsigned, unsigned> >::iterator edge_iter = long_edges.begin();
874 edge_iter != long_edges.end();
877 unsigned node_a_global_index = edge_iter->first;
878 unsigned node_b_global_index = edge_iter->second;
880 double distance_between_nodes = this->GetDistanceBetweenNodes(node_a_global_index, node_b_global_index);
882 if (distance_between_nodes > longest_edge)
884 longest_edge = distance_between_nodes;
885 longest_edge_iter = edge_iter;
888 assert(longest_edge >0);
890 c_vector<unsigned, 3> new_node_index = SplitEdge(this->GetNode(longest_edge_iter->first), this->GetNode(longest_edge_iter->second));
892 c_vector<unsigned, 5> node_set;
893 node_set(0) = new_node_index[0];
894 node_set(1) = longest_edge_iter->first;
895 node_set(2) = longest_edge_iter->second;
896 node_set(3) = new_node_index[1];
897 node_set(4) = new_node_index[2];
898 history.push_back(node_set);
901 long_edges.erase(*longest_edge_iter);
906 long_edge_exists =
false;
913 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
916 c_vector<unsigned, 3> new_node_index_vector;
921 std::set<unsigned> intersection_elements;
922 std::set_intersection(elements_of_node_a.begin(), elements_of_node_a.end(),
923 elements_of_node_b.begin(), elements_of_node_b.end(),
924 std::inserter(intersection_elements, intersection_elements.begin()));
929 bool is_boundary_node = intersection_elements.size() == 1;
933 unsigned new_node_index = this->AddNode(p_new_node);
935 new_node_index_vector[0] = new_node_index;
937 unsigned counter = 1;
939 for (std::set<unsigned>::const_iterator it = intersection_elements.begin(); it != intersection_elements.end(); ++it)
941 unsigned elementIndex = *it;
949 AddElement(p_new_element);
952 p_new_element->
ReplaceNode(pNodeA, this->mNodes[new_node_index]);
955 p_original_element->
ReplaceNode(pNodeB, this->mNodes[new_node_index]);
979 new_node_index_vector[counter] = other_node_index;
991 return new_node_index_vector;
994 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
997 assert(ELEMENT_DIM == SPACE_DIM);
999 std::set<unsigned> neighbouring_elements_indices;
1000 std::set< Element<ELEMENT_DIM,SPACE_DIM> *> neighbouring_elements;
1001 std::set<unsigned> neighbouring_nodes_indices;
1004 for (
unsigned i=0; i<num_nodes; i++)
1008 for (std::set<unsigned>::const_iterator it = neighbouring_elements_indices.begin();
1009 it != neighbouring_elements_indices.end();
1012 neighbouring_elements.insert(this->GetElement(*it));
1015 neighbouring_elements.erase(pElement);
1018 typedef typename std::set<Element<ELEMENT_DIM,SPACE_DIM> *>::const_iterator
ElementIterator;
1020 for (ElementIterator it = neighbouring_elements.begin();
1021 it != neighbouring_elements.end();
1024 for (
unsigned i=0; i<num_nodes; i++)
1026 neighbouring_nodes_indices.insert((*it)->GetNodeGlobalIndex(i));
1031 for (
unsigned i = 0; i < num_nodes; i++)
1037 c_vector<double, SPACE_DIM+1> this_circum_centre;
1042 c_vector<double, ELEMENT_DIM> circum_centre;
1043 for (
unsigned i=0; i<ELEMENT_DIM; i++)
1045 circum_centre[i] = this_circum_centre[i];
1048 for (std::set<unsigned>::const_iterator it = neighbouring_nodes_indices.begin();
1049 it != neighbouring_nodes_indices.end();
1052 c_vector<double, ELEMENT_DIM> node_location = this->GetNode(*it)->rGetLocation();
1055 node_location -= circum_centre;
1058 double squared_distance = inner_prod(node_location, node_location);
1062 if (squared_distance < this_circum_centre[ELEMENT_DIM])
1065 double radius = sqrt(this_circum_centre[ELEMENT_DIM]);
1066 double distance = radius - sqrt(squared_distance);
1069 if (distance/radius > maxPenetration)
1078 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1083 for (
unsigned i=0; i<this->mElements.size(); i++)
1086 if (!this->mElements[i]->IsDeleted())
1089 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)