Flow123d  release_3.0.0-1191-g7740876
table_function.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 table_function.cc
15  * @brief
16  */
17 
18 #include "fields/table_function.hh"
19 #include "tools/time_governor.hh"
20 #include "input/input_type.hh"
21 #include "system/logger.hh"
22 
23 namespace it = Input::Type;
24 
25 template <class Value>
27 {
28  /*
29  * Table function is now fixed for representation of time value. It can be changed
30  * to independent value. It needs only replace type of 't' with generic type
31  * (Input::Type::Parameter).
32  */
33  return it::Tuple("IndependentValue", "Value of Field for time variable.")
34  //"Value of Field for independent variable."
36  "Time stamp." )
37  //"Independent variable of stamp."
38  .declare_key("value", Value::get_input_type(), it::Default::obligatory(),
39  "Value of the field in given stamp." )
40  .close();
41 }
42 
43 template <class Value>
45 {
46  return it::Record("TableFunction", "Allow set variable series initialization of Fields.")
48  "Initizaliation values of Field." )
49  .allow_auto_conversion("values")
50  .close();
51 
52 }
53 
54 
55 template <class Value>
57 : last_t_(-1.0),
58  value_(r_value_)
59 {}
60 
61 
62 template <class Value>
64 {
65  ASSERT( !this->initialized() ).error("TableFunction can't be initialized more than once.");
66 
67  Input::Array data_array = rec.val<Input::Array>("values");
68  double last_t = -1.0;
69  for (Input::Iterator<Input::Tuple> it = data_array.begin<Input::Tuple>(); it != data_array.end(); ++it) {
70  double t = time.read_time(it->find<Input::Tuple>("t"));
71  if (last_t >= t) {
72  WarningOut().fmt("Nonascending order of declared stamps in TableFunction at address {}.\nStamp {} will be skipped.",
73  rec.address_string(), t);
74  } else {
75  last_t = t;
76 
77  typename Value::return_type r_value;
78  Value value(r_value);
79  value.init_from_input( it->val<typename Value::AccessType>("value") );
80  table_values_.push_back( TableValue(t, value) );
81  }
82  }
83 }
84 
85 template <class Value>
87 {
88  return ( table_values_.size() > 0 );
89 }
90 
91 template <class Value>
93 {
94  ASSERT( this->initialized() ).error("Compute value of uninitialized TableFunction.");
95 
96  if (t != last_t_) {
97  unsigned int last_idx = table_values_.size() - 1;
98  if (t < table_values_[0].t_) {
99  WarningOut().fmt("Value of stamp {} is out of range of TableFunction: <{}, {}>. Extrapolation of minimal value will be used.",
100  t, table_values_[0].t_, table_values_[last_idx].t_);
101  this->interpolated(0.0, 0);
102  } else if (t > table_values_[last_idx].t_) {
103  WarningOut().fmt("Value of stamp {} is out of range of TableFunction: <{}, {}>. Extrapolation of maximal value will be used.",
104  t, table_values_[0].t_, table_values_[last_idx].t_);
105  this->interpolated(1.0, last_idx-1);
106  } else {
107  for (unsigned int i=0; i<last_idx; ++i) {
108  if (t >= table_values_[i].t_ && t <= table_values_[i+1].t_) {
109  double coef = (t - table_values_[i].t_) / (table_values_[i+1].t_ - table_values_[i].t_);
110  this->interpolated(coef, i);
111  break;
112  }
113  }
114  }
115  }
116 
117  return this->r_value_;
118 }
119 
120 template <class Value>
121 void TableFunction<Value>::interpolated(double coef, unsigned int idx)
122 {
123  ASSERT(coef >= 0 && coef <= 1)(coef).error();
124  ASSERT(idx >= 0 && idx <= table_values_.size()-2)(idx).error();
125 
126  Value val_0(table_values_[idx].r_value_);
127  Value val_1(table_values_[idx+1].r_value_);
128  if (Value::is_scalable())
129  for( unsigned int row=0; row<value_.n_rows(); row++)
130  for( unsigned int col=0; col<value_.n_cols(); col++) {
131  value_(row,col) = val_0(row,col) + coef * (val_1(row,col) - val_0(row,col));
132  }
133 }
134 
135 
136 // Instantiation of TableFunction class
137 template class TableFunction<FieldValue<0>::Enum >;
138 template class TableFunction<FieldValue<0>::Integer >;
139 template class TableFunction<FieldValue<0>::Scalar >;
140 template class TableFunction<FieldValue<0>::Vector >; // temporary solution for computing more fields at once in python
Iterator< ValueType > begin() const
return_type r_value_
bool initialized()
Return true if TableFunction is initialized (method init_from_input was called).
Accessor to input data conforming to declared Array.
Definition: accessors.hh:567
Tuple & 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())
Overrides Record::declare_key(const string &, std::shared_ptr<TypeBase>, const Default &...
Definition: type_tuple.cc:173
static Default obligatory()
The factory function to make an empty default value which is obligatory.
Definition: type_record.hh:110
const Tuple & close() const
Close the Tuple for further declarations of keys.
Definition: type_tuple.cc:70
static const Input::Type::Record & get_input_type()
Value value_
Last value, prevents passing large values (vectors) by value.
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:346
double last_t_
Last t stamp of computed value_ (to prevent repetitive calculation)
void interpolated(double coef, unsigned int idx)
Record & close() const
Close the Record for further declarations of keys.
Definition: type_record.cc:304
Basic time management class.
Class for declaration of inputs sequences.
Definition: type_base.hh:346
IteratorBase end() const
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
static const Input::Type::Tuple & get_input_time_type(double lower_bound=-std::numeric_limits< double >::max(), double upper_bound=std::numeric_limits< double >::max())
Accessor to the data with type Type::Record.
Definition: accessors.hh:292
const Ret val(const string &key) const
TableFunction()
Default constructor.
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
double read_time(Input::Iterator< Input::Tuple > time_it, double default_time=std::numeric_limits< double >::quiet_NaN()) const
Tuple type proxy class.
Definition: type_tuple.hh:45
static const Input::Type::Tuple & get_input_type_val()
return_type const & value(double t)
Value::return_type return_type
#define WarningOut()
Macro defining &#39;warning&#39; record of log.
Definition: logger.hh:246
std::vector< struct TableValue > table_values_
Vector of values in all stamps.
Record type proxy class.
Definition: type_record.hh:182
Accessor to the data with type Type::Tuple.
Definition: accessors.hh:412
Representation of one time step..
Store value in one t stamp.
void init_from_input(const Input::Record &rec, const TimeStep &time)
Initialize actual values of the field given from the given Input::Record rec.
string address_string() const
Definition: accessors.cc:184