Flow123d  release_1.8.2-1603-g0109a2b
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 
27 
30 
31 
32 using namespace Input::Type;
33 
34 const Record & OutputTime::get_input_type() {
35  return Record("OutputStream", "Parameters of output.")
36  // The stream
37  .declare_key("file", FileName::output(), Default::obligatory(),
38  "File path to the connected output file.")
39  // The format
40  .declare_key("format", OutputTime::get_input_format_type(), Default::optional(),
41  "Format of output stream and possible parameters.")
42  .declare_key("time_step", Double(0.0),
43  "Time interval between outputs.\n"
44  "Regular grid of output time points starts at the initial time of the equation and ends at the end time which must be specified.\n"
45  "The start time and the end time are always added. ")
46  .declare_key("time_list", Array(Double(0.0)),
47  Default::read_time("List containing the initial time of the equation. \n You can prescribe an empty list to override this behavior."),
48  "Explicit array of output time points (can be combined with 'time_step'.")
49  .declare_key("add_input_times", Bool(), Default("false"),
50  "Add all input time points of the equation, mentioned in the 'input_fields' list, also as the output points.")
51  .close();
52 }
53 
54 
56  return Abstract("OutputTime", "Format of output stream and possible parameters.")
57  .close();
58 }
59 
60 
62 : _mesh(nullptr)
63 {}
64 
65 
66 
68 : input_record_(in_rec)
69 {
70 
71  this->_base_filename = in_rec.val<FilePath>("file");
72  this->current_step = 0;
73  this->_mesh = NULL;
74  this->time = -1.0;
75  this->write_time = -1.0;
76 
77 
79 
80 }
81 
82 
83 
85 {
86  /* It's possible now to do output to the file only in the first process */
87  //if(rank != 0) {
88  // /* TODO: do something, when support for Parallel VTK is added */
89  // return;
90  // }
91 
92  if (this->_base_file.is_open()) this->_base_file.close();
93 
94  xprintf(MsgLog, "O.K.\n");
95 }
96 
97 
98 
99 
100 
101 
102 
103 void OutputTime::fix_main_file_extension(std::string extension)
104 {
105  if(this->_base_filename.compare(this->_base_filename.size()-extension.size(), extension.size(), extension) != 0) {
106  string new_name = this->_base_filename + extension;
107  xprintf(Warn, "Renaming output file: %s to %s\n",
108  this->_base_filename.c_str(), new_name.c_str());
109  this->_base_filename = new_name;
110  }
111 }
112 
113 
114 /* Initialize static member of the class */
115 //std::vector<OutputTime*> OutputTime::output_streams;
116 
117 
118 /*
119 void OutputTime::destroy_all(void)
120 {
121  // Delete all objects
122  for(std::vector<OutputTime*>::iterator ot_iter = OutputTime::output_streams.begin();
123  ot_iter != OutputTime::output_streams.end();
124  ++ot_iter)
125  {
126  delete *ot_iter;
127  }
128 
129  OutputTime::output_streams.clear();
130 }
131  */
132 
133 
134 std::shared_ptr<OutputTime> OutputTime::create_output_stream(const Input::Record &in_rec)
135 {
136  std::shared_ptr<OutputTime> output_time;
137 
139 
140  if(format) {
141  output_time = (*format).factory< OutputTime, const Input::Record & >(in_rec);
142  output_time->format_record_ = *format;
143  } else {
144  output_time = Input::Factory< OutputTime, const Input::Record & >::instance()->create("OutputVTK", in_rec);
145  }
146 
147  return output_time;
148 }
149 
150 
152 {
153  vector<Input::FullEnum> field_ids;
154  in_array.copy_to(field_ids);
155 
156  for (auto field_full_enum: field_ids) {
157  /* Setting flags to zero means use just discrete space
158  * provided as default in the field.
159  */
160  DiscreteSpaceFlags flags = 0;
161  this->output_names[(std::string)field_full_enum]=flags;
162  }
163 }
164 
165 
166 
167 
169 {
170  TimeMark::Type output_mark_type = tg.equation_fixed_mark_type() | tg.marks().type_output();
171 
172  double time_step;
173  if (input_record_.opt_val("time_step", time_step)) {
174  tg.add_time_marks_grid(time_step, output_mark_type);
175  }
176 
177  Input::Array time_list;
178  if (input_record_.opt_val("time_list", time_list)) {
180  time_list.copy_to(list);
181  for( double time : list) tg.marks().add(TimeMark(time, output_mark_type));
182  } else {
183  tg.marks().add( TimeMark(tg.init_time(), output_mark_type) );
184  }
185 
186  bool add_flag;
187  if (input_record_.opt_val("add_input_times", add_flag) && add_flag) {
188  TimeMark::Type input_mark_type = tg.equation_mark_type() | tg.marks().type_input();
189  vector<double> mark_times;
190  // can not add marks while iterating through time marks
191  for(auto it = tg.marks().begin(input_mark_type); it != tg.marks().end(input_mark_type); ++it)
192  mark_times.push_back(it->time());
193  for(double time : mark_times)
194  tg.marks().add( TimeMark(time, output_mark_type) );
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 (this->rank == 0) {
206  // Write data to output stream, when data registered to this output
207  // streams were changed
208  if(write_time < time) {
209  xprintf(MsgLog, "Write output to output stream: %s for time: %f\n",
210  this->_base_filename.c_str(), time);
211  write_data();
212  // Remember the last time of writing to output stream
213  write_time = time;
214  current_step++;
215  } else {
216  xprintf(MsgLog, "Skipping output stream: %s in time: %f\n",
217  this->_base_filename.c_str(), time);
218  }
219  }
220  clear_data();
221 }
222 
224 {
225  for(auto &map : output_data_vec_) map.clear();
226 }
227 
228 
229 
230 #define INSTANCE_register_field(spacedim, value) \
231  template void OutputTime::register_data<spacedim, value> \
232  (const DiscreteSpace ref_type, Field<spacedim, value> &field);
233 
234 #define INSTANCE_register_multifield(spacedim, value) \
235  template void OutputTime::register_data<spacedim, value> \
236  (const DiscreteSpace ref_type, MultiField<spacedim, value> &field);
237 
238 
239 #define INSTANCE_OutputData(spacedim, value) \
240  template class OutputData<value>;
241 
242 
243 #define INSTANCE_DIM_DEP_VALUES( MACRO, dim_from, dim_to) \
244  MACRO(dim_from, FieldValue<dim_to>::VectorFixed ) \
245  MACRO(dim_from, FieldValue<dim_to>::TensorFixed )
246 
247 #define INSTANCE_TO_ALL( MACRO, dim_from) \
248  MACRO(dim_from, FieldValue<0>::Enum ) \
249  MACRO(dim_from, FieldValue<0>::EnumVector) \
250  MACRO(dim_from, FieldValue<0>::Integer) \
251  MACRO(dim_from, FieldValue<0>::Scalar) \
252  MACRO(dim_from, FieldValue<0>::Vector) \
253  INSTANCE_DIM_DEP_VALUES(MACRO, dim_from, 2) \
254  INSTANCE_DIM_DEP_VALUES(MACRO, dim_from, 3) \
255 
256 #define INSTANCE_ALL(MACRO) \
257  INSTANCE_TO_ALL( MACRO, 3) \
258  INSTANCE_TO_ALL( MACRO, 2)
259 
260 
263 
264 //INSTANCE_TO_ALL( INSTANCE_OutputData, 0)
265 
266 
267 //INSTANCE_register_field(3, FieldValue<0>::Scalar)
268 //INSTANCE_register_multifield(3, FieldValue<0>::Scalar)
269 //INSTANCE_OutputData(3, FieldValue<0>::Scalar)
double time
Definition: output_time.hh:200
Mesh * _mesh
Definition: output_time.hh:232
unsigned long int Type
Definition: time_marks.hh:51
Input::Record input_record_
Definition: output_time.hh:217
#define INSTANCE_register_multifield(spacedim, value)
Definition: output_time.cc:234
Accessor to input data conforming to declared Array.
Definition: accessors.hh:552
static Input::Type::Abstract & get_input_format_type()
The specification of output file format.
Definition: output_time.cc:55
void fix_main_file_extension(std::string extension)
Definition: output_time.cc:103
TimeMarks::iterator begin(TimeMark::Type mask=TimeMark::every_type) const
Iterator for the begin mimics container-like of TimeMarks.
Definition: time_marks.cc:149
void add_admissible_field_names(const Input::Array &in_array)
Registers names of output fields that can be written using this stream.
Definition: output_time.cc:151
#define INSTANCE_ALL(MACRO)
Definition: output_time.cc:256
Class Input::Type::Default specifies default value of keys of a Input::Type::Record.
Definition: type_record.hh:50
Class for declaration of the input of type Bool.
Definition: type_base.hh:429
TimeMark::Type type_output()
Definition: time_marks.hh:190
Iterator< Ret > find(const string &key) const
OutputTime()
Default constructor. Only for testing.
Definition: output_time.cc:61
shared_ptr< Type > const create(string name, Arguments...arguments) const
create an instance of a registered class
Definition: factory_impl.hh:49
Abstract & close()
Can be used to close the Abstract for further declarations of keys.
Basic time management functionality for unsteady (and steady) solvers (class Equation).
static TimeMarks & marks()
Definition: system.hh:59
Class for declaration of inputs sequences.
Definition: type_base.hh:316
std::map< std::string, DiscreteSpaceFlags > output_names
Definition: output_time.hh:212
unsigned int DiscreteSpaceFlags
Definition: output_time.hh:211
static Factory * instance()
Get the single instance of the factory.
Definition: factory_impl.hh:27
void add(const TimeMark &mark)
Definition: time_marks.cc:74
double init_time() const
bool opt_val(const string &key, Ret &value) const
Class for declaration of the input data that are floating point numbers.
Definition: type_base.hh:513
Definition: system.hh:59
int current_step
Definition: output_time.hh:195
void add_time_marks_grid(double step, TimeMark::Type mark_type=TimeMark::none_type) const
TimeMark::Type equation_fixed_mark_type() const
Accessor to the data with type Type::Record.
Definition: accessors.hh:277
TimeMark::Type equation_mark_type() const
const Ret val(const string &key) const
#define xprintf(...)
Definition: system.hh:87
#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:84
void clear_data(void)
Clear data for output computed by method compute_field_data.
Definition: output_time.cc:223
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:459
const Record & close() const
Close the Record for further declarations of keys.
Definition: type_record.cc:271
ofstream _base_file
Definition: output_time.hh:222
The class for outputting data during time.
Definition: output_time.hh:42
void mark_output_times(const TimeGovernor &tg)
Definition: output_time.cc:168
string _base_filename
Definition: output_time.hh:227
Class for declaration of polymorphic Record.
Accessor to the polymorphic input data of a type given by an AbstracRecord object.
Definition: accessors.hh:444
static std::shared_ptr< OutputTime > create_output_stream(const Input::Record &in_rec)
This method delete all object instances of class OutputTime stored in output_streams vector...
Definition: output_time.cc:134
#define MPI_Comm_rank
Definition: mpi.h:236
Dedicated class for storing path to input and output files.
Definition: file_path.hh:42
void write_time_frame()
Definition: output_time.cc:201
void copy_to(Container &out) const
TimeMark::Type type_input()
Definition: time_marks.hh:195
virtual int write_data(void)=0
Virtual method for writing data to output file.
#define INSTANCE_register_field(spacedim, value)
Definition: output_time.cc:230
OutputDataFieldVec output_data_vec_[N_DISCRETE_SPACES]
Definition: output_time.hh:190
#define MPI_COMM_WORLD
Definition: mpi.h:123
Class used for marking specified times at which some events occur.
Definition: time_marks.hh:36
Record type proxy class.
Definition: type_record.hh:171
double write_time
Definition: output_time.hh:205
TimeMarks::iterator end(TimeMark::Type mask=TimeMark::every_type) const
Iterator for the end mimics container-like of TimeMarks.
Definition: time_marks.cc:156
#define FLOW123D_FORCE_LINK_IN_PARENT(x)
Definition: global_defs.h:247
const std::shared_ptr< Type > factory(Arguments...arguments) const