AbstractMesh.cpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2010
00004 
00005 University of Oxford means the Chancellor, Masters and Scholars of the
00006 University of Oxford, having an administrative office at Wellington
00007 Square, Oxford OX1 2JD, UK.
00008 
00009 This file is part of Chaste.
00010 
00011 Chaste is free software: you can redistribute it and/or modify it
00012 under the terms of the GNU Lesser General Public License as published
00013 by the Free Software Foundation, either version 2.1 of the License, or
00014 (at your option) any later version.
00015 
00016 Chaste is distributed in the hope that it will be useful, but WITHOUT
00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00019 License for more details. The offer of Chaste under the terms of the
00020 License is subject to the License being interpreted in accordance with
00021 English Law and subject to any action against the University of Oxford
00022 being under the jurisdiction of the English Courts.
00023 
00024 You should have received a copy of the GNU Lesser General Public License
00025 along with Chaste. If not, see <http://www.gnu.org/licenses/>.
00026 
00027 */
00028 
00029 #include "AbstractMesh.hpp"
00030 
00032 // Implementation
00034 
00035 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00036 AbstractMesh<ELEMENT_DIM, SPACE_DIM>::AbstractMesh()
00037     : mpDistributedVectorFactory(NULL),
00038       mMeshFileBaseName(""),
00039       mMeshChangesDuringSimulation(false)
00040 {
00041 }
00042 
00043 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00044 AbstractMesh<ELEMENT_DIM, SPACE_DIM>::~AbstractMesh()
00045 {
00046     // Iterate over nodes and free the memory
00047     for (unsigned i=0; i<mNodes.size(); i++)
00048     {
00049         delete mNodes[i];
00050     }
00051     if (mpDistributedVectorFactory)
00052     {
00053         delete mpDistributedVectorFactory;
00054     }
00055 }
00056 
00057 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00058 unsigned AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetNumNodes() const
00059 {
00060     return mNodes.size();
00061 }
00062 
00063 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00064 unsigned AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetNumBoundaryNodes() const
00065 {
00066     return mBoundaryNodes.size();
00067 }
00068 
00069 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00070 unsigned AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetNumAllNodes() const
00071 {
00072     return mNodes.size();
00073 }
00074 
00075 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00076 Node<SPACE_DIM>* AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetNode(unsigned index) const
00077 {
00078     unsigned local_index = SolveNodeMapping(index);
00079     return mNodes[local_index];
00080 }
00081 
00082 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00083 Node<SPACE_DIM>* AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetNodeFromPrePermutationIndex(unsigned index) const
00084 {
00085     if (mNodesPermutation.empty())
00086     {
00087         return GetNode(index);
00088     }
00089     else
00090     {
00091         return GetNode(mNodesPermutation[index]);
00092     }
00093 }
00094 
00095 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00096 void AbstractMesh<ELEMENT_DIM, SPACE_DIM>::ReadNodesPerProcessorFile(const std::string& rNodesPerProcessorFile)
00097 {
00098     NEVER_REACHED;
00099 }
00100 
00101 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00102 DistributedVectorFactory* AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetDistributedVectorFactory()
00103 {
00104     if (mpDistributedVectorFactory == NULL)
00105     {
00106         mpDistributedVectorFactory = new DistributedVectorFactory(GetNumNodes());
00107     }
00108     return mpDistributedVectorFactory;
00109 }
00110 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00111 void AbstractMesh<ELEMENT_DIM, SPACE_DIM>::SetDistributedVectorFactory(DistributedVectorFactory *pFactory)
00112 {
00113     if (mpDistributedVectorFactory)
00114     {
00115         EXCEPTION("Cannot change the mesh's distributed vector factory once it has been set.");
00116     }
00117     if (pFactory->GetNumProcs() != PetscTools::GetNumProcs())
00118     {
00119         EXCEPTION("The distributed vector factory provided to the mesh is for the wrong number of processes.");
00120     }
00121     mpDistributedVectorFactory = pFactory;
00122 }
00123 
00124 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00125 void AbstractMesh<ELEMENT_DIM, SPACE_DIM>::PermuteNodes()
00126 {
00127     NEVER_REACHED;
00128 }
00129 
00130 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00131 typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::BoundaryNodeIterator AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetBoundaryNodeIteratorBegin() const
00132 {
00133     return mBoundaryNodes.begin();
00134 }
00135 
00136 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00137 typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::BoundaryNodeIterator AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetBoundaryNodeIteratorEnd() const
00138 {
00139     return mBoundaryNodes.end();
00140 }
00141 
00142 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00143 std::string AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetMeshFileBaseName() const
00144 {
00145     if (mMeshFileBaseName == "")
00146     {
00147         EXCEPTION("This mesh was not constructed from a file.");
00148     }
00149 
00150     return mMeshFileBaseName;
00151 }
00152 
00153 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00154 const std::vector<unsigned>& AbstractMesh<ELEMENT_DIM, SPACE_DIM>::rGetNodePermutation() const
00155 {
00156     return mNodesPermutation;
00157 }
00158 
00159 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00160 c_vector<double, SPACE_DIM> AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetVectorFromAtoB(
00161     const c_vector<double, SPACE_DIM>& rLocationA, const c_vector<double, SPACE_DIM>& rLocationB)
00162 {
00163     c_vector<double, SPACE_DIM> vector = rLocationB - rLocationA;
00164     return vector;
00165 }
00166 
00167 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00168 double AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetDistanceBetweenNodes(unsigned indexA, unsigned indexB)
00169 {
00170     c_vector<double, SPACE_DIM> vector = GetVectorFromAtoB(mNodes[indexA]->rGetLocation(),
00171                                                            mNodes[indexB]->rGetLocation());
00172     return norm_2(vector);
00173 }
00174 
00175 
00176 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00177 double AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetWidth(const unsigned& rDimension) const
00178 {
00179     assert(rDimension < SPACE_DIM);
00180     c_vector<double,2> extremes = GetWidthExtremes(rDimension);
00181     return extremes[1] - extremes[0];
00182 }
00183 
00184 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00185 c_vector<double,2> AbstractMesh<ELEMENT_DIM, SPACE_DIM>::GetWidthExtremes(const unsigned& rDimension) const
00186 {
00187     assert(rDimension < SPACE_DIM);
00188 
00189     double max = -1e200;
00190     double min = 1e200;
00191 
00192     assert(mNodes.size() > 0u);
00193 
00195     for (unsigned i=0; i<mNodes.size(); i++)
00196     {
00197         if (!mNodes[i]->IsDeleted())
00198         {
00199             double this_node_value = mNodes[i]->rGetLocation()[rDimension];
00200             if (this_node_value>max)
00201             {
00202                 max = this_node_value;
00203             }
00204             if (this_node_value < min)
00205             {
00206                 min = this_node_value;
00207             }
00208         }
00209     }
00210     c_vector<double,2> extremes;
00211     extremes[0] = min;
00212     extremes[1] = max;
00213     return extremes;
00214 }
00215 
00216 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00217 void AbstractMesh<ELEMENT_DIM, SPACE_DIM>::Scale(const double xScale, const double yScale, const double zScale)
00218 {
00219     unsigned num_nodes = mNodes.size();
00220 
00221     for (unsigned i=0; i<num_nodes; i++)
00222     {
00223         c_vector<double, SPACE_DIM>& r_location = mNodes[i]->rGetModifiableLocation();
00224         if (SPACE_DIM>=3)
00225         {
00226             r_location[2] *= zScale;
00227         }
00228         if (SPACE_DIM>=2)
00229         {
00230             r_location[1] *= yScale;
00231         }
00232         r_location[0] *= xScale;
00233     }
00234 
00235     RefreshMesh();
00236 }
00237 
00238 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00239 void AbstractMesh<ELEMENT_DIM, SPACE_DIM>::RefreshMesh()
00240 {
00241 }
00242 
00243 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00244 bool AbstractMesh<ELEMENT_DIM, SPACE_DIM>::IsMeshChanging() const
00245 {
00246     return mMeshChangesDuringSimulation;
00247 }
00248 
00249 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00250 void AbstractMesh<ELEMENT_DIM, SPACE_DIM>::SetMeshHasChangedSinceLoading()
00251 {
00252     // We just forget what the original file was, which has the desired effect
00253     mMeshFileBaseName = "";
00254 }
00255 
00257 // Explicit instantiation
00259 
00260 template class AbstractMesh<1,1>;
00261 template class AbstractMesh<1,2>;
00262 template class AbstractMesh<1,3>;
00263 template class AbstractMesh<2,2>;
00264 template class AbstractMesh<2,3>;
00265 template class AbstractMesh<3,3>;

Generated by  doxygen 1.6.2