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 #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 bool AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::IsFileFormatBinary() 00119 { 00120 return false; 00121 } 00122 00123 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00124 bool AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::HasNclFile() 00125 { 00126 return false; 00127 } 00128 00129 00130 // Cable elements aren't supported in most formats 00131 00132 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00133 unsigned AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumCableElements() const 00134 { 00135 return 0u; 00136 } 00137 00138 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00139 unsigned AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumCableElementAttributes() const 00140 { 00141 return 0u; 00142 } 00143 00144 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00145 ElementData AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextCableElementData() 00146 { 00147 EXCEPTION("Cable elements are not supported by this mesh format."); 00148 } 00149 00150 00151 // Iterator-related methods 00152 00153 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00154 typename AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::ElementIterator 00155 AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorBegin() 00156 { 00157 return ElementIterator(0u, this); 00158 } 00159 00160 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00161 typename AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::ElementIterator 00162 AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorBegin(const std::set<unsigned>& rIndices) 00163 { 00164 return ElementIterator(rIndices, this); 00165 } 00166 00167 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00168 typename AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::ElementIterator 00169 AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetElementIteratorEnd() 00170 { 00171 return ElementIterator(GetNumElements(), this); 00172 } 00173 00174 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00175 AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::ElementIterator::ElementIterator(const std::set<unsigned>& rIndices, 00176 AbstractMeshReader* pReader) 00177 : mpIndices(&rIndices), 00178 mpReader(pReader) 00179 { 00180 if (mpIndices->empty()) 00181 { 00182 mIndex = mpReader->GetNumElements(); 00183 } 00184 else 00185 { 00186 mIndicesIterator = mpIndices->begin(); 00187 mIndex = 0; 00188 CacheData(*mIndicesIterator, true); 00189 } 00190 } 00191 00192 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00193 void AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::ElementIterator::increment() 00194 { 00195 unsigned next_index; 00196 if (mpIndices) 00197 { 00198 // Iterating over a subset 00199 ++mIndicesIterator; 00200 if (mIndicesIterator != mpIndices->end()) 00201 { 00202 next_index = *mIndicesIterator; 00203 } 00204 else 00205 { 00206 // The subset is complete so skip to the end of the items so that we can be 00207 // compared to GetElementIteratorEnd 00208 next_index = mpReader->GetNumElements(); 00209 } 00210 } 00211 else 00212 { 00213 // Iterating over all items 00214 next_index = mIndex + 1; 00215 } 00216 CacheData(next_index); 00217 } 00218 00219 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00220 void AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::ElementIterator::CacheData(unsigned index, bool firstRead) 00221 { 00222 assert(mpReader); 00223 assert(mIndex < index || mIndex == 0u || index == mpReader->GetNumElements()); 00224 if (index < mpReader->GetNumElements()) 00225 { 00226 if (mpReader->IsFileFormatBinary()) 00227 { 00228 mLastDataRead = mpReader->GetElementData(index); 00229 } 00230 else 00231 { 00232 if (firstRead) 00233 { 00234 assert(mIndex == 0u); 00235 //ASCII at construction - do an initial read to make sure the line mIndex is read 00236 mLastDataRead = mpReader->GetNextElementData(); 00237 } 00238 //ASCII generic case, where we might need to skip some unread items 00239 while (mIndex < index) 00240 { 00241 mLastDataRead = mpReader->GetNextElementData(); 00242 mIndex++; 00243 } 00244 } 00245 } 00246 mIndex = index; 00247 } 00248 00249 00250 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00251 typename AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::NodeIterator 00252 AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNodeIteratorBegin() 00253 { 00254 return NodeIterator(0u, this); 00255 } 00256 00257 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00258 typename AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::NodeIterator 00259 AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNodeIteratorBegin(const std::set<unsigned>& rIndices) 00260 { 00261 return NodeIterator(rIndices, this); 00262 } 00263 00264 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00265 typename AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::NodeIterator 00266 AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNodeIteratorEnd() 00267 { 00268 return NodeIterator(GetNumNodes(), this); 00269 } 00270 00271 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00272 AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::NodeIterator::NodeIterator(const std::set<unsigned>& rIndices, 00273 AbstractMeshReader* pReader) 00274 : mpIndices(&rIndices), 00275 mpReader(pReader) 00276 { 00277 if (mpIndices->empty()) 00278 { 00279 mIndex = mpReader->GetNumNodes(); 00280 } 00281 else 00282 { 00283 mIndicesIterator = mpIndices->begin(); 00284 mIndex = 0; 00285 CacheData(*mIndicesIterator, true); 00286 } 00287 } 00288 00289 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00290 void AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::NodeIterator::increment() 00291 { 00292 unsigned next_index; 00293 if (mpIndices) 00294 { 00295 // Iterating over a subset 00296 ++mIndicesIterator; 00297 if (mIndicesIterator != mpIndices->end()) 00298 { 00299 next_index = *mIndicesIterator; 00300 } 00301 else 00302 { 00303 // The subset is complete so skip to the end of the items so that we can be 00304 // compared to GetNodeIteratorEnd 00305 next_index = mpReader->GetNumNodes(); 00306 } 00307 } 00308 else 00309 { 00310 // Iterating over all items 00311 next_index = mIndex + 1; 00312 } 00313 CacheData(next_index); 00314 } 00315 00316 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00317 void AbstractMeshReader<ELEMENT_DIM, SPACE_DIM>::NodeIterator::CacheData(unsigned index, bool firstRead) 00318 { 00319 assert(mpReader); 00320 assert(mIndex < index || mIndex == 0u || index == mpReader->GetNumNodes()); 00321 if (index < mpReader->GetNumNodes()) 00322 { 00323 if (mpReader->IsFileFormatBinary()) 00324 { 00325 mLastDataRead = mpReader->GetNode(index); 00326 } 00327 else 00328 { 00329 if (firstRead) 00330 { 00331 assert(mIndex == 0u); 00332 //ASCII at construction - do an initial read to make sure the line mIndex is read 00333 mLastDataRead = mpReader->GetNextNode(); 00334 } 00335 //ASCII generic case, where we might need to skip some unread items 00336 while (mIndex < index) 00337 { 00338 mLastDataRead = mpReader->GetNextNode(); 00339 mIndex++; 00340 } 00341 } 00342 } 00343 mIndex = index; 00344 } 00345 00346 00348 // Explicit instantiation 00350 00351 template class AbstractMeshReader<0,1>; 00352 template class AbstractMeshReader<1,1>; 00353 template class AbstractMeshReader<1,2>; 00354 template class AbstractMeshReader<1,3>; 00355 template class AbstractMeshReader<2,2>; 00356 template class AbstractMeshReader<2,3>; 00357 template class AbstractMeshReader<3,3>;