/
PicardSolve.h
159 lines (136 loc) · 5.26 KB
/
PicardSolve.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
//* 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
#ifndef PICARDSOLVE_H
#define PICARDSOLVE_H
#include "MooseObject.h"
#include "PerfGraphInterface.h"
// System includes
#include <string>
class Executioner;
class FEProblemBase;
class NonlinearSystemBase;
class PicardSolve : public MooseObject, public PerfGraphInterface
{
public:
PicardSolve(Executioner * ex);
/**
* Picard solve the FEProblem.
* @return True if solver is converged.
*/
bool solve();
/// Enumeration for Picard convergence reasons
enum class MoosePicardConvergenceReason
{
UNSOLVED = 0,
CONVERGED_NONLINEAR = 1,
CONVERGED_ABS = 2,
CONVERGED_RELATIVE = 3,
CONVERGED_CUSTOM = 4,
DIVERGED_MAX_ITS = -1,
DIVERGED_NONLINEAR = -2,
DIVERGED_FAILED_MULTIAPP = -3
};
/**
* Get the number of Picard iterations performed
* Because this returns the number of Picard iterations, rather than the current
* iteration count (which starts at 0), increment by 1.
*
* @return Number of Picard iterations performed
*/
unsigned int numPicardIts() const { return _picard_it + 1; }
/// Check the solver status
MoosePicardConvergenceReason checkConvergence() const { return _picard_status; }
/// This function checks the _xfem_repeat_step flag set by solve.
bool XFEMRepeatStep() const { return _xfem_repeat_step; }
/// Clear Picard status
void clearPicardStatus() { _picard_status = MoosePicardConvergenceReason::UNSOLVED; }
/// Whether or not this has Picard iterations
bool hasPicardIteration() { return _has_picard_its; }
/// Set relaxation factor for the current solve as a MultiApp
void setMultiAppRelaxationFactor(Real factor) { _picard_self_relaxation_factor = factor; }
/// Set relaxation variables for the current solve as a MultiApp
void setMultiAppRelaxationVariables(const std::vector<std::string> & vars)
{
_picard_self_relaxed_variables = vars;
}
protected:
/**
* Perform one Picard iteration or a full solve.
*
* @param begin_norm_old Residual norm after timestep_begin execution of previous Picard
* iteration
* @param begin_norm Residual norm after timestep_begin execution
* @param end_norm_old Residual norm after timestep_end execution of previous Picard iteration
* @param end_norm Residual norm after timestep_end execution
* @param relax Whether or not we do relaxation in this iteration
* @param relaxed_dofs DoFs to be relaxed
*
* @return True if both nonlinear solve and the execution of multiapps are successful.
*
* Note: this function also set _xfem_repeat_step flag for XFEM. It tracks _xfem_update_count
* state.
* FIXME: The proper design will be to let XFEM use Picard iteration to control the execution.
*/
bool solveStep(Real begin_norm_old,
Real & begin_norm,
Real end_norm_old,
Real & end_norm,
bool relax,
const std::set<dof_id_type> & relaxed_dofs);
/// Executioner used to construct this
Executioner & _executioner;
/// Reference to FEProblem
FEProblemBase & _problem;
/// Reference to nonlinear system base for faster access
NonlinearSystemBase & _nl;
/// Maximum Picard iterations
unsigned int _picard_max_its;
/// Whether or not we activate Picard iteration
bool _has_picard_its;
/// Relative tolerance on residual norm
Real _picard_rel_tol;
/// Absolute tolerance on residual norm
Real _picard_abs_tol;
/// Whether or not we force evaluation of residual norms even without multiapps
bool _picard_force_norms;
/// Relaxation factor for Picard Iteration
Real _relax_factor;
/// The transferred variables that are going to be relaxed
std::vector<std::string> _relaxed_vars;
/// Relaxation factor outside of Picard iteration (used as a subapp)
Real _picard_self_relaxation_factor;
/// Variables to be relaxed outside of Picard iteration (used as a subapp)
std::vector<std::string> _picard_self_relaxed_variables;
/// Maximum number of xfem updates per step
unsigned int _max_xfem_update;
/// Controls whether xfem should update the mesh at the beginning of the time step
bool _update_xfem_at_timestep_begin;
private:
/// Timer for Picard iteration
const PerfID _picard_timer;
///@{ Variables used by the Picard iteration
/// Picard iteration counter
unsigned int _picard_it;
/// Initial residual norm
Real _picard_initial_norm;
/// Full history of residual norm after evaluation of timestep_begin
std::vector<Real> _picard_timestep_begin_norm;
/// Full history of residual norm after evaluation of timestep_end
std::vector<Real> _picard_timestep_end_norm;
/// Status of Picard solve
MoosePicardConvergenceReason _picard_status;
///@}
/// Counter for number of xfem updates that have been performed in the current step
unsigned int _xfem_update_count;
/// Whether step should be repeated due to xfem modifying the mesh
bool _xfem_repeat_step;
/// Time of previous Picard solve as a subapp
Real _previous_entering_time;
};
#endif // PICARDSOLVE_H