Flow123d  JS_before_hm-989-g79825ac
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/unit_si.hh"
25 
26 
28 
29 
30 using namespace Input::Type;
31 
32 
33 const Record & OutputMSH::get_input_type() {
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 
50 
51 
52 }
53 
55 {
56  this->write_tail();
57 }
58 
59 
60 
61 
63 {
64  ofstream &file = this->_base_file;
65 
66  // Write simple header
67  file << "$MeshFormat" << endl;
68  file << "2" << " 0 " << sizeof(double) << endl;
69  file << "$EndMeshFormat" << endl;
70 }
71 
73 {
74  ofstream &file = this->_base_file;
75 
76  // Write information about nodes
77  file << "$Nodes" << endl;
78  file << this->nodes_->n_values() << endl;
79  auto &id_node_vec = *( this->node_ids_->get_component_data(0).get() );
80  for(unsigned int i_node=0; i_node < id_node_vec.size(); ++i_node) {
81  file << id_node_vec[i_node] << " ";
82  this->nodes_->print_ascii(file, i_node);
83  file << endl;
84  }
85  file << "$EndNodes" << endl;
86 }
87 
89 {
90  ofstream &file = this->_base_file;
91  const static unsigned int gmsh_simplex_types_[4] = {0, 1, 2, 4};
92  auto &id_elem_vec = *( this->elem_ids_->get_component_data(0).get() );
93  auto &id_node_vec = *( this->node_ids_->get_component_data(0).get() );
94  auto &connectivity_vec = *( this->connectivity_->get_component_data(0).get() );
95  auto &offsets_vec = *( this->offsets_->get_component_data(0).get() );
96  auto &regions_vec = *( this->region_ids_->get_component_data(0).get() );
97  auto &partition_vec = *( this->partitions_->get_component_data(0).get() );
98 
99  unsigned int n_nodes, i_node=0;
100 
101  // Write information about elements
102  file << "$Elements" << endl;
103  file << this->offsets_->n_values() << endl;
105  for(unsigned int i_elm=0; i_elm < id_elem_vec.size(); ++i_elm) {
106  n_nodes = (i_elm==0) ? (offsets_vec[0]) : (offsets_vec[i_elm]-offsets_vec[i_elm-1]);
107  // element_id element_type 3_other_tags material region partition
108  file << id_elem_vec[i_elm]
109  << " " << gmsh_simplex_types_[ n_nodes-1 ]
110  << " 3 " << regions_vec[i_elm] << " " << regions_vec[i_elm] << " " << partition_vec[i_elm];
111 
112  for(unsigned int i=0; i<n_nodes; i++, i_node++) {
113  file << " " << id_node_vec[connectivity_vec[i_node]];
114  }
115  file << endl;
116  }
117  file << "$EndElements" << endl;
118 }
119 
120 
121 void OutputMSH::write_msh_ascii_data(std::shared_ptr<ElementDataCache<unsigned int>> id_cache, OutputDataPtr output_data, bool discont)
122 {
123  ofstream &file = this->_base_file;
124  auto &id_vec = *( id_cache->get_component_data(0).get() );
125 
126  if (discont) { // corner data
127  auto &offsets_vec = *( this->offsets_->get_component_data(0).get() );
128  unsigned int n_nodes, i_corner=0;
129  for(unsigned int i=0; i < id_vec.size(); ++i) {
130  n_nodes = (i==0) ? (offsets_vec[0]) : (offsets_vec[i]-offsets_vec[i-1]);
131  file << id_vec[i] << " " << n_nodes << " ";
132  for (unsigned int j=0; j<n_nodes; j++)
133  output_data->print_ascii(file, i_corner++);
134  file << std::endl;
135  }
136  } else { // element / node data
137  for(unsigned int i=0; i < output_data->n_values(); ++i) {
138  file << id_vec[i] << " ";
139  output_data->print_ascii(file, i);
140  file << std::endl;
141  }
142 
143  }
144 }
145 
146 
148 {
149  ofstream &file = this->_base_file;
150  double time_fixed = isfinite(this->time)?this->time:0;
151  time_fixed /= UnitSI().s().convert_unit_from(this->unit_string_);
152 
153  file << "$NodeData" << endl;
154 
155  file << "1" << endl; // one string tag
156  file << "\"" << output_data->field_input_name() <<"\"" << endl;
157 
158  file << "1" << endl; // one real tag
159  file << time_fixed << endl; // first real tag = time
160 
161  file << "3" << endl; // 3 integer tags
162  file << this->current_step << endl; // step number (start = 0)
163  file << output_data->n_comp() << endl; // number of components
164  file << output_data->n_values() << endl; // number of values
165 
166  this->write_msh_ascii_data(this->node_ids_, output_data);
167 
168  file << "$EndNodeData" << endl;
169 }
170 
171 
173 {
174  ofstream &file = this->_base_file;
175  double time_fixed = isfinite(this->time)?this->time:0;
176 
177  file << "$ElementNodeData" << endl;
178 
179  file << "1" << endl; // one string tag
180  file << "\"" << output_data->field_input_name() <<"\"" << endl;
181 
182  file << "1" << endl; // one real tag
183  file << time_fixed << endl; // first real tag = time
184 
185  file << "3" << endl; // 3 integer tags
186  file << this->current_step << endl; // step number (start = 0)
187  file << output_data->n_comp() << endl; // number of components
188  file << this->offsets_->n_values() << endl; // number of values
189 
190  this->write_msh_ascii_data(this->elem_ids_, output_data, true);
191 
192  file << "$EndElementNodeData" << endl;
193 }
194 
196 {
197  ofstream &file = this->_base_file;
198  double time_fixed = isfinite(this->time)?this->time:0;
199 
200  file << "$ElementData" << endl;
201 
202  file << "1" << endl; // one string tag
203  file << "\"" << output_data->field_input_name() <<"\"" << endl;
204 
205  file << "1" << endl; // one real tag
206  file << time_fixed << endl; // first real tag = time
207 
208  file << "3" << endl; // 3 integer tags
209  file << this->current_step << endl; // step number (start = 0)
210  file << output_data->n_comp() << endl; // number of components
211  file << output_data->n_values() << endl; // number of values
212 
213  this->write_msh_ascii_data(this->elem_ids_, output_data);
214 
215  file << "$EndElementData" << endl;
216 }
217 
219 {
220  LogOut() << __func__ << ": Writing output file " << this->_base_filename << " ... ";
221 
222  this->write_msh_header();
223 
224  this->write_msh_geometry();
225 
226  this->write_msh_topology();
227 
228  LogOut() << "O.K.";
229 
230  return 1;
231 }
232 
234 {
235  /* Output of serial format is implemented only in the first process */
236  if (this->rank_ != 0) {
237  return 0;
238  }
239 
240  // Write header with mesh, when it hasn't been written to output file yet
241  if(this->header_written == false) {
242  this->fix_main_file_extension(".msh");
243  try {
244  this->_base_filename.open_stream( this->_base_file );
245  this->set_stream_precision(this->_base_file);
246  } INPUT_CATCH(FilePath::ExcFileOpen, FilePath::EI_Address_String, input_record_)
247 
248  this->write_head();
249  this->header_written = true;
250  }
251 
252  LogOut() << __func__ << ": Writing output file " << this->_base_filename << " ... ";
253 
254 
255  auto &node_data_list = this->output_data_vec_[NODE_DATA];
256  for(auto data_it = node_data_list.begin(); data_it != node_data_list.end(); ++data_it) {
257  write_node_data(*data_it);
258  }
259  auto &corner_data_list = this->output_data_vec_[CORNER_DATA];
260  for(auto data_it = corner_data_list.begin(); data_it != corner_data_list.end(); ++data_it) {
261  write_corner_data(*data_it);
262  }
263  auto &elem_data_list = this->output_data_vec_[ELEM_DATA];
264  for(auto data_it = elem_data_list.begin(); data_it != elem_data_list.end(); ++data_it) {
265  write_elem_data(*data_it);
266  }
267 
268  // Flush stream to be sure everything is in the file now
269  this->_base_file.flush();
270 
271  LogOut() << "O.K.";
272 
273  return 1;
274 }
275 
276 
277 
279 {
280  return 1;
281 }
282 
283 
284 void OutputMSH::set_output_data_caches(std::shared_ptr<OutputMeshBase> mesh_ptr) {
286 
287  mesh_ptr->get_master_mesh()->create_id_caches();
288  this->node_ids_ = mesh_ptr->get_master_mesh()->node_ids_;
289  this->elem_ids_ = mesh_ptr->get_master_mesh()->elem_ids_;
290  this->region_ids_ = mesh_ptr->get_master_mesh()->region_ids_;
291  this->partitions_ = mesh_ptr->get_master_mesh()->partitions_;
292 }
293 
Classes for auxiliary output mesh.
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:130
double time
Definition: output_time.hh:275
void write_msh_header(void)
This function write header of GMSH (.msh) file format.
Definition: output_msh.cc:62
static const Input::Type::Record & get_input_type()
The definition of input record for gmsh file format.
Definition: output_msh.cc:33
Input::Record input_record_
Definition: output_time.hh:285
OutputMSH()
The constructor of this class. We open the output file in first call of write_data.
Definition: output_msh.cc:44
void fix_main_file_extension(std::string extension)
Definition: output_time.cc:150
unsigned int size() const
Returns number of keys in the Record.
Definition: type_record.hh:602
std::shared_ptr< ElementDataCache< unsigned int > > connectivity_
Vector maps the nodes to their coordinates in vector nodes_.
Definition: output_time.hh:325
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:121
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:327
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:72
FilePath _base_filename
Definition: output_time.hh:295
double convert_unit_from(std::string actual_unit) const
Convert and check user-defined unit.
Definition: unit_si.cc:217
Abstract linear system class.
Definition: balance.hh:40
void write_corner_data(OutputDataPtr output_data)
writes ElementNode data ascii GMSH (.msh) output file.
Definition: output_msh.cc:172
#define INPUT_CATCH(ExceptionType, AddressEITag, input_accessor)
Definition: accessors.hh:63
int write_tail(void)
This method should write tail of GMSH (.msh) file format.
Definition: output_msh.cc:278
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:122
std::shared_ptr< ElementDataCache< double > > nodes_
Vector of node coordinates. [spacedim x n_nodes].
Definition: output_time.hh:323
std::shared_ptr< ElementDataCache< unsigned int > > node_ids_
Vector gets ids of nodes.
Definition: output_msh.hh:148
#define LogOut()
Macro defining &#39;log&#39; record of log.
Definition: logger.hh:261
std::shared_ptr< ElementDataCache< int > > partitions_
Vector gets partitions of elements.
Definition: output_msh.hh:154
Record & close() const
Close the Record for further declarations of keys.
Definition: type_record.cc:304
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:147
virtual Record & derive_from(Abstract &parent)
Method to derive new Record from an AbstractRecord parent.
Definition: type_record.cc:196
void open_stream(Stream &stream) const
Definition: file_path.cc:211
int current_step
Definition: output_time.hh:270
void write_msh_topology(void)
This function writes topology (connection of nodes) to the GMSH (.msh) file format.
Definition: output_msh.cc:88
UnitSI & s(int exp=1)
Definition: unit_si.cc:76
static const unsigned int N_DISCRETE_SPACES
Definition: output_time.hh:103
bool header_written
Definition: output_msh.hh:84
void set_stream_precision(std::ofstream &stream)
Definition: output_time.cc:99
string unit_string_
String representation of time unit.
Definition: output_time.hh:320
~OutputMSH()
The destructor of this class.
Definition: output_msh.cc:54
ofstream _base_file
Definition: output_time.hh:290
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:195
void set_output_data_caches(std::shared_ptr< OutputMeshBase > mesh_ptr) override
Definition: output_msh.cc:284
int write_data(void)
This method writes data to GMSH (.msh) file format for current time.
Definition: output_msh.cc:233
Class OutputElement and its iterator OutputElementIterator on the output mesh.
OutputDataFieldVec output_data_vec_[N_DISCRETE_SPACES]
Definition: output_time.hh:265
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:314
std::shared_ptr< ElementDataCache< unsigned int > > elem_ids_
Vector gets ids of elements.
Definition: output_msh.hh:150
Class for representation SI units of Fields.
Definition: unit_si.hh:40
This class is used for output data to VTK file format.
Definition: output_msh.hh:30
int write_head(void)
This method writes head of GMSH (.msh) file format.
Definition: output_msh.cc:218
#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:152