From c28e4ec4c991a98e72683468e2347f9b76f88ffb Mon Sep 17 00:00:00 2001 From: Wenqing Wang <wenqing.wang@ufz.de> Date: Thu, 14 Dec 2017 16:44:31 +0100 Subject: [PATCH] [Coupling] Enabled each individual process having its own convergence criterion in the coupling loop. --- .../i_convergence_criteria.md} | 0 .../t_convergence_criterion.md | 2 + .../i_global_process_coupling.md | 2 +- ProcessLib/UncoupledProcessesTimeLoop.cpp | 86 ++++++++++++------- ProcessLib/UncoupledProcessesTimeLoop.h | 5 +- .../ConstViscosity/square_5500x5500.vtu | 2 +- .../square_5500x5500_staggered_scheme.prj | 19 ++-- 7 files changed, 76 insertions(+), 40 deletions(-) rename Documentation/ProjectFile/prj/time_loop/global_process_coupling/{t_convergence_criterion.md => convergence_criteria/i_convergence_criteria.md} (100%) create mode 100644 Documentation/ProjectFile/prj/time_loop/global_process_coupling/convergence_criteria/t_convergence_criterion.md diff --git a/Documentation/ProjectFile/prj/time_loop/global_process_coupling/t_convergence_criterion.md b/Documentation/ProjectFile/prj/time_loop/global_process_coupling/convergence_criteria/i_convergence_criteria.md similarity index 100% rename from Documentation/ProjectFile/prj/time_loop/global_process_coupling/t_convergence_criterion.md rename to Documentation/ProjectFile/prj/time_loop/global_process_coupling/convergence_criteria/i_convergence_criteria.md diff --git a/Documentation/ProjectFile/prj/time_loop/global_process_coupling/convergence_criteria/t_convergence_criterion.md b/Documentation/ProjectFile/prj/time_loop/global_process_coupling/convergence_criteria/t_convergence_criterion.md new file mode 100644 index 00000000000..4e4aa84b97b --- /dev/null +++ b/Documentation/ProjectFile/prj/time_loop/global_process_coupling/convergence_criteria/t_convergence_criterion.md @@ -0,0 +1,2 @@ +Defines the convergence criteria of the global un-coupling loop of the staggered + scheme for each individual process. diff --git a/Documentation/ProjectFile/prj/time_loop/global_process_coupling/i_global_process_coupling.md b/Documentation/ProjectFile/prj/time_loop/global_process_coupling/i_global_process_coupling.md index 5263a21d1d8..7073b6fc903 100644 --- a/Documentation/ProjectFile/prj/time_loop/global_process_coupling/i_global_process_coupling.md +++ b/Documentation/ProjectFile/prj/time_loop/global_process_coupling/i_global_process_coupling.md @@ -1 +1 @@ -Global convergence criteria of the coupling iterations. \ No newline at end of file +Defines global convergence controls of the coupling iterations. \ No newline at end of file diff --git a/ProcessLib/UncoupledProcessesTimeLoop.cpp b/ProcessLib/UncoupledProcessesTimeLoop.cpp index 4b4e4ec926d..4df5dbbc22d 100644 --- a/ProcessLib/UncoupledProcessesTimeLoop.cpp +++ b/ProcessLib/UncoupledProcessesTimeLoop.cpp @@ -325,16 +325,29 @@ std::unique_ptr<UncoupledProcessesTimeLoop> createUncoupledProcessesTimeLoop( //! \ogs_file_param{prj__time_loop__global_process_coupling} = config.getConfigSubtreeOptional("global_process_coupling"); - std::unique_ptr<NumLib::ConvergenceCriterion> coupling_conv_crit = nullptr; + std::vector<std::unique_ptr<NumLib::ConvergenceCriterion>> + _global_coupling_conv_criteria; unsigned max_coupling_iterations = 1; if (coupling_config) { max_coupling_iterations //! \ogs_file_param{prj__time_loop__global_process_coupling__max_iter} = coupling_config->getConfigParameter<unsigned>("max_iter"); - coupling_conv_crit = NumLib::createConvergenceCriterion( - //! \ogs_file_param{prj__time_loop__global_process_coupling__convergence_criterion} - coupling_config->getConfigSubtree("convergence_criterion")); + + auto const& coupling_convergence_criteria_config = + //! \ogs_file_param{prj__time_loop__global_process_coupling__convergence_criteria} + coupling_config->getConfigSubtree("convergence_criteria"); + + for ( + auto coupling_convergence_criterion_config : + //! \ogs_file_param{prj__time_loop__global_process_coupling__convergence_criteria__convergence_criterion} + coupling_convergence_criteria_config.getConfigSubtreeList( + "convergence_criterion")) + { + _global_coupling_conv_criteria.push_back( + NumLib::createConvergenceCriterion( + coupling_convergence_criterion_config)); + } } auto output = @@ -361,7 +374,7 @@ std::unique_ptr<UncoupledProcessesTimeLoop> createUncoupledProcessesTimeLoop( return std::make_unique<UncoupledProcessesTimeLoop>( std::move(output), std::move(per_process_data), max_coupling_iterations, - std::move(coupling_conv_crit), start_time, end_time); + std::move(_global_coupling_conv_criteria), start_time, end_time); } std::vector<GlobalVector*> setInitialConditions( @@ -409,9 +422,9 @@ std::vector<GlobalVector*> setInitialConditions( return process_solutions; } -bool solveOneTimeStepOneProcess(const unsigned process_index, - GlobalVector& x, std::size_t const timestep, - double const t, double const delta_t, +bool solveOneTimeStepOneProcess(const unsigned process_index, GlobalVector& x, + std::size_t const timestep, double const t, + double const delta_t, SingleProcessData const& process_data, Output& output_control) { @@ -435,9 +448,9 @@ bool solveOneTimeStepOneProcess(const unsigned process_index, auto const post_iteration_callback = [&](unsigned iteration, GlobalVector const& x) { - output_control.doOutputNonlinearIteration( - process, process_index, process_data.process_output, timestep, t, - x, iteration); + output_control.doOutputNonlinearIteration(process, process_index, + process_data.process_output, + timestep, t, x, iteration); }; bool nonlinear_solver_succeeded = @@ -450,7 +463,8 @@ UncoupledProcessesTimeLoop::UncoupledProcessesTimeLoop( std::unique_ptr<Output>&& output, std::vector<std::unique_ptr<SingleProcessData>>&& per_process_data, const unsigned global_coupling_max_iterations, - std::unique_ptr<NumLib::ConvergenceCriterion>&& global_coupling_conv_crit, + std::vector<std::unique_ptr<NumLib::ConvergenceCriterion>>&& + global_coupling_conv_crit, const double start_time, const double end_time) : _output(std::move(output)), _per_process_data(std::move(per_process_data)), @@ -800,8 +814,8 @@ bool UncoupledProcessesTimeLoop::solveUncoupledEquationSystems( auto& pcs = spd->process; pcs.preTimestep(x, t, dt, pcs_idx); - const auto nonlinear_solver_succeeded = - solveOneTimeStepOneProcess(pcs_idx, x, timestep_id, t, dt, *spd, *_output); + const auto nonlinear_solver_succeeded = solveOneTimeStepOneProcess( + pcs_idx, x, timestep_id, t, dt, *spd, *_output); spd->nonlinear_solver_converged = nonlinear_solver_succeeded; pcs.postTimestep(x, pcs_idx); pcs.computeSecondaryVariable(t, x); @@ -816,8 +830,8 @@ bool UncoupledProcessesTimeLoop::solveUncoupledEquationSystems( timestep_id, t, pcs_idx); // save unsuccessful solution - _output->doOutputAlways(pcs, pcs_idx, spd->process_output, timestep_id, t, - x); + _output->doOutputAlways(pcs, pcs_idx, spd->process_output, + timestep_id, t, x); if (!spd->timestepper->isSolutionErrorComputationNeeded()) { @@ -842,12 +856,22 @@ bool UncoupledProcessesTimeLoop::solveCoupledEquationSystemsByStaggeredScheme( if (_global_coupling_max_iterations != 0) { // Set the flag of the first iteration be true. - _global_coupling_conv_crit->preFirstIteration(); + for (auto& conv_crit : _global_coupling_conv_crit) + { + conv_crit->preFirstIteration(); + } } + auto resetCouplingConvergenceCtiteria = [&]() { + for (auto& conv_crit : _global_coupling_conv_crit) + { + conv_crit->reset(); + } + }; + bool coupling_iteration_converged = true; for (unsigned global_coupling_iteration = 0; global_coupling_iteration < _global_coupling_max_iterations; - global_coupling_iteration++, _global_coupling_conv_crit->reset()) + global_coupling_iteration++, resetCouplingConvergenceCtiteria()) { // TODO(wenqing): use process name bool nonlinear_solver_succeeded = true; @@ -900,8 +924,7 @@ bool UncoupledProcessesTimeLoop::solveCoupledEquationSystemsByStaggeredScheme( // save unsuccessful solution _output->doOutputAlways(spd->process, pcs_idx, - spd->process_output, - timestep_id, t, x); + spd->process_output, timestep_id, t, x); if (!spd->timestepper->isSolutionErrorComputationNeeded()) { @@ -913,15 +936,17 @@ bool UncoupledProcessesTimeLoop::solveCoupledEquationSystemsByStaggeredScheme( // Check the convergence of the coupling iteration auto& x_old = *_solutions_of_last_cpl_iteration[pcs_idx]; - MathLib::LinAlg::axpy(x_old, -1.0, x); - _global_coupling_conv_crit->checkResidual(x_old); - coupling_iteration_converged = - coupling_iteration_converged && - _global_coupling_conv_crit->isSatisfied(); - + if (global_coupling_iteration > 0) + { + MathLib::LinAlg::axpy(x_old, -1.0, x); // save dx to x_old + _global_coupling_conv_crit[pcs_idx]->checkDeltaX(x_old, x); + coupling_iteration_converged = + coupling_iteration_converged && + _global_coupling_conv_crit[pcs_idx]->isSatisfied(); + } MathLib::LinAlg::copy(x, x_old); - if (coupling_iteration_converged) + if (coupling_iteration_converged && global_coupling_iteration > 0) { break; } @@ -929,7 +954,7 @@ bool UncoupledProcessesTimeLoop::solveCoupledEquationSystemsByStaggeredScheme( ++pcs_idx; } // end of for (auto& spd : _per_process_data) - if (coupling_iteration_converged) + if (coupling_iteration_converged && global_coupling_iteration > 0) { break; } @@ -1007,9 +1032,8 @@ void UncoupledProcessesTimeLoop::outputSolutions( spd->process.setCoupledSolutionsForStaggeredScheme( &coupled_solutions); spd->process.setCoupledTermForTheStaggeredSchemeToLocalAssemblers(); - (output_object.*output_class_member)(pcs, pcs_idx, - spd->process_output, - timestep, t, x); + (output_object.*output_class_member)( + pcs, pcs_idx, spd->process_output, timestep, t, x); } else { diff --git a/ProcessLib/UncoupledProcessesTimeLoop.h b/ProcessLib/UncoupledProcessesTimeLoop.h index e26ea2d986f..b62cf9c3df0 100644 --- a/ProcessLib/UncoupledProcessesTimeLoop.h +++ b/ProcessLib/UncoupledProcessesTimeLoop.h @@ -39,7 +39,7 @@ public: std::unique_ptr<Output>&& output, std::vector<std::unique_ptr<SingleProcessData>>&& per_process_data, const unsigned global_coupling_max_iterations, - std::unique_ptr<NumLib::ConvergenceCriterion>&& + std::vector<std::unique_ptr<NumLib::ConvergenceCriterion>>&& global_coupling_conv_crit, const double start_time, const double end_time); @@ -72,7 +72,8 @@ private: /// Maximum iterations of the global coupling. const unsigned _global_coupling_max_iterations; /// Convergence criteria of the global coupling iterations. - std::unique_ptr<NumLib::ConvergenceCriterion> _global_coupling_conv_crit; + std::vector<std::unique_ptr<NumLib::ConvergenceCriterion>> + _global_coupling_conv_crit; /** * Vector of solutions of the coupled processes. diff --git a/Tests/Data/Parabolic/HT/StaggeredCoupling/ConstViscosity/square_5500x5500.vtu b/Tests/Data/Parabolic/HT/StaggeredCoupling/ConstViscosity/square_5500x5500.vtu index 3df5c5201c9..daa22a7fd61 100644 --- a/Tests/Data/Parabolic/HT/StaggeredCoupling/ConstViscosity/square_5500x5500.vtu +++ b/Tests/Data/Parabolic/HT/StaggeredCoupling/ConstViscosity/square_5500x5500.vtu @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6f5d32a50ce7d3eddd0f4f4b1f33de2230d2e49a24aa1b55511222e3cf038f68 +oid sha256:5938bdfce5fdd7675654514a0e2c26ff1b8fbdf419e02cef8ffc48da15f13aa2 size 138816 diff --git a/Tests/Data/Parabolic/HT/StaggeredCoupling/ConstViscosity/square_5500x5500_staggered_scheme.prj b/Tests/Data/Parabolic/HT/StaggeredCoupling/ConstViscosity/square_5500x5500_staggered_scheme.prj index fe303865d28..eee8f7a9319 100644 --- a/Tests/Data/Parabolic/HT/StaggeredCoupling/ConstViscosity/square_5500x5500_staggered_scheme.prj +++ b/Tests/Data/Parabolic/HT/StaggeredCoupling/ConstViscosity/square_5500x5500_staggered_scheme.prj @@ -57,11 +57,20 @@ <time_loop> <global_process_coupling> <max_iter> 6 </max_iter> - <convergence_criterion> - <type>Residual</type> - <norm_type>NORM2</norm_type> - <reltol>1.e-10</reltol> - </convergence_criterion> + <convergence_criteria> + <!-- convergence criterion for the first process --> + <convergence_criterion> + <type>DeltaX</type> + <norm_type>NORM2</norm_type> + <reltol>1.e-14</reltol> + </convergence_criterion> + <!-- convergence criterion for the second process --> + <convergence_criterion> + <type>DeltaX</type> + <norm_type>NORM2</norm_type> + <reltol>1.e-14</reltol> + </convergence_criterion> + </convergence_criteria> </global_process_coupling> <processes> -- GitLab