18 #ifndef FIELD_FORMULA_IMPL_HH_
19 #define FIELD_FORMULA_IMPL_HH_
25 #include <boost/foreach.hpp>
29 namespace it = Input::Type;
34 template <
int spacedim, class Value>
35 const Input::Type::Record &
FieldFormula<spacedim, Value>::get_input_type()
41 "String, array of strings, or matrix of strings with formulas for individual "
42 "entries of scalar, vector, or tensor value respectively.\n"
43 "For vector values, you can use just one string to enter homogeneous vector.\n"
44 "For square (($N\\times N$))-matrix values, you can use:\n\n"
45 " - array of strings of size (($N$)) to enter diagonal matrix\n"
46 " - array of strings of size (($\\frac12N(N+1)$)) to enter symmetric matrix (upper triangle, row by row)\n"
47 " - just one string to enter (spatially variable) multiple of the unit matrix.\n"
48 "Formula can contain variables ```x,y,z,t``` and usual operators and functions." )
54 template <
int spacedim,
class Value>
56 Input::register_class< FieldFormula<spacedim, Value>,
unsigned int >(
"FieldFormula") +
61 template <
int spacedim,
class Value>
64 formula_matrix_(this->value_.n_rows(), this->value_.n_cols())
67 for(
unsigned int row=0; row < this->
value_.n_rows(); row++) {
74 template <
int spacedim,
class Value>
82 template <
int spacedim,
class Value>
86 bool any_parser_changed =
false;
89 std::string vars = string(
"x,y,z").substr(0, 2*spacedim-1);
91 for(
unsigned int row=0; row < this->value_.n_rows(); row++)
92 for(
unsigned int col=0; col < this->value_.n_cols(); col++) {
96 FunctionParser tmp_parser;
97 tmp_parser.AddConstant(
"Pi", 3.14159265358979323846);
98 tmp_parser.AddConstant(
"E", 2.71828182845904523536);
101 #pragma GCC diagnostic push
102 #pragma GCC diagnostic ignored "-Wunused-variable"
104 int err=tmp_parser.ParseAndDeduceVariables(formula_matrix_.at(row,col), var_list);
105 OLD_ASSERT( err != FunctionParser::FP_NO_ERROR,
"ParseAndDeduceVariables error: %s\n", tmp_parser.ErrorMsg() );
107 #pragma GCC diagnostic pop
109 bool time_dependent =
false;
110 BOOST_FOREACH(std::string &var_name, var_list ) {
111 if (var_name == std::string(
"t") ) time_dependent=
true;
112 else if (var_name ==
"x" || var_name ==
"y" || var_name ==
"z")
continue;
114 WarningOut().fmt(
"Unknown variable '{}' in the FieldFormula[{}][{}] == '{}'\n at the input address:\n {} \n",
115 var_name, row, col, formula_matrix_.at(row,col), value_input_address_ );
119 parser_matrix_[row][col].AddConstant(
"Pi", 3.14159265358979323846);
120 parser_matrix_[row][col].AddConstant(
"E", 2.71828182845904523536);
121 if (time_dependent) {
122 parser_matrix_[row][col].AddConstant(
"t", time.
end());
129 if (time_dependent || this->time_ ==
TimeStep() ) {
130 parser_matrix_[row][col].Parse(formula_matrix_.at(row,col), vars);
132 if ( parser_matrix_[row][col].GetParseErrorType() != FunctionParser::FP_NO_ERROR ) {
133 xprintf(
UsrErr,
"ParserError: %s\n in the FieldFormula[%d][%d] == '%s'\n at the input address:\n %s \n",
134 parser_matrix_[row][col].ErrorMsg(),
135 row,col,formula_matrix_.at(row,col).c_str(),
136 value_input_address_.c_str());
139 parser_matrix_[row][col].Optimize();
140 any_parser_changed =
true;
147 return any_parser_changed;
154 template <
int spacedim,
class Value>
157 for(
unsigned int row=0; row < this->value_.n_rows(); row++)
158 for(
unsigned int col=0; col < this->value_.n_cols(); col++) {
159 this->value_(row,col) = parser_matrix_[row][col].Eval(p.memptr());
161 return this->r_value_;
168 template <
int spacedim,
class Value>
173 for(
unsigned int i=0; i< point_list.size(); i++) {
174 Value envelope(value_list[i]);
175 OLD_ASSERT( envelope.n_rows()==this->value_.n_rows(),
176 "value_list[%d] has wrong number of rows: %d; should match number of components: %d\n",
177 i, envelope.n_rows(),this->value_.n_rows());
179 for(
unsigned int row=0; row < this->value_.n_rows(); row++)
180 for(
unsigned int col=0; col < this->value_.n_cols(); col++) {
181 envelope(row,col) = parser_matrix_[row][col].Eval(point_list[i].memptr());
187 template <
int spacedim,
class Value>
Space< spacedim >::Point Point
Value value_
Last value, prevents passing large values (vectors) by value.
#define WarningOut()
Macro defining 'warning' record of log.
#define OLD_ASSERT_EQUAL(a, b)
Representation of one time step.
#define FLOW123D_FORCE_LINK_IN_CHILD(x)