diff --git a/framework/doc/content/source/utils/InputParameters.md b/framework/doc/content/source/utils/InputParameters.md index ceb884a335e1..97be77ab1475 100644 --- a/framework/doc/content/source/utils/InputParameters.md +++ b/framework/doc/content/source/utils/InputParameters.md @@ -27,3 +27,17 @@ custom logic does not need to be implemented in every end-user object. The range the second to last paramter right before the doc string. !listing framework/include/utils/InputParameters.h start=BEGIN RANGE CHECKED PARAMETER METHODS end=END RANGE CHECKED PARAMETER METHODS + +## Deprecating coupled variables + +The `InputParameters` class provides a convenient method for deprecating coupled +variable names called `addDeprecatedCoupledVar`. The method takes four +arguments. The first corresponds to the deprecated name; the second argument is +the new, blessed name that users should use. This name should have a +corresponding `params.addCoupledVar('blessed_name', 'blessed_name_doc_string')` +in the relevant `Class::validParams()` block. The third argument to +`InputParameters::addDeprecatedCoupledVar` is the documentation string +describing what the coupled variable is used for. We recommend that this +documentation string match the 'blessed_name_doc_string'. The final argument is +the deprecation message that should be conveyed to users who use the deprecated +coupled variable name in their input file. diff --git a/framework/include/interfaces/Coupleable.h b/framework/include/interfaces/Coupleable.h index 6c591d47abd2..1c60f6a2d316 100644 --- a/framework/include/interfaces/Coupleable.h +++ b/framework/include/interfaces/Coupleable.h @@ -914,6 +914,9 @@ class Coupleable /// Vector of standard finite volume oupled variables std::vector *> _coupled_standard_fv_moose_vars; + /// map from new to deprecated variable names + const std::unordered_map & _new_to_deprecated_coupled_vars; + /// True if we provide coupling to nodal values bool _c_nodal; @@ -1224,31 +1227,48 @@ template ::valu const T * Coupleable::getVarHelper(const std::string & var_name, unsigned int comp) const { + auto name_to_use = var_name; + + // First check for supplied name if (!checkVar(var_name, comp, 0)) - return nullptr; + { + // See if there is an associated deprecated name that the user may have used instead + auto it = _new_to_deprecated_coupled_vars.find(var_name); + if (it == _new_to_deprecated_coupled_vars.end()) + return nullptr; + else + { + auto deprecated_name = it->second; + if (checkVar(deprecated_name, comp, 0)) + name_to_use = deprecated_name; + else + return nullptr; + } + } + + auto coupled_vars_it = _coupled_vars.find(name_to_use); - auto coupled_vars_it = _coupled_vars.find(var_name); - if (coupled_vars_it == _coupled_vars.end()) - mooseError("Trying to get a coupled var ", var_name, " that doesn't exist"); + mooseAssert(coupled_vars_it != _coupled_vars.end(), + "Trying to get a coupled var " << name_to_use << " that doesn't exist"); if (auto coupled_var = dynamic_cast(coupled_vars_it->second[comp])) return coupled_var; else { for (auto & var : _coupled_standard_moose_vars) - if (var->name() == var_name) + if (var->name() == name_to_use) mooseError("The named variable is a standard variable, try a " "'coupled[Value/Gradient/Dot/etc]...' function instead"); for (auto & var : _coupled_vector_moose_vars) - if (var->name() == var_name) + if (var->name() == name_to_use) mooseError("The named variable is a vector variable, try a " "'coupledVector[Value/Gradient/Dot/etc]...' function instead"); for (auto & var : _coupled_array_moose_vars) - if (var->name() == var_name) + if (var->name() == name_to_use) mooseError("The named variable is an array variable, try a " "'coupledArray[Value/Gradient/Dot/etc]...' function instead"); mooseError( - "Variable '", var_name, "' is of a different C++ type than you tried to fetch it as."); + "Variable '", name_to_use, "' is of a different C++ type than you tried to fetch it as."); } } diff --git a/framework/include/utils/InputParameters.h b/framework/include/utils/InputParameters.h index 525b79ec94f4..5c8dac0b8bb5 100644 --- a/framework/include/utils/InputParameters.h +++ b/framework/include/utils/InputParameters.h @@ -29,6 +29,7 @@ class FunctionParserBase #endif #include +#include // Forward declarations class Action; @@ -311,11 +312,13 @@ class InputParameters : public Parameters * This method adds a deprecated coupled variable name pair. The parser will look for variable * name pair in the input file and can return a reference to the storage location * for the coupled variable if found - * @param name The name of the coupled variable + * @param old_name The deprecated name of the coupled variable + * @param new_name The new name of the coupled variable * @param doc_string A description of what the coupled variable should be * @param deprecation_message The deprecation message to convey to the user */ - void addDeprecatedCoupledVar(const std::string & name, + void addDeprecatedCoupledVar(const std::string & old_name, + const std::string & new_name, const std::string & doc_string, const std::string & deprecation_message); @@ -582,6 +585,14 @@ class InputParameters : public Parameters */ const std::set & getCoupledVariableParamNames() const { return _coupled_vars; } + /** + * Return the new to deprecated variable name map + */ + const std::unordered_map & getNewToDeprecatedVarMap() const + { + return _new_to_deprecated_coupled_vars; + } + /** * Return whether or not the coupled variable exists * @param coupling_name The name of the coupled variable to test for @@ -995,6 +1006,9 @@ class InputParameters : public Parameters /// A flag for toggling the error message in the copy constructor. bool _allow_copy; + /// A map from deprecated coupled variable names to the new blessed name + std::unordered_map _new_to_deprecated_coupled_vars; + // These are the only objects allowed to _create_ InputParameters friend InputParameters emptyInputParameters(); friend class InputParameterWarehouse; diff --git a/framework/src/interfaces/Coupleable.C b/framework/src/interfaces/Coupleable.C index cd3bf6072a0e..30193d255040 100644 --- a/framework/src/interfaces/Coupleable.C +++ b/framework/src/interfaces/Coupleable.C @@ -20,6 +20,7 @@ Coupleable::Coupleable(const MooseObject * moose_object, bool nodal, bool is_fv) : _c_parameters(moose_object->parameters()), _c_name(_c_parameters.get("_object_name")), _c_fe_problem(*_c_parameters.getCheckedPointerParam("_fe_problem_base")), + _new_to_deprecated_coupled_vars(_c_parameters.getNewToDeprecatedVarMap()), _c_nodal(nodal), _c_is_implicit(_c_parameters.have_parameter("implicit") ? _c_parameters.get("implicit") diff --git a/framework/src/utils/InputParameters.C b/framework/src/utils/InputParameters.C index dae56634e686..895763d63cab 100644 --- a/framework/src/utils/InputParameters.C +++ b/framework/src/utils/InputParameters.C @@ -58,6 +58,7 @@ InputParameters::clear() Parameters::clear(); _params.clear(); _coupled_vars.clear(); + _new_to_deprecated_coupled_vars.clear(); _collapse_nesting = false; _moose_object_syntax_visibility = true; _show_deprecated_message = true; @@ -131,6 +132,7 @@ InputParameters::operator=(const InputParameters & rhs) _collapse_nesting = rhs._collapse_nesting; _moose_object_syntax_visibility = rhs._moose_object_syntax_visibility; _coupled_vars = rhs._coupled_vars; + _new_to_deprecated_coupled_vars = rhs._new_to_deprecated_coupled_vars; _allow_copy = rhs._allow_copy; _block_fullpath = rhs._block_fullpath; _block_location = rhs._block_location; @@ -155,6 +157,8 @@ InputParameters::operator+=(const InputParameters & rhs) // Collapse nesting and moose object syntax hiding are not modified with += _coupled_vars.insert(rhs._coupled_vars.begin(), rhs._coupled_vars.end()); + _new_to_deprecated_coupled_vars.insert(rhs._new_to_deprecated_coupled_vars.begin(), + rhs._new_to_deprecated_coupled_vars.end()); return *this; } @@ -187,15 +191,17 @@ InputParameters::addCoupledVar(const std::string & name, const std::string & doc } void -InputParameters::addDeprecatedCoupledVar(const std::string & name, +InputParameters::addDeprecatedCoupledVar(const std::string & old_name, + const std::string & new_name, const std::string & doc_string, const std::string & deprecation_message) { _show_deprecated_message = false; - addParam>(name, doc_string); - _coupled_vars.insert(name); + addParam>(old_name, doc_string); + _coupled_vars.insert(old_name); + _new_to_deprecated_coupled_vars.emplace(new_name, old_name); - _params[name]._deprecation_message = deprecation_message; + _params[old_name]._deprecation_message = deprecation_message; _show_deprecated_message = true; } diff --git a/test/include/kernels/DeprecatedCoupledVarKernel.h b/test/include/kernels/DeprecatedCoupledVarKernel.h new file mode 100644 index 000000000000..8e67800a74a0 --- /dev/null +++ b/test/include/kernels/DeprecatedCoupledVarKernel.h @@ -0,0 +1,29 @@ +//* This file is part of the MOOSE framework +//* https://www.mooseframework.org +//* +//* All rights reserved, see COPYRIGHT for full restrictions +//* https://github.com/idaholab/moose/blob/master/COPYRIGHT +//* +//* Licensed under LGPL 2.1, please see LICENSE for details +//* https://www.gnu.org/licenses/lgpl-2.1.html + +#pragma once + +#include "ADKernel.h" + +/** + * Tests the InputParameters::addDeprecatedCoupledVar method + * + */ +class DeprecatedCoupledVarKernel : public ADKernel +{ +public: + static InputParameters validParams(); + + DeprecatedCoupledVarKernel(const InputParameters & parameters); + +protected: + ADReal computeQpResidual() override; + + const ADVariableValue & _source; +}; diff --git a/test/src/kernels/DeprecatedCoupledVarKernel.C b/test/src/kernels/DeprecatedCoupledVarKernel.C new file mode 100644 index 000000000000..486ad4a99cc7 --- /dev/null +++ b/test/src/kernels/DeprecatedCoupledVarKernel.C @@ -0,0 +1,35 @@ +//* This file is part of the MOOSE framework +//* https://www.mooseframework.org +//* +//* All rights reserved, see COPYRIGHT for full restrictions +//* https://github.com/idaholab/moose/blob/master/COPYRIGHT +//* +//* Licensed under LGPL 2.1, please see LICENSE for details +//* https://www.gnu.org/licenses/lgpl-2.1.html + +#include "DeprecatedCoupledVarKernel.h" + +registerMooseObject("MooseTestApp", DeprecatedCoupledVarKernel); + +InputParameters +DeprecatedCoupledVarKernel::validParams() +{ + InputParameters params = ADKernel::validParams(); + params.addCoupledVar("source", "A variable representing a source term"); + params.addDeprecatedCoupledVar("stupid_name", + "source", + "A variable representing a source term", + "'stupid_name' is deprecated. Please use 'source' instead"); + return params; +} + +DeprecatedCoupledVarKernel::DeprecatedCoupledVarKernel(const InputParameters & parameters) + : ADKernel(parameters), _source(adCoupledValue("source")) +{ +} + +ADReal +DeprecatedCoupledVarKernel::computeQpResidual() +{ + return -_test[_i][_qp] * _source[_qp]; +} diff --git a/test/tests/misc/deprecation/deprecated_coupled_var.i b/test/tests/misc/deprecation/deprecated_coupled_var.i new file mode 100644 index 000000000000..09a1b3d962c7 --- /dev/null +++ b/test/tests/misc/deprecation/deprecated_coupled_var.i @@ -0,0 +1,75 @@ +[Mesh] + type = GeneratedMesh + dim = 2 + nx = 10 + ny = 10 +[] + +[Variables] + [./u] + [../] + [v][] +[] + +[Kernels] + active = 'diff_u coupled_u diff_v deprecated_coupled_v' + [./diff_u] + type = Diffusion + variable = u + [../] + [coupled_u] + type = DeprecatedCoupledVarKernel + variable = u + source = v + [] + [diff_v] + type = Diffusion + variable = v + [] + [deprecated_coupled_v] + type = DeprecatedCoupledVarKernel + variable = v + stupid_name = u + [] + [blessed_coupled_v] + type = DeprecatedCoupledVarKernel + variable = v + source = u + [] +[] + +[BCs] + [./left_u] + type = DirichletBC + variable = u + boundary = left + value = 0 + [../] + [./right_u] + type = DirichletBC + variable = u + boundary = right + value = 1 + [../] + [./left_v] + type = DirichletBC + variable = v + boundary = left + value = 1 + [../] + [./right_v] + type = DirichletBC + variable = v + boundary = right + value = 0 + [../] +[] + +[Executioner] + type = Steady + solve_type = 'NEWTON' +[] + +[Outputs] + exodus = true +[] diff --git a/test/tests/misc/deprecation/gold/blessed_coupled_var_out.e b/test/tests/misc/deprecation/gold/blessed_coupled_var_out.e new file mode 120000 index 000000000000..0d81cb63bae5 --- /dev/null +++ b/test/tests/misc/deprecation/gold/blessed_coupled_var_out.e @@ -0,0 +1 @@ +deprecated_coupled_var_out.e \ No newline at end of file diff --git a/test/tests/misc/deprecation/gold/deprecated_coupled_var_out.e b/test/tests/misc/deprecation/gold/deprecated_coupled_var_out.e new file mode 100644 index 000000000000..e8c517117745 Binary files /dev/null and b/test/tests/misc/deprecation/gold/deprecated_coupled_var_out.e differ diff --git a/test/tests/misc/deprecation/tests b/test/tests/misc/deprecation/tests index ff1263f227b8..af09336035ed 100644 --- a/test/tests/misc/deprecation/tests +++ b/test/tests/misc/deprecation/tests @@ -41,4 +41,24 @@ requirement = 'The system shall produce a warning indicating a possible replacement when deprecated code is superseded.' [../] + + [deprecated_coupled_var] + type = 'Exodiff' + input = 'deprecated_coupled_var.i' + exodiff = 'deprecated_coupled_var_out.e' + requirement = 'The system shall be able to deprecate coupled variable names, while enabling user code to only use the new, blessed name' + design = 'InputParameters.md' + issues = '#15497' + no_error_deprecated = True + [] + + [blessed_coupled_var] + type = 'Exodiff' + input = 'deprecated_coupled_var.i' + exodiff = 'blessed_coupled_var_out.e' + cli_args = "Kernels/active='diff_u coupled_u diff_v blessed_coupled_v' Outputs/file_base=blessed_coupled_var_out" + requirement = 'The system shall not give a deprecation warning if the user uses the blessed coupled variable name instead of the deprecated coupled variable name.' + design = 'InputParameters.md' + issues = '#15497' + [] []