Flow123d  release_2.2.0-914-gf1a3a4f
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 [EXPERIMENTAL, VTK only]."
51  "Sofar refinement is performed only in discontinous sense."
52  "Therefore only corner and element data can be written on refined output mesh."
53  "Node data are to be transformed to corner data, native data cannot be written."
54  "Do not include any node or native data in output fields.")
55  .declare_key("precision", IT::Integer(0), IT::Default(default_prec.str()),
56  "The number of decimal digits used in output of floating point values.\\ "
57  "Default is about 17 decimal digits which is enough to keep double values exect after write-read cycle.")
59  "Array of observe points.")
60  .close();
61 }
62 
63 
65  return IT::Abstract("OutputTime", "Format of output stream and possible parameters.")
66  .allow_auto_conversion("vtk")
67  .close();
68 }
69 
70 
72 : current_step(0),
73  time(-1.0),
74  write_time(-1.0),
75  parallel_(false)
76 {
79 }
80 
81 
82 
83 void OutputTime::init_from_input(const std::string &equation_name, const Input::Record &in_rec)
84 {
85 
86  input_record_ = in_rec;
87  equation_name_ = equation_name;
88 
89  // Read output base file name
90  // TODO: remove dummy ".xyz" extension after merge with DF
91  FilePath output_file_path(equation_name+"_fields", FilePath::output_file);
92  input_record_.opt_val("file", output_file_path);
93  this->precision_ = input_record_.val<int>("precision");
94  this->_base_filename = output_file_path;
95 }
96 
97 
98 void OutputTime::set_stream_precision(std::ofstream &stream)
99 {
100  //stream.setf(std::ios::scientific);
101  stream.precision(this->precision_);
102 }
103 
104 
106 {
107  /* It's possible now to do output to the file only in the first process */
108  //if(rank != 0) {
109  // /* TODO: do something, when support for Parallel VTK is added */
110  // return;
111  // }
112 
113  if (this->_base_file.is_open()) this->_base_file.close();
114 
115  LogOut() << "O.K.";
116 }
117 
118 
120  return input_record_.find<Input::Array>("times");
121 }
122 
123 
125  return input_record_.find<Input::Record>("output_mesh");
126 }
127 
128 
129 void OutputTime::set_output_data_caches(std::shared_ptr<OutputMeshBase> mesh_ptr) {
130  this->nodes_ = mesh_ptr->nodes_;
131  this->connectivity_ = mesh_ptr->connectivity_;
132  this->offsets_ = mesh_ptr->offsets_;
133  output_mesh_ = mesh_ptr;
134 }
135 
136 
137 std::shared_ptr<OutputMeshBase> OutputTime::get_output_mesh_ptr() {
138  return output_mesh_;
139 }
140 
141 
142 void OutputTime::update_time(double field_time) {
143  if (this->time < field_time) {
144  this->time = field_time;
145  }
146 }
147 
148 
149 void OutputTime::fix_main_file_extension(std::string extension)
150 {
151  if(extension.compare( this->_base_filename.extension() ) != 0) {
152  string old_name = (string)this->_base_filename;
153  std::vector<string> path = {this->_base_filename.parent_path(), this->_base_filename.stem() + extension};
154  this->_base_filename = FilePath(
155  path,
157  WarningOut() << "Renaming output file: " << old_name << " to " << this->_base_filename;
158 
159  }
160 }
161 
162 
163 /* Initialize static member of the class */
164 //std::vector<OutputTime*> OutputTime::output_streams;
165 
166 
167 /*
168 void OutputTime::destroy_all(void)
169 {
170  // Delete all objects
171  for(std::vector<OutputTime*>::iterator ot_iter = OutputTime::output_streams.begin();
172  ot_iter != OutputTime::output_streams.end();
173  ++ot_iter)
174  {
175  delete *ot_iter;
176  }
177 
178  OutputTime::output_streams.clear();
179 }
180  */
181 
182 
183 std::shared_ptr<OutputTime> OutputTime::create_output_stream(const std::string &equation_name, const Input::Record &in_rec)
184 {
185 
187  std::shared_ptr<OutputTime> output_time = format.factory< OutputTime >();
188  output_time->init_from_input(equation_name, in_rec);
189 
190  return output_time;
191 }
192 
193 
194 
195 
196 
198 {
199  START_TIMER("OutputTime::write_time_frame");
200  if (observe_)
201  observe_->output_time_frame(time);
202 
203  if (this->rank == 0 || this->parallel_) {
204 
205  // Write data to output stream, when data registered to this output
206  // streams were changed
207  if(write_time < time) {
208 
209  LogOut() << "Write output to output stream: " << this->_base_filename << " for time: " << time;
210  write_data();
211  // Remember the last time of writing to output stream
212  write_time = time;
213  current_step++;
214 
215  // invalidate output data caches after the time frame written
216  // TODO we need invalidate pointers only in special cases (e. g. refining of mesh)
217  /*output_mesh_.reset();
218  this->nodes_.reset();
219  this->connectivity_.reset();
220  this->offsets_.reset();*/
221  } else {
222  LogOut() << "Skipping output stream: " << this->_base_filename << " in time: " << time;
223  }
224  }
225  clear_data();
226 }
227 
228 std::shared_ptr<Observe> OutputTime::observe(Mesh *mesh)
229 {
230  // create observe object at first call
231  if (! observe_) {
232  auto observe_points = input_record_.val<Input::Array>("observe_points");
233  unsigned int precision = input_record_.val<unsigned int>("precision");
234  observe_ = std::make_shared<Observe>(this->equation_name_, *mesh, observe_points, precision);
235  }
236  return observe_;
237 }
238 
239 
241 {
242  for(auto &map : output_data_vec_) map.clear();
243 }
244 
245 
247 {
248  if (parallel_) return n_proc*current_step+rank;
249  else return current_step;
250 }
251 
252 
254 {}
255 
256 
257 
258 // explicit instantiation of template methods
259 #define OUTPUT_PREPARE_COMPUTE_DATA(TYPE) \
260 template ElementDataCache<TYPE> & OutputTime::prepare_compute_data<TYPE>(std::string field_name, DiscreteSpace space_type, \
261  unsigned int n_rows, unsigned int n_cols)
262 
264 OUTPUT_PREPARE_COMPUTE_DATA(unsigned int);
266 
Classes for auxiliary output mesh.
virtual void set_output_data_caches(std::shared_ptr< OutputMeshBase > mesh_ptr)
Definition: output_time.cc:129
string stem() const
Definition: file_path.cc:193
double time
Definition: output_time.hh:254
Abstract & allow_auto_conversion(const string &type_default)
Allows shorter input of the Abstract providing the default value to the "TYPE" key.
Input::Record input_record_
Definition: output_time.hh:264
Accessor to input data conforming to declared Array.
Definition: accessors.hh:567
void fix_main_file_extension(std::string extension)
Definition: output_time.cc:149
static std::shared_ptr< OutputTime > create_output_stream(const std::string &equation_name, const Input::Record &in_rec)
This method delete all object instances of class OutputTime stored in output_streams vector...
Definition: output_time.cc:183
std::shared_ptr< ElementDataCache< unsigned int > > connectivity_
Vector maps the nodes to their coordinates in vector nodes_.
Definition: output_time.hh:301
std::shared_ptr< OutputMeshBase > output_mesh_
Output mesh.
Definition: output_time.hh:288
Class Input::Type::Default specifies default value of keys of a Input::Type::Record.
Definition: type_record.hh:61
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
FilePath _base_filename
Definition: output_time.hh:274
Abstract linear system class.
Definition: equation.hh:37
static const Input::Type::Record & get_input_type()
Definition: observe.cc:107
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:64
std::shared_ptr< OutputMeshBase > get_output_mesh_ptr()
Definition: output_time.cc:137
std::shared_ptr< Observe > observe_
Definition: output_time.hh:290
void update_time(double field_time)
Definition: output_time.cc:142
static const Input::Type::Record & get_input_type()
The specification of output mesh.
Definition: output_mesh.cc:27
Definition: mesh.h:99
Iterator< Ret > find(const string &key) const
#define OUTPUT_PREPARE_COMPUTE_DATA(TYPE)
Definition: output_time.cc:259
OutputTime()
Default constructor. Only for testing.
Definition: output_time.cc:71
std::shared_ptr< ElementDataCache< double > > nodes_
Vector of node coordinates. [spacedim x n_nodes].
Definition: output_time.hh:299
std::shared_ptr< Observe > observe(Mesh *mesh)
Definition: output_time.cc:228
virtual void init_from_input(const std::string &equation_name, const Input::Record &in_rec)
Constructor of OutputTime object. It opens base file for writing.
Definition: output_time.cc:83
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:249
Record & close() const
Close the Record for further declarations of keys.
Definition: type_record.cc:303
int get_parallel_current_step()
Return unique value current step for parallel or serial output.
Definition: output_time.cc:246
Class for declaration of inputs sequences.
Definition: type_base.hh:345
bool parallel_
Parallel or serial version of file format (parallel has effect only for VTK)
Definition: output_time.hh:296
static Default optional()
The factory function to make an empty default value which is optional.
Definition: type_record.hh:124
virtual void add_dummy_fields()
Complete information about dummy fields, method has effect only for GMSH output.
Definition: output_time.cc:253
bool opt_val(const string &key, Ret &value) const
int current_step
Definition: output_time.hh:249
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:105
void clear_data(void)
Clear data for output computed by method compute_field_data.
Definition: output_time.cc:240
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
void set_stream_precision(std::ofstream &stream)
Definition: output_time.cc:98
ofstream _base_file
Definition: output_time.hh:269
The class for outputting data during time.
Definition: output_time.hh:44
Class for declaration of polymorphic Record.
#define MPI_Comm_size
Definition: mpi.h:235
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:119
void write_time_frame()
Definition: output_time.cc:197
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
Input::Iterator< Input::Record > get_output_mesh_record()
Definition: output_time.cc:124
virtual int write_data(void)=0
Virtual method for writing data to output file.
static const Input::Type::Array get_input_type()
OutputDataFieldVec output_data_vec_[N_DISCRETE_SPACES]
Definition: output_time.hh:244
#define WarningOut()
Macro defining &#39;warning&#39; record of log.
Definition: logger.hh:246
#define MPI_COMM_WORLD
Definition: mpi.h:123
Record type proxy class.
Definition: type_record.hh:182
double write_time
Definition: output_time.hh:259
#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:280