AbstractMeshReader.cpp

00001 /*
00002 
00003 Copyright (c) 2005-2015, 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 #include <cassert>
00036 #include "AbstractMeshReader.hpp"
00037 #include "Exception.hpp"
00038 
00040 // Implementation
00042 
00043 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00044 unsigned AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumElementAttributes() const
00045 {
00046     // By default returns 0.  If a concrete class does read attributes
00047     // it needs to overload this method.
00048     return 0;
00049 }
00050 
00051 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00052 unsigned AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumEdges() const
00053 {
00054     return GetNumFaces();
00055 }
00056 
00057 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00058 unsigned AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumFaceAttributes() const
00059 {
00060     // By default returns 0.  If a concrete class does read attributes
00061     // it needs to overload this method.
00062     return 0;
00063 }
00064 
00065 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00066 std::vector<double> AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNodeAttributes()
00067 {
00068     // By default returns an empty vector.  If a concrete class does read node attributes
00069     // it needs to overload this method.
00070     std::vector<double> empty;
00071     return empty;
00072 }
00073 
00074 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00075 ElementData AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextEdgeData()
00076 {
00077     return GetNextFaceData();
00078 }
00079 
00080 
00081 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00082 std::vector<double> AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNode(unsigned index)
00083 {
00084     EXCEPTION("Random access is only implemented in mesh readers for binary mesh files.");
00085 }
00086 
00087 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00088 ElementData AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetElementData(unsigned index)
00089 {
00090     EXCEPTION("Random access is only implemented in mesh readers for binary mesh files.");
00091 }
00092 
00093 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00094 ElementData AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetFaceData(unsigned index)
00095 {
00096     EXCEPTION("Random access is only implemented in mesh readers for binary mesh files.");
00097 }
00098 
00099 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00100 ElementData AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetEdgeData(unsigned index)
00101 {
00102     return GetFaceData(index);
00103 }
00104 
00105 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00106 std::vector<unsigned> AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetContainingElementIndices(unsigned index)
00107 {
00108     EXCEPTION("Ncl files are only implemented in mesh readers for binary mesh files.");
00109 }
00110 
00111 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00112 std::string AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetMeshFileBaseName()
00113 {
00114     return "";
00115 }
00116 
00117 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00118 unsigned AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetOrderOfElements()
00119 {
00120     return 1u;
00121 }
00122 
00123 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00124 unsigned AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetOrderOfBoundaryElements()
00125 {
00126     return 1u;
00127 }
00128 
00129 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00130 bool AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetReadContainingElementOfBoundaryElement()
00131 {
00132     return false;
00133 }
00134 
00135 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00136 bool AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::IsFileFormatBinary()
00137 {
00138     return false;
00139 }
00140 
00141 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00142 bool AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::HasNclFile()
00143 {
00144     return false;
00145 }
00146 
00147 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00148 bool AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::HasNodePermutation()
00149 {
00150     return false;
00151 }
00152 
00153 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00154 const std::vector<unsigned>& AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::rGetNodePermutation()
00155 {
00156     EXCEPTION("Node permutations aren't supported by this reader");
00157 }
00158 
00159 // Cable elements aren't supported in most formats
00160 
00161 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00162 unsigned AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumCableElements() const
00163 {
00164     return 0u;
00165 }
00166 
00167 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00168 unsigned AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumCableElementAttributes() const
00169 {
00170     return 0u;
00171 }
00172 
00173 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00174 ElementData AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextCableElementData()
00175 {
00176     EXCEPTION("Cable elements are not supported by this mesh format.");
00177 }
00178 
00179 
00180 // Iterator-related methods
00181 
00182 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00183 typename AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::ElementIterator
00184     AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorBegin()
00185 {
00186     return ElementIterator(0u, this);
00187 }
00188 
00189 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00190 typename AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::ElementIterator
00191     AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorBegin(const std::set<unsigned>& rIndices)
00192 {
00193     return ElementIterator(rIndices, this);
00194 }
00195 
00196 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00197 typename AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::ElementIterator
00198     AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorEnd()
00199 {
00200     return ElementIterator(GetNumElements(), this);
00201 }
00202 
00203 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00204 AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::ElementIterator::ElementIterator(const std::set<unsigned>& rIndices,
00205                                                                              AbstractMeshReader* pReader)
00206     : mpIndices(&rIndices),
00207       mpReader(pReader)
00208 {
00209     if (mpIndices->empty())
00210     {
00211         mIndex = mpReader->GetNumElements();
00212     }
00213     else
00214     {
00215         mIndicesIterator = mpIndices->begin();
00216         mIndex = 0;
00217         CacheData(*mIndicesIterator, true);
00218     }
00219 }
00220 
00221 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00222 void AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::ElementIterator::increment()
00223 {
00224     unsigned next_index;
00225     if (mpIndices)
00226     {
00227         // Iterating over a subset
00228         ++mIndicesIterator;
00229         if (mIndicesIterator != mpIndices->end())
00230         {
00231             next_index = *mIndicesIterator;
00232         }
00233         else
00234         {
00235             // The subset is complete so skip to the end of the items so that we can be
00236             // compared to GetElementIteratorEnd
00237             next_index = mpReader->GetNumElements();
00238         }
00239     }
00240     else
00241     {
00242         // Iterating over all items
00243         next_index = mIndex + 1;
00244     }
00245     CacheData(next_index);
00246 }
00247 
00248 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00249 void AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::ElementIterator::CacheData(unsigned index, bool firstRead)
00250 {
00251     assert(mpReader);
00252     assert(mIndex < index || mIndex == 0u || index == mpReader->GetNumElements());
00253     if (index < mpReader->GetNumElements())
00254     {
00255         if (mpReader->IsFileFormatBinary())
00256         {
00257             mLastDataRead = mpReader->GetElementData(index);
00258         }
00259         else
00260         {
00261             if (firstRead)
00262             {
00263                 assert(mIndex == 0u);
00264                 //ASCII at construction - do an initial read to make sure the line mIndex is read
00265                 mLastDataRead = mpReader->GetNextElementData();
00266             }
00267             //ASCII generic case, where we might need to skip some unread items
00268             while (mIndex < index)
00269             {
00270                 mLastDataRead = mpReader->GetNextElementData();
00271                 mIndex++;
00272             }
00273         }
00274     }
00275     mIndex = index;
00276 }
00277 
00278 
00279 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00280 typename AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::NodeIterator
00281     AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNodeIteratorBegin()
00282 {
00283     return NodeIterator(0u, this);
00284 }
00285 
00286 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00287 typename AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::NodeIterator
00288     AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNodeIteratorBegin(const std::set<unsigned>& rIndices)
00289 {
00290     return NodeIterator(rIndices, this);
00291 }
00292 
00293 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00294 typename AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::NodeIterator
00295     AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNodeIteratorEnd()
00296 {
00297     return NodeIterator(GetNumNodes(), this);
00298 }
00299 
00300 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00301 AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::NodeIterator::NodeIterator(const std::set<unsigned>& rIndices,
00302                                                                              AbstractMeshReader* pReader)
00303     : mpIndices(&rIndices),
00304       mpReader(pReader)
00305 {
00306     if (mpIndices->empty())
00307     {
00308         mIndex = mpReader->GetNumNodes();
00309     }
00310     else
00311     {
00312         mIndicesIterator = mpIndices->begin();
00313         mIndex = 0;
00314         CacheData(*mIndicesIterator, true);
00315     }
00316 }
00317 
00318 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00319 void AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::NodeIterator::increment()
00320 {
00321     unsigned next_index;
00322     if (mpIndices)
00323     {
00324         // Iterating over a subset
00325         ++mIndicesIterator;
00326         if (mIndicesIterator != mpIndices->end())
00327         {
00328             next_index = *mIndicesIterator;
00329         }
00330         else
00331         {
00332             // The subset is complete so skip to the end of the items so that we can be
00333             // compared to GetNodeIteratorEnd
00334             next_index = mpReader->GetNumNodes();
00335         }
00336     }
00337     else
00338     {
00339         // Iterating over all items
00340         next_index = mIndex + 1;
00341     }
00342     CacheData(next_index);
00343 }
00344 
00345 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00346 void AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::NodeIterator::CacheData(unsigned index, bool firstRead)
00347 {
00348     assert(mpReader);
00349     assert(mIndex < index || mIndex == 0u || index == mpReader->GetNumNodes());
00350     if (index < mpReader->GetNumNodes())
00351     {
00352         if (mpReader->IsFileFormatBinary())
00353         {
00354             mLastDataRead = mpReader->GetNode(index);
00355         }
00356         else
00357         {
00358             if (firstRead)
00359             {
00360                 assert(mIndex == 0u);
00361                 //ASCII at construction - do an initial read to make sure the line mIndex is read
00362                 mLastDataRead = mpReader->GetNextNode();
00363             }
00364             //ASCII generic case, where we might need to skip some unread items
00365             while (mIndex < index)
00366             {
00367                 mLastDataRead = mpReader->GetNextNode();
00368                 mIndex++;
00369             }
00370         }
00371     }
00372     mIndex = index;
00373 }
00374 
00375 
00377 // Explicit instantiation
00379 
00380 template class AbstractMeshReader<0,1>;
00381 template class AbstractMeshReader<1,1>;
00382 template class AbstractMeshReader<1,2>;
00383 template class AbstractMeshReader<1,3>;
00384 template class AbstractMeshReader<2,2>;
00385 template class AbstractMeshReader<2,3>;
00386 template class AbstractMeshReader<3,3>;

Generated by  doxygen 1.6.2