Permalink
Browse files

Merge pull request #12797 from YaqiWang/cleanup_picard_its_for_9038

Picard iteration refactoring
  • Loading branch information...
friedmud committed Feb 4, 2019
2 parents 6e7e926 + 28662ff commit 28eaab6a0c8b6b8d819ab80214d642ec728b5a72
Showing with 1,336 additions and 536 deletions.
  1. +9 −0 framework/doc/content/syntax/Executioner/index.md
  2. +4 −2 framework/include/executioners/EigenExecutionerBase.h
  3. +10 −1 framework/include/executioners/Executioner.h
  4. +4 −0 framework/include/executioners/InversePowerMethod.h
  5. +3 −0 framework/include/executioners/NonlinearEigen.h
  6. +159 −0 framework/include/executioners/PicardSolve.h
  7. +5 −0 framework/include/executioners/Steady.h
  8. +1 −57 framework/include/executioners/Transient.h
  9. +1 −8 framework/include/multiapps/FullSolveMultiApp.h
  10. +0 −7 framework/include/multiapps/MultiApp.h
  11. +2 −0 framework/include/outputs/Console.h
  12. +30 −29 framework/include/problems/FEProblemBase.h
  13. +2 −1 framework/include/timesteppers/AB2PredictorCorrector.h
  14. +1 −1 framework/include/timesteppers/DT2.h
  15. +2 −2 framework/include/timesteppers/IterationAdaptiveDT.h
  16. +1 −1 framework/include/timesteppers/TimeStepper.h
  17. +15 −4 framework/src/executioners/EigenExecutionerBase.C
  18. +51 −6 framework/src/executioners/Executioner.C
  19. +10 −10 framework/src/executioners/InversePowerMethod.C
  20. +1 −1 framework/src/executioners/NonlinearEigen.C
  21. +355 −0 framework/src/executioners/PicardSolve.C
  22. +1 −11 framework/src/executioners/Steady.C
  23. +20 −305 framework/src/executioners/Transient.C
  24. +1 −9 framework/src/multiapps/FullSolveMultiApp.C
  25. +21 −1 framework/src/multiapps/MultiApp.C
  26. +10 −2 framework/src/outputs/Console.C
  27. +1 −1 framework/src/postprocessors/NumPicardIterations.C
  28. +19 −25 framework/src/problems/FEProblemBase.C
  29. +11 −10 framework/src/timesteppers/AB2PredictorCorrector.C
  30. +1 −1 framework/src/timesteppers/DT2.C
  31. +2 −7 framework/src/timesteppers/IterationAdaptiveDT.C
  32. +2 −3 framework/src/timesteppers/TimeStepper.C
  33. +11 −11 framework/src/utils/PetscSupport.C
  34. +5 −3 modules/contact/src/AugmentedLagrangianContactProblem.C
  35. +8 −8 modules/contact/src/ReferenceResidualProblem.C
  36. BIN modules/level_set/test/tests/reinitialization/gold/master_out.e
  37. +1 −0 modules/stochastic_tools/test/tests/multiapps/commandline_control/gold/master_multiple_out_sub0.csv
  38. +1 −0 modules/stochastic_tools/test/tests/multiapps/commandline_control/gold/master_multiple_out_sub1.csv
  39. +1 −0 modules/stochastic_tools/test/tests/multiapps/commandline_control/gold/master_multiple_out_sub2.csv
  40. +1 −0 modules/stochastic_tools/test/tests/multiapps/commandline_control/gold/master_single_out_sub0.csv
  41. +1 −0 modules/stochastic_tools/test/tests/multiapps/commandline_control/gold/master_single_out_sub1.csv
  42. +1 −0 modules/stochastic_tools/test/tests/multiapps/commandline_control/gold/master_single_out_sub2.csv
  43. +1 −1 test/include/timesteppers/TimeSequenceStepperFailTest.h
  44. +0 −2 test/src/executioners/AdaptAndModify.C
  45. +1 −1 test/src/timesteppers/TimeSequenceStepperFailTest.C
  46. BIN test/tests/multiapps/command_line/gold/master_common_out_sub0.e
  47. BIN test/tests/multiapps/command_line/gold/master_common_out_sub1.e
  48. BIN test/tests/multiapps/command_line/gold/master_out_sub0.e
  49. BIN test/tests/multiapps/command_line/gold/master_out_sub1.e
  50. +1 −1 test/tests/multiapps/initial_failure/sub.i
  51. BIN test/tests/multiapps/picard/gold/steady_picard_master_out.e
  52. +94 −0 test/tests/multiapps/picard/steady_picard_master.i
  53. +53 −0 test/tests/multiapps/picard/steady_picard_sub.i
  54. +10 −0 test/tests/multiapps/picard/tests
  55. +2 −0 test/tests/multiapps/relaxation/sub_relaxed_master.i
  56. +0 −3 test/tests/multiapps/relaxation/sub_relaxed_sub.i
  57. +7 −1 test/tests/multiapps/relaxation/tests
  58. +139 −0 test/tests/problems/eigen_problem/ne_coupled_picard.i
  59. +80 −0 test/tests/problems/eigen_problem/ne_coupled_picard_masterT.i
  60. +113 −0 test/tests/problems/eigen_problem/ne_coupled_picard_masterT_sub.i
  61. +50 −0 test/tests/problems/eigen_problem/ne_coupled_picard_sub.i
@@ -11,6 +11,15 @@ Executioner block. Please see the online
[PETSc documentation](http://www.mcs.anl.gov/petsc/documentation/index.html) for
detailed information about these options.

MOOSE provides Picard iterations in all its executioners for tightly-coupled multiphysics simulations.
MultiApps of two groups of before and after master app and master app are solved sequentially within one Picard iteration.
The execution order of MutlApps within one group is undefined.
Relevant data transfers happen before and after each of the two groups of MultiApps runs.
Because MultiApp allows wrapping another levels of MultiApps, the design enables multi-level Picard iterations automatically.
Picard iterations can be relaxed to improve the stabilitity of the convergence.
When a MultiApp is a subapp of a master and a master of its own subapps, MOOSE allows relaxation of the MultiApp solution
within the master Picard iterations and within the Picard iterations, where the MultiApp is the master, independently.

!syntax list /Executioner objects=True actions=False subsystems=False

!syntax list /Executioner objects=False actions=False subsystems=True
@@ -65,8 +65,9 @@ class EigenExecutionerBase : public Executioner
* @param tol_x Tolerance on the difference of the solution norm of two successive iterations.
* @param k Eigenvalue, input as the initial guess.
* @param initial_res The initial residual.
* @return true solve converges, otherwise false.
*/
virtual void inversePowerIteration(unsigned int min_iter,
virtual bool inversePowerIteration(unsigned int min_iter,
unsigned int max_iter,
Real pfactor,
bool cheb_on,
@@ -109,8 +110,9 @@ class EigenExecutionerBase : public Executioner
* @param abs_tol Absolute tolerance on system residual.
* @param pfactor The factor on reducing the residual norm of each linear iteration.
* @param k Eigenvalue, input as the initial guess.
* @return true solve converges, otherwise false.
*/
virtual void nonlinearSolve(Real rel_tol, Real abs_tol, Real pfactor, Real & k);
virtual bool nonlinearSolve(Real rel_tol, Real abs_tol, Real pfactor, Real & k);

/**
* A method for returning the eigenvalue computed by the executioner
@@ -15,6 +15,7 @@
#include "PostprocessorInterface.h"
#include "Restartable.h"
#include "PerfGraphInterface.h"
#include "PicardSolve.h"

// System includes
#include <string>
@@ -107,7 +108,13 @@ class Executioner : public MooseObject,
/**
* Whether or not the last solve converged.
*/
virtual bool lastSolveConverged();
virtual bool lastSolveConverged() const = 0;

/// Return underlining PicardSolve object.
PicardSolve & picardSolve() { return _picard_solve; }

/// Augmented Picard convergence check that can be overridden by derived executioners
virtual bool augmentedPicardConvergenceCheck() const { return false; }

protected:
/**
@@ -122,6 +129,8 @@ class Executioner : public MooseObject,

FEProblemBase & _fe_problem;

PicardSolve _picard_solve;

/// Initial Residual Variables
Real _initial_residual_norm;
Real _old_initial_residual_norm;
@@ -27,6 +27,8 @@ class InversePowerMethod : public EigenExecutionerBase

virtual void execute() override;

virtual bool lastSolveConverged() const override { return _last_solve_converged; }

protected:
virtual void takeStep();

@@ -46,6 +48,8 @@ class InversePowerMethod : public EigenExecutionerBase
const Real & _pfactor;
/// indicating if Chebyshev acceleration is turned on
const bool & _cheb_on;
/// flag to indicate if inverse power iteration converged
bool _last_solve_converged;
};

#endif // INVERSEPOWERMETHOD_H
@@ -27,6 +27,8 @@ class NonlinearEigen : public EigenExecutionerBase

virtual void execute() override;

virtual bool lastSolveConverged() const override { return _last_solve_converged; }

protected:
virtual void takeStep();

@@ -36,6 +38,7 @@ class NonlinearEigen : public EigenExecutionerBase
const Real & _pfactor;
bool _output_pi;
bool _output_after_pi;
bool _last_solve_converged;
};

#endif // NONLINEAREIGEN_H
@@ -0,0 +1,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
@@ -46,13 +46,18 @@ class Steady : public Executioner

virtual void checkIntegrity();

virtual bool lastSolveConverged() const override { return _last_solve_converged; }

protected:
FEProblemBase & _problem;

int & _time_step;
Real & _time;

PerfID _final_timer;

private:
bool _last_solve_converged;
};

#endif // STEADY_H
@@ -67,7 +67,7 @@ class Transient : public Executioner
/**
* Whether or not the last solve converged.
*/
virtual bool lastSolveConverged() override;
virtual bool lastSolveConverged() const override;

virtual void preExecute() override;

@@ -192,37 +192,12 @@ class Transient : public Executioner

void parentOutputPositionChanged() override { _fe_problem.parentOutputPositionChanged(); }

/**
* 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; }

/**
* Print the Picard norms before the convergence check
*/
virtual void printPicardNorms() const;

/**
* Check if Picard iteration converged when maximum number of Picard iterations is greater than
* one.
*/
virtual bool picardConverged() const;

/**
* The relative L2 norm of the difference between solution and old solution vector.
*/
virtual Real relativeSolutionDifferenceNorm();

protected:
/**
* This should execute the solve for one timestep.
*/
virtual void solveStep(Real input_dt = -1.0);

/// Here for backward compatibility
FEProblemBase & _problem;

@@ -245,9 +220,6 @@ class Transient : public Executioner
Real & _unconstrained_dt;
bool & _at_sync_point;

/// Is it our first time through the execution loop?
bool & _first;

/// Whether or not the multiapps failed during the last timestem
bool & _multiapps_converged;

@@ -293,20 +265,6 @@ class Transient : public Executioner
Real & _target_time;
bool _use_multiapp_dt;

/**
* Picard Related
*/
/// Number of Picard iterations to perform
unsigned int & _picard_it;
unsigned int _picard_max_its;
bool & _picard_converged;
Real & _picard_initial_norm;
std::vector<Real> & _picard_timestep_begin_norm;
std::vector<Real> & _picard_timestep_end_norm;
Real _picard_rel_tol;
Real _picard_abs_tol;
bool _picard_force_norms;

///should detailed diagnostic output be printed
bool _verbose;

@@ -317,20 +275,6 @@ class Transient : public Executioner

void setupTimeIntegrator();

/// Relaxation factor for Picard Iteration
Real _relax_factor;

/// The _time when this app solved last.
/// This allows a sub-app to know if this is the first
/// Picard iteration or not.
Real _prev_time;

/// The transferred variables that are going to be relaxed
std::vector<std::string> _relaxed_vars;

/// The DoFs associates with all of the relaxed variables
std::set<dof_id_type> _relaxed_dofs;

PerfID _final_timer;
};

Oops, something went wrong.

0 comments on commit 28eaab6

Please sign in to comment.