8 #ifndef FIELD_FORMULA_IMPL_HH_
9 #define FIELD_FORMULA_IMPL_HH_
15 #include <boost/foreach.hpp>
19 namespace it = Input::Type;
21 template <
int spacedim,
class Value>
24 template <
int spacedim,
class Value>
33 "String, array of strings, or matrix of strings with formulas for individual "
34 "entries of scalar, vector, or tensor value respectively.\n"
35 "For vector values, you can use just one string to enter homogeneous vector.\n"
36 "For square NxN-matrix values, you can use:\n"
37 "* array of strings of size N to enter diagonal matrix\n"
38 "* array of strings of size (N+1)*N/2 to enter symmetric matrix (upper triangle, row by row)\n"
39 "* just one string to enter (spatially variable) multiple of the unit matrix.\n"
40 "Formula can contain variables x,y,z,t and usual operators and functions." );
48 template <
int spacedim,
class Value>
51 formula_matrix_(this->value_.n_rows(), this->value_.n_cols()),
52 formula_matrix_helper_(formula_matrix_), parser_matrix_(this->value_.n_rows())
54 for(
unsigned int row=0; row < this->
value_.n_rows(); row++) {
61 template <
int spacedim,
class Value>
69 template <
int spacedim,
class Value>
73 bool any_parser_changed =
false;
76 std::string vars = string(
"x,y,z").substr(0, 2*spacedim-1);
78 for(
unsigned int row=0; row < this->value_.n_rows(); row++)
79 for(
unsigned int col=0; col < this->value_.n_cols(); col++) {
83 FunctionParser tmp_parser;
84 #pragma GCC diagnostic push
85 #pragma GCC diagnostic ignored "-Wunused-variable"
87 int err=tmp_parser.ParseAndDeduceVariables(formula_matrix_.at(row,col), var_list);
88 ASSERT( err != FunctionParser::FP_NO_ERROR,
"ParseAndDeduceVariables error: %s\n", tmp_parser.ErrorMsg() );
90 #pragma GCC diagnostic pop
92 bool time_dependent =
false;
93 BOOST_FOREACH(std::string &var_name, var_list ) {
94 if (var_name == std::string(
"t") ) time_dependent=
true;
95 else if (var_name ==
"x" || var_name ==
"y" || var_name ==
"z")
continue;
97 xprintf(
Warn,
"Unknown variable '%s' in the FieldFormula[%d][%d] == '%s'\n at the input address:\n %s \n",
98 var_name.c_str(), row, col, formula_matrix_.at(row,col).c_str(),
99 value_input_address_.c_str() );
101 if (time_dependent) {
102 parser_matrix_[row][col].AddConstant(
"t", time);
109 if (time_dependent || this->time_ == -numeric_limits<double>::infinity() ) {
110 parser_matrix_[row][col].Parse(formula_matrix_.at(row,col), vars);
112 if ( parser_matrix_[row][col].GetParseErrorType() != FunctionParser::FP_NO_ERROR ) {
113 xprintf(
UsrErr,
"ParserError: %s\n in the FieldFormula[%d][%d] == '%s'\n at the input address:\n %s \n",
114 parser_matrix_[row][col].ErrorMsg(),
115 row,col,formula_matrix_.at(row,col).c_str(),
116 value_input_address_.c_str());
119 parser_matrix_[row][col].Optimize();
120 any_parser_changed =
true;
127 return any_parser_changed;
134 template <
int spacedim,
class Value>
137 for(
unsigned int row=0; row < this->value_.n_rows(); row++)
138 for(
unsigned int col=0; col < this->value_.n_cols(); col++) {
139 this->value_(row,col) = parser_matrix_[row][col].Eval(p.memptr());
141 return this->r_value_;
148 template <
int spacedim,
class Value>
153 for(
unsigned int i=0; i< point_list.size(); i++) {
154 Value envelope(value_list[i]);
155 ASSERT( envelope.n_rows()==this->value_.n_rows(),
156 "value_list[%d] has wrong number of rows: %d; should match number of components: %d\n",
157 i, envelope.n_rows(),this->value_.n_rows());
159 for(
unsigned int row=0; row < this->value_.n_rows(); row++)
160 for(
unsigned int col=0; col < this->value_.n_cols(); col++) {
161 envelope(row,col) = parser_matrix_[row][col].Eval(point_list[i].memptr());
167 template <
int spacedim,
class Value>
#define ASSERT_EQUAL(a, b)
Space< spacedim >::Point Point
Value value_
Last value, prevents passing large values (vectors) by value.