Flow123d  release_2.2.0-23-g01927c6
output_time.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.cc
15  * @brief The functions for all outputs (methods of classes: Output and OutputTime).
16  */
17 
18 #include <string>
19 
20 #include "system/sys_profiler.hh"
21 #include "mesh/mesh.h"
22 #include "input/accessors.hh"
23 #include "output_time.impl.hh"
24 #include "output_vtk.hh"
25 #include "output_msh.hh"
26 #include "output_mesh.hh"
27 #include "io/output_time_set.hh"
28 #include "io/observe.hh"
29 
30 
33 
34 
35 namespace IT = Input::Type;
36 
37 const IT::Record & OutputTime::get_input_type() {
38  stringstream default_prec;
39  default_prec << std::numeric_limits<double>::max_digits10;
40  return IT::Record("OutputStream", "Configuration of the spatial output of a single balance equation.")
41  // The stream
42  .declare_key("file", IT::FileName::output(), IT::Default::read_time("Name of the equation associated with the output stream."),
43  "File path to the connected output file.")
44  // The format
46  "Format of output stream and possible parameters.")
48  "Output times used for equations without is own output times key.")
50  "Output mesh record enables output on a refined mesh.")
51  .declare_key("precision", IT::Integer(0), IT::Default(default_prec.str()),
52  "The number of decimal digits used in output of floating point values.\\ "
53  "Default is about 17 decimal digits which is enough to keep double values exect after write-read cycle.")
55  "Array of observe points.")
56  .close();
57 }
58 
59 
61  return IT::Abstract("OutputTime", "Format of output stream and possible parameters.")
62  .allow_auto_conversion("vtk")
63  .close();
64 }
65 
66 
68 : current_step(0),
69  time(-1.0),
70  write_time(-1.0),
71  _mesh(nullptr)
72 {
74 }
75 
76 
77 
78 void OutputTime::init_from_input(const std::string &equation_name, Mesh &mesh, const Input::Record &in_rec)
79 {
80  _mesh = &mesh;
81 
82  input_record_ = in_rec;
83  equation_name_ = equation_name;
84 
85  // Read output base file name
86  // TODO: remove dummy ".xyz" extension after merge with DF
87  FilePath output_file_path(equation_name+"_fields", FilePath::output_file);
88  input_record_.opt_val("file", output_file_path);
89  this->precision_ = input_record_.val<int>("precision");
90  this->_base_filename = output_file_path;
91 }
92 
93 
94 void OutputTime::set_stream_precision(std::ofstream &stream)
95 {
96  //stream.setf(std::ios::scientific);
97  stream.precision(this->precision_);
98 }
99 
100 
102 {
103  /* It's possible now to do output to the file only in the first process */
104  //if(rank != 0) {
105  // /* TODO: do something, when support for Parallel VTK is added */
106  // return;
107  // }
108 
109  if (this->_base_file.is_open()) this->_base_file.close();
110 
111  LogOut() << "O.K.";
112 }
113 
114 
116  return input_record_.find<Input::Array>("times");
117 }
118 
119 
121  return input_record_.find<Input::Record>("output_mesh");
122 }
123 
124 
125 std::shared_ptr<OutputMeshBase> OutputTime::create_output_mesh_ptr(bool init_input, bool discont) {
126  if (discont) {
127  if (init_input) output_mesh_discont_ = std::make_shared<OutputMeshDiscontinuous>(*_mesh, *this->get_output_mesh_record());
128  else output_mesh_discont_ = std::make_shared<OutputMeshDiscontinuous>(*_mesh);
129  return output_mesh_discont_;
130  } else {
131  if (init_input) output_mesh_ = std::make_shared<OutputMesh>(*_mesh, *this->get_output_mesh_record());
132  else output_mesh_ = std::make_shared<OutputMesh>(*_mesh);
133  return output_mesh_;
134  }
135 }
136 
137 
138 std::shared_ptr<OutputMeshBase> OutputTime::get_output_mesh_ptr(bool discont) {
139  if (discont) {
140  return output_mesh_discont_;
141  } else {
142  return output_mesh_;
143  }
144 }
145 
146 
147 void OutputTime::update_time(double field_time) {
148  if (this->time < field_time) {
149  this->time = field_time;
150  }
151 }
152 
153 
155 {
156  ASSERT_PTR(output_mesh_).error("Create output mesh first!");
157  output_mesh_discont_->create_mesh(output_mesh_);
158 }
159 
160 
161 
162 void OutputTime::fix_main_file_extension(std::string extension)
163 {
164  if(extension.compare( this->_base_filename.extension() ) != 0) {
165  string old_name = (string)this->_base_filename;
166  std::vector<string> path = {this->_base_filename.parent_path(), this->_base_filename.stem() + extension};
167  this->_base_filename = FilePath(
168  path,
170  WarningOut() << "Renaming output file: " << old_name << " to " << this->_base_filename;
171 
172  }
173 }
174 
175 
176 /* Initialize static member of the class */
177 //std::vector<OutputTime*> OutputTime::output_streams;
178 
179 
180 /*
181 void OutputTime::destroy_all(void)
182 {
183  // Delete all objects
184  for(std::vector<OutputTime*>::iterator ot_iter = OutputTime::output_streams.begin();
185  ot_iter != OutputTime::output_streams.end();
186  ++ot_iter)
187  {
188  delete *ot_iter;
189  }
190 
191  OutputTime::output_streams.clear();
192 }
193  */
194 
195 
196 std::shared_ptr<OutputTime> OutputTime::create_output_stream(const std::string &equation_name, Mesh &mesh, const Input::Record &in_rec)
197 {
198 
200  std::shared_ptr<OutputTime> output_time = format.factory< OutputTime >();
201  output_time->init_from_input(equation_name, mesh, in_rec);
202 
203  return output_time;
204 }
205 
206 
207 
208 
209 
211 {
212  START_TIMER("OutputTime::write_time_frame");
213  /* TODO: do something, when support for Parallel VTK is added */
214  if (observe_)
215  observe_->output_time_frame(time);
216 
217  if (this->rank == 0) {
218 
219  // Write data to output stream, when data registered to this output
220  // streams were changed
221  if(write_time < time) {
222 
223  LogOut() << "Write output to output stream: " << this->_base_filename << " for time: " << time;
224  write_data();
225  // Remember the last time of writing to output stream
226  write_time = time;
227  current_step++;
228 
229  // invalidate output meshes after the time frame written
230  output_mesh_.reset();
231  output_mesh_discont_.reset();
232  } else {
233  LogOut() << "Skipping output stream: " << this->_base_filename << " in time: " << time;
234  }
235  }
236  clear_data();
237 }
238 
239 std::shared_ptr<Observe> OutputTime::observe()
240 {
241  ASSERT_PTR(_mesh);
242  // create observe object at first call
243  if (! observe_) {
244  auto observe_points = input_record_.val<Input::Array>("observe_points");
245  unsigned int precision = input_record_.val<unsigned int>("precision");
246  observe_ = std::make_shared<Observe>(this->equation_name_, *_mesh, observe_points, precision);
247  }
248  return observe_;
249 }
250 
251 
253 {
254  for(auto &map : output_data_vec_) map.clear();
255 }
256 
257 
258 
259 // explicit instantiation of template methods
260 #define OUTPUT_PREPARE_COMPUTE_DATA(TYPE) \
261 template ElementDataCache<TYPE> & OutputTime::prepare_compute_data<TYPE>(std::string field_name, DiscreteSpace space_type, \
262  unsigned int n_rows, unsigned int n_cols)
263 
265 OUTPUT_PREPARE_COMPUTE_DATA(unsigned int);
267 
std::shared_ptr< Observe > observe()
Definition: output_time.cc:239
Classes for auxiliary output mesh.
string stem() const
Definition: file_path.cc:193
double time
Definition: output_time.hh:228
Mesh * _mesh
Definition: output_time.hh:264
Abstract & allow_auto_conversion(const string &type_default)
Allows shorter input of the Abstract providing the default value to the "TYPE" key.
std::shared_ptr< OutputMesh > output_mesh_
Output mesh.
Definition: output_time.hh:267
virtual void init_from_input(const std::string &equation_name, Mesh &mesh, const Input::Record &in_rec)
Constructor of OutputTime object. It opens base file for writing.
Definition: output_time.cc:78
Input::Record input_record_
Definition: output_time.hh:238
Accessor to input data conforming to declared Array.
Definition: accessors.hh:567
std::shared_ptr< OutputMeshDiscontinuous > output_mesh_discont_
Discontinuous (non-conforming) mesh. Used for CORNER_DATA.
Definition: output_time.hh:269
void fix_main_file_extension(std::string extension)
Definition: output_time.cc:162
Class Input::Type::Default specifies default value of keys of a Input::Type::Record.
Definition: type_record.hh:61
FilePath _base_filename
Definition: output_time.hh:248
static const Input::Type::Record & get_input_type()
Definition: observe.cc:29
std::string format(CStringRef format_str, ArgList args)
Definition: format.h:3141
static Input::Type::Abstract & get_input_format_type()
The specification of output file format.
Definition: output_time.cc:60
std::shared_ptr< Observe > observe_
Definition: output_time.hh:271
void update_time(double field_time)
Definition: output_time.cc:147
static const Input::Type::Record & get_input_type()
The specification of output mesh.
Definition: output_mesh.cc:24
Definition: mesh.h:97
Iterator< Ret > find(const string &key) const
#define OUTPUT_PREPARE_COMPUTE_DATA(TYPE)
Definition: output_time.cc:260
OutputTime()
Default constructor. Only for testing.
Definition: output_time.cc:67
Class for declaration of the integral input data.
Definition: type_base.hh:489
Abstract & close()
Close the Abstract and add its to type repository (see TypeRepository::add_type). ...
#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
Class for declaration of inputs sequences.
Definition: type_base.hh:345
static Default optional()
The factory function to make an empty default value which is optional.
Definition: type_record.hh:124
bool opt_val(const string &key, Ret &value) const
int current_step
Definition: output_time.hh:223
Accessor to the data with type Type::Record.
Definition: accessors.hh:292
const Ret val(const string &key) const
#define START_TIMER(tag)
Starts a timer with specified tag.
string parent_path() const
Definition: file_path.cc:183
virtual ~OutputTime()
Destructor of OutputTime. It doesn&#39;t do anything, because all necessary destructors will be called in...
Definition: output_time.cc:101
void clear_data(void)
Clear data for output computed by method compute_field_data.
Definition: output_time.cc:252
Record & declare_key(const string &key, std::shared_ptr< TypeBase > type, const Default &default_value, const string &description, TypeBase::attribute_map key_attributes=TypeBase::attribute_map())
Declares a new key of the Record.
Definition: type_record.cc:490
std::shared_ptr< OutputMeshBase > get_output_mesh_ptr(bool discont=false)
Definition: output_time.cc:138
void set_stream_precision(std::ofstream &stream)
Definition: output_time.cc:94
ofstream _base_file
Definition: output_time.hh:243
The class for outputting data during time.
Definition: output_time.hh:44
Class for declaration of polymorphic Record.
Accessor to the polymorphic input data of a type given by an AbstracRecord object.
Definition: accessors.hh:459
#define MPI_Comm_rank
Definition: mpi.h:236
Dedicated class for storing path to input and output files.
Definition: file_path.hh:54
Input::Iterator< Input::Array > get_time_set_array()
Definition: output_time.cc:115
void write_time_frame()
Definition: output_time.cc:210
static Default read_time(const std::string &description)
The factory function to make an default value that will be specified at the time when a key will be r...
Definition: type_record.hh:97
static std::shared_ptr< OutputTime > create_output_stream(const std::string &equation_name, Mesh &mesh, const Input::Record &in_rec)
This method delete all object instances of class OutputTime stored in output_streams vector...
Definition: output_time.cc:196
Input::Iterator< Input::Record > get_output_mesh_record()
Definition: output_time.cc:120
std::shared_ptr< OutputMeshBase > create_output_mesh_ptr(bool init_input, bool discont=false)
Definition: output_time.cc:125
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR)
Definition: asserts.hh:335
virtual int write_data(void)=0
Virtual method for writing data to output file.
void compute_discontinuous_output_mesh()
Definition: output_time.cc:154
static const Input::Type::Array get_input_type()
OutputDataFieldVec output_data_vec_[N_DISCRETE_SPACES]
Definition: output_time.hh:218
#define WarningOut()
Macro defining &#39;warning&#39; record of log.
Definition: logger.hh:236
#define MPI_COMM_WORLD
Definition: mpi.h:123
Record type proxy class.
Definition: type_record.hh:182
double write_time
Definition: output_time.hh:233
#define FLOW123D_FORCE_LINK_IN_PARENT(x)
Definition: global_defs.h:183
const std::shared_ptr< Type > factory(Arguments...arguments) const
static FileName output()
The factory function for declaring type FileName for input files.
Definition: type_base.cc:533
std::string equation_name_
Definition: output_time.hh:254