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