Flow123d  release_2.1.0-84-g6a13a75
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 #include <fields/field_set.hh>
30 
31 
34 
35 
36 namespace IT = Input::Type;
37 
38 const IT::Record & OutputTime::get_input_type() {
39  return IT::Record("OutputStream", "Configuration of the spatial output of a single balance equation.")
40  // The stream
41  .declare_key("file", IT::FileName::output(), IT::Default::read_time("Name of the equation associated with the output stream."),
42  "File path to the connected output file.")
43  // The format
45  "Format of output stream and possible parameters.")
47  "Output times used for equations without is own output times key.")
49  "Output mesh record enables output on a refined mesh.")
50  .declare_key("precision", IT::Integer(0), IT::Default("5"),
51  "The number of decimal digits used in output of floating point values.")
53  "Array of observe points.")
54  .close();
55 }
56 
57 
59  return IT::Abstract("OutputTime", "Format of output stream and possible parameters.")
60  .allow_auto_conversion("vtk")
61  .close();
62 }
63 
64 
66 : current_step(0),
67  time(-1.0),
68  write_time(-1.0),
69  _mesh(nullptr)
70 {
72 }
73 
74 
75 
76 void OutputTime::init_from_input(const std::string &equation_name, Mesh &mesh, const Input::Record &in_rec)
77 {
78  _mesh = &mesh;
79 
80  input_record_ = in_rec;
81  equation_name_ = equation_name;
82 
83  // Read output base file name
84  // TODO: remove dummy ".xyz" extension after merge with DF
85  FilePath output_file_path(equation_name+"_fields", FilePath::output_file);
86  input_record_.opt_val("file", output_file_path);
87  this->_base_filename = output_file_path;
88 }
89 
90 
91 
93 {
94  /* It's possible now to do output to the file only in the first process */
95  //if(rank != 0) {
96  // /* TODO: do something, when support for Parallel VTK is added */
97  // return;
98  // }
99 
100  if (this->_base_file.is_open()) this->_base_file.close();
101 
102  LogOut() << "O.K.";
103 }
104 
105 
107  return input_record_.find<Input::Array>("times");
108 }
109 
110 
112 {
113 
114  // make observe points if not already done
115  observe();
116 
117  // already computed
118  if(output_mesh_) return;
119 
120  // Read optional error control field name
121  auto it = input_record_.find<Input::Record>("output_mesh");
122 
123  if(enable_refinement_) {
124  if(it) {
125  output_mesh_ = std::make_shared<OutputMesh>(*_mesh, *it);
126  output_mesh_discont_ = std::make_shared<OutputMeshDiscontinuous>(*_mesh, *it);
127  output_mesh_->select_error_control_field(output_fields);
128  output_mesh_discont_->select_error_control_field(output_fields);
129 
130  output_mesh_->create_refined_mesh();
131  return;
132  }
133  }
134  else
135  {
136  // skip creation of output mesh (use computational one)
137  if(it)
138  WarningOut() << "Ignoring output mesh record.\n Output in GMSH format available only on computational mesh!";
139  }
140 
141 
142  output_mesh_ = std::make_shared<OutputMesh>(*_mesh);
143  output_mesh_discont_ = std::make_shared<OutputMeshDiscontinuous>(*_mesh);
144 
145  output_mesh_->create_identical_mesh();
146 }
147 
148 
150 {
151  ASSERT_PTR(output_mesh_).error("Create output mesh first!");
152  output_mesh_discont_->create_mesh(output_mesh_);
153 }
154 
155 
156 
157 void OutputTime::fix_main_file_extension(std::string extension)
158 {
159  if(extension.compare( this->_base_filename.extension() ) != 0) {
160  string old_name = (string)this->_base_filename;
161  std::vector<string> path = {this->_base_filename.parent_path(), this->_base_filename.stem() + extension};
162  this->_base_filename = FilePath(
163  path,
165  WarningOut() << "Renaming output file: " << old_name << " to " << this->_base_filename;
166 
167  }
168 }
169 
170 
171 /* Initialize static member of the class */
172 //std::vector<OutputTime*> OutputTime::output_streams;
173 
174 
175 /*
176 void OutputTime::destroy_all(void)
177 {
178  // Delete all objects
179  for(std::vector<OutputTime*>::iterator ot_iter = OutputTime::output_streams.begin();
180  ot_iter != OutputTime::output_streams.end();
181  ++ot_iter)
182  {
183  delete *ot_iter;
184  }
185 
186  OutputTime::output_streams.clear();
187 }
188  */
189 
190 
191 std::shared_ptr<OutputTime> OutputTime::create_output_stream(const std::string &equation_name, Mesh &mesh, const Input::Record &in_rec)
192 {
193 
195  std::shared_ptr<OutputTime> output_time = format.factory< OutputTime >();
196  output_time->init_from_input(equation_name, mesh, in_rec);
197 
198  return output_time;
199 }
200 
201 
202 
203 
204 
206 {
207  START_TIMER("OutputTime::write_time_frame");
208  /* TODO: do something, when support for Parallel VTK is added */
209  if (observe_)
210  observe_->output_time_frame(time);
211 
212  if (this->rank == 0) {
213 
214  // Write data to output stream, when data registered to this output
215  // streams were changed
216  if(write_time < time) {
217 
218  LogOut() << "Write output to output stream: " << this->_base_filename << " for time: " << time;
219  write_data();
220  // Remember the last time of writing to output stream
221  write_time = time;
222  current_step++;
223 
224  // invalidate output meshes after the time frame written
225  output_mesh_.reset();
226  output_mesh_discont_.reset();
227  } else {
228  LogOut() << "Skipping output stream: " << this->_base_filename << " in time: " << time;
229  }
230  }
231  clear_data();
232 }
233 
234 std::shared_ptr<Observe> OutputTime::observe()
235 {
236  ASSERT_PTR(_mesh);
237  // create observe object at first call
238  if (! observe_) {
239  auto observe_points = input_record_.val<Input::Array>("observe_points");
240  unsigned int precision = input_record_.val<unsigned int>("precision");
241  observe_ = std::make_shared<Observe>(this->equation_name_, *_mesh, observe_points, precision);
242  }
243  return observe_;
244 }
245 
246 
248 {
249  for(auto &map : output_data_vec_) map.clear();
250 }
251 
252 
253 
254 #define INSTANCE_register_field(spacedim, value) \
255  template void OutputTime::register_data<spacedim, value> \
256  (const DiscreteSpace ref_type, Field<spacedim, value> &field);
257 
258 #define INSTANCE_register_multifield(spacedim, value) \
259  template void OutputTime::register_data<spacedim, value> \
260  (const DiscreteSpace ref_type, MultiField<spacedim, value> &field);
261 
262 
263 #define INSTANCE_OutputData(spacedim, value) \
264  template class OutputData<value>;
265 
266 
267 #define INSTANCE_DIM_DEP_VALUES( MACRO, dim_from, dim_to) \
268  MACRO(dim_from, FieldValue<dim_to>::VectorFixed ) \
269  MACRO(dim_from, FieldValue<dim_to>::TensorFixed )
270 
271 #define INSTANCE_TO_ALL( MACRO, dim_from) \
272  MACRO(dim_from, FieldValue<0>::Enum ) \
273  MACRO(dim_from, FieldValue<0>::Integer) \
274  MACRO(dim_from, FieldValue<0>::Scalar) \
275  INSTANCE_DIM_DEP_VALUES(MACRO, dim_from, 2) \
276  INSTANCE_DIM_DEP_VALUES(MACRO, dim_from, 3) \
277 
278 #define INSTANCE_ALL(MACRO) \
279  INSTANCE_TO_ALL( MACRO, 3) \
280  INSTANCE_TO_ALL( MACRO, 2)
281 
282 
285 
286 //INSTANCE_TO_ALL( INSTANCE_OutputData, 0)
287 
288 
289 //INSTANCE_register_field(3, FieldValue<0>::Scalar)
290 //INSTANCE_register_multifield(3, FieldValue<0>::Scalar)
291 //INSTANCE_OutputData(3, FieldValue<0>::Scalar)
std::shared_ptr< Observe > observe()
Definition: output_time.cc:234
Classes for auxiliary output mesh.
string stem() const
Definition: file_path.cc:193
double time
Definition: output_time.hh:208
Mesh * _mesh
Definition: output_time.hh:245
Container for various descendants of FieldCommonBase.
Definition: field_set.hh:61
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:248
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:76
Input::Record input_record_
Definition: output_time.hh:224
#define INSTANCE_register_multifield(spacedim, value)
Definition: output_time.cc:258
Accessor to input data conforming to declared Array.
Definition: accessors.hh:561
std::shared_ptr< OutputMeshDiscontinuous > output_mesh_discont_
Discontinuous (non-conforming) mesh. Used for CORNER_DATA.
Definition: output_time.hh:250
void fix_main_file_extension(std::string extension)
Definition: output_time.cc:157
#define INSTANCE_ALL(MACRO)
Definition: output_time.cc:278
Class Input::Type::Default specifies default value of keys of a Input::Type::Record.
Definition: type_record.hh:56
FilePath _base_filename
Definition: output_time.hh:234
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:58
std::shared_ptr< Observe > observe_
Definition: output_time.hh:252
static const Input::Type::Record & get_input_type()
The specification of output mesh.
Definition: output_mesh.cc:26
Definition: mesh.h:95
Iterator< Ret > find(const string &key) const
void make_output_mesh(FieldSet &output_fields)
Definition: output_time.cc:111
OutputTime()
Default constructor. Only for testing.
Definition: output_time.cc:65
Class for declaration of the integral input data.
Definition: type_base.hh:483
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:237
Record & close() const
Close the Record for further declarations of keys.
Definition: type_record.cc:301
Class for declaration of inputs sequences.
Definition: type_base.hh:339
static Default optional()
The factory function to make an empty default value which is optional.
Definition: type_record.hh:119
bool opt_val(const string &key, Ret &value) const
int current_step
Definition: output_time.hh:203
Accessor to the data with type Type::Record.
Definition: accessors.hh:286
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:92
void clear_data(void)
Clear data for output computed by method compute_field_data.
Definition: output_time.cc:247
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:488
ofstream _base_file
Definition: output_time.hh:229
The class for outputting data during time.
Definition: output_time.hh:48
Class for declaration of polymorphic Record.
Accessor to the polymorphic input data of a type given by an AbstracRecord object.
Definition: accessors.hh:453
#define MPI_Comm_rank
Definition: mpi.h:236
Dedicated class for storing path to input and output files.
Definition: file_path.hh:48
Input::Iterator< Input::Array > get_time_set_array()
Definition: output_time.cc:106
void write_time_frame()
Definition: output_time.cc:205
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:92
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:191
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR)
Definition: asserts.hh:336
virtual int write_data(void)=0
Virtual method for writing data to output file.
void compute_discontinuous_output_mesh()
Definition: output_time.cc:149
#define INSTANCE_register_field(spacedim, value)
Definition: output_time.cc:254
static const Input::Type::Array get_input_type()
OutputDataFieldVec output_data_vec_[N_DISCRETE_SPACES]
Definition: output_time.hh:198
#define WarningOut()
Macro defining &#39;warning&#39; record of log.
Definition: logger.hh:234
#define MPI_COMM_WORLD
Definition: mpi.h:123
Record type proxy class.
Definition: type_record.hh:177
bool enable_refinement_
Auxliary flag for refinement enabling, due to gmsh format.
Definition: output_time.hh:255
double write_time
Definition: output_time.hh:213
#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:508
std::string equation_name_
Definition: output_time.hh:240