Flow123d  release_2.2.0-23-g01927c6
equation_output.cc
Go to the documentation of this file.
1 /*
2  * equation_output.cc
3  *
4  * Created on: Jul 8, 2016
5  * Author: jb
6  */
7 
8 #include "tools/time_marks.hh"
9 #include "input/input_type.hh"
10 #include "input/accessors.hh"
12 #include "io/output_time_set.hh"
13 #include "io/output_mesh.hh"
15 #include <memory>
16 
17 
18 namespace IT = Input::Type;
19 
20 
21 
23 
24  static const IT::Record &field_output_setting =
25  IT::Record("FieldOutputSetting", "Setting of the field output. The field name, output times, output interpolation (future).")
26  .allow_auto_conversion("field")
27  .declare_key("field", IT::Parameter("output_field_selection"), IT::Default::obligatory(),
28  "The field name (from selection).")
30  "Output times specific to particular field.")
31  //.declare_key("interpolation", ...)
32  .close();
33 
34  return IT::Record("EquationOutput",
35  "Output of the equation's fields."
36  "The output is done through the output stream of the associated balance law equation."
37  "The stream defines output format for the full space information in selected times and "
38  "observe points for the full time information. The key 'fields' select the fields for the full spatial output."
39  "The set of output times may be specified per field otherwise common time set 'times' is used. If even this is not provided"
40  "the time set of the output_stream is used. The initial time of the equation is automatically added "
41  "to the time set of every selected field. The end time of the equation is automatically added "
42  "to the common output time set.")
45  "Output times used for the output fields without is own time series specification.")
46  .declare_key("add_input_times", IT::Bool(), IT::Default("false"),
47  "Add all input time points of the equation, mentioned in the 'input_fields' list, also as the output points.")
48  .declare_key("fields", IT::Array(field_output_setting), IT::Default("[]"),
49  "Array of output fields and their individual output settings.")
50  .declare_key("observe_fields", IT::Array( IT::Parameter("output_field_selection")), IT::Default("[]"),
51  "Array of the fields evaluated in the observe points of the associated output stream.")
52  .close();
53 }
54 
55 
56 
57 const IT::Instance &EquationOutput::make_output_type(const string &equation_name, const string &additional_description)
58 {
59  string selection_name = equation_name + ":OutputFields";
60  string description = "Selection of output fields for the " + equation_name + " model.\n" + additional_description;
61  IT::Selection sel(selection_name, description );
62  int i=0;
63  // add value for each field excluding boundary fields
64  for( FieldCommon * field : field_list)
65  {
66  //DebugOut().fmt("type for field: {}\n", field->name());
67  if ( !field->is_bc() && field->flags().match( FieldFlag::allow_output) )
68  {
69  string desc = "(($[" + field->units().format_latex()+"]$)) "; + "Output of: the field " + field->name() + " ";
71  desc += "Input field: ";
72  if (field->description().length() > 0)
73  desc += field->description();
75  i++;
76  }
77  }
78 
79  const IT::Selection &output_field_selection = sel.close();
80 
82  param_vec.push_back( std::make_pair("output_field_selection", std::make_shared< IT::Selection >(output_field_selection) ) );
83  return IT::Instance(get_input_type(), param_vec).close();
84 
85 }
86 
87 
88 void EquationOutput::initialize(std::shared_ptr<OutputTime> stream, Input::Record in_rec, const TimeGovernor & tg)
89 {
90  stream_ = stream;
93  read_from_input(in_rec, tg);
94 }
95 
96 
97 
99 {
100  ASSERT(stream_).error("The 'set_stream' method must be called before the 'read_from_input'.");
101  auto &marks = TimeGovernor::marks();
102 
103  Input::Array times_array;
104  if (in_rec.opt_val("times", times_array) ) {
105  common_output_times_.read_from_input(times_array, tg);
106  } else {
107  // take times from the output_stream if key times is missing
108  auto times_array_it = stream_->get_time_set_array();
109  if (times_array_it) {
110  common_output_times_.read_from_input(*times_array_it, tg);
111  }
112  }
113  // always add the end time
115 
116  if (in_rec.val<bool>("add_input_times")) {
117  // copy time marks in order to prevent invalidation of the iterator
118  TimeMarks marks_copy = TimeGovernor::marks();
119  for(auto time_mark_it = marks_copy.begin(equation_type_ | marks.type_input());
120  time_mark_it != marks_copy.end(equation_type_ | marks.type_input());
121  ++time_mark_it) {
122  common_output_times_.add(time_mark_it->time(), equation_fixed_type_);
123  }
124  }
125  auto fields_array = in_rec.val<Input::Array>("fields");
126  for(auto it = fields_array.begin<Input::Record>(); it != fields_array.end(); ++it) {
127  string field_name = it -> val< Input::FullEnum >("field");
128  Input::Array field_times_array;
129  if (it->opt_val("times", field_times_array)) {
130  OutputTimeSet field_times;
131  field_times.read_from_input(field_times_array, tg);
132  field_output_times_[field_name] = field_times;
133  } else {
135  }
136  // Add init time as the output time for every output field.
137  field_output_times_[field_name].add(tg.init_time(), equation_fixed_type_);
138  }
139  auto observe_fields_array = in_rec.val<Input::Array>("observe_fields");
140  for(auto it = observe_fields_array.begin<Input::FullEnum>(); it != observe_fields_array.end(); ++it) {
141  observe_fields_.insert(string(*it));
142  }
143 }
144 
146 {
147  auto &marks = TimeGovernor::marks();
148  auto field_times_it = field_output_times_.find(field.name());
149  if (field_times_it == field_output_times_.end()) return false;
150  ASSERT( step.eq(field.time()) )(step.end())(field.time())(field.name()).error("Field is not set to the output time.");
151  auto current_mark_it = marks.current(step, equation_type_ | marks.type_output() );
152  if (current_mark_it == marks.end(equation_type_ | marks.type_output()) ) return false;
153  return (field_times_it->second.contains(*current_mark_it) );
154 }
155 
157 {
158  // TODO: remove const_cast after resolving problems with const Mesh.
159  //Mesh *field_mesh = const_cast<Mesh *>(field_list[0]->mesh());
160  this->make_output_mesh();
161 
162  for(FieldCommon * field : this->field_list) {
163 
164  if ( field->flags().match( FieldFlag::allow_output) ) {
165  if (is_field_output_time(*field, step)) {
167  }
168  // observe output
169  if (observe_fields_.find(field->name()) != observe_fields_.end()) {
170  field->observe_output( stream_->observe() );
171  }
172  }
173  }
174 }
175 
176 
177 void EquationOutput::add_output_times(double begin, double step, double end)
178 {
179  common_output_times_.add(begin,step, end, equation_fixed_type_ );
180 }
181 
182 
184 {
185  // make observe points if not already done
186  stream_->observe();
187 
188  // already computed
189  if (stream_->is_output_mesh_init()) return;
190 
191  // Read optional error control field name
192  auto it = stream_->get_output_mesh_record();
193 
194  if(stream_->enable_refinement()) {
195  if(it) {
196  auto output_mesh = stream_->create_output_mesh_ptr(true);
197  auto output_mesh_discont = stream_->create_output_mesh_ptr(true, true);
198  //TODO solve setting of error_control_field
199  this->select_error_control_field( output_mesh->error_control_field_name() );
200  this->select_error_control_field( output_mesh_discont->error_control_field_name() );
201 
202  output_mesh->create_refined_mesh();
203  return;
204  }
205  }
206  else
207  {
208  // skip creation of output mesh (use computational one)
209  if(it)
210  WarningOut() << "Ignoring output mesh record.\n Output in GMSH format available only on computational mesh!";
211  }
212 
213 
214  std::shared_ptr<OutputMesh> output_mesh = std::dynamic_pointer_cast<OutputMesh>( stream_->create_output_mesh_ptr(false) );
215  stream_->create_output_mesh_ptr(false, true);
216 
217  output_mesh->create_identical_mesh();
218 }
219 
220 
221 void EquationOutput::select_error_control_field(std::string error_control_field_name)
222 {
223  if(error_control_field_name!="")
224  {
225  FieldCommon* field = this->field(error_control_field_name);
226  // throw input exception if the field is unknown
227  if(field == nullptr){
228  THROW(FieldSet::ExcUnknownField()
229  << FieldCommon::EI_Field(error_control_field_name));
230  //<< input_record_.ei_address());
231  return;
232  }
233 
234  // throw input exception if the field is not scalar
235  if( typeid(*field) == typeid(Field<3,FieldValue<3>::Scalar>) ) {
236 
238  DebugOut() << "Output mesh will be refined according to field " << error_control_field_name << ".";
239  }
240  else{
241  THROW(ExcFieldNotScalar()
242  << FieldCommon::EI_Field(error_control_field_name));
243  //<< input_record_.ei_address());
244  }
245  }
246  else
247  {
248  error_control_field_ = nullptr;
249  }
250 }
Class represents output mesh with continuous elements.
Definition: output_mesh.hh:127
virtual void field_output(std::shared_ptr< OutputTime > stream)=0
Classes for auxiliary output mesh.
std::vector< FieldCommon * > field_list
List of all fields.
Definition: field_set.hh:243
void add_output_times(double begin, double step, double end)
Common abstract parent of all Field<...> classes.
Definition: field_common.hh:60
std::unordered_set< string > observe_fields_
Set of observed fields. The observe points are given within the observe stream.
Accessor to input data conforming to declared Array.
Definition: accessors.hh:567
double end_time() const
End time.
static constexpr Mask allow_output
The field can output. Is part of generated output selection. (default on)
Definition: field_flag.hh:37
Class Input::Type::Default specifies default value of keys of a Input::Type::Record.
Definition: type_record.hh:61
Class for declaration of the input of type Bool.
Definition: type_base.hh:458
void output(TimeStep step)
Class template representing a field with values dependent on: point, element, and region...
Definition: field.hh:62
const Instance & close() const
Used for set Instance to TypeRepository.
TimeMarks::iterator begin(TimeMark::Type mask) const
Iterator for the begin mimics container-like of TimeMarks.
Definition: time_marks.cc:192
static Default obligatory()
The factory function to make an empty default value which is obligatory.
Definition: type_record.hh:110
virtual std::string get_value_attribute() const =0
Class for representing parametric types in IST.
Definition: type_generic.hh:53
void initialize(std::shared_ptr< OutputTime > stream, Input::Record in_rec, const TimeGovernor &tg)
TimeMark::Type equation_fixed_type_
The fixed time mark type of the equation.
Helper class that stores data of generic types.
Definition: type_generic.hh:89
void read_from_input(Input::Array in_array, const TimeGovernor &tg)
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:346
Basic time management functionality for unsteady (and steady) solvers (class Equation).
FieldCommon & units(const UnitSI &units)
Set basic units of the field.
Field< 3, FieldValue< 3 >::Scalar > * error_control_field_
Refinement error control field.
static TimeMarks & marks()
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
double init_time() const
bool opt_val(const string &key, Ret &value) const
void read_from_input(Input::Record in_rec, const TimeGovernor &tg)
double time() const
FieldCommon * field(const std::string &field_name) const
Definition: field_set.cc:132
virtual Record & allow_auto_conversion(const string &from_key)
Allows shorter input of the Record providing only value of the from_key given as the parameter...
Definition: type_record.cc:132
TimeMark::Type equation_fixed_mark_type() const
Accessor to the data with type Type::Record.
Definition: accessors.hh:292
TimeMark::Type equation_mark_type() const
const Ret val(const string &key) const
virtual Record & root_of_generic_subtree()
Definition: type_record.cc:419
Selection & add_value(const int value, const std::string &key, const std::string &description="", TypeBase::attribute_map attributes=TypeBase::attribute_map())
Adds one new value with name given by key to the Selection.
static string field_value_shape()
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< OutputTime > stream_
output stream (may be shared by more equation)
double end() const
This class is a collection of time marks to manage various events occurring during simulation time...
Definition: time_marks.hh:197
std::unordered_map< string, OutputTimeSet > field_output_times_
Time sets of individual fields.
void select_error_control_field(std::string error_control_field_name)
Selects the error control field out of output field set according to input record.
FieldCommon & description(const string &description)
const Selection & close() const
Close the Selection, no more values can be added.
static Input::Type::Record & get_input_type()
static const Input::Type::Array get_input_type()
TimeMarks::iterator end(TimeMark::Type mask) const
Iterator for the end mimics container-like of TimeMarks.
Definition: time_marks.cc:206
#define WarningOut()
Macro defining &#39;warning&#39; record of log.
Definition: logger.hh:236
FieldCommon & name(const string &name)
Definition: field_common.hh:97
virtual void observe_output(std::shared_ptr< Observe > observe)=0
Record type proxy class.
Definition: type_record.hh:182
bool is_field_output_time(const FieldCommon &field, TimeStep step) const
const Input::Type::Instance & make_output_type(const string &equation_name, const string &aditional_description="")
FieldCommon & flags(FieldFlag::Flags::Mask mask)
OutputTimeSet common_output_times_
The time set used for the fields without explicit time set.
static constexpr Mask equation_input
The field is data parameter of the owning equation. (default on)
Definition: field_flag.hh:33
bool is_bc() const
#define DebugOut()
Macro defining &#39;debug&#39; record of log.
Definition: logger.hh:242
TimeMark::Type equation_type_
The time mark type of the equation.
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:53
Representation of one time step..
Template for classes storing finite set of named values.
bool eq(double other_time) const
void add(double begin, TimeMark::Type mark_type)