$extrastylesheet
ensight_io.C
Go to the documentation of this file.
00001 // The libMesh Finite Element Library.
00002 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
00003 
00004 // This library is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public
00006 // License as published by the Free Software Foundation; either
00007 // version 2.1 of the License, or (at your option) any later version.
00008 
00009 // This library is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // Lesser General Public License for more details.
00013 
00014 // You should have received a copy of the GNU Lesser General Public
00015 // License along with this library; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 
00018 
00019 
00020 #include <sstream>
00021 #include <fstream>
00022 #include <string>
00023 #include <cstring>
00024 #include <stdio.h>
00025 #include <iomanip>
00026 
00027 #include "libmesh/dof_map.h"
00028 #include "libmesh/ensight_io.h"
00029 #include "libmesh/equation_systems.h"
00030 #include "libmesh/fe_interface.h"
00031 #include "libmesh/libmesh.h"
00032 #include "libmesh/system.h"
00033 
00034 
00035 namespace libMesh
00036 {
00037 
00038 
00039 EnsightIO::EnsightIO (const std::string &filename, const EquationSystems &eq) :
00040   MeshOutput<MeshBase> (eq.get_mesh()),
00041   _equation_systems(eq)
00042 {
00043 
00044   if (_equation_systems.n_processors() == 1)
00045     _ensight_file_name = filename;
00046   else
00047     {
00048       std::stringstream tmp_file;
00049       tmp_file << filename << "_rank" << _equation_systems.processor_id();
00050       _ensight_file_name = tmp_file.str();
00051     }
00052 }
00053 
00054 
00055 
00056 EnsightIO::~EnsightIO ()
00057 {}
00058 
00059 
00060 
00061 void EnsightIO::add_vector (const std::string &system_name, const std::string &vec_description,
00062                             const std::string &u, const std::string &v)
00063 {
00064   libmesh_assert (_equation_systems.has_system(system_name));
00065   libmesh_assert (_equation_systems.get_system(system_name).has_variable(u));
00066   libmesh_assert (_equation_systems.get_system(system_name).has_variable(v));
00067 
00068   Vectors vec;
00069   vec.description = vec_description;
00070   vec.components.push_back(u);
00071   vec.components.push_back(v);
00072 
00073   _systems_vars_map[system_name].EnsightVectors.push_back(vec);
00074 }
00075 
00076 
00077 
00078 void EnsightIO::add_vector (const std::string &system_name, const std::string &vec_name,
00079                             const std::string &u, const std::string &v, const std::string &w)
00080 {
00081   libmesh_assert(_equation_systems.has_system(system_name));
00082   libmesh_assert(_equation_systems.get_system(system_name).has_variable(u));
00083   libmesh_assert(_equation_systems.get_system(system_name).has_variable(v));
00084   libmesh_assert(_equation_systems.get_system(system_name).has_variable(w));
00085 
00086   Vectors vec;
00087   vec.description = vec_name;
00088   vec.components.push_back(u);
00089   vec.components.push_back(v);
00090   vec.components.push_back(w);
00091   _systems_vars_map[system_name].EnsightVectors.push_back(vec);
00092 }
00093 
00094 
00095 
00096 void EnsightIO::add_scalar(const std::string &system_name, const std::string &scl_description,
00097                            const std::string &s)
00098 {
00099   libmesh_assert(_equation_systems.has_system(system_name));
00100   libmesh_assert(_equation_systems.get_system(system_name).has_variable(s));
00101 
00102   Scalars scl;
00103   scl.description = scl_description;
00104   scl.scalar_name = s;
00105 
00106   _systems_vars_map[system_name].EnsightScalars.push_back(scl);
00107 }
00108 
00109 
00110 
00111 // This method must be implemented as it is pure virtual in
00112 // the MeshOutput base class.
00113 void EnsightIO::write (const std::string &name)
00114 {
00115   // We may need to gather a ParallelMesh to output it, making that
00116   // const qualifier in our constructor a dirty lie
00117   MeshSerializer serialize(const_cast<MeshBase&>(this->mesh()), !_is_parallel_format);
00118 
00119   _ensight_file_name = name;
00120   this->write();
00121 }
00122 
00123 
00124 
00125 void EnsightIO::write (const double time)
00126 {
00127   this->write_ascii(time);
00128   this->write_case();
00129 }
00130 
00131 
00132 
00133 void EnsightIO::write_ascii (const double time)
00134 {
00135   _time_steps.push_back(time);
00136 
00137   this->write_geometry_ascii();
00138   this->write_solution_ascii();
00139 }
00140 
00141 
00142 
00143 void EnsightIO::write_geometry_ascii()
00144 {
00145   std::ostringstream file;
00146   file << _ensight_file_name << ".geo";
00147 
00148   file << std::setw(3)
00149        << std::setprecision(0)
00150        << std::setfill('0')
00151        << std::right
00152        << _time_steps.size()-1;
00153 
00154   FILE* fout = fopen(file.str().c_str(),"w");
00155 
00156   char buffer[80];
00157 
00158   fprintf(fout,"EnSight Gold Geometry File Format\n");
00159   fprintf(fout,"Generated by \n");
00160   fprintf(fout,"node id off\n");
00161   fprintf(fout,"element id given\n");
00162   fprintf(fout,"part\n");
00163   fprintf(fout,"%10d\n",1);
00164   fprintf(fout,"uns-elements\n");
00165   fprintf(fout,"coordinates\n");
00166 
00167   // mapping between nodal index and your coordinates
00168   std::map<int, Point>                     mesh_nodes_map;
00169   typedef std::map <int, Point>::iterator  mesh_nodes_iterator;
00170   typedef std::pair<int, Point>            mesh_node_value;
00171 
00172   // Mapping between global and local indices
00173   std::map <int, int>       ensight_node_index;
00174 
00175   // Grouping elements of the same type
00176   std::map<ElemType, std::vector<const Elem*> >                    ensight_parts_map;
00177   typedef std::map<ElemType, std::vector<const Elem*> >::iterator  ensight_parts_iterator;
00178   typedef std::pair<ElemType, std::vector<const Elem*> >           ensight_parts_value;
00179 
00180   const MeshBase& the_mesh = MeshOutput<MeshBase>::mesh();
00181 
00182   MeshBase::const_element_iterator       el     = the_mesh.active_local_elements_begin();
00183   const MeshBase::const_element_iterator end_el = the_mesh.active_local_elements_end();
00184 
00185   for ( ; el != end_el ; ++el)
00186     {
00187       const Elem* elem = *el;
00188       ensight_parts_map[elem->type()].push_back(elem);
00189 
00190       for (unsigned int i = 0; i < elem->n_nodes(); i++)
00191         mesh_nodes_map[elem->node(i)] = elem->point(i);
00192     }
00193 
00194   // Write number of local points
00195   fprintf(fout,"%10d\n",static_cast<int>(mesh_nodes_map.size()));
00196 
00197   mesh_nodes_iterator           no_it = mesh_nodes_map.begin();
00198   const mesh_nodes_iterator no_end_it = mesh_nodes_map.end();
00199 
00200   // write x
00201   for(int i = 1; no_it != no_end_it; ++no_it, i++)
00202     {
00203       const mesh_node_value pn = *no_it;
00204       fprintf(fout,"%12.5e\n",static_cast<double>(pn.second(0)));
00205       ensight_node_index[pn.first] = i;
00206     }
00207 
00208   // write y
00209   no_it = mesh_nodes_map.begin();
00210   for(; no_it != no_end_it; ++no_it)
00211     {
00212       const mesh_node_value pn = *no_it;
00213       fprintf(fout,"%12.5e\n",static_cast<double>(pn.second(1)));
00214     }
00215 
00216   // write z
00217   no_it = mesh_nodes_map.begin();
00218   for(; no_it != no_end_it; ++no_it)
00219     {
00220       const mesh_node_value pn = *no_it;
00221       fprintf(fout,"%12.5e\n",static_cast<double>(pn.second(2)));
00222     }
00223 
00224   ensight_parts_iterator            parts_it  =  ensight_parts_map.begin();
00225   const ensight_parts_iterator  end_parts_it  =  ensight_parts_map.end();
00226 
00227   // Write parts
00228   for (; parts_it != end_parts_it; ++parts_it)
00229     {
00230       ensight_parts_value kvp = *parts_it;
00231 
00232       // Write element type
00233       elem_type_to_string(kvp.first,buffer);
00234       fprintf(fout,"\n%s\n", buffer);
00235 
00236       std::vector<const Elem*> elem_ref  = kvp.second;
00237 
00238       // Write number of element
00239       fprintf(fout,"%10d\n",static_cast<int>(elem_ref.size()));
00240 
00241       // Write element id
00242       for (unsigned int i = 0; i < elem_ref.size(); i++)
00243         fprintf(fout,"%10lu\n",static_cast<unsigned long>(elem_ref[i]->id()));
00244 
00245       // Write connectivity
00246       for (unsigned int i = 0; i < elem_ref.size(); i++)
00247         {
00248           for (unsigned int j = 0; j < elem_ref[i]->n_nodes(); j++) {
00249             // tests!
00250             if(kvp.first == QUAD9 && i==4)
00251               continue;
00252             // tests!
00253             if(kvp.first == HEX27 && (i==4    || i ==10 || i == 12 ||
00254                                       i == 13 || i ==14 || i == 16 || i == 22))
00255               continue;
00256 
00257             fprintf(fout,"%10d",ensight_node_index[elem_ref[i]->node(j)]);
00258           }
00259           fprintf(fout,"\n");
00260         }
00261     }
00262   fclose(fout);
00263 }
00264 
00265 
00266 
00267 
00268 
00269 void EnsightIO::write_case()
00270 {
00271   std::stringstream case_file, geo_file;
00272   case_file << _ensight_file_name << ".case";
00273 
00274   FILE* fout = fopen(case_file.str().c_str(),"w");
00275   fprintf(fout,"FORMAT\n");
00276   fprintf(fout,"type:  ensight gold\n\n");
00277   fprintf(fout,"GEOMETRY\n");
00278 
00279   geo_file << _ensight_file_name << ".geo";
00280 
00281 
00282   fprintf(fout,"model:            1     %s***\n",geo_file.str().c_str());
00283 
00284   SystemsVarsMapIterator       sys      = _systems_vars_map.begin();
00285   const SystemsVarsMapIterator sys_end  = _systems_vars_map.end();
00286 
00287   // Write Variable per node section
00288   if ( sys != sys_end )
00289     fprintf(fout,"\n\nVARIABLE\n");
00290 
00291   for (; sys != sys_end; ++sys)
00292     {
00293       SystemsVarsValue value = *sys;
00294 
00295       for (unsigned int i=0; i < value.second.EnsightScalars.size(); i++)
00296         {
00297           std::stringstream scl_file;
00298           Scalars scalar = value.second.EnsightScalars[i];
00299           scl_file << _ensight_file_name
00300                    << "_" << scalar.scalar_name
00301                    << ".scl";
00302 
00303           fprintf(fout,"scalar per node:   1  %s %s***\n",scalar.description.c_str(), scl_file.str().c_str());
00304         }
00305 
00306       for (unsigned int i=0; i < value.second.EnsightVectors.size(); i++)
00307         {
00308           std::stringstream vec_file;
00309           Vectors vec = value.second.EnsightVectors[i];
00310           vec_file<<_ensight_file_name<<"_"<<vec.description<<".vec";
00311 
00312           fprintf(fout,"vector per node:      1    %s %s***\n",vec.description.c_str(), vec_file.str().c_str());
00313         }
00314 
00315       // Write time step section
00316       if( _time_steps.size() != 0)
00317         {
00318           fprintf(fout,"\n\nTIME\n");
00319           fprintf(fout,"time set:             1\n");
00320           fprintf(fout,"number of steps:   %10d\n", static_cast<int>(_time_steps.size()));
00321           fprintf(fout,"filename start number:   %10d\n", 0);
00322           fprintf(fout,"filename increment:  %10d\n", 1);
00323           fprintf(fout,"time values:\n");
00324           for (unsigned int i = 0; i < _time_steps.size(); i++)
00325             fprintf(fout,"%12.5e\n", _time_steps[i]);
00326         }
00327     }
00328   fclose(fout);
00329 }
00330 
00331 
00332 // Write scalar and vector solution
00333 void EnsightIO::write_solution_ascii()
00334 {
00335 
00336   SystemsVarsMapIterator       sys     = _systems_vars_map.begin();
00337   const SystemsVarsMapIterator sys_end = _systems_vars_map.end();
00338 
00339   for (; sys != sys_end; ++sys)
00340     {
00341       SystemsVarsValue value = *sys;
00342 
00343       for (unsigned int i = 0; i < value.second.EnsightScalars.size(); i++)
00344         this->write_scalar_ascii(value.first,
00345                                  value.second.EnsightScalars[i].scalar_name);
00346 
00347       for (unsigned int i = 0; i < value.second.EnsightVectors.size(); i++)
00348         this->write_vector_ascii(value.first,
00349                                  value.second.EnsightVectors[i].components,
00350                                  value.second.EnsightVectors[i].description);
00351     }
00352 }
00353 
00354 
00355 void EnsightIO::write_scalar_ascii(const std::string &sys, const std::string &var_name)
00356 {
00357   std::ostringstream scl_file;
00358   scl_file << _ensight_file_name << "_" << var_name << ".scl";
00359 
00360   scl_file << std::setw(3)
00361            << std::setprecision(0)
00362            << std::setfill('0')
00363            << std::right
00364            << _time_steps.size()-1;
00365 
00366   FILE * fout = fopen(scl_file.str().c_str(),"w");
00367 
00368   fprintf(fout,"Per node scalar value\n");
00369   fprintf(fout,"part\n");
00370   fprintf(fout,"%10d\n",1);
00371   fprintf(fout,"coordinates\n");
00372 
00373   const MeshBase& the_mesh = MeshOutput<MeshBase>::mesh();
00374 
00375   const unsigned int dim = the_mesh.mesh_dimension();
00376 
00377   const System &system = _equation_systems.get_system(sys);
00378 
00379   const DofMap& dof_map = system.get_dof_map();
00380 
00381 
00382   int var = system.variable_number(var_name);
00383 
00384 
00385   std::vector<dof_id_type> dof_indices;
00386   std::vector<dof_id_type> dof_indices_scl;
00387 
00388   // Now we will loop over all the elements in the mesh.
00389 
00390   MeshBase::const_element_iterator       el     = the_mesh.active_local_elements_begin();
00391   const MeshBase::const_element_iterator end_el = the_mesh.active_local_elements_end();
00392 
00393   typedef std::map<int,Real> map_local_soln;
00394   typedef map_local_soln::iterator local_soln_iterator;
00395 
00396   map_local_soln local_soln;
00397 
00398   std::vector<Number>       elem_soln;
00399   std::vector<Number>       nodal_soln;
00400 
00401   for ( ; el != end_el ; ++el){
00402 
00403     const Elem* elem = *el;
00404 
00405     const FEType& fe_type    = system.variable_type(var);
00406 
00407     dof_map.dof_indices (elem, dof_indices);
00408     dof_map.dof_indices (elem, dof_indices_scl, var);
00409 
00410     elem_soln.resize(dof_indices_scl.size());
00411 
00412     for (unsigned int i = 0; i < dof_indices_scl.size(); i++)
00413       elem_soln[i] = system.current_solution(dof_indices_scl[i]);
00414 
00415     FEInterface::nodal_soln (dim,fe_type, elem, elem_soln, nodal_soln);
00416 
00417     libmesh_assert_equal_to (nodal_soln.size(), elem->n_nodes());
00418 
00419 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
00420     libMesh::err << "Complex-valued Ensight output not yet supported" << std::endl;
00421     libmesh_not_implemented();
00422 #endif
00423 
00424     for (unsigned int n=0; n<elem->n_nodes(); n++)
00425       local_soln[elem->node(n)] = libmesh_real(nodal_soln[n]);
00426 
00427   }
00428 
00429   local_soln_iterator sol = local_soln.begin();
00430   const local_soln_iterator sol_end = local_soln.end();
00431   for(; sol != sol_end; ++sol)
00432     fprintf(fout,"%12.5e\n",static_cast<double>((*sol).second));
00433 
00434   fclose(fout);
00435 
00436 }
00437 
00438 
00439 void EnsightIO::write_vector_ascii(const std::string &sys, const std::vector<std::string> &vec, const std::string &var_name)
00440 {
00441   std::ostringstream vec_file;
00442   vec_file<<_ensight_file_name<<"_"<<var_name<<".vec";
00443 
00444   vec_file << std::setw(3)
00445            << std::setprecision(0)
00446            << std::setfill('0')
00447            << std::right
00448            << _time_steps.size()-1;
00449 
00450   FILE * fout = fopen(vec_file.str().c_str(),"w");
00451   fprintf(fout,"Per vector per value\n");
00452   fprintf(fout,"part\n");
00453   fprintf(fout,"%10d\n",1);
00454   fprintf(fout,"coordinates\n");
00455 
00456   // Get a constant reference to the mesh object.
00457   const MeshBase& the_mesh = MeshOutput<MeshBase>::mesh();
00458 
00459   // The dimension that we are running
00460   const unsigned int dim = the_mesh.mesh_dimension();
00461 
00462   const System &system = _equation_systems.get_system(sys);
00463 
00464   const DofMap& dof_map = system.get_dof_map();
00465 
00466   const unsigned int u_var = system.variable_number(vec[0]);
00467   const unsigned int v_var = system.variable_number(vec[1]);
00468   const unsigned int w_var = (dim==3) ? system.variable_number(vec[2]) : 0;
00469 
00470   std::vector<dof_id_type> dof_indices;
00471   std::vector<dof_id_type> dof_indices_u;
00472   std::vector<dof_id_type> dof_indices_v;
00473   std::vector<dof_id_type> dof_indices_w;
00474 
00475   // Now we will loop over all the elements in the mesh.
00476   MeshBase::const_element_iterator       el     = the_mesh.active_local_elements_begin();
00477   const MeshBase::const_element_iterator end_el = the_mesh.active_local_elements_end();
00478 
00479   typedef std::map<int,std::vector<Real> > map_local_soln;
00480   typedef map_local_soln::iterator  local_soln_iterator;
00481 
00482   map_local_soln local_soln;
00483 
00484   for ( ; el != end_el ; ++el){
00485 
00486     const Elem* elem = *el;
00487 
00488     const FEType& fe_type    = system.variable_type(u_var);
00489 
00490     dof_map.dof_indices (elem, dof_indices);
00491     dof_map.dof_indices (elem, dof_indices_u,u_var);
00492     dof_map.dof_indices (elem, dof_indices_v,v_var);
00493     if(dim==3)  dof_map.dof_indices (elem, dof_indices,w_var);
00494 
00495 
00496     std::vector<Number>       elem_soln_u;
00497     std::vector<Number>       elem_soln_v;
00498     std::vector<Number>       elem_soln_w;
00499 
00500     std::vector<Number>       nodal_soln_u;
00501     std::vector<Number>       nodal_soln_v;
00502     std::vector<Number>       nodal_soln_w;
00503 
00504     elem_soln_u.resize(dof_indices_u.size());
00505     elem_soln_v.resize(dof_indices_v.size());
00506     if(dim == 3) elem_soln_w.resize(dof_indices_w.size());
00507 
00508     for (unsigned int i = 0; i < dof_indices_u.size(); i++)
00509       {
00510         elem_soln_u[i] = system.current_solution(dof_indices_u[i]);
00511         elem_soln_v[i] = system.current_solution(dof_indices_v[i]);
00512         if(dim==3) elem_soln_w[i] = system.current_solution(dof_indices_w[i]);
00513       }
00514 
00515     FEInterface::nodal_soln (dim,fe_type,elem,elem_soln_u,nodal_soln_u);
00516     FEInterface::nodal_soln (dim,fe_type,elem,elem_soln_v,nodal_soln_v);
00517     if(dim == 3) FEInterface::nodal_soln (dim,fe_type,elem,elem_soln_w,nodal_soln_w);
00518 
00519 
00520     libmesh_assert_equal_to (nodal_soln_u.size(), elem->n_nodes());
00521     libmesh_assert_equal_to (nodal_soln_v.size(), elem->n_nodes());
00522 
00523 #ifdef LIBMESH_ENABLE_COMPLEX
00524     libMesh::err << "Complex-valued Ensight output not yet supported" << std::endl;
00525     libmesh_not_implemented()
00526 #endif
00527 
00528       for (unsigned int n=0; n<elem->n_nodes(); n++)
00529         {
00530           std::vector<Real> node_vec(3);
00531           node_vec[0]= libmesh_real(nodal_soln_u[n]);
00532           node_vec[1]= libmesh_real(nodal_soln_v[n]);
00533           node_vec[2]=0.0;
00534           if(dim==3) node_vec[2]= libmesh_real(nodal_soln_w[n]);
00535           local_soln[elem->node(n)] = node_vec;
00536         }
00537 
00538   }
00539 
00540   local_soln_iterator sol = local_soln.begin();
00541   const local_soln_iterator sol_end = local_soln.end();
00542 
00543   for(; sol != sol_end; ++sol)
00544     fprintf(fout,"%12.5e\n",static_cast<double>((*sol).second[0]));
00545   sol = local_soln.begin();
00546   for(; sol != sol_end; ++sol)
00547     fprintf(fout,"%12.5e\n",static_cast<double>((*sol).second[1]));
00548   sol = local_soln.begin();
00549   for(; sol != sol_end; ++sol)
00550     fprintf(fout,"%12.5e\n",static_cast<double>((*sol).second[2]));
00551 
00552   fclose(fout);
00553 
00554 }
00555 
00556 void EnsightIO::elem_type_to_string(ElemType type, char* buffer)
00557 {
00558   switch(type){
00559   case EDGE2:
00560     std::strcpy(buffer,"bar2");
00561     break;
00562   case EDGE3:
00563     std::strcpy(buffer,"bar3");
00564     break;
00565   case QUAD4:
00566     std::strcpy(buffer,"quad4");
00567     break;
00568   case QUAD8:
00569     std::strcpy(buffer,"quad8");
00570     break;
00571   case QUAD9:
00572     libmesh_error_msg("QUAD9: element not supported!");
00573     break;
00574 
00575   case TRI3:
00576     std::strcpy(buffer,"tria3");
00577     break;
00578   case TRI6:
00579     std::strcpy(buffer,"tria6");
00580     break;
00581   case TET4:
00582     std::strcpy(buffer,"tetra4");
00583     break;
00584   case TET10:
00585     std::strcpy(buffer,"tetra10");
00586     break;
00587   case HEX8:
00588     std::strcpy(buffer,"hexa8");
00589     break;
00590   case HEX20:
00591     std::strcpy(buffer,"hexa20");
00592     break;
00593   case HEX27:
00594     libmesh_error_msg("HEX27: element not supported!");
00595     break;
00596   case PYRAMID5:
00597     std::strcpy(buffer,"pyramid5");
00598     break;
00599   default:
00600     break;
00601   }
00602 }
00603 
00604 } // namespace libMesh