www.mooseframework.org
PetscOutput.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 // MOOSE includes
11 #include "PetscOutput.h"
12 #include "FEProblem.h"
13 #include "NonlinearSystem.h"
14 
15 #include "libmesh/libmesh_common.h"
16 #include "libmesh/petsc_nonlinear_solver.h"
17 
19 {
20  // register petsc output interface
22 }
23 
24 PetscErrorCode
25 PetscOutputInterface::petscNonlinearOutput(SNES, PetscInt its, PetscReal norm, void * void_ptr)
26 {
27  // Get the primary outputter object
28  PetscOutput * primary_ptr = static_cast<PetscOutput *>(void_ptr);
29 
30  // loop over all interface objects
31  for (const auto poi_ptr : primary_ptr->getMooseApp().getInterfaceObjects<PetscOutputInterface>())
32  {
33  auto ptr = poi_ptr->_petsc_output;
34 
35  // check time
36  if (!ptr->inNonlinearTimeWindow())
37  continue;
38 
39  // Update the pseudo times
40  ptr->_nonlinear_time += ptr->_nonlinear_dt;
41  ptr->_linear_time = ptr->_nonlinear_time;
42 
43  // Set the current norm and iteration number
44  ptr->_norm = norm;
45  ptr->_nonlinear_iter = its;
46 
47  // Set the flag indicating that output is occurring on the non-linear residual
48  ptr->_on_nonlinear_residual = true;
49 
50  // Perform the output
51  ptr->outputStep(EXEC_NONLINEAR);
52 
64  ptr->_app.getOutputWarehouse().flushConsoleBuffer();
65 
66  // Reset the non-linear output flag and the simulation time
67  ptr->_on_nonlinear_residual = false;
68  }
69 
70  // Done
71  return 0;
72 }
73 
74 PetscErrorCode
75 PetscOutputInterface::petscLinearOutput(KSP, PetscInt its, PetscReal norm, void * void_ptr)
76 {
77  // Get the primary outputter object
78  PetscOutput * primary_ptr = static_cast<PetscOutput *>(void_ptr);
79 
80  // loop over all interface objects
81  for (const auto poi_ptr : primary_ptr->getMooseApp().getInterfaceObjects<PetscOutputInterface>())
82  {
83  auto ptr = poi_ptr->_petsc_output;
84 
85  // check time
86  if (!ptr->inLinearTimeWindow())
87  continue;
88 
89  // Update the pseudo time
90  ptr->_linear_time += ptr->_linear_dt;
91 
92  // Set the current norm and iteration number
93  ptr->_norm = norm;
94  ptr->_linear_iter = its;
95 
96  // Set the flag indicating that output is occurring on the non-linear residual
97  ptr->_on_linear_residual = true;
98 
99  // Perform the output
100  ptr->outputStep(EXEC_LINEAR);
101 
113  ptr->_app.getOutputWarehouse().flushConsoleBuffer();
114 
115  // Reset the linear output flag and the simulation time
116  ptr->_on_linear_residual = false;
117  }
118 
119  // Done
120  return 0;
121 }
122 
125 {
127 
128  // Toggled for outputting nonlinear and linear residuals, only if we have PETSc
129  params.addParam<bool>("output_linear",
130  false,
131  "Specifies whether output occurs on each PETSc linear residual evaluation");
132  params.addParam<bool>(
133  "output_nonlinear",
134  false,
135  "Specifies whether output occurs on each PETSc nonlinear residual evaluation");
136  params.addParamNamesToGroup("output_linear output_nonlinear", "Execution scheduling");
137 
138  // Pseudo time step divisors
139  params.addParam<Real>(
140  "nonlinear_residual_dt_divisor",
141  1000,
142  "Number of divisions applied to time step when outputting non-linear residuals");
143  params.addParam<Real>(
144  "linear_residual_dt_divisor",
145  1000,
146  "Number of divisions applied to time step when outputting linear residuals");
147 
148  // Start times for residual output
149  params.addParam<Real>(
150  "linear_residual_start_time",
151  "Specifies a start time to begin output on each linear residual evaluation");
152  params.addParam<Real>(
153  "nonlinear_residual_start_time",
154  "Specifies a start time to begin output on each nonlinear residual evaluation");
155 
156  // End time for residual output
157  /* Note, No default is given here so that in Peacock giant numbers do not show up by default, the
158  * defaults are set in the initialization list */
159  params.addParam<Real>("linear_residual_end_time",
160  "Specifies an end time to begin output on each linear residual evaluation");
161  params.addParam<Real>(
162  "nonlinear_residual_end_time",
163  "Specifies an end time to begin output on each nonlinear residual evaluation");
164 
165  params.addParamNamesToGroup("linear_residual_start_time "
166  "nonlinear_residual_start_time linear_residual_end_time "
167  "nonlinear_residual_end_time nonlinear_residual_dt_divisor "
168  "linear_residual_dt_divisor",
169  "PETSc linear/nonlinear output");
170  return params;
171 }
172 
174  : Output(parameters),
175  PetscOutputInterface(this),
176  _nonlinear_iter(0),
177  _linear_iter(0),
178  _on_linear_residual(false),
179  _on_nonlinear_residual(false),
180  _nonlinear_dt_divisor(getParam<Real>("nonlinear_residual_dt_divisor")),
181  _linear_dt_divisor(getParam<Real>("linear_residual_dt_divisor")),
182  _nonlinear_start_time(-std::numeric_limits<Real>::max()),
183  _linear_start_time(-std::numeric_limits<Real>::max()),
184  _nonlinear_end_time(std::numeric_limits<Real>::max()),
185  _linear_end_time(std::numeric_limits<Real>::max())
186 {
187  // Output toggle support
188  if (getParam<bool>("output_linear"))
189  _execute_on.push_back("linear");
190  if (getParam<bool>("output_nonlinear"))
191  _execute_on.push_back("nonlinear");
192 
193  // Nonlinear residual start-time supplied by user
194  if (isParamValid("nonlinear_residual_start_time"))
195  {
196  _nonlinear_start_time = getParam<Real>("nonlinear_residual_start_time");
197  _execute_on.push_back("nonlinear");
198  }
199 
200  // Nonlinear residual end-time supplied by user
201  if (isParamValid("nonlinear_residual_end_time"))
202  _nonlinear_end_time = getParam<Real>("nonlinear_residual_end_time");
203 
204  // Linear residual start-time supplied by user
205  if (isParamValid("linear_residual_start_time"))
206  {
207  _linear_start_time = getParam<Real>("linear_residual_start_time");
208  _execute_on.push_back("linear");
209  }
210 
211  // Linear residual end-time supplied by user
212  if (isParamValid("linear_residual_end_time"))
213  _linear_end_time = getParam<Real>("linear_residual_end_time");
214 }
215 
216 void
218 {
219  // Update the pseudo times
220  _nonlinear_time = _time_old; // non-linear time starts with the previous time step
221  if (_dt != 0)
222  // set the pseudo non-linear timestep as fraction
223  // of real timestep for transient executioners
225  else
226  // set the pseudo non-linear timestep for steady
227  // executioners (here _dt==0)
229 
230  _linear_dt = _nonlinear_dt / _linear_dt_divisor; // set the pseudo linear timestep
231 
232  // only the first PetscOutput object registers a DM monitor for linear and nonlinear
233  // all other PetscOutput objects are dispatched from that one monitor (per app).
235  return;
236 
237  // Extract the non-linear and linear solvers from PETSc
239  SNES snes = nl.getSNES();
240  KSP ksp;
241  SNESGetKSP(snes, &ksp);
242 
243  // Set the PETSc monitor functions (register the nonlinear callback so that linear outputs
244  // get an updated nonlinear iteration number)
245  // Not every Output should register its own DM monitor! Just register one each of nonlinear
246  // and linear and dispatch all Outputs from there!
247  auto ierr1 = SNESMonitorSet(snes, petscNonlinearOutput, this, LIBMESH_PETSC_NULLPTR);
248  CHKERRABORT(_communicator.get(), ierr1);
249  auto ierr2 = KSPMonitorSet(ksp, petscLinearOutput, this, LIBMESH_PETSC_NULLPTR);
250  CHKERRABORT(_communicator.get(), ierr2);
251 }
252 
253 Real
255 {
257  return _nonlinear_time;
258  else if (_on_linear_residual)
259  return _linear_time;
260  else
261  return Output::time();
262 }
263 
264 Real
266 {
267  return time();
268 }
Real & _time_old
The old time.
Definition: Output.h:211
ExecFlagEnum _execute_on
The common Execution types; this is used as the default execution type for everything except system i...
Definition: Output.h:197
virtual SNES getSNES()=0
static PetscErrorCode petscLinearOutput(KSP, PetscInt its, PetscReal fnorm, void *void_ptr)
Performs the output onlinear iterations This is the monitor method that PETSc will call on linear ite...
Definition: PetscOutput.C:75
virtual Real time() override
Get the output time.
Definition: PetscOutput.C:254
void solveSetup() override
Internal setup function that executes at the beginning of the time step.
Definition: PetscOutput.C:217
bool _on_linear_residual
True if current output calls is on the linear residual (used by time())
Definition: PetscOutput.h:90
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
static PetscErrorCode petscNonlinearOutput(SNES, PetscInt its, PetscReal fnorm, void *void_ptr)
Performs the output on non-linear iterations This is the monitor method that PETSc will call on non-l...
Definition: PetscOutput.C:25
const Parallel::Communicator & _communicator
Real _nonlinear_dt
The pseuedo non-linear time step.
Definition: PetscOutput.h:105
Real _linear_time
Psuedo linear time.
Definition: PetscOutput.h:108
bool _on_nonlinear_residual
True if current output call is on the non-linear residual (used by time())
Definition: PetscOutput.h:93
Real _linear_start_time
Linear residual output start time.
Definition: PetscOutput.h:123
MooseApp & getMooseApp() const
Get the MooseApp this class is associated with.
Definition: MooseBase.h:44
auto max(const L &left, const R &right)
PetscOutputInterface(PetscOutput *obj)
Definition: PetscOutput.C:18
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Real _nonlinear_start_time
Non-linear residual output start time.
Definition: PetscOutput.h:120
Nonlinear system to be solved.
Based class for output objects.
Definition: Output.h:43
Real _linear_end_time
Linear residual output end time.
Definition: PetscOutput.h:129
static InputParameters validParams()
Definition: PetscOutput.C:124
NonlinearSystemBase & currentNonlinearSystem()
Real _linear_dt
Psuedo linear time step.
Definition: PetscOutput.h:111
FEProblemBase * _problem_ptr
Pointer the the FEProblemBase object for output object (use this)
Definition: Output.h:179
PetscOutput * _petsc_output
Definition: PetscOutput.h:23
Real _nonlinear_time
The psuedo non-linear time.
Definition: PetscOutput.h:102
MooseApp & _app
The MOOSE application this is associated with.
Definition: MooseBase.h:69
auto norm(const T &a) -> decltype(std::abs(a))
const ExecFlagType EXEC_LINEAR
Definition: Moose.C:29
PetscOutput(const InputParameters &parameters)
Class constructor.
Definition: PetscOutput.C:173
virtual Real time()
Get the output time.
Definition: Output.C:351
const ExecFlagType EXEC_NONLINEAR
Definition: Moose.C:30
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Real _nonlinear_dt_divisor
Pseudo non-linear timestep divisor.
Definition: PetscOutput.h:114
void push_back(const std::string &names)
Insert operators Operator to insert (push_back) values into the enum.
Real _linear_dt_divisor
Pseudo linear timestep divisor.
Definition: PetscOutput.h:117
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an option parameter and a documentation string to the InputParameters object...
const std::vector< T * > & getInterfaceObjects() const
Gets the registered interface objects for a given interface.
Definition: MooseApp.h:1535
Adds the ability to output on every nonlinear and/or linear residual.
Definition: PetscOutput.h:41
Real _nonlinear_end_time
Non-linear residual output end time.
Definition: PetscOutput.h:126
static InputParameters validParams()
Definition: Output.C:32
virtual Real getOutputTime()
Get the time that will be used for stream/file outputting.
Definition: PetscOutput.C:265
Real & _dt
Time step delta.
Definition: Output.h:217
void registerInterfaceObject(T &interface)
Registers an interface object for accessing with getInterfaceObjects.
Definition: MooseApp.h:1513
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
This method takes a space delimited list of parameter names and adds them to the specified group name...