CmguiMeshWriter.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "Exception.hpp"
00029 #include "CmguiMeshWriter.hpp"
00030 #include "Version.hpp"
00031 #include <boost/shared_ptr.hpp>
00032
00033 #include "AbstractTetrahedralMesh.hpp"
00034 #include "DistributedTetrahedralMesh.hpp"
00035
00037
00039
00040 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00041 CmguiMeshWriter<ELEMENT_DIM,SPACE_DIM>::CmguiMeshWriter(const std::string &rDirectory,
00042 const std::string &rBaseName,
00043 bool cleanDirectory)
00044 : AbstractTetrahedralMeshWriter<ELEMENT_DIM,SPACE_DIM>(rDirectory, rBaseName, cleanDirectory)
00045 {
00046 this->mIndexFromZero = false;
00047 mGroupName = this->mBaseName;
00048
00049 switch (ELEMENT_DIM)
00050 {
00051 case 1:
00052 {
00053 mElementFileHeader = CmguiElementFileHeader1D;
00054 mCoordinatesFileHeader = CmguiCoordinatesFileHeader1D;
00055 mAdditionalFieldHeader = CmguiAdditionalFieldHeader1D;
00056 break;
00057 }
00058 case 2:
00059 {
00060 mElementFileHeader = CmguiElementFileHeader2D;
00061 mCoordinatesFileHeader = CmguiCoordinatesFileHeader2D;
00062 mAdditionalFieldHeader = CmguiAdditionalFieldHeader2D;
00063 break;
00064 }
00065 case 3:
00066 {
00067 mElementFileHeader = CmguiElementFileHeader3D;
00068 mCoordinatesFileHeader = CmguiCoordinatesFileHeader3D;
00069 mAdditionalFieldHeader = CmguiAdditionalFieldHeader3D;
00070 break;
00071 }
00072 default:
00073 {
00074 NEVER_REACHED;
00075 }
00076 }
00077
00078
00079 mNumNodesPerElement = ELEMENT_DIM+1;
00080 mReordering.resize(mNumNodesPerElement);
00081 for (unsigned i=0; i<mNumNodesPerElement; i++)
00082 {
00083 mReordering[i] = i;
00084 }
00085 }
00086
00087 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00088 void CmguiMeshWriter<ELEMENT_DIM,SPACE_DIM>::WriteFiles()
00089 {
00091
00093 out_stream p_node_file = OpenNodeFile();
00094 WriteNodeFileHeader(p_node_file);
00095
00096
00097 for (unsigned item_num=0; item_num<this->GetNumNodes(); item_num++)
00098 {
00099 std::vector<double> current_item = this->GetNextNode();
00100
00101 *p_node_file << "Node:\t" << item_num+1 << "\t";
00102 for (unsigned i=0; i<ELEMENT_DIM; i++)
00103 {
00104 *p_node_file << current_item[i] << "\t";
00105 }
00106
00107 *p_node_file << "\n";
00108 }
00109 p_node_file->close();
00110
00112
00114
00115 std::vector<boost::shared_ptr<std::ofstream> > elem_files = OpenElementFiles();
00116 WriteElementsFileHeader(elem_files);
00117
00118
00119 for (unsigned item_num=0; item_num<this->GetNumElements(); item_num++)
00120 {
00121 ElementData elem =this->GetNextElement();
00122 std::vector<unsigned> current_element = elem.NodeIndices;
00123
00125 assert(elem.AttributeValue < mRegionNames.size());
00126
00127 *elem_files[elem.AttributeValue] << "Element:\t" << item_num+1 << " 0 0 Nodes:\t";
00128 for (unsigned i=0; i<mNumNodesPerElement; i++)
00129 {
00130 *elem_files[elem.AttributeValue] << current_element[mReordering[i]]+1 << "\t";
00131 }
00132
00133 *elem_files[elem.AttributeValue] << "\n";
00134
00135 }
00136
00137 for (unsigned region_index=0; region_index<mRegionNames.size(); region_index++)
00138 {
00139 elem_files[region_index]->close();
00140 }
00141 }
00142
00143 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00144 void CmguiMeshWriter<ELEMENT_DIM,SPACE_DIM>::SetAdditionalFieldNames(std::vector<std::string>& rFieldNames)
00145 {
00146 mAdditionalFieldNames = rFieldNames;
00147 }
00148
00149 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00150 void CmguiMeshWriter<ELEMENT_DIM,SPACE_DIM>::SetRegionNames(std::vector<std::string>& rRegionNames)
00151 {
00152 mRegionNames = rRegionNames;
00153 }
00154
00155 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00156 out_stream CmguiMeshWriter<ELEMENT_DIM, SPACE_DIM>::OpenNodeFile(bool append)
00157 {
00158 std::string node_file_name = this->mBaseName + ".exnode";
00159 return this->mpOutputFileHandler->OpenOutputFile(node_file_name, GetOpenMode(append));
00160 }
00161
00162 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00163 std::vector<boost::shared_ptr<std::ofstream> > CmguiMeshWriter<ELEMENT_DIM, SPACE_DIM>::OpenElementFiles(bool append)
00164 {
00165
00166 std::vector<boost::shared_ptr<std::ofstream> > elem_files;
00167
00168 if (mRegionNames.size() == 0)
00169 {
00170 mRegionNames.push_back(this->mBaseName);
00171 }
00172 elem_files.resize(mRegionNames.size());
00173
00174 std::string directory = this->mpOutputFileHandler->GetOutputDirectoryFullPath();
00175 for (unsigned region_index=0; region_index<mRegionNames.size(); region_index++)
00176 {
00177 std::string elem_file_name = mRegionNames[region_index] + ".exelem";
00178
00179 boost::shared_ptr<std::ofstream> p_output_file(new std::ofstream((directory+elem_file_name).c_str(), GetOpenMode(append)));
00180 #define COVERAGE_IGNORE
00181 if (!p_output_file->is_open())
00182 {
00183 EXCEPTION("Could not open file \"" + elem_file_name + "\" in " + directory);
00184 }
00185 #undef COVERAGE_IGNORE
00186
00187
00188
00189
00190
00191
00192
00193 elem_files[region_index] = p_output_file;
00194 }
00195 return elem_files;
00196 }
00197
00198 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00199 void CmguiMeshWriter<ELEMENT_DIM,SPACE_DIM>::WriteNodeFileHeader(out_stream& rpNodeFile)
00200 {
00201
00202 std::string comment = "! " + ChasteBuildInfo::GetProvenanceString();
00203 *rpNodeFile << comment;
00204
00205
00206 *rpNodeFile << "Group name: " << this->mGroupName << "\n";
00207 switch (SPACE_DIM)
00208 {
00209 case 1:
00210 {
00211 *rpNodeFile << CmguiNodeFileHeader1D;
00212 break;
00213 }
00214 case 2:
00215 {
00216 *rpNodeFile << CmguiNodeFileHeader2D;
00217 break;
00218 }
00219 case 3:
00220 {
00221 *rpNodeFile << CmguiNodeFileHeader3D;
00222 break;
00223 }
00224 default:
00225 {
00226 NEVER_REACHED;
00227 }
00228 }
00229 }
00230
00231 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00232 void CmguiMeshWriter<ELEMENT_DIM,SPACE_DIM>::WriteElementsFileHeader(std::vector<boost::shared_ptr<std::ofstream> >& rElemFiles)
00233 {
00234
00235 for (unsigned region_index=0; region_index<mRegionNames.size(); region_index++)
00236 {
00237
00238
00239
00240 std::string comment = "! " + ChasteBuildInfo::GetProvenanceString();
00241 *rElemFiles[region_index] << comment;
00242
00243 *rElemFiles[region_index] << "Group name: " << mGroupName << "\n";
00244 *rElemFiles[region_index] << mElementFileHeader;
00245
00246
00247 unsigned number_of_fields = mAdditionalFieldNames.size();
00248 std::stringstream string_of_number_of_fields;
00249
00250
00251 string_of_number_of_fields << number_of_fields+1;
00252
00253
00254 *rElemFiles[region_index] << " #Fields="<<string_of_number_of_fields.str()<<"\n";
00255
00256
00257 *rElemFiles[region_index] << mCoordinatesFileHeader;
00258
00259
00260 for (unsigned i = 0; i < number_of_fields; i++)
00261 {
00262
00263 std::stringstream i_string;
00264 i_string << i+2;
00265 *rElemFiles[region_index]<<i_string.str()<<") "<<mAdditionalFieldNames[i]<<" ,";
00266 *rElemFiles[region_index] << mAdditionalFieldHeader;
00267 }
00268 }
00269 }
00270
00271 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00272 void CmguiMeshWriter<ELEMENT_DIM, SPACE_DIM>::CreateFilesWithHeaders()
00273 {
00274
00275
00276
00277 out_stream p_node_file = OpenNodeFile();
00278 WriteNodeFileHeader(p_node_file);
00279 p_node_file->close();
00280
00281
00282
00283
00284
00285 std::vector<boost::shared_ptr<std::ofstream> > elem_files = OpenElementFiles();
00286 WriteElementsFileHeader(elem_files);
00287 for (unsigned i = 0; i < elem_files.size(); i++)
00288 {
00289 elem_files[i]->close();
00290 }
00291 }
00292
00293 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00294 void CmguiMeshWriter<ELEMENT_DIM, SPACE_DIM>::AppendLocalDataToFiles()
00295 {
00296
00297 out_stream p_node_file = OpenNodeFile(true);
00298
00299 typedef typename AbstractMesh<ELEMENT_DIM,SPACE_DIM>::NodeIterator NodeIterType;
00300
00301 for (NodeIterType iter = this->mpDistributedMesh->GetNodeIteratorBegin();
00302 iter != this->mpDistributedMesh->GetNodeIteratorEnd();
00303 ++iter)
00304 {
00305 const c_vector<double, SPACE_DIM>& r_current_item = iter->rGetLocation();
00306 *p_node_file << "Node:\t" << iter->GetIndex()+1 << "\t";
00307 for (unsigned i=0; i<ELEMENT_DIM; i++)
00308 {
00309 *p_node_file << r_current_item[i] << "\t";
00310 }
00311
00312 *p_node_file << "\n";
00313 }
00314 p_node_file->close();
00315
00316
00317
00318 std::vector<boost::shared_ptr<std::ofstream> > elem_files = OpenElementFiles(true);
00319 typedef typename AbstractTetrahedralMesh<ELEMENT_DIM,SPACE_DIM>::ElementIterator ElemIterType;
00320
00321 for (ElemIterType iter = this->mpDistributedMesh->GetElementIteratorBegin();
00322 iter != this->mpDistributedMesh->GetElementIteratorEnd();
00323 ++iter)
00324 {
00325 if ( this->mpDistributedMesh->CalculateDesignatedOwnershipOfElement(iter->GetIndex()))
00326 {
00327 assert(iter->GetRegion() < mRegionNames.size());
00328
00329 *elem_files[iter->GetRegion()] << "Element:\t" << iter->GetIndex()+1 << " 0 0 Nodes:\t";
00330 for (unsigned i=0; i<this->mNodesPerElement; i++)
00331 {
00332 *elem_files[iter->GetRegion()] << iter->GetNodeGlobalIndex(i)+1 << "\t";
00333 }
00334
00335 *elem_files[iter->GetRegion()] << "\n";
00336 }
00337 }
00338
00339 for (unsigned region_index=0; region_index<mRegionNames.size(); region_index++)
00340 {
00341 elem_files[region_index]->close();
00342 }
00343
00344 }
00345
00346 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00347 void CmguiMeshWriter<ELEMENT_DIM, SPACE_DIM>::WriteFilesFooter()
00348 {
00349
00350 }
00351
00352 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00353 std::ios_base::openmode CmguiMeshWriter<ELEMENT_DIM, SPACE_DIM>::GetOpenMode(bool append)
00354 {
00355 std::ios_base::openmode mode = std::ios::out;
00356 if (append)
00357 {
00358 mode |= std::ios::app;
00359 }
00360 else
00361 {
00362 mode |= std::ios::trunc;
00363 }
00364 return mode;
00365 }
00366
00367 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00368 bool CmguiMeshWriter<ELEMENT_DIM,SPACE_DIM>::CompareCmguiFiles(std::string& rPath1, std::string& rPath2)
00369 {
00370 std::string compare_command = "diff --ignore-matching-lines=\"! \" ";
00371 compare_command += rPath1;
00372 compare_command += " ";
00373 compare_command += rPath2;
00374
00375
00376 if (system(compare_command.c_str()) == 0)
00377 {
00378 return true;
00379 }
00380 else
00381 {
00382 return false;
00383 }
00384 }
00385
00387
00389
00390 template class CmguiMeshWriter<1,1>;
00391 template class CmguiMeshWriter<1,2>;
00392 template class CmguiMeshWriter<1,3>;
00393 template class CmguiMeshWriter<2,2>;
00394 template class CmguiMeshWriter<2,3>;
00395 template class CmguiMeshWriter<3,3>;