Flow123d  3.9.0-3aaaea010
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 field.hh
15  * @brief
16  */
17 
18 #ifndef FIELD_HH_
19 #define FIELD_HH_
20 
21 #include <stdio.h> // for sprintf
22 #include <string.h> // for memcpy
23 #include <algorithm> // for find, min
24 #include <boost/circular_buffer.hpp>
25 #include <memory> // for dynamic_pointe...
26 #include <new> // for operator new[]
27 #include <ostream> // for basic_ostream:...
28 #include <string> // for basic_string
29 #include <utility> // for pair
30 #include <vector> // for vector
31 #include <armadillo>
32 #include "fields/field_algo_base.hh" // for FieldAlgorithm...
33 #include "fields/field_common.hh" // for FieldCommon::T...
34 #include "fields/field_values.hh" // for FieldValue<>::...
35 #include "fields/field_value_cache.hh" // for FieldValueCache
36 #include "input/accessors.hh" // for ExcTypeMismatch
37 #include "input/accessors_impl.hh" // for Record::opt_val
38 #include "input/factory_impl.hh" // for Factory::create
39 #include "input/input_exception.hh" // for FieldCommon::E...
40 #include "input/storage.hh" // for ExcStorageType...
41 #include "input/type_base.hh" // for Array
42 #include "input/type_generic.hh" // for Instance
43 #include "input/type_record.hh" // for Record::ExcRec...
44 #include "input/input_exception.hh" // for Input::Exception
45 #include "io/output_time.hh" // for OutputTime
46 #include "mesh/elements.h" // for Element::dim
47 #include "mesh/region.hh" // for RegionDB::ExcU...
48 #include "system/asserts.hh" // for Assert, ASSERT
49 #include "system/exceptions.hh" // for ExcAssertMsg::...
50 #include "tools/time_governor.hh" // for TimeStep
51 
52 class Mesh;
53 class Observe;
54 class EvalPoints;
55 class BulkPoint;
56 class SidePoint;
57 class FieldSet;
58 template <int spacedim> class ElementAccessor;
59 template <int spacedim, class Value> class FieldFE;
60 namespace detail
61 {
62  template< typename CALLABLE, typename TUPLE, int INDEX >
64 }
65 
66 using namespace std;
67 namespace IT=Input::Type;
68 
69 /**
70  * @brief Class template representing a field with values dependent on: point, element, and region.
71  *
72  * By "field" we mean a mapping of a a pair (Point, Time) to a @p Value, where
73  * Point is from @p spacedim dimensional ambient space, Time is real number (set by @p set_time method),
74  * and @p Value type representing range of the field, which can be: real scalar, integer scalar (a discrete value),
75  * real vector of fixed (compile time) size, real vector of runtime size, or a matrix of fixed dimensions.
76  * Extensions to vectors or matrices of integers, or to variable tensors are possible. For vector and matrix values
77  * we use classes provided by Armadillo library for linear algebra.
78  * The @p Value template parameter should FieldValue<> template, usual choices are:
79  * FieldValue<spacedim>::Scalar, FieldValue<spacedim>::Integer, FieldValue<spacedim>::Enum,
80  * FieldValue<spacedim>::VectorFixed, FieldValue<spacedim>::TensorFixed.
81  *
82  * This class assign particular fields (instances of descendants of FiledBase) to the regions. It keeps a table of pointers to fields for every possible bulk
83  * region index (very same functionality, but for boundary regions is provided by @p BCField class). This class has interface very similar to FiledBase, however
84  * key methods @p value, and @p value_list are not virtual in this class by contrast these methods are inlined to minimize overhead for
85  * simplest fields like FieldConstant.
86  *
87  * TODO: currently it works only for spacedim==3 since we have only mesh in 3D ambient space.
88  *
89  */
90 template<int spacedim, class Value>
91 class Field : public FieldCommon {
92 public:
93 
95  typedef std::shared_ptr< FieldBaseType > FieldBasePtr;
97  typedef Value ValueType;
98 
99  static const unsigned int space_dim = spacedim;
100 
101 
102  /**
103  * Factory class that creates an instance of FieldBase for field
104  * with name @p field_name based on data in field descriptor @p rec.
105  *
106  * Default implementation in method @p create_field just reads key given by
107  * @p field_name and creates instance using @p FieldBase<...>::function_factory.
108  * Function should return empty SharedField (that is shared_ptr to FieldBase).
109  *
110  * Implementation of these descendants is necessary:
111  * 1) for backward compatibility with old BCD input files
112  * 2) for setting pressure values are piezometric head values
113  */
114  /**
115  * Note for future:
116  * We pass through parameter @p field information about field that holds the factory which are necessary
117  * for interpreting user input and create particular field instance. It would be clearer to pass these information
118  * when the factory is assigned to a field. Moreover some information may not be set to field at all but directly passed
119  * to the factory.
120  */
121  class FactoryBase {
122  public:
123  /**
124  * Default method that creates an instance of FieldBase for field.
125  *
126  * Reads key given by @p field_name and creates the field instance using
127  * @p FieldBase<...>::function_factory.
128  */
129  virtual FieldBasePtr create_field(Input::Record rec, const FieldCommon &field);
130 
131  /**
132  * Check if Input::Record accessor contains data of field given by input_name.
133  *
134  * Returns true when ever the method create_field returns non-null pointer, otherwise returns false.
135  */
136  virtual bool is_active_field_descriptor(const Input::Record &in_rec, const std::string &input_name);
137  };
138 
139  /**
140  * Default constructor.
141  *
142  */
143  Field();
144 
145  Field(const string &name, bool bc = false);
146 
147  /**
148  * Constructor that must be used for create of MultiField components.
149  *
150  * Set parameters @p component_index_, @p shared_->input_name_ and @p name_.
151  * Parameter name_ of Field is consisted of component name and MultiField name.
152  */
153  Field(unsigned int component_index, string input_name, string name = "", bool bc = false);
154 
155  /**
156  * Copy constructor. Keeps shared history, declaration data, mesh.
157  */
158  Field(const Field &other);
159 
160  /**
161  * Assignment operator. Same properties as copy constructor, but class member name_ is not copied.
162  *
163  * Question: do we really need this, isn't copy constructor enough?
164  * Answer: It is necessary in (usual) case when Field instance is created as the class member
165  * but is filled later by assignment possibly from other class.
166  * TODO: operator can be merged with copy constructor, but we must provide to set correct value
167  * of name in method copy_from
168  */
169  Field &operator=(const Field &other);
170 
171 
172  /// Return appropriate value to BulkPoint in FieldValueCache
173  typename Value::return_type operator() (BulkPoint &p);
174 
175 
176  /// Return appropriate value to EdgePoint in FieldValueCache
177  typename Value::return_type operator() (SidePoint &p);
178 
179 
180  /**
181  * Returns reference to input type of particular field instance, this is static member @p input_type of the corresponding FieldBase class
182  * (i.e. with same template parameters). However, for fields returning "Enum" we have to create whole unique Input::Type hierarchy using following method
183  * @p make_input_tree.
184  * every instance since every such field use different Selection for initialization, even if all returns just unsigned int.
185  */
186  IT::Instance get_input_type() override;
187 
188  IT::Array get_multifield_input_type() override;
189 
190 
191  /**
192  * 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
193  * FieldConstant and has value in given @p value_list. We check this in the set_time method. Through this mechanism we
194  * can switch of e.g. boundary data fields according to the type of the boundary condition.
195  */
196  auto disable_where(
197  const Field<spacedim, typename FieldValue<spacedim>::Enum > &control_field,
198  const vector<FieldEnum> &value_list) -> Field &;
199 
200 
201 
202  /**
203  * Set mesh pointer and resize region arrays.
204  *
205  * Implements abstract method.
206  */
207  void set_mesh(const Mesh &mesh) override;
208 
209 
210  /**
211  * Direct read access to the table of Field pointers on regions.
212  */
213  //std::shared_ptr< FieldBaseType > operator[] (Region reg);
214 
215  /**
216  * Implementation of @p FieldCommonBase::is_constant().
217  * See also Field<>::field_result which provide better information about special field values.
218  */
219  bool is_constant(Region reg) override;
220 
221  /**
222  * Assigns given @p field to all regions in region set given by @p region_set_names.
223  * Field is added to the history with given time and possibly used in the next call of the set_time method.
224  * Caller is responsible for correct construction of given field.
225  *
226  * Use this method only if necessary.
227  */
228  void set(FieldBasePtr field, double time, std::vector<std::string> region_set_names = {"ALL"});
229 
230  /**
231  * Same as before but the field is first created using FieldBase::function_factory(), from
232  * given abstract record accessor @p a_rec.
233  */
234  void set(const Input::AbstractRecord &a_rec, double time, std::vector<std::string> region_set_names = {"ALL"});
235 
236  /**
237  * Check that whole field list is set, possibly use default values for unset regions
238  * and call set_time for every field in the field list.
239  *
240  * Returns true if the field has been changed.
241  */
242  bool set_time(const TimeStep &time, LimitSide limit_side) override;
243 
244  /**
245  * Check that other has same type and assign from it.
246  */
247  void copy_from(const FieldCommon & other) override;
248 
249  /**
250  * Implementation of FieldCommonBase::output().
251  */
252  void field_output(std::shared_ptr<OutputTime> stream, OutputTime::DiscreteSpace type) override;
253 
254  /**
255  * Implementation of FieldCommonBase::observe_output().
256  */
257  void observe_output(std::shared_ptr<Observe> observe) override;
258 
259  /**
260  * Returns true, if field is currently set to a time in which it is discontinuous.
261  */
262  //bool is_jump_time();
263 
264 
265  /**
266  * @brief Indicates special field states.
267  *
268  * Return possible values from the enum @p FieldResult, see description there.
269  * The initial state is @p field_none, if the field is correctly set on all regions of the @p region_set given as parameter
270  * we return state @p field_other
271  * - Special field values spatially constant. Could allow optimization of tensor multiplication and
272  * tensor or vector addition. field_result_ should be set in constructor and in set_time method of particular Field implementation.
273  * We return value @p result_none, if the field is not initialized on the region of the given element accessor @p elm.
274  * Other possible results are: result_zeros, result_eye, result_ones, result_constant, result_other
275  * see @p FieldResult for explanation.
276  */
277  FieldResult field_result( RegionSet region_set) const override;
278 
279  /**
280  * Return value of input type attribute 'field_value_shape' that is appended to the
281  * input type of this field in FieldSet::make_field_descriptor_type and also to the output field selection
282  * created in EquationOutput::make_output_type.
283  * This attribute is used by GeoMop to have semantics of the input and output field data.
284  *
285  * Attribute value is a valid JSON (and/or flow style YAML) with keys:
286  * 'subfields' - value True for multifields, False or not presented for single value fields
287  * 'shape' - [ NRows, Ncols] ... given by FieldValue
288  * 'type' - <element type> (Double or Integer) ... given by FieldValue
289  * 'limit' - bounds of the field values.
290  *
291  */
292  std::string get_value_attribute() const override;
293 
294  /**
295  * Returns one value in one given point @p on an element given by ElementAccessor @p elm.
296  * It returns reference to he actual value in order to avoid temporaries for vector and tensor values.
297  */
298  virtual typename Value::return_type const &value(const Point &p, const ElementAccessor<spacedim> &elm) const;
299 
300  /**
301  * Returns std::vector of scalar values in several points at once. The base class implements
302  * trivial implementation using the @p value(,,) method. This is not optimal as it involves lot of virtual calls,
303  * but this overhead can be negligible for more complex fields as Python of Formula.
304  */
305  virtual void value_list(const Armor::array &point_list, const ElementAccessor<spacedim> &elm,
306  std::vector<typename Value::return_type> &value_list) const;
307 
308  /**
309  * Add a new factory for creating Field algorithms on individual regions.
310  * The last factory is tried first, the last one is always the default implementation
311  * Field<...>::FactoryBase.
312  *
313  * The Field<...> object keeps a list of such factories. When the instance of a new field algorithm
314  * has to be created from the input field descriptor, we pass through the list of factories backward
315  * and let factories to create the field algorithm instance from the actual input field descriptor.
316  * The first instance (non-null pointer) is used.
317  */
318  void add_factory(std::shared_ptr<FactoryBase> factory);
319 
320  void set_input_list(const Input::Array &list, const TimeGovernor &tg) override;
321 
322  /**
323  * Create and return shared_ptr to ElementDataCache appropriate to Field. Data cache is given by discrete @p space_type
324  * and is stored into data structures of output time @p stream for postponed output too.
325  */
326  void set_output_data_cache(OutputTime::DiscreteSpace space_type, std::shared_ptr<OutputTime> stream) override;
327 
328  /**
329  * Interpolate given field into output discrete @p space_type and store the values
330  * into storage of output time @p stream for postponed output.
331  */
332  void compute_field_data(OutputTime::DiscreteSpace space_type, std::shared_ptr<OutputTime> stream);
333 
334  /// Implements FieldCommon::cache_allocate
335  void cache_reallocate(const ElementCacheMap &cache_map, unsigned int region_idx) const override;
336 
337  /// Implements FieldCommon::cache_update
338  void cache_update(ElementCacheMap &cache_map, unsigned int region_patch_idx) const override;
339 
340  /// Implements FieldCommon::value_cache
341  FieldValueCache<double> * value_cache() override;
342 
343  /// Implements FieldCommon::value_cache
344  const FieldValueCache<double> * value_cache() const override;
345 
346  /**
347  * Implementation of FieldCommon::set_dependency().
348  */
349  std::vector<const FieldCommon *> set_dependency(FieldSet &field_set, unsigned int i_reg) const override;
350 
351  /// Implements FieldCommon::fill_data_value
352  void fill_data_value(const std::vector<int> &offsets) override;
353 
354 protected:
355 
356  /// Return item of @p value_cache_ given by i_cache_point.
357  typename Value::return_type operator[] (unsigned int i_cache_point) const;
358 
359  /**
360  * Read input into @p regions_history_ possibly pop some old values from the
361  * history queue to keep its size less then @p history_length_limit_.
362  */
363  void update_history(const TimeStep &time);
364 
365  /**
366  * Check that whole field list (@p region_fields_) is set, possibly use default values for unset regions.
367  */
368  void check_initialized_region_fields_();
369 
370  /**
371  * Check that the field is in fact FieldFE set on all bulk regions, return shared pointer to that FieldFE or NULL
372  * if the Field is not FieldFE.
373  */
374  std::shared_ptr< FieldFE<spacedim, Value> > get_field_fe();
375 
376  /**************** Shared data **************/
377 
378  /// Pair: time, pointer to FieldBase instance
379  typedef pair<double, FieldBasePtr> HistoryPoint;
380  /// Nearest history of one region.
381  typedef boost::circular_buffer<HistoryPoint> RegionHistory;
382 
383  struct SharedData {
384 
385  /**
386  * History for every region. Shared among copies.
387  */
389  };
390 
391  /**************** Data per copy **************/
392 
393  std::shared_ptr<SharedData> data_;
394 
395  /**
396  * If this pointer is set, turn off check of initialization in the
397  * @p set_time method on the regions where the method @p get_constant_enum_value
398  * of the control field returns value from @p no_check_values_. This
399  * field is private copy, its set_time method is called from the
400  * set_Time method of actual object.
401  */
403  std::shared_ptr<ControlField> no_check_control_field_;
404 
405  /**
406  * Table with pointers to fields on individual regions.
407  */
409 
411 
412  /**
413  * Field value data cache
414  *
415  * Data is ordered like three dimensional table. The highest level is determinated by subsets,
416  * those data ranges are holds in subset_starts. Data block size of each subset is determined
417  * by number of eval_points (of subset) and maximal number of stored elements.
418  * The table is allocated to hold all subsets, but only those marked in used_subsets are updated.
419  * Order of subsets is same as in eval_points.
420  */
422 
423  /// ElementDataCache used during field output, object is shared with OutputTime
424  std::shared_ptr<ElementDataCache<typename Value::element_type>> output_data_cache_;
425 
426 
427 
428  template<int dim, class Val>
429  friend class MultiField;
430 
431  template< typename CALLABLE, typename TUPLE, int INDEX >
433 
434 };
435 
436 
437 
438 
439 
440 
441 
442 /****************************************************************************************
443  * Inlined methods of Field< ... >
444  */
445 
446 template<int spacedim, class Value>
447 inline typename Value::return_type const & Field<spacedim,Value>::value(const Point &p, const ElementAccessor<spacedim> &elm) const
448 {
449 
450  ASSERT(this->set_time_result_ != TimeStatus::unknown)(this->name()).error("Unknown time status.\n");
451  ASSERT_LT(elm.region_idx().idx(), region_fields_.size() )(this->name()).error("Region idx is out of range\n");
452  ASSERT( region_fields_[elm.region_idx().idx()] )(elm.region().id())(elm.region_idx().idx())(this->name())
453  .error("Null field ptr on region\n");
454  return region_fields_[elm.region_idx().idx()]->value(p,elm);
455 }
456 
457 
458 
459 template<int spacedim, class Value>
462 {
463  ASSERT(this->set_time_result_ != TimeStatus::unknown)(this->name()).error("Unknown time status.\n");
464  ASSERT_LT(elm.region_idx().idx(), region_fields_.size() )(this->name()).error("Region idx is out of range\n");
465  ASSERT( region_fields_[elm.region_idx().idx()] )(elm.region().id())(elm.region_idx().idx())(this->name())
466  .error("Null field ptr on region\n");
467  ASSERT(point_list.n_rows() == spacedim && point_list.n_cols() == 1).error("Invalid point size.\n");
468 
469  region_fields_[elm.region_idx().idx()]->value_list(point_list,elm, value_list);
470 }
471 
472 
473 
474 
475 
476 
477 #endif /* FIELD_HH_ */
detail::model_cache_item
base case for building up arguments for the function call
Definition: field.hh:63
Observe
Definition: observe.hh:198
Field::SharedData::region_history_
std::vector< RegionHistory > region_history_
Definition: field.hh:388
Field::HistoryPoint
pair< double, FieldBasePtr > HistoryPoint
Pair: time, pointer to FieldBase instance.
Definition: field.hh:379
time_governor.hh
Basic time management class.
field_algo_base.hh
Field::value_cache_
FieldValueCache< typename Value::element_type > value_cache_
Definition: field.hh:421
ASSERT
#define ASSERT(expr)
Definition: asserts.hh:351
string.h
ElementCacheMap
Directing class of FieldValueCache.
Definition: field_value_cache.hh:151
asserts.hh
Definitions of ASSERTS.
value
static constexpr bool value
Definition: json.hpp:87
FieldResult
FieldResult
Definition: field_algo_base.hh:70
BulkPoint
Base point accessor class.
Definition: eval_subset.hh:55
Field::output_data_cache_
std::shared_ptr< ElementDataCache< typename Value::element_type > > output_data_cache_
ElementDataCache used during field output, object is shared with OutputTime.
Definition: field.hh:424
detail
Definition: field.hh:60
std::vector< FieldEnum >
ElementAccessor
Definition: dh_cell_accessor.hh:32
SidePoint
General point a+ side_begin_ + ccessor allow iterate over quadrature points of given side defined in ...
Definition: eval_subset.hh:116
RegionIdx::idx
unsigned int idx() const
Returns a global index of the region.
Definition: region.hh:81
type_base.hh
FieldAlgorithmBase::Point
Space< spacedim >::Point Point
Definition: field_algo_base.hh:115
Field::FactoryBase
Definition: field.hh:121
storage.hh
exceptions.hh
type_record.hh
ASSERT_LT
#define ASSERT_LT(a, b)
Definition of comparative assert macro (Less Than) only for debug mode.
Definition: asserts.hh:301
Region::id
unsigned int id() const
Returns id of the region (using RegionDB)
Definition: region.cc:37
Armor::Array::n_rows
uint n_rows() const
Definition: armor.hh:715
Region
Definition: region.hh:145
Field::Point
FieldAlgorithmBase< spacedim, Value >::Point Point
Definition: field.hh:96
Input::Record
Accessor to the data with type Type::Record.
Definition: accessors.hh:291
elements.h
type_generic.hh
accessors.hh
TimeStep
Representation of one time step..
Definition: time_governor.hh:123
TimeGovernor
Basic time management functionality for unsteady (and steady) solvers (class Equation).
Definition: time_governor.hh:317
output_time.hh
field_values.hh
Input::AbstractRecord
Accessor to the polymorphic input data of a type given by an AbstracRecord object.
Definition: accessors.hh:458
FieldCommon
Common abstract parent of all Field<...> classes.
Definition: field_common.hh:76
Field::data_
std::shared_ptr< SharedData > data_
Definition: field.hh:393
Field::factories_
std::vector< std::shared_ptr< FactoryBase > > factories_
Definition: field.hh:410
Input::Type::Instance
Helper class that stores data of generic types.
Definition: type_generic.hh:89
LimitSide
LimitSide
Definition: field_common.hh:63
input_exception.hh
Field::region_fields_
std::vector< FieldBasePtr > region_fields_
Definition: field.hh:408
FieldSet
Container for various descendants of FieldCommonBase.
Definition: field_set.hh:159
Field::RegionHistory
boost::circular_buffer< HistoryPoint > RegionHistory
Nearest history of one region.
Definition: field.hh:381
Armor::Array::n_cols
uint n_cols() const
Definition: armor.hh:720
FieldValue_
Definition: field_values.hh:248
Input::Type
Definition: balance.hh:41
Field::value
virtual const Value::return_type & value(const Point &p, const ElementAccessor< spacedim > &elm) const
Definition: field.hh:447
Value
@ Value
Definition: finite_element.hh:43
Field::FieldBasePtr
std::shared_ptr< FieldBaseType > FieldBasePtr
Definition: field.hh:95
Field::FieldBaseType
FieldAlgorithmBase< spacedim, Value > FieldBaseType
Definition: field.hh:94
FieldFE
Definition: field.hh:59
Mesh
Definition: mesh.h:361
Field::no_check_control_field_
std::shared_ptr< ControlField > no_check_control_field_
Definition: field.hh:403
FieldAlgorithmBase
Definition: field_algo_base.hh:112
Input::Type::Array
Class for declaration of inputs sequences.
Definition: type_base.hh:339
accessors_impl.hh
factory_impl.hh
Field::value_list
virtual void value_list(const Armor::array &point_list, const ElementAccessor< spacedim > &elm, std::vector< typename Value::return_type > &value_list) const
Definition: field.hh:460
Input::Array
Accessor to input data conforming to declared Array.
Definition: accessors.hh:566
std
Definition: doxy_dummy_defs.hh:5
ElementAccessor::region
Region region() const
Definition: accessors.hh:198
MultiField
Class for representation of a vector of fields of the same physical quantity.
Definition: multi_field.hh:87
field_value_cache.hh
Field::SharedData
Definition: field.hh:383
region.hh
Field::ValueType
Value ValueType
Definition: field.hh:97
Armor::Array< double >
OutputTime::DiscreteSpace
DiscreteSpace
Definition: output_time.hh:108
Field
Class template representing a field with values dependent on: point, element, and region.
Definition: field.hh:91
std::list
Definition: doxy_dummy_defs.hh:9
field_common.hh
ElementAccessor::region_idx
RegionIdx region_idx() const
Definition: accessors.hh:201
Field::ControlField
Field< spacedim, typename FieldValue< spacedim >::Enum > ControlField
Definition: field.hh:402
EvalPoints
Class holds local coordinations of evaluating points (bulk and sides) specified by element dimension.
Definition: eval_points.hh:43