https://mooseframework.inl.gov
PetscOutput.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 // MOOSE includes
11 #include "PetscOutput.h"
12 #include "FEProblem.h"
13 #include "NonlinearSystem.h"
14 #include "CommonOutputAction.h"
15 
16 #include "libmesh/libmesh_common.h"
17 #include "libmesh/petsc_nonlinear_solver.h"
18 
20 {
21  // register petsc output interface
23 }
24 
25 PetscErrorCode
26 PetscOutputInterface::petscNonlinearOutput(SNES, PetscInt its, PetscReal norm, void * void_ptr)
27 {
28  // Get the primary outputter object
29  PetscOutput * primary_ptr = static_cast<PetscOutput *>(void_ptr);
30 
31  // loop over all interface objects
32  for (const auto poi_ptr : primary_ptr->getMooseApp().getInterfaceObjects<PetscOutputInterface>())
33  {
34  auto ptr = poi_ptr->_petsc_output;
35 
36  // check time
37  if (!ptr->inNonlinearTimeWindow())
38  continue;
39 
40  // Update the pseudo times
41  ptr->_nonlinear_time += ptr->_nonlinear_dt;
42  ptr->_linear_time = ptr->_nonlinear_time;
43 
44  // Set the current norm and iteration number
45  ptr->_norm = norm;
46  ptr->_nonlinear_iter = its;
47 
48  // Set the flag indicating that output is occurring on the non-linear residual
49  ptr->_on_nonlinear_residual = true;
50 
51  // Perform the output
52  ptr->outputStep(EXEC_NONLINEAR);
53 
65  ptr->_app.getOutputWarehouse().flushConsoleBuffer();
66 
67  // Reset the non-linear output flag and the simulation time
68  ptr->_on_nonlinear_residual = false;
69  }
70 
71  // Done
72  return (PetscErrorCode)0;
73 }
74 
75 PetscErrorCode
76 PetscOutputInterface::petscLinearOutput(KSP, PetscInt its, PetscReal norm, void * void_ptr)
77 {
78  // Get the primary outputter object
79  PetscOutput * primary_ptr = static_cast<PetscOutput *>(void_ptr);
80 
81  // loop over all interface objects
82  for (const auto poi_ptr : primary_ptr->getMooseApp().getInterfaceObjects<PetscOutputInterface>())
83  {
84  auto ptr = poi_ptr->_petsc_output;
85 
86  // check time
87  if (!ptr->inLinearTimeWindow())
88  continue;
89 
90  // Update the pseudo time
91  ptr->_linear_time += ptr->_linear_dt;
92 
93  // Set the current norm and iteration number
94  ptr->_norm = norm;
95  ptr->_linear_iter = its;
96 
97  // Set the flag indicating that output is occurring on the non-linear residual
98  ptr->_on_linear_residual = true;
99 
100  // Perform the output
101  ptr->outputStep(EXEC_LINEAR);
102 
114  ptr->_app.getOutputWarehouse().flushConsoleBuffer();
115 
116  // Reset the linear output flag and the simulation time
117  ptr->_on_linear_residual = false;
118  }
119 
120  // Done
121  return (PetscErrorCode)0;
122 }
123 
126 {
128 
129  // Toggled for outputting nonlinear and linear residuals, only if we have PETSc
130  params.addParam<bool>("output_linear",
131  false,
132  "Specifies whether output occurs on each PETSc linear residual evaluation");
133  params.addParam<bool>(
134  "output_nonlinear",
135  false,
136  "Specifies whether output occurs on each PETSc nonlinear residual evaluation");
137  params.addParamNamesToGroup("output_linear output_nonlinear", "Execution scheduling");
138 
139  // Pseudo time step divisors
140  params.addParam<Real>(
141  "nonlinear_residual_dt_divisor",
142  1000,
143  "Number of divisions applied to time step when outputting non-linear residuals");
144  params.addParam<Real>(
145  "linear_residual_dt_divisor",
146  1000,
147  "Number of divisions applied to time step when outputting linear residuals");
148 
149  // Start times for residual output
150  params.addParam<Real>(
151  "linear_residual_start_time",
152  "Specifies a start time to begin output on each linear residual evaluation");
153  params.addParam<Real>(
154  "nonlinear_residual_start_time",
155  "Specifies a start time to begin output on each nonlinear residual evaluation");
156 
157  // End time for residual output
158  /* Note, No default is given here so that in Peacock giant numbers do not show up by default, the
159  * defaults are set in the initialization list */
160  params.addParam<Real>("linear_residual_end_time",
161  "Specifies an end time to begin output on each linear residual evaluation");
162  params.addParam<Real>(
163  "nonlinear_residual_end_time",
164  "Specifies an end time to begin output on each nonlinear residual evaluation");
165 
166  params.addParamNamesToGroup("linear_residual_start_time "
167  "nonlinear_residual_start_time linear_residual_end_time "
168  "nonlinear_residual_end_time nonlinear_residual_dt_divisor "
169  "linear_residual_dt_divisor",
170  "PETSc linear/nonlinear output");
171  return params;
172 }
173 
175  : Output(parameters),
176  PetscOutputInterface(this),
177  _nonlinear_iter(0),
178  _linear_iter(0),
179  _on_linear_residual(false),
180  _on_nonlinear_residual(false),
181  _nonlinear_dt_divisor(getParam<Real>("nonlinear_residual_dt_divisor")),
182  _linear_dt_divisor(getParam<Real>("linear_residual_dt_divisor")),
183  _nonlinear_start_time(-std::numeric_limits<Real>::max()),
184  _linear_start_time(-std::numeric_limits<Real>::max()),
185  _nonlinear_end_time(std::numeric_limits<Real>::max()),
186  _linear_end_time(std::numeric_limits<Real>::max())
187 {
188  // Output toggle support
189  if (getParam<bool>("output_linear"))
191  if (getParam<bool>("output_nonlinear"))
192  _execute_on.setAdditionalValue("nonlinear");
193 
194  // Nonlinear residual start-time supplied by user
195  if (isParamValid("nonlinear_residual_start_time"))
196  {
197  _nonlinear_start_time = getParam<Real>("nonlinear_residual_start_time");
198  _execute_on.setAdditionalValue("nonlinear");
199  }
200 
201  // Nonlinear residual end-time supplied by user
202  if (isParamValid("nonlinear_residual_end_time"))
203  _nonlinear_end_time = getParam<Real>("nonlinear_residual_end_time");
204 
205  // Linear residual start-time supplied by user
206  if (isParamValid("linear_residual_start_time"))
207  {
208  _linear_start_time = getParam<Real>("linear_residual_start_time");
210  }
211 
212  // Linear residual end-time supplied by user
213  if (isParamValid("linear_residual_end_time"))
214  _linear_end_time = getParam<Real>("linear_residual_end_time");
215 }
216 
217 void
219 {
220  // Update the pseudo times
221  _nonlinear_time = _time_old; // non-linear time starts with the previous time step
222  if (_dt != 0)
223  // set the pseudo non-linear timestep as fraction
224  // of real timestep for transient executioners
226  else
227  // set the pseudo non-linear timestep for steady
228  // executioners (here _dt==0)
230 
231  _linear_dt = _nonlinear_dt / _linear_dt_divisor; // set the pseudo linear timestep
232 
233  // only the first PetscOutput object registers a DM monitor for linear and nonlinear
234  // all other PetscOutput objects are dispatched from that one monitor (per app).
236  return;
237 
239  const auto actions = awh.getActions<CommonOutputAction>();
240  mooseAssert(actions.size() <= 1, "Should not be more than one CommonOutputAction");
241  const Action * common = actions.empty() ? nullptr : *actions.begin();
242 
243  // Extract the non-linear and linear solvers from PETSc
245  SNES snes = nl.getSNES();
246  KSP ksp;
247  LibmeshPetscCallA(_communicator.get(), SNESGetKSP(snes, &ksp));
248 
249  // Set the PETSc monitor functions (register the nonlinear callback so that linear outputs
250  // get an updated nonlinear iteration number)
251  // Not every Output should register its own DM monitor! Just register one each of nonlinear
252  // and linear and dispatch all Outputs from there!
253  if (common && common->getParam<bool>("print_nonlinear_residuals"))
254  LibmeshPetscCallA(_communicator.get(),
255  SNESMonitorSet(snes, petscNonlinearOutput, this, LIBMESH_PETSC_NULLPTR));
256  if (common && common->getParam<bool>("print_linear_residuals"))
257  LibmeshPetscCallA(_communicator.get(),
258  KSPMonitorSet(ksp, petscLinearOutput, this, LIBMESH_PETSC_NULLPTR));
259 }
260 
261 Real
263 {
265  return _nonlinear_time;
266  else if (_on_linear_residual)
267  return _linear_time;
268  else
269  return Output::time();
270 }
271 
272 Real
274 {
275  return time();
276 }
Real & _time_old
The old time.
Definition: Output.h:217
ExecFlagEnum _execute_on
The common Execution types; this is used as the default execution type for everything except system i...
Definition: Output.h:203
virtual SNES getSNES()=0
void setAdditionalValue(const std::string &names)
Insert operators Operator to insert (push_back) values into the enum.
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:76
virtual Real time() override
Get the output time.
Definition: PetscOutput.C:262
void solveSetup() override
Internal setup function that executes at the beginning of the time step.
Definition: PetscOutput.C:218
bool _on_linear_residual
True if current output calls is on the linear residual (used by time())
Definition: PetscOutput.h:90
Storage for action instances.
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:26
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
Base class for actions.
Definition: Action.h:33
MooseApp & getMooseApp() const
Get the MooseApp this class is associated with.
Definition: MooseBase.h:45
auto max(const L &left, const R &right)
PetscOutputInterface(PetscOutput *obj)
Definition: PetscOutput.C:19
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:125
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:185
ActionWarehouse & actionWarehouse()
Return a writable reference to the ActionWarehouse associated with this app.
Definition: MooseApp.h:237
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:84
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:174
virtual Real time()
Get the output time.
Definition: Output.C:353
const ExecFlagType EXEC_NONLINEAR
Definition: Moose.C:31
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Real _nonlinear_dt_divisor
Pseudo non-linear timestep divisor.
Definition: PetscOutput.h:114
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 optional 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:1674
Adds the ability to output on every nonlinear and/or linear residual.
Definition: PetscOutput.h:41
std::vector< const T * > getActions()
Retrieve all actions in a specific type ordered by their names.
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:273
Real & _dt
Time step delta.
Definition: Output.h:223
Meta-action for creating common output object parameters This action serves two purpose, first it adds common output object parameters.
void registerInterfaceObject(T &interface)
Registers an interface object for accessing with getInterfaceObjects.
Definition: MooseApp.h:1652
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...