Flow123d  JS_before_hm-937-g93502c2
field_algo_base.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_algo_base.hh
15  * @brief
16  * @todo
17  * - better tests:
18  * - common set of quantities with different kind of values (scalar, vector, tensor, discrete, ..),
19  * common points and elements for evaluation
20  * - for individual Field implementations have:
21  * - different input
22  * - possibly different EPETCT_EQ tests, but rather have majority common
23  */
24 
25 #ifndef field_algo_base_HH_
26 #define field_algo_base_HH_
27 
28 #include <string.h> // for memcpy
29 #include <boost/type_traits/is_same.hpp> // for is_same
30 #include <limits> // for numeric_limits
31 #include <memory> // for shared_ptr
32 #include <ostream> // for operator<<
33 #include <string> // for string
34 #include <utility> // for make_pair, pair
35 #include <vector> // for vector
36 #include <armadillo> // for operator%, operator<<
37 #include "fields/field_values.hh" // for FieldValue<>::Enum, FieldV...
38 #include "fields/field_flag.hh"
40 #include "input/type_selection.hh" // for Selection
41 #include "mesh/point.hh" // for Space
42 #include "mesh/accessors.hh"
43 #include "system/asserts.hh" // for Assert, ASSERT
44 #include "tools/time_governor.hh" // for TimeStep
45 
46 class Mesh;
47 class UnitSI;
48 class DOFHandlerMultiDim;
49 namespace Input {
50  class AbstractRecord;
51  class Record;
52  namespace Type {
53  class Abstract;
54  class Instance;
55  class Record;
56  }
57 }
58 template <int spacedim> class ElementAccessor;
59 
60 
61 
62 /**
63  * Indication of special field states. Returned by Field<>::field_result.
64  * Individual states have values corresponding to week ordering of the states according
65  * to the exactness of the value. May possibly be helpful in implementation, e.g.
66  * one can use (field_result >= result_constant) to check that the field is constant on given region.
67  */
68 typedef enum {
69  result_none=0, // field not set
70  result_other=1, // field initialized but no particular result information
71  result_constant=2, // spatially constant result
72  result_zeros=10, // zero scalar, vector, or tensor
73  result_ones=20, // all elements equal to 1.0
74  result_eye=21 // identity tensor
75 
76 } FieldResult;
77 
78 /// Helper struct stores data for initizalize descentants of \p FieldAlgorithmBase.
80  /// Full constructor
81  FieldAlgoBaseInitData(std::string field_name, unsigned int n_comp, const UnitSI &unit_si, std::pair<double, double> limits, FieldFlag::Flags flags)
82  : field_name_(field_name), n_comp_(n_comp), unit_si_(unit_si), limits_(limits), flags_(flags) {}
83  /// Simplified constructor, set limit values automatically (used in unit tests)
84  FieldAlgoBaseInitData(std::string field_name, unsigned int n_comp, const UnitSI &unit_si)
85  : field_name_(field_name), n_comp_(n_comp), unit_si_(unit_si),
86  limits_( std::make_pair(-std::numeric_limits<double>::max(), std::numeric_limits<double>::max()) ),
87  flags_(FieldFlag::declare_input & FieldFlag::equation_input & FieldFlag::allow_output) {}
88 
89  std::string field_name_;
90  unsigned int n_comp_;
91  const UnitSI &unit_si_;
92  std::pair<double, double> limits_;
94 };
95 
96 
97 
98 
99 /// Declaration of exception.
100 TYPEDEF_ERR_INFO(EI_Field, std::string);
101 DECLARE_INPUT_EXCEPTION(ExcUndefElementValue,
102  << "Values of some elements of FieldFE " << EI_Field::qval << " is undefined.\n"
103  << "Please specify in default_value key.\n");
104 
105 
106 /**
107  * Base class for space-time function classes.
108  */
109 template <int spacedim, class Value>
111 public:
112  // expose template parameters
113  typedef typename Space<spacedim>::Point Point;
114  static const unsigned int spacedim_=spacedim;
116 
117 
118  /**
119  * Kind of default constructor , with possible setting of the initial time.
120  * Fields that returns variable size vectors accepts number of components @p n_comp.
121  */
122  FieldAlgorithmBase(unsigned int n_comp=0);
123 
124  /**
125  * Returns template parameters as string in order to distinguish name of Abstracts
126  * for initialization of different instances of the FieldBase template.
127  */
128  static std::string template_name();
129 
130  /**
131  * Returns whole tree of input types for FieldBase with all descendants based on element input type (namely for FieldConstant)
132  * given by element_input_type pointer.
133  */
134  static Input::Type::Abstract & get_input_type();
135 
136  /**
137  * Returns parameterized whole tree of input types for FieldBase with all descendants based on element input type (namely
138  * for FieldConstant) given by element_input_type pointer.
139  */
140  static const Input::Type::Instance & get_input_type_instance( Input::Type::Selection value_selection=Input::Type::Selection() );
141 
142  /**
143  * Returns auxiliary record with keys common to all field algorithms.
144  */
145  static const Input::Type::Record & get_field_algo_common_keys();
146 
147  /**
148  * This static method gets accessor to abstract record with function input,
149  * dispatch to correct constructor and initialize appropriate function object from the input.
150  * Returns shared pointer to FunctionBase<>.
151  */
152  static std::shared_ptr< FieldAlgorithmBase<spacedim, Value> >
153  function_factory(const Input::AbstractRecord &rec, const struct FieldAlgoBaseInitData& init_data);
154 
155  /**
156  * Function can provide way to initialize itself from the input data.
157  *
158  * TODO: make protected, should be called through function factory
159  */
160  virtual void init_from_input(const Input::Record &rec, const struct FieldAlgoBaseInitData& init_data);
161 
162  /**
163  * Set new time value. Some Fields may and some may not implement time dependent values and
164  * possibly various types of interpolation. There can not be unified approach to interpolation (at least not on this abstraction level)
165  * since some fields (FieldFormula, FieldPython) provides naturally time dependent functions other fields like (FieldConstant, ...), however,
166  * can be equipped by various time interpolation schemes. In future, we obviously need time interpolation of higher order so that
167  * we can use ODE integrators of higher order.
168  *
169  * The method returns true if the value of the field has changed in the new time step.
170  */
171  virtual bool set_time(const TimeStep &time);
172 
173  /**
174  * Is used only by some Field implementations, but can be used to check validity of incoming ElementAccessor in value methods.
175  *
176  * Optional parameter @p boundary_domain can be used to specify, that the field will be evaluated only on the boundary part of the mesh.
177  * TODO: make separate mesh for the boundary, then we can drop this parameter.
178  */
179  virtual void set_mesh(const Mesh *mesh, bool boundary_domain);
180 
181  /**
182  * Sets @p component_idx_
183  */
184  void set_component_idx(unsigned int idx)
185  { this->component_idx_ = idx; }
186 
187  /**
188  * Returns number of rows, i.e. number of components for variable size vectors. For values of fixed size returns zero.
189  */
190  unsigned int n_comp() const;
191 
192  /**
193  * Special field values spatially constant. Could allow optimization of tensor multiplication and
194  * tensor or vector addition. field_result_ should be set in constructor and in set_time method of particular Field implementation.
195  */
197  { return field_result_;}
198 
199  /**
200  * Method for getting some information about next time where the function change its character.
201  * Used to add appropriate TimeMarks.
202  * TODO: think what kind of information we may need, is the next time value enough?
203  */
204  virtual double next_change_time()
205  { ASSERT(false).error("Not implemented yet."); return 0.0; }
206 
207  /**
208  * Returns one value in one given point @p on an element given by ElementAccessor @p elm.
209  * It returns reference to he actual value in order to avoid temporaries for vector and tensor values.
210  *
211  * This method just call the later one @p value(Point, ElementAccessor, Value) and drops the FieldResult.
212  *
213  * Usual implementation of this method fills @p member r_value_ through unified envelope @p value_ as general tensor
214  * and then returns member @p r_value_. However, some particular Fields may have result stored elsewhere, in such a case
215  * the reference to the result can be returned directly without using the member @p value_. Keeping such wide space for optimization
216  * has drawback in slow generic implementation of the @p value_list method that fills whole vector of values for vector of points.
217  * Its generic implementation has to copy all values instead of directly store them into the vector of result values.
218  *
219  * So the best practice when implementing @p value and @value_list methods in particular FieldBase descendant is
220  * implement some thing like value(point, elm, Value::return_type &value) and using
221  * s having in part
222  *
223  */
224  virtual typename Value::return_type const &value(const Point &p, const ElementAccessor<spacedim> &elm)=0;
225 
226  /**
227  * Returns std::vector of scalar values in several points at once. The base class implements
228  * trivial implementation using the @p value(,,) method. This is not optimal as it involves lot of virtual calls,
229  * but this overhead can be negligible for more complex fields as Python of Formula.
230  *
231  * FieldAlgorithmBase provides a slow implementation using the value() method. Derived Field can implement its value_list method
232  * as call of FieldAlgoritmBase<...>::value_list().
233  */
234  virtual void value_list(const Armor::array &point_list, const ElementAccessor<spacedim> &elm,
236 
237  virtual void cache_update(FieldValueCache<typename Value::element_type> &data_cache,
238  ElementCacheMap &cache_map, unsigned int region_idx);
239 
240  /**
241  * Postponed setter of Dof handler for FieldFE. For other types of fields has no effect.
242  */
243  virtual void set_native_dh(std::shared_ptr<DOFHandlerMultiDim>)
244  {}
245 
246  /**
247  * Return true if field is only dependent on time.
248  */
249  inline bool is_constant_in_space() const {
250  return is_constant_in_space_;
251  }
252 
253  /**
254  * Virtual destructor.
255  */
256  virtual ~FieldAlgorithmBase() {}
257 
258 
259 protected:
260  /// Init value of @p unit_conversion_coefficient_ from input
261  void init_unit_conversion_coefficient(const Input::Record &rec, const struct FieldAlgoBaseInitData& init_data);
262  /// Actual time level; initial value is -infinity.
264  /// Last value, prevents passing large values (vectors) by value.
266  typename Value::return_type r_value_;
267  /// Indicator of particular values (zero, one) constant over space.
269  /// Specify if the field is part of a MultiField and which component it is
270  unsigned int component_idx_;
271  /// Coeficient of conversion of user-defined unit
273  /// Flag detects that field is only dependent on time
275 };
276 
277 
278 #endif /* FUNCTION_BASE_HH_ */
TimeStep time_
Actual time level; initial value is -infinity.
virtual double next_change_time()
TYPEDEF_ERR_INFO(EI_KeyName, const string)
unsigned int component_idx_
Specify if the field is part of a MultiField and which component it is.
Armor::ArmaVec< double, spacedim > Point
Definition: point.hh:42
FieldResult field_result_
Indicator of particular values (zero, one) constant over space.
Abstract linear system class.
Definition: balance.hh:40
FieldFlag::Flags flags_
Definitions of ASSERTS.
Directing class of FieldValueCache.
Definition: mesh.h:78
Helper class that stores data of generic types.
Definition: type_generic.hh:89
Helper struct stores data for initizalize descentants of FieldAlgorithmBase.
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:347
virtual void set_native_dh(std::shared_ptr< DOFHandlerMultiDim >)
Value::return_type r_value_
Basic time management class.
static constexpr bool value
Definition: json.hpp:87
double unit_conversion_coefficient_
Coeficient of conversion of user-defined unit.
bool is_constant_in_space() const
FieldResult field_result() const
Accessor to the data with type Type::Record.
Definition: accessors.hh:292
Provides the numbering of the finite element degrees of freedom on the computational mesh...
Definition: dofhandler.hh:151
FieldAlgoBaseInitData(std::string field_name, unsigned int n_comp, const UnitSI &unit_si)
Simplified constructor, set limit values automatically (used in unit tests)
Space< spacedim >::Point Point
Class for declaration of polymorphic Record.
Accessor to the polymorphic input data of a type given by an AbstracRecord object.
Definition: accessors.hh:459
FieldResult
const UnitSI & unit_si_
bool is_constant_in_space_
Flag detects that field is only dependent on time.
Value value_
Last value, prevents passing large values (vectors) by value.
virtual ~FieldAlgorithmBase()
void set_component_idx(unsigned int idx)
std::pair< double, double > limits_
Record type proxy class.
Definition: type_record.hh:182
FieldAlgoBaseInitData(std::string field_name, unsigned int n_comp, const UnitSI &unit_si, std::pair< double, double > limits, FieldFlag::Flags flags)
Full constructor.
Class for representation SI units of Fields.
Definition: unit_si.hh:40
DECLARE_INPUT_EXCEPTION(ExcInputMessage,<< EI_Message::val)
Simple input exception that accepts just string message.
Representation of one time step..
Template for classes storing finite set of named values.