Flow123d  release_2.2.0-22-g936454a
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 "fields/field.hh"
25 #include "fields/field_common.hh"
26 
27 
28 namespace IT=Input::Type;
29 
30 /**
31  * @brief Class for representation of a vector of fields of the same physical quantity.
32  *
33  * When solving a system of same equations with the number of components given at runtime
34  * (as in the case of transport equation for runtime given number of substances) we need means how to work with the whole
35  * vector of fields at once. This is the aim of this class. It provides the interface given by the parent class @p FieldCommonBase,
36  * but principally it is just a vector of Field<Value,dim> objects. The sub-fields or components of a @p MultiField are independent
37  * objects, how ever the setters propagates the values from the MultiFields to the individual fields. The only exception is the
38  * @p set_name method which in conjunction with @p MultiField::set_subfield_names can set unique name to each component.
39  *
40  * Template parameters are used for every subfield.
41  *
42  * TODO:
43  * - general mechanism how to convert a Field< dim, Vector> to MultiField< dim, Value>
44  * - implement set_from_input
45  * - implement set_Time
46  *
47  * - problem with "input" methods, since Field works with AbstratRecord, the MultiField - However - should use Array of Abstracts
48  * simplest solution - test that in EqDataBase and have more methods in FieldCommonBase, or somehow detach input handling from
49  * Fields
50  *
51  * Definition of MultiField must be in separate file.
52  * In other case source file field.cc is too big and compiler can throw compile error.
53  */
54 template<int spacedim, class Value>
55 class MultiField : public FieldCommon {
56 public:
61 
62  TYPEDEF_ERR_INFO( EI_MultiFieldName, const string );
63  TYPEDEF_ERR_INFO( EI_Size, unsigned int );
64  TYPEDEF_ERR_INFO( EI_ExpectedSize, unsigned int );
65  DECLARE_INPUT_EXCEPTION( Exc_InvalidMultiFieldSize, << "Invalid size " << EI_Size::val
66  << "of the MultiField " << EI_MultiFieldName::qval << ", expected size: " << EI_ExpectedSize::val );
67 
68  class MultiFieldFactory : public Field<spacedim, Value>::FactoryBase {
69  public:
70  /// Constructor.
71  MultiFieldFactory(unsigned int index)
72  : index_(index) {}
73 
74  virtual typename Field<spacedim, Value>::FieldBasePtr create_field(Input::Record rec, const FieldCommon &field);
75 
76  bool is_active_field_descriptor(const Input::Record &in_rec, const std::string &input_name) override;
77 
78  unsigned int index_;
79  };
80 
81  /**
82  * Default constructor.
83  * bc indicates boundary multifield.
84  */
85  MultiField(bool bc = false);
86 
87  /**
88  * Copy constructor.
89  */
90  MultiField(const MultiField &other);
91 
92  /**
93  * Assignment operator. Same properties as copy constructor, but class member name_ is not copied.
94  */
95  MultiField &operator=(const MultiField &other);
96 
97 
98  /**
99  * Returns input type of particular field instance, this is usually static member input_type of the corresponding FieldBase class (
100  * with same template parameters), however, for fields returning "Enum" we have to create whole unique Input::Type hierarchy for
101  * every instance since every such field use different Selection for initialization, even if all returns just unsigned int.
102  */
103  IT::Instance get_input_type() override;
104 
105  IT::Array get_multifield_input_type() override;
106 
107  /**
108  * 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
109  * FieldConstant and has value in given @p value_list. We check this in the set_time method. Through this mechanism we
110  * can switch of e.g. boundary data fields according to the type of the boundary condition.
111  */
112  auto disable_where(
113  const MultiField<spacedim, typename FieldValue<spacedim>::Enum > &control_field,
114  const vector<FieldEnum> &value_list) -> MultiField &;
115 
116  /**
117  * Abstract method to update field to the new time level.
118  * Implemented by in class template Field<...>.
119  *
120  * Return true if the value of the field was changed on some region.
121  * The returned value is also stored in @p changed_during_set_time data member.
122  *
123  * In first call initialize MultiField to the number of components given by the size of @p names
124  * and use this vector to name individual components. Should be called after the setters derived from
125  * FieldCommonBase.
126  */
127  bool set_time(const TimeStep &time, LimitSide limit_side) override;
128 
129  /**
130  * We have to override the @p set_mesh method in order to call set_mesh method for subfields.
131  */
132  void set_mesh(const Mesh &mesh) override;
133 
134  /**
135  * Polymorphic copy. Check correct type, allows copy of MultiField or Field.
136  */
137  void copy_from(const FieldCommon & other) override;
138 
139  /**
140  * Implementation of @p FieldCommonBase::output().
141  */
142  void field_output(std::shared_ptr<OutputTime> stream) override;
143 
144  /**
145  * Implementation of FieldCommonBase::observe_output().
146  */
147  void observe_output(std::shared_ptr<Observe> observe) override;
148 
149  /**
150  * Implementation of @p FieldCommonBase::is_constant().
151  */
152  bool is_constant(Region reg) override;
153 
154  /**
155  * @brief Indicates special field states.
156  *
157  * Return possible values from the enum @p FieldResult, see description there.
158  *
159  * Only difference to Field<>::field_result is meaning of @p result_constant. Here we return this value if
160  * all subfields are (possibly different) constants.
161  *
162  * Not used yet. Possibly tune behavior after usage.
163  */
164  FieldResult field_result( RegionSet region_set) const override;
165 
166  std::string get_value_attribute() const override;
167 
168  /**
169  * Virtual destructor.
170  */
171  inline virtual ~MultiField() {}
172 
173  /// Number of subfields that compose the multi-field.
174  inline unsigned int size() const
175  { return sub_fields_.size(); }
176 
177  /**
178  * Returns reference to the sub-field (component) of given index @p idx.
179  */
180  inline SubFieldType &operator[](unsigned int idx)
181  {
182  OLD_ASSERT(idx < sub_fields_.size(), "Index of subfield in MultiField '%s' is out of range.\n", this->input_name().c_str());
183  return sub_fields_[idx];
184  }
185 
186  /**
187  * Returns constant reference to the sub-field (component) of given index @p idx.
188  */
189  inline const SubFieldType &operator[](unsigned int idx) const
190  {
191  OLD_ASSERT(idx < sub_fields_.size(), "Index of subfield in MultiField '%s' is out of range.\n", this->input_name().c_str());
192  return sub_fields_[idx];
193  }
194 
195  /**
196  * Initialize components of MultiField.
197  *
198  * Must be call after setting components, mesh and limit side.
199  */
200  void setup_components();
201 
202  /**
203  * Returns vector of value in one given point @p on an element given by ElementAccessor @p elm.
204  * It returns reference to he actual value in order to avoid temporaries for vector and tensor values.
205  */
206 // virtual typename MultiFieldValue::return_type value(const Point &p, const ElementAccessor<spacedim> &elm) const;
207 
208  /**
209  * Returns std::vector of vector values in several points at once. The base class implements
210  * trivial implementation using the @p value(,,) method. This is not optimal as it involves lot of virtual calls,
211  * but this overhead can be negligible for more complex fields as Python of Formula.
212  */
213 // virtual void value_list(const std::vector< Point > &point_list, const ElementAccessor<spacedim> &elm,
214 // std::vector<typename MultiFieldValue::return_type> &value_list) const;
215 
216  void set_input_list(const Input::Array &list) override;
217 
218 private:
219  /// Subfields (items) of MultiField
221 
222  /// Full list of input field descriptors from which the subfields of MultiField are set.
224 
225  /**
226  * If this pointer is set, turn off check of initialization in the
227  * @p set_time method on the regions where the method @p get_constant_enum_value
228  * of the control field returns value from @p no_check_values_. This
229  * field is private copy, its set_time method is called from the
230  * set_Time method of actual object.
231  */
233 };
234 
235 
236 #endif /* MULTI_FIELD_HH_ */
Common abstract parent of all Field<...> classes.
Definition: field_common.hh:60
Accessor to input data conforming to declared Array.
Definition: accessors.hh:567
unsigned int size() const
Number of subfields that compose the multi-field.
Definition: multi_field.hh:174
Class template representing a field with values dependent on: point, element, and region...
Definition: field.hh:62
Field< spacedim, Value > SubFieldType
Definition: multi_field.hh:58
Definition: mesh.h:97
const MultiField< spacedim, typename FieldValue< spacedim >::Enum > * no_check_control_field_
Definition: multi_field.hh:232
Helper class that stores data of generic types.
Definition: type_generic.hh:89
FieldValue_< 0, 1, typename Value::element_type > MultiFieldValue
Definition: multi_field.hh:60
Input::Array full_input_list_
Full list of input field descriptors from which the subfields of MultiField are set.
Definition: multi_field.hh:223
Class for declaration of inputs sequences.
Definition: type_base.hh:345
#define OLD_ASSERT(...)
Definition: global_defs.h:131
FieldAlgorithmBase< spacedim, Value > SubFieldBaseType
Definition: multi_field.hh:57
std::vector< SubFieldType > sub_fields_
Subfields (items) of MultiField.
Definition: multi_field.hh:220
Accessor to the data with type Type::Record.
Definition: accessors.hh:292
MultiFieldFactory(unsigned int index)
Constructor.
Definition: multi_field.hh:71
#define TYPEDEF_ERR_INFO(EI_Type, Type)
Macro to simplify declaration of error_info types.
Definition: exceptions.hh:194
Space< spacedim >::Point Point
FieldResult
FieldAlgorithmBase< spacedim, Value >::Point Point
Definition: multi_field.hh:59
std::shared_ptr< FieldBaseType > FieldBasePtr
Definition: field.hh:66
#define DECLARE_INPUT_EXCEPTION(ExcName, Format)
Macro for simple definition of input exceptions.
virtual ~MultiField()
Definition: multi_field.hh:171
const SubFieldType & operator[](unsigned int idx) const
Definition: multi_field.hh:189
Class for representation of a vector of fields of the same physical quantity.
Definition: multi_field.hh:55
SubFieldType & operator[](unsigned int idx)
Definition: multi_field.hh:180
Representation of one time step..
LimitSide
Definition: field_common.hh:47