https://mooseframework.inl.gov
PicardSolve.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 
10 #include "PicardSolve.h"
11 
12 #include "Executioner.h"
13 #include "FEProblemBase.h"
14 #include "NonlinearSystem.h"
16 #include "Console.h"
17 
20 {
22  return params;
23 }
24 
26 
27 void
28 PicardSolve::allocateStorage(const bool primary)
29 {
30  Real relaxation_factor;
31  TagID old_tag_id;
32  const std::vector<PostprocessorName> * transformed_pps;
33  std::vector<std::vector<PostprocessorValue>> * transformed_pps_values;
34  if (primary)
35  {
36  relaxation_factor = _relax_factor;
37  old_tag_id = _problem.addVectorTag("xn_m1", Moose::VECTOR_TAG_SOLUTION);
38  _old_tag_id = old_tag_id;
39  transformed_pps = &_transformed_pps;
40  transformed_pps_values = &_transformed_pps_values;
41  }
42  else
43  {
44  relaxation_factor = _secondary_relaxation_factor;
45  old_tag_id = _problem.addVectorTag("secondary_xn_m1", Moose::VECTOR_TAG_SOLUTION);
46  _secondary_old_tag_id = old_tag_id;
47  transformed_pps = &_secondary_transformed_pps;
48  transformed_pps_values = &_secondary_transformed_pps_values;
49  }
50 
51  if (relaxation_factor != 1.)
52  {
53  // Store a copy of the previous solution
54  _solver_sys.addVector(old_tag_id, false, PARALLEL);
55 
56  // Allocate storage for the previous postprocessor values
57  (*transformed_pps_values).resize((*transformed_pps).size());
58  for (size_t i = 0; i < (*transformed_pps).size(); i++)
59  (*transformed_pps_values)[i].resize(1);
60  }
61 }
62 
63 void
65 {
66  Real relaxation_factor;
67  TagID old_tag_id;
68  if (primary)
69  {
70  relaxation_factor = _relax_factor;
71  old_tag_id = _old_tag_id;
72  }
73  else
74  {
75  relaxation_factor = _secondary_relaxation_factor;
76  old_tag_id = _secondary_old_tag_id;
77  }
78 
79  if (relaxation_factor != 1.)
80  {
81  // Save variable previous values
83  NumericVector<Number> & transformed_old = _solver_sys.getVector(old_tag_id);
84  transformed_old = solution;
85  }
86 }
87 
88 void
90 {
91  Real relaxation_factor;
92  const std::vector<PostprocessorName> * transformed_pps;
93  std::vector<std::vector<PostprocessorValue>> * transformed_pps_values;
94  if (primary)
95  {
96  relaxation_factor = _relax_factor;
97  transformed_pps = &_transformed_pps;
98  transformed_pps_values = &_transformed_pps_values;
99  }
100  else
101  {
102  relaxation_factor = _secondary_relaxation_factor;
103  transformed_pps = &_secondary_transformed_pps;
104  transformed_pps_values = &_secondary_transformed_pps_values;
105  }
106 
107  if (relaxation_factor != 1.)
108  // Save postprocessor previous values
109  for (size_t i = 0; i < (*transformed_pps).size(); i++)
110  (*transformed_pps_values)[i][0] = getPostprocessorValueByName((*transformed_pps)[i]);
111 }
112 
113 bool
115 {
116  // unrelaxed Picard is the default update for fixed point iterations
117  // old values are required for relaxation
118  if (primary)
119  return _relax_factor != 1. && _fixed_point_it > 0;
120  else
122 }
123 
124 void
126 {
127  Real relaxation_factor;
128  const std::vector<PostprocessorName> * transformed_pps;
129  std::vector<std::vector<PostprocessorValue>> * transformed_pps_values;
130  if (primary)
131  {
132  relaxation_factor = _relax_factor;
133  transformed_pps = &_transformed_pps;
134  transformed_pps_values = &_transformed_pps_values;
135  }
136  else
137  {
138  relaxation_factor = _secondary_relaxation_factor;
139  transformed_pps = &_secondary_transformed_pps;
140  transformed_pps_values = &_secondary_transformed_pps_values;
141  }
142 
143  // Relax the postprocessors
144  for (size_t i = 0; i < (*transformed_pps).size(); i++)
145  {
146  // Get new postprocessor value
147  const Real current_value = getPostprocessorValueByName((*transformed_pps)[i]);
148  const Real old_value = (*transformed_pps_values)[i][0];
149 
150  // Compute and set relaxed value
151  Real new_value = current_value;
152  new_value = relaxation_factor * current_value + (1 - relaxation_factor) * old_value;
153  _problem.setPostprocessorValueByName((*transformed_pps)[i], new_value);
154  }
155 }
156 
157 void
158 PicardSolve::transformVariables(const std::set<dof_id_type> & transformed_dofs, const bool primary)
159 {
160  Real relaxation_factor;
161  TagID old_tag_id;
162  if (primary)
163  {
164  relaxation_factor = _relax_factor;
165  old_tag_id = _old_tag_id;
166  }
167  else
168  {
169  relaxation_factor = _secondary_relaxation_factor;
170  old_tag_id = _secondary_old_tag_id;
171  }
172 
174  NumericVector<Number> & transformed_old = _solver_sys.getVector(old_tag_id);
175 
176  for (const auto & dof : transformed_dofs)
177  solution.set(dof,
178  (transformed_old(dof) * (1.0 - relaxation_factor)) +
179  (solution(dof) * relaxation_factor));
180 
181  solution.close();
183 }
184 
185 void
187  const std::vector<Real> & timestep_begin_norms,
188  const std::vector<Real> & timestep_end_norms) const
189 {
190  _console << "\n 0 Picard |R| = "
191  << Console::outputNorm(std::numeric_limits<Real>::max(), initial_norm) << '\n';
192 
193  Real max_norm_old = initial_norm;
194  for (unsigned int i = 0; i <= _fixed_point_it; ++i)
195  {
196  Real max_norm = std::max(timestep_begin_norms[i], timestep_end_norms[i]);
197  _console << std::setw(2) << i + 1
198  << " Picard |R| = " << Console::outputNorm(max_norm_old, max_norm) << '\n';
199  max_norm_old = max_norm;
200  }
201 
202  _console << std::endl;
203 }
std::vector< std::vector< PostprocessorValue > > _transformed_pps_values
Previous values of the relaxed postprocessors.
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:47
virtual void savePostprocessorValues(const bool primary) override final
Saves the current values of the postprocessors, and update the old(er) vectors.
Definition: PicardSolve.C:89
virtual void transformPostprocessors(const bool primary) override final
Use the fixed point algorithm to transform the postprocessors.
Definition: PicardSolve.C:125
unsigned int TagID
Definition: MooseTypes.h:210
NumericVector< Number > & solution()
Definition: SystemBase.h:195
PARALLEL
void setPostprocessorValueByName(const PostprocessorName &name, const PostprocessorValue &value, std::size_t t_index=0)
Set the value of a PostprocessorValue.
virtual TagID addVectorTag(const TagName &tag_name, const Moose::VectorTagType type=Moose::VECTOR_TAG_RESIDUAL)
Create a Tag.
Definition: SubProblem.C:92
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
virtual void printFixedPointConvergenceHistory(Real initial_norm, const std::vector< Real > &timestep_begin_norms, const std::vector< Real > &timestep_end_norms) const override final
Print the convergence history of the coupling, at every fixed point iteration.
Definition: PicardSolve.C:186
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.
NumericVector< Number > & addVector(const std::string &vector_name, const bool project, const libMesh::ParallelType type)
Adds a solution length vector to the system.
virtual bool useFixedPointAlgorithmUpdateInsteadOfPicard(const bool primary) override final
Use the fixed point algorithm transform instead of simply using the Picard update.
Definition: PicardSolve.C:114
void update()
Update the system (doing libMesh magic)
Definition: SystemBase.C:1245
const Real _relax_factor
Relaxation factor for fixed point Iteration.
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:88
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:91
SystemBase & _solver_sys
Reference to a system for creating vectors as needed for the solve, etc.
Definition: SolveObject.h:55
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:619
virtual void allocateStorage(const bool primary) override final
Allocate storage for the fixed point algorithm.
Definition: PicardSolve.C:28
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.
virtual void saveVariableValues(const bool primary) override final
Saves the current values of the variables, and update the old(er) vectors.
Definition: PicardSolve.C:64
PicardSolve(Executioner &ex)
Definition: PicardSolve.C:25
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:158
virtual NumericVector< Number > & getVector(const std::string &name)
Get a raw NumericVector by name.
Definition: SystemBase.C:916
unsigned int _main_fixed_point_it
fixed point iteration counter for the main app