diff --git a/framework/include/utils/InputParameters.h b/framework/include/utils/InputParameters.h index 2124860b324d..ff199b271e5b 100644 --- a/framework/include/utils/InputParameters.h +++ b/framework/include/utils/InputParameters.h @@ -91,6 +91,9 @@ class InputParameters : public Parameters */ template void rangeCheck(const std::string & full_name, const std::string & short_name, InputParameters::Parameter * param, std::ostream & oss=Moose::out); + template void rangeCheck(const std::string & full_name, const std::string & short_name, + InputParameters::Parameter > * param, + std::ostream & oss=Moose::out); /** * Verifies that the requested parameter exists and is not NULL and returns it to the caller. @@ -525,6 +528,102 @@ InputParameters::set (const std::string& name) return cast_ptr*>(_values[name])->set(); } +template +void +InputParameters::rangeCheck(const std::string & full_name, const std::string & short_name, InputParameters::Parameter > * param, std::ostream & oss) +{ + mooseAssert(param, "Parameter is NULL"); + + if (_range_functions.find(short_name) == _range_functions.end()) + return; + + /** + * Automatically detect teh variables used in the range checking expression. + * We allow the following variables (where snam is the short_name of the parameter) + * + * snam : tests every component in the vector + * 'snam > 0' + * snam_size : the size of the vector + * 'snam_size = 5' + * snam_i : where i is a number from 0 to sname_size-1 tests a specific component + * 'snam_0 > snam_1' + */ + FunctionParserBase fp; + std::vector vars; + if (fp.ParseAndDeduceVariables(_range_functions[short_name], vars) != -1) // -1 for success + { + oss << "Error parsing expression: " << _range_functions[short_name] << '\n'; + return; + } + + // Fparser parameter buffer + std::vector parbuf(vars.size()); + + // parameter vector + const std::vector & value = param->set(); + + // iterate over all vector values (maybe ;) + bool need_to_iterate = false; + for (unsigned int i = 0; i < value.size(); i++) + { + // set parameters + for (unsigned int j = 0; j < vars.size(); j++) + { + if (vars[j] == short_name) + { + parbuf[j] = value[i]; + need_to_iterate = true; + } + else if (vars[j] == short_name + "_size") + parbuf[j] = value.size(); + else + { + std::size_t found = vars[j].find_last_of('_'); + if (found==std::string::npos) + { + oss << "Error parsing expression: " << _range_functions[short_name] << '\n'; + return; + } + std::istringstream iss(vars[j]); + iss.seekg(found+1); + + int index; + if (iss >> index) + { + if (index < 0 || index >= value.size()) + { + oss << "Error parsing expression: " << _range_functions[short_name] << "\nOut of range variable " << vars[j] << '\n'; + return; + } + parbuf[j] = value[index]; + } + else + { + oss << "Error parsing expression: " << _range_functions[short_name] << "\nInvalid variable " << vars[j] << ' ' << found << '\n'; + return; + } + } + } + + // test function using the parameters determined above + UP_T result = fp.Eval(&parbuf[0]); + if (fp.EvalError()) + { + oss << "Error evaluating expression: " << _range_functions[short_name] << '\n'; + return; + } + + if (!result) + { + oss << "Range check failed for parameter " << full_name << "\n\tExpression: " << _range_functions[short_name] << "\n"; + if (need_to_iterate) + oss << "\t Component: " << i << '\n'; + } + + if (!need_to_iterate) break; + } +} + template void InputParameters::rangeCheck(const std::string & full_name, const std::string & short_name, InputParameters::Parameter * param, std::ostream & oss) diff --git a/framework/src/utils/InputParameters.C b/framework/src/utils/InputParameters.C index a2f5bd0cc048..0f938af5d752 100644 --- a/framework/src/utils/InputParameters.C +++ b/framework/src/utils/InputParameters.C @@ -272,9 +272,11 @@ InputParameters::mooseObjectSyntaxVisibility() const InputParameters::Parameter * scalar_p = dynamic_cast*>(param); \ if (scalar_p) \ rangeCheck(long_name, short_name, scalar_p, oss); \ + InputParameters::Parameter > * vector_p = dynamic_cast >*>(param); \ + if (vector_p) \ + rangeCheck(long_name, short_name, vector_p, oss); \ } while (0) - void InputParameters::checkParams(const std::string &prefix) {