Flow123d  last_with_con_2.0.0-4-g42e6930
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", "Parameters of output.")
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 new_name = (string)this->_base_filename + extension;
161  WarningOut() << "Renaming output file: " << this->_base_filename << " to " << new_name;
162  this->_base_filename = new_name;
163  }
164 }
165 
166 
167 /* Initialize static member of the class */
168 //std::vector<OutputTime*> OutputTime::output_streams;
169 
170 
171 /*
172 void OutputTime::destroy_all(void)
173 {
174  // Delete all objects
175  for(std::vector<OutputTime*>::iterator ot_iter = OutputTime::output_streams.begin();
176  ot_iter != OutputTime::output_streams.end();
177  ++ot_iter)
178  {
179  delete *ot_iter;
180  }
181 
182  OutputTime::output_streams.clear();
183 }
184  */
185 
186 
187 std::shared_ptr<OutputTime> OutputTime::create_output_stream(const std::string &equation_name, Mesh &mesh, const Input::Record &in_rec)
188 {
189 
191  std::shared_ptr<OutputTime> output_time = format.factory< OutputTime >();
192  output_time->init_from_input(equation_name, mesh, in_rec);
193 
194  return output_time;
195 }
196 
197 
198 
199 
200 
202 {
203  START_TIMER("OutputTime::write_time_frame");
204  /* TODO: do something, when support for Parallel VTK is added */
205  if (observe_)
206  observe_->output_time_frame(time);
207 
208  if (this->rank == 0) {
209 
210  // Write data to output stream, when data registered to this output
211  // streams were changed
212  if(write_time < time) {
213 
214  LogOut() << "Write output to output stream: " << this->_base_filename << " for time: " << time;
215  write_data();
216  // Remember the last time of writing to output stream
217  write_time = time;
218  current_step++;
219 
220  // invalidate output meshes after the time frame written
221  output_mesh_.reset();
222  output_mesh_discont_.reset();
223  } else {
224  LogOut() << "Skipping output stream: " << this->_base_filename << " in time: " << time;
225  }
226  }
227  clear_data();
228 }
229 
230 std::shared_ptr<Observe> OutputTime::observe()
231 {
232  ASSERT_PTR(_mesh);
233  // create observe object at first call
234  if (! observe_) {
235  auto observe_points = input_record_.val<Input::Array>("observe_points");
236  unsigned int precision = input_record_.val<unsigned int>("precision");
237  observe_ = std::make_shared<Observe>(this->equation_name_, *_mesh, observe_points, precision);
238  }
239  return observe_;
240 }
241 
242 
244 {
245  for(auto &map : output_data_vec_) map.clear();
246 }
247 
248 
249 
250 #define INSTANCE_register_field(spacedim, value) \
251  template void OutputTime::register_data<spacedim, value> \
252  (const DiscreteSpace ref_type, Field<spacedim, value> &field);
253 
254 #define INSTANCE_register_multifield(spacedim, value) \
255  template void OutputTime::register_data<spacedim, value> \
256  (const DiscreteSpace ref_type, MultiField<spacedim, value> &field);
257 
258 
259 #define INSTANCE_OutputData(spacedim, value) \
260  template class OutputData<value>;
261 
262 
263 #define INSTANCE_DIM_DEP_VALUES( MACRO, dim_from, dim_to) \
264  MACRO(dim_from, FieldValue<dim_to>::VectorFixed ) \
265  MACRO(dim_from, FieldValue<dim_to>::TensorFixed )
266 
267 #define INSTANCE_TO_ALL( MACRO, dim_from) \
268  MACRO(dim_from, FieldValue<0>::Enum ) \
269  MACRO(dim_from, FieldValue<0>::Integer) \
270  MACRO(dim_from, FieldValue<0>::Scalar) \
271  INSTANCE_DIM_DEP_VALUES(MACRO, dim_from, 2) \
272  INSTANCE_DIM_DEP_VALUES(MACRO, dim_from, 3) \
273 
274 #define INSTANCE_ALL(MACRO) \
275  INSTANCE_TO_ALL( MACRO, 3) \
276  INSTANCE_TO_ALL( MACRO, 2)
277 
278 
281 
282 //INSTANCE_TO_ALL( INSTANCE_OutputData, 0)
283 
284 
285 //INSTANCE_register_field(3, FieldValue<0>::Scalar)
286 //INSTANCE_register_multifield(3, FieldValue<0>::Scalar)
287 //INSTANCE_OutputData(3, FieldValue<0>::Scalar)
std::shared_ptr< Observe > observe()
Definition: output_time.cc:230
Classes for auxiliary output mesh.
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
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:254
Accessor to input data conforming to declared Array.
Definition: accessors.hh:552
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:274
Class Input::Type::Default specifies default value of keys of a Input::Type::Record.
Definition: type_record.hh:50
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:465
Abstract & close()
Can be used to close the Abstract for further declarations of keys.
#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:286
Class for declaration of inputs sequences.
Definition: type_base.hh:321
static Default optional()
The factory function to make an empty default value which is optional.
Definition: type_record.hh:113
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:277
const Ret val(const string &key) const
#define START_TIMER(tag)
Starts a timer with specified tag.
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:243
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:468
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:444
#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:201
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:86
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:187
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR)
Definition: asserts.hh:336
static FileName output()
The factory function for declaring type FileName for input files.
Definition: type_base.hh:612
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:250
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:171
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:181
const std::shared_ptr< Type > factory(Arguments...arguments) const
std::string equation_name_
Definition: output_time.hh:240