Chaste Release::3.1
|
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)