CmguiMeshWriter.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 #include "Exception.hpp"
00029 #include "CmguiMeshWriter.hpp"
00030 #include "Version.hpp"
00031 #include <boost/shared_ptr.hpp>
00032 
00034 // Implementation
00036 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00037 CmguiMeshWriter<ELEMENT_DIM,SPACE_DIM>::CmguiMeshWriter(const std::string &rDirectory,
00038                                                         const std::string &rBaseName,
00039                                                         bool cleanDirectory)
00040         : AbstractTetrahedralMeshWriter<ELEMENT_DIM,SPACE_DIM>(rDirectory, rBaseName, cleanDirectory)
00041 {
00042     this->mIndexFromZero = false;
00043     mGroupName = this->mBaseName;
00044     
00045     switch(ELEMENT_DIM)
00046     {
00047         case 1:
00048         {
00049             mElementFileHeader = CmguiElementFileHeader1D;
00050             mCoordinatesFileHeader = CmguiCoordinatesFileHeader1D;
00051             mAdditionalFieldHeader = CmguiAdditionalFieldHeader1D;
00052             break;
00053         }
00054         case 2:
00055         {
00056             mElementFileHeader = CmguiElementFileHeader2D;
00057             mCoordinatesFileHeader = CmguiCoordinatesFileHeader2D;
00058             mAdditionalFieldHeader = CmguiAdditionalFieldHeader2D;
00059             break;
00060         }
00061         case 3:
00062         {
00063             mElementFileHeader = CmguiElementFileHeader3D;
00064             mCoordinatesFileHeader = CmguiCoordinatesFileHeader3D;
00065             mAdditionalFieldHeader = CmguiAdditionalFieldHeader3D;
00066             break;
00067         }
00068         default:
00069         {
00070             NEVER_REACHED;
00071         }
00072     }    
00073     
00074 
00075     mNumNodesPerElement = ELEMENT_DIM+1;
00076     mReordering.resize(mNumNodesPerElement);
00077     for(unsigned i=0; i<mNumNodesPerElement; i++)
00078     {
00079         mReordering[i] = i;
00080     }
00081 }
00082 
00083 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00084 void CmguiMeshWriter<ELEMENT_DIM,SPACE_DIM>::WriteFiles()
00085 {
00087     // Write the exnode file
00089     std::string node_file_name = this->mBaseName + ".exnode";
00090     out_stream p_node_file = this->mpOutputFileHandler->OpenOutputFile(node_file_name);
00091 
00092     WriteNodeFileHeader(p_node_file);
00093 
00094     // Write each node's data
00095     for (unsigned item_num=0; item_num<this->GetNumNodes(); item_num++)
00096     {
00097         std::vector<double> current_item = this->GetNextNode();
00098 
00099         *p_node_file << "Node:\t" << item_num+1 << "\t";
00100         for (unsigned i=0; i<ELEMENT_DIM; i++)
00101         {
00102             *p_node_file << current_item[i] << "\t";
00103         }
00104 
00105         *p_node_file << "\n";
00106     }
00107     p_node_file->close();
00108 
00110     // Write the exlem file
00112     
00113     // If nobody defined region names we default to the same name as the file.
00114     if (mRegionNames.size() == 0)
00115     {
00116         mRegionNames.push_back(this->mBaseName);
00117     }
00118 
00119     // Array with file descriptors for each of regions    
00120     std::vector<boost::shared_ptr<std::ofstream> > p_elem_file;
00121     
00122     p_elem_file.resize(mRegionNames.size());
00123     
00124     for (unsigned region_index=0; region_index<mRegionNames.size(); region_index++)     
00125     {
00126         std::string elem_file_name = mRegionNames[region_index] + ".exelem";
00127         out_stream p_tmp_file = this->mpOutputFileHandler->OpenOutputFile(elem_file_name);
00128         p_elem_file[region_index] = p_tmp_file;
00129         
00130         // Write the elem header
00131         
00132         //write provenance info
00133         std::string comment = "! " + ChasteBuildInfo::GetProvenanceString();
00134         *p_elem_file[region_index] << comment;
00135     
00136         *p_elem_file[region_index] << "Group name: " << mGroupName << "\n";
00137         *p_elem_file[region_index] << mElementFileHeader;
00138     
00139     
00140         //now we need to figure out how many additional fields we have
00141         unsigned number_of_fields = mAdditionalFieldNames.size();
00142         std::stringstream string_of_number_of_fields;
00143         //we write the number of additional fields + 1 because the coordinates field gets written anyway
00144         string_of_number_of_fields << number_of_fields+1;
00145         //and write accordingly the total number of fields
00146         *p_elem_file[region_index] << " #Fields="<<string_of_number_of_fields.str()<<"\n";
00147     
00148         //first field (the coordinates field is fixed and alwys there)
00149         *p_elem_file[region_index] << mCoordinatesFileHeader;
00150     
00151     
00152         //now write the specification for each additional field
00153         for (unsigned i = 0; i <  number_of_fields; i++)
00154         {
00155             //unsigned to string
00156             std::stringstream i_string;
00157             i_string << i+2;
00158             *p_elem_file[region_index]<<i_string.str()<<")  "<<mAdditionalFieldNames[i]<<" ,";
00159             *p_elem_file[region_index] << mAdditionalFieldHeader;
00160         }
00161     }
00162 
00163     // Write each elements's data        
00164     for (unsigned item_num=0; item_num<this->GetNumElements(); item_num++)
00165     {
00166         ElementData elem =this->GetNextElement();
00167         std::vector<unsigned> current_element = elem.NodeIndices;
00168         
00170         assert(elem.AttributeValue < mRegionNames.size());
00171            
00172         *p_elem_file[elem.AttributeValue] << "Element:\t" << item_num+1 << " 0 0 Nodes:\t";
00173         for (unsigned i=0; i<mNumNodesPerElement; i++)
00174         {
00175             *p_elem_file[elem.AttributeValue] << current_element[mReordering[i]]+1 << "\t";
00176         }
00177 
00178         *p_elem_file[elem.AttributeValue] << "\n";
00179             
00180     }
00181     
00182     for (unsigned region_index=0; region_index<mRegionNames.size(); region_index++)     
00183     {
00184         p_elem_file[region_index]->close();
00185     }
00186 }
00187 
00188 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00189 void CmguiMeshWriter<ELEMENT_DIM,SPACE_DIM>::SetAdditionalFieldNames(std::vector<std::string>& rFieldNames)
00190 {
00191     mAdditionalFieldNames = rFieldNames;
00192 }
00193 
00194 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00195 void CmguiMeshWriter<ELEMENT_DIM,SPACE_DIM>::SetRegionNames(std::vector<std::string>& rRegionNames)
00196 {    
00197     mRegionNames = rRegionNames;
00198 }
00199 
00200 
00201 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00202 void CmguiMeshWriter<ELEMENT_DIM,SPACE_DIM>::WriteNodeFileHeader(out_stream& rpNodeFile)
00203 {
00204     //write provenance info
00205     std::string comment = "! " + ChasteBuildInfo::GetProvenanceString();
00206     *rpNodeFile << comment;
00207     
00208     // Write the node header
00209     *rpNodeFile << "Group name: " << this->mGroupName << "\n";
00210     switch (SPACE_DIM)
00211     {
00212         case 1:
00213         {
00214             *rpNodeFile << CmguiNodeFileHeader1D;
00215             break;
00216         }
00217         case 2:
00218         {
00219             *rpNodeFile << CmguiNodeFileHeader2D;
00220             break;
00221         }
00222         case 3:
00223         {
00224             *rpNodeFile << CmguiNodeFileHeader3D;
00225             break;
00226         }
00227         default:
00228         {
00229             NEVER_REACHED;
00230         }
00231     }
00232 }
00233 
00234 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00235 bool CmguiMeshWriter<ELEMENT_DIM,SPACE_DIM>::CompareCmguiFiles(std::string& rPath1, std::string& rPath2)
00236 {
00237     std::string compare_command = "diff --ignore-matching-lines=\"! \" ";
00238     compare_command += rPath1;
00239     compare_command += " ";
00240     compare_command += rPath2;
00241 
00242     //Compare the new test file with one from the repository
00243     if (system(compare_command.c_str()) == 0)
00244     {
00245         return true;
00246     }
00247     else
00248     {
00249         return false;
00250     }
00251 }
00252 
00254 // Explicit instantiation
00256 
00257 template class CmguiMeshWriter<1,1>;
00258 template class CmguiMeshWriter<1,2>;
00259 template class CmguiMeshWriter<1,3>;
00260 template class CmguiMeshWriter<2,2>;
00261 template class CmguiMeshWriter<2,3>;
00262 template class CmguiMeshWriter<3,3>;

Generated on Mon Nov 1 12:35:24 2010 for Chaste by  doxygen 1.5.5