Skip to content
Snippets Groups Projects
Commit c28e4ec4 authored by wenqing's avatar wenqing
Browse files

[Coupling] Enabled each individual process having its own convergence criterion

 in the coupling loop.
parent eb8e1d25
No related branches found
No related tags found
No related merge requests found
Defines the convergence criteria of the global un-coupling loop of the staggered
scheme for each individual process.
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
......@@ -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
{
......
......@@ -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.
......
No preview for this file type
......@@ -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>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment