Flow123d  3.9.1-787489b
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  this->write_msh_ascii_data(this->node_ids_, this->nodes_, permutation_vec);
84  file << "$EndNodes" << endl;
85 }
86 
88 {
89  ofstream &file = this->_base_file;
90  const static unsigned int gmsh_simplex_types_[4] = {0, 1, 2, 4};
91  auto &id_elem_vec = *( this->elem_ids_->get_data().get() );
92  auto &id_node_vec = *( this->node_ids_->get_data().get() );
93  auto &connectivity_vec = *( this->connectivity_->get_data().get() );
94  auto &offsets_vec = *( this->offsets_->get_data().get() );
95  auto &regions_vec = *( this->region_ids_->get_data().get() );
96  auto &partition_vec = *( this->partitions_->get_data().get() );
97 
98  unsigned int n_nodes, i_node=0;
99 
100  std::vector<unsigned int> gmsh_connectivity(4*id_elem_vec.size(), 0);
101  for(unsigned int i_elm=0; i_elm < id_elem_vec.size(); ++i_elm) {
102  n_nodes = offsets_vec[i_elm+1]-offsets_vec[i_elm];
103  auto &new_to_old_node = output_mesh_->orig_mesh_->element_accessor(i_elm).orig_nodes_order();
104  for(unsigned int i=0; i<n_nodes; i++, i_node++) {
105  // permute element nodes to the order of the input mesh
106  // works only for GMSH, serial output
107  uint old_i = new_to_old_node[i];
108  gmsh_connectivity[4*i_elm+old_i] = connectivity_vec[i_node];
109  }
110  }
111 
112 
113  // Write information about elements
114  file << "$Elements" << endl;
115  file << this->offsets_->n_values()-1 << endl;
117  bool is_corner_output = (this->nodes_->n_values() != output_mesh_->orig_mesh_->node_permutations().size());
118  unsigned int i_gmsh_elm, gmsh_id;
119  auto permutation_vec = output_mesh_->orig_mesh_->element_permutations();
120  for(unsigned int i_elm=0; i_elm < id_elem_vec.size(); ++i_elm) {
121  i_gmsh_elm = permutation_vec[i_elm];
122  if (is_corner_output) gmsh_id = id_elem_vec[i_elm];
123  else gmsh_id = id_elem_vec[i_gmsh_elm];
124 
125  n_nodes = offsets_vec[i_gmsh_elm+1]-offsets_vec[i_gmsh_elm];
126  // element_id element_type 3_other_tags material region partition
127  file << gmsh_id
128  << " " << gmsh_simplex_types_[ n_nodes-1 ]
129  << " 3 " << regions_vec[i_gmsh_elm] << " " << regions_vec[i_gmsh_elm] << " " << partition_vec[i_gmsh_elm];
130 
131  for(unsigned int i=4*i_gmsh_elm; i<4*i_gmsh_elm+n_nodes; i++) {
132  file << " " << id_node_vec[gmsh_connectivity[i]];
133  }
134  file << endl;
135  }
136  file << "$EndElements" << endl;
137 }
138 
139 
141  const std::vector<unsigned int> &permutations)
142 {
143  unsigned int i_gmsh;
144  ofstream &file = this->_base_file;
145  auto &id_vec = *( id_cache->get_data().get() );
146 
147  bool is_corner_output = (this->nodes_->n_values() != output_mesh_->orig_mesh_->node_permutations().size());
148  for(unsigned int i=0; i < output_data->n_values(); ++i) {
149 
150  if (is_corner_output) i_gmsh = i;
151  else i_gmsh = permutations[i];
152 
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 
182  file << "$EndNodeData" << endl;
183 }
184 
185 
187 {
188  ofstream &file = this->_base_file;
189  double time_fixed = isfinite(this->registered_time_)?this->registered_time_:0;
190 
191  file << "$ElementNodeData" << endl;
192 
193  file << "1" << endl; // one string tag
194  file << "\"" << output_data->field_input_name() <<"\"" << endl;
195 
196  file << "1" << endl; // one real tag
197  file << time_fixed << endl; // first real tag = registered_time_
198 
199  file << "3" << endl; // 3 integer tags
200  file << this->current_step << endl; // step number (start = 0)
201  file << output_data->n_comp() << endl; // number of components
202  file << this->offsets_->n_values()-1 << endl; // number of values
203 
204  //this->write_msh_ascii_data(this->elem_ids_, output_data, true);
205  auto &id_vec = *( this->elem_ids_->get_data().get() );
206  auto &offsets_vec = *( this->offsets_->get_data().get() );
207  unsigned int n_nodes, i_corner;
208  auto permutation_vec = output_mesh_->orig_mesh_->element_permutations();
209  for(unsigned int i=0; i < id_vec.size(); ++i) {
210  unsigned int i_gmsh_elm = permutation_vec[i];
211  n_nodes = offsets_vec[i_gmsh_elm+1]-offsets_vec[i_gmsh_elm];
212  i_corner = offsets_vec[i_gmsh_elm];
213  file << id_vec[i] << " " << n_nodes << " ";
214  for (unsigned int j=0; j<n_nodes; j++)
215  output_data->print_ascii(file, i_corner++);
216  file << std::endl;
217  }
218 
219  file << "$EndElementNodeData" << endl;
220 }
221 
223 {
224  ofstream &file = this->_base_file;
225  double time_fixed = isfinite(this->registered_time_)?this->registered_time_:0;
226 
227  file << "$ElementData" << endl;
228 
229  file << "1" << endl; // one string tag
230  file << "\"" << output_data->field_input_name() <<"\"" << endl;
231 
232  file << "1" << endl; // one real tag
233  file << time_fixed << endl; // first real tag = registered_time_
234 
235  file << "3" << endl; // 3 integer tags
236  file << this->current_step << endl; // step number (start = 0)
237  file << output_data->n_comp() << endl; // number of components
238  file << output_data->n_values() << endl; // number of values
239 
240  auto permutation_vec = output_mesh_->orig_mesh_->element_permutations();
241  this->write_msh_ascii_data(this->elem_ids_, output_data, permutation_vec);
242 
243  file << "$EndElementData" << endl;
244 }
245 
247 {
248  LogOut() << __func__ << ": Writing output file " << this->_base_filename << " ... ";
249 
250  this->write_msh_header();
251 
252  this->write_msh_geometry();
253 
254  this->write_msh_topology();
255 
256  LogOut() << "O.K.";
257 
258  return 1;
259 }
260 
262 {
263  /* Output of serial format is implemented only in the first process */
264  if (this->rank_ != 0) {
265  return 0;
266  }
267 
268  // Write header with mesh, when it hasn't been written to output file yet
269  if(this->header_written == false) {
270  this->fix_main_file_extension(".msh");
271  try {
272  this->_base_filename.open_stream( this->_base_file );
273  this->set_stream_precision(this->_base_file);
274  } INPUT_CATCH(FilePath::ExcFileOpen, FilePath::EI_Address_String, input_record_)
275 
276  this->write_head();
277  this->header_written = true;
278  }
279 
280  LogOut() << __func__ << ": Writing output file " << this->_base_filename << " ... ";
281 
282 
283  auto &node_data_list = this->output_data_vec_[NODE_DATA];
284  for(auto data_it = node_data_list.begin(); data_it != node_data_list.end(); ++data_it) {
285  write_node_data(*data_it);
286  }
287  auto &corner_data_list = this->output_data_vec_[CORNER_DATA];
288  for(auto data_it = corner_data_list.begin(); data_it != corner_data_list.end(); ++data_it) {
289  write_corner_data(*data_it);
290  }
291  auto &elem_data_list = this->output_data_vec_[ELEM_DATA];
292  for(auto data_it = elem_data_list.begin(); data_it != elem_data_list.end(); ++data_it) {
293  write_elem_data(*data_it);
294  }
295 
296  // Flush stream to be sure everything is in the file now
297  this->_base_file.flush();
298 
299  LogOut() << "O.K.";
300 
301  return 1;
302 }
303 
304 
305 
307 {
308  return 1;
309 }
310 
311 
312 void OutputMSH::set_output_data_caches(std::shared_ptr<OutputMeshBase> mesh_ptr) {
314 
315  mesh_ptr->get_master_mesh()->create_id_caches();
316  this->node_ids_ = mesh_ptr->get_master_mesh()->node_ids_;
317  this->elem_ids_ = mesh_ptr->get_master_mesh()->elem_ids_;
318  this->region_ids_ = mesh_ptr->get_master_mesh()->region_ids_;
319  this->partitions_ = mesh_ptr->get_master_mesh()->partitions_;
320 }
321 
OutputMSH::write_corner_data
void write_corner_data(OutputDataPtr output_data)
writes ElementNode data ascii GMSH (.msh) output file.
Definition: output_msh.cc:186
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:246
FLOW123D_FORCE_LINK_IN_CHILD
#define FLOW123D_FORCE_LINK_IN_CHILD(x)
Definition: global_defs.h:104
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:222
uint
unsigned int uint
Definition: mh_dofhandler.hh:101
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:87
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:140
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:261
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:312
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:306
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.