465 EXCEPTION(
"RefineElement could not be started (point is not in element)");
474 for (
unsigned i = 0; i < ELEMENT_DIM; i++)
478 unsigned new_elt_index;
479 if (mDeletedElementIndices.empty())
481 new_elt_index = this->mElements.size();
485 new_elt_index = mDeletedElementIndices.back();
486 mDeletedElementIndices.pop_back();
492 p_new_element->UpdateNode(ELEMENT_DIM-1-i, this->mNodes[new_node_index]);
495 if ((
unsigned) new_elt_index == this->mElements.size())
497 this->mElements.push_back(p_new_element);
501 delete this->mElements[new_elt_index];
502 this->mElements[new_elt_index] = p_new_element;
507 pElement->
UpdateNode(ELEMENT_DIM, this->mNodes[new_node_index]);
509 return new_node_index;
515 if (!this->mNodes[index]->IsBoundaryNode() )
517 EXCEPTION(
" You may only delete a boundary node ");
520 this->mNodes[index]->MarkAsDeleted();
521 mDeletedNodeIndices.push_back(index);
524 auto b_node_iter = std::find(this->mBoundaryNodes.begin(), this->mBoundaryNodes.end(), this->mNodes[index]);
525 this->mBoundaryNodes.erase(b_node_iter);
528 std::set<unsigned> boundary_element_indices = this->mNodes[index]->rGetContainingBoundaryElementIndices();
529 std::set<unsigned>::const_iterator boundary_element_indices_iterator = boundary_element_indices.begin();
530 while (boundary_element_indices_iterator != boundary_element_indices.end())
532 BoundaryElement<ELEMENT_DIM-1, SPACE_DIM>* p_boundary_element = this->GetBoundaryElement(*boundary_element_indices_iterator);
533 p_boundary_element->MarkAsDeleted();
534 mDeletedBoundaryElementIndices.push_back(*boundary_element_indices_iterator);
535 boundary_element_indices_iterator++;
539 std::set<unsigned> element_indices = this->mNodes[index]->rGetContainingElementIndices();
540 std::set<unsigned>::const_iterator element_indices_iterator = element_indices.begin();
541 while (element_indices_iterator != element_indices.end())
544 for (
unsigned i=0; i<p_element->
GetNumNodes(); i++)
551 this->mBoundaryNodes.push_back(p_node);
555 mDeletedElementIndices.push_back(p_element->
GetIndex());
556 element_indices_iterator++;
563 assert(!mAddedNodes);
564 map.
Resize(this->GetNumAllNodes());
566 std::vector<Element<ELEMENT_DIM, SPACE_DIM> *> live_elements;
568 for (
unsigned i=0; i<this->mElements.size(); i++)
570 assert(i==this->mElements[i]->GetIndex());
571 if (this->mElements[i]->IsDeleted())
573 delete this->mElements[i];
577 live_elements.push_back(this->mElements[i]);
579 unsigned this_element_index = this->mElements[i]->GetIndex();
580 if (SPACE_DIM == ELEMENT_DIM)
582 this->mElementJacobians[live_elements.size()-1] = this->mElementJacobians[this_element_index];
583 this->mElementInverseJacobians[live_elements.size()-1] = this->mElementInverseJacobians[this_element_index];
587 this->mElementWeightedDirections[live_elements.size()-1] = this->mElementWeightedDirections[this_element_index];
589 this->mElementJacobianDeterminants[live_elements.size()-1] = this->mElementJacobianDeterminants[this_element_index];
593 assert(mDeletedElementIndices.size() == this->mElements.size()-live_elements.size());
594 mDeletedElementIndices.clear();
595 this->mElements = live_elements;
596 unsigned num_elements = this->mElements.size();
598 if (SPACE_DIM == ELEMENT_DIM)
600 this->mElementJacobians.resize(num_elements);
601 this->mElementInverseJacobians.resize(num_elements);
605 this->mElementWeightedDirections.resize(num_elements);
607 this->mElementJacobianDeterminants.resize(num_elements);
609 std::vector<Node<SPACE_DIM> *> live_nodes;
610 for (
unsigned i=0; i<this->mNodes.size(); i++)
612 if (this->mNodes[i]->IsDeleted())
614 delete this->mNodes[i];
619 live_nodes.push_back(this->mNodes[i]);
622 map.
SetNewIndex(i, (
unsigned)(live_nodes.size()-1));
626 assert(mDeletedNodeIndices.size() == this->mNodes.size()-live_nodes.size());
627 this->mNodes = live_nodes;
628 mDeletedNodeIndices.clear();
630 std::vector<
BoundaryElement<ELEMENT_DIM-1, SPACE_DIM> *> live_boundary_elements;
631 for (
unsigned i=0; i<this->mBoundaryElements.size(); i++)
633 if (this->mBoundaryElements[i]->IsDeleted())
635 delete this->mBoundaryElements[i];
639 live_boundary_elements.push_back(this->mBoundaryElements[i]);
641 this->mBoundaryElementWeightedDirections[live_boundary_elements.size()-1] = this->mBoundaryElementWeightedDirections[this->mBoundaryElements[i]->GetIndex()];
642 this->mBoundaryElementJacobianDeterminants[live_boundary_elements.size()-1] = this->mBoundaryElementJacobianDeterminants[this->mBoundaryElements[i]->GetIndex()];
646 assert(mDeletedBoundaryElementIndices.size() == this->mBoundaryElements.size()-live_boundary_elements.size());
647 this->mBoundaryElements = live_boundary_elements;
648 mDeletedBoundaryElementIndices.clear();
650 unsigned num_boundary_elements = this->mBoundaryElements.size();
652 this->mBoundaryElementWeightedDirections.resize(num_boundary_elements);
653 this->mBoundaryElementJacobianDeterminants.resize(num_boundary_elements);
655 for (
unsigned i=0; i<this->mNodes.size(); i++)
657 this->mNodes[i]->SetIndex(i);
660 for (
unsigned i=0; i<this->mElements.size(); i++)
662 this->mElements[i]->ResetIndex(i);
665 for (
unsigned i=0; i<this->mBoundaryElements.size(); i++)
667 this->mBoundaryElements[i]->ResetIndex(i);
675 assert( ELEMENT_DIM == SPACE_DIM );
679 if (GetNumNodes() <= SPACE_DIM)
681 EXCEPTION(
"The number of nodes must exceed the spatial dimension.");
685 map.
Resize(this->GetNumAllNodes());
686 if (mAddedNodes || !mDeletedNodeIndices.empty())
689 if (this->mpDistributedVectorFactory)
691 delete this->mpDistributedVectorFactory;
698 std::vector<c_vector<double, SPACE_DIM> > old_node_locations;
699 unsigned new_index = 0;
700 for (
unsigned i=0; i<this->GetNumAllNodes(); i++)
702 if (this->mNodes[i]->IsDeleted())
709 old_node_locations.push_back(this->mNodes[i]->rGetLocation());
718 for (
unsigned node_index=0; node_index<old_node_locations.size(); node_index++)
721 bool is_boundary_node = (node_index==0 || node_index==old_node_locations.size()-1);
724 this->mNodes.push_back(p_node);
726 if (is_boundary_node)
728 this->mBoundaryNodes.push_back(p_node);
733 std::map<double, unsigned> location_index_map;
734 for (
unsigned i=0; i<this->mNodes.size(); i++)
736 location_index_map[this->mNodes[i]->rGetLocation()[0]] = this->mNodes[i]->GetIndex();
740 std::vector<unsigned> node_indices_ordered_spatially;
741 for (std::map<double, unsigned>::iterator iter = location_index_map.begin();
742 iter != location_index_map.end();
745 node_indices_ordered_spatially.push_back(iter->second);
749 this->mElements.reserve(old_node_locations.size()-1);
750 for (
unsigned element_index=0; element_index<old_node_locations.size()-1; element_index++)
752 std::vector<Node<SPACE_DIM>*> nodes;
753 for (
unsigned j=0; j<2; j++)
755 unsigned global_node_index = node_indices_ordered_spatially[element_index + j];
756 assert(global_node_index < this->mNodes.size());
757 nodes.push_back(this->mNodes[global_node_index]);
763 std::vector<Node<SPACE_DIM>*> nodes;
764 nodes.push_back(this->mNodes[0]);
768 nodes.push_back(this->mNodes[old_node_locations.size()-1]);
771 this->RefreshJacobianCachedData();
773 else if (SPACE_DIM==2)
775 struct triangulateio mesher_input, mesher_output;
776 this->InitialiseTriangulateIo(mesher_input);
777 this->InitialiseTriangulateIo(mesher_output);
779 this->ExportToMesher(map, mesher_input);
782 triangulate((
char*)
"Qze", &mesher_input, &mesher_output,
nullptr);
784 this->ImportFromMesher(mesher_output, mesher_output.numberoftriangles, mesher_output.trianglelist, mesher_output.numberofedges, mesher_output.edgelist, mesher_output.edgemarkerlist);
787 this->FreeTriangulateIo(mesher_input);
788 this->FreeTriangulateIo(mesher_output);
793 class tetgen::tetgenio mesher_input, mesher_output;
795 this->ExportToMesher(map, mesher_input);
798 tetgen::tetrahedralize((
char*)
"Qz", &mesher_input, &mesher_output);
800 this->ImportFromMesher(mesher_output, mesher_output.numberoftetrahedra, mesher_output.tetrahedronlist, mesher_output.numberoftrifaces, mesher_output.trifacelist,
nullptr);
814 assert(ELEMENT_DIM == 2);
815 assert(SPACE_DIM == 3);
817 std::vector<c_vector<unsigned, 5> > history;
819 bool long_edge_exists =
true;
821 while (long_edge_exists)
823 std::set<std::pair<unsigned, unsigned> > long_edges;
827 elem_iter != this->GetElementIteratorEnd();
830 unsigned num_nodes = ELEMENT_DIM+1;
833 for (
unsigned local_index=0; local_index<num_nodes; local_index++)
837 unsigned local_index_plus_one = (local_index+1)%num_nodes;
841 double distance_between_nodes = this->GetDistanceBetweenNodes(p_node_a->
GetIndex(), p_node_b->
GetIndex());
843 if (distance_between_nodes > cutoffLength)
847 std::pair<unsigned, unsigned> long_edge(p_node_a->
GetIndex(),p_node_b->
GetIndex());
848 long_edges.insert(long_edge);
852 std::pair<unsigned, unsigned> long_edge(p_node_b->
GetIndex(),p_node_a->
GetIndex());
853 long_edges.insert(long_edge);
859 if (long_edges.size() > 0)
861 while (long_edges.size() > 0)
863 double longest_edge = 0.0;
864 std::set<std::pair<unsigned, unsigned> >::iterator longest_edge_iter;
867 for (std::set<std::pair<unsigned, unsigned> >::iterator edge_iter = long_edges.begin();
868 edge_iter != long_edges.end();
871 unsigned node_a_global_index = edge_iter->first;
872 unsigned node_b_global_index = edge_iter->second;
874 double distance_between_nodes = this->GetDistanceBetweenNodes(node_a_global_index, node_b_global_index);
876 if (distance_between_nodes > longest_edge)
878 longest_edge = distance_between_nodes;
879 longest_edge_iter = edge_iter;
882 assert(longest_edge >0);
884 c_vector<unsigned, 3> new_node_index = SplitEdge(this->GetNode(longest_edge_iter->first), this->GetNode(longest_edge_iter->second));
886 c_vector<unsigned, 5> node_set;
887 node_set(0) = new_node_index[0];
888 node_set(1) = longest_edge_iter->first;
889 node_set(2) = longest_edge_iter->second;
890 node_set(3) = new_node_index[1];
891 node_set(4) = new_node_index[2];
892 history.push_back(node_set);
895 long_edges.erase(*longest_edge_iter);
900 long_edge_exists =
false;
910 c_vector<unsigned, 3> new_node_index_vector;
915 std::set<unsigned> intersection_elements;
916 std::set_intersection(elements_of_node_a.begin(), elements_of_node_a.end(),
917 elements_of_node_b.begin(), elements_of_node_b.end(),
918 std::inserter(intersection_elements, intersection_elements.begin()));
923 bool is_boundary_node = intersection_elements.size() == 1;
927 unsigned new_node_index = this->AddNode(p_new_node);
929 new_node_index_vector[0] = new_node_index;
931 unsigned counter = 1;
933 for (std::set<unsigned>::const_iterator it = intersection_elements.begin(); it != intersection_elements.end(); ++it)
935 unsigned elementIndex = *it;
943 AddElement(p_new_element);
946 p_new_element->ReplaceNode(pNodeA, this->mNodes[new_node_index]);
949 p_original_element->
ReplaceNode(pNodeB, this->mNodes[new_node_index]);
973 new_node_index_vector[counter] = other_node_index;
985 return new_node_index_vector;
991 assert(ELEMENT_DIM == SPACE_DIM);
993 std::set<unsigned> neighbouring_elements_indices;
994 std::set< Element<ELEMENT_DIM,SPACE_DIM> *> neighbouring_elements;
995 std::set<unsigned> neighbouring_nodes_indices;
998 for (
unsigned i=0; i<num_nodes; i++)
1002 for (std::set<unsigned>::const_iterator it = neighbouring_elements_indices.begin();
1003 it != neighbouring_elements_indices.end();
1006 neighbouring_elements.insert(this->GetElement(*it));
1009 neighbouring_elements.erase(pElement);
1012 typedef typename std::set<Element<ELEMENT_DIM,SPACE_DIM> *>::const_iterator
ElementIterator;
1015 it != neighbouring_elements.end();
1018 for (
unsigned i=0; i<num_nodes; i++)
1020 neighbouring_nodes_indices.insert((*it)->GetNodeGlobalIndex(i));
1025 for (
unsigned i = 0; i < num_nodes; i++)
1031 c_vector<double, SPACE_DIM+1> this_circum_centre = zero_vector<double>(SPACE_DIM+1);
1036 c_vector<double, ELEMENT_DIM> circum_centre = zero_vector<double>(ELEMENT_DIM);
1037 for (
unsigned i=0; i<ELEMENT_DIM; i++)
1039 circum_centre[i] = this_circum_centre[i];
1042 for (std::set<unsigned>::const_iterator it = neighbouring_nodes_indices.begin();
1043 it != neighbouring_nodes_indices.end();
1046 c_vector<double, ELEMENT_DIM> node_location = this->GetNode(*it)->rGetLocation();
1049 node_location -= circum_centre;
1052 double squared_distance = inner_prod(node_location, node_location);
1056 if (squared_distance < this_circum_centre[ELEMENT_DIM])
1059 double radius = sqrt(this_circum_centre[ELEMENT_DIM]);
1060 double distance = radius - sqrt(squared_distance);
1063 if (distance/radius > maxPenetration)