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 "TrianglesMeshWriter.hpp" 00037 #include "Version.hpp" 00038 00039 #include <cassert> 00040 00042 // Implementation 00044 00045 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00046 TrianglesMeshWriter<ELEMENT_DIM, SPACE_DIM>::TrianglesMeshWriter( 00047 const std::string &rDirectory, 00048 const std::string &rBaseName, 00049 const bool clearOutputDir) 00050 : AbstractTetrahedralMeshWriter<ELEMENT_DIM, SPACE_DIM>(rDirectory, rBaseName, clearOutputDir) 00051 { 00052 } 00053 00054 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00055 TrianglesMeshWriter<ELEMENT_DIM, SPACE_DIM>::~TrianglesMeshWriter() 00056 { 00057 } 00058 00059 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00060 void TrianglesMeshWriter<ELEMENT_DIM, SPACE_DIM>::SetWriteFilesAsBinary() 00061 { 00062 this->mFilesAreBinary=true; 00063 } 00064 00065 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00066 void TrianglesMeshWriter<ELEMENT_DIM, SPACE_DIM>::WriteFiles() 00067 { 00068 std::string comment = "#\n# " + ChasteBuildInfo::GetProvenanceString(); 00069 00070 // Write node file 00071 std::string node_file_name = this->mBaseName + ".node"; 00072 out_stream p_node_file = this->mpOutputFileHandler->OpenOutputFile(node_file_name); 00073 00074 // Write the node header 00075 unsigned num_attr = 0; 00077 unsigned max_bdy_marker = 0; 00078 unsigned num_nodes = this->GetNumNodes(); 00079 00080 *p_node_file << num_nodes << "\t"; 00081 *p_node_file << SPACE_DIM << "\t"; 00082 *p_node_file << num_attr << "\t"; 00083 *p_node_file << max_bdy_marker; 00084 if (this->mFilesAreBinary) 00085 { 00086 *p_node_file << "\tBIN\n"; 00087 } 00088 else 00089 { 00090 *p_node_file << "\n"; 00091 } 00092 00093 *p_node_file << std::setprecision(20); 00094 00095 // Write each node's data 00096 unsigned default_marker = UINT_MAX; 00097 for (unsigned item_num=0; item_num<num_nodes; item_num++) 00098 { 00099 WriteItem(p_node_file, item_num, this->GetNextNode(), default_marker); 00100 } 00101 *p_node_file << comment << "\n"; 00102 p_node_file->close(); 00103 00104 if (ELEMENT_DIM < SPACE_DIM) 00105 { 00106 WriteElementsAsFaces(); 00107 WriteFacesAsEdges(); 00108 return; 00109 } 00110 00111 // Write element file 00112 std::string element_file_name = this->mBaseName + ".ele"; 00113 out_stream p_element_file = this->mpOutputFileHandler->OpenOutputFile(element_file_name); 00114 00115 // Write the element header 00116 unsigned num_elements = this->GetNumElements(); 00118 num_attr = 1u; // We have a single region code 00119 00120 // The condition below allows the writer to cope with a NodesOnlyMesh 00121 if (num_elements == 0) 00122 { 00123 *p_element_file << 0 << "\t"; 00124 *p_element_file << 0 << "\t"; 00125 *p_element_file << 0; 00126 if (this->mFilesAreBinary) 00127 { 00128 *p_element_file << "\tBIN\n"; 00129 } 00130 else 00131 { 00132 *p_element_file << "\n"; 00133 } 00134 p_element_file->close(); 00135 } 00136 else 00137 { 00138 ElementData element_data = this->GetNextElement(); 00139 00140 unsigned nodes_per_element = element_data.NodeIndices.size(); 00141 if (nodes_per_element != ELEMENT_DIM+1) 00142 { 00143 // Check that this is a quadratic mesh 00144 assert(ELEMENT_DIM == SPACE_DIM); 00145 assert(nodes_per_element == (ELEMENT_DIM+1)*(ELEMENT_DIM+2)/2); 00146 } 00147 00148 *p_element_file << num_elements << "\t"; 00149 *p_element_file << nodes_per_element << "\t"; 00150 *p_element_file << num_attr; 00151 if (this->mFilesAreBinary) 00152 { 00153 *p_element_file << "\tBIN\n"; 00154 } 00155 else 00156 { 00157 *p_element_file << "\n"; 00158 } 00159 00160 // Write each element's data 00161 for (unsigned item_num=0; item_num<num_elements; item_num++) 00162 { 00163 /* 00164 * If item_num==0 we will already have got the element above (in order to 00165 * get the number of nodes per element). 00166 */ 00167 if (item_num > 0) 00168 { 00169 element_data = this->GetNextElement(); 00170 } 00171 //Note: Cable element has a double attribute for radius but regular element have always had an unsigned region marker 00172 WriteItem(p_element_file, item_num, element_data.NodeIndices, (unsigned) element_data.AttributeValue); 00173 } 00174 *p_element_file << comment << "\n"; 00175 p_element_file->close(); 00176 } 00177 00178 // Write boundary face file 00179 std::string face_file_name = this->mBaseName; 00180 00181 if (ELEMENT_DIM == 1) 00182 { 00183 // In 1-D there is no boundary file: it's trivial to calculate 00184 return; 00185 } 00186 else if (ELEMENT_DIM == 2) 00187 { 00188 face_file_name = face_file_name + ".edge"; 00189 } 00190 else 00191 { 00192 face_file_name = face_file_name + ".face"; 00193 } 00194 out_stream p_face_file = this->mpOutputFileHandler->OpenOutputFile(face_file_name); 00195 00196 // Write the boundary face header 00197 if (num_elements != 0) 00198 { 00199 unsigned num_faces = this->GetNumBoundaryFaces(); 00200 00201 *p_face_file << num_faces << "\t"; 00203 *p_face_file << max_bdy_marker; 00204 if (this->mFilesAreBinary) 00205 { 00206 *p_face_file << "\tBIN\n"; 00207 } 00208 else 00209 { 00210 *p_face_file << "\n"; 00211 } 00212 00213 // Write each face's data 00214 default_marker = UINT_MAX; 00215 for (unsigned item_num=0; item_num<num_faces; item_num++) 00216 { 00217 ElementData face_data = this->GetNextBoundaryElement(); 00218 WriteItem(p_face_file, item_num, face_data.NodeIndices, default_marker); 00219 } 00220 *p_face_file << comment << "\n"; 00221 p_face_file->close(); 00222 00223 if (this->GetNumCableElements() > 0) 00224 { 00225 // Write cable element file 00226 std::string cable_element_file_name = this->mBaseName + ".cable"; 00227 out_stream p_cable_element_file = this->mpOutputFileHandler->OpenOutputFile(cable_element_file_name); 00228 00229 // Write the cable element header 00230 unsigned num_cable_elements = this->GetNumCableElements(); 00232 num_attr = 1u; // We have a single region code - which is actually a radius 00233 00234 *p_cable_element_file << num_cable_elements << "\t"; 00235 *p_cable_element_file << 2 << "\t"; 00236 *p_cable_element_file << num_attr; 00237 if (this->mFilesAreBinary) 00238 { 00239 *p_cable_element_file << "\tBIN\n"; 00240 } 00241 else 00242 { 00243 *p_cable_element_file << "\n"; 00244 } 00245 00246 // Write each element's data 00247 for (unsigned item_num=0; item_num<num_cable_elements; item_num++) 00248 { 00249 ElementData cable_element_data = this->GetNextCableElement(); 00250 //Cable element has a double attribute for radius 00251 WriteItem(p_cable_element_file, item_num, cable_element_data.NodeIndices, cable_element_data.AttributeValue); 00252 } 00253 *p_cable_element_file << comment; 00254 p_cable_element_file->close(); 00255 } 00256 } 00257 } 00258 00259 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00260 void TrianglesMeshWriter<ELEMENT_DIM, SPACE_DIM>::WriteElementsAsFaces() 00261 { 00262 std::string comment = "#\n# " + ChasteBuildInfo::GetProvenanceString(); 00263 00264 std::string element_file_name = this->mBaseName; 00265 if (ELEMENT_DIM == 1 && (SPACE_DIM == 2 || SPACE_DIM == 3)) 00266 { 00267 element_file_name = element_file_name + ".edge"; 00268 } 00269 else if (ELEMENT_DIM == 2 && SPACE_DIM == 3) 00270 { 00271 element_file_name = element_file_name + ".face"; 00272 } 00273 00274 out_stream p_element_file = this->mpOutputFileHandler->OpenOutputFile(element_file_name); 00275 00276 // Write the element header 00277 unsigned num_elements = this->GetNumElements(); 00278 assert(SPACE_DIM != ELEMENT_DIM); 00279 unsigned num_attr = 0; 00280 00281 *p_element_file << num_elements << "\t"; 00282 //*p_element_file << nodes_per_element << "\t"; 00283 *p_element_file << num_attr; 00284 if (this->mFilesAreBinary) 00285 { 00286 *p_element_file << "\tBIN\n"; 00287 } 00288 else 00289 { 00290 *p_element_file << "\n"; 00291 } 00292 00293 // Write each element's data 00294 for (unsigned item_num=0; item_num<num_elements; item_num++) 00295 { 00296 WriteItem(p_element_file, item_num, this->GetNextElement().NodeIndices); 00297 } 00298 *p_element_file << comment << "\n"; 00299 p_element_file->close(); 00300 00301 } 00302 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00303 void TrianglesMeshWriter<ELEMENT_DIM, SPACE_DIM>::WriteFacesAsEdges() 00304 { 00305 std::string comment = "#\n# " + ChasteBuildInfo::GetProvenanceString(); 00306 00307 if (ELEMENT_DIM == 1 && (SPACE_DIM == 2 || SPACE_DIM == 3)) 00308 { 00309 return; 00310 } 00311 00312 assert(SPACE_DIM == 3 && ELEMENT_DIM == 2); 00313 00314 std::string face_file_name = this->mBaseName; 00315 face_file_name = face_file_name + ".edge"; 00316 00317 out_stream p_face_file = this->mpOutputFileHandler->OpenOutputFile(face_file_name); 00318 00319 // Write the boundary face header 00320 unsigned num_faces = this->GetNumBoundaryFaces(); 00321 00322 unsigned max_bdy_marker = 0; 00323 unsigned default_marker = UINT_MAX; 00324 00325 *p_face_file << num_faces << "\t"; 00326 *p_face_file << max_bdy_marker; 00327 if (this->mFilesAreBinary) 00328 { 00329 *p_face_file << "\tBIN\n"; 00330 } 00331 else 00332 { 00333 *p_face_file << "\n"; 00334 } 00335 00336 // Write each face's data 00337 for (unsigned item_num=0; item_num<num_faces; item_num++) 00338 { 00339 ElementData face_data = this->GetNextBoundaryElement(); 00340 WriteItem(p_face_file, item_num, face_data.NodeIndices, default_marker); 00341 } 00342 *p_face_file << comment << "\n"; 00343 p_face_file->close(); 00344 } 00345 00346 00347 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00348 template<class T_DATA> 00349 void TrianglesMeshWriter<ELEMENT_DIM, SPACE_DIM>::WriteItem(out_stream &pFile, unsigned itemNumber, 00350 const std::vector<T_DATA> &dataPacket) 00351 { 00352 //Writing with no attribute 00353 //Instantiates the attribute variety with the attribute type set to unsigned 00354 WriteItem(pFile, itemNumber, dataPacket, UINT_MAX); 00355 } 00356 00357 00358 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00359 template<class T_DATA, class T_ATTR> 00360 void TrianglesMeshWriter<ELEMENT_DIM, SPACE_DIM>::WriteItem(out_stream &pFile, unsigned itemNumber, 00361 const std::vector<T_DATA> &dataPacket, T_ATTR attribute) 00362 { 00363 if (this->mFilesAreBinary) 00364 { 00365 // No item numbers 00366 // Write raw data out of std::vector into the file 00367 pFile->write((char*)&dataPacket[0], dataPacket.size()*sizeof(T_DATA)); 00368 00369 // Write raw attribute 00370 if (attribute != (std::numeric_limits<T_ATTR>::max)()) //or attribute != UINT_MAX 00371 { 00372 pFile->write((char*) &attribute, sizeof(attribute)); 00373 } 00374 } 00375 else 00376 { 00377 *pFile << itemNumber; 00378 for (unsigned i=0; i<dataPacket.size(); i++) 00379 { 00380 *pFile << "\t" << dataPacket[i]; 00381 } 00382 if (attribute != (std::numeric_limits<T_ATTR>::max)()) //or attribute != UINT_MAX 00383 { 00384 *pFile << "\t" << attribute; 00385 } 00386 *pFile << "\n"; 00387 } 00388 } 00389 00391 // Explicit instantiation 00393 00394 template class TrianglesMeshWriter<1,1>; 00395 template class TrianglesMeshWriter<1,2>; 00396 template class TrianglesMeshWriter<1,3>; 00397 template class TrianglesMeshWriter<2,2>; 00398 template class TrianglesMeshWriter<2,3>; 00399 template class TrianglesMeshWriter<3,3>; 00400 00405 template void TrianglesMeshWriter<1, 1>::WriteItem(out_stream &, unsigned, const std::vector<unsigned> &, double ); 00406 template void TrianglesMeshWriter<1, 1>::WriteItem(out_stream &, unsigned, const std::vector<double> &, double ); 00407 template void TrianglesMeshWriter<1, 2>::WriteItem(out_stream &, unsigned, const std::vector<unsigned> &, double ); 00408 template void TrianglesMeshWriter<1, 2>::WriteItem(out_stream &, unsigned, const std::vector<double> &, double ); 00409 template void TrianglesMeshWriter<1, 3>::WriteItem(out_stream &, unsigned, const std::vector<unsigned> &, double ); 00410 template void TrianglesMeshWriter<1, 3>::WriteItem(out_stream &, unsigned, const std::vector<double> &, double ); 00411 template void TrianglesMeshWriter<2, 2>::WriteItem(out_stream &, unsigned, const std::vector<unsigned> &, double ); 00412 template void TrianglesMeshWriter<2, 2>::WriteItem(out_stream &, unsigned, const std::vector<double> &, double ); 00413 template void TrianglesMeshWriter<2, 3>::WriteItem(out_stream &, unsigned, const std::vector<unsigned> &, double ); 00414 template void TrianglesMeshWriter<2, 3>::WriteItem(out_stream &, unsigned, const std::vector<double> &, double ); 00415 template void TrianglesMeshWriter<3, 3>::WriteItem(out_stream &, unsigned, const std::vector<unsigned> &, double ); 00416 template void TrianglesMeshWriter<3, 3>::WriteItem(out_stream &, unsigned, const std::vector<double> &, double );