Flow123d  master-ad1076ca0
field_set.hh
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 field_set.hh
15  * @brief
16  */
17 
18 #ifndef FIELD_SET_HH_
19 #define FIELD_SET_HH_
20 
21 
22 #include <iosfwd> // for ostream
23 #include <string> // for string
24 #include <vector> // for vector
25 #include "fields/field_common.hh" // for FieldCommon, FieldCommon::EI_Field
26 #include "fields/field_flag.hh" // for FieldFlag, FieldFlag::Flags
27 #include "fields/eval_subset.hh" // for EvalSubset
28 #include "fields/eval_points.hh" // for EvalPoints
30 #include "fields/field.hh"
31 #include "fields/field_coords.hh" // for FieldCoords
32 #include "fields/field_depth.hh" // for FieldDepth
33 #include "fields/surface_depth.hh" // for SurfaceDepth
34 #include "mesh/range_wrapper.hh"
36 #include "input/accessors.hh" // for Array
37 #include "input/type_record.hh" // for Record
38 #include "io/output_time.hh" // for OutputTime, OutputTime::DiscreteSpace
39 #include "system/exceptions.hh" // for ExcStream, operator<<, DECLARE_EXC...
40 #include "system/flag_array.hh" // for FlagArray<>::Mask
41 #include "tools/time_governor.hh" // for TimeGovernor (ptr only), TimeStep
42 class Mesh;
43 class Region;
44 template <int spacedim, class Value> class FieldFormula;
45 
46 
47 
48 /**
49  * Accessor to vector of Fields holds in FieldSet.
50  *
51  * Class holds position to vector and allows iterate through all instances of Field class
52  * and all components (SubFields) of MultiFields.
53  *
54  * Base methods:
55  * - inc() - increment to next Field instance:
56  * Field - iterates to next item in field list
57  * MultiFields - iterates to next component of MultiField or if actual position is last component
58  * jumps to next item in field list
59  * - operator ->() - returns pointer to actual Field.
60  */
62 public:
63  /// Default constructor
66 
67  /// Constructor
70 
71  /// Iterates to next Field.
72  inline void inc() {
73  if (field_list_[field_idx_]->is_multifield()) {
75  if (field_component_idx_ == field_list_[field_idx_]->n_comp()) {
76  field_idx_++;
78  }
79  } else {
80  field_idx_++;
81  }
82  }
83 
84  /// Getter for field_idx_
85  inline unsigned int field_idx() const {
86  return field_idx_;
87  }
88 
89  /// Getter for field_component_idx_
90  inline unsigned int field_component_idx() const {
91  return field_component_idx_;
92  }
93 
94  /// Returns pointer to actual field held by accessor
95  FieldCommon * field() const {
96  if (field_list_[field_idx_]->is_multifield())
97  return field_list_[field_idx_]->get_component(field_component_idx_);
98  else
99  return field_list_[field_idx_];
100  }
101 
102  /// Comparison of accessors.
103  inline bool operator ==(const FieldListAccessor &other) {
104  return this->field_idx_ == other.field_idx_ && field_component_idx_ == other.field_component_idx_;
105  }
106 
107  inline bool operator !=(const FieldListAccessor &other) const {
108  return this->field_idx_ != other.field_idx_ || field_component_idx_ != other.field_component_idx_;
109  }
110 
111  /// Dereference operator simplify access to actual field held by accessor
113  if (field_list_[field_idx_]->is_multifield())
114  return field_list_[field_idx_]->get_component(field_component_idx_);
115  else
116  return field_list_[field_idx_];
117  }
118 
119 private:
120  std::vector<FieldCommon *> field_list_; ///< List of FieldCommon objects (combine Fields and MultiFields
121  unsigned int field_idx_; ///< Index of actual Field in field_list
122  unsigned int field_component_idx_; ///< Index of subfield in MultiField (fo fields hold only value 0 that is not used)
123 };
124 
125 
126 /**
127  * @brief Container for various descendants of FieldCommonBase.
128  *
129  * Provides various collective operations.
130  * Typical usage:
131  *
132  * class EqData : public FieldSet
133  * {
134  * EqData() {
135  * *this += scalar_field
136  * .name("scalar_field")
137  * .description("Some description for input and output documentation.")
138  * .input_default("{0.0}")
139  * .units("m");
140  * *this += vector_field
141  * .name("vector_field")
142  * .description("Some description for input and output documentation.")
143  * .units("m");
144  * }
145  *
146  * Field<3, FieldValue<3>::Scalar> scalar_field;
147  * Field<3, FieldValue<3>::VectorFixed> vector_field;
148  * };
149  *
150  * This way the fields are destructed just before their pointers stored in the FieldSet.
151  *
152  * TODO:
153  * Some set_XY functions set also to the fields added to the FieldSet in future.
154  * This behavior should be removed, since it is misleading in combination with mask subsets. If one set
155  * something to mask subset, it does not influence fields added to the original field set even if
156  * they match the mask of the subset.
157  *
158  */
159 class FieldSet : public FieldFlag {
160 public:
161  DECLARE_EXCEPTION(ExcUnknownField, << "Field set has no field with name: " << FieldCommon::EI_Field::qval);
162  DECLARE_INPUT_EXCEPTION(ExcFieldNotSet,
163  << "Field " << FieldCommon::EI_Field::qval << " is not set. Please set key 'scalar_field', 'vector_field' or 'tensor_field' at: \n");
164 
165  /// Default constructor.
166  FieldSet();
167 
168  /**
169  * @brief Declare input record type of field defined by user.
170  */
171  const Input::Type::Record & get_user_field(const std::string &equation_name);
172 
173  /**
174  * Add an existing Field to the list. It stores just pointer to the field.
175  * Be careful to not destroy passed Field before the FieldSet.
176  *
177  * Using operator allows elegant setting and adding of a field to the field set:
178  * @code
179  * Field<...> init_quantity; // member of a FieldSet descendant
180  *
181  * field_set +=
182  * some_field
183  * .disable_where(type, {dirichlet, neumann}) // this must come first since it is not member of FieldCommonBase
184  * .name("init_temperature")
185  * .description("Initial temperature");
186  *
187  */
188  FieldSet &operator +=(FieldCommon &add_field);
189 
190  /**
191  * Add other FieldSet to current one.
192  */
193  FieldSet &operator +=(const FieldSet &other);
194 
195  /**
196  * Make new FieldSet as a subset of *this. The new FieldSet contains fields with names given by the @p names parameter.
197  */
198  FieldSet subset(std::vector<std::string> names) const;
199 
200  /**
201  * Make new FieldSet as a subset of *this.
202  * The new FieldSet contains all fields that match given @p mask.
203  */
204  FieldSet subset( FieldFlag::Flags::Mask mask) const;
205 
206  /**
207  * Number of fields in the FieldSet.
208  */
209  inline unsigned int size() const {
210  return field_list.size();
211  }
212 
213  /**
214  * Returns input type for a field descriptor, that can contain any of the fields in the set.
215  * Typical usage is from derived class, where we add fields in the constructor
216  * and make auxiliary temporary instance
217  * to get the record of the field descriptor.
218  * The returned Record has name equation_name + "_Data".
219  *
220  * Simplest example:
221  *
222  * @code
223  * class EqData : public FieldSet {
224  * public:
225  * // fields
226  * Field<..> field_a;
227  * Field<..> field_b
228  * EqData() {
229  * add(field_a);
230  * add(field_b);
231  * }
232  * }
233  *
234  * Input::Type::Record SomEquation::input_type=
235  * Record("SomeEquation","equation's description")
236  * .declare_key("data",Input::Type::Array(
237  * EqData().make_field_descriptor_type("SomeEquation")),"List of field descriptors.");
238  * @endcode
239  *
240  */
241  Input::Type::Record make_field_descriptor_type(const std::string &equation_name) const;
242 
243  /**
244  * Make Selection with strings for all field names in the FieldSet.
245  */
246  //Input::Type::Selection make_output_field_selection(const string &name, const string &desc);
247 
248  /**
249  * Use @p FieldCommonBase::copy_from() to set field of the field set given by the first parameter
250  * @p dest_field_name. The source field is given as the second parameter @p source. The field
251  * copies share the same input descriptor list and the same instances of FieldBase classes
252  * but each copy can be set to different time and different limit side.
253  *
254  * See @p FieldCommonBase::copy_from documentation for details.
255  */
256  void set_field(const std::string &dest_field_name, FieldCommon &source);
257 
258  /**
259  * Return pointer to the field given by name @p field_name. Return nullptr if not found.
260  */
261  FieldCommon *field(const std::string &field_name) const;
262 
263  /**
264  * Returns reference to the field given by @p field_name.
265  * Throws if the field with given name is not found.
266  */
267  FieldCommon &operator[](const std::string &field_name) const;
268 
269  /**
270  * Collective interface to @p FieldCommonBase::set_components().
271  * It is safe to call this for field sets containing also fields
272  * with return value other then variable vector as long as all variable
273  * vector fields should be set to the same number of components.
274  */
275  void set_components(const std::vector<string> &names) {
277  }
278  /**
279  * Collective interface to @p FieldCommonBase::set_mesh().
280  */
281  void set_mesh(const Mesh &mesh) {
282  this->mesh_ = &mesh;
284  }
285 
286  /**
287  * Collective interface to @p FieldCommon::set_input_list().
288  */
289  void set_input_list(Input::Array input_list, const TimeGovernor &tg) {
290  for(FieldCommon *field : field_list) field->set_input_list(input_list, tg);
291  }
292 
293  /**
294  * Fill data of user defined fields to user_fields_input_ map.
295  */
296  void set_user_fields_map(Input::Array input_list);
297 
298  /**
299  * Collective interface to @p FieldCommonBase::flags_add().
300  * @param mask mask to set for all fields in the field set.
301  */
302  void flags_add( FieldFlag::Flags::Mask mask) {
303  for(FieldCommon *field : field_list) field->flags_add(mask);
304  }
305 
306  /**
307  * Collective interface to @p FieldCommonBase::set_mesh().
308  */
309  bool set_time(const TimeStep &time, LimitSide limit_side);
310 
311  /**
312  * Collective interface to @p FieldCommonBase::output_type().
313  * @param rt Discrete function space (element, node or corner data).
314  */
317  }
318 
319  /**
320  * Collective interface to @p FieldCommonBase::mark_input_times().
321  */
322  void mark_input_times(const TimeGovernor &tg) {
323  for(auto field : field_list) field->mark_input_times(tg);
324  }
325 
326  /**
327  * Collective interface to @p FieldCommonBase::set_mesh().
328  */
329  bool changed() const;
330 
331  /**
332  * Collective interface to @p FieldCommonBase::set_mesh().
333  */
334  bool is_constant(Region reg) const;
335 
336  /**
337  * Collective interface to @p FieldCommonBase::is_jump_time().
338  */
339  bool is_jump_time() const;
340 
341  /**
342  * Collective interface to @p FieldCommon::recache_allocate().
343  */
344  void cache_reallocate(const ElementCacheMap &cache_map, FieldSet &used_fieldset) {
345  this->set_dependency(used_fieldset);
346  for (auto reg_it : region_field_update_order_) {
347  unsigned int region_idx = reg_it.first;
348  for (auto f_it : reg_it.second) {
349  f_it->cache_reallocate(cache_map, region_idx);
350  }
351  }
352  //for(auto field : field_list) field->cache_reallocate(cache_map);
353  }
354 
355  /**
356  * Collective interface to @p FieldCommon::cache_update().
357  */
358  void cache_update(ElementCacheMap &cache_map);
359 
360  /**
361  * Set reference of FieldSet to all instances of FieldFormula.
362  */
363  void set_dependency(FieldSet &used_fieldset);
364 
365  /**
366  * Add coords field (X_) and depth field to field_list.
367  *
368  * We can't add this field automatically in constructor, because there is problem
369  * in equation where we add one FieldSet to other.
370  */
371  void add_coords_field();
372 
373  /// Set surface depth object to "d" field.
374  inline void set_surface_depth(std::shared_ptr<SurfaceDepth> surface_depth) {
375  depth_.set_surface_depth( surface_depth );
376  }
377 
378  /// Returns range of Fields held in field_list
380 
381  /// Returns pointer to mesh.
382  inline const Mesh *mesh() const {
383  return mesh_;
384  }
385 
386  /// Return order of evaluated fields by dependency and region_idx.
387  std::string print_dependency() const;
388 
389  /**
390  * Return pointer to the field defined by user given by name @p field_name. Return nullptr if not found.
391  */
392  FieldCommon *user_field(const std::string &field_name, const TimeStep &time);
393 
394 
395 protected:
396 
397  /// Helper method sort used fields by dependency
398  void topological_sort(const FieldCommon *f, unsigned int i_reg, std::unordered_set<const FieldCommon *> &used_fields);
399 
400  /// List of all fields.
402 
403  /// List of fields defined by user.
405 
406  /// Pointer to the mesh.
407  const Mesh *mesh_;
408 
409  /**
410  * Holds vector of indices of fields in field_list sorted by dependency for every region.
411  *
412  * - first: index of region
413  * - second: vector of indices of fields (corresponding to position in field_list vector)
414  */
416 
417  // Default fields.
418  // TODO derive from Field<>, make public, rename
419 
420  /// Field holds coordinates for computing of FieldFormulas
422 
423  /// Field holds surface depth for computing of FieldFormulas
425 
426  /// Map assigns Input::Record to each field defined in optional Input::Array 'user_fields'
427  std::unordered_map<std::string, Input::Record> user_fields_input_;
428 
429  /**
430  * Stream output operator
431  */
432  friend std::ostream &operator<<(std::ostream &stream, const FieldSet &set);
433 
434  template<int dim, class Val>
435  friend class FieldFormula;
436 };
437 
438 
439 
440 #endif /* FIELD_SET_HH_ */
surface_depth.hh
FieldSet::set_user_fields_map
void set_user_fields_map(Input::Array input_list)
Definition: field_set.cc:349
FieldListAccessor::field_list_
std::vector< FieldCommon * > field_list_
List of FieldCommon objects (combine Fields and MultiFields.
Definition: field_set.hh:120
FieldSet::operator[]
FieldCommon & operator[](const std::string &field_name) const
Definition: field_set.cc:235
FieldSet::mesh
const Mesh * mesh() const
Returns pointer to mesh.
Definition: field_set.hh:382
FieldCoords
Definition: field_coords.hh:36
FieldSet::get_user_field
const Input::Type::Record & get_user_field(const std::string &equation_name)
Declare input record type of field defined by user.
Definition: field_set.cc:33
general_iterator.hh
Template Iter serves as general template for internal iterators.
eval_subset.hh
FieldListAccessor::field_idx
unsigned int field_idx() const
Getter for field_idx_.
Definition: field_set.hh:85
FieldSet::user_field_list_
std::vector< FieldCommon * > user_field_list_
List of fields defined by user.
Definition: field_set.hh:404
FieldSet::is_jump_time
bool is_jump_time() const
Definition: field_set.cc:267
FieldSet::set_time
bool set_time(const TimeStep &time, LimitSide limit_side)
Definition: field_set.cc:244
FieldSet::is_constant
bool is_constant(Region reg) const
Definition: field_set.cc:260
FieldListAccessor
Definition: field_set.hh:61
time_governor.hh
Basic time management class.
FieldDepth
Definition: field_depth.hh:35
FieldCommon::output_type
FieldCommon & output_type(OutputTime::DiscreteSpace rt)
Definition: field_common.hh:184
ElementCacheMap
Directing class of FieldValueCache.
Definition: field_value_cache.hh:151
FieldSet::set_dependency
void set_dependency(FieldSet &used_fieldset)
Definition: field_set.cc:283
FieldSet::mark_input_times
void mark_input_times(const TimeGovernor &tg)
Definition: field_set.hh:322
FieldSet::set_input_list
void set_input_list(Input::Array input_list, const TimeGovernor &tg)
Definition: field_set.hh:289
eval_points.hh
FieldSet::user_field
FieldCommon * user_field(const std::string &field_name, const TimeStep &time)
Definition: field_set.cc:176
FieldSet::flags_add
void flags_add(FieldFlag::Flags::Mask mask)
Definition: field_set.hh:302
FieldSet::output_type
void output_type(OutputTime::DiscreteSpace rt)
Definition: field_set.hh:315
FieldListAccessor::operator==
bool operator==(const FieldListAccessor &other)
Comparison of accessors.
Definition: field_set.hh:103
FieldListAccessor::FieldListAccessor
FieldListAccessor(std::vector< FieldCommon * > field_list, unsigned int field_idx)
Constructor.
Definition: field_set.hh:68
FieldSet::fields_range
Range< FieldListAccessor > fields_range() const
Returns range of Fields held in field_list.
Definition: field_set.cc:329
std::vector< FieldCommon * >
FieldSet::region_field_update_order_
std::map< unsigned int, std::vector< const FieldCommon * > > region_field_update_order_
Definition: field_set.hh:415
FieldSet::changed
bool changed() const
Definition: field_set.cc:252
FieldListAccessor::field_component_idx_
unsigned int field_component_idx_
Index of subfield in MultiField (fo fields hold only value 0 that is not used)
Definition: field_set.hh:122
FieldCommon::set_input_list
virtual void set_input_list(const Input::Array &list, const TimeGovernor &tg)=0
FieldSet::set_surface_depth
void set_surface_depth(std::shared_ptr< SurfaceDepth > surface_depth)
Set surface depth object to "d" field.
Definition: field_set.hh:374
FieldFlag
Definition: field_flag.hh:23
FieldSet::DECLARE_EXCEPTION
DECLARE_EXCEPTION(ExcUnknownField,<< "Field set has no field with name: "<< FieldCommon::EI_Field::qval)
field_flag.hh
FieldListAccessor::field
FieldCommon * field() const
Returns pointer to actual field held by accessor.
Definition: field_set.hh:95
FieldSet::user_fields_input_
std::unordered_map< std::string, Input::Record > user_fields_input_
Map assigns Input::Record to each field defined in optional Input::Array 'user_fields'.
Definition: field_set.hh:427
exceptions.hh
type_record.hh
FieldCommon::flags_add
FieldCommon & flags_add(FieldFlag::Flags::Mask mask)
Definition: field_common.hh:197
Region
Definition: region.hh:146
FieldSet::field_list
std::vector< FieldCommon * > field_list
List of all fields.
Definition: field_set.hh:401
FieldSet::X_
FieldCoords X_
Field holds coordinates for computing of FieldFormulas.
Definition: field_set.hh:421
FieldSet::set_components
void set_components(const std::vector< string > &names)
Definition: field_set.hh:275
FieldListAccessor::FieldListAccessor
FieldListAccessor()
Default constructor.
Definition: field_set.hh:64
FieldSet::topological_sort
void topological_sort(const FieldCommon *f, unsigned int i_reg, std::unordered_set< const FieldCommon * > &used_fields)
Helper method sort used fields by dependency.
Definition: field_set.cc:296
FieldSet::print_dependency
std::string print_dependency() const
Return order of evaluated fields by dependency and region_idx.
Definition: field_set.cc:336
accessors.hh
TimeStep
Representation of one time step..
Definition: time_governor.hh:123
FieldSet::mesh_
const Mesh * mesh_
Pointer to the mesh.
Definition: field_set.hh:407
TimeGovernor
Basic time management functionality for unsteady (and steady) solvers (class Equation).
Definition: time_governor.hh:317
output_time.hh
FieldCommon
Common abstract parent of all Field<...> classes.
Definition: field_common.hh:76
FieldSet::add_coords_field
void add_coords_field()
Definition: field_set.cc:307
FieldListAccessor::operator->
FieldCommon * operator->() const
Dereference operator simplify access to actual field held by accessor.
Definition: field_set.hh:112
LimitSide
LimitSide
Definition: field_common.hh:63
FieldSet::cache_update
void cache_update(ElementCacheMap &cache_map)
Definition: field_set.cc:274
FieldListAccessor::inc
void inc()
Iterates to next Field.
Definition: field_set.hh:72
FieldSet
Container for various descendants of FieldCommonBase.
Definition: field_set.hh:159
std::map
Definition: doxy_dummy_defs.hh:11
FieldListAccessor::field_idx_
unsigned int field_idx_
Index of actual Field in field_list.
Definition: field_set.hh:121
Input::Type::Record
Record type proxy class.
Definition: type_record.hh:182
FieldListAccessor::operator!=
bool operator!=(const FieldListAccessor &other) const
Definition: field_set.hh:107
FieldCommon::set_components
void set_components(const std::vector< string > &names)
Definition: field_common.hh:207
Mesh
Definition: mesh.h:359
FieldDepth::set_surface_depth
void set_surface_depth(std::shared_ptr< SurfaceDepth > surface_depth)
Setter of surface_depth data member.
Definition: field_depth.hh:138
Range
Range helper class.
Definition: range_wrapper.hh:65
Input::Array
Accessor to input data conforming to declared Array.
Definition: accessors.hh:566
FieldSet::set_mesh
void set_mesh(const Mesh &mesh)
Definition: field_set.hh:281
field_value_cache.hh
flag_array.hh
FieldSet::FieldSet
FieldSet()
Default constructor.
Definition: field_set.cc:29
FieldSet::DECLARE_INPUT_EXCEPTION
DECLARE_INPUT_EXCEPTION(ExcFieldNotSet,<< "Field "<< FieldCommon::EI_Field::qval<< " is not set. Please set key 'scalar_field', 'vector_field' or 'tensor_field' at: \n")
OutputTime::DiscreteSpace
DiscreteSpace
Definition: output_time.hh:108
FieldSet::operator<<
friend std::ostream & operator<<(std::ostream &stream, const FieldSet &set)
Definition: field_set.cc:360
FieldSet::cache_reallocate
void cache_reallocate(const ElementCacheMap &cache_map, FieldSet &used_fieldset)
Definition: field_set.hh:344
field_depth.hh
FieldSet::set_field
void set_field(const std::string &dest_field_name, FieldCommon &source)
Definition: field_set.cc:160
FieldCommon::set_mesh
virtual void set_mesh(const Mesh &mesh)=0
FieldCommon::mark_input_times
void mark_input_times(const TimeGovernor &tg)
Definition: field_common.cc:82
FieldSet::depth_
FieldDepth depth_
Field holds surface depth for computing of FieldFormulas.
Definition: field_set.hh:424
FieldSet::make_field_descriptor_type
Input::Type::Record make_field_descriptor_type(const std::string &equation_name) const
Definition: field_set.cc:90
FieldListAccessor::field_component_idx
unsigned int field_component_idx() const
Getter for field_component_idx_.
Definition: field_set.hh:90
field.hh
field_common.hh
field_coords.hh
FieldSet::field
FieldCommon * field(const std::string &field_name) const
Definition: field_set.cc:168
range_wrapper.hh
Implementation of range helper class.
FieldFormula
Definition: field_formula.hh:63