28 "Generates the full fixed-point inverse-solve workflow (forward sub-app, transfers, "
29 "postprocessors, convergence, and a secant or Newton inversion control) from a single "
32 MooseEnum method(
"secant newton",
"secant");
34 params.
addRequiredParam<FileName>(
"forward_input",
"Forward-model sub-app input file.");
36 "sub_parameter_postprocessor",
"Sub-app postprocessor that receives the parameter value.");
38 "sub_output_postprocessor",
"Sub-app postprocessor holding the output to match the target.");
39 params.
addRequiredParam<FunctionName>(
"target_function",
"Target output f(t).");
40 params.
addParam<Real>(
"initial_parameter", 1.0,
"Initial guess for the parameter.");
45 "Perturbation used to seed/compute the derivative (initial_delta for secant, "
46 "parameter_delta for newton).");
49 "absolute_tolerance>0",
50 "Absolute tolerance on |output - target|.");
54 "relative_tolerance>0",
55 "Relative tolerance on |output - target|, relative to |target|.");
59 "Maximum number of fixed-point iterations on the generated convergence. With method=newton "
60 "each Newton update consumes two fixed-point iterations (a base and a perturbed solve), so "
61 "the effective number of Newton updates is about half this value.");
63 "accept_on_max_iterations",
65 "If true, accept the current estimate when the fixed-point loop reaches max_iterations "
66 "instead of diverging, cutting the time step, and erroring.");
68 "result_postprocessor",
70 "Name of the created postprocessor holding the converged parameter (output to CSV).");
74 "Forwarded to the generated convergence: if true, it prints per-iteration convergence "
75 "information, including the accept-on-max decision when accept_on_max_iterations is set.");
91 const bool newton = getParam<MooseEnum>(
"method") ==
"newton";
92 const std::string residual =
p +
"_residual";
93 const PostprocessorName result = getParam<PostprocessorName>(
"result_postprocessor");
98 ps.
set<std::vector<FileName>>(
"input_files") = {getParam<FileName>(
"forward_input")};
102 _problem->addMultiApp(
"TransientMultiApp",
p +
"_forward", ps);
107 t1.
set<MultiAppName>(
"to_multi_app") =
p +
"_forward";
108 t1.set<PostprocessorName>(
"from_postprocessor") =
p +
"_param";
109 t1.set<PostprocessorName>(
"to_postprocessor") =
110 getParam<PostprocessorName>(
"sub_parameter_postprocessor");
111 _problem->addTransfer(
"MultiAppPostprocessorTransfer",
p +
"_to_forward", t1);
114 t2.
set<MultiAppName>(
"from_multi_app") =
p +
"_forward";
115 t2.set<PostprocessorName>(
"from_postprocessor") =
116 getParam<PostprocessorName>(
"sub_output_postprocessor");
117 t2.set<PostprocessorName>(
"to_postprocessor") =
p +
"_output";
118 t2.set<
MooseEnum>(
"reduction_type") =
"average";
119 _problem->addTransfer(
"MultiAppPostprocessorTransfer",
p +
"_from_forward", t2);
123 const std::vector<OutputName> none = {
"none"};
127 pp.
set<Real>(
"default") = getParam<Real>(
"initial_parameter");
128 pp.set<std::vector<OutputName>>(
"outputs") = none;
129 _problem->addPostprocessor(
"Receiver",
p +
"_param", pp);
133 po.
set<std::vector<OutputName>>(
"outputs") = none;
134 _problem->addPostprocessor(
"Receiver",
p +
"_output", po);
138 pr.
set<Real>(
"default") = 0.0;
139 _problem->addPostprocessor(
"Receiver", result, pr);
144 pres.
set<Real>(
"default") = 1e30;
145 pres.set<std::vector<OutputName>>(
"outputs") = none;
146 _problem->addPostprocessor(
"Receiver", residual, pres);
151 pc.
set<PostprocessorName>(
"postprocessor") = residual;
152 pc.set<Real>(
"tolerance") = 1.0;
153 pc.set<
unsigned int>(
"max_iterations") = getParam<unsigned int>(
"max_iterations");
154 pc.set<
bool>(
"converge_at_max_iterations") = getParam<bool>(
"accept_on_max_iterations");
155 pc.set<
bool>(
"verbose") = getParam<bool>(
"verbose");
156 _problem->addConvergence(
"PostprocessorConvergence",
p +
"_convergence", pc);
164 const std::string conv_name =
p +
"_convergence";
165 if (!
_problem->hasSetMultiAppFixedPointConvergenceName() ||
166 _problem->getMultiAppFixedPointConvergenceName() != conv_name)
175 if (!
_problem->hasSetMultiAppFixedPointConvergenceName())
178 current =
"It is currently not set.";
179 else if (
_problem->needToAddDefaultMultiAppFixedPointConvergence())
180 current =
"No 'multiapp_fixed_point_convergence' was given, so MOOSE created a default "
184 "It is currently set to '" +
_problem->getMultiAppFixedPointConvergenceName() +
"'.";
188 "] requires the executioner to use its generated convergence to enable and drive "
189 "the fixed-point loop. Add\n\n multiapp_fixed_point_convergence = ",
191 "\n\nto the [Executioner] block. ",
195 const std::string ctype = newton ?
"NewtonInversionControl" :
"SecantInversionControl";
197 pctl.
set<PostprocessorName>(
"output_postprocessor") =
p +
"_output";
198 pctl.set<PostprocessorName>(
"parameter_postprocessor") =
p +
"_param";
199 pctl.set<PostprocessorName>(
"converged_parameter_postprocessor") = result;
200 pctl.set<PostprocessorName>(
"residual_postprocessor") = residual;
201 pctl.set<FunctionName>(
"target_function") = getParam<FunctionName>(
"target_function");
202 pctl.set<Real>(
"absolute_tolerance") = getParam<Real>(
"absolute_tolerance");
203 pctl.set<Real>(
"relative_tolerance") = getParam<Real>(
"relative_tolerance");
205 pctl.set<Real>(
"parameter_delta") = getParam<Real>(
"perturbation");
207 pctl.set<Real>(
"initial_delta") = getParam<Real>(
"perturbation");
211 _problem->getControlWarehouse().addObject(control);
const ExecFlagType EXEC_TIMESTEP_BEGIN
registerMooseAction("OptimizationApp", SingleParameterInverseSolveAction, "add_multi_app")
static InputParameters validParams()
std::shared_ptr< FEProblemBase > & _problem
const std::string & _current_task
std::shared_ptr< MooseObject > create(const std::string &obj_name, const std::string &name, const InputParameters ¶meters, THREAD_ID tid=0, bool print_deprecated=true)
InputParameters getValidParams(const std::string &name) const
const std::string & name() const
void mooseError(Args &&... args) const
Generates the full fixed-point inverse-solve workflow for a single scalar parameter from one SinglePa...
virtual void act() override
static InputParameters validParams()
SingleParameterInverseSolveAction(const InputParameters ¶meters)
std::string camelCaseToUnderscore(const std::string &camel_case_name)