Flow123d  release_2.1.2-337-g6b7a56b
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 "mesh/mesh.h"
21 #include "input/factory.hh"
22 
23 
25 
26 
27 using namespace Input::Type;
28 
29 
30 /**
31  * Auxiliary implementation of ElementDataCacheBase that performs output of single zero data for the fields that are
32  * off for current time frame.
33  */
35 public:
36 
37  DummyOutputData(std::string field_name_in, ElementDataCacheBase::NumCompValueType n_elem_in)
38  {
39  this->field_input_name_ = field_name_in;
40  this->n_elem_ = n_elem_in;
41  this->n_values_ = 1;
42  }
43 
44  virtual ~DummyOutputData() override
45  {}
46 
47  void print_ascii(ostream &out_stream, unsigned int idx) override
48  {
49  for(unsigned int i=0; i< n_elem_;i++) out_stream << 0 << " ";
50  }
51 
52  void print_ascii_all(ostream &out_stream) override
53  {
54  for(unsigned int i=0; i< n_elem_;i++) out_stream << 0 << " ";
55  }
56 
57  void print_binary_all(ostream &out_stream, bool print_data_size = true) override
58  {
59  ASSERT(false).error("Not implemented.");
60  }
61 
62  void print_all_yaml(ostream &out_stream, unsigned int precision) override
63  {}
64 
65  void get_min_max_range(double &min, double &max) override
66  {}
67 
68  void read_ascii_data(Tokenizer &tok, unsigned int n_components, unsigned int i_row) override
69  {}
70 
71  void read_binary_data(std::istream &data_stream, unsigned int n_components, unsigned int i_row) override
72  {}
73 };
74 
75 
76 
77 
78 
79 
80 
82  return Record("gmsh", "Parameters of gmsh output format.")
83  // It is derived from abstract class
85  .close();
86 }
87 
88 const int OutputMSH::registrar = Input::register_class< OutputMSH >("gmsh") +
90 
91 
93 {
94  this->enable_refinement_ = false;
95  this->header_written = false;
96 
98 
99 
100 }
101 
103 {
104  this->write_tail();
105 }
106 
107 
108 
109 
111 {
112  ofstream &file = this->_base_file;
113 
114  // Write simple header
115  file << "$MeshFormat" << endl;
116  file << "2" << " 0 " << sizeof(double) << endl;
117  file << "$EndMeshFormat" << endl;
118 }
119 
121 {
122  ofstream &file = this->_base_file;
123  Mesh* mesh = this->_mesh;
124 
125  // Write information about nodes
126  file << "$Nodes" << endl;
127  file << mesh->node_vector.size() << endl;
128  FOR_NODES(mesh, nod) {
129  file << NODE_FULL_ITER(mesh, nod).id() << " " << nod->getX() << " " << nod->getY() << " " << nod->getZ() << endl;
130  }
131  file << "$EndNodes" << endl;
132 }
133 
135 {
136  ofstream &file = this->_base_file;
137  Mesh* mesh = this->_mesh;
138  unsigned int i;
139  const static unsigned int gmsh_simplex_types_[4] = {0, 1, 2, 4};
140 
141  // Write information about elements
142  file << "$Elements" << endl;
143  file << mesh->n_elements() << endl;
144  FOR_ELEMENTS(mesh, elm) {
145  // element_id element_type 3_other_tags material region partition
146  file << ELEM_FULL_ITER(mesh, elm).id()
147  << " " << gmsh_simplex_types_[ elm->dim() ]
148  << " 3 " << elm->region().id() << " " << elm->region().id() << " " << elm->pid;
149 
150  FOR_ELEMENT_NODES(elm, i)
151  file << " " << NODE_FULL_ITER(mesh, elm->node[i]).id();
152  file << endl;
153  }
154  file << "$EndElements" << endl;
155 }
156 
157 
158 template<class element>
160 {
161  ofstream &file = this->_base_file;
162 
163  for(unsigned int i=0; i < output_data->n_values(); i ++) {
164  file << vec(i).id() << " ";
165  output_data->print_ascii(file, i);
166  file << std::endl;
167  }
168 
169 }
170 
171 
173 {
174  Mesh *mesh = this->_mesh;
175  ofstream &file = this->_base_file;
176 
177  /* Write ascii data */
178  unsigned int i_node;
179  unsigned int i_corner = 0;
180  FOR_ELEMENTS(mesh, ele) {
181  file << ele.id() << " " << ele->n_nodes() << " ";
182 
183  FOR_ELEMENT_NODES(ele, i_node) {
184  output_data->print_ascii(file, i_corner++);
185  }
186 
187  file << std::endl;
188  }
189 }
190 
191 
192 
194 {
195  ofstream &file = this->_base_file;
196  double time_fixed = isfinite(this->time)?this->time:0;
197 
198 
199  file << "$NodeData" << 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 = time
206 
207  file << "3" << endl; // 3 integer tags
208  file << this->current_step << endl; // step number (start = 0)
209  file << output_data->n_elem() << endl; // number of components
210  file << output_data->n_values() << endl; // number of values
211 
212  this->write_msh_ascii_cont_data(this->_mesh->node_vector, output_data);
213 
214  file << "$EndNodeData" << endl;
215 }
216 
217 
219 {
220  ofstream &file = this->_base_file;
221  double time_fixed = isfinite(this->time)?this->time:0;
222 
223  file << "$ElementNodeData" << endl;
224 
225  file << "1" << endl; // one string tag
226  file << "\"" << output_data->field_input_name() <<"\"" << endl;
227 
228  file << "1" << endl; // one real tag
229  file << time_fixed << endl; // first real tag = time
230 
231  file << "3" << endl; // 3 integer tags
232  file << this->current_step << endl; // step number (start = 0)
233  file << output_data->n_elem() << endl; // number of components
234  file << this->_mesh->n_elements() << endl; // number of values
235 
236  this->write_msh_ascii_discont_data(output_data);
237 
238  file << "$EndElementNodeData" << endl;
239 }
240 
242 {
243  ofstream &file = this->_base_file;
244  double time_fixed = isfinite(this->time)?this->time:0;
245 
246  file << "$ElementData" << endl;
247 
248  file << "1" << endl; // one string tag
249  file << "\"" << output_data->field_input_name() <<"\"" << endl;
250 
251  file << "1" << endl; // one real tag
252  file << time_fixed << endl; // first real tag = time
253 
254  file << "3" << endl; // 3 integer tags
255  file << this->current_step << endl; // step number (start = 0)
256  file << output_data->n_elem() << endl; // number of components
257  file << output_data->n_values() << endl; // number of values
258 
259  this->write_msh_ascii_cont_data(this->_mesh->element, output_data);
260 
261  file << "$EndElementData" << endl;
262 }
263 
265 {
266  auto &dummy_data_list = dummy_data_list_[type_idx];
267  auto &data_list = this->output_data_vec_[type_idx];
268 
269  if (dummy_data_list.size() == 0) {
270  // Collect all output fields
271  // If more EquationOutput object with different initial times output into same
272  // output stream, we may need to possibly update this list on every output frame.
273  for(auto out_ptr : data_list)
274  dummy_data_list.push_back( std::make_shared<DummyOutputData>(out_ptr->field_input_name(), out_ptr->n_elem()));
275  }
276 
277 
278  auto data_it = data_list.begin();
279  for(auto dummy_it = dummy_data_list.begin(); dummy_it != dummy_data_list.end(); ++dummy_it) {
280  //DebugOut().fmt("dummy field: {} data field: {}\n", (*dummy_it)->field_input_name_, (*data_it)->field_input_name_);
281  if ((*dummy_it)->field_input_name() == (*data_it)->field_input_name()) {
282  (this->*format_fce)(*data_it); ++data_it;
283  } else {
284  (this->*format_fce)(*dummy_it);
285  }
286  }
287  ASSERT( data_it == data_list.end() )(data_it - data_list.begin())(data_list.size());
288 }
289 
291 {
292  LogOut() << __func__ << ": Writing output file " << this->_base_filename << " ... ";
293 
294  this->write_msh_header();
295 
296  this->write_msh_geometry();
297 
298  this->write_msh_topology();
299 
300  LogOut() << "O.K.";
301 
302  return 1;
303 }
304 
306 {
307  // Write header with mesh, when it hasn't been written to output file yet
308  if(this->header_written == false) {
309  if(this->rank == 0) {
310  this->fix_main_file_extension(".msh");
311  try {
312  this->_base_filename.open_stream( this->_base_file );
313  this->set_stream_precision(this->_base_file);
314  } INPUT_CATCH(FilePath::ExcFileOpen, FilePath::EI_Address_String, input_record_)
315  }
316 
317  this->write_head();
318  this->header_written = true;
319  }
320 
321  LogOut() << __func__ << ": Writing output file " << this->_base_filename << " ... ";
322 
323 
327 
328  // Flush stream to be sure everything is in the file now
329  this->_base_file.flush();
330 
331  LogOut() << "O.K.";
332 
333  return 1;
334 }
335 
336 
337 
339 {
340  return 1;
341 }
342 
343 
344 
void read_ascii_data(Tokenizer &tok, unsigned int n_components, unsigned int i_row) override
Definition: output_msh.cc:68
std::vector< std::vector< OutputDataPtr > > dummy_data_list_
Definition: output_msh.hh:83
void print_ascii_all(ostream &out_stream) override
Definition: output_msh.cc:52
double time
Definition: output_time.hh:228
Mesh * _mesh
Definition: output_time.hh:264
void print_ascii(ostream &out_stream, unsigned int idx) override
Definition: output_msh.cc:47
void write_msh_header(void)
This function write header of GMSH (.msh) file format.
Definition: output_msh.cc:110
#define FOR_ELEMENT_NODES(i, j)
Definition: elements.h:187
static const Input::Type::Record & get_input_type()
The definition of input record for gmsh file format.
Definition: output_msh.cc:81
Input::Record input_record_
Definition: output_time.hh:238
void read_binary_data(std::istream &data_stream, unsigned int n_components, unsigned int i_row) override
Definition: output_msh.cc:71
#define NODE_FULL_ITER(_mesh_, i)
Definition: mesh.h:66
OutputMSH()
The constructor of this class. We open the output file in first call of write_data.
Definition: output_msh.cc:92
void fix_main_file_extension(std::string extension)
Definition: output_time.cc:162
unsigned int size() const
Returns number of keys in the Record.
Definition: type_record.hh:598
#define FOR_ELEMENTS(_mesh_, __i)
Definition: mesh.h:426
static const int registrar
Registrar of class to factory.
Definition: output_msh.hh:75
void write_msh_geometry(void)
This function writes geometry (position of nodes) to GMSH (.msh) file format.
Definition: output_msh.cc:120
FilePath _base_filename
Definition: output_time.hh:248
void write_corner_data(OutputDataPtr output_data)
writes ElementNode data ascii GMSH (.msh) output file.
Definition: output_msh.cc:218
#define ELEM_FULL_ITER(_mesh_, i)
Definition: mesh.h:78
#define INPUT_CATCH(ExceptionType, AddressEITag, input_accessor)
Definition: accessors.hh:64
int write_tail(void)
This method should write tail of GMSH (.msh) file format.
Definition: output_msh.cc:338
static Input::Type::Abstract & get_input_format_type()
The specification of output file format.
Definition: output_time.cc:60
Small extension of Vector<T> container with support to Id numbers.
Definition: sys_vector.hh:154
Definition: mesh.h:97
std::shared_ptr< ElementDataCacheBase > OutputDataPtr
Definition: output_time.hh:111
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:346
#define LogOut()
Macro defining &#39;log&#39; record of log.
Definition: logger.hh:239
Record & close() const
Close the Record for further declarations of keys.
Definition: type_record.cc:303
void write_field_data(OutputTime::DiscreteSpace type_idx, void(OutputMSH::*format_fce)(OutputDataPtr))
Definition: output_msh.cc:264
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:193
DummyOutputData(std::string field_name_in, ElementDataCacheBase::NumCompValueType n_elem_in)
Definition: output_msh.cc:37
virtual Record & derive_from(Abstract &parent)
Method to derive new Record from an AbstractRecord parent.
Definition: type_record.cc:195
unsigned int size() const
Returns size of the container. This is independent of the allocated space.
Definition: sys_vector.hh:391
void open_stream(Stream &stream) const
Definition: file_path.cc:211
unsigned int n_elements() const
Definition: mesh.h:141
void write_msh_ascii_cont_data(flow::VectorId< element > &vec, OutputDataPtr output_data)
This function writes continuous ascii data to GMSH (.msh) output file.
Definition: output_msh.cc:159
int current_step
Definition: output_time.hh:223
void write_msh_topology(void)
This function writes topology (connection of nodes) to the GMSH (.msh) file format.
Definition: output_msh.cc:134
static const unsigned int N_DISCRETE_SPACES
Definition: output_time.hh:95
void write_msh_ascii_discont_data(OutputDataPtr output_data)
This function writes discontinuous ascii data to GMSH (.msh) output file.
Definition: output_msh.cc:172
bool header_written
Definition: output_msh.hh:77
void set_stream_precision(std::ofstream &stream)
Definition: output_time.cc:94
~OutputMSH()
The destructor of this class.
Definition: output_msh.cc:102
ofstream _base_file
Definition: output_time.hh:243
#define FOR_NODES(_mesh_, i)
Definition: mesh.h:58
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:241
virtual ~DummyOutputData() override
Definition: output_msh.cc:44
int write_data(void)
This method writes data to GMSH (.msh) file format for current time.
Definition: output_msh.cc:305
OutputDataFieldVec output_data_vec_[N_DISCRETE_SPACES]
Definition: output_time.hh:218
Record type proxy class.
Definition: type_record.hh:182
bool enable_refinement_
Auxiliary flag for refinement enabling, due to gmsh format.
Definition: output_time.hh:274
void print_all_yaml(ostream &out_stream, unsigned int precision) override
Definition: output_msh.cc:62
void print_binary_all(ostream &out_stream, bool print_data_size=true) override
Definition: output_msh.cc:57
void get_min_max_range(double &min, double &max) override
Definition: output_msh.cc:65
This class is used for output data to VTK file format.
Definition: output_msh.hh:27
int write_head(void)
This method writes head of GMSH (.msh) file format.
Definition: output_msh.cc:290
#define FLOW123D_FORCE_LINK_IN_CHILD(x)
Definition: global_defs.h:180
NodeVector node_vector
Vector of nodes of the mesh.
Definition: mesh.h:226
ElementVector element
Vector of elements of the mesh.
Definition: mesh.h:228