diff --git a/framework/include/executioners/Executioner.h b/framework/include/executioners/Executioner.h index c15238037f04..b48dbc2ab66d 100644 --- a/framework/include/executioners/Executioner.h +++ b/framework/include/executioners/Executioner.h @@ -153,6 +153,12 @@ class Executioner : public MooseObject, */ static MooseEnum iterationMethods() { return MooseEnum("picard secant steffensen", "picard"); } + /** + * Whether the executioner has the legacy time execution, i.e. timestep_begin/end are executed + * within the fixed point solve object + */ + bool legacyTimeExecution() const { return _legacy_execute_on; } + protected: /** * Adds a postprocessor that the executioner can directly assign values to @@ -163,6 +169,9 @@ class Executioner : public MooseObject, virtual PostprocessorValue & addAttributeReporter(const std::string & name, Real initial_value = 0); + /// Flag to indicate timestep_begin/end objects are to be executed within a fixed point iteration + const bool _legacy_execute_on; + FEProblemBase & _fe_problem; MooseEnum _iteration_method; diff --git a/framework/include/executioners/FixedPointSolve.h b/framework/include/executioners/FixedPointSolve.h index e1abf510dcd4..c7f257cb6c55 100644 --- a/framework/include/executioners/FixedPointSolve.h +++ b/framework/include/executioners/FixedPointSolve.h @@ -23,6 +23,10 @@ class FixedPointSolve : public SolveObject static InputParameters validParams(); + /// Custom execute flags for fixed point iterations + static const ExecFlagType EXEC_FIXEDPOINT_BEGIN; + static const ExecFlagType EXEC_FIXEDPOINT_END; + /** * Iteratively solves the FEProblem. * @return True if solver is converged. @@ -143,8 +147,8 @@ class FixedPointSolve : public SolveObject /** * Perform one fixed point iteration or a full solve. * - * @param begin_norm Residual norm after timestep_begin execution - * @param end_norm Residual norm after timestep_end execution + * @param begin_norm Residual norm after fixedpoint_begin execution + * @param end_norm Residual norm after fixedpoint_end execution * @param transformed_dofs DoFs targetted by the fixed point algorithm * * @return True if both nonlinear solve and the execution of multiapps are successful. @@ -193,6 +197,8 @@ class FixedPointSolve : public SolveObject /// Print information about the fixed point convergence void printFixedPointConvergenceReason(); + /// Flag to indicate timestep_begin/end objects are to be executed within a fixed point iteration + const bool _legacy_execute_on; /// Minimum fixed point iterations unsigned int _min_fixed_point_its; /// Maximum fixed point iterations @@ -239,10 +245,10 @@ class FixedPointSolve : public SolveObject unsigned int _main_fixed_point_it; /// Initial residual norm Real _fixed_point_initial_norm; - /// Full history of residual norm after evaluation of timestep_begin - std::vector _fixed_point_timestep_begin_norm; - /// Full history of residual norm after evaluation of timestep_end - std::vector _fixed_point_timestep_end_norm; + /// Full history of residual norm after evaluation of fixedpoint_begin + std::vector _fixed_point_begin_norm; + /// Full history of residual norm after evaluation of fixedpoint_end + std::vector _fixed_point_end_norm; /// Status of fixed point solve MooseFixedPointConvergenceReason _fixed_point_status; ///@} diff --git a/framework/src/base/MooseApp.C b/framework/src/base/MooseApp.C index 5d95db8d1c2d..1fac7f0655b0 100644 --- a/framework/src/base/MooseApp.C +++ b/framework/src/base/MooseApp.C @@ -358,6 +358,12 @@ MooseApp::validParams() "solution modifying objects are executed prior to the initial (0th nonlinear iteration) " "residual evaluation. The new behavior skips that redundant residual evaluation unless the " "parameter Executioner/use_pre_SMO_residual is set to true."); + params.addParam( + "use_legacy_fixed_point_execute_on", + true, + "The legacy behavior executes objects including aux kernels, user objects, postprocessors, " + "MultiApps, transfers, etc. on timestep_begin and timestep_end within a fixed point " + "iteration."); params.addParam( MeshGeneratorSystem::allow_data_driven_param, diff --git a/framework/src/executioners/Eigenvalue.C b/framework/src/executioners/Eigenvalue.C index cf2634dd9080..c3bbe1864b3b 100644 --- a/framework/src/executioners/Eigenvalue.C +++ b/framework/src/executioners/Eigenvalue.C @@ -257,6 +257,21 @@ Eigenvalue::execute() #endif // LIBMESH_ENABLE_AMR _eigen_problem.timestepSetup(); + if (!_legacy_execute_on) + { + _eigen_problem.execTransfers(EXEC_TIMESTEP_BEGIN); + if (!_eigen_problem.execMultiApps(EXEC_TIMESTEP_BEGIN)) + { + _console << "Aborting as executing multiapps on timestep_begin failed" << std::endl; + return; + } + + _eigen_problem.execute(EXEC_TIMESTEP_BEGIN); + _time = _time_step; + _eigen_problem.outputStep(EXEC_TIMESTEP_BEGIN); + _time = _system_time; + } + _last_solve_converged = _fixed_point_solve->solve(); if (!lastSolveConverged()) { @@ -270,6 +285,19 @@ Eigenvalue::execute() _eigen_problem.computeIndicators(); _eigen_problem.computeMarkers(); } + + if (!_legacy_execute_on) + { + _eigen_problem.onTimestepEnd(); + _eigen_problem.execute(EXEC_TIMESTEP_END); + + _eigen_problem.execTransfers(EXEC_TIMESTEP_END); + if (!_eigen_problem.execMultiApps(EXEC_TIMESTEP_END)) + { + _console << "Aborting as executing multiapps on timestep_end failed" << std::endl; + return; + } + } // need to keep _time in sync with _time_step to get correct output _time = _time_step; _eigen_problem.outputStep(EXEC_TIMESTEP_END); diff --git a/framework/src/executioners/Executioner.C b/framework/src/executioners/Executioner.C index 8d49fd946985..70b0031e8fd2 100644 --- a/framework/src/executioners/Executioner.C +++ b/framework/src/executioners/Executioner.C @@ -58,6 +58,7 @@ Executioner::Executioner(const InputParameters & parameters) PostprocessorInterface(this), Restartable(this, "Executioners"), PerfGraphInterface(this), + _legacy_execute_on(_app.parameters().get("use_legacy_fixed_point_execute_on")), _fe_problem(*getCheckedPointerParam( "_fe_problem_base", "This might happen if you don't have a mesh")), _iteration_method(getParam("fixed_point_algorithm")), @@ -91,6 +92,7 @@ Executioner::Executioner(const InputParameters & parameters, bool) PostprocessorInterface(this), Restartable(this, "Executioners"), PerfGraphInterface(this), + _legacy_execute_on(_app.parameters().get("use_legacy_fixed_point_execute_on")), _fe_problem(*getCheckedPointerParam( "_fe_problem_base", "This might happen if you don't have a mesh")), _iteration_method(getParam("fixed_point_algorithm")), diff --git a/framework/src/executioners/FixedPointSolve.C b/framework/src/executioners/FixedPointSolve.C index 7977f2467c04..2fd715658adf 100644 --- a/framework/src/executioners/FixedPointSolve.C +++ b/framework/src/executioners/FixedPointSolve.C @@ -16,6 +16,11 @@ #include "AllLocalDofIndicesThread.h" #include "Console.h" #include "EigenExecutionerBase.h" +#include "ExecFlagRegistry.h" + +const ExecFlagType FixedPointSolve::EXEC_FIXEDPOINT_BEGIN = + registerDefaultExecFlag("FIXEDPOINT_BEGIN"); +const ExecFlagType FixedPointSolve::EXEC_FIXEDPOINT_END = registerDefaultExecFlag("FIXEDPOINT_END"); InputParameters FixedPointSolve::validParams() @@ -51,7 +56,8 @@ FixedPointSolve::validParams() params.addParam( "fixed_point_force_norms", false, - "Force the evaluation of both the TIMESTEP_BEGIN and TIMESTEP_END norms regardless of the " + "Force the evaluation of residual norms after executing objects and MultiApps on " + "fixedpoint_begin and fixedpoint_end regardless of the " "existence of active MultiApps with those execute_on flags, default: false."); // Parameters for using a custom postprocessor for convergence checks @@ -116,7 +122,7 @@ FixedPointSolve::validParams() "Maximum number of times to update XFEM crack topology in a step due to evolving cracks"); params.addParam("update_xfem_at_timestep_begin", false, - "Should XFEM update the mesh at the beginning of the timestep"); + "Should XFEM update the mesh at the beginning of a fixed point iteration"); params.addParamNamesToGroup("max_xfem_update update_xfem_at_timestep_begin", "XFEM fixed point iterations"); @@ -126,6 +132,7 @@ FixedPointSolve::validParams() FixedPointSolve::FixedPointSolve(Executioner & ex) : SolveObject(ex), + _legacy_execute_on(ex.legacyTimeExecution()), _min_fixed_point_its(getParam("fixed_point_min_its")), _max_fixed_point_its(getParam("fixed_point_max_its")), _has_fixed_point_its(_max_fixed_point_its > 1), @@ -198,18 +205,23 @@ FixedPointSolve::solve() Real current_dt = _problem.dt(); - _fixed_point_timestep_begin_norm.clear(); - _fixed_point_timestep_end_norm.clear(); - _fixed_point_timestep_begin_norm.resize(_max_fixed_point_its); - _fixed_point_timestep_end_norm.resize(_max_fixed_point_its); + _fixed_point_begin_norm.clear(); + _fixed_point_end_norm.clear(); + _fixed_point_begin_norm.resize(_max_fixed_point_its); + _fixed_point_end_norm.resize(_max_fixed_point_its); bool converged = true; // need to back up multi-apps even when not doing fixed point iteration for recovering from failed // multiapp solve _problem.backupMultiApps(EXEC_MULTIAPP_FIXED_POINT_BEGIN); - _problem.backupMultiApps(EXEC_TIMESTEP_BEGIN); - _problem.backupMultiApps(EXEC_TIMESTEP_END); + if (_legacy_execute_on) + { + _problem.backupMultiApps(EXEC_TIMESTEP_BEGIN); + _problem.backupMultiApps(EXEC_TIMESTEP_END); + } + _problem.backupMultiApps(EXEC_FIXEDPOINT_BEGIN); + _problem.backupMultiApps(EXEC_FIXEDPOINT_END); _problem.backupMultiApps(EXEC_MULTIAPP_FIXED_POINT_END); // Prepare to relax variables as a main app @@ -273,8 +285,13 @@ FixedPointSolve::solve() { // For every iteration other than the first, we need to restore the state of the MultiApps _problem.restoreMultiApps(EXEC_MULTIAPP_FIXED_POINT_BEGIN); - _problem.restoreMultiApps(EXEC_TIMESTEP_BEGIN); - _problem.restoreMultiApps(EXEC_TIMESTEP_END); + if (_legacy_execute_on) + { + _problem.restoreMultiApps(EXEC_TIMESTEP_BEGIN); + _problem.restoreMultiApps(EXEC_TIMESTEP_END); + } + _problem.restoreMultiApps(EXEC_FIXEDPOINT_BEGIN); + _problem.restoreMultiApps(EXEC_FIXEDPOINT_END); _problem.restoreMultiApps(EXEC_MULTIAPP_FIXED_POINT_END); } @@ -288,8 +305,8 @@ FixedPointSolve::solve() _pp_old = *_fixed_point_custom_pp; // Solve a single application for one time step - bool solve_converged = solveStep(_fixed_point_timestep_begin_norm[_fixed_point_it], - _fixed_point_timestep_end_norm[_fixed_point_it], + bool solve_converged = solveStep(_fixed_point_begin_norm[_fixed_point_it], + _fixed_point_end_norm[_fixed_point_it], transformed_dofs); // Get new value and print history for the custom postprocessor convergence criterion @@ -335,8 +352,8 @@ FixedPointSolve::solve() current_dt; // _dt might be smaller than this at this point for multistep methods } - // Save postprocessors after the solve and their potential timestep_end execution - // The postprocessors could be overwritten at timestep_begin, which is why they are saved + // Save postprocessors after the solve and their potential fixedpoint_end execution + // The postprocessors could be overwritten at fixedpoint_begin, which is why they are saved // after the solve. They could also be saved right after the transfers. if (_old_entering_time == _problem.time()) savePostprocessorValues(false); @@ -377,13 +394,15 @@ FixedPointSolve::solveStep(Real & begin_norm, bool auto_advance = autoAdvance(); // Compute previous norms for coloring the norm output - Real begin_norm_old = (_fixed_point_it > 0 ? _fixed_point_timestep_begin_norm[_fixed_point_it - 1] + Real begin_norm_old = (_fixed_point_it > 0 ? _fixed_point_begin_norm[_fixed_point_it - 1] : std::numeric_limits::max()); - Real end_norm_old = (_fixed_point_it > 0 ? _fixed_point_timestep_end_norm[_fixed_point_it - 1] + Real end_norm_old = (_fixed_point_it > 0 ? _fixed_point_end_norm[_fixed_point_it - 1] : std::numeric_limits::max()); _executioner.preSolve(); - _problem.execTransfers(EXEC_TIMESTEP_BEGIN); + if (_legacy_execute_on) + _problem.execTransfers(EXEC_TIMESTEP_BEGIN); + _problem.execTransfers(EXEC_FIXEDPOINT_BEGIN); if (_fixed_point_it == 0) { @@ -397,7 +416,12 @@ FixedPointSolve::solveStep(Real & begin_norm, _problem.outputStep(EXEC_MULTIAPP_FIXED_POINT_BEGIN); } - if (!_problem.execMultiApps(EXEC_TIMESTEP_BEGIN, auto_advance)) + if (_legacy_execute_on && !_problem.execMultiApps(EXEC_TIMESTEP_BEGIN, auto_advance)) + { + _fixed_point_status = MooseFixedPointConvergenceReason::DIVERGED_FAILED_MULTIAPP; + return false; + } + if (!_problem.execMultiApps(EXEC_FIXEDPOINT_BEGIN, auto_advance)) { _fixed_point_status = MooseFixedPointConvergenceReason::DIVERGED_FAILED_MULTIAPP; return false; @@ -406,10 +430,12 @@ FixedPointSolve::solveStep(Real & begin_norm, if (_problem.haveXFEM() && _update_xfem_at_timestep_begin) _problem.updateMeshXFEM(); - _problem.execute(EXEC_TIMESTEP_BEGIN); + if (_legacy_execute_on) + _problem.execute(EXEC_TIMESTEP_BEGIN); + _problem.execute(EXEC_FIXEDPOINT_BEGIN); - // Transform the fixed point postprocessors before solving, but after the timestep_begin transfers - // have been received + // Transform the fixed point postprocessors before solving, but after the fixedpoint_begin + // transfers have been received if (_transformed_pps.size() > 0 && useFixedPointAlgorithmUpdateInsteadOfPicard(true)) transformPostprocessors(true); if (_secondary_transformed_pps.size() > 0 && useFixedPointAlgorithmUpdateInsteadOfPicard(false) && @@ -417,16 +443,19 @@ FixedPointSolve::solveStep(Real & begin_norm, transformPostprocessors(false); if (_has_fixed_point_its && _has_fixed_point_norm) - if (_problem.hasMultiApps(EXEC_TIMESTEP_BEGIN) || _fixed_point_force_norms) + if ((_legacy_execute_on && _problem.hasMultiApps(EXEC_TIMESTEP_BEGIN)) || + _problem.hasMultiApps(EXEC_FIXEDPOINT_BEGIN) || _fixed_point_force_norms) { begin_norm = _problem.computeResidualL2Norm(); - _console << COLOR_MAGENTA << "Fixed point residual norm after TIMESTEP_BEGIN MultiApps: " + _console << COLOR_MAGENTA << "Fixed point residual norm after FIXEDPOINT_BEGIN MultiApps: " << Console::outputNorm(begin_norm_old, begin_norm) << std::endl; } // Perform output for timestep begin - _problem.outputStep(EXEC_TIMESTEP_BEGIN); + if (_legacy_execute_on) + _problem.outputStep(EXEC_TIMESTEP_BEGIN); + _problem.outputStep(EXEC_FIXEDPOINT_BEGIN); // Update warehouse active objects _problem.updateActiveObjects(); @@ -466,11 +495,22 @@ FixedPointSolve::solveStep(Real & begin_norm, _console << "\nXFEM did not modify mesh, continuing" << std::endl; } - _problem.onTimestepEnd(); - _problem.execute(EXEC_TIMESTEP_END); + if (_legacy_execute_on) + { + _problem.onTimestepEnd(); + _problem.execute(EXEC_TIMESTEP_END); + + _problem.execTransfers(EXEC_TIMESTEP_END); + if (!_problem.execMultiApps(EXEC_TIMESTEP_END, auto_advance)) + { + _fixed_point_status = MooseFixedPointConvergenceReason::DIVERGED_FAILED_MULTIAPP; + return false; + } + } + _problem.execute(EXEC_FIXEDPOINT_END); - _problem.execTransfers(EXEC_TIMESTEP_END); - if (!_problem.execMultiApps(EXEC_TIMESTEP_END, auto_advance)) + _problem.execTransfers(EXEC_FIXEDPOINT_END); + if (!_problem.execMultiApps(EXEC_FIXEDPOINT_END, auto_advance)) { _fixed_point_status = MooseFixedPointConvergenceReason::DIVERGED_FAILED_MULTIAPP; return false; @@ -486,11 +526,12 @@ FixedPointSolve::solveStep(Real & begin_norm, _executioner.postSolve(); if (_has_fixed_point_its && _has_fixed_point_norm) - if (_problem.hasMultiApps(EXEC_TIMESTEP_END) || _fixed_point_force_norms) + if ((_legacy_execute_on && _problem.hasMultiApps(EXEC_TIMESTEP_END)) || + _problem.hasMultiApps(EXEC_FIXEDPOINT_END) || _fixed_point_force_norms) { end_norm = _problem.computeResidualL2Norm(); - _console << COLOR_MAGENTA << "Fixed point residual norm after TIMESTEP_END MultiApps: " + _console << COLOR_MAGENTA << "Fixed point residual norm after FIXEDPOINT_END MultiApps: " << Console::outputNorm(end_norm_old, end_norm) << std::endl; } @@ -516,8 +557,8 @@ FixedPointSolve::examineFixedPointConvergence(bool & converged) { if (_fixed_point_it + 2 > _min_fixed_point_its) { - Real max_norm = std::max(_fixed_point_timestep_begin_norm[_fixed_point_it], - _fixed_point_timestep_end_norm[_fixed_point_it]); + Real max_norm = + std::max(_fixed_point_begin_norm[_fixed_point_it], _fixed_point_end_norm[_fixed_point_it]); Real max_relative_drop = max_norm / _fixed_point_initial_norm; diff --git a/framework/src/executioners/PicardSolve.C b/framework/src/executioners/PicardSolve.C index 2829500201b2..ea928ee74816 100644 --- a/framework/src/executioners/PicardSolve.C +++ b/framework/src/executioners/PicardSolve.C @@ -24,8 +24,8 @@ PicardSolve::validParams() "picard_max_its", 1, "Specifies the maximum number of Picard iterations. " - "Mainly used when wanting to do Picard iterations with MultiApps " - "that are set to execute_on timestep_end or timestep_begin. " + "Mainly used when wanting to do Picard iterations with MultiApps " + "that are set to execute_on fixedpoint_end or fixedpoint_begin. " "Setting this parameter to 1 turns off the Picard iterations.", "Deprecated, use fixed_point_max_its"); params.addDeprecatedParam( @@ -60,8 +60,8 @@ PicardSolve::validParams() params.addDeprecatedParam( "picard_force_norms", false, - "Force the evaluation of both the TIMESTEP_BEGIN and TIMESTEP_END norms regardless of the " - "existence of active MultiApps with those execute_on flags, default: false.", + "Force the evaluation of both the FIXEDPOINT_BEGIN and FIXEDPOINT_END norms regardless of " + "the existence of active MultiApps with those execute_on flags, default: false.", "Deprecated, use fixed_point_force_norms"); return params; @@ -265,8 +265,7 @@ PicardSolve::printFixedPointConvergenceHistory() Real max_norm_old = _fixed_point_initial_norm; for (unsigned int i = 0; i <= _fixed_point_it; ++i) { - Real max_norm = - std::max(_fixed_point_timestep_begin_norm[i], _fixed_point_timestep_end_norm[i]); + Real max_norm = std::max(_fixed_point_begin_norm[i], _fixed_point_end_norm[i]); _console << std::setw(2) << i + 1 << " Picard |R| = " << Console::outputNorm(max_norm_old, max_norm) << '\n'; max_norm_old = max_norm; diff --git a/framework/src/executioners/SecantSolve.C b/framework/src/executioners/SecantSolve.C index 3b08929b8b6b..d0164a92bf74 100644 --- a/framework/src/executioners/SecantSolve.C +++ b/framework/src/executioners/SecantSolve.C @@ -135,10 +135,10 @@ SecantSolve::savePostprocessorValues(const bool primary) (*transformed_pps_values)[i][2] = (*transformed_pps_values)[i][0]; // Save current value - // Primary: this is done before the timestep's solves and before timestep_begin transfers, + // Primary: this is done before the fixedpoint's solves and before fixedpoint_begin transfers, // so the value is the result of the previous Secant update (xn_m1) - // Secondary: this is done after the secondary solve, but before timestep_end postprocessors - // are computed, or timestep_end transfers are received. + // Secondary: this is done after the secondary solve, but before fixedpoint_end postprocessors + // are computed, or fixedpoint_end transfers are received. // This value is the same as before the solve (xn_m1) (*transformed_pps_values)[i][1] = getPostprocessorValueByName((*transformed_pps)[i]); } @@ -258,8 +258,7 @@ SecantSolve::printFixedPointConvergenceHistory() Real max_norm_old = _fixed_point_initial_norm; for (unsigned int i = 0; i <= _fixed_point_it; ++i) { - Real max_norm = - std::max(_fixed_point_timestep_begin_norm[i], _fixed_point_timestep_end_norm[i]); + Real max_norm = std::max(_fixed_point_begin_norm[i], _fixed_point_end_norm[i]); std::stringstream secant_prefix; if (i < 2) secant_prefix << " Secant initialization |R| = "; diff --git a/framework/src/executioners/Steady.C b/framework/src/executioners/Steady.C index 33cc71cd7ed2..c0996d9be157 100644 --- a/framework/src/executioners/Steady.C +++ b/framework/src/executioners/Steady.C @@ -80,6 +80,21 @@ Steady::execute() #endif // LIBMESH_ENABLE_AMR _problem.timestepSetup(); + if (!_legacy_execute_on) + { + _problem.execTransfers(EXEC_TIMESTEP_BEGIN); + if (!_problem.execMultiApps(EXEC_TIMESTEP_BEGIN)) + { + _console << "Aborting as executing multiapps on timestep_begin failed" << std::endl; + return; + } + + _problem.execute(EXEC_TIMESTEP_BEGIN); + _time = _time_step; + _problem.outputStep(EXEC_TIMESTEP_BEGIN); + _time = _system_time; + } + _last_solve_converged = _fixed_point_solve->solve(); if (!lastSolveConverged()) @@ -91,6 +106,18 @@ Steady::execute() _problem.computeIndicators(); _problem.computeMarkers(); + if (!_legacy_execute_on) + { + _problem.onTimestepEnd(); + _problem.execute(EXEC_TIMESTEP_END); + + _problem.execTransfers(EXEC_TIMESTEP_END); + if (!_problem.execMultiApps(EXEC_TIMESTEP_END)) + { + _console << "Aborting as executing multiapps on timestep_end failed" << std::endl; + return; + } + } // need to keep _time in sync with _time_step to get correct output _time = _time_step; _problem.outputStep(EXEC_TIMESTEP_END); diff --git a/framework/src/executioners/SteffensenSolve.C b/framework/src/executioners/SteffensenSolve.C index c97702d3e7fd..57df5eee574c 100644 --- a/framework/src/executioners/SteffensenSolve.C +++ b/framework/src/executioners/SteffensenSolve.C @@ -231,8 +231,7 @@ SteffensenSolve::printFixedPointConvergenceHistory() Real max_norm_old = _fixed_point_initial_norm; for (unsigned int i = 0; i <= _fixed_point_it; ++i) { - Real max_norm = - std::max(_fixed_point_timestep_begin_norm[i], _fixed_point_timestep_end_norm[i]); + Real max_norm = std::max(_fixed_point_begin_norm[i], _fixed_point_end_norm[i]); std::stringstream steffensen_prefix; if (i == 0) steffensen_prefix << " Steffensen initialization |R| = "; diff --git a/framework/src/executioners/Transient.C b/framework/src/executioners/Transient.C index 7081a8ea93b4..b8aa3f5c6f57 100644 --- a/framework/src/executioners/Transient.C +++ b/framework/src/executioners/Transient.C @@ -23,6 +23,7 @@ #include "TimeIntegrator.h" #include "Console.h" #include "AuxiliarySystem.h" +#include "FixedPointSolve.h" #include "libmesh/implicit_system.h" #include "libmesh/nonlinear_implicit_system.h" @@ -310,6 +311,10 @@ Transient::execute() /*recurse_through_multiapp_levels=*/true); _problem.finishMultiAppStep(EXEC_TIMESTEP_BEGIN, /*recurse_through_multiapp_levels=*/true); _problem.finishMultiAppStep(EXEC_TIMESTEP_END, /*recurse_through_multiapp_levels=*/true); + _problem.finishMultiAppStep(FixedPointSolve::EXEC_FIXEDPOINT_BEGIN, + /*recurse_through_multiapp_levels=*/true); + _problem.finishMultiAppStep(FixedPointSolve::EXEC_FIXEDPOINT_END, + /*recurse_through_multiapp_levels=*/true); _problem.finishMultiAppStep(EXEC_MULTIAPP_FIXED_POINT_END, /*recurse_through_multiapp_levels=*/true); } @@ -369,6 +374,8 @@ Transient::incrementStepOrReject() _problem.finishMultiAppStep(EXEC_MULTIAPP_FIXED_POINT_BEGIN); _problem.finishMultiAppStep(EXEC_TIMESTEP_BEGIN); _problem.finishMultiAppStep(EXEC_TIMESTEP_END); + _problem.finishMultiAppStep(FixedPointSolve::EXEC_FIXEDPOINT_BEGIN); + _problem.finishMultiAppStep(FixedPointSolve::EXEC_FIXEDPOINT_END); _problem.finishMultiAppStep(EXEC_MULTIAPP_FIXED_POINT_END); } @@ -380,6 +387,8 @@ Transient::incrementStepOrReject() _problem.incrementMultiAppTStep(EXEC_MULTIAPP_FIXED_POINT_BEGIN); _problem.incrementMultiAppTStep(EXEC_TIMESTEP_BEGIN); _problem.incrementMultiAppTStep(EXEC_TIMESTEP_END); + _problem.incrementMultiAppTStep(FixedPointSolve::EXEC_FIXEDPOINT_BEGIN); + _problem.incrementMultiAppTStep(FixedPointSolve::EXEC_FIXEDPOINT_END); _problem.incrementMultiAppTStep(EXEC_MULTIAPP_FIXED_POINT_END); } } @@ -388,6 +397,8 @@ Transient::incrementStepOrReject() _problem.restoreMultiApps(EXEC_MULTIAPP_FIXED_POINT_BEGIN, true); _problem.restoreMultiApps(EXEC_TIMESTEP_BEGIN, true); _problem.restoreMultiApps(EXEC_TIMESTEP_END, true); + _problem.restoreMultiApps(FixedPointSolve::EXEC_FIXEDPOINT_BEGIN, true); + _problem.restoreMultiApps(FixedPointSolve::EXEC_FIXEDPOINT_END, true); _problem.restoreMultiApps(EXEC_MULTIAPP_FIXED_POINT_END, true); _time_stepper->rejectStep(); _time = _time_old; @@ -411,6 +422,12 @@ Transient::takeStep(Real input_dt) _problem.timestepSetup(); + if (!_legacy_execute_on) + { + _problem.backupMultiApps(EXEC_TIMESTEP_BEGIN); + _problem.backupMultiApps(EXEC_TIMESTEP_END); + } + _problem.onTimestepBegin(); _time_stepper->step(); @@ -419,10 +436,7 @@ Transient::takeStep(Real input_dt) _last_solve_converged = _time_stepper->converged(); if (!lastSolveConverged()) - { - _console << "Aborting as solve did not converge" << std::endl; return; - } if (!(_problem.haveXFEM() && _fixed_point_solve->XFEMRepeatStep())) { @@ -534,6 +548,8 @@ Transient::computeConstrainedDT() constrainDTFromMultiApp(dt_cur, diag, EXEC_MULTIAPP_FIXED_POINT_BEGIN); constrainDTFromMultiApp(dt_cur, diag, EXEC_TIMESTEP_BEGIN); constrainDTFromMultiApp(dt_cur, diag, EXEC_TIMESTEP_END); + constrainDTFromMultiApp(dt_cur, diag, FixedPointSolve::EXEC_FIXEDPOINT_BEGIN); + constrainDTFromMultiApp(dt_cur, diag, FixedPointSolve::EXEC_FIXEDPOINT_END); constrainDTFromMultiApp(dt_cur, diag, EXEC_MULTIAPP_FIXED_POINT_END); if (_verbose) diff --git a/framework/src/outputs/ConsoleUtils.C b/framework/src/outputs/ConsoleUtils.C index a05fe72f52cb..023df52dd7ba 100644 --- a/framework/src/outputs/ConsoleUtils.C +++ b/framework/src/outputs/ConsoleUtils.C @@ -427,6 +427,17 @@ outputLegacyInformation(MooseApp & app) << COLOR_DEFAULT << std::endl; } + if (app.parameters().get("use_legacy_fixed_point_execute_on")) + { + oss << COLOR_RED << "LEGACY MODES ENABLED:" << COLOR_DEFAULT << '\n'; + oss << " This application uses the legacy fixed point execution option: objects including aux " + "kernels, user objects, postprocessors, multi-apps, transfers, etc. on timestep_begin " + "and timestep_end are executed within a fixed point iteration while those objects " + "should be executed on fixedpoint_begin and fixedpoint_end. To remove this message set " + "the parameter 'use_legacy_fixed_point_execute_on' to false in *App.C. Codes in Actions " + "and inputs setting 'execute_on' parameters must be examined and changed if necessary.\n" + << COLOR_DEFAULT << std::endl; + } return oss.str(); } diff --git a/framework/src/problems/FEProblemBase.C b/framework/src/problems/FEProblemBase.C index d5134e07e5fc..443c8c43e6b8 100644 --- a/framework/src/problems/FEProblemBase.C +++ b/framework/src/problems/FEProblemBase.C @@ -5061,6 +5061,10 @@ FEProblemBase::addMultiApp(const std::string & multi_app_name, parameters.set("_sys") = _aux.get(); } + if (!_app.parameters().get("use_legacy_fixed_point_execute_on") && + !parameters.isParamSetByUser("execute_on")) + parameters.set("execute_on", true) = FixedPointSolve::EXEC_FIXEDPOINT_BEGIN; + std::shared_ptr multi_app = _factory.create(multi_app_name, name, parameters); logAdd("MultiApp", name, multi_app_name, parameters); multi_app->setupPositions(); @@ -5425,6 +5429,12 @@ FEProblemBase::addTransfer(const std::string & transfer_name, if (multiapp) exec_enum = multiapp->getParam("execute_on"); } + else + { + if (!_app.parameters().get("use_legacy_fixed_point_execute_on") && + !parameters.isParamSetByUser("execute_on")) + parameters.set("execute_on", true) = FixedPointSolve::EXEC_FIXEDPOINT_BEGIN; + } // Create the Transfer objects std::shared_ptr transfer = _factory.create(transfer_name, name, parameters); diff --git a/framework/src/timesteppers/TimeStepper.C b/framework/src/timesteppers/TimeStepper.C index f95162eca425..13b02d373208 100644 --- a/framework/src/timesteppers/TimeStepper.C +++ b/framework/src/timesteppers/TimeStepper.C @@ -165,10 +165,44 @@ TimeStepper::constrainStep(Real & dt) void TimeStepper::step() { + if (!_executioner.legacyTimeExecution()) + { + _fe_problem.execTransfers(EXEC_TIMESTEP_BEGIN); + if (!_fe_problem.execMultiApps(EXEC_TIMESTEP_BEGIN)) + { + _converged = false; + _failure_count++; + _console << "Aborting as executing multiapps on timestep_begin failed" << std::endl; + return; + } + + _fe_problem.execute(EXEC_TIMESTEP_BEGIN); + _fe_problem.outputStep(EXEC_TIMESTEP_BEGIN); + } + _converged = _executioner.timeStepSolveObject()->solve(); if (!_converged) + { + _console << "Aborting as solve did not converge" << std::endl; _failure_count++; + return; + } + + if (!_executioner.legacyTimeExecution()) + { + _fe_problem.onTimestepEnd(); + _fe_problem.execute(EXEC_TIMESTEP_END); + + _fe_problem.execTransfers(EXEC_TIMESTEP_END); + if (!_fe_problem.execMultiApps(EXEC_TIMESTEP_END)) + { + _converged = false; + _failure_count++; + _console << "Aborting as executing multiapps on timestep_end failed" << std::endl; + return; + } + } } void diff --git a/test/tests/outputs/console/multiapp/tests b/test/tests/outputs/console/multiapp/tests index 02df3e3edef6..47efe4b20c91 100644 --- a/test/tests/outputs/console/multiapp/tests +++ b/test/tests/outputs/console/multiapp/tests @@ -15,23 +15,23 @@ [./ts_begin_multi_output] type = 'RunApp' input = 'picard_parent.i' - absent_out = "Fixed point residual norm after TIMESTEP_END" + absent_out = "Fixed point residual norm after FIXEDPOINT_END" - requirement = "The system shall only output the coupling iteration residual TIMESTEP_BEGIN norms when there are no TIMESTEP_END Multiapps." + requirement = "The system shall only output the coupling iteration residual FIXEDPOINT_BEGIN norms when there are no FIXEDPOINT_END Multiapps." [../] [./ts_end_multi_output] type = 'RunApp' input = 'picard_parent.i' - absent_out = "Fixed point residual norm after TIMESTEP_BEGIN" + absent_out = "Fixed point residual norm after FIXEDPOINT_BEGIN" cli_args = 'MultiApps/sub/execute_on=timestep_end' - requirement = "The system shall only output the coupling iteration TIMESTEP_END norms when there are no TIMESTEP_BEGIN Multiapps." + requirement = "The system shall only output the coupling iteration FIXEDPOINT_END norms when there are no FIXEDPOINT_BEGIN Multiapps." [../] [./ts_both_multi_output] type = 'RunApp' input = 'picard_parent_both.i' - expect_out = "Fixed point residual norm after TIMESTEP_BEGIN.*Fixed point residual norm after TIMESTEP_END" + expect_out = "Fixed point residual norm after FIXEDPOINT_BEGIN.*Fixed point residual norm after FIXEDPOINT_END" - requirement = "The system shall output the coupling iteration residual norm for TIMESTEP_BEGIN and TIMESTEP_END Multiapps when both exist in the simulation." + requirement = "The system shall output the coupling iteration residual norm for FIXEDPOINT_BEGIN and FIXEDPOINT_END Multiapps when both exist in the simulation." [../] [] diff --git a/test/tests/outputs/format/tests b/test/tests/outputs/format/tests index cf925a5fa8d9..ed49352579a3 100644 --- a/test/tests/outputs/format/tests +++ b/test/tests/outputs/format/tests @@ -260,7 +260,7 @@ [definition_valenum_test] type = 'RunApp' input = '' - expect_out = '\'execute_on\'{[^{]*{[^}]*ValEnums=\[ "NONE" "INI[^]]*?GIN" "FINAL" "CUSTOM"[^]]*\][^}]*}[^}]*}' + expect_out = '\'execute_on\'{[^{]*{[^}]*ValEnums=\[ "FIXEDPOINT_BEGIN" "FIXEDPOINT_END" "NONE" "INI[^]]*?GIN" "FINAL" "CUSTOM"[^]]*\][^}]*}[^}]*}' cli_args = '--definition' # suppress error checking, the word 'ERROR' shows up in the definition dump errors = 'zzzzzzzzzz'