Flow123d  master-ae9ffcc
field_constant.cc
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_constant.cc
15  * @brief
16  */
17 
18 #include "fields/field_constant.hh"
20 #include "fields/field_instances.hh" // for instantiation macros
21 #include "fields/field_values.hh"
22 #include "input/input_type.hh"
23 #include "system/armor.hh"
24 
25 
26 /// Implementation.
27 
28 namespace it = Input::Type;
29 
30 FLOW123D_FORCE_LINK_IN_CHILD(field_constant)
31 
32 
33 template <int spacedim, class Value>
35  if (Value::NRows_ == Value::NCols_) {
36  // for square tensors allow initialization by diagonal vector, etc.
37  return it::Array( it::Array( it::Parameter("element_input_type"), 1), 1 );
38  }
39  else {
40  return it::Array( it::Array( it::Parameter("element_input_type"), Value::NCols_, Value::NCols_), Value::NRows_, Value::NRows_ );
41  }
42 
43 }
44 
45 template <int spacedim, class Value>
47 {
48  return it::Record("FieldConstant", FieldAlgorithmBase<spacedim,Value>::template_name()+" Field constant in space.")
52  "Value of the constant field. "
53  "For vector values, you can use scalar value to enter constant vector. "
54  "For square (($N\\times N$))-matrix values, you can use: "
55  " - vector of size (($N$)) to enter diagonal matrix\n\n"
56  " - vector of size (($\\frac12N(N+1)$)) to enter symmetric matrix (upper triangle, row by row)\n"
57  " - scalar to enter multiple of the unit matrix." )
58  //.declare_key("unit", FieldAlgorithmBase<spacedim, Value>::get_input_type_unit_si(), it::Default::optional(),
59  // "Definition of unit.")
60  .allow_auto_conversion("value")
61  .close();
62 }
63 
64 template <int spacedim, class Value>
66  Input::register_class< FieldConstant<spacedim, Value>, unsigned int >("FieldConstant") +
68 
69 
70 template <int spacedim, class Value>
72 : FieldAlgorithmBase<spacedim, Value>(n_comp)
73 {
74  this->is_constant_in_space_ = true;
75 }
76 
77 
78 template <int spacedim, class Value>
80 {
81  this->r_value_ = val;
82 
83  return *this;
84 }
85 
86 
87 template <int spacedim, class Value>
89  this->init_unit_conversion_coefficient(rec, init_data);
90 
91  this->value_.init_from_input( rec.val<Input::Array>("value") );
92  this->value_.scale(this->unit_conversion_coefficient_);
93  this->check_field_limits(rec, init_data);
94 
95  typename Value::return_type tmp_value;
96  Value tmp_field_value(tmp_value);
97  tmp_field_value.set_n_comp(this->n_comp());
98 
99  tmp_field_value.zeros();
100  if ( this->value_.equal_to(tmp_value) ) {
101  this->field_result_ = result_zeros;
102  return;
103  }
104 
105 
106  tmp_field_value.ones();
107  if ( this->value_.equal_to(tmp_value) ) {
108  this->field_result_ = result_ones;
109  return;
110  }
111 
112  // This check must be the last one, since for scalar and vector values ones() == eye().
113  // For vector, eye() does nothing. So, the value of tmp_value remains equal to ones().
114  tmp_field_value.eye();
115  if ( this->value_.equal_to(tmp_value) ) {
116  this->field_result_ = result_eye;
117  return;
118  }
119 
120 
121  this->field_result_ = result_constant;
122 }
123 
124 
125 
126 template <int spacedim, class Value>
128  ElementCacheMap &cache_map, unsigned int region_patch_idx)
129 {
130  unsigned int reg_chunk_begin = cache_map.region_chunk_begin(region_patch_idx);
131  unsigned int reg_chunk_end = cache_map.region_chunk_end(region_patch_idx);
132  Armor::ArmaMat<typename Value::element_type, Value::NRows_, Value::NCols_> mat_value( const_cast<typename Value::element_type*>(this->value_.mem_ptr()) );
133  for (unsigned int i_cache = reg_chunk_begin; i_cache < reg_chunk_end; ++i_cache)
134  data_cache.set(i_cache) = mat_value;
135 }
136 
137 
138 template <int spacedim, class Value>
140 {
141  if (Value::is_scalable())
142  for( unsigned int row=0; row<this->value_.n_rows(); row++)
143  for( unsigned int col=0; col<this->value_.n_cols(); col++) {
144  if ( (this->value_(row,col) < init_data.limits_.first) || (this->value_(row,col) > init_data.limits_.second) ) {
145  WarningOut().fmt("Value '{}' of Field '{}' at address '{}' is out of limits: <{}, {}>\nUnit of the Field: [{}]\n",
146  this->value_(row,col), init_data.field_name_, rec.address_string(),
147  init_data.limits_.first, init_data.limits_.second, init_data.unit_si_.format_text() );
148  }
149  }
150 }
151 
152 
153 
154 template <int spacedim, class Value>
156 }
157 
158 
159 // Instantiations of FieldConstant
161 
162 // temporary solution for computing more fields at once in python
163 template class FieldConstant<3, FieldValue<0>::Vector >; // Necessary due to default value of the abstract.
164 
ArrayMatSet set(uint index)
Definition: armor.hh:886
Directing class of FieldValueCache.
unsigned int region_chunk_end(unsigned int region_patch_idx) const
Return end position of region chunk in FieldValueCache.
unsigned int region_chunk_begin(unsigned int region_patch_idx) const
Return begin position of region chunk in FieldValueCache.
bool is_constant_in_space_
Flag detects that field is only dependent on time.
void cache_update(FieldValueCache< typename Value::element_type > &data_cache, ElementCacheMap &cache_map, unsigned int region_patch_idx) override
static const Input::Type::Record & get_input_type()
void check_field_limits(const Input::Record &rec, const struct FieldAlgoBaseInitData &init_data)
Compare field value with given minimal and maximal limits.
FieldConstant< spacedim, Value > & set_value(const typename Value::return_type &val)
static Input::Type::Array get_tensor_input_type()
Implementation.
FieldConstant(unsigned int n_comp=0)
virtual ~FieldConstant()
virtual void init_from_input(const Input::Record &rec, const struct FieldAlgoBaseInitData &init_data) override
Accessor to input data conforming to declared Array.
Definition: accessors.hh:566
Accessor to the data with type Type::Record.
Definition: accessors.hh:291
string address_string() const
Definition: accessors.cc:184
const Ret val(const string &key) const
Class for declaration of inputs sequences.
Definition: type_base.hh:339
static Default obligatory()
The factory function to make an empty default value which is obligatory.
Definition: type_record.hh:110
Class for representing parametric types in IST.
Definition: type_generic.hh:53
Record type proxy class.
Definition: type_record.hh:182
virtual Record & allow_auto_conversion(const string &from_key)
Allows shorter input of the Record providing only value of the from_key given as the parameter.
Definition: type_record.cc:133
virtual Record & derive_from(Abstract &parent)
Method to derive new Record from an AbstractRecord parent.
Definition: type_record.cc:196
Record & close() const
Close the Record for further declarations of keys.
Definition: type_record.cc:304
Record & copy_keys(const Record &other)
Copy keys from other record.
Definition: type_record.cc:216
Record & declare_key(const string &key, std::shared_ptr< TypeBase > type, const Default &default_value, const string &description, TypeBase::attribute_map key_attributes=TypeBase::attribute_map())
Declares a new key of the Record.
Definition: type_record.cc:503
std::string format_text() const
Definition: unit_si.cc:127
@ result_zeros
@ result_eye
@ result_ones
@ result_constant
#define INSTANCE_ALL(field)
@ Value
#define FLOW123D_FORCE_LINK_IN_CHILD(x)
Definition: global_defs.h:104
#define WarningOut()
Macro defining 'warning' record of log.
Definition: logger.hh:278
typename arma::Mat< Type >::template fixed< nr, nc > ArmaMat
Definition: armor.hh:502
Helper struct stores data for initizalize descentants of FieldAlgorithmBase.
const UnitSI & unit_si_
std::pair< double, double > limits_