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