https://mooseframework.inl.gov
Loading...
Searching...
No Matches
InversionControlBase.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
11
12#include "Function.h"
13#include "FEProblemBase.h"
14#include "Executioner.h"
15#include "FixedPointSolve.h"
16#include "MooseApp.h"
17
18#include <algorithm>
19#include <cmath>
20
23{
25
26 params.addRequiredParam<PostprocessorName>(
27 "output_postprocessor",
28 "Postprocessor holding the sub-app output to compare against the target.");
29 params.addRequiredParam<PostprocessorName>(
30 "parameter_postprocessor",
31 "Postprocessor (e.g. a Receiver) holding the parameter value; read and updated in place.");
32 params.addParam<PostprocessorName>(
33 "converged_parameter_postprocessor",
34 "Optional postprocessor to which the parameter value that produced the current output is "
35 "written each iteration; at convergence this holds the inverse-problem solution.");
36 params.addRequiredParam<FunctionName>(
37 "target_function", "Function f(t) giving the target output value at each time step.");
38 params.addRequiredParam<PostprocessorName>(
39 "residual_postprocessor",
40 "Postprocessor (e.g. a Receiver) the control writes with the normalized convergence "
41 "residual; "
42 "point the fixed-point Convergence object at it with a tolerance of 1.");
43 params.addRangeCheckedParam<Real>("absolute_tolerance",
44 1e-8,
45 "absolute_tolerance>0",
46 "Absolute tolerance on |output - target|.");
47 params.addRangeCheckedParam<Real>(
48 "relative_tolerance",
49 1e-6,
50 "relative_tolerance>0",
51 "Relative tolerance on |output - target|, taken relative to |target|.");
52
53 // Run once per fixed-point iteration, after the sub-app has solved and its output transferred.
54 params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_BEGIN;
55
56 return params;
57}
58
60 : Control(parameters),
61 _output(getPostprocessorValue("output_postprocessor")),
62 _param(getPostprocessorValue("parameter_postprocessor")),
63 _param_name(getParam<PostprocessorName>("parameter_postprocessor")),
64 _converged_param_name(
65 isParamValid("converged_parameter_postprocessor")
66 ? std::make_optional(getParam<PostprocessorName>("converged_parameter_postprocessor"))
67 : std::nullopt),
68 _target_function(getFunction("target_function")),
69 _residual_name(getParam<PostprocessorName>("residual_postprocessor")),
70 _abs_tol(getParam<Real>("absolute_tolerance")),
71 _rel_tol(getParam<Real>("relative_tolerance"))
72{
73}
74
75unsigned int
77{
78 Executioner * const executioner = _app.getExecutioner();
79 // hasSolveObject<FixedPointSolve>() guards the null (executor-style executioners never build
80 // one); hasFixedPointIteration() then checks that fixed-point iteration is actually enabled.
81 // Without the second check a standard executioner with no fixed-point settings still owns a
82 // FixedPointSolve, so the control would silently drift the parameter once per time step instead
83 // of iterating.
84 if (!executioner || !executioner->hasSolveObject<FixedPointSolve>() ||
87 "requires an executioner configured to perform fixed-point (MultiApp) iterations; set "
88 "'fixed_point_max_its' greater than 1 (or otherwise enable fixed-point iteration) on "
89 "the executioner.");
90 // numFixedPointIts() returns _fixed_point_it + 1, i.e. 1 on the first iteration of each fresh
91 // fixed-point solve (including a restep retry).
92 return executioner->fixedPointSolve().numFixedPointIts();
93}
94
95Real
100
101void
103{
104 const unsigned int it = fixedPointIteration();
105 const Real p_used = _param;
106 const Real y = _output;
107 const Real y_target = targetValue();
108
109 const IterationUpdate update = computeUpdate(it, p_used, y, y_target);
110
111 // Publish the parameter that produced the current output (the solution at convergence).
112 if (update.publish)
114 // Report the convergence residual the fixed-point Convergence object compares against 1.
115 setResidual(update.residual);
116 // Write the next guess back to the working parameter postprocessor.
118}
119
120void
126
127void
132
133Real
134InversionControlBase::linearRootUpdate(Real p_a, Real y_a, Real p_b, Real y_b, Real y_target)
135{
136 const Real dp = p_b - p_a;
137 const Real dy = y_b - y_a;
138 // Guard a vanishing or non-finite denominator/slope before dividing. The magnitude-scaled
139 // threshold is a pragmatic "dy too small" heuristic, not a principled relative tolerance; the
140 // finiteness check also traps a NaN/Inf sample from a diverging forward solve, which the "<"
141 // comparisons alone would let through (every comparison with NaN is false).
142 if (!std::isfinite(dp) || !std::isfinite(dy) || std::abs(dp) < 1e-15 ||
143 std::abs(dy) < 1e-15 * (std::abs(y_b) + std::abs(y_a) + 1.0))
144 {
145 mooseWarning("The parameter update at t = ",
146 _t,
147 " has a vanishing or non-finite denominator or slope; leaving the parameter "
148 "unchanged.");
149 return p_b;
150 }
151 return p_b - (y_b - y_target) * dp / dy;
152}
153
154Real
156{
157 const Real target = targetValue();
158 return std::abs(y - target) / std::max(_abs_tol, _rel_tol * std::abs(target));
159}
160
161void
const std::vector< double > y
const Real p
const ExecFlagType EXEC_TIMESTEP_BEGIN
static InputParameters validParams()
FEProblemBase & _fe_problem
bool hasSolveObject() const
FixedPointSolve & fixedPointSolve()
void setPostprocessorValueByName(const PostprocessorName &name, const PostprocessorValue &value, std::size_t t_index=0)
unsigned int numFixedPointIts() const
bool hasFixedPointIteration()
virtual Real value(Real t, const Point &p) const
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
T & set(const std::string &name, bool quiet_mode=false)
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
virtual IterationUpdate computeUpdate(unsigned int it, Real p_used, Real y, Real y_target)=0
Compute this iteration's update from the current sample: the 1-based fixed-point iteration it and the...
Real normalizedResidual(Real y) const
Normalized convergence residual for output value y: |y - targetValue()| / max(absolute_tolerance,...
const Real _rel_tol
Relative tolerance on |output - target|, relative to |target|.
const Real _abs_tol
Absolute tolerance on |output - target|.
const PostprocessorName _residual_name
Name of the postprocessor the control writes with the normalized convergence residual.
void setResidual(Real value)
Write a value to the residual postprocessor that the Convergence object compares against 1.
Real linearRootUpdate(Real p_a, Real y_a, Real p_b, Real y_b, Real y_target)
One guarded linear-model root update from two (parameter, output) samples – a secant step shared by t...
unsigned int fixedPointIteration() const
1-based fixed-point iteration (1 on the first iteration of each fixed-point solve,...
const PostprocessorValue & _param
Parameter value consumed by the most recent sub-app solve (read in place)
void publishConvergedParameter(Real p)
Publish a parameter value to the optional converged-parameter postprocessor (no-op if unset)
const std::optional< PostprocessorName > _converged_param_name
Optional postprocessor to publish the parameter value that produced the current output.
void setParameter(Real p)
Write the next parameter guess to the parameter postprocessor.
const PostprocessorName _param_name
Name of the parameter postprocessor to update with the next guess.
virtual void execute() override final
Template method: reads the current (parameter, output) sample, delegates the scheme-specific decision...
const PostprocessorValue & _output
Sub-app output value transferred back to the main app (compared against the target)
Real targetValue() const
Target output value at the current time.
const Function & _target_function
Target output as a function of time.
static InputParameters validParams()
InversionControlBase(const InputParameters &parameters)
Executioner * getExecutioner() const
void mooseError(Args &&... args) const
void mooseWarning(Args &&... args) const
MooseApp & _app
Real & _t
One iteration's update, produced by the derived scheme and applied by execute().
bool publish
Whether the current (already-evaluated) parameter is the solution of record to publish.
Real residual
Residual to report for the current sample (compared against 1 by the Convergence object)
Real next_parameter
Parameter guess to write for the next solve.