TrianglesMeshWriter.cpp

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