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