Chaste Release::3.1
MutableVertexMesh.cpp
00001 /*
00002 
00003 Copyright (c) 2005-2012, University of Oxford.
00004 All rights reserved.
00005 
00006 University of Oxford means the Chancellor, Masters and Scholars of the
00007 University of Oxford, having an administrative office at Wellington
00008 Square, Oxford OX1 2JD, UK.
00009 
00010 This file is part of Chaste.
00011 
00012 Redistribution and use in source and binary forms, with or without
00013 modification, are permitted provided that the following conditions are met:
00014  * Redistributions of source code must retain the above copyright notice,
00015    this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright notice,
00017    this list of conditions and the following disclaimer in the documentation
00018    and/or other materials provided with the distribution.
00019  * Neither the name of the University of Oxford nor the names of its
00020    contributors may be used to endorse or promote products derived from this
00021    software without specific prior written permission.
00022 
00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033 
00034 */
00035 
00036 #include "MutableVertexMesh.hpp"
00037 #include "RandomNumberGenerator.hpp"
00038 #include "UblasCustomFunctions.hpp"
00039 #include "Warnings.hpp"
00040 #include "LogFile.hpp"
00041 
00042 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00043 MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::MutableVertexMesh(std::vector<Node<SPACE_DIM>*> nodes,
00044                                                std::vector<VertexElement<ELEMENT_DIM,SPACE_DIM>*> vertexElements,
00045                                                double cellRearrangementThreshold,
00046                                                double t2Threshold,
00047                                                double cellRearrangementRatio)
00048     : mCellRearrangementThreshold(cellRearrangementThreshold),
00049       mCellRearrangementRatio(cellRearrangementRatio),
00050       mT2Threshold(t2Threshold),
00051       mCheckForInternalIntersections(false)
00052 {
00053     assert(cellRearrangementThreshold > 0.0);
00054     assert(t2Threshold > 0.0);
00055 
00056     // Reset member variables and clear mNodes and mElements
00057     Clear();
00058 
00059     // Populate mNodes and mElements
00060     for (unsigned node_index=0; node_index<nodes.size(); node_index++)
00061     {
00062         Node<SPACE_DIM>* p_temp_node = nodes[node_index];
00063         this->mNodes.push_back(p_temp_node);
00064     }
00065     for (unsigned elem_index=0; elem_index<vertexElements.size(); elem_index++)
00066     {
00067         VertexElement<ELEMENT_DIM,SPACE_DIM>* p_temp_vertex_element = vertexElements[elem_index];
00068         this->mElements.push_back(p_temp_vertex_element);
00069     }
00070     // In 3D, populate mFaces
00071     if (SPACE_DIM == 3)
00072     {
00073         // Use a std::set to keep track of which faces have been added to mFaces
00074         std::set<unsigned> faces_counted;
00075 
00076         // Loop over mElements
00077         for (unsigned elem_index=0; elem_index<this->mElements.size(); elem_index++)
00078         {
00079             // Loop over faces of this element
00080             for (unsigned face_index=0; face_index<this->mElements[elem_index]->GetNumFaces(); face_index++)
00081             {
00082                 VertexElement<ELEMENT_DIM-1, SPACE_DIM>* p_face = this->mElements[elem_index]->GetFace(face_index);
00083 
00084                 // If this face is not already contained in mFaces, add it, and update faces_counted
00085                 if (faces_counted.find(p_face->GetIndex()) == faces_counted.end())
00086                 {
00087                     this->mFaces.push_back(p_face);
00088                     faces_counted.insert(p_face->GetIndex());
00089                 }
00090             }
00091         }
00092     }
00093 
00094     // Register elements with nodes
00095     for (unsigned index=0; index<this->mElements.size(); index++)
00096     {
00097         VertexElement<ELEMENT_DIM,SPACE_DIM>* p_temp_vertex_element = this->mElements[index];
00098         for (unsigned node_index=0; node_index<p_temp_vertex_element->GetNumNodes(); node_index++)
00099         {
00100             Node<SPACE_DIM>* p_temp_node = p_temp_vertex_element->GetNode(node_index);
00101             p_temp_node->AddElement(p_temp_vertex_element->GetIndex());
00102         }
00103     }
00104 
00105     this->mMeshChangesDuringSimulation = true;
00106 }
00107 
00108 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00109 MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::MutableVertexMesh()
00110     : mCellRearrangementThreshold(0.01), // Overwritten as soon as archiving is complete
00111       mCellRearrangementRatio(1.5), // Overwritten as soon as archiving is complete
00112       mT2Threshold(0.001), // Overwritten as soon as archiving is complete
00113       mCheckForInternalIntersections(false) // Overwritten as soon as archiving is complete
00114 {
00115     this->mMeshChangesDuringSimulation = true;
00116     Clear();
00117 }
00118 
00119 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00120 MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::~MutableVertexMesh()
00121 {
00122     Clear();
00123 }
00124 
00125 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00126 double MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::GetCellRearrangementThreshold() const
00127 {
00128     return mCellRearrangementThreshold;
00129 }
00130 
00131 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00132 double MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::GetT2Threshold() const
00133 {
00134     return mT2Threshold;
00135 }
00136 
00137 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00138 double MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::GetCellRearrangementRatio() const
00139 {
00140     return mCellRearrangementRatio;
00141 }
00142 
00143 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00144 bool MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::GetCheckForInternalIntersections() const
00145 {
00146     return mCheckForInternalIntersections;
00147 }
00148 
00149 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00150 void MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::SetCellRearrangementThreshold(double cellRearrangementThreshold)
00151 {
00152     mCellRearrangementThreshold = cellRearrangementThreshold;
00153 }
00154 
00155 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00156 void MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::SetT2Threshold(double t2Threshold)
00157 {
00158     mT2Threshold = t2Threshold;
00159 }
00160 
00161 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00162 void MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::SetCellRearrangementRatio(double cellRearrangementRatio)
00163 {
00164     mCellRearrangementRatio = cellRearrangementRatio;
00165 }
00166 
00167 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00168 void MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::SetCheckForInternalIntersections(bool checkForInternalIntersections)
00169 {
00170     mCheckForInternalIntersections=checkForInternalIntersections;
00171 }
00172 
00173 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00174 void MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::Clear()
00175 {
00176     mDeletedNodeIndices.clear();
00177     mDeletedElementIndices.clear();
00178 
00179     VertexMesh<ELEMENT_DIM, SPACE_DIM>::Clear();
00180 }
00181 
00182 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00183 unsigned MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::GetNumNodes() const
00184 {
00185     return this->mNodes.size() - mDeletedNodeIndices.size();
00186 }
00187 
00188 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00189 unsigned MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::GetNumElements() const
00190 {
00191     return this->mElements.size() - mDeletedElementIndices.size();
00192 }
00193 
00194 //\todo deal with boundary elements in vertex meshes #1392.
00195 //template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00196 //unsigned AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetNumBoundaryElements() const
00197 //{
00198 //    return mBoundaryElements.size();
00199 //}
00200 
00201 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00202 std::vector< c_vector<double, SPACE_DIM> > MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::GetLocationsOfT1Swaps()
00203 {
00204     return mLocationsOfT1Swaps;
00205 }
00206 
00207 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00208 std::vector< c_vector<double, SPACE_DIM> > MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::GetLocationsOfT3Swaps()
00209 {
00210     return mLocationsOfT3Swaps;
00211 }
00212 
00213 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00214 void MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::ClearLocationsOfT1Swaps()
00215 {
00216     mLocationsOfT1Swaps.clear();
00217 }
00218 
00219 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00220 void MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::ClearLocationsOfT3Swaps()
00221 {
00222     mLocationsOfT3Swaps.clear();
00223 }
00224 
00225 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00226 unsigned MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::AddNode(Node<SPACE_DIM>* pNewNode)
00227 {
00228     if (mDeletedNodeIndices.empty())
00229     {
00230         pNewNode->SetIndex(this->mNodes.size());
00231         this->mNodes.push_back(pNewNode);
00232     }
00233     else
00234     {
00235         unsigned index = mDeletedNodeIndices.back();
00236         pNewNode->SetIndex(index);
00237         mDeletedNodeIndices.pop_back();
00238         delete this->mNodes[index];
00239         this->mNodes[index] = pNewNode;
00240     }
00241     return pNewNode->GetIndex();
00242 }
00243 
00244 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00245 unsigned MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::AddElement(VertexElement<ELEMENT_DIM,SPACE_DIM>* pNewElement)
00246 {
00247     unsigned new_element_index = pNewElement->GetIndex();
00248 
00249     if (new_element_index == this->mElements.size())
00250     {
00251         this->mElements.push_back(pNewElement);
00252     }
00253     else
00254     {
00255         this->mElements[new_element_index] = pNewElement;
00256     }
00257     pNewElement->RegisterWithNodes();
00258     return pNewElement->GetIndex();
00259 }
00260 
00261 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00262 void MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::SetNode(unsigned nodeIndex, ChastePoint<SPACE_DIM> point)
00263 {
00264     this->mNodes[nodeIndex]->SetPoint(point);
00265 }
00266 
00267 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00268 unsigned MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::DivideElementAlongGivenAxis(VertexElement<ELEMENT_DIM,SPACE_DIM>* pElement,
00269                                                                                 c_vector<double, SPACE_DIM> axisOfDivision,
00270                                                                                 bool placeOriginalElementBelow)
00271 {
00272     // Make sure that we are in the correct dimension - this code will be eliminated at compile time
00273     assert(SPACE_DIM == 2); // only works in 2D at present
00274     assert(ELEMENT_DIM == SPACE_DIM);
00275 
00276     // Get the centroid of the element
00277     c_vector<double, SPACE_DIM> centroid = this->GetCentroidOfElement(pElement->GetIndex());
00278 
00279     // Create a vector perpendicular to the axis of division
00280     c_vector<double, SPACE_DIM> perp_axis;
00281     perp_axis(0) = -axisOfDivision(1);
00282     perp_axis(1) = axisOfDivision(0);
00283 
00284     /*
00285      * Find which edges the axis of division crosses by finding any node
00286      * that lies on the opposite side of the axis of division to its next
00287      * neighbour.
00288      */
00289     unsigned num_nodes = pElement->GetNumNodes();
00290     std::vector<unsigned> intersecting_nodes;
00291     for (unsigned i=0; i<num_nodes; i++)
00292     {
00293         bool is_current_node_on_left = (inner_prod(this->GetVectorFromAtoB(pElement->GetNodeLocation(i), centroid), perp_axis) >= 0);
00294         bool is_next_node_on_left = (inner_prod(this->GetVectorFromAtoB(pElement->GetNodeLocation((i+1)%num_nodes), centroid), perp_axis) >= 0);
00295 
00296         if (is_current_node_on_left != is_next_node_on_left)
00297         {
00298             intersecting_nodes.push_back(i);
00299         }
00300     }
00301 
00302     // If the axis of division does not cross two edges then we cannot proceed
00303     if (intersecting_nodes.size() != 2)
00304     {
00305         EXCEPTION("Cannot proceed with element division: the given axis of division does not cross two edges of the element");
00306     }
00307 
00308     std::vector<unsigned> division_node_global_indices;
00309     unsigned nodes_added = 0;
00310 
00311     // Find the intersections between the axis of division and the element edges
00312     for (unsigned i=0; i<intersecting_nodes.size(); i++)
00313     {
00314         /*
00315          * Get pointers to the nodes forming the edge into which one new node will be inserted.
00316          *
00317          * Note that when we use the first entry of intersecting_nodes to add a node,
00318          * we change the local index of the second entry of intersecting_nodes in
00319          * pElement, so must account for this by moving one entry further on.
00320          */
00321         Node<SPACE_DIM>* p_node_A = pElement->GetNode((intersecting_nodes[i]+nodes_added)%pElement->GetNumNodes());
00322         Node<SPACE_DIM>* p_node_B = pElement->GetNode((intersecting_nodes[i]+nodes_added+1)%pElement->GetNumNodes());
00323 
00324         // Find the indices of the elements owned by each node on the edge into which one new node will be inserted
00325         std::set<unsigned> elems_containing_node_A = p_node_A->rGetContainingElementIndices();
00326         std::set<unsigned> elems_containing_node_B = p_node_B->rGetContainingElementIndices();
00327 
00328         c_vector<double, SPACE_DIM> position_a = p_node_A->rGetLocation();
00329         c_vector<double, SPACE_DIM> position_b = p_node_B->rGetLocation();
00330         c_vector<double, SPACE_DIM> a_to_b = this->GetVectorFromAtoB(position_a, position_b);
00331 
00332         c_vector<double, SPACE_DIM> intersection;
00333 
00334         if (norm_2(a_to_b) < 2.0*mCellRearrangementRatio*mCellRearrangementThreshold)
00335         {
00336             WARNING("Edge is too small for normal division, putting node in the middle of a and b, there may be T1Swaps straight away.");
00338             intersection = position_a + 0.5*a_to_b;
00339         }
00340         else
00341         {
00342             // Find the location of the intersection
00343             double determinant = a_to_b[0]*axisOfDivision[1] - a_to_b[1]*axisOfDivision[0];
00344 
00345             c_vector<double, SPACE_DIM> moved_centroid = position_a + this->GetVectorFromAtoB(position_a, centroid); // allow for periodicity and other metrics
00346 
00347             double alpha = (moved_centroid[0]*a_to_b[1] - position_a[0]*a_to_b[1]
00348                             -moved_centroid[1]*a_to_b[0] + position_a[1]*a_to_b[0])/determinant;
00349 
00350             intersection = moved_centroid + alpha*axisOfDivision;
00351 
00352             /*
00353              * If then new node is too close to one of the edge nodes, then reposition it
00354              * a distance mCellRearrangementRatio*mCellRearrangementThreshold further along the edge.
00355              */
00356             c_vector<double, SPACE_DIM> a_to_intersection = this->GetVectorFromAtoB(position_a, intersection);
00357             if (norm_2(a_to_intersection) < mCellRearrangementThreshold)
00358             {
00359                 intersection = position_a + mCellRearrangementRatio*mCellRearrangementThreshold*a_to_b/norm_2(a_to_b);
00360             }
00361 
00362             c_vector<double, SPACE_DIM> b_to_intersection = this->GetVectorFromAtoB(position_b, intersection);
00363             if (norm_2(b_to_intersection) < mCellRearrangementThreshold)
00364             {
00365                 assert(norm_2(a_to_intersection) > mCellRearrangementThreshold); // to prevent moving intersection back to original position
00366 
00367                 intersection = position_b - mCellRearrangementRatio*mCellRearrangementThreshold*a_to_b/norm_2(a_to_b);
00368             }
00369         }
00370 
00371         /*
00372          * The new node is boundary node if the 2 nodes are boundary nodes and the elements don't look like
00373          *   ___A___
00374          *  |   |   |
00375          *  |___|___|
00376          *      B
00377          */
00378 
00379         bool is_boundary = false;
00380         if (p_node_A->IsBoundaryNode() && p_node_B->IsBoundaryNode())
00381         {
00382             if (elems_containing_node_A.size() !=2 ||
00383                 elems_containing_node_B.size() !=2 ||
00384                 elems_containing_node_A != elems_containing_node_B)
00385             {
00386                 is_boundary = true;
00387             }
00388         }
00389 
00390         // Add a new node to the mesh at the location of the intersection
00391         unsigned new_node_global_index = this->AddNode(new Node<SPACE_DIM>(0, is_boundary, intersection[0], intersection[1]));
00392         nodes_added++;
00393 
00394         // Now make sure node is added to neighbouring elements
00395 
00396         // Find common elements
00397         std::set<unsigned> shared_elements;
00398         std::set_intersection(elems_containing_node_A.begin(),
00399                               elems_containing_node_A.end(),
00400                               elems_containing_node_B.begin(),
00401                               elems_containing_node_B.end(),
00402                               std::inserter(shared_elements, shared_elements.begin()));
00403 
00404         // Iterate over common elements
00405         for (std::set<unsigned>::iterator iter = shared_elements.begin();
00406              iter != shared_elements.end();
00407              ++iter)
00408         {
00409             // Find which node has the lower local index in this element
00410             unsigned local_indexA = this->GetElement(*iter)->GetNodeLocalIndex(p_node_A->GetIndex());
00411             unsigned local_indexB = this->GetElement(*iter)->GetNodeLocalIndex(p_node_B->GetIndex());
00412 
00413             unsigned index = local_indexB;
00414             if (local_indexB > local_indexA)
00415             {
00416                 index = local_indexA;
00417             }
00418             if ((local_indexA == 0) && (local_indexB == this->GetElement(*iter)->GetNumNodes()-1))
00419             {
00420                 index = local_indexB;
00421             }
00422             if ((local_indexB == 0) && (local_indexA == this->GetElement(*iter)->GetNumNodes()-1))
00423             {
00424                 index = local_indexA;
00425             }
00426             // Add new node to this element
00427             this->GetElement(*iter)->AddNode(this->GetNode(new_node_global_index), index);
00428         }
00429         // Store index of new node
00430         division_node_global_indices.push_back(new_node_global_index);
00431     }
00432 
00433     // Now call DivideElement() to divide the element using the new nodes
00434     unsigned new_element_index = DivideElement(pElement,
00435                                                pElement->GetNodeLocalIndex(division_node_global_indices[0]),
00436                                                pElement->GetNodeLocalIndex(division_node_global_indices[1]),
00437                                                placeOriginalElementBelow);
00438     return new_element_index;
00439 }
00440 
00441 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00442 unsigned MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::DivideElementAlongShortAxis(VertexElement<ELEMENT_DIM,SPACE_DIM>* pElement,
00443                                                                                 bool placeOriginalElementBelow)
00444 {
00445     // Make sure that we are in the correct dimension - this code will be eliminated at compile time
00446     assert(SPACE_DIM == 2); // only works in 2D at present
00447     assert(ELEMENT_DIM == SPACE_DIM);
00448 
00449     // Find the short axis of the element
00450     c_vector<double, SPACE_DIM> short_axis = this->GetShortAxisOfElement(pElement->GetIndex());
00451 
00452     unsigned new_element_index = DivideElementAlongGivenAxis(pElement, short_axis, placeOriginalElementBelow);
00453     return new_element_index;
00454 }
00455 
00456 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00457 unsigned MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::DivideElement(VertexElement<ELEMENT_DIM,SPACE_DIM>* pElement,
00458                                                                   unsigned nodeAIndex,
00459                                                                   unsigned nodeBIndex,
00460                                                                   bool placeOriginalElementBelow)
00461 {
00462     // Make sure that we are in the correct dimension - this code will be eliminated at compile time
00463     assert(SPACE_DIM == 2); // only works in 2D at present
00464     assert(ELEMENT_DIM == SPACE_DIM);
00465 
00466     // Sort nodeA and nodeB such that nodeBIndex > nodeAindex
00467     assert(nodeBIndex != nodeAIndex);
00468 
00469     unsigned node1_index = (nodeAIndex < nodeBIndex) ? nodeAIndex : nodeBIndex; // low index
00470     unsigned node2_index = (nodeAIndex < nodeBIndex) ? nodeBIndex : nodeAIndex; // high index
00471 
00472     // Store the number of nodes in the element (this changes when nodes are deleted from the element)
00473     unsigned num_nodes = pElement->GetNumNodes();
00474 
00475     // Copy the nodes in this element
00476     std::vector<Node<SPACE_DIM>*> nodes_elem;
00477     for (unsigned i=0; i<num_nodes; i++)
00478     {
00479         nodes_elem.push_back(pElement->GetNode(i));
00480     }
00481 
00482     // Get the index of the new element
00483     unsigned new_element_index;
00484     if (mDeletedElementIndices.empty())
00485     {
00486         new_element_index = this->mElements.size();
00487     }
00488     else
00489     {
00490         new_element_index = mDeletedElementIndices.back();
00491         mDeletedElementIndices.pop_back();
00492         delete this->mElements[new_element_index];
00493     }
00494 
00495     // Add the new element to the mesh
00496     AddElement(new VertexElement<ELEMENT_DIM,SPACE_DIM>(new_element_index, nodes_elem));
00497 
00504     // Find lowest element
00506     double height_midpoint_1 = 0.0;
00507     double height_midpoint_2 = 0.0;
00508     unsigned counter_1 = 0;
00509     unsigned counter_2 = 0;
00510 
00511     for (unsigned i=0; i<num_nodes; i++)
00512     {
00513         if (i>=node1_index && i<=node2_index)
00514         {
00515             height_midpoint_1 += pElement->GetNode(i)->rGetLocation()[1];
00516             counter_1++;
00517         }
00518         if (i<=node1_index || i>=node2_index)
00519         {
00520             height_midpoint_2 += pElement->GetNode(i)->rGetLocation()[1];
00521             counter_2++;
00522         }
00523     }
00524     height_midpoint_1 /= (double)counter_1;
00525     height_midpoint_2 /= (double)counter_2;
00526 
00527     for (unsigned i=num_nodes; i>0; i--)
00528     {
00529         if (i-1 < node1_index || i-1 > node2_index)
00530         {
00531             if (height_midpoint_1 < height_midpoint_2)
00532             {
00533                 if (placeOriginalElementBelow)
00534                 {
00535                     pElement->DeleteNode(i-1);
00536                 }
00537                 else
00538                 {
00539                     this->mElements[new_element_index]->DeleteNode(i-1);
00540                 }
00541             }
00542             else
00543             {
00544                 if (placeOriginalElementBelow)
00545                 {
00546                     this->mElements[new_element_index]->DeleteNode(i-1);
00547                 }
00548                 else
00549                 {
00550                     pElement->DeleteNode(i-1);
00551                 }
00552             }
00553         }
00554         else if (i-1 > node1_index && i-1 < node2_index)
00555         {
00556             if (height_midpoint_1 < height_midpoint_2)
00557             {
00558                 if (placeOriginalElementBelow)
00559                 {
00560                     this->mElements[new_element_index]->DeleteNode(i-1);
00561                 }
00562                 else
00563                 {
00564                     pElement->DeleteNode(i-1);
00565                 }
00566             }
00567             else
00568             {
00569                 if (placeOriginalElementBelow)
00570                 {
00571                     pElement->DeleteNode(i-1);
00572                 }
00573                 else
00574                 {
00575                     this->mElements[new_element_index]->DeleteNode(i-1);
00576                 }
00577             }
00578         }
00579     }
00580 
00581     return new_element_index;
00582 }
00583 
00584 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00585 void MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::DeleteElementPriorToReMesh(unsigned index)
00586 {
00587     assert(SPACE_DIM == 2);
00588 
00589     // Mark any nodes that are contained only in this element as deleted
00590     for (unsigned i=0; i<this->mElements[index]->GetNumNodes(); i++)
00591     {
00592         Node<SPACE_DIM>* p_node = this->mElements[index]->GetNode(i);
00593 
00594         if (p_node->rGetContainingElementIndices().size()==1)
00595         {
00596             DeleteNodePriorToReMesh(p_node->GetIndex());
00597         }
00598 
00599         // Mark all the nodes contained in the removed element as boundary nodes
00600         p_node->SetAsBoundaryNode(true);
00601     }
00602 
00603     // Mark this element as deleted
00604     this->mElements[index]->MarkAsDeleted();
00605     mDeletedElementIndices.push_back(index);
00606 }
00607 
00608 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00609 void MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::DeleteNodePriorToReMesh(unsigned index)
00610 {
00611     this->mNodes[index]->MarkAsDeleted();
00612     mDeletedNodeIndices.push_back(index);
00613 }
00614 
00615 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00616 void MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::DivideEdge(Node<SPACE_DIM>* pNodeA, Node<SPACE_DIM>* pNodeB)
00617 {
00618     // Find the indices of the elements owned by each node
00619     std::set<unsigned> elements_containing_nodeA = pNodeA->rGetContainingElementIndices();
00620     std::set<unsigned> elements_containing_nodeB = pNodeB->rGetContainingElementIndices();
00621 
00622     // Find common elements
00623     std::set<unsigned> shared_elements;
00624     std::set_intersection(elements_containing_nodeA.begin(),
00625                           elements_containing_nodeA.end(),
00626                           elements_containing_nodeB.begin(),
00627                           elements_containing_nodeB.end(),
00628                           std::inserter(shared_elements, shared_elements.begin()));
00629 
00630     // Check that the nodes have a common edge and not more than 2
00631     assert(!shared_elements.empty());
00632     assert(!shared_elements.size()<=2);
00633 
00634     // Specifiy if its a boundary node
00635     bool is_boundary_node = false;
00636     if (shared_elements.size()==1)
00637     {
00638         // If only one shared element then must be on the boundary.
00639         assert((pNodeA->IsBoundaryNode())&&(pNodeB->IsBoundaryNode()));
00640         is_boundary_node = true;
00641     }
00642 
00643     // Create a new node (position is not important as it will be changed)
00644     Node<SPACE_DIM>* p_new_node = new Node<SPACE_DIM>(GetNumNodes(), is_boundary_node, 0.0, 0.0);
00645 
00646     // Update the node location
00647     c_vector<double, SPACE_DIM> new_node_position = pNodeA->rGetLocation() + 0.5*this->GetVectorFromAtoB(pNodeA->rGetLocation(), pNodeB->rGetLocation());
00648     ChastePoint<SPACE_DIM> point(new_node_position);
00649     p_new_node->SetPoint(new_node_position);
00650 
00651     // Add node to mesh
00652     this->mNodes.push_back(p_new_node);
00653 
00654     // Iterate over common elements
00655     for (std::set<unsigned>::iterator iter = shared_elements.begin();
00656          iter != shared_elements.end();
00657          ++iter)
00658     {
00659         // Find which node has the lower local index in this element
00660         unsigned local_indexA = this->GetElement(*iter)->GetNodeLocalIndex(pNodeA->GetIndex());
00661         unsigned local_indexB = this->GetElement(*iter)->GetNodeLocalIndex(pNodeB->GetIndex());
00662 
00663         unsigned index = local_indexB;
00664         if ( local_indexB > local_indexA )
00665         {
00666             index = local_indexA;
00667         }
00668         if ( (local_indexA == 0) && (local_indexB == this->GetElement(*iter)->GetNumNodes()-1))
00669         {
00670             index = local_indexB;
00671         }
00672         if ( (local_indexB == 0) && (local_indexA == this->GetElement(*iter)->GetNumNodes()-1))
00673         {
00674             index = local_indexA;
00675         }
00676         // Add new node to this element
00677         this->GetElement(*iter)->AddNode(p_new_node, index);
00678     }
00679 }
00680 
00681 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00682 void MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::RemoveDeletedNodesAndElements(VertexElementMap& rElementMap)
00683 {
00684     // Make sure that we are in the correct dimension - this code will be eliminated at compile time
00685     assert(SPACE_DIM==2 || SPACE_DIM==3);
00686     assert(ELEMENT_DIM == SPACE_DIM);
00687 
00688     // Make sure the map is big enough
00689     rElementMap.Resize(this->GetNumAllElements());
00690 
00691     // Remove deleted elements
00692     std::vector<VertexElement<ELEMENT_DIM, SPACE_DIM>*> live_elements;
00693     for (unsigned i=0; i< this->mElements.size(); i++)
00694     {
00695         if (this->mElements[i]->IsDeleted())
00696         {
00697             delete this->mElements[i];
00698             rElementMap.SetDeleted(i);
00699         }
00700         else
00701         {
00702             live_elements.push_back(this->mElements[i]);
00703             rElementMap.SetNewIndex(i, (unsigned)(live_elements.size()-1));
00704         }
00705     }
00706 
00707     assert(mDeletedElementIndices.size() == this->mElements.size() - live_elements.size());
00708     mDeletedElementIndices.clear();
00709     this->mElements = live_elements;
00710 
00711     for (unsigned i=0; i<this->mElements.size(); i++)
00712     {
00713         this->mElements[i]->ResetIndex(i);
00714     }
00715 
00716     // Remove deleted nodes
00717     RemoveDeletedNodes();
00718 }
00719 
00720 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00721 void MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::RemoveDeletedNodes()
00722 {
00723     std::vector<Node<SPACE_DIM>*> live_nodes;
00724     for (unsigned i=0; i<this->mNodes.size(); i++)
00725     {
00726         if (this->mNodes[i]->IsDeleted())
00727         {
00728             delete this->mNodes[i];
00729         }
00730         else
00731         {
00732             live_nodes.push_back(this->mNodes[i]);
00733         }
00734     }
00735 
00736     assert(mDeletedNodeIndices.size() == this->mNodes.size() - live_nodes.size());
00737     this->mNodes = live_nodes;
00738     mDeletedNodeIndices.clear();
00739 
00740     for (unsigned i=0; i<this->mNodes.size(); i++)
00741     {
00742         this->mNodes[i]->SetIndex(i);
00743     }
00744 }
00745 
00746 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00747 void MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::ReMesh(VertexElementMap& rElementMap)
00748 {
00749     // Make sure that we are in the correct dimension - this code will be eliminated at compile time
00750     assert(SPACE_DIM==2 || SPACE_DIM==3);
00751     assert(ELEMENT_DIM == SPACE_DIM);
00752 
00753     if (SPACE_DIM==2)
00754     {
00755         /*
00756          * We do not need to call Clear() and remove all current data, since
00757          * cell birth, rearrangement and death result only in local remeshing
00758          * of a vertex-based mesh.
00759          */
00760 
00761         // Remove deleted nodes and elements
00762         RemoveDeletedNodesAndElements(rElementMap);
00763 
00764         // Check for element rearrangements
00765         bool recheck_mesh = true;
00766         while (recheck_mesh == true)
00767         {
00768             // Separate loops as need to check for T2Swaps first
00769             recheck_mesh = CheckForT2Swaps(rElementMap);
00770 
00771             if (recheck_mesh == false)
00772             {
00773                 recheck_mesh = CheckForT1Swaps(rElementMap);
00774             }
00775         }
00776 
00777         //Check for element intersections.
00778         recheck_mesh = true;
00779         while (recheck_mesh == true)
00780         {
00781             //Check mesh for intersections, and perform T3Swaps where required
00782             recheck_mesh = CheckForIntersections();
00783         }
00784 
00785         RemoveDeletedNodes(); // to remove any nodes if they are deleted
00786     }
00787     else // 3D
00788     {
00789         #define COVERAGE_IGNORE
00790         EXCEPTION("Remeshing has not been implemented in 3D (see #827 and #860)\n");
00791         #undef COVERAGE_IGNORE
00792 
00793     }
00794 }
00795 
00796 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00797 void MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::ReMesh()
00798 {
00799     VertexElementMap map(GetNumElements());
00800     ReMesh(map);
00801 }
00802 
00803 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00804 bool MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::CheckForT1Swaps(VertexElementMap& rElementMap)
00805 {
00806     // Loop over elements to check for T1Swaps
00807     for (typename VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator elem_iter = this->GetElementIteratorBegin();
00808          elem_iter != this->GetElementIteratorEnd();
00809          ++elem_iter)
00810     {
00811         unsigned num_nodes = elem_iter->GetNumNodes();
00812         assert(num_nodes > 0); // if not element should be deleted
00813 
00814         unsigned new_num_nodes = num_nodes;
00815 
00816         /*
00817          * Perform T1 swaps and merges where necessary
00818          * Check there are > 3 nodes in both elements that contain the pair of nodes
00819          * and the edges are small enough
00820          */
00821 
00822         // Loop over element vertices
00823         for (unsigned local_index=0; local_index<num_nodes; local_index++)
00824         {
00825             // Find locations of current node and anticlockwise node
00826             Node<SPACE_DIM>* p_current_node = elem_iter->GetNode(local_index);
00827             unsigned local_index_plus_one = (local_index+1)%new_num_nodes; 
00828             Node<SPACE_DIM>* p_anticlockwise_node = elem_iter->GetNode(local_index_plus_one);
00829 
00830             // Find distance between nodes
00831             double distance_between_nodes = this->GetDistanceBetweenNodes(p_current_node->GetIndex(), p_anticlockwise_node->GetIndex());
00832 
00833             std::set<unsigned> elements_of_node_a = p_current_node->rGetContainingElementIndices();
00834             std::set<unsigned> elements_of_node_b = p_anticlockwise_node->rGetContainingElementIndices();
00835 
00836             std::set<unsigned> all_elements;
00837             std::set_union(elements_of_node_a.begin(), elements_of_node_a.end(),
00838                            elements_of_node_b.begin(), elements_of_node_b.end(),
00839                            std::inserter(all_elements, all_elements.begin()));
00840 
00841             // Track if either node is in a triangular element.
00842             bool triangular_element = false;
00843 
00844             for (std::set<unsigned>::const_iterator it = all_elements.begin();
00845                  it != all_elements.end();
00846                  ++it)
00847             {
00848                 if (this->GetElement(*it)->GetNumNodes() <= 3)
00849                 {
00850                     triangular_element = true;
00851                 }
00852             }
00853 
00854             // If the nodes are too close together and we don't have any triangular elements connected to the nodes, perform a swap
00855             if ((!triangular_element) && (distance_between_nodes < mCellRearrangementThreshold))
00856             {
00857                 // Identify the type of node swap/merge needed then call method to perform swap/merge
00858                 IdentifySwapType(p_current_node, p_anticlockwise_node, rElementMap);
00859                 return true;
00860             }
00861         }
00862     }
00863     return false;
00864 }
00865 
00866 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00867 bool MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::CheckForT2Swaps(VertexElementMap& rElementMap)
00868 {
00869 
00870     // Loop over elements to check for T2Swaps
00871     for (typename VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator elem_iter = this->GetElementIteratorBegin();
00872          elem_iter != this->GetElementIteratorEnd();
00873          ++elem_iter)
00874     {
00875         if (elem_iter->GetNumNodes() == 3u)
00876         {
00877             /*
00878              * Perform T2 swaps where necessary
00879              * Check there are only 3 nodes and the element is small enough
00880              */
00881             if (this->GetVolumeOfElement(elem_iter->GetIndex()) < GetT2Threshold())
00882             {
00883                 PerformT2Swap(*elem_iter);
00884 
00885                 // Now remove the deleted nodes (if we don't do this then the search for T1Swap causes errors)
00886                 RemoveDeletedNodesAndElements(rElementMap);
00887 
00888                 return true;
00889             }
00890         }
00891     }
00892     return false;
00893 }
00894 
00895 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00896 bool MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::CheckForIntersections()
00897 {
00898     // Check that no boundary nodes have overlapped elements on the boundary
00899     for (typename AbstractMesh<ELEMENT_DIM,SPACE_DIM>::NodeIterator node_iter = this->GetNodeIteratorBegin();
00900          node_iter != this->GetNodeIteratorEnd();
00901          ++node_iter)
00902     {
00903         if (node_iter->IsBoundaryNode())
00904         {
00905             assert(!(node_iter->IsDeleted()));
00906 
00907             for (typename VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator elem_iter = this->GetElementIteratorBegin();
00908                  elem_iter != this->GetElementIteratorEnd();
00909                  ++elem_iter)
00910             {
00911                 if (elem_iter->IsElementOnBoundary())
00912                 {
00913 
00914                     unsigned elem_index = elem_iter->GetIndex();
00915 
00916                     // Check that the node is not part of this element.
00917                     if (node_iter->rGetContainingElementIndices().count(elem_index) == 0)
00918                     {
00919                         if (this->ElementIncludesPoint(node_iter->rGetLocation(), elem_index))
00920                         {
00921                             PerformT3Swap(&(*node_iter), elem_index);
00922                             return true;
00923                         }
00924                     }
00925                 }
00926             }
00927         }
00928     }
00929 
00930     if (mCheckForInternalIntersections)
00931     {
00932         // Check that no nodes have overlapped elements inside the mesh  // Change to only loop over neighboring elements
00933         for (typename AbstractMesh<ELEMENT_DIM,SPACE_DIM>::NodeIterator node_iter = this->GetNodeIteratorBegin();
00934              node_iter != this->GetNodeIteratorEnd();
00935              ++node_iter)
00936         {
00937              assert(!(node_iter->IsDeleted()));
00938 
00939             for (typename VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator elem_iter = this->GetElementIteratorBegin();
00940                  elem_iter != this->GetElementIteratorEnd();
00941                  ++elem_iter)
00942             {
00943                 unsigned elem_index = elem_iter->GetIndex();
00944 
00945                 // Check that the node is not part of this element.
00946                 if (node_iter->rGetContainingElementIndices().count(elem_index) == 0)
00947                 {
00948                     if (this->ElementIncludesPoint(node_iter->rGetLocation(), elem_index))
00949                     {
00950                         PerformIntersectionSwap(&(*node_iter), elem_index);
00951                         return true;
00952                     }
00953                 }
00954             }
00955         }
00956     }
00957 
00958     return false;
00959 }
00960 
00961 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00962 void MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::IdentifySwapType(Node<SPACE_DIM>* pNodeA, Node<SPACE_DIM>* pNodeB, VertexElementMap& rElementMap)
00963 {
00964     // Make sure that we are in the correct dimension - this code will be eliminated at compile time
00965     assert(SPACE_DIM == 2); // this method only works in 2D at present
00966     assert(ELEMENT_DIM == SPACE_DIM);
00967 
00968     // Find the sets of elements containing nodes A and B
00969     std::set<unsigned> nodeA_elem_indices = pNodeA->rGetContainingElementIndices();
00970 
00971     std::set<unsigned> nodeB_elem_indices = pNodeB->rGetContainingElementIndices();
00972 
00973     // Form the set union
00974     std::set<unsigned> all_indices, temp_set;
00975     std::set_union(nodeA_elem_indices.begin(), nodeA_elem_indices.end(),
00976                    nodeB_elem_indices.begin(), nodeB_elem_indices.end(),
00977                    std::inserter(temp_set, temp_set.begin()));
00978     all_indices.swap(temp_set); // temp_set will be deleted
00979 
00980     if ((nodeA_elem_indices.size()>3) || (nodeB_elem_indices.size()>3))
00981     {
00982         /*
00983          * Looks like
00984          *
00985          *  \
00986          *   \ A   B
00987          * ---o---o---
00988          *   /
00989          *  /
00990          *
00991          */
00992         EXCEPTION("A node is contained in more than three elements"); // the code can't handle this case
00993     }
00994     else // each node is contained in at most three elements
00995     {
00996         switch (all_indices.size())
00997         {
00998             case 1:
00999             {
01000                 /*
01001                  * In this case, each node is contained in a single element, so the nodes
01002                  * lie on the boundary of the mesh:
01003                  *
01004                  *    A   B
01005                  * ---o---o---
01006                  *
01007                  * We merge the nodes.
01008                  */
01009 
01010                 // Check nodes A and B are on the boundary
01011                 assert(pNodeA->IsBoundaryNode());
01012                 assert(pNodeB->IsBoundaryNode());
01013 
01014                 PerformNodeMerge(pNodeA, pNodeB);
01015 
01016                 // Remove the deleted node and re-index
01017                 RemoveDeletedNodes();
01018                 break;
01019             }
01020             case 2:
01021             {
01022                 if (nodeA_elem_indices.size()==2 && nodeB_elem_indices.size()==2)
01023                 {
01024                     if (pNodeA->IsBoundaryNode() && pNodeB->IsBoundaryNode())
01025                     {
01026                         /*
01027                          * In this case, the node configuration looks like:
01028                          *
01029                          *   \   /
01030                          *    \ / Node A
01031                          * (1) |   (2)      (element number in brackets)
01032                          *    / \ Node B
01033                          *   /   \
01034                          *
01035                          * With voids on top and bottom
01036                          *
01037                          * We perform a Type 1 swap and separate the elements in this case.
01038                          */
01039                          PerformT1Swap(pNodeA, pNodeB,all_indices);
01040                     }
01041                     else if (pNodeA->IsBoundaryNode() || pNodeB->IsBoundaryNode())
01042                     {
01043                         /*
01044                          * In this case, the node configuration looks like:
01045                          *
01046                          *   \   /
01047                          *    \ / Node A
01048                          * (1) |   (2)      (element number in brackets)
01049                          *     x Node B
01050                          *     |
01051                          *
01052                          * With a void on top.
01053                          *
01054                          * We should not be able to get here when running normal vertex code
01055                          * as there should only be nodes on 3 way junctions or boundaries.
01056                          *
01057                          */
01058 
01059                         EXCEPTION("There is a non boundary node contained only in 2 elements something has gone wrong.");
01060                     }
01061                     else
01062                     {
01063                         /*
01064                          * In this case, each node is contained in two elements, so the nodes
01065                          * lie on an internal edge:
01066                          *
01067                          *    A   B
01068                          * ---o---o---
01069                          *
01070                          * We should not be able to get here when running normal vertex code
01071                          * as there should only be nodes on 3 way junctions or boundaries.
01072                          */
01073 
01074                         EXCEPTION("There are non-boundary nodes contained in only in 2 elements something has gone wrong.");
01075                     }
01076                 }
01077                 else
01078                 {
01079                     /*
01080                      * In this case, the node configuration looks like:
01081                      *
01082                      * Outside
01083                      *         /
01084                      *   --o--o (2)
01085                      *     (1) \
01086                      *
01087                      * We merge the nodes in this case. ///\todo this should be a T1 Swap see #1263
01088                      */
01089 
01090                     PerformNodeMerge(pNodeA, pNodeB);
01091 
01092                     // Remove the deleted node and re-index
01093                     RemoveDeletedNodes();
01094                 }
01095                 break;
01096             }
01097             case 3:
01098             {
01099                 if (nodeA_elem_indices.size()==1 || nodeB_elem_indices.size()==1)
01100                 {
01101                     /*
01102                      * In this case, one node is contained in one element and
01103                      * the other node is contained in three elements:
01104                      *
01105                      *    A   B
01106                      *
01107                      *  empty   /
01108                      *         / (3)
01109                      * ---o---o-----   (element number in brackets)
01110                      *  (1)    \ (2)
01111                      *          \
01112                      *
01113                      * We should not be able to get here when running normal vertex code
01114                      * as a boundary node is contained in at most 2 elements.
01115                      */
01116 
01117                     // Check nodes A and B are on the boundary
01118                     assert(pNodeA->IsBoundaryNode());
01119                     assert(pNodeB->IsBoundaryNode());
01120 
01121                     EXCEPTION("There is a boundary node contained in three elements something has gone wrong.");
01122                 }
01123                 else if (nodeA_elem_indices.size()==2 && nodeB_elem_indices.size()==2)
01124                 {
01125                     // element in nodeA_elem_indices which is not in nodeB_elem_indices contains a shared node with the element in nodeA_elem_indices which is not in nodeB_elem_indices.
01126 
01127                     std::set<unsigned> element_A_not_B, temp_set;
01128                     std::set_difference(all_indices.begin(), all_indices.end(),
01129                                         nodeB_elem_indices.begin(), nodeB_elem_indices.end(),
01130                                         std::inserter(temp_set, temp_set.begin()));
01131                     element_A_not_B.swap(temp_set);
01132 
01133                     // Should only be one such element
01134                     assert(element_A_not_B.size()==1);
01135 
01136                     std::set<unsigned> element_B_not_A;
01137                     std::set_difference(all_indices.begin(), all_indices.end(),
01138                                         nodeA_elem_indices.begin(), nodeA_elem_indices.end(),
01139                                         std::inserter(temp_set, temp_set.begin()));
01140                     element_B_not_A.swap(temp_set);
01141 
01142                     // Should only be one such element
01143                     assert(element_B_not_A.size()==1);
01144 
01145                     VertexElement<ELEMENT_DIM, SPACE_DIM>* p_element_A_not_B = this->mElements[*element_A_not_B.begin()];
01146                     VertexElement<ELEMENT_DIM, SPACE_DIM>* p_element_B_not_A = this->mElements[*element_B_not_A.begin()];
01147 
01148                     unsigned local_index_1 = p_element_A_not_B->GetNodeLocalIndex(pNodeA->GetIndex());
01149                     unsigned next_node_1 = p_element_A_not_B->GetNodeGlobalIndex((local_index_1 + 1)%(p_element_A_not_B->GetNumNodes()));
01150                     unsigned previous_node_1 = p_element_A_not_B->GetNodeGlobalIndex((local_index_1 + p_element_A_not_B->GetNumNodes() - 1)%(p_element_A_not_B->GetNumNodes()));
01151                     unsigned local_index_2 = p_element_B_not_A->GetNodeLocalIndex(pNodeB->GetIndex());
01152                     unsigned next_node_2 = p_element_B_not_A->GetNodeGlobalIndex((local_index_2 + 1)%(p_element_B_not_A->GetNumNodes()));
01153                     unsigned previous_node_2 = p_element_B_not_A->GetNodeGlobalIndex((local_index_2 + p_element_B_not_A->GetNumNodes() - 1)%(p_element_B_not_A->GetNumNodes()));
01154 
01155                     if (next_node_1 == previous_node_2 || next_node_2 == previous_node_1)
01156                      {
01157                         /*
01158                          * In this case, the node configuration looks like:
01159                          *
01160                          *    A  C  B                A      B
01161                          *      /\                 \        /
01162                          *     /v \                 \  (1) /
01163                          * (3)o----o (1)  or     (2) o----o (3)    (element number in brackets, v is a void)
01164                          *   /  (2) \                 \v /
01165                          *  /        \                 \/
01166                          *                             C
01167                          *
01168                          * We perform a T3 way merge, removing the void.
01169                          */
01170 
01171                         // Check nodes A and B are on the boundary
01172                         assert(pNodeA->IsBoundaryNode());
01173                         assert(pNodeB->IsBoundaryNode());
01174 
01175                         // Get the other node in the triangular void
01176                         unsigned nodeC_index;
01177                         if (next_node_1 == previous_node_2 && next_node_2 != previous_node_1)
01178                         {
01179                             nodeC_index = next_node_1;
01180                         }
01181                         else if (next_node_2 == previous_node_1 && next_node_1 != previous_node_2)
01182                         {
01183                             nodeC_index = next_node_2;
01184                         }
01185                         else
01186                         {
01187                              assert(next_node_1 == previous_node_2 && next_node_2 == previous_node_1);
01188                              EXCEPTION("Triangular element next to triangular void, not implemented yet.");
01189                         }
01190 
01191                         PerformVoidRemoval(pNodeA, pNodeB, this->mNodes[nodeC_index]);
01192                     }
01193                     else
01194                     {
01195                         /*
01196                          * In this case, the node configuration looks like:
01197                          *
01198                          *     A  B                  A  B
01199                          *   \ empty/              \      /
01200                          *    \    /                \(1) /
01201                          * (3) o--o (1)  or      (2) o--o (3)    (element number in brackets)
01202                          *    / (2)\                /    \
01203                          *   /      \              /empty \
01204                          *
01205                          * We perform a T1 Swap in this case.
01206                          */
01207 
01208                         // Check nodes A and B are on the boundary
01209                         assert(pNodeA->IsBoundaryNode());
01210                         assert(pNodeB->IsBoundaryNode());
01211 
01212                         PerformT1Swap(pNodeA, pNodeB, all_indices);
01213                     }
01214                 }
01215                 else
01216                 {
01217                     /*
01218                      * In this case, one of the nodes is contained in two elements
01219                      * and the other node is contained in three elements.
01220                      */
01221                     assert (   (nodeA_elem_indices.size()==2 && nodeB_elem_indices.size()==3)
01222                             || (nodeA_elem_indices.size()==3 && nodeB_elem_indices.size()==2) );
01223 
01224                     // They can't both be boundary nodes
01225                     assert(!(pNodeA->IsBoundaryNode() && pNodeB->IsBoundaryNode()));
01226 
01227                     if (pNodeA->IsBoundaryNode() || pNodeB->IsBoundaryNode())
01228                     {
01229                         /*
01230                          * In this case, the node configuration looks like:
01231                          *
01232                          *     A  B                      A  B
01233                          *   \      /                  \      /
01234                          *    \ (1)/                    \(1) /
01235                          * (3) o--o (empty)  or  (empty) o--o (3)    (element number in brackets)
01236                          *    / (2)\                    /(2) \
01237                          *   /      \                  /      \
01238                          *
01239                          * We perform a Type 1 swap in this case.
01240                          */
01241                         PerformT1Swap(pNodeA, pNodeB, all_indices);
01242                     }
01243                     else
01244                     {
01245                         /*
01246                          * In this case, the node configuration looks like:
01247                          *
01248                          *     A  B             A  B
01249                          *   \                       /
01250                          *    \  (1)           (1)  /
01251                          * (3) o--o---   or  ---o--o (3)    (element number in brackets)
01252                          *    /  (2)           (2)  \
01253                          *   /                       \
01254                          *
01255                           * We should not be able to get here when running normal vertex code
01256                          * as there should only be nodes on 3 way junctions or boundaries.
01257                          */
01258 
01259                         EXCEPTION("There are non-boundary nodes contained only in 2 elements something has gone wrong.");
01260                     }
01261                 }
01262                 break;
01263             }
01264             case 4:
01265             {
01266                 /*
01267                  * In this case, the node configuration looks like:
01268                  *
01269                  *   \(1)/
01270                  *    \ / Node A
01271                  * (2) |   (4)      (element number in brackets)
01272                  *    / \ Node B
01273                  *   /(3)\
01274                  *
01275                  * We perform a Type 1 swap in this case.
01276                  */
01277                 PerformT1Swap(pNodeA, pNodeB, all_indices);
01278                 break;
01279             }
01280             default:
01281                 // This can't happen
01282                 NEVER_REACHED;
01283         }
01284     }
01285 }
01286 
01287 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
01288 void MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::PerformNodeMerge(Node<SPACE_DIM>* pNodeA, Node<SPACE_DIM>* pNodeB)
01289 {
01290     // Sort the nodes by index
01291     unsigned nodeA_index = pNodeA->GetIndex();
01292     unsigned nodeB_index = pNodeB->GetIndex();
01293 
01294     unsigned lo_node_index = (nodeA_index < nodeB_index) ? nodeA_index : nodeB_index; // low index
01295     unsigned hi_node_index = (nodeA_index < nodeB_index) ? nodeB_index : nodeA_index; // high index
01296 
01297     // Get pointers to the nodes, sorted by index
01298     Node<SPACE_DIM>* p_lo_node = this->GetNode(lo_node_index);
01299     Node<SPACE_DIM>* p_hi_node = this->GetNode(hi_node_index);
01300 
01301     // Find the sets of elements containing each of the nodes, sorted by index
01302     std::set<unsigned> lo_node_elem_indices = p_lo_node->rGetContainingElementIndices();
01303     std::set<unsigned> hi_node_elem_indices = p_hi_node->rGetContainingElementIndices();
01304 
01305     // Move the low-index node to the mid-point
01306     c_vector<double, SPACE_DIM> node_midpoint = p_lo_node->rGetLocation() + 0.5*this->GetVectorFromAtoB(p_lo_node->rGetLocation(), p_hi_node->rGetLocation());
01307     c_vector<double, SPACE_DIM>& r_lo_node_location = p_lo_node->rGetModifiableLocation();
01308     r_lo_node_location = node_midpoint;
01309 
01310     // Update the elements previously containing the high-index node to contain the low-index node
01311     for (std::set<unsigned>::const_iterator it = hi_node_elem_indices.begin();
01312          it != hi_node_elem_indices.end();
01313          ++it)
01314     {
01315         // Find the local index of the high-index node in this element
01316         unsigned hi_node_local_index = this->mElements[*it]->GetNodeLocalIndex(hi_node_index);
01317         assert(hi_node_local_index < UINT_MAX); // this element should contain the high-index node
01318 
01319         /*
01320          * If this element already contains the low-index node, then just remove the high-index node.
01321          * Otherwise replace it with the low-index node in the element and remove it from mNodes.
01322          */
01323         if (lo_node_elem_indices.count(*it) > 0)
01324         {
01325             this->mElements[*it]->DeleteNode(hi_node_local_index); // think this method removes the high-index node from mNodes
01326         }
01327         else
01328         {
01329             // Replace the high-index node with the low-index node in this element
01330             this->mElements[*it]->UpdateNode(hi_node_local_index, p_lo_node);
01331         }
01332     }
01333     assert(!(this->mNodes[hi_node_index]->IsDeleted()));
01334     this->mNodes[hi_node_index]->MarkAsDeleted();
01335     mDeletedNodeIndices.push_back(hi_node_index);
01336 }
01337 
01338 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
01339 void MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::PerformT1Swap(Node<SPACE_DIM>* pNodeA,
01340                                                               Node<SPACE_DIM>* pNodeB,
01341                                                               std::set<unsigned>& rElementsContainingNodes)
01342 {
01343     // Make sure that we are in the correct dimension - this code will be eliminated at compile time
01344     assert(SPACE_DIM == 2); // only works in 2D at present
01345     assert(ELEMENT_DIM == SPACE_DIM);
01346 
01347     /*
01348      * Restructure elements - remember to update nodes and elements.
01349      *
01350      * We need to implement the following changes:
01351      *
01352      * The element whose index was in nodeA_elem_indices but not nodeB_elem_indices,
01353      * and the element whose index was in nodeB_elem_indices but not nodeA_elem_indices,
01354      * should now both contain nodes A and B.
01355      *
01356      * The element whose index was in nodeA_elem_indices and nodeB_elem_indices, and which
01357      * node C lies inside, should now only contain node A.
01358      *
01359      * The element whose index was in nodeA_elem_indices and nodeB_elem_indices, and which
01360      * node D lies inside, should now only contain node B.
01361      *
01362      * Iterate over all elements involved and identify which element they are
01363      * in the diagram then update the nodes as necessary.
01364      *
01365      *   \(1)/
01366      *    \ / Node A
01367      * (2) |   (4)     elements in brackets
01368      *    / \ Node B
01369      *   /(3)\
01370      *
01371      */
01372 
01373     /*
01374      * Compute the locations of two new nodes C, D, placed on either side of the
01375      * edge E_old formed by nodes current_node and anticlockwise_node, such
01376      * that the edge E_new formed by the new nodes is the perpendicular bisector
01377      * of E_old, with |E_new| 'just larger' (mCellRearrangementRatio) than mThresholdDistance.
01378      */
01379 
01380     // Find the sets of elements containing nodes A and B
01381     std::set<unsigned> nodeA_elem_indices = pNodeA->rGetContainingElementIndices();
01382     std::set<unsigned> nodeB_elem_indices = pNodeB->rGetContainingElementIndices();
01383 
01384     double distance_between_nodes_CD = mCellRearrangementRatio*mCellRearrangementThreshold;
01385 
01386     c_vector<double, SPACE_DIM> nodeA_location = pNodeA->rGetLocation();
01387     c_vector<double, SPACE_DIM> nodeB_location = pNodeB->rGetLocation();
01388 
01389     c_vector<double, SPACE_DIM> a_to_b = this->GetVectorFromAtoB(nodeA_location, nodeB_location);
01390 
01391     // Store the location of the T1Swap, the mid point of the moving nodes,
01392     mLocationsOfT1Swaps.push_back(nodeA_location + 0.5*a_to_b);
01393 
01394     c_vector<double, SPACE_DIM> perpendicular_vector;
01395     perpendicular_vector(0) = -a_to_b(1);
01396     perpendicular_vector(1) = a_to_b(0);
01397 
01399     if (norm_2(a_to_b) < 1e-10)
01400     {
01401         EXCEPTION("Nodes are too close together, this shouldn't happen");
01402     }
01403 
01404     c_vector<double, SPACE_DIM> c_to_d = distance_between_nodes_CD / norm_2(a_to_b) * perpendicular_vector;
01405     c_vector<double, SPACE_DIM> nodeC_location = nodeA_location + 0.5*a_to_b - 0.5*c_to_d;
01406     c_vector<double, SPACE_DIM> nodeD_location = nodeC_location + c_to_d;
01407 
01408     /*
01409      * Move node A to C and node B to D
01410      */
01411 
01412     c_vector<double, SPACE_DIM>& r_nodeA_location = pNodeA->rGetModifiableLocation();
01413     r_nodeA_location = nodeC_location;
01414 
01415     c_vector<double, SPACE_DIM>& r_nodeB_location = pNodeB->rGetModifiableLocation();
01416     r_nodeB_location = nodeD_location;
01417 
01418     for (std::set<unsigned>::const_iterator it = rElementsContainingNodes.begin();
01419          it != rElementsContainingNodes.end();
01420          ++it)
01421     {
01422         if (nodeA_elem_indices.find(*it) == nodeA_elem_indices.end()) // not in nodeA_elem_indices so element 3
01423         {
01424             /*
01425              * In this case the element index was not in
01426              * nodeA_elem_indices, so this element
01427              * does not contain node A. Therefore we must add node A
01428              * (which has been moved to node C) to this element.
01429              *
01430              * Locate local index of node B in element then add node A after
01431              * in anticlockwise direction.
01432              */
01433 
01434             unsigned nodeB_local_index = this->mElements[*it]->GetNodeLocalIndex(pNodeB->GetIndex());
01435             assert(nodeB_local_index < UINT_MAX); // this element should contain node B
01436 
01437             this->mElements[*it]->AddNode(pNodeA, nodeB_local_index);
01438         }
01439         else if (nodeB_elem_indices.find(*it) == nodeB_elem_indices.end()) // not in nodeB_elem_indices so element 1
01440         {
01441             /*
01442              * In this case the element index was not in
01443              * nodeB_elem_indices, so this element
01444              * does not contain node B. Therefore we must add node B
01445              * (which has been moved to node D) to this element.
01446              *
01447              * Locate local index of node A in element then add node B after
01448              * in anticlockwise direction.
01449              */
01450             unsigned nodeA_local_index = this->mElements[*it]->GetNodeLocalIndex(pNodeA->GetIndex());
01451             assert(nodeA_local_index < UINT_MAX); // this element should contain node A
01452             this->mElements[*it]->AddNode(pNodeB, nodeA_local_index);
01453         }
01454         else
01455         {
01456             /*
01457              * In this case the element index was in both nodeB_elem_indices and nodeB_elem_indices
01458              * so is element 2 or 4
01459              */
01460 
01461             /*
01462              * Locate local index of nodeA and nodeB and use the ordering to
01463              * identify the element, if nodeB_index > nodeA_index then element 4
01464              * and if nodeA_index > nodeB_index then element 2
01465              */
01466             unsigned nodeA_local_index = this->mElements[*it]->GetNodeLocalIndex(pNodeA->GetIndex());
01467             assert(nodeA_local_index < UINT_MAX); // this element should contain node A
01468 
01469             unsigned nodeB_local_index = this->mElements[*it]->GetNodeLocalIndex(pNodeB->GetIndex());
01470             assert(nodeB_local_index < UINT_MAX); // this element should contain node B
01471 
01472             unsigned nodeB_local_index_plus_one = (nodeB_local_index + 1)%(this->mElements[*it]->GetNumNodes());
01473 
01474             if (nodeA_local_index == nodeB_local_index_plus_one)
01475             {
01476                 /*
01477                  * In this case the local index of nodeA is the local index of
01478                  * nodeB plus one so we are in element 2 so we remove nodeB
01479                  */
01480                 this->mElements[*it]->DeleteNode(nodeB_local_index);
01481             }
01482             else
01483             {
01484                 assert(nodeB_local_index == (nodeA_local_index + 1)%(this->mElements[*it]->GetNumNodes())); // as A and B are next to each other
01485                 /*
01486                  * In this case the local index of nodeA is the local index of
01487                  * nodeB minus one so we are in element 4 so we remove nodeA
01488                  */
01489                 this->mElements[*it]->DeleteNode(nodeA_local_index);
01490             }
01491         }
01492     }
01493 
01494     // Sort out boundary nodes
01495     if (pNodeA->IsBoundaryNode() || pNodeB->IsBoundaryNode())
01496     {
01497         if (pNodeA->GetNumContainingElements()==3)
01498         {
01499             pNodeA->SetAsBoundaryNode(false);
01500         }
01501         else
01502         {
01503             pNodeA->SetAsBoundaryNode(true);
01504         }
01505         if (pNodeB->GetNumContainingElements()==3)
01506         {
01507             pNodeB->SetAsBoundaryNode(false);
01508         }
01509         else
01510         {
01511             pNodeB->SetAsBoundaryNode(true);
01512         }
01513     }
01514 }
01515 
01516 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
01517 void MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::PerformIntersectionSwap(Node<SPACE_DIM>* pNode, unsigned elementIndex)
01518 {
01519     // Make sure that we are in the correct dimension - this code will be eliminated at compile time
01520     assert(SPACE_DIM == 2); // only works in 2D at present
01521     assert(ELEMENT_DIM == SPACE_DIM);
01522 
01523     VertexElement<ELEMENT_DIM, SPACE_DIM>* p_element = this->GetElement(elementIndex);
01524     unsigned num_nodes = p_element->GetNumNodes();
01525 
01526     std::set<unsigned> elements_containing_intersecting_node;
01527 
01528     for (unsigned node_local_index=0; node_local_index<num_nodes; node_local_index++)
01529     {
01530         unsigned node_global_index = p_element->GetNodeGlobalIndex(node_local_index);
01531 
01532         std::set<unsigned> node_elem_indices = this->GetNode(node_global_index)->rGetContainingElementIndices();
01533 
01534         for (std::set<unsigned>::const_iterator elem_iter = node_elem_indices.begin();
01535              elem_iter != node_elem_indices.end();
01536              ++elem_iter)
01537         {
01538             VertexElement<ELEMENT_DIM, SPACE_DIM>* p_neighboring_element = this->GetElement(*elem_iter);
01539 
01540             // Check if element contains the intersecting node
01541             for (unsigned node_index_2 = 0;  node_index_2 < p_neighboring_element->GetNumNodes(); node_index_2++)
01542             {
01543                 if(p_neighboring_element->GetNodeGlobalIndex(node_index_2)==pNode->GetIndex())
01544                 {
01545                     elements_containing_intersecting_node.insert(p_neighboring_element->GetIndex());
01546                 }
01547             }
01548         }
01549     }
01550     /*
01551      * If there are not 2 elements containing the intersecting node then the node is coming from the other side of the element
01552      * and there is no way to fix it unles you want to make 2 new elements.
01553      */
01554     assert(elements_containing_intersecting_node.size()==2);
01555 
01556     std::set<unsigned> all_elements_containing_intersecting_node = pNode->rGetContainingElementIndices();
01557 
01558     std::set<unsigned> intersecting_element;
01559 
01560     std::set_difference( all_elements_containing_intersecting_node.begin(), all_elements_containing_intersecting_node.end(),
01561                          elements_containing_intersecting_node.begin(), elements_containing_intersecting_node.end(),
01562                          std::inserter(intersecting_element, intersecting_element.begin()));
01563 
01564     /*
01565      * Identify nodes and Elements to perform switch on
01566      * Intersecting node is node A
01567      * Other node is node B
01568      *
01569      * Element 1 only contains node A
01570      * Element 2 has nodes B and A (in that order)
01571      * Element 3 only contains node B
01572      * Element 4 has nodes A and B (in that order)
01573      */
01574     unsigned node_A_index = pNode->GetIndex();
01575     unsigned node_B_index;
01576     unsigned element_1_index =  *(intersecting_element.begin());
01577     unsigned element_2_index;
01578     unsigned element_3_index =  elementIndex;
01579     unsigned element_4_index;
01580 
01581     std::set<unsigned>::iterator iter = elements_containing_intersecting_node.begin();
01582     unsigned element_a_index = *(iter);
01583     iter++;
01584     unsigned element_b_index = *(iter);
01585 
01586     VertexElement<ELEMENT_DIM, SPACE_DIM>* p_element_a = this->GetElement(element_a_index);
01587     VertexElement<ELEMENT_DIM, SPACE_DIM>* p_element_b = this->GetElement(element_b_index);
01588 
01589     std::set<unsigned> element_a_nodes;
01590     for (unsigned node_index = 0;  node_index < p_element_a->GetNumNodes(); node_index++)
01591     {
01592         element_a_nodes.insert(p_element_a->GetNodeGlobalIndex(node_index));
01593     }
01594 
01595     std::set<unsigned> element_b_nodes;
01596     for (unsigned node_index = 0;  node_index < p_element_b->GetNumNodes(); node_index++)
01597     {
01598         element_b_nodes.insert(p_element_b->GetNodeGlobalIndex(node_index));
01599     }
01600 
01601     std::set<unsigned> switching_nodes;
01602     std::set_intersection(element_a_nodes.begin(), element_a_nodes.end(),
01603                           element_b_nodes.begin(), element_b_nodes.end(),
01604                           std::inserter(switching_nodes, switching_nodes.begin()));
01605 
01606     assert(switching_nodes.size() == 2);
01607 
01608     // Check intersecting node is this set
01609     assert(switching_nodes.find(node_A_index) != switching_nodes.end());
01610     switching_nodes.erase(node_A_index);
01611 
01612     assert(switching_nodes.size() == 1);
01613 
01614     node_B_index = *(switching_nodes.begin());
01615 
01616     // Now identify elements 2 and 4
01617     unsigned node_A_local_index_in_a = p_element_a->GetNodeLocalIndex(node_A_index);
01618     unsigned node_B_local_index_in_a = p_element_a->GetNodeLocalIndex(node_B_index);
01619 
01620     if ((node_B_local_index_in_a+1)%p_element_a->GetNumNodes() == node_A_local_index_in_a)
01621     {
01622         assert((p_element_b->GetNodeLocalIndex(node_A_index)+1)%p_element_b->GetNumNodes()
01623                == p_element_b->GetNodeLocalIndex(node_B_index));
01624 
01625         // Element 2 is element a, element 4 is element b
01626         element_2_index = element_a_index;
01627         element_4_index = element_b_index;
01628     }
01629     else
01630     {
01631         assert((p_element_b->GetNodeLocalIndex(node_B_index)+1)%p_element_b->GetNumNodes()
01632                == p_element_b->GetNodeLocalIndex(node_A_index));
01633 
01634         // Element 2 is element b, element 4 is element a
01635         element_2_index = element_b_index;
01636         element_4_index = element_a_index;
01637     }
01638 
01639     unsigned intersected_edge = this->GetLocalIndexForElementEdgeClosestToPoint(pNode->rGetLocation(), elementIndex);
01640 
01641     unsigned node_A_local_index_in_1 = this->GetElement(element_1_index)->GetNodeLocalIndex(node_A_index);
01642 
01643     unsigned node_A_local_index_in_2 = this->GetElement(element_2_index)->GetNodeLocalIndex(node_A_index);
01644     unsigned node_B_local_index_in_2 = this->GetElement(element_2_index)->GetNodeLocalIndex(node_B_index);
01645 
01646     unsigned node_B_local_index_in_3 = this->GetElement(elementIndex)->GetNodeLocalIndex(node_B_index);
01647 
01648     unsigned node_A_local_index_in_4 = this->GetElement(element_4_index)->GetNodeLocalIndex(node_A_index);
01649     unsigned node_B_local_index_in_4 = this->GetElement(element_4_index)->GetNodeLocalIndex(node_B_index);
01650 
01651     if (intersected_edge==node_B_local_index_in_3)
01652     {
01653         /*
01654          * Add node B to element 1 after node A
01655          * Add node A to element 3 after node B
01656          *
01657          * Remove node B from element 2
01658          * Remove node A from element 4
01659          */
01660         this->mElements[element_1_index]->AddNode(this->mNodes[node_B_index], node_A_local_index_in_1);
01661         this->mElements[element_3_index]->AddNode(this->mNodes[node_A_index], node_B_local_index_in_3);
01662 
01663         this->mElements[element_2_index]->DeleteNode(node_B_local_index_in_2);
01664         this->mElements[element_4_index]->DeleteNode(node_A_local_index_in_4);
01665     }
01666     else
01667     {
01668         assert((intersected_edge+1)%num_nodes==node_B_local_index_in_3);
01669 
01670         /*
01671          * Add node B to element 1 before node A
01672          * Add node A to element 3 before node B
01673          *
01674          * Remove node A from element 2
01675          * Remove node B from element 4
01676          */
01677         unsigned node_before_A_in_1 = (node_A_local_index_in_1 - 1)%this->GetElement(element_1_index)->GetNumNodes();
01678         unsigned node_before_B_in_3 = (node_B_local_index_in_3 - 1)%this->GetElement(element_3_index)->GetNumNodes();
01679 
01680         this->mElements[element_1_index]->AddNode(this->mNodes[node_B_index], node_before_A_in_1);
01681         this->mElements[element_3_index]->AddNode(this->mNodes[node_A_index], node_before_B_in_3);
01682 
01683         this->mElements[element_2_index]->DeleteNode(node_A_local_index_in_2);
01684         this->mElements[element_4_index]->DeleteNode(node_B_local_index_in_4);
01685     }
01686 }
01687 
01688 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
01689 void MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::PerformT2Swap(VertexElement<ELEMENT_DIM,SPACE_DIM>& rElement)
01690 {
01691     // Make sure that we are in the correct dimension - this code will be eliminated at compile time
01692     assert(SPACE_DIM == 2); // only works in 2D at present
01693     assert(ELEMENT_DIM == SPACE_DIM);
01694 
01695     /*
01696      * For removing a small triangle
01697      *
01698      *  \
01699      *   \
01700      *   |\
01701      *   | \
01702      *   |  \_ _ _ _ _
01703      *   |  /
01704      *   | /
01705      *   |/
01706      *   /
01707      *  /
01708      *
01709      * To
01710      *
01711      *  \
01712      *   \
01713      *    \
01714      *     \
01715      *      \_ _ _ _ _
01716      *      /
01717      *     /
01718      *    /
01719      *   /
01720      *  /
01721      *
01722      */
01723 
01724     // Assert that the triangle element has only three nodes (!)
01725     assert(rElement.GetNumNodes() == 3u);
01726 
01727     bool is_node_on_boundary = false;
01728     for (unsigned i=0; i<3; i++)
01729     {
01730         if (rElement.GetNode(i)->IsBoundaryNode())
01731         {
01732             is_node_on_boundary= true;
01733         }
01734     }
01735 
01736     // Create new node at centroid of element which will be a boundary node if any of the existing nodes was on the boundary.
01737     c_vector<double, SPACE_DIM> new_node_location = this->GetCentroidOfElement(rElement.GetIndex());
01738     unsigned new_node_global_index = this->AddNode(new Node<SPACE_DIM>(GetNumNodes(), new_node_location, is_node_on_boundary));
01739     Node<SPACE_DIM>* p_new_node = this->GetNode(new_node_global_index);
01740 
01741     std::set<unsigned> neighbouring_elements;
01742 
01743     for (unsigned i=0; i<3; i++)
01744     {
01745         Node<SPACE_DIM>* p_node_a = rElement.GetNode((i+1)%3);
01746         Node<SPACE_DIM>* p_node_b = rElement.GetNode((i+2)%3);
01747 
01748         std::set<unsigned> elements_of_node_a = p_node_a->rGetContainingElementIndices();
01749         std::set<unsigned> elements_of_node_b = p_node_b->rGetContainingElementIndices();
01750 
01751         std::set<unsigned> common_elements;
01752 
01753         std::set_intersection( elements_of_node_a.begin(), elements_of_node_a.end(),
01754                                elements_of_node_b.begin(), elements_of_node_b.end(),
01755                                std::inserter(common_elements, common_elements.begin()));
01756 
01757         assert(common_elements.size() <= 2u);
01758         common_elements.erase(rElement.GetIndex());
01759 
01760         if (common_elements.size() == 1u) // there is a neighbouring element
01761         {
01762             VertexElement<ELEMENT_DIM,SPACE_DIM>* p_neighbouring_element = this->GetElement(*(common_elements.begin()));
01763 
01764             if (p_neighbouring_element->GetNumNodes() < 4u)
01765             {
01766                 EXCEPTION("One of the neighbours of a small triangular element is also a triangle - dealing with this has not been implemented yet");
01767             }
01768 
01769             p_neighbouring_element-> ReplaceNode(p_node_a, p_new_node);
01770             p_neighbouring_element->DeleteNode(p_neighbouring_element->GetNodeLocalIndex(p_node_b->GetIndex()));
01771         }
01772         else
01773         {
01774             assert( (p_node_a->IsBoundaryNode()) && (p_node_b->IsBoundaryNode()) );
01775         }
01776     }
01777 
01778     // Also have to mark pElement, pElement->GetNode(0), pElement->GetNode(1), and pElement->GetNode(2) as deleted.
01779     mDeletedNodeIndices.push_back(rElement.GetNodeGlobalIndex(0));
01780     mDeletedNodeIndices.push_back(rElement.GetNodeGlobalIndex(1));
01781     mDeletedNodeIndices.push_back(rElement.GetNodeGlobalIndex(2));
01782     rElement.GetNode(0)->MarkAsDeleted();
01783     rElement.GetNode(1)->MarkAsDeleted();
01784     rElement.GetNode(2)->MarkAsDeleted();
01785 
01786     mDeletedElementIndices.push_back(rElement.GetIndex());
01787     rElement.MarkAsDeleted();
01788 }
01789 
01790 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
01791 void MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::PerformT3Swap(Node<SPACE_DIM>* pNode, unsigned elementIndex)
01792 {
01793     // Make sure that we are in the correct dimension - this code will be eliminated at compile time
01794     assert(SPACE_DIM == 2); // only works in 2D at present
01795     assert(ELEMENT_DIM == SPACE_DIM);
01796 
01797     // Check pNode is a boundary node
01798     assert(pNode->IsBoundaryNode());
01799 
01800     // Store the index of the elements containing the intersecting node
01801     std::set<unsigned> elements_containing_intersecting_node = pNode->rGetContainingElementIndices();
01802 
01803     // Get the local index of the node in the intersected element after which the new node is to be added
01804     unsigned node_A_local_index = this->GetLocalIndexForElementEdgeClosestToPoint(pNode->rGetLocation(), elementIndex);
01805 
01806     // Get current node location
01807     c_vector<double, SPACE_DIM> node_location = pNode->rGetModifiableLocation();
01808 
01809     // Get element
01810     VertexElement<ELEMENT_DIM, SPACE_DIM>* p_element = this->GetElement(elementIndex);
01811     unsigned num_nodes = p_element->GetNumNodes();
01812 
01814 //   TRACE("intersecting node");
01815 //    PRINT_2_VARIABLES(pNode->GetIndex(),node_location);
01816 //
01817 //
01818 //    for (std::set<unsigned>::const_iterator elem_iter = elements_containing_intersecting_node.begin();
01819 //         elem_iter != elements_containing_intersecting_node.end();
01820 //         elem_iter++)
01821 //
01822 //    {
01823 //        TRACE("intersecting element");
01824 //
01825 //        VertexElement<ELEMENT_DIM, SPACE_DIM>* p_element_intersection = this->GetElement(*elem_iter);
01826 //        PRINT_VARIABLE(p_element_intersection->GetIndex());
01827 //
01828 //        for (unsigned node_index = 0;
01829 //             node_index < p_element_intersection->GetNumNodes();
01830 //             node_index++)
01831 //        {
01832 //            PRINT_3_VARIABLES(p_element_intersection->GetNodeGlobalIndex(node_index),
01833 //                              p_element_intersection->GetNode(node_index)->IsBoundaryNode(),
01834 //                              p_element_intersection->GetNodeLocation(node_index));
01835 //        }
01836 //    }
01837 //    TRACE("intersected element");
01838 //    PRINT_VARIABLE(p_element->GetIndex());
01839 //    for (unsigned node_index = 0;
01840 //         node_index < p_element->GetNumNodes();
01841 //         node_index++)
01842 //    {
01843 //        PRINT_3_VARIABLES(p_element->GetNodeGlobalIndex(node_index),
01844 //                          p_element->GetNode(node_index)->IsBoundaryNode(),
01845 //                          p_element->GetNodeLocation(node_index));
01846 //    }
01848 
01849     // Get the nodes at either end of the edge to be divided
01850     unsigned vertexA_index = p_element->GetNodeGlobalIndex(node_A_local_index);
01851     unsigned vertexB_index = p_element->GetNodeGlobalIndex((node_A_local_index+1)%num_nodes);
01852 
01853     // Check these nodes are also boundary nodes if this fails then the elements have become concave and you need a smaller timestep
01854     if (!this->mNodes[vertexA_index]->IsBoundaryNode() || !this->mNodes[vertexB_index]->IsBoundaryNode())
01855     {
01856         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.");
01857     }
01858 
01859     // Get the nodes at either end of the edge to be divided and calculate intersection
01860     c_vector<double, SPACE_DIM> vertexA = p_element->GetNodeLocation(node_A_local_index);
01861     c_vector<double, SPACE_DIM> vertexB = p_element->GetNodeLocation((node_A_local_index+1)%num_nodes);
01862     c_vector<double, SPACE_DIM> vector_a_to_point = this->GetVectorFromAtoB(vertexA, node_location);
01863 
01864     c_vector<double, SPACE_DIM> vector_a_to_b = this->GetVectorFromAtoB(vertexA, vertexB);
01865 
01866     c_vector<double, SPACE_DIM> edge_ab_unit_vector = vector_a_to_b/norm_2(vector_a_to_b);
01867     c_vector<double, SPACE_DIM> intersection = vertexA + edge_ab_unit_vector*inner_prod(vector_a_to_point, edge_ab_unit_vector);
01868 
01869     // Store the location of the T3Swap, the location of the intersection with the edge.
01870     mLocationsOfT3Swaps.push_back(intersection);
01871 
01872     /*
01873      * If the edge is shorter than 4.0*mCellRearrangementRatio*mCellRearrangementThreshold move vertexA and vertexB
01874      * 4.0*mCellRearrangementRatio*mCellRearrangementThreshold apart. \todo investigate if moving A and B causes other issues with nearby nodes.
01875      *
01876      * Note: this distance so that there is always enough room for new nodes (if necessary)
01877      * \todo currently this assumes a worst case scenario of 3 nodes between A and B could be less movement for other cases. #1399
01878      */
01879     if (norm_2(vector_a_to_b) < 4.0*mCellRearrangementRatio*mCellRearrangementThreshold)
01880     {
01881         WARNING("Trying to merge a node onto an edge which is too small.");
01882 
01883         c_vector<double, SPACE_DIM> centre_a_and_b = vertexA + 0.5*vector_a_to_b;
01884 
01885         vertexA = centre_a_and_b  - 2.0*mCellRearrangementRatio*mCellRearrangementThreshold*vector_a_to_b/norm_2(vector_a_to_b);
01886         ChastePoint<SPACE_DIM> vertex_A_point(vertexA);
01887         SetNode(p_element->GetNodeGlobalIndex(node_A_local_index), vertex_A_point);
01888 
01889         vertexB = centre_a_and_b  + 2.0*mCellRearrangementRatio*mCellRearrangementThreshold*vector_a_to_b/norm_2(vector_a_to_b);
01890         ChastePoint<SPACE_DIM> vertex_B_point(vertexB);
01891         SetNode(p_element->GetNodeGlobalIndex((node_A_local_index+1)%num_nodes), vertex_B_point);
01892 
01893         // Reset distances
01894         vector_a_to_b = this->GetVectorFromAtoB(vertexA, vertexB);
01895         edge_ab_unit_vector = vector_a_to_b/norm_2(vector_a_to_b);
01896 
01897         // Reset the intersection to the middle to allow enough room for new nodes
01898         intersection = centre_a_and_b;
01899     }
01900 
01901     /*
01902      * If the intersection is within mCellRearrangementRatio^2*mCellRearrangementThreshold of vertexA or vertexB move it
01903      * mCellRearrangementRatio^2*mCellRearrangementThreshold away.
01904      *
01905      * Note: this distance so that there is always enough room for new nodes (if necessary).
01906      * \todo currently this assumes a worst case scenario of 3 nodes between A and B could be less movement for other cases.
01907      */
01908     if (norm_2(intersection - vertexA) < 2.0*mCellRearrangementRatio*mCellRearrangementThreshold)
01909     {
01910         intersection = vertexA + 2.0*mCellRearrangementRatio*mCellRearrangementThreshold*edge_ab_unit_vector;
01911     }
01912     if (norm_2(intersection - vertexB) < 2.0*mCellRearrangementRatio*mCellRearrangementThreshold)
01913     {
01914         intersection = vertexB - 2.0*mCellRearrangementRatio*mCellRearrangementThreshold*edge_ab_unit_vector;
01915     }
01916 
01917     if (pNode->GetNumContainingElements() == 1)
01918     {
01919         // Get the index of the element containing the intersecting node
01920         unsigned intersecting_element_index = *elements_containing_intersecting_node.begin();
01921 
01922         // Get element
01923         VertexElement<ELEMENT_DIM, SPACE_DIM>* p_intersecting_element = this->GetElement(intersecting_element_index);
01924 
01925         unsigned local_index = p_intersecting_element->GetNodeLocalIndex(pNode->GetIndex());
01926         unsigned next_node = p_intersecting_element->GetNodeGlobalIndex((local_index + 1)%(p_intersecting_element->GetNumNodes()));
01927         unsigned previous_node = p_intersecting_element->GetNodeGlobalIndex((local_index + p_intersecting_element->GetNumNodes() - 1)%(p_intersecting_element->GetNumNodes()));
01928 
01929         // Check to see if the nodes adjacent to the intersecting node are contained in the intersected element VertexA and VertexB
01930         if (next_node == vertexA_index || previous_node == vertexA_index || next_node == vertexB_index || previous_node == vertexB_index)
01931         {
01932             unsigned common_vertex_index;
01933 
01934             if (next_node == vertexA_index || previous_node == vertexA_index)
01935             {
01936                 common_vertex_index = vertexA_index;
01937             }
01938             else
01939             {
01940                 common_vertex_index = vertexB_index;
01941             }
01942 
01943             assert(this->mNodes[common_vertex_index]->GetNumContainingElements()>1);
01944 
01945             std::set<unsigned> elements_containing_common_vertex = this->mNodes[common_vertex_index]->rGetContainingElementIndices();
01946             std::set<unsigned>::const_iterator it = elements_containing_common_vertex.begin();
01947             VertexElement<ELEMENT_DIM, SPACE_DIM>* p_element_common_1 = this->GetElement(*it);
01948             it++;
01949             VertexElement<ELEMENT_DIM, SPACE_DIM>* p_element_common_2 = this->GetElement(*it);
01950 
01951             // Calculate the number of common vertices between element_1 and element_2
01952             unsigned num_common_vertices = 0;
01953             for (unsigned i=0; i<p_element_common_1->GetNumNodes(); i++)
01954             {
01955                 for (unsigned j=0; j<p_element_common_2->GetNumNodes(); j++)
01956                 {
01957                     if (p_element_common_1->GetNodeGlobalIndex(i)==p_element_common_2->GetNodeGlobalIndex(j))
01958                     {
01959                         num_common_vertices++;
01960                     }
01961                 }
01962             }
01963 
01964             if (num_common_vertices == 1 || this->mNodes[common_vertex_index]->GetNumContainingElements() > 2)
01965             {
01966                 /*
01967                  * This is the situation here.
01968                  *
01969                  *  From          To
01970                  *   _             _
01971                  *    |  <---       |
01972                  *    |  /\         |\
01973                  *    | /  \        | \
01974                  *   _|/____\      _|__\
01975                  *
01976                  * The edge goes from vertexA--vertexB to vertexA--pNode--vertexB
01977                  */
01978 
01979                 // Move original node
01980                 pNode->rGetModifiableLocation() = intersection;
01981 
01982                 // Add the moved nodes to the element (this also updates the node)
01983                 this->GetElement(elementIndex)->AddNode(pNode, node_A_local_index);
01984 
01985                 // Check the nodes are updated correctly
01986                 assert(pNode->GetNumContainingElements() == 2);
01987             }
01988             else if (num_common_vertices == 2)
01989             {
01990                 /*
01991                  * This is the situation here.
01992                  *
01993                  * C is common_vertex D is the other one.
01994                  *
01995                  *  From          To
01996                  *   _ D          _
01997                  *    | <---       |
01998                  *    | /\         |\
01999                  *   C|/  \        | \
02000                  *   _|____\      _|__\
02001                  *
02002                  *  The edge goes from vertexC--vertexB to vertexC--pNode--vertexD
02003                  *  then VertexB is removed as it is no longer needed.
02004                  */
02005 
02006                 // Move original node
02007                 pNode->rGetModifiableLocation() = intersection;
02008 
02009                 // Replace common_vertex with the the moved node (this also updates the nodes)
02010                 this->GetElement(elementIndex)->ReplaceNode(this->mNodes[common_vertex_index], pNode);
02011 
02012                 // Remove common_vertex
02013                 unsigned common_vertex_local_index = this->GetElement(intersecting_element_index)->GetNodeLocalIndex(common_vertex_index);
02014                 this->GetElement(intersecting_element_index)->DeleteNode(common_vertex_local_index);
02015                 assert(this->mNodes[common_vertex_index]->GetNumContainingElements() == 0);
02016 
02017                 this->mNodes[common_vertex_index]->MarkAsDeleted();
02018                 mDeletedNodeIndices.push_back(common_vertex_index);
02019 
02020                 // Check the nodes are updated correctly
02021                 assert(pNode->GetNumContainingElements() == 2);
02022             }
02023             else
02024             {
02025                 // This can't happen as nodes can't be on the internal edge of 2 elements.
02026                 NEVER_REACHED;
02027             }
02028         }
02029         else
02030         {
02031             /*
02032              *  From          To
02033              *   ____        _______
02034              *                 / \
02035              *    /\   ^      /   \
02036              *   /  \  |
02037              *
02038              *  The edge goes from vertexA--vertexB to vertexA--new_node--pNode--vertexB
02039              */
02040 
02041             // Move original node
02042             pNode->rGetModifiableLocation() = intersection + 0.5*mCellRearrangementRatio*mCellRearrangementThreshold*edge_ab_unit_vector;
02043 
02044             c_vector<double, SPACE_DIM> new_node_location = intersection - 0.5*mCellRearrangementRatio*mCellRearrangementThreshold*edge_ab_unit_vector;
02045 
02046             // Add new node which will always be a boundary node
02047             unsigned new_node_global_index = this->AddNode(new Node<SPACE_DIM>(0, true, new_node_location[0], new_node_location[1]));
02048 
02049             // Add the moved and new nodes to the element (this also updates the node)
02050             this->GetElement(elementIndex)->AddNode(pNode, node_A_local_index);
02051             this->GetElement(elementIndex)->AddNode(this->mNodes[new_node_global_index], node_A_local_index);
02052 
02053             // Add the new node to the original element containing pNode (this also updates the node)
02054             this->GetElement(intersecting_element_index)->AddNode(this->mNodes[new_node_global_index], this->GetElement(intersecting_element_index)->GetNodeLocalIndex(pNode->GetIndex()));
02055 
02056             // Check the nodes are updated correctly
02057             assert(pNode->GetNumContainingElements() == 2);
02058             assert(this->mNodes[new_node_global_index]->GetNumContainingElements() == 2);
02059         }
02060     }
02061     else if (pNode->GetNumContainingElements() == 2)
02062     {
02063         // Find the nodes contained in elements containing the intersecting node
02064         std::set<unsigned>::const_iterator it = elements_containing_intersecting_node.begin();
02065         VertexElement<ELEMENT_DIM, SPACE_DIM>* p_element_intersection_1 = this->GetElement(*it);
02066         it++;
02067         VertexElement<ELEMENT_DIM, SPACE_DIM>* p_element_intersection_2 = this->GetElement(*it);
02068 
02069         unsigned local_index_1 = p_element_intersection_1->GetNodeLocalIndex(pNode->GetIndex());
02070         unsigned next_node_1 = p_element_intersection_1->GetNodeGlobalIndex((local_index_1 + 1)%(p_element_intersection_1->GetNumNodes()));
02071         unsigned previous_node_1 = p_element_intersection_1->GetNodeGlobalIndex((local_index_1 + p_element_intersection_1->GetNumNodes() - 1)%(p_element_intersection_1->GetNumNodes()));
02072         unsigned local_index_2 = p_element_intersection_2->GetNodeLocalIndex(pNode->GetIndex());
02073         unsigned next_node_2 = p_element_intersection_2->GetNodeGlobalIndex((local_index_2 + 1)%(p_element_intersection_2->GetNumNodes()));
02074         unsigned previous_node_2 = p_element_intersection_2->GetNodeGlobalIndex((local_index_2 + p_element_intersection_2->GetNumNodes() - 1)%(p_element_intersection_2->GetNumNodes()));
02075 
02076         // Check to see if the nodes adjacent to the intersecting node are contained in the intersected element VertexA and VertexB
02077         if ((next_node_1 == vertexA_index || previous_node_1 == vertexA_index || next_node_2 == vertexA_index || previous_node_2 == vertexA_index) &&
02078                (next_node_1 == vertexB_index || previous_node_1 == vertexB_index || next_node_2 == vertexB_index || previous_node_2 == vertexB_index))
02079         {
02080             /*
02081              * Here we have
02082              *        __
02083              *      /|             /
02084              *  __ / |     --> ___/
02085              *     \ |            \
02086              *      \|__           \
02087              *
02088              * Where the node on the left has overlapped the edge A B
02089              *
02090              * Move p_node to the intersection on A B and merge AB and p_node
02091              */
02092 
02093             //Check they are all boundary nodes
02094             assert(pNode->IsBoundaryNode());
02095             assert(this->mNodes[vertexA_index]->IsBoundaryNode());
02096             assert(this->mNodes[vertexB_index]->IsBoundaryNode());
02097 
02098             // Move p_node to the intersection with the edge A B
02099             pNode->rGetModifiableLocation() = intersection;
02100             pNode->SetAsBoundaryNode(false);
02101 
02102             // Add pNode to the intersected element
02103             this->GetElement(elementIndex)->AddNode(pNode, node_A_local_index);
02104 
02105             // Remove VertexA from elements
02106             std::set<unsigned> elements_containing_vertex_A = this->mNodes[vertexA_index]->rGetContainingElementIndices();
02107             for (std::set<unsigned>::const_iterator iter = elements_containing_vertex_A.begin();
02108                  iter != elements_containing_vertex_A.end();
02109                  iter++)
02110             {
02111                 this->GetElement(*iter)->DeleteNode(this->GetElement(*iter)->GetNodeLocalIndex(vertexA_index));
02112             }
02113 
02114             // Remove VertexA from the mesh
02115             assert(this->mNodes[vertexA_index]->GetNumContainingElements()==0);
02116 
02117             this->mNodes[vertexA_index]->MarkAsDeleted();
02118             mDeletedNodeIndices.push_back(vertexA_index);
02119 
02120             // Remove VertexB from elements
02121             std::set<unsigned> elements_containing_vertex_B = this->mNodes[vertexB_index]->rGetContainingElementIndices();
02122             for (std::set<unsigned>::const_iterator iter = elements_containing_vertex_B.begin();
02123                  iter != elements_containing_vertex_B.end();
02124                  iter++)
02125             {
02126                 this->GetElement(*iter)->DeleteNode(this->GetElement(*iter)->GetNodeLocalIndex(vertexB_index));
02127             }
02128 
02129             // Remove VertexB from the mesh
02130             assert(this->mNodes[vertexB_index]->GetNumContainingElements()==0);
02131 
02132             this->mNodes[vertexB_index]->MarkAsDeleted();
02133             mDeletedNodeIndices.push_back(vertexB_index);
02134         }
02135         else
02136         {
02137             if (next_node_1 == vertexA_index || previous_node_1 == vertexA_index || next_node_2 == vertexA_index || previous_node_2 == vertexA_index)
02138             {
02139                 // Get elements containing vertexA_index (the Common vertex)
02140 
02141                 assert(this->mNodes[vertexA_index]->GetNumContainingElements()>1);
02142 
02143                 std::set<unsigned> elements_containing_vertex_A = this->mNodes[vertexA_index]->rGetContainingElementIndices();
02144                 std::set<unsigned>::const_iterator iter = elements_containing_vertex_A.begin();
02145                 VertexElement<ELEMENT_DIM, SPACE_DIM>* p_element_common_1 = this->GetElement(*iter);
02146                 iter++;
02147                 VertexElement<ELEMENT_DIM, SPACE_DIM>* p_element_common_2 = this->GetElement(*iter);
02148 
02149                 // Calculate the number of common vertices between element_1 and element_2
02150                 unsigned num_common_vertices = 0;
02151                 for (unsigned i=0; i<p_element_common_1->GetNumNodes(); i++)
02152                 {
02153                     for (unsigned j=0; j<p_element_common_2->GetNumNodes(); j++)
02154                     {
02155                         if (p_element_common_1->GetNodeGlobalIndex(i) == p_element_common_2->GetNodeGlobalIndex(j))
02156                         {
02157                             num_common_vertices++;
02158                         }
02159                     }
02160                 }
02161 
02162                 if (num_common_vertices == 1 || this->mNodes[vertexA_index]->GetNumContainingElements() > 2)
02163                 {
02164                     /*
02165                      *  From          To
02166                      *   _ B              _ B
02167                      *    |  <---          |
02168                      *    |   /|\          |\
02169                      *    |  / | \         | \
02170                      *    | /  |  \        |\ \
02171                      *   _|/___|___\      _|_\_\
02172                      *     A                A
02173                      *
02174                      * The edge goes from vertexA--vertexB to vertexA--pNode--new_node--vertexB
02175                      */
02176 
02177                     // Move original node and change to non-boundary node
02178                     pNode->rGetModifiableLocation() = intersection - 0.5*mCellRearrangementRatio*mCellRearrangementThreshold*edge_ab_unit_vector;
02179                     pNode->SetAsBoundaryNode(false);
02180 
02181                     c_vector<double, SPACE_DIM> new_node_location = intersection + 0.5*mCellRearrangementRatio*mCellRearrangementThreshold*edge_ab_unit_vector;
02182 
02183                     // Add new node which will always be a boundary node
02184                     unsigned new_node_global_index = this->AddNode(new Node<SPACE_DIM>(0, true, new_node_location[0], new_node_location[1]));
02185 
02186                     // Add the moved nodes to the element (this also updates the node)
02187                     this->GetElement(elementIndex)->AddNode(this->mNodes[new_node_global_index], node_A_local_index);
02188                     this->GetElement(elementIndex)->AddNode(pNode, node_A_local_index);
02189 
02190                     // Add the new nodes to the original elements containing pNode (this also updates the node)
02191                     if (next_node_1 == previous_node_2)
02192                     {
02193                         p_element_intersection_1->AddNode(this->mNodes[new_node_global_index], (local_index_1 + p_element_intersection_1->GetNumNodes() - 1)%(p_element_intersection_1->GetNumNodes()));
02194                     }
02195                     else
02196                     {
02197                         assert(next_node_2 == previous_node_1);
02198 
02199                         p_element_intersection_2->AddNode(this->mNodes[new_node_global_index], (local_index_2 + p_element_intersection_2->GetNumNodes() - 1)%(p_element_intersection_2->GetNumNodes()));
02200                     }
02201 
02202                     // Check the nodes are updated correctly
02203                     assert(pNode->GetNumContainingElements() == 3);
02204                     assert(this->mNodes[new_node_global_index]->GetNumContainingElements() == 2);
02205                 }
02206                 else if (num_common_vertices == 2)
02207                 {
02208                     /*
02209                      *  From          To
02210                      *   _ B              _ B
02211                      *    |<---          |
02212                      *    | /|\          |\
02213                      *    |/ | \         | \
02214                      *    |  |  \        |\ \
02215                      *   _|__|___\      _|_\_\
02216                      *     A              A
02217                      *
02218                      * The edge goes from vertexA--vertexB to vertexA--pNode--new_node--vertexB
02219                      * then vertexA is removed
02220                      */
02221 
02222                     // Move original node and change to non-boundary node
02223                     pNode->rGetModifiableLocation() = intersection - 0.5*mCellRearrangementRatio*mCellRearrangementThreshold*edge_ab_unit_vector;
02224                     pNode->SetAsBoundaryNode(false);
02225 
02226                      c_vector<double, SPACE_DIM> new_node_location = intersection + 0.5*mCellRearrangementRatio*mCellRearrangementThreshold*edge_ab_unit_vector;
02227 
02228                     // Add new node which will always be a boundary node
02229                     unsigned new_node_global_index = this->AddNode(new Node<SPACE_DIM>(0, true, new_node_location[0], new_node_location[1]));
02230 
02231                     // Add the moved nodes to the element (this also updates the node)
02232                     this->GetElement(elementIndex)->AddNode(this->mNodes[new_node_global_index], node_A_local_index);
02233                     this->GetElement(elementIndex)->AddNode(pNode, node_A_local_index);
02234 
02235                     // Add the new nodes to the original elements containing pNode (this also updates the node)
02236                     if (next_node_1 == previous_node_2)
02237                     {
02238                         p_element_intersection_1->AddNode(this->mNodes[new_node_global_index], (local_index_1 + p_element_intersection_1->GetNumNodes() - 1)%(p_element_intersection_1->GetNumNodes()));
02239                     }
02240                     else
02241                     {
02242                         assert(next_node_2 == previous_node_1);
02243 
02244                         p_element_intersection_2->AddNode(this->mNodes[new_node_global_index], (local_index_2 + p_element_intersection_2->GetNumNodes() - 1)%(p_element_intersection_2->GetNumNodes()));
02245                     }
02246 
02247                     // Remove VertexA from the mesh
02248                     p_element_common_1->DeleteNode(p_element_common_1->GetNodeLocalIndex(vertexA_index));
02249                     p_element_common_2->DeleteNode(p_element_common_2->GetNodeLocalIndex(vertexA_index));
02250 
02251                     assert(this->mNodes[vertexA_index]->GetNumContainingElements()==0);
02252 
02253                     this->mNodes[vertexA_index]->MarkAsDeleted();
02254                     mDeletedNodeIndices.push_back(vertexA_index);
02255 
02256                     // Check the nodes are updated correctly
02257                     assert(pNode->GetNumContainingElements() == 3);
02258                     assert(this->mNodes[new_node_global_index]->GetNumContainingElements() == 2);
02259                 }
02260                 else
02261                 {
02262                     // This can't happen as nodes can't be on the internal edge of 2 elements.
02263                     NEVER_REACHED;
02264                 }
02265 
02266             }
02267             else if (next_node_1 == vertexB_index || previous_node_1 == vertexB_index || next_node_2 == vertexB_index || previous_node_2 == vertexB_index)
02268             {
02269                 // Get elements containing vertexB_index (the Common vertex)
02270 
02271                 assert(this->mNodes[vertexB_index]->GetNumContainingElements()>1);
02272 
02273                 std::set<unsigned> elements_containing_vertex_B = this->mNodes[vertexB_index]->rGetContainingElementIndices();
02274                 std::set<unsigned>::const_iterator iter = elements_containing_vertex_B.begin();
02275                 VertexElement<ELEMENT_DIM, SPACE_DIM>* p_element_common_1 = this->GetElement(*iter);
02276                 iter++;
02277                 VertexElement<ELEMENT_DIM, SPACE_DIM>* p_element_common_2 = this->GetElement(*iter);
02278 
02279                 // Calculate the number of common vertices between element_1 and element_2
02280                 unsigned num_common_vertices = 0;
02281                 for (unsigned i=0; i<p_element_common_1->GetNumNodes(); i++)
02282                 {
02283                     for (unsigned j=0; j<p_element_common_2->GetNumNodes(); j++)
02284                     {
02285                         if (p_element_common_1->GetNodeGlobalIndex(i)==p_element_common_2->GetNodeGlobalIndex(j))
02286                         {
02287                             num_common_vertices++;
02288                         }
02289                     }
02290                 }
02291 
02292                 if (num_common_vertices == 1 || this->mNodes[vertexB_index]->GetNumContainingElements() > 2)
02293                 {
02294                     /*
02295                      *  From          To
02296                      *   _B_________      _B____
02297                      *    |\   |   /       | / /
02298                      *    | \  |  /        |/ /
02299                      *    |  \ | /         | /
02300                      *    |   \|/          |/
02301                      *   _|   <---        _|
02302                      *    A
02303                      *
02304                      * The edge goes from vertexA--vertexB to vertexA--new_node--pNode--vertexB
02305                      */
02306 
02307                     // Move original node and change to non-boundary node
02308                     pNode->rGetModifiableLocation() = intersection + 0.5*mCellRearrangementRatio*mCellRearrangementThreshold*edge_ab_unit_vector;
02309                     pNode->SetAsBoundaryNode(false);
02310 
02311                     c_vector<double, SPACE_DIM> new_node_location = intersection - 0.5*mCellRearrangementRatio*mCellRearrangementThreshold*edge_ab_unit_vector;
02312 
02313                     // Add new node which will always be a boundary node
02314                     unsigned new_node_global_index = this->AddNode(new Node<SPACE_DIM>(0, true, new_node_location[0], new_node_location[1]));
02315 
02316                     // Add the moved nodes to the element (this also updates the node)
02317                     this->GetElement(elementIndex)->AddNode(pNode, node_A_local_index);
02318                     this->GetElement(elementIndex)->AddNode(this->mNodes[new_node_global_index], node_A_local_index);
02319 
02320                     // Add the new nodes to the original elements containing pNode (this also updates the node)
02321                     if (next_node_1 == previous_node_2)
02322                     {
02323                         p_element_intersection_2->AddNode(this->mNodes[new_node_global_index], local_index_2);
02324                     }
02325                     else
02326                     {
02327                         assert(next_node_2 == previous_node_1);
02328 
02329                         p_element_intersection_1->AddNode(this->mNodes[new_node_global_index], local_index_1);
02330                     }
02331 
02332                     // Check the nodes are updated correctly
02333                     assert(pNode->GetNumContainingElements() == 3);
02334                     assert(this->mNodes[new_node_global_index]->GetNumContainingElements() == 2);
02335                 }
02336                 else if (num_common_vertices == 2)
02337                 {
02338                     /*
02339                      *  From          To
02340                      *   _B_______      _B____
02341                      *    |  |   /       | / /
02342                      *    |  |  /        |/ /
02343                      *    |\ | /         | /
02344                      *    | \|/          |/
02345                      *   _| <---        _|
02346                      *    A
02347                      *
02348                      * The edge goes from vertexA--vertexB to vertexA--new_node--pNode--vertexB
02349                      * then vertexB is removed
02350                      */
02351 
02352                     // Move original node and change to non-boundary node
02353                     pNode->rGetModifiableLocation() = intersection + 0.5*mCellRearrangementRatio*mCellRearrangementThreshold*edge_ab_unit_vector;
02354                     pNode->SetAsBoundaryNode(false);
02355 
02356                     c_vector<double, SPACE_DIM> new_node_location = intersection - 0.5*mCellRearrangementRatio*mCellRearrangementThreshold*edge_ab_unit_vector;
02357 
02358                     // Add new node which will always be a boundary node
02359                     unsigned new_node_global_index = this->AddNode(new Node<SPACE_DIM>(0, true, new_node_location[0], new_node_location[1]));
02360 
02361                     // Add the moved nodes to the element (this also updates the node)
02362                     this->GetElement(elementIndex)->AddNode(pNode, node_A_local_index);
02363                     this->GetElement(elementIndex)->AddNode(this->mNodes[new_node_global_index], node_A_local_index);
02364 
02365                     // Add the new nodes to the original elements containing pNode (this also updates the node)
02366                     if (next_node_1 == previous_node_2)
02367                     {
02368                         p_element_intersection_2->AddNode(this->mNodes[new_node_global_index], local_index_2);
02369                     }
02370                     else
02371                     {
02372                         assert(next_node_2 == previous_node_1);
02373 
02374                         p_element_intersection_1->AddNode(this->mNodes[new_node_global_index], local_index_1);
02375                     }
02376 
02377                     // Remove VertexB from the mesh
02378                     p_element_common_1->DeleteNode(p_element_common_1->GetNodeLocalIndex(vertexB_index));
02379                     p_element_common_2->DeleteNode(p_element_common_2->GetNodeLocalIndex(vertexB_index));
02380 
02381                     assert(this->mNodes[vertexB_index]->GetNumContainingElements()==0);
02382 
02383                     this->mNodes[vertexB_index]->MarkAsDeleted();
02384                     mDeletedNodeIndices.push_back(vertexB_index);
02385 
02386                     // Check the nodes are updated correctly
02387                     assert(pNode->GetNumContainingElements() == 3);
02388                     assert(this->mNodes[new_node_global_index]->GetNumContainingElements() == 2);
02389                 }
02390                 else
02391                 {
02392                     // This can't happen as nodes can't be on the internal edge of 2 elements.
02393                     NEVER_REACHED;
02394                 }
02395             }
02396             else
02397             {
02398                 /*
02399                  *  From          To
02400                  *   _____         _______
02401                  *                  / | \
02402                  *    /|\   ^      /  |  \
02403                  *   / | \  |
02404                  *
02405                  * The edge goes from vertexA--vertexB to vertexA--new_node_1--pNode--new_node_2--vertexB
02406                  */
02407 
02408                 // Move original node and change to non-boundary node
02409                 pNode->rGetModifiableLocation() = intersection;
02410                 pNode->SetAsBoundaryNode(false);
02411 
02412                 c_vector<double, SPACE_DIM> new_node_1_location = intersection - mCellRearrangementRatio*mCellRearrangementThreshold*edge_ab_unit_vector;
02413                 c_vector<double, SPACE_DIM> new_node_2_location = intersection + mCellRearrangementRatio*mCellRearrangementThreshold*edge_ab_unit_vector;
02414 
02415                 // Add new nodes which will always be boundary nodes
02416                 unsigned new_node_1_global_index = this->AddNode(new Node<SPACE_DIM>(0, true, new_node_1_location[0], new_node_1_location[1]));
02417                 unsigned new_node_2_global_index = this->AddNode(new Node<SPACE_DIM>(0, true, new_node_2_location[0], new_node_2_location[1]));
02418 
02419                 // Add the moved and new nodes to the element (this also updates the node)
02420                 this->GetElement(elementIndex)->AddNode(this->mNodes[new_node_2_global_index], node_A_local_index);
02421                 this->GetElement(elementIndex)->AddNode(pNode, node_A_local_index);
02422                 this->GetElement(elementIndex)->AddNode(this->mNodes[new_node_1_global_index], node_A_local_index);
02423 
02424                 // Add the new nodes to the original elements containing pNode (this also updates the node)
02425                 if (next_node_1 == previous_node_2)
02426                 {
02427                     p_element_intersection_1->AddNode(this->mNodes[new_node_2_global_index], (local_index_1 + p_element_intersection_1->GetNumNodes() - 1)%(p_element_intersection_1->GetNumNodes()));
02428                     p_element_intersection_2->AddNode(this->mNodes[new_node_1_global_index], local_index_2);
02429                 }
02430                 else
02431                 {
02432                     assert(next_node_2 == previous_node_1);
02433 
02434                     p_element_intersection_1->AddNode(this->mNodes[new_node_1_global_index], local_index_1);
02435                     p_element_intersection_2->AddNode(this->mNodes[new_node_2_global_index], (local_index_2 + p_element_intersection_2->GetNumNodes() - 1)%(p_element_intersection_2->GetNumNodes()));
02436                 }
02437 
02438                 // Check the nodes are updated correctly
02439                 assert(pNode->GetNumContainingElements() == 3);
02440                 assert(this->mNodes[new_node_1_global_index]->GetNumContainingElements() == 2);
02441                 assert(this->mNodes[new_node_2_global_index]->GetNumContainingElements() == 2);
02442             }
02443         }
02444     }
02445     else
02446     {
02447         EXCEPTION("Trying to merge a node, contained in more than 2 elements, into another element, this is not possible with the vertex mesh.");
02448     }
02449 }
02450 
02451 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
02452 void MutableVertexMesh<ELEMENT_DIM, SPACE_DIM>::PerformVoidRemoval(Node<SPACE_DIM>* pNodeA, Node<SPACE_DIM>* pNodeB, Node<SPACE_DIM>* pNodeC)
02453 {
02454     unsigned nodeA_index = pNodeA->GetIndex();
02455     unsigned nodeB_index = pNodeB->GetIndex();
02456     unsigned nodeC_index = pNodeC->GetIndex();
02457 
02458     c_vector<double, SPACE_DIM> nodes_midpoint = pNodeA->rGetLocation() + this->GetVectorFromAtoB(pNodeA->rGetLocation(), pNodeB->rGetLocation())/3.0
02459                                                                         + this->GetVectorFromAtoB(pNodeA->rGetLocation(), pNodeC->rGetLocation())/3.0;
02460 
02461     Node<SPACE_DIM>* p_low_node_A_B = (nodeA_index < nodeB_index) ? pNodeA : pNodeB; // Node with the lowest index out of A and B
02462     Node<SPACE_DIM>* p_low_node = (p_low_node_A_B->GetIndex() < nodeC_index) ? p_low_node_A_B : pNodeC; // Node with the lowest index out of A, B and C.
02463     PerformNodeMerge(pNodeA,pNodeB);
02464     PerformNodeMerge(p_low_node_A_B,pNodeC);
02465 
02466     c_vector<double, SPACE_DIM>& r_low_node_location = p_low_node->rGetModifiableLocation();
02467 
02468     r_low_node_location = nodes_midpoint;
02469 
02470     // Sort out boundary nodes
02471     p_low_node->SetAsBoundaryNode(false);
02472 
02473     // Remove the deleted nodes and re-index
02474     RemoveDeletedNodes();
02475 }
02476 
02478 // Explicit instantiation
02480 
02481 template class MutableVertexMesh<1,1>;
02482 template class MutableVertexMesh<1,2>;
02483 template class MutableVertexMesh<1,3>;
02484 template class MutableVertexMesh<2,2>;
02485 template class MutableVertexMesh<2,3>;
02486 template class MutableVertexMesh<3,3>;
02487 
02488 // Serialization for Boost >= 1.36
02489 #include "SerializationExportWrapperForCpp.hpp"
02490 EXPORT_TEMPLATE_CLASS_ALL_DIMS(MutableVertexMesh);