www.mooseframework.org
PicardSolve.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 
10 #include "PicardSolve.h"
11 
12 #include "Executioner.h"
13 #include "FEProblemBase.h"
14 #include "NonlinearSystem.h"
16 #include "Console.h"
17 
20 {
22 
23  params.addDeprecatedParam<unsigned int>(
24  "picard_max_its",
25  1,
26  "Specifies the maximum number of Picard iterations. "
27  "Mainly used when wanting to do Picard iterations with MultiApps "
28  "that are set to execute_on timestep_end or timestep_begin. "
29  "Setting this parameter to 1 turns off the Picard iterations.",
30  "Deprecated, use fixed_point_max_its");
31  params.addDeprecatedParam<bool>(
32  "accept_on_max_picard_iteration",
33  false,
34  "True to treat reaching the maximum number of Picard iterations as converged.",
35  "Deprecated, use accept_on_max_fixed_point_iteration");
36  params.addDeprecatedParam<bool>(
37  "disable_picard_residual_norm_check",
38  false,
39  "Disable the Picard residual norm evaluation thus the three parameters "
40  "picard_rel_tol, picard_abs_tol and picard_force_norms.",
41  "Deprecated, use disable_fixed_point_residual_norm_check");
42  params.addDeprecatedParam<Real>("picard_rel_tol",
43  1e-8,
44  "The relative nonlinear residual drop to shoot for "
45  "during Picard iterations. This check is "
46  "performed based on the Master app's nonlinear "
47  "residual.",
48  "Deprecated, use fixed_point_rel_tol");
49  params.addDeprecatedParam<Real>("picard_abs_tol",
50  1e-50,
51  "The absolute nonlinear residual to shoot for "
52  "during Picard iterations. This check is "
53  "performed based on the Master app's nonlinear "
54  "residual.",
55  "Deprecated, use fixed_point_abs_tol");
56  params.addDeprecatedParam<PostprocessorName>("picard_custom_pp",
57  "Postprocessor for custom picard convergence check.",
58  "Deprecated, use custom_pp");
59  params.deprecateParam("picard_custom_pp", "custom_pp", "06/06/2024");
60 
61  params.addDeprecatedParam<bool>(
62  "picard_force_norms",
63  false,
64  "Force the evaluation of both the TIMESTEP_BEGIN and TIMESTEP_END norms regardless of the "
65  "existence of active MultiApps with those execute_on flags, default: false.",
66  "Deprecated, use fixed_point_force_norms");
67 
68  return params;
69 }
70 
72 {
73  // Handle deprecated parameters
74  if (!parameters().isParamSetByAddParam("picard_max_its"))
75  {
76  _max_fixed_point_its = getParam<unsigned int>("picard_max_its");
78  }
79 
80  if (!parameters().isParamSetByAddParam("accept_on_max_picard_iteration"))
81  _accept_max_it = getParam<bool>("accept_on_max_picard_iteration");
82 
83  if (!parameters().isParamSetByAddParam("disable_picard_residual_norm_check"))
84  _has_fixed_point_norm = !getParam<bool>("disable_picard_residual_norm_check");
85 
86  if (!parameters().isParamSetByAddParam("picard_rel_tol"))
87  _fixed_point_rel_tol = getParam<Real>("picard_rel_tol");
88 
89  if (!parameters().isParamSetByAddParam("picard_abs_tol"))
90  _fixed_point_abs_tol = getParam<Real>("picard_abs_tol");
91 
92  if (isParamValid("picard_custom_pp"))
93  _fixed_point_custom_pp = &getPostprocessorValue("picard_custom_pp");
94 
95  if (!parameters().isParamSetByAddParam("picard_force_norms"))
96  _fixed_point_force_norms = getParam<bool>("picard_force_norms");
97 
98  allocateStorage(true);
99 }
100 
101 void
102 PicardSolve::allocateStorage(const bool primary)
103 {
104  Real relaxation_factor;
105  TagID old_tag_id;
106  const std::vector<PostprocessorName> * transformed_pps;
107  std::vector<std::vector<PostprocessorValue>> * transformed_pps_values;
108  if (primary)
109  {
110  relaxation_factor = _relax_factor;
111  old_tag_id = _problem.addVectorTag("xn_m1", Moose::VECTOR_TAG_SOLUTION);
112  _old_tag_id = old_tag_id;
113  transformed_pps = &_transformed_pps;
114  transformed_pps_values = &_transformed_pps_values;
115  }
116  else
117  {
118  relaxation_factor = _secondary_relaxation_factor;
119  old_tag_id = _problem.addVectorTag("secondary_xn_m1", Moose::VECTOR_TAG_SOLUTION);
120  _secondary_old_tag_id = old_tag_id;
121  transformed_pps = &_secondary_transformed_pps;
122  transformed_pps_values = &_secondary_transformed_pps_values;
123  }
124 
125  if (relaxation_factor != 1.)
126  {
127  // Store a copy of the previous solution
128  _solver_sys.addVector(old_tag_id, false, PARALLEL);
129 
130  // Allocate storage for the previous postprocessor values
131  (*transformed_pps_values).resize((*transformed_pps).size());
132  for (size_t i = 0; i < (*transformed_pps).size(); i++)
133  (*transformed_pps_values)[i].resize(1);
134  }
135 }
136 
137 void
139 {
140  Real relaxation_factor;
141  TagID old_tag_id;
142  if (primary)
143  {
144  relaxation_factor = _relax_factor;
145  old_tag_id = _old_tag_id;
146  }
147  else
148  {
149  relaxation_factor = _secondary_relaxation_factor;
150  old_tag_id = _secondary_old_tag_id;
151  }
152 
153  if (relaxation_factor != 1.)
154  {
155  // Save variable previous values
157  NumericVector<Number> & transformed_old = _solver_sys.getVector(old_tag_id);
158  transformed_old = solution;
159  }
160 }
161 
162 void
164 {
165  Real relaxation_factor;
166  const std::vector<PostprocessorName> * transformed_pps;
167  std::vector<std::vector<PostprocessorValue>> * transformed_pps_values;
168  if (primary)
169  {
170  relaxation_factor = _relax_factor;
171  transformed_pps = &_transformed_pps;
172  transformed_pps_values = &_transformed_pps_values;
173  }
174  else
175  {
176  relaxation_factor = _secondary_relaxation_factor;
177  transformed_pps = &_secondary_transformed_pps;
178  transformed_pps_values = &_secondary_transformed_pps_values;
179  }
180 
181  if (relaxation_factor != 1.)
182  // Save postprocessor previous values
183  for (size_t i = 0; i < (*transformed_pps).size(); i++)
184  (*transformed_pps_values)[i][0] = getPostprocessorValueByName((*transformed_pps)[i]);
185 }
186 
187 bool
189 {
190  // unrelaxed Picard is the default update for fixed point iterations
191  // old values are required for relaxation
192  if (primary)
193  return _relax_factor != 1. && _fixed_point_it > 0;
194  else
196 }
197 
198 void
200 {
201  Real relaxation_factor;
202  const std::vector<PostprocessorName> * transformed_pps;
203  std::vector<std::vector<PostprocessorValue>> * transformed_pps_values;
204  if (primary)
205  {
206  relaxation_factor = _relax_factor;
207  transformed_pps = &_transformed_pps;
208  transformed_pps_values = &_transformed_pps_values;
209  }
210  else
211  {
212  relaxation_factor = _secondary_relaxation_factor;
213  transformed_pps = &_secondary_transformed_pps;
214  transformed_pps_values = &_secondary_transformed_pps_values;
215  }
216 
217  // Relax the postprocessors
218  for (size_t i = 0; i < (*transformed_pps).size(); i++)
219  {
220  // Get new postprocessor value
221  const Real current_value = getPostprocessorValueByName((*transformed_pps)[i]);
222  const Real old_value = (*transformed_pps_values)[i][0];
223 
224  // Compute and set relaxed value
225  Real new_value = current_value;
226  new_value = relaxation_factor * current_value + (1 - relaxation_factor) * old_value;
227  _problem.setPostprocessorValueByName((*transformed_pps)[i], new_value);
228  }
229 }
230 
231 void
232 PicardSolve::transformVariables(const std::set<dof_id_type> & transformed_dofs, const bool primary)
233 {
234  Real relaxation_factor;
235  TagID old_tag_id;
236  if (primary)
237  {
238  relaxation_factor = _relax_factor;
239  old_tag_id = _old_tag_id;
240  }
241  else
242  {
243  relaxation_factor = _secondary_relaxation_factor;
244  old_tag_id = _secondary_old_tag_id;
245  }
246 
248  NumericVector<Number> & transformed_old = _solver_sys.getVector(old_tag_id);
249 
250  for (const auto & dof : transformed_dofs)
251  solution.set(dof,
252  (transformed_old(dof) * (1.0 - relaxation_factor)) +
253  (solution(dof) * relaxation_factor));
254 
255  solution.close();
257 }
258 
259 void
261 {
262  _console << "\n 0 Picard |R| = "
264  << '\n';
265 
266  Real max_norm_old = _fixed_point_initial_norm;
267  for (unsigned int i = 0; i <= _fixed_point_it; ++i)
268  {
269  Real max_norm =
271  _console << std::setw(2) << i + 1
272  << " Picard |R| = " << Console::outputNorm(max_norm_old, max_norm) << '\n';
273  max_norm_old = max_norm;
274  }
275 
276  _console << std::endl;
277 }
std::vector< std::vector< PostprocessorValue > > _transformed_pps_values
Previous values of the relaxed postprocessors.
virtual void update(bool update_libmesh_system=true)
Update the system (doing libMesh magic)
Definition: SystemBase.C:1218
std::vector< std::vector< PostprocessorValue > > _secondary_transformed_pps_values
Previous values of the postprocessors relaxed outside of the fixed point iteration (used as a subapp)...
static InputParameters validParams()
Definition: PicardSolve.C:19
FEProblemBase & _problem
Reference to FEProblem.
Definition: SolveObject.h:42
virtual void savePostprocessorValues(const bool primary) override final
Saves the current values of the postprocessors, and update the old(er) vectors.
Definition: PicardSolve.C:163
void addDeprecatedParam(const std::string &name, const T &value, const std::string &doc_string, const std::string &deprecation_message)
virtual void transformPostprocessors(const bool primary) override final
Use the fixed point algorithm to transform the postprocessors.
Definition: PicardSolve.C:199
Real _fixed_point_initial_norm
Initial residual norm.
unsigned int TagID
Definition: MooseTypes.h:199
NumericVector< Number > & solution()
Definition: SystemBase.h:182
PARALLEL
NumericVector< Number > & addVector(const std::string &vector_name, const bool project, const ParallelType type)
Adds a solution length vector to the system.
Definition: SystemBase.C:604
void setPostprocessorValueByName(const PostprocessorName &name, const PostprocessorValue &value, std::size_t t_index=0)
Set the value of a PostprocessorValue.
bool _has_fixed_point_its
Whether or not we activate fixed point iteration.
bool _fixed_point_force_norms
Whether or not we force evaluation of residual norms even without multiapps.
std::vector< Real > _fixed_point_timestep_end_norm
Full history of residual norm after evaluation of timestep_end.
virtual TagID addVectorTag(const TagName &tag_name, const Moose::VectorTagType type=Moose::VECTOR_TAG_RESIDUAL)
Create a Tag.
Definition: SubProblem.C:82
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
bool _has_fixed_point_norm
Whether or not to use residual norm to check the fixed point convergence.
const PostprocessorValue * _fixed_point_custom_pp
Postprocessor value for user-defined fixed point convergence check.
virtual void printFixedPointConvergenceHistory() override final
Print the convergence history of the coupling, at every coupling iteration.
Definition: PicardSolve.C:260
const PostprocessorValue & getPostprocessorValue(const std::string &param_name, const unsigned int index=0) const
doco-normal-methods-begin Retrieve the value of a Postprocessor or one of it&#39;s old or older values ...
std::vector< PostprocessorName > _secondary_transformed_pps
Postprocessors to be relaxed outside of fixed point iteration (used as a subapp)
auto max(const L &left, const R &right)
const std::vector< PostprocessorName > _transformed_pps
The postprocessors (transferred or not) that are going to be relaxed.
Real _fixed_point_rel_tol
Relative tolerance on residual norm.
virtual bool useFixedPointAlgorithmUpdateInsteadOfPicard(const bool primary) override final
Use the fixed point algorithm transform instead of simply using the Picard update.
Definition: PicardSolve.C:188
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
std::vector< Real > _fixed_point_timestep_begin_norm
Full history of residual norm after evaluation of timestep_begin.
bool isParamSetByAddParam(const std::string &name) const
Returns whether or not the parameter was set due to addParam.
const Real _relax_factor
Relaxation factor for fixed point Iteration.
void deprecateParam(const std::string &old_name, const std::string &new_name, const std::string &removal_date)
Executioners are objects that do the actual work of solving your problem.
Definition: Executioner.h:30
TagID _old_tag_id
Vector tag id for the previous solution variable, as a main app.
Definition: PicardSolve.h:86
unsigned int _max_fixed_point_its
Maximum fixed point iterations.
Real _secondary_relaxation_factor
Relaxation factor outside of fixed point iteration (used as a subapp)
virtual void close()=0
virtual const PostprocessorValue & getPostprocessorValueByName(const PostprocessorName &name) const
Retrieve the value of the Postprocessor.
unsigned int _fixed_point_it
TagID _secondary_old_tag_id
Vector tag id for the previous solution variable, as a sub app.
Definition: PicardSolve.h:89
SystemBase & _solver_sys
Reference to a system for creating vectors as needed for the solve, etc.
Definition: SolveObject.h:50
static InputParameters validParams()
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static std::string outputNorm(const Real &old_norm, const Real &norm, const unsigned int precision=6)
A helper function for outputting norms in color.
Definition: Console.C:615
virtual void allocateStorage(const bool primary) override final
Allocate storage for the fixed point algorithm.
Definition: PicardSolve.C:102
const InputParameters & parameters() const
Get the parameters of the object.
virtual void set(const numeric_index_type i, const Number value)=0
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
Real _fixed_point_abs_tol
Absolute tolerance on residual norm.
virtual void saveVariableValues(const bool primary) override final
Saves the current values of the variables, and update the old(er) vectors.
Definition: PicardSolve.C:138
PicardSolve(Executioner &ex)
Definition: PicardSolve.C:71
virtual void transformVariables(const std::set< dof_id_type > &transformed_dofs, const bool primary) override final
Use the fixed point algorithm to transform the variables.
Definition: PicardSolve.C:232
virtual NumericVector< Number > & getVector(const std::string &name)
Get a raw NumericVector by name.
Definition: SystemBase.C:889
bool _accept_max_it
Whether or not to treat reaching maximum number of fixed point iteration as converged.
unsigned int _main_fixed_point_it
fixed point iteration counter for the main app