Flow123d  master-f44eb46
multi_field.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 multi_field.hh
15  * @brief
16  */
17 
18 #ifndef MULTI_FIELD_HH_
19 #define MULTI_FIELD_HH_
20 
21 using namespace std;
22 
23 
24 #include <boost/core/explicit_operator_bool.hpp> // for optional::oper...
25 #include <boost/format/alt_sstream.hpp> // for basic_altstrin...
26 #include <boost/format/alt_sstream_impl.hpp> // for basic_altstrin...
27 #include <boost/format/parsing.hpp> // for basic_format::...
28 #include <boost/optional/optional.hpp> // for get_pointer
29 #include <boost/type_index/type_index_facade.hpp> // for operator==
30 #include <iostream> // for basic_ostream:...
31 #include <memory> // for shared_ptr
32 #include <string> // for string, basic_...
33 #include <vector> // for vector
34 #include "fields/field.hh" // for Field<>::Field...
35 #include "fields/field_algo_base.hh" // for FieldAlgorithm...
36 #include "fields/field_common.hh" // for FieldCommon
37 #include "fields/field_values.hh" // for FieldValue<>::...
38 #include "input/accessors.hh" // for ExcTypeMismatch
39 #include "input/accessors_impl.hh" // for Array::begin
40 #include "input/factory_impl.hh" // for Factory::create
41 #include "input/input_exception.hh" // for DECLARE_INPUT_...
42 #include "input/input_type_forward.hh" // for Type
43 #include "input/type_base.hh" // for Array
44 #include "input/type_generic.hh" // for Instance
45 #include "input/type_record.hh" // for Record::ExcRec...
46 #include "mesh/region.hh" // for Region (ptr only)
47 #include "system/exc_common.hh" // for ExcAssertMsg
48 #include "system/exceptions.hh" // for ExcMessage::~E...
49 #include "system/asserts.hh" // for ASSERT_PERMANENT
50 #include "tools/time_governor.hh" // for TimeStep
51 
52 class Mesh;
53 class Observe;
54 class OutputTime;
55 class EvalPoints;
56 class ElementCacheMap;
57 class FieldSet;
58 
59 
60 namespace IT=Input::Type;
61 
62 /**
63  * @brief Class for representation of a vector of fields of the same physical quantity.
64  *
65  * When solving a system of same equations with the number of components given at runtime
66  * (as in the case of transport equation for runtime given number of substances) we need means how to work with the whole
67  * vector of fields at once. This is the aim of this class. It provides the interface given by the parent class @p FieldCommonBase,
68  * but principally it is just a vector of Field<Value,dim> objects. The sub-fields or components of a @p MultiField are independent
69  * objects, how ever the setters propagates the values from the MultiFields to the individual fields. The only exception is the
70  * @p set_name method which in conjunction with @p MultiField::set_subfield_names can set unique name to each component.
71  *
72  * Template parameters are used for every subfield.
73  *
74  * TODO:
75  * - general mechanism how to convert a Field< dim, Vector> to MultiField< dim, Value>
76  * - implement set_from_input
77  * - implement set_Time
78  *
79  * - problem with "input" methods, since Field works with AbstratRecord, the MultiField - However - should use Array of Abstracts
80  * simplest solution - test that in EqDataBase and have more methods in FieldCommonBase, or somehow detach input handling from
81  * Fields
82  *
83  * Definition of MultiField must be in separate file.
84  * In other case source file field.cc is too big and compiler can throw compile error.
85  */
86 template<int spacedim, class Value>
87 class MultiField : public FieldCommon {
88 public:
93 
94  TYPEDEF_ERR_INFO( EI_MultiFieldName, const string );
95  TYPEDEF_ERR_INFO( EI_Size, unsigned int );
96  TYPEDEF_ERR_INFO( EI_ExpectedSize, unsigned int );
97  DECLARE_INPUT_EXCEPTION( Exc_InvalidMultiFieldSize, << "Invalid size " << EI_Size::val
98  << "of the MultiField " << EI_MultiFieldName::qval << ", expected size: " << EI_ExpectedSize::val );
99 
100  class MultiFieldFactory : public Field<spacedim, Value>::FactoryBase {
101  public:
102  /// Constructor.
103  MultiFieldFactory(unsigned int index)
104  : index_(index) {}
105 
106  virtual typename Field<spacedim, Value>::FieldBasePtr create_field(Input::Record rec, const FieldCommon &field);
107 
108  bool is_active_field_descriptor(const Input::Record &in_rec, const std::string &input_name) override;
109 
110  unsigned int index_;
111  };
112 
113  /**
114  * Default constructor.
115  */
116  MultiField();
117 
118  /**
119  * Copy constructor.
120  */
121  MultiField(const MultiField &other);
122 
123  /**
124  * Assignment operator. Same properties as copy constructor, but class member name_ is not copied.
125  */
126  MultiField &operator=(const MultiField &other);
127 
128 
129  /**
130  * Returns input type of particular field instance, this is usually static member input_type of the corresponding FieldBase class (
131  * with same template parameters), however, for fields returning "Enum" we have to create whole unique Input::Type hierarchy for
132  * every instance since every such field use different Selection for initialization, even if all returns just unsigned int.
133  */
134  IT::Instance get_input_type() override;
135 
136  IT::Array get_multifield_input_type() override;
137 
138  /**
139  * By this method you can allow that the field need not to be set on regions (and times) where the given @p control_field is
140  * FieldConstant and has value in given @p value_list. We check this in the set_time method. Through this mechanism we
141  * can switch of e.g. boundary data fields according to the type of the boundary condition.
142  */
143  auto disable_where(
144  const MultiField<spacedim, typename FieldValue<spacedim>::Enum > &control_field,
145  const vector<FieldEnum> &value_list) -> MultiField &;
146 
147  /**
148  * Abstract method to update field to the new time level.
149  * Implemented by in class template Field<...>.
150  *
151  * Return true if the value of the field was changed on some region.
152  * The returned value is also stored in @p changed_during_set_time data member.
153  *
154  * In first call initialize MultiField to the number of components given by the size of @p names
155  * and use this vector to name individual components. Should be called after the setters derived from
156  * FieldCommonBase.
157  */
158  bool set_time(const TimeStep &time, LimitSide limit_side) override;
159 
160  /**
161  * We have to override the @p set_mesh method in order to call set_mesh method for subfields.
162  */
163  void set_mesh(const Mesh &mesh) override;
164 
165  /**
166  * Polymorphic copy. Check correct type, allows copy of MultiField or Field.
167  */
168  void copy_from(const FieldCommon & other) override;
169 
170  /**
171  * Implementation of @p FieldCommonBase::output().
172  */
173  void field_output(std::shared_ptr<OutputTime> stream, OutputTime::DiscreteSpace type) override;
174 
175  /**
176  * Implementation of @p FieldCommonBase::is_constant().
177  */
178  bool is_constant(Region reg) override;
179 
180  /**
181  * @brief Indicates special field states.
182  *
183  * Return possible values from the enum @p FieldResult, see description there.
184  *
185  * Only difference to Field<>::field_result is meaning of @p result_constant. Here we return this value if
186  * all subfields are (possibly different) constants.
187  *
188  * Not used yet. Possibly tune behavior after usage.
189  */
190  FieldResult field_result( RegionSet region_set) const override;
191 
192  std::string get_value_attribute() const override;
193 
194  /**
195  * Virtual destructor.
196  */
197  inline virtual ~MultiField() {}
198 
199  /// Number of subfields that compose the multi-field.
200  inline unsigned int size() const
201  { return sub_fields_.size(); }
202 
203  /**
204  * Implementation of FieldCommon::set_dependency().
205  */
206  std::vector<const FieldCommon *> set_dependency(unsigned int i_reg) const override;
207 
208  /**
209  * Returns reference to the sub-field (component) of given index @p idx.
210  */
211  inline SubFieldType &operator[](unsigned int idx)
212  {
213  ASSERT_LT(idx, sub_fields_.size())(this->input_name()).error("Index of subfield in MultiField is out of range.\n");
214  return sub_fields_[idx];
215  }
216 
217  /**
218  * Returns constant reference to the sub-field (component) of given index @p idx.
219  */
220  inline const SubFieldType &operator[](unsigned int idx) const
221  {
222  ASSERT_LT(idx, sub_fields_.size())(this->input_name()).error("Index of subfield in MultiField is out of range.\n");
223  return sub_fields_[idx];
224  }
225 
226  /**
227  * Returns pointer to the sub-field (component, as FieldCommon) of given index @p idx.
228  */
229  FieldCommon *get_component(unsigned int idx) override
230  {
231  ASSERT_LT(idx, sub_fields_.size())(this->input_name()).error("Index of subfield in MultiField is out of range.\n");
232  return &(sub_fields_[idx]);
233  }
234 
235  /**
236  * Initialize components of MultiField.
237  *
238  * Must be call after setting components, mesh and limit side.
239  */
240  void setup_components();
241 
242  void set_input_list(const Input::Array &list, const TimeGovernor &tg) override;
243 
244  /// Implements FieldCommon::cache_reallocate
245  void cache_reallocate(const ElementCacheMap &cache_map, unsigned int region_idx) const override;
246 
247  /// Implements FieldCommon::cache_update
248  void cache_update(ElementCacheMap &cache_map, unsigned int region_patch_idx) const override;
249 
250  /**
251  * Assigns fields from @p field_vec to individual components and all regions in region sets given by @p region_set_names.
252  * Field is added to the history with given time and possibly used in the next call of the set_time method.
253  * Caller is responsible for correct construction of given field.
254  *
255  * Use this method only if necessary.
256  */
257  void set(std::vector<typename Field<spacedim, Value>::FieldBasePtr> field_vec,
258  double time,
259  std::vector<std::string> region_set_names = {"ALL"});
260 
261  /**
262  * Same as previous but only for one-component MultiField (simplification for HeatModel).
263  */
264  void set(typename Field<spacedim, Value>::FieldBasePtr field,
265  double time,
266  std::vector<std::string> region_set_names = {"ALL"});
267 
268  /// Implements FieldCommon::value_cache
270  return nullptr;
271  }
272 
273  /// Implements FieldCommon::value_cache
274  const FieldValueCache<double> * value_cache() const override {
275  return nullptr;
276  }
277 
278 private:
279  /// Subfields (items) of MultiField
281 
282  /// Full list of input field descriptors from which the subfields of MultiField are set.
284 
285  /// TimeGovernor is necessary for set input list in setup_components method.
287 
288  /**
289  * If this pointer is set, turn off check of initialization in the
290  * @p set_time method on the regions where the method @p get_constant_enum_value
291  * of the control field returns value from @p no_check_values_. This
292  * field is private copy, its set_time method is called from the
293  * set_Time method of actual object.
294  */
296 };
297 
298 
299 #endif /* MULTI_FIELD_HH_ */
Definitions of ASSERTS.
#define ASSERT_LT(a, b)
Definition of comparative assert macro (Less Than) only for debug mode.
Definition: asserts.hh:301
Directing class of FieldValueCache.
Class holds local coordinations of evaluating points (bulk and sides) specified by element dimension.
Definition: eval_points.hh:43
Space< spacedim >::Point Point
Common abstract parent of all Field<...> classes.
Definition: field_common.hh:77
Container for various descendants of FieldCommonBase.
Definition: field_set.hh:159
Class template representing a field with values dependent on: point, element, and region.
Definition: field.hh:92
std::shared_ptr< FieldBaseType > FieldBasePtr
Definition: field.hh:96
Accessor to input data conforming to declared Array.
Definition: accessors.hh:566
Accessor to the data with type Type::Record.
Definition: accessors.hh:291
Class for declaration of inputs sequences.
Definition: type_base.hh:339
Helper class that stores data of generic types.
Definition: type_generic.hh:89
Definition: mesh.h:362
MultiFieldFactory(unsigned int index)
Constructor.
Definition: multi_field.hh:103
Class for representation of a vector of fields of the same physical quantity.
Definition: multi_field.hh:87
Input::Array full_input_list_
Full list of input field descriptors from which the subfields of MultiField are set.
Definition: multi_field.hh:283
FieldValue_< 0, 1, typename Value::element_type > MultiFieldValue
Definition: multi_field.hh:92
TYPEDEF_ERR_INFO(EI_ExpectedSize, unsigned int)
virtual ~MultiField()
Definition: multi_field.hh:197
TYPEDEF_ERR_INFO(EI_Size, unsigned int)
SubFieldType & operator[](unsigned int idx)
Definition: multi_field.hh:211
TYPEDEF_ERR_INFO(EI_MultiFieldName, const string)
const TimeGovernor * tg_
TimeGovernor is necessary for set input list in setup_components method.
Definition: multi_field.hh:286
DECLARE_INPUT_EXCEPTION(Exc_InvalidMultiFieldSize,<< "Invalid size "<< EI_Size::val<< "of the MultiField "<< EI_MultiFieldName::qval<< ", expected size: "<< EI_ExpectedSize::val)
FieldCommon * get_component(unsigned int idx) override
Definition: multi_field.hh:229
unsigned int size() const
Number of subfields that compose the multi-field.
Definition: multi_field.hh:200
const SubFieldType & operator[](unsigned int idx) const
Definition: multi_field.hh:220
FieldAlgorithmBase< spacedim, Value >::Point Point
Definition: multi_field.hh:91
std::vector< SubFieldType > sub_fields_
Subfields (items) of MultiField.
Definition: multi_field.hh:280
Field< spacedim, Value > SubFieldType
Definition: multi_field.hh:90
FieldAlgorithmBase< spacedim, Value > SubFieldBaseType
Definition: multi_field.hh:89
FieldValueCache< double > * value_cache() override
Implements FieldCommon::value_cache.
Definition: multi_field.hh:269
const MultiField< spacedim, typename FieldValue< spacedim >::Enum > * no_check_control_field_
Definition: multi_field.hh:295
const FieldValueCache< double > * value_cache() const override
Implements FieldCommon::value_cache.
Definition: multi_field.hh:274
The class for outputting data during time.
Definition: output_time.hh:51
Basic time management functionality for unsteady (and steady) solvers (class Equation).
Representation of one time step..
FieldResult
LimitSide
Definition: field_common.hh:64
Basic time management class.