Chaste Release::3.1
NodesOnlyMesh.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 <map>
00037 #include "NodesOnlyMesh.hpp"
00038 
00039 template<unsigned SPACE_DIM>
00040 NodesOnlyMesh<SPACE_DIM>::NodesOnlyMesh()
00041         : MutableMesh<SPACE_DIM, SPACE_DIM>(),
00042           mpBoxCollection(NULL)
00043 {
00044 }
00045 
00046 template<unsigned SPACE_DIM>
00047 NodesOnlyMesh<SPACE_DIM>::~NodesOnlyMesh()
00048 {
00049     Clear();
00050     ClearBoxCollection();
00051 }
00052 
00053 template<unsigned SPACE_DIM>
00054 void NodesOnlyMesh<SPACE_DIM>::ConstructNodesWithoutMesh(const std::vector<Node<SPACE_DIM>*>& rNodes)
00055 {
00056     this->Clear();
00057     mpBoxCollection = NULL;
00058 
00059     for (unsigned i=0; i<rNodes.size(); i++)
00060     {
00061         assert(!rNodes[i]->IsDeleted());
00062         c_vector<double, SPACE_DIM> location = rNodes[i]->rGetLocation();
00063 
00064         Node<SPACE_DIM>* p_node_copy = new Node<SPACE_DIM>(i, location);
00065         this->mNodes.push_back(p_node_copy);
00066 
00067         mCellRadii.push_back(0.5);
00068     }
00069 }
00070 
00071 template<unsigned SPACE_DIM>
00072 void NodesOnlyMesh<SPACE_DIM>::ConstructNodesWithoutMesh(const AbstractMesh<SPACE_DIM,SPACE_DIM>& rGeneratingMesh)
00073 {
00074     ConstructNodesWithoutMesh(rGeneratingMesh.mNodes);
00075 }
00076 
00077 template<unsigned SPACE_DIM>
00078 void NodesOnlyMesh<SPACE_DIM>::Clear()
00079 {
00080     // Call Clear() on the parent class
00081     MutableMesh<SPACE_DIM,SPACE_DIM>::Clear();
00082 
00083     // Clear the cell radii
00084     mCellRadii.clear();
00085 }
00086 
00087 template<unsigned SPACE_DIM>
00088 double NodesOnlyMesh<SPACE_DIM>::GetCellRadius(unsigned index)
00089 {
00090     assert(index < mCellRadii.size());
00091     return mCellRadii[index];
00092 }
00093 
00094 template<unsigned SPACE_DIM>
00095 void NodesOnlyMesh<SPACE_DIM>::SetCellRadius(unsigned index, double radius)
00096 {
00097     assert(index < mCellRadii.size());
00098     mCellRadii[index] = radius;
00099 }
00100 
00101 template<unsigned SPACE_DIM>
00102 BoxCollection<SPACE_DIM>* NodesOnlyMesh<SPACE_DIM>::GetBoxCollection()
00103 {
00104     return mpBoxCollection;
00105 }
00106 
00107 template<unsigned SPACE_DIM>
00108 void NodesOnlyMesh<SPACE_DIM>::ClearBoxCollection()
00109 {
00110     if (mpBoxCollection != NULL)
00111     {
00112         delete mpBoxCollection;
00113     }
00114     mpBoxCollection = NULL;
00115 }
00116 
00117 template<unsigned SPACE_DIM>
00118 void NodesOnlyMesh<SPACE_DIM>::SetUpBoxCollection(double cutOffLength, c_vector<double, 2*SPACE_DIM> domainSize)
00119 {
00120     mpBoxCollection = new BoxCollection<SPACE_DIM>(cutOffLength, domainSize);
00121     mpBoxCollection->SetupLocalBoxesHalfOnly();
00122 
00123     //Put the nodes in the boxes.
00124     for (unsigned i=0; i< this->GetNumNodes(); i++)
00125     {
00126         unsigned box_index = mpBoxCollection->CalculateContainingBox(this->GetNode(i));
00127         mpBoxCollection->rGetBox(box_index).AddNode(this->GetNode(i));
00128     }
00129 }
00130 
00131 template<unsigned SPACE_DIM>
00132 void NodesOnlyMesh<SPACE_DIM>::SetMaximumInteractionDistance(double maximumInteractionDistance)
00133 {
00134     mMaximumInteractionDistance = maximumInteractionDistance;
00135 }
00136 
00137 template<unsigned SPACE_DIM>
00138 void NodesOnlyMesh<SPACE_DIM>::CalculateNodePairs(std::set<std::pair<Node<SPACE_DIM>*, Node<SPACE_DIM>*> >& rNodePairs, std::map<unsigned, std::set<unsigned> >& rNodeNeighbours)
00139 {
00140     assert(mpBoxCollection != NULL);
00141     mpBoxCollection->CalculateNodePairs(this->mNodes, rNodePairs, rNodeNeighbours);
00142 }
00143 
00144 template<unsigned SPACE_DIM>
00145 void NodesOnlyMesh<SPACE_DIM>::ReMesh(NodeMap& map)
00146 {
00147     // Store the node locations
00148     std::vector<c_vector<double, SPACE_DIM> > old_node_locations;
00149     std::vector<double> old_cell_radii;
00150     bool copy_radii = !mCellRadii.empty();
00151 
00152     unsigned new_index = 0;
00153     for (unsigned i=0; i<this->GetNumAllNodes(); i++)
00154     {
00155         if (this->mNodes[i]->IsDeleted())
00156         {
00157             map.SetDeleted(i);
00158         }
00159         else
00160         {
00161             map.SetNewIndex(i, new_index);
00162             old_node_locations.push_back(this->mNodes[i]->rGetLocation());
00163             if (copy_radii)
00164             {
00165                 old_cell_radii.push_back(mCellRadii[i]);
00166             }
00167 
00168             new_index++;
00169         }
00170     }
00171     // Remove current data
00172     this->Clear();
00173 
00174     // Replace radius data
00175     mCellRadii = old_cell_radii;
00176 
00177     // Construct the nodes
00178     for (unsigned node_index=0; node_index<old_node_locations.size(); node_index++)
00179     {
00180         Node<SPACE_DIM>* p_node = new Node<SPACE_DIM>(node_index, old_node_locations[node_index], false);
00181         this->mNodes.push_back(p_node);
00182     }
00183 }
00184 
00185 template<unsigned SPACE_DIM>
00186 unsigned NodesOnlyMesh<SPACE_DIM>::AddNode(Node<SPACE_DIM>* pNewNode)
00187 {
00188     // Call method on parent class
00189     unsigned new_node_index = MutableMesh<SPACE_DIM, SPACE_DIM>::AddNode(pNewNode);
00190 
00191     // Then update mCellRadii
00192     if (new_node_index >= mCellRadii.size())
00193     {
00194         mCellRadii.resize(new_node_index+1);
00195     }
00196     SetCellRadius(new_node_index, 0.5);
00197 
00198     return new_node_index;
00199 }
00200 
00201 template<unsigned SPACE_DIM>
00202 void NodesOnlyMesh<SPACE_DIM>::DeleteNode(unsigned index)
00203 {
00204     if (this->mNodes[index]->IsDeleted())
00205     {
00206         EXCEPTION("Trying to delete a deleted node");
00207     }
00208 
00209     this->mNodes[index]->MarkAsDeleted();
00210     this->mDeletedNodeIndices.push_back(index);
00211 
00217     mCellRadii[index] = DOUBLE_UNSET;
00218 }
00219 
00221 // Explicit instantiation
00223 
00224 template class NodesOnlyMesh<1>;
00225 template class NodesOnlyMesh<2>;
00226 template class NodesOnlyMesh<3>;
00227 
00228 // Serialization for Boost >= 1.36
00229 #include "SerializationExportWrapperForCpp.hpp"
00230 EXPORT_TEMPLATE_CLASS_SAME_DIMS(NodesOnlyMesh)