Flow123d  release_2.2.0-48-gb04af7f
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  "File format of the output stream and possible parameters.")
48  "Output times used for fields that do not have their own output times defined.")
50  "Output mesh record enables output on a refined mesh. [Not impemented]")
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.\n"
53  "Default is 17 decimal digits which are necessary to reproduce double values exactly 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