Flow123d  jenkins-Flow123d-linux-release-multijob-198
field_common.hh
Go to the documentation of this file.
1 /*
2  * field.hh
3  *
4  * Created on: Feb 13, 2014
5  * Author: jb
6  */
7 
8 #ifndef FIELD_COMMON_HH_
9 #define FIELD_COMMON_HH_
10 
11 #include <vector>
12 using namespace std;
13 
14 #include "system/exceptions.hh"
15 #include "fields/field_values.hh"
16 #include "input/accessors.hh"
17 #include "tools/time_marks.hh"
18 #include "tools/time_governor.hh"
19 
20 #include "fields/field_flag.hh"
21 #include "fields/unit_si.hh"
22 #include "io/output_time.hh"
23 
24 
25 class Region;
26 
27 namespace IT=Input::Type;
28 
29 /**
30  * Left and right time limit, used in the @p set_time() method.
31  * Assigned values allow to index an array.
32  */
33 enum class LimitSide {
34  left=0,
35  right=1,
36  unknown=2 // undefined value
37 };
38 
39 
40 
41 /**
42  * @brief Common abstract parent of all Field<...> classes.
43  *
44  * We need common ancestor in order to keep a list of all fields in one EqData object and allow
45  * collective operations like @p set_time or @p init_from_input.
46  */
47 class FieldCommon {
48 
49 public:
50  TYPEDEF_ERR_INFO(EI_Time, double);
51  TYPEDEF_ERR_INFO(EI_Field, std::string);
52  DECLARE_INPUT_EXCEPTION(ExcNonascendingTime,
53  << "Non-ascending time: " << EI_Time::val << " for field " << EI_Field::qval << ".\n");
54  DECLARE_INPUT_EXCEPTION(ExcMissingDomain,
55  << "Missing domain specification (region, r_id, or r_set) in the field descriptor:");
56  DECLARE_EXCEPTION(ExcFieldMeshDifference,
57  << "Two copies of the field " << EI_Field::qval << "call set_mesh with different arguments.\n");
58 
59 
60 
61  /**
62  * Set name of the field. In fact there are two attributes set by this method.
63  *
64  * The first is name used to identify the field as part of a FieldSet or MultiField objects.
65  * This name is permanent and can be set only by this method. Can be accessed by @p name() method.
66  * This name is also used at output.
67  *
68  * The second is @p input_name_ that determines appropriate key name in the input field descriptor.
69  * This name is also set by this method, but is stored in the internal shared space which
70  * is overwritten during call of copy_from method or assignment operator. Can be accessed by @p input_name() mathod.
71  *
72  */
73  FieldCommon &name(const string & name)
74  { name_=shared_->input_name_ = name;
75  return *this;
76  }
77  /**
78  * Set description of the field, used for description of corresponding key in documentation.
79  */
80  FieldCommon & description(const string & description)
81  { shared_->input_description_ = description; return *this;}
82  /**
83  * Set default value for the field's key from which the default constant valued field will be constructed.
84  *
85  * During the first call of the @p set_time method, we check that the field is defined on all regions.
86  * On regions where it is not set yet, we use given @p dflt string to get particular instance of
87  * FieldBase<> (see @p check_initialized_region_fields_).
88  * The default string is interpreted in the same way as if it appears in the input file
89  * as the value of the field. In particular it can be whole record with @p TYPE of the field etc.
90  * Most common choice is however mere constant.
91  */
92  FieldCommon & input_default(const string &input_default)
93  { shared_->input_default_ = input_default; return *this;}
94  /**
95  * @brief Set basic units of the field.
96  *
97  * Currently, we use it only during output and we represents units just by a string.
98  *
99  * TODO:
100  * Particular class for representing and conversion of various units would be more appropriate.
101  * This can allow specification of the units on the inptu, automatic conversion and the same on the output.
102  * Possibly this allow using Boost::Units library, however, it seems to introduce lot of boilerplate code.
103  * But can increase correctness of the calculations.
104  */
105  FieldCommon & units(const UnitSI & units)
106  { shared_->units_ = units; return *this;}
107 
108  /**
109  * For the fields returning "Enum", we have to pass the Input::Type::Selection object to
110  * the field implementations.
111  *
112  * We must save raw pointer since selection may not be yet initialized (during static initialization phase).
113  */
115  {
116  shared_->input_element_selection_=element_selection;
117  return *this;
118  }
119 
120  /**
121  * Output discrete space used in the output() method. Can be different for different field copies.
122  * one can choose between:
123  * data constant on elements, linear data given in nodes, and discontinuous linear data.
124  *
125  * If not set explicitly by this method, the default value is OutputTime::ELEM_DATA
126  */
128  { type_of_output_data_ = rt; return *this; }
129 
130  /**
131  * Set given mask to the field flags, ignoring default setting.
132  * Default setting is declare_input & equation_input & allow_output.
133  */
134  FieldCommon & flags(FieldFlag::Flags::Mask mask)
135  { flags_ = FieldFlag::Flags(mask); return *this; }
136 
137  /**
138  * Add given mask to the field flags.
139  */
140  FieldCommon & flags_add(FieldFlag::Flags::Mask mask)
141  { flags().add(mask); return *this; }
142 
143  /**
144  * Set vector of component names.
145  * Set number of components for run-time sized vectors. This is used latter when we construct
146  * objects derived from FieldBase<...>.
147  *
148  * n_comp_ is constant zero for fixed values, this zero is set by Field<...> constructors
149  */
150  void set_components(const std::vector<string> &names) {
151  shared_->comp_names_ = names;
152  shared_->n_comp_ = (shared_->n_comp_ ? names.size() : 0);
153  }
154 
155 
156  /**
157  * Set internal mesh pointer.
158  */
159  virtual void set_mesh(const Mesh &mesh) {};
160  /**
161  * Set the data list from which field will read its input. It is list of "field descriptors".
162  * When reading from the input list we consider only field descriptors containing key of
163  * named by the field name. These field descriptors has to have times forming ascending sequence.
164  *
165  * The list is used by set_time method to set field on individual regions to actual FieldBase descendants.
166  */
167  void set_input_list(const Input::Array &list);
168 
169  /**
170  * Set side of limit when calling @p set_time
171  * with jump time, i.e. time where the field change implementation on some region.
172  * Wee assume that implementations prescribe only smooth fields.
173  * This method invalidate result of
174  * @p changed() so it should be called just before @p set_time.
175  * Can be different for different field copies.
176  */
178  { this->limit_side_=side; }
179 
180  /**
181  * Getters.
182  */
183  const std::string &input_name() const
184  { return shared_->input_name_;}
185 
186  const std::string &name() const
187  { return name_;}
188 
189  const std::string description() const
190  {return shared_->input_description_;}
191 
192  const std::string &input_default() const
193  { return shared_->input_default_;}
194 
195  const UnitSI &units() const
196  { return shared_->units_;}
197 
199  { return type_of_output_data_; }
200 
201  bool is_bc() const
202  { return shared_->bc_;}
203 
204  unsigned int n_comp() const
205  { return shared_->n_comp_;}
206 
207  const Mesh * mesh() const
208  { return shared_->mesh_;}
209 
211  { return limit_side_;}
212 
214  { return flags_; }
215 
216  /**
217  * Returns time set by last call of set_time method.
218  * Can be different for different field copies.
219  */
220  double time() const
221  { return last_time_; }
222 
223 
224  /**
225  * Common part of the field descriptor. To get finished record
226  * one has to add keys for individual fields. This is done automatically
227  * using FieldSet::get_input_type().
228  */
229  static IT::Record field_descriptor_record(const string& record_name);
230 
231  /**
232  * Returns input type for particular field instance, this is reference to a static member input_type of the corresponding @p FieldBase
233  * class (i.e. with the same template parameters). This is used in FieldSet::make_field_descriptor_type.
234  */
235  virtual IT::AbstractRecord &get_input_type() =0;
236 
237  /**
238  * Returns input type for MultiField instance.
239  * TODO: temporary solution, see @p multifield_
240  */
241  virtual IT::Record &get_multifield_input_type() =0;
242 
243  /**
244  * Pass through the input array @p input_list_, collect all times where the field could change and
245  * put appropriate time marks into global TimeMarks object.
246  * Introduced time marks have both given @p mark_type and @p type_input() type.
247  *
248  * Further development:
249  * - we have to distinguish "jump" times and "smooth" times
250  */
251  void mark_input_times(TimeMark::Type mark_type);
252 
253  /**
254  * Abstract method to update field to the new time level.
255  * Implemented by in class template Field<...>.
256  *
257  * Return true if the value of the field was changed on some region.
258  * The returned value is also stored in @p changed_during_set_time data member.
259  *
260  * Default values helps when creating steady field. Note that default TimeGovernor constructor
261  * set time to 0.0.
262  *
263  * Different field copies can be set to different times.
264  */
265  virtual bool set_time(const TimeStep &time) =0;
266 
267  /**
268  * Check that @p other is instance of the same Field<..> class and
269  * perform assignment. Polymorphic copy.
270  */
271  virtual void copy_from(const FieldCommon & other) =0;
272 
273  /**
274  * Output the field.
275  * The parameter @p output_fields is checked for value named by the field name. If the key exists,
276  * then the output of the field is performed. If the key do not appear in the input, no output is done.
277  */
278  virtual void output(OutputTime *stream) =0;
279 
280 
281  /**
282  * If the field on given region @p reg exists and is of type FieldConstant<...> the method method returns true
283  * otherwise it returns false.
284  * Then one call ElementAccessor<spacedim>(mesh(), reg ) to construct an ElementAccessor @p elm
285  * pointing to "virtual" element on which Field::value returns constant value.
286  *
287  * Current implementation use virtual functions and can be prohibitively slow if called for every element. If this
288  * becomes necessary it is possible to incorporate such test into set_time method and in this method just return precomputed result.
289  */
290  virtual bool is_constant(Region reg) =0;
291 
292  /**
293  * Returns true if set_time_result_ is not @p TimeStatus::constant.
294  * Returns the same value as last set_time method.
295  */
296  bool changed() const
297  {
298  ASSERT( set_time_result_ != TimeStatus::unknown, "Invalid time status.\n");
299  return ( (set_time_result_ == TimeStatus::changed) );
300  }
301 
302  /**
303  * Sets @p component_index_
304  */
305  void set_component_index(unsigned int idx)
306  {
307  this->component_index_ = idx;
308  }
309 
310  /**
311  * Return @p multifield_ flag.
312  * TODO: temporary solution
313  */
314  inline bool is_multifield() const
315  {
316  return this->multifield_;
317  }
318 
319  /**
320  * Virtual destructor.
321  */
322  virtual ~FieldCommon();
323 
324 
325 protected:
326  /**
327  * Private default constructor. Should be used only through
328  * Field<...>
329  */
330  FieldCommon();
331 
332  /**
333  * Private copy constructor. Should be used only through
334  * Field<...>
335  */
336  FieldCommon(const FieldCommon & other);
337 
338  /**
339  * Invalidate last time in order to force set_time method
340  * update region_fields_.
341  */
343  {
344  last_time_ = -numeric_limits<double>::infinity();
345  }
346 
347  /**
348  * Setters for essential field properties.
349  */
350  /**
351  * Data shared among copies of the same field.
352  *
353  * This allow field copies in different equations with different time setting, but
354  * sharing common input field descriptor array and common history.
355  */
356  struct SharedData {
357  /**
358  * Empty constructor.
359  */
361 
362  /**
363  * True for boundary fields.
364  */
365  bool bc_;
366  /**
367  * Number of components for fields that return variable size vectors. Zero in other cases.
368  */
369  unsigned int n_comp_;
370  /**
371  * Names of field components.
372  */
374  /**
375  * Name of the particular field. Used to name the key in the Field list Record.
376  */
377  std::string input_name_;
378  /**
379  * Description of corresponding key in the Field list Record.
380  */
381  std::string input_description_;
382  /**
383  * Units of the field values. Currently just a string description.
384  */
386  /**
387  * For Enum valued fields this is the input type selection that should be used
388  * to read possible values of the field (e.g. for FieldConstant the key 'value' has this selection input type).
389  *
390  * Is empty selection for for non-enum values fields.
391  *
392  * In fact we must use raw pointer since selection may not be constructed yet (static variable).
393  */
395  /**
396  * Possible default value of the field.
397  */
399  /**
400  * Pointer to the mesh on which the field lives.
401  */
402  const Mesh *mesh_;
403 
404  /**
405  * List of input field descriptors from which the field is set.
406  */
408 
409  /**
410  * Iterator to current input field descriptor.
411  */
413 
414  /**
415  * True after check_initialized_region_fields_ is called. That happen at first call of the set_time method.
416  */
418 
419  /**
420  * For which values of an enum valued field we do not
421  * check the field. User is responsible, that the value will not be called
422  * on such regions.
423  */
425 
426 
427  };
428 
429  /**
430  * Name that identifies the field in the field_set. By default this is same as
431  * shared_->input_name_.
432  */
433  std::string name_;
434 
435  /**
436  * Data shared among copies of the same input field.
437  */
438  std::shared_ptr<SharedData> shared_;
439 
440  /**
441  * Which value is returned for times where field is discontinuous.
442  */
444 
445  /**
446  * Result of last set time method
447  */
448  enum class TimeStatus {
449  changed, //< Field changed during last set time call.
450  constant, //< Field doesn't change.
451  unknown //< Before first call of set_time.
452  };
453 
454  /// Status of @p history.
456 
457  /**
458  * Last set time. Can be different for different field copies.
459  */
460  double last_time_ = -numeric_limits<double>::infinity();
461 
462  /**
463  * Output data type used in the output() method. Can be different for different field copies.
464  */
466 
467  /**
468  * Specify if the field is part of a MultiField and which component it is
469  */
470  unsigned int component_index_;
471 
472  /**
473  * Flag determining if object is Multifield or Field.
474  * TODO: temporary solution, goal is to make these two classes to behave similarly
475  */
477 
478  /**
479  * Maximum number of FieldBase objects we store per one region.
480  */
481  static const unsigned int history_length_limit_=3;
482 
483  /// Field flags. Default setting is "an equation input field, that can read from user input, and can be written to output"
485 
486  /**
487  * Stream output operator
488  */
489  friend std::ostream &operator<<(std::ostream &stream, const FieldCommon &field) {
490 
491  string limit_side_str =
492  (field.limit_side_ == LimitSide::left ? "left" :
493  (field.limit_side_ == LimitSide::right ? "right" :
494  "unknown"));
495 
496  stream
497  << "field name:" << field.name()
498  << " limit side:" << limit_side_str
499  << " n. comp.:" << field.n_comp()
500  << " last time:" << field.last_time_;
501  return stream;
502  }
503 };
504 
505 
506 
507 
508 
509 
510 
511 #endif /* FIELD_COMMON_HH_ */
virtual void set_mesh(const Mesh &mesh)
std::string input_description_
Common abstract parent of all Field&lt;...&gt; classes.
Definition: field_common.hh:47
unsigned long int Type
Definition: time_marks.hh:64
void set_limit_side(LimitSide side)
Accessor to input data conforming to declared Array.
Definition: accessors.hh:558
static constexpr Mask allow_output
The field can output. Is part of generated output selection. (default on)
Definition: field_flag.hh:27
FieldCommon & flags_add(FieldFlag::Flags::Mask mask)
std::string name_
#define DECLARE_EXCEPTION(ExcName, Format)
Macro for simple definition of exceptions.
Definition: exceptions.hh:135
LimitSide limit_side_
unsigned int component_index_
Definition: mesh.h:109
double last_time_
const std::string & input_default() const
FieldCommon & units(const UnitSI &units)
Set basic units of the field.
const std::string description() const
Basic time management class.
std::shared_ptr< SharedData > shared_
OutputTime::DiscreteSpace output_type() const
double time() const
friend std::ostream & operator<<(std::ostream &stream, const FieldCommon &field)
#define ASSERT(...)
Definition: global_defs.h:121
const std::string & name() const
FieldFlag::Flags & flags()
FieldCommon & input_default(const string &input_default)
Definition: field_common.hh:92
const UnitSI & units() const
FieldCommon & input_selection(const Input::Type::Selection *element_selection)
const IT::Selection * input_element_selection_
Class for declaration of polymorphic Record.
Definition: type_record.hh:487
Input::Iterator< Input::Record > list_it_
bool is_multifield() const
#define TYPEDEF_ERR_INFO(EI_Type, Type)
Macro to simplify declaration of error_info types.
Definition: exceptions.hh:171
The class for outputting data during time.
Definition: output_time.hh:32
std::vector< FieldEnum > no_check_values_
FieldCommon & description(const string &description)
Definition: field_common.hh:80
void set_component_index(unsigned int idx)
LimitSide limit_side() const
const Mesh * mesh() const
FieldCommon & name(const string &name)
Definition: field_common.hh:73
unsigned int n_comp() const
DECLARE_INPUT_EXCEPTION(ExcFV_Input,<< "Wrong field value input: "<< EI_InputMsg::val)
bool changed() const
void set_components(const std::vector< string > &names)
Record type proxy class.
Definition: type_record.hh:169
void set_history_changed()
FlagArray< FieldFlag > Flags
Definition: field_flag.hh:16
FieldCommon & flags(FieldFlag::Flags::Mask mask)
const std::string & input_name() const
static constexpr Mask equation_input
The field is data parameter of the owning equation. (default on)
Definition: field_flag.hh:23
Class for representation SI units of Fields.
Definition: unit_si.hh:31
bool is_bc() const
Representation of one time step.
TimeStatus set_time_result_
Status of history.
Template for classes storing finite set of named values.
LimitSide
Definition: field_common.hh:33
FieldCommon & output_type(OutputTime::DiscreteSpace rt)
static constexpr Mask declare_input
The field can be set from input. The key in input field descriptor is declared. (default on) ...
Definition: field_flag.hh:25
std::vector< std::string > comp_names_