Flow123d  JS_before_hm-1830-gb19ac973c
output_msh.cc
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file output_msh.cc
15  * @brief The functions for outputs to GMSH files.
16  */
17 
18 #include "output_msh.hh"
19 #include "output_mesh.hh"
20 #include "output_element.hh"
21 #include "mesh/mesh.h"
23 #include "input/factory.hh"
24 #include "tools/time_governor.hh"
25 
26 
28 
29 
30 using namespace Input::Type;
31 
32 
34  return Record("gmsh", "Parameters of gmsh output format.")
35  // It is derived from abstract class
37  .close();
38 }
39 
40 const int OutputMSH::registrar = Input::register_class< OutputMSH >("gmsh") +
42 
43 
45 {
46  this->enable_refinement_ = false;
47  this->header_written = false;
48 
49  dummy_data_list_.resize(OutputTime::N_DISCRETE_SPACES);
50 
51 
52 }
53 
55 {
56  // Perform output of last time step
57  this->write_time_frame();
58 
59  this->write_tail();
60 }
61 
62 
63 
64 
66 {
67  ofstream &file = this->_base_file;
68 
69  // Write simple header
70  file << "$MeshFormat" << endl;
71  file << "2" << " 0 " << sizeof(double) << endl;
72  file << "$EndMeshFormat" << endl;
73 }
74 
76 {
77  ofstream &file = this->_base_file;
78 
79  // Write information about nodes
80  file << "$Nodes" << endl;
81  file << this->nodes_->n_values() << endl;
82  auto permutation_vec = output_mesh_->orig_mesh_->node_permutations();
83  bool is_corner_output = (this->nodes_->n_values() != permutation_vec.size());
84  unsigned int i_gmsh_node;
85  auto &id_node_vec = *( this->node_ids_->get_component_data(0).get() );
86  for(unsigned int i_node=0; i_node < id_node_vec.size(); ++i_node) {
87  if (is_corner_output) i_gmsh_node = i_node;
88  else i_gmsh_node = permutation_vec[i_node];
89  file << id_node_vec[i_gmsh_node] << " ";
90  this->nodes_->print_ascii(file, i_gmsh_node);
91  file << endl;
92  }
93  file << "$EndNodes" << endl;
94 }
95 
97 {
98  ofstream &file = this->_base_file;
99  const static unsigned int gmsh_simplex_types_[4] = {0, 1, 2, 4};
100  auto &id_elem_vec = *( this->elem_ids_->get_component_data(0).get() );
101  auto &id_node_vec = *( this->node_ids_->get_component_data(0).get() );
102  auto &connectivity_vec = *( this->connectivity_->get_component_data(0).get() );
103  auto &offsets_vec = *( this->offsets_->get_component_data(0).get() );
104  auto &regions_vec = *( this->region_ids_->get_component_data(0).get() );
105  auto &partition_vec = *( this->partitions_->get_component_data(0).get() );
106 
107  unsigned int n_nodes, i_node=0;
108 
109  std::vector<unsigned int> gmsh_connectivity(4*id_elem_vec.size(), 0);
110  for(unsigned int i_elm=0; i_elm < id_elem_vec.size(); ++i_elm) {
111  n_nodes = offsets_vec[i_elm+1]-offsets_vec[i_elm];
112  for(unsigned int i=4*i_elm; i<4*i_elm+n_nodes; i++, i_node++) {
113  gmsh_connectivity[i] = connectivity_vec[i_node];
114  }
115  }
116 
117 
118  // Write information about elements
119  file << "$Elements" << endl;
120  file << this->offsets_->n_values()-1 << endl;
122  bool is_corner_output = (this->nodes_->n_values() != output_mesh_->orig_mesh_->node_permutations().size());
123  unsigned int gmsh_id;
124  auto permutation_vec = output_mesh_->orig_mesh_->element_permutations();
125  for(unsigned int i_elm=0; i_elm < id_elem_vec.size(); ++i_elm) {
126  unsigned int i_gmsh_elm = permutation_vec[i_elm];
127  n_nodes = offsets_vec[i_gmsh_elm+1]-offsets_vec[i_gmsh_elm];
128  // element_id element_type 3_other_tags material region partition
129  if (is_corner_output) gmsh_id = i_elm;
130  else gmsh_id = id_elem_vec[i_gmsh_elm];
131  file << gmsh_id
132  << " " << gmsh_simplex_types_[ n_nodes-1 ]
133  << " 3 " << regions_vec[i_gmsh_elm] << " " << regions_vec[i_gmsh_elm] << " " << partition_vec[i_gmsh_elm];
134 
135  for(unsigned int i=4*i_gmsh_elm; i<4*i_gmsh_elm+n_nodes; i++) {
136  file << " " << id_node_vec[gmsh_connectivity[i]];
137  }
138  file << endl;
139  }
140  file << "$EndElements" << endl;
141 }
142 
143 
145  const std::vector<unsigned int> &permutations)
146 {
147  unsigned int i_gmsh;
148  ofstream &file = this->_base_file;
149  auto &id_vec = *( id_cache->get_component_data(0).get() );
150 
151  for(unsigned int i=0; i < output_data->n_values(); ++i) {
152  i_gmsh = permutations[i];
153  file << id_vec[i_gmsh] << " ";
154  output_data->print_ascii(file, i_gmsh);
155  file << std::endl;
156  }
157 }
158 
159 
161 {
162  ofstream &file = this->_base_file;
163  double time_fixed = isfinite(this->registered_time_)?this->registered_time_:0;
164  time_fixed /= this->time_unit_converter->get_coef();
165 
166  file << "$NodeData" << endl;
167 
168  file << "1" << endl; // one string tag
169  file << "\"" << output_data->field_input_name() <<"\"" << endl;
170 
171  file << "1" << endl; // one real tag
172  file << time_fixed << endl; // first real tag = time
173 
174  file << "3" << endl; // 3 integer tags
175  file << this->current_step << endl; // step number (start = 0)
176  file << output_data->n_comp() << endl; // number of components
177  file << output_data->n_values() << endl; // number of values
178 
179  auto permutation_vec = output_mesh_->orig_mesh_->node_permutations();
180  this->write_msh_ascii_data(this->node_ids_, output_data, permutation_vec);
181  /*unsigned int i_gmsh;
182  auto &id_vec = *( this->node_ids_->get_component_data(0).get() );
183  for(unsigned int i=0; i < output_data->n_values(); ++i) {
184  i_gmsh = permutation_vec[i];
185  file << id_vec[i_gmsh] << " ";
186  output_data->print_ascii(file, i_gmsh);
187  file << std::endl;
188  }*/
189 
190  file << "$EndNodeData" << endl;
191 }
192 
193 
195 {
196  ofstream &file = this->_base_file;
197  double time_fixed = isfinite(this->registered_time_)?this->registered_time_:0;
198 
199  file << "$ElementNodeData" << endl;
200 
201  file << "1" << endl; // one string tag
202  file << "\"" << output_data->field_input_name() <<"\"" << endl;
203 
204  file << "1" << endl; // one real tag
205  file << time_fixed << endl; // first real tag = registered_time_
206 
207  file << "3" << endl; // 3 integer tags
208  file << this->current_step << endl; // step number (start = 0)
209  file << output_data->n_comp() << endl; // number of components
210  file << this->offsets_->n_values()-1 << endl; // number of values
211 
212  //this->write_msh_ascii_data(this->elem_ids_, output_data, true);
213  auto &id_vec = *( this->elem_ids_->get_component_data(0).get() );
214  auto &offsets_vec = *( this->offsets_->get_component_data(0).get() );
215  unsigned int n_nodes, i_corner;
216  auto permutation_vec = output_mesh_->orig_mesh_->element_permutations();
217  for(unsigned int i=0; i < id_vec.size(); ++i) {
218  unsigned int i_gmsh_elm = permutation_vec[i];
219  n_nodes = offsets_vec[i_gmsh_elm+1]-offsets_vec[i_gmsh_elm];
220  i_corner = offsets_vec[i_gmsh_elm];
221  file << id_vec[i] << " " << n_nodes << " ";
222  for (unsigned int j=0; j<n_nodes; j++)
223  output_data->print_ascii(file, i_corner++);
224  file << std::endl;
225  }
226 
227  file << "$EndElementNodeData" << endl;
228 }
229 
231 {
232  ofstream &file = this->_base_file;
233  double time_fixed = isfinite(this->registered_time_)?this->registered_time_:0;
234 
235  file << "$ElementData" << endl;
236 
237  file << "1" << endl; // one string tag
238  file << "\"" << output_data->field_input_name() <<"\"" << endl;
239 
240  file << "1" << endl; // one real tag
241  file << time_fixed << endl; // first real tag = registered_time_
242 
243  file << "3" << endl; // 3 integer tags
244  file << this->current_step << endl; // step number (start = 0)
245  file << output_data->n_comp() << endl; // number of components
246  file << output_data->n_values() << endl; // number of values
247 
248  auto permutation_vec = output_mesh_->orig_mesh_->element_permutations();
249  this->write_msh_ascii_data(this->elem_ids_, output_data, permutation_vec);
250  /*unsigned int i_gmsh;
251  auto &id_vec = *( this->elem_ids_->get_component_data(0).get() );
252  for(unsigned int i=0; i < output_data->n_values(); ++i) {
253  i_gmsh = permutation_vec[i];
254  file << id_vec[i_gmsh] << " ";
255  output_data->print_ascii(file, i_gmsh);
256  file << std::endl;
257  }*/
258 
259  file << "$EndElementData" << endl;
260 }
261 
263 {
264  LogOut() << __func__ << ": Writing output file " << this->_base_filename << " ... ";
265 
266  this->write_msh_header();
267 
268  this->write_msh_geometry();
269 
270  this->write_msh_topology();
271 
272  LogOut() << "O.K.";
273 
274  return 1;
275 }
276 
278 {
279  /* Output of serial format is implemented only in the first process */
280  if (this->rank_ != 0) {
281  return 0;
282  }
283 
284  // Write header with mesh, when it hasn't been written to output file yet
285  if(this->header_written == false) {
286  this->fix_main_file_extension(".msh");
287  try {
288  this->_base_filename.open_stream( this->_base_file );
289  this->set_stream_precision(this->_base_file);
290  } INPUT_CATCH(FilePath::ExcFileOpen, FilePath::EI_Address_String, input_record_)
291 
292  this->write_head();
293  this->header_written = true;
294  }
295 
296  LogOut() << __func__ << ": Writing output file " << this->_base_filename << " ... ";
297 
298 
299  auto &node_data_list = this->output_data_vec_[NODE_DATA];
300  for(auto data_it = node_data_list.begin(); data_it != node_data_list.end(); ++data_it) {
301  write_node_data(*data_it);
302  }
303  auto &corner_data_list = this->output_data_vec_[CORNER_DATA];
304  for(auto data_it = corner_data_list.begin(); data_it != corner_data_list.end(); ++data_it) {
305  write_corner_data(*data_it);
306  }
307  auto &elem_data_list = this->output_data_vec_[ELEM_DATA];
308  for(auto data_it = elem_data_list.begin(); data_it != elem_data_list.end(); ++data_it) {
309  write_elem_data(*data_it);
310  }
311 
312  // Flush stream to be sure everything is in the file now
313  this->_base_file.flush();
314 
315  LogOut() << "O.K.";
316 
317  return 1;
318 }
319 
320 
321 
323 {
324  return 1;
325 }
326 
327 
328 void OutputMSH::set_output_data_caches(std::shared_ptr<OutputMeshBase> mesh_ptr) {
330 
331  mesh_ptr->get_master_mesh()->create_id_caches();
332  this->node_ids_ = mesh_ptr->get_master_mesh()->node_ids_;
333  this->elem_ids_ = mesh_ptr->get_master_mesh()->elem_ids_;
334  this->region_ids_ = mesh_ptr->get_master_mesh()->region_ids_;
335  this->partitions_ = mesh_ptr->get_master_mesh()->partitions_;
336 }
337 
OutputMSH::write_corner_data
void write_corner_data(OutputDataPtr output_data)
writes ElementNode data ascii GMSH (.msh) output file.
Definition: output_msh.cc:194
OutputMSH::write_msh_geometry
void write_msh_geometry(void)
This function writes geometry (position of nodes) to GMSH (.msh) file format.
Definition: output_msh.cc:75
factory.hh
time_governor.hh
Basic time management class.
OutputMSH::OutputMSH
OutputMSH()
The constructor of this class. We open the output file in first call of write_data.
Definition: output_msh.cc:44
ElementDataCache
Definition: element_data_cache.hh:44
element_data_cache_base.hh
OutputMSH::write_head
int write_head(void)
This method writes head of GMSH (.msh) file format.
Definition: output_msh.cc:262
FLOW123D_FORCE_LINK_IN_CHILD
#define FLOW123D_FORCE_LINK_IN_CHILD(x)
Definition: global_defs.h:157
std::vector< unsigned int >
ElementAccessor
Definition: dh_cell_accessor.hh:32
OutputMSH::write_elem_data
void write_elem_data(OutputDataPtr output_data)
This function write all data on elements to output file. This function is used for static and dynamic...
Definition: output_msh.cc:230
Input::Type::Record::size
unsigned int size() const
Returns number of keys in the Record.
Definition: type_record.hh:602
Input::Type::Record::derive_from
virtual Record & derive_from(Abstract &parent)
Method to derive new Record from an AbstractRecord parent.
Definition: type_record.cc:196
LogOut
#define LogOut()
Macro defining 'log' record of log.
Definition: logger.hh:281
OutputMSH::write_msh_topology
void write_msh_topology(void)
This function writes topology (connection of nodes) to the GMSH (.msh) file format.
Definition: output_msh.cc:96
OutputMSH::registrar
static const int registrar
Registrar of class to factory.
Definition: output_msh.hh:82
OutputMSH::write_msh_ascii_data
void write_msh_ascii_data(std::shared_ptr< ElementDataCache< unsigned int >> id_cache, OutputDataPtr output_data, const std::vector< unsigned int > &permutations)
This function writes nodes / elements ascii data to GMSH (.msh) output file.
Definition: output_msh.cc:144
INPUT_CATCH
#define INPUT_CATCH(ExceptionType, AddressEITag, input_accessor)
Definition: accessors.hh:63
mesh.h
Input::Type::Record::close
Record & close() const
Close the Record for further declarations of keys.
Definition: type_record.cc:304
Input::Type
Definition: balance.hh:41
Input::Type::Record
Record type proxy class.
Definition: type_record.hh:182
OutputTime::set_output_data_caches
virtual void set_output_data_caches(std::shared_ptr< OutputMeshBase > mesh_ptr)
Definition: output_time.cc:133
OutputMSH::write_data
int write_data(void)
This method writes data to GMSH (.msh) file format for current time.
Definition: output_msh.cc:277
OutputTime::get_input_format_type
static Input::Type::Abstract & get_input_format_type()
The specification of output file format.
Definition: output_time.cc:65
OutputMSH::set_output_data_caches
void set_output_data_caches(std::shared_ptr< OutputMeshBase > mesh_ptr) override
Definition: output_msh.cc:328
OutputTime::OutputDataPtr
std::shared_ptr< ElementDataCacheBase > OutputDataPtr
Definition: output_time.hh:144
OutputMSH::write_msh_header
void write_msh_header(void)
This function write header of GMSH (.msh) file format.
Definition: output_msh.cc:65
OutputMSH::get_input_type
static const Input::Type::Record & get_input_type()
The definition of input record for gmsh file format.
Definition: output_msh.cc:33
output_msh.hh
output_mesh.hh
Classes for auxiliary output mesh.
OutputMSH::~OutputMSH
~OutputMSH()
The destructor of this class.
Definition: output_msh.cc:54
OutputMSH::write_node_data
void write_node_data(OutputDataPtr output_data)
This function write all data on nodes to output file. This function is used for static and dynamic da...
Definition: output_msh.cc:160
OutputMSH::write_tail
int write_tail(void)
This method should write tail of GMSH (.msh) file format.
Definition: output_msh.cc:322
OutputTime::N_DISCRETE_SPACES
static const unsigned int N_DISCRETE_SPACES
Definition: output_time.hh:107
output_element.hh
Class OutputElement and its iterator OutputElementIterator on the output mesh.