Hdf5ToCmguiConverter.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 "Hdf5ToCmguiConverter.hpp"
00030 #include "CmguiMeshWriter.hpp"
00031 #include "UblasCustomFunctions.hpp"
00032 #include "HeartConfig.hpp"
00033 #include "PetscTools.hpp"
00034 #include "Exception.hpp"
00035 #include "ReplicatableVector.hpp"
00036 #include "DistributedVector.hpp"
00037 #include "DistributedVectorFactory.hpp"
00038 #include "Version.hpp"
00039 #include "GenericMeshReader.hpp"
00040 
00041 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00042 void Hdf5ToCmguiConverter<ELEMENT_DIM,SPACE_DIM>::Write(std::string type)
00043 {
00044     out_stream p_file = out_stream(NULL);
00045 
00046     unsigned num_nodes = this->mpReader->GetNumberOfRows();
00047     unsigned num_timesteps = this->mpReader->GetUnlimitedDimensionValues().size();
00048 
00049     DistributedVectorFactory factory(num_nodes);
00050 
00051     Vec data = factory.CreateVec();//for V
00052     Vec data_phie = factory.CreateVec();//for phi_e
00053     Vec data_second_cell = factory.CreateVec();//for the V of the second cell, used in extended bidomain problems.
00054 
00055     for (unsigned time_step=0; time_step<num_timesteps; time_step++)
00056     {
00057         // Create the file for this time step
00058         std::stringstream time_step_string;
00059 
00060         // unsigned to string
00061         time_step_string << time_step;
00062         if (PetscTools::AmMaster())
00063         {
00064             p_file = this->mpOutputFileHandler->OpenOutputFile(this->mFileBaseName + "_" + time_step_string.str() + ".exnode");
00065 
00066             // Check how many digits are to be output in the solution (0 goes to default value of digits)
00067             unsigned int num_digits = HeartConfig::Instance()->GetVisualizerOutputPrecision();
00068             if (num_digits != 0)
00069             {
00070                p_file->precision(num_digits);
00071             }
00072         }
00073 
00074         std::vector<ReplicatableVector*> all_data;
00075         unsigned num_vars = this->mpReader->GetVariableNames().size();
00076         for (unsigned var=0; var<num_vars; var++)
00077         {
00078             // Read the data for this time step
00079             this->mpReader->GetVariableOverNodes(data, this->mpReader->GetVariableNames()[var], time_step);
00080             ReplicatableVector* p_repl_data = new ReplicatableVector(data);
00081             assert(p_repl_data->GetSize()==num_nodes);
00082             all_data.push_back(p_repl_data);
00083         }
00084 
00085         if (PetscTools::AmMaster())
00086         {
00087             // Write provenance info
00088             std::string comment = "! " + ChasteBuildInfo::GetProvenanceString();
00089             *p_file << comment;
00090             // The header first
00091             *p_file << "Group name: " << this->mFileBaseName << "\n";
00092             *p_file << "#Fields=" << num_vars << "\n";
00093             for (unsigned var=0; var<num_vars; var++)
00094             {
00095                 *p_file << " " << var+1 << ") " <<this->mpReader->GetVariableNames()[var]<< " , field, rectangular cartesian, #Components=1" << "\n" << "x.  Value index=1, #Derivatives=0, #Versions=1"<<"\n";
00096                 if (var != num_vars-1)
00097                 {
00098                     *p_file << "\n";
00099                 }
00100             }
00101 
00102             // Write the data
00103             for (unsigned i=0; i<num_nodes; i++)
00104             {
00105                 // cmgui counts nodes from 1
00106                 *p_file << "Node: "<< i+1 << "\n";
00107                 for (unsigned var=0; var<num_vars; var++)
00108                 {
00109                     *p_file  << (*(all_data[var]))[i] << "\n";
00110                 }
00111             }
00112         }
00113 
00114         for (unsigned var=0; var<num_vars; var++)
00115         {
00116            delete all_data[var];
00117         }
00118     }
00119     VecDestroy(data);
00120     VecDestroy(data_phie);
00121     VecDestroy(data_second_cell);
00122 
00123     if (PetscTools::AmMaster())
00124     {
00125         p_file->close();
00126     }
00127 }
00128 
00129 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00130 Hdf5ToCmguiConverter<ELEMENT_DIM,SPACE_DIM>::Hdf5ToCmguiConverter(std::string inputDirectory,
00131                                                                   std::string fileBaseName,
00132                                                                   AbstractTetrahedralMesh<ELEMENT_DIM,SPACE_DIM>* pMesh,
00133                                                                   bool hasBath)
00134     : AbstractHdf5Converter<ELEMENT_DIM,SPACE_DIM>(inputDirectory, fileBaseName, pMesh, "cmgui_output")
00135 {
00136     // Write the node data out
00137     Write("");
00138 
00139     // Write mesh in a suitable form for cmgui
00140     std::string output_directory =  HeartConfig::Instance()->GetOutputDirectory() + "/cmgui_output";
00141 
00142     CmguiMeshWriter<ELEMENT_DIM,SPACE_DIM> cmgui_mesh_writer(output_directory, HeartConfig::Instance()->GetOutputFilenamePrefix(), false);
00143 
00144     // Used to inform the mesh of the data names
00145     std::vector<std::string> field_names = this->mpReader->GetVariableNames();
00146     cmgui_mesh_writer.SetAdditionalFieldNames(field_names);
00147     if (hasBath)
00148     {
00149         std::vector<std::string> names;
00150         names.push_back("tissue");
00151         names.push_back("bath");
00152         cmgui_mesh_writer.SetRegionNames(names);
00153     }
00154 
00155     // Normally the in-memory mesh is converted:
00156     if (HeartConfig::Instance()->GetOutputUsingOriginalNodeOrdering() == false)
00157     {
00158         cmgui_mesh_writer.WriteFilesUsingMesh(*(this->mpMesh), false);
00159     }
00160     else
00161     {
00162         // In this case we expect the mesh to have been read in from file
00164         // Note that the next line will throw if the mesh has not been read from file
00165         std::string original_file=this->mpMesh->GetMeshFileBaseName();
00166         std::auto_ptr<AbstractMeshReader<ELEMENT_DIM, SPACE_DIM> > p_original_mesh_reader
00167             = GenericMeshReader<ELEMENT_DIM, SPACE_DIM>(original_file);
00168         cmgui_mesh_writer.WriteFilesUsingMeshReader(*p_original_mesh_reader);
00169     }
00170 
00171     WriteCmguiScript();
00172     PetscTools::Barrier("Hdf5ToCmguiConverter");
00173 }
00174 
00175 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00176 void Hdf5ToCmguiConverter<ELEMENT_DIM,SPACE_DIM>::WriteCmguiScript()
00177 {
00178     unsigned num_timesteps = this->mpReader->GetUnlimitedDimensionValues().size();
00179     assert(this->mpReader->GetVariableNames().size() > 0); // seg fault guard
00180     std::string variable_name = this->mpReader->GetVariableNames()[0];
00181 
00182     if (PetscTools::AmMaster())
00183     {
00184         out_stream p_script_file = this->mpOutputFileHandler->OpenOutputFile("script.com");
00185 
00186         // Write provenance info, note the # instead of ! because this is - essentially - a PERL script that Cmgui interprets
00187         std::string comment = "# " + ChasteBuildInfo::GetProvenanceString();
00188         *p_script_file << comment;
00189 
00190         *p_script_file << "# Read the mesh \n"
00191                        << "gfx read node "<<HeartConfig::Instance()->GetOutputFilenamePrefix()<<".exnode \n"
00192                        << "gfx read elem "<<HeartConfig::Instance()->GetOutputFilenamePrefix()<<".exelem generate_faces_and_lines \n" // note the mesh file name is taken from HeartConfig...
00193                        << "# Create a window \n"
00194                        << "gfx cre win 1 \n"
00195                        << "# Modify the scene (obtained by gfx list g_element XXXX commands) to visualize first var on lines and nodes \n"
00196                        << "gfx modify g_element "<< HeartConfig::Instance()->GetOutputFilenamePrefix()<<" general clear circle_discretization 6 default_coordinate coordinates element_discretization \"4*4*4\" native_discretization none; \n"
00197                        << "gfx modify g_element "<< HeartConfig::Instance()->GetOutputFilenamePrefix()<<" lines select_on material default data "<<variable_name<<" spectrum default selected_material default_selected; \n"
00198                        << "gfx modify g_element "<< HeartConfig::Instance()->GetOutputFilenamePrefix()<<" node_points glyph point general size \"1*1*1\" centre 0,0,0 font default select_on material default data "<<variable_name<<" spectrum default selected_material default_selected; \n"
00199                        << "# Load the data \n"
00200                        << "for ($i=0; $i<" << num_timesteps << "; $i++) { \n"
00201                        << "    gfx read node " << this->mFileBaseName << "_$i.exnode time $i\n" // ...while the data file from mFileBaseName...
00202                        << "}\n";
00203         p_script_file->close();
00204     }
00205 }
00206 
00208 // Explicit instantiation
00210 
00211 template class Hdf5ToCmguiConverter<1,1>;
00212 template class Hdf5ToCmguiConverter<1,2>;
00213 template class Hdf5ToCmguiConverter<2,2>;
00214 template class Hdf5ToCmguiConverter<1,3>;
00215 template class Hdf5ToCmguiConverter<2,3>;
00216 template class Hdf5ToCmguiConverter<3,3>;
Generated on Thu Dec 22 13:00:06 2011 for Chaste by  doxygen 1.6.3