Flow123d  release_2.2.0-914-gf1a3a4f
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 
25 
27 
28 
29 using namespace Input::Type;
30 
31 
32 /**
33  * Auxiliary implementation of ElementDataCacheBase that performs output of single zero data for the fields that are
34  * off for current time frame.
35  */
37 public:
38 
39  DummyOutputData(std::string field_name_in, ElementDataCacheBase::NumCompValueType n_elem_in)
40  {
41  this->field_input_name_ = field_name_in;
42  this->n_elem_ = n_elem_in;
43  this->n_values_ = 1;
44  }
45 
46  virtual ~DummyOutputData() override
47  {}
48 
49  void print_ascii(ostream &out_stream, unsigned int idx) override
50  {
51  for(unsigned int i=0; i< n_elem_;i++) out_stream << 0 << " ";
52  }
53 
54  void print_ascii_all(ostream &out_stream) override
55  {
56  for(unsigned int i=0; i< n_elem_;i++) out_stream << 0 << " ";
57  }
58 
59  void print_binary_all(ostream &out_stream, bool print_data_size = true) override
60  {
61  ASSERT(false).error("Not implemented.");
62  }
63 
64  void print_all_yaml(ostream &out_stream, unsigned int precision) override
65  {}
66 
67  void get_min_max_range(double &min, double &max) override
68  {}
69 
70  void read_ascii_data(Tokenizer &tok, unsigned int n_components, unsigned int i_row) override
71  {}
72 
73  void read_binary_data(std::istream &data_stream, unsigned int n_components, unsigned int i_row) override
74  {}
75 };
76 
77 
78 
79 
80 
81 
82 
83 const Record & OutputMSH::get_input_type() {
84  return Record("gmsh", "Parameters of gmsh output format.")
85  // It is derived from abstract class
87  .close();
88 }
89 
90 const int OutputMSH::registrar = Input::register_class< OutputMSH >("gmsh") +
92 
93 
95 {
96  this->enable_refinement_ = false;
97  this->header_written = false;
98 
100 
101 
102 }
103 
105 {
106  this->write_tail();
107 }
108 
109 
110 
111 
113 {
114  ofstream &file = this->_base_file;
115 
116  // Write simple header
117  file << "$MeshFormat" << endl;
118  file << "2" << " 0 " << sizeof(double) << endl;
119  file << "$EndMeshFormat" << endl;
120 }
121 
123 {
124  ofstream &file = this->_base_file;
125 
126  // Write information about nodes
127  file << "$Nodes" << endl;
128  file << this->nodes_->n_values() << endl;
129  auto &id_node_vec = *( this->node_ids_->get_component_data(0).get() );
130  unsigned int i_node=0;
131  for(unsigned int i_node=0; i_node < id_node_vec.size(); ++i_node) {
132  file << id_node_vec[i_node] << " ";
133  this->nodes_->print_ascii(file, i_node);
134  file << endl;
135  }
136  file << "$EndNodes" << endl;
137 }
138 
140 {
141  ofstream &file = this->_base_file;
142  const static unsigned int gmsh_simplex_types_[4] = {0, 1, 2, 4};
143  auto &id_elem_vec = *( this->elem_ids_->get_component_data(0).get() );
144  auto &id_node_vec = *( this->node_ids_->get_component_data(0).get() );
145  auto &connectivity_vec = *( this->connectivity_->get_component_data(0).get() );
146  auto &offsets_vec = *( this->offsets_->get_component_data(0).get() );
147  auto &regions_vec = *( this->region_ids_->get_component_data(0).get() );
148  auto &partition_vec = *( this->partitions_->get_component_data(0).get() );
149 
150  unsigned int n_nodes, i_node=0;
151 
152  // Write information about elements
153  file << "$Elements" << endl;
154  file << this->offsets_->n_values() << endl;
156  for(unsigned int i_elm=0; i_elm < id_elem_vec.size(); ++i_elm) {
157  n_nodes = (i_elm==0) ? (offsets_vec[0]) : (offsets_vec[i_elm]-offsets_vec[i_elm-1]);
158  // element_id element_type 3_other_tags material region partition
159  file << id_elem_vec[i_elm]
160  << " " << gmsh_simplex_types_[ n_nodes-1 ]
161  << " 3 " << regions_vec[i_elm] << " " << regions_vec[i_elm] << " " << partition_vec[i_elm];
162 
163  for(unsigned int i=0; i<n_nodes; i++, i_node++) {
164  file << " " << id_node_vec[connectivity_vec[i_node]];
165  }
166  file << endl;
167  }
168  file << "$EndElements" << endl;
169 }
170 
171 
172 void OutputMSH::write_msh_ascii_data(std::shared_ptr<ElementDataCache<unsigned int>> id_cache, OutputDataPtr output_data, bool discont)
173 {
174  ofstream &file = this->_base_file;
175  auto &id_vec = *( id_cache->get_component_data(0).get() );
176 
177  if (discont) { // corner data
178  auto &offsets_vec = *( this->offsets_->get_component_data(0).get() );
179  unsigned int n_nodes, i_corner=0;
180  for(unsigned int i=0; i < id_vec.size(); ++i) {
181  n_nodes = (i==0) ? (offsets_vec[0]) : (offsets_vec[i]-offsets_vec[i-1]);
182  file << id_vec[i] << " " << n_nodes << " ";
183  for (unsigned int j=0; j<n_nodes; j++)
184  output_data->print_ascii(file, i_corner++);
185  file << std::endl;
186  }
187  } else { // element / node data
188  for(unsigned int i=0; i < output_data->n_values(); ++i) {
189  file << id_vec[i] << " ";
190  output_data->print_ascii(file, i);
191  file << std::endl;
192  }
193 
194  }
195 }
196 
197 
199 {
200  ofstream &file = this->_base_file;
201  double time_fixed = isfinite(this->time)?this->time:0;
202 
203 
204  file << "$NodeData" << endl;
205 
206  file << "1" << endl; // one string tag
207  file << "\"" << output_data->field_input_name() <<"\"" << endl;
208 
209  file << "1" << endl; // one real tag
210  file << time_fixed << endl; // first real tag = time
211 
212  file << "3" << endl; // 3 integer tags
213  file << this->current_step << endl; // step number (start = 0)
214  file << output_data->n_elem() << endl; // number of components
215  file << output_data->n_values() << endl; // number of values
216 
217  this->write_msh_ascii_data(this->node_ids_, output_data);
218 
219  file << "$EndNodeData" << endl;
220 }
221 
222 
224 {
225  ofstream &file = this->_base_file;
226  double time_fixed = isfinite(this->time)?this->time:0;
227 
228  file << "$ElementNodeData" << endl;
229 
230  file << "1" << endl; // one string tag
231  file << "\"" << output_data->field_input_name() <<"\"" << endl;
232 
233  file << "1" << endl; // one real tag
234  file << time_fixed << endl; // first real tag = time
235 
236  file << "3" << endl; // 3 integer tags
237  file << this->current_step << endl; // step number (start = 0)
238  file << output_data->n_elem() << endl; // number of components
239  file << this->offsets_->n_values() << endl; // number of values
240 
241  this->write_msh_ascii_data(this->elem_ids_, output_data, true);
242 
243  file << "$EndElementNodeData" << endl;
244 }
245 
247 {
248  ofstream &file = this->_base_file;
249  double time_fixed = isfinite(this->time)?this->time:0;
250 
251  file << "$ElementData" << endl;
252 
253  file << "1" << endl; // one string tag
254  file << "\"" << output_data->field_input_name() <<"\"" << endl;
255 
256  file << "1" << endl; // one real tag
257  file << time_fixed << endl; // first real tag = time
258 
259  file << "3" << endl; // 3 integer tags
260  file << this->current_step << endl; // step number (start = 0)
261  file << output_data->n_elem() << endl; // number of components
262  file << output_data->n_values() << endl; // number of values
263 
264  this->write_msh_ascii_data(this->elem_ids_, output_data);
265 
266  file << "$EndElementData" << endl;
267 }
268 
270 {
271  LogOut() << __func__ << ": Writing output file " << this->_base_filename << " ... ";
272 
273  this->write_msh_header();
274 
275  this->write_msh_geometry();
276 
277  this->write_msh_topology();
278 
279  LogOut() << "O.K.";
280 
281  return 1;
282 }
283 
285 {
286  // Write header with mesh, when it hasn't been written to output file yet
287  if(this->header_written == false) {
288  if(this->rank == 0) {
289  this->fix_main_file_extension(".msh");
290  try {
291  this->_base_filename.open_stream( this->_base_file );
292  this->set_stream_precision(this->_base_file);
293  } INPUT_CATCH(FilePath::ExcFileOpen, FilePath::EI_Address_String, input_record_)
294  }
295 
296  this->write_head();
297  this->header_written = true;
298  }
299 
300  LogOut() << __func__ << ": Writing output file " << this->_base_filename << " ... ";
301 
302 
303  auto &node_data_list = this->output_data_vec_[NODE_DATA];
304  for(auto data_it = node_data_list.begin(); data_it != node_data_list.end(); ++data_it) {
305  write_node_data(*data_it);
306  }
307  auto &corner_data_list = this->output_data_vec_[CORNER_DATA];
308  for(auto data_it = corner_data_list.begin(); data_it != corner_data_list.end(); ++data_it) {
309  write_corner_data(*data_it);
310  }
311  auto &elem_data_list = this->output_data_vec_[ELEM_DATA];
312  for(auto data_it = elem_data_list.begin(); data_it != elem_data_list.end(); ++data_it) {
313  write_elem_data(*data_it);
314  }
315 
316  // Flush stream to be sure everything is in the file now
317  this->_base_file.flush();
318 
319  LogOut() << "O.K.";
320 
321  return 1;
322 }
323 
324 
325 
327 {
328  return 1;
329 }
330 
331 
332 
334 {
336  for (auto type_idx : space_types) {
337  auto &dummy_data_list = dummy_data_list_[type_idx];
338  auto &data_list = this->output_data_vec_[type_idx];
339 
340  // Collect all output fields
341  if (dummy_data_list.size() == 0)
342  for(auto out_ptr : data_list)
343  dummy_data_list.push_back( std::make_shared<DummyOutputData>(out_ptr->field_input_name(), out_ptr->n_elem()));
344 
345  auto data_it = data_list.begin();
346  for(auto dummy_it = dummy_data_list.begin(); dummy_it != dummy_data_list.end(); ++dummy_it) {
347  if ( data_it == data_list.end() ) {
348  data_list.push_back( *dummy_it );
349  } else if ((*dummy_it)->field_input_name() == (*data_it)->field_input_name()) {
350  ++data_it;
351  } else {
352  data_list.push_back( *dummy_it );
353  }
354  }
355  }
356 }
357 
358 
359 
360 void OutputMSH::set_output_data_caches(std::shared_ptr<OutputMeshBase> mesh_ptr) {
362 
363  mesh_ptr->create_id_caches();
364  this->node_ids_ = mesh_ptr->node_ids_;
365  this->elem_ids_ = mesh_ptr->elem_ids_;
366  this->region_ids_ = mesh_ptr->region_ids_;
367  this->partitions_ = mesh_ptr->partitions_;
368 }
369 
Classes for auxiliary output mesh.
void read_ascii_data(Tokenizer &tok, unsigned int n_components, unsigned int i_row) override
Definition: output_msh.cc:70
std::vector< std::vector< OutputDataPtr > > dummy_data_list_
Definition: output_msh.hh:90
virtual void set_output_data_caches(std::shared_ptr< OutputMeshBase > mesh_ptr)
Definition: output_time.cc:129
void print_ascii_all(ostream &out_stream) override
Definition: output_msh.cc:54
double time
Definition: output_time.hh:254
void print_ascii(ostream &out_stream, unsigned int idx) override
Definition: output_msh.cc:49
void write_msh_header(void)
This function write header of GMSH (.msh) file format.
Definition: output_msh.cc:112
static const Input::Type::Record & get_input_type()
The definition of input record for gmsh file format.
Definition: output_msh.cc:83
Input::Record input_record_
Definition: output_time.hh:264
void read_binary_data(std::istream &data_stream, unsigned int n_components, unsigned int i_row) override
Definition: output_msh.cc:73
OutputMSH()
The constructor of this class. We open the output file in first call of write_data.
Definition: output_msh.cc:94
void fix_main_file_extension(std::string extension)
Definition: output_time.cc:149
unsigned int size() const
Returns number of keys in the Record.
Definition: type_record.hh:598
std::shared_ptr< ElementDataCache< unsigned int > > connectivity_
Vector maps the nodes to their coordinates in vector nodes_.
Definition: output_time.hh:301
void write_msh_ascii_data(std::shared_ptr< ElementDataCache< unsigned int >> id_cache, OutputDataPtr output_data, bool discont=false)
This function writes ascii data to GMSH (.msh) output file.
Definition: output_msh.cc:172
std::shared_ptr< ElementDataCache< unsigned int > > offsets_
Vector of offsets of node indices of elements. Maps elements to their nodes in connectivity_.
Definition: output_time.hh:303
static const int registrar
Registrar of class to factory.
Definition: output_msh.hh:82
void write_msh_geometry(void)
This function writes geometry (position of nodes) to GMSH (.msh) file format.
Definition: output_msh.cc:122
FilePath _base_filename
Definition: output_time.hh:274
Abstract linear system class.
Definition: equation.hh:37
void write_corner_data(OutputDataPtr output_data)
writes ElementNode data ascii GMSH (.msh) output file.
Definition: output_msh.cc:223
#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:326
static Input::Type::Abstract & get_input_format_type()
The specification of output file format.
Definition: output_time.cc:64
std::shared_ptr< ElementDataCacheBase > OutputDataPtr
Definition: output_time.hh:116
std::shared_ptr< ElementDataCache< double > > nodes_
Vector of node coordinates. [spacedim x n_nodes].
Definition: output_time.hh:299
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:346
std::shared_ptr< ElementDataCache< unsigned int > > node_ids_
Vector gets ids of nodes.
Definition: output_msh.hh:149
#define LogOut()
Macro defining &#39;log&#39; record of log.
Definition: logger.hh:249
std::shared_ptr< ElementDataCache< int > > partitions_
Vector gets partitions of elements.
Definition: output_msh.hh:155
Record & close() const
Close the Record for further declarations of keys.
Definition: type_record.cc:303
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:198
DummyOutputData(std::string field_name_in, ElementDataCacheBase::NumCompValueType n_elem_in)
Definition: output_msh.cc:39
virtual Record & derive_from(Abstract &parent)
Method to derive new Record from an AbstractRecord parent.
Definition: type_record.cc:195
void open_stream(Stream &stream) const
Definition: file_path.cc:211
void add_dummy_fields() override
Complete information about dummy fields that are not in output_data_list_.
Definition: output_msh.cc:333
int current_step
Definition: output_time.hh:249
void write_msh_topology(void)
This function writes topology (connection of nodes) to the GMSH (.msh) file format.
Definition: output_msh.cc:139
static const unsigned int N_DISCRETE_SPACES
Definition: output_time.hh:97
bool header_written
Definition: output_msh.hh:84
void set_stream_precision(std::ofstream &stream)
Definition: output_time.cc:98
~OutputMSH()
The destructor of this class.
Definition: output_msh.cc:104
ofstream _base_file
Definition: output_time.hh:269
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:246
void set_output_data_caches(std::shared_ptr< OutputMeshBase > mesh_ptr) override
Definition: output_msh.cc:360
virtual ~DummyOutputData() override
Definition: output_msh.cc:46
int write_data(void)
This method writes data to GMSH (.msh) file format for current time.
Definition: output_msh.cc:284
Class OutputElement and its iterator OutputElementIterator on the output mesh.
OutputDataFieldVec output_data_vec_[N_DISCRETE_SPACES]
Definition: output_time.hh:244
bool enable_refinement_
Auxiliary flag for refinement enabling, due to gmsh format.
Definition: output_time.hh:293
std::shared_ptr< ElementDataCache< unsigned int > > elem_ids_
Vector gets ids of elements.
Definition: output_msh.hh:151
void print_all_yaml(ostream &out_stream, unsigned int precision) override
Definition: output_msh.cc:64
void print_binary_all(ostream &out_stream, bool print_data_size=true) override
Definition: output_msh.cc:59
void get_min_max_range(double &min, double &max) override
Definition: output_msh.cc:67
int write_head(void)
This method writes head of GMSH (.msh) file format.
Definition: output_msh.cc:269
#define FLOW123D_FORCE_LINK_IN_CHILD(x)
Definition: global_defs.h:180
std::shared_ptr< ElementDataCache< unsigned int > > region_ids_
Vector gets ids of regions.
Definition: output_msh.hh:153