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

[Coupling] Moved the stuffs in the coupling loop to two new members

parent 8624654c
No related branches found
No related tags found
No related merge requests found
Defines the maximum number of the iterations of the un-coupling loop. Defines the maximum iteration number of the coupling loop of the staggered scheme.
\ No newline at end of file
...@@ -612,136 +612,185 @@ bool UncoupledProcessesTimeLoop::loop() ...@@ -612,136 +612,185 @@ bool UncoupledProcessesTimeLoop::loop()
INFO("=== timestep #%u (t=%gs, dt=%gs) ==============================", INFO("=== timestep #%u (t=%gs, dt=%gs) ==============================",
timestep, t, delta_t); timestep, t, delta_t);
bool coupling_iteration_converged = true; if (is_staggered_coupling)
// Coupling iteration nonlinear_solver_succeeded =
for (unsigned i = 0; i < _global_coupling_max_iterations; i++) solveCoupledEquationSystemsByStaggeredScheme(t, delta_t,
timestep);
else
nonlinear_solver_succeeded =
solveUncoupledEquationSystems(t, delta_t, timestep);
INFO("[time] Timestep #%u took %g s.", timestep,
time_timestep.elapsed());
if (!nonlinear_solver_succeeded)
break;
}
// output last timestep
if (nonlinear_solver_succeeded)
{
unsigned pcs_idx = 0;
for (auto& spd : _per_process_data)
{ {
// TODO use process name auto& pcs = spd->process;
unsigned pcs_idx = 0; auto const& x = *_process_solutions[pcs_idx];
for (auto& spd : _per_process_data) _output->doOutputLastTimestep(pcs, spd->process_output, timestep, t,
{ x);
auto& pcs = spd->process;
BaseLib::RunTime time_timestep_process; ++pcs_idx;
time_timestep_process.start(); }
}
auto& x = *_process_solutions[pcs_idx];
if (i == 0)
pcs.preTimestep(x, t, delta_t);
if (is_staggered_coupling)
{
// Create a coupling term
if (i == 0)
_global_coupling_conv_crit->preFirstIteration();
else
_global_coupling_conv_crit->setNoFirstIteration();
StaggeredCouplingTerm coupled_term(
spd->coupled_processes,
_solutions_of_coupled_processes[pcs_idx], delta_t);
nonlinear_solver_succeeded = solveOneTimeStepOneProcess(
x, timestep, t, delta_t, *spd, coupled_term, *_output);
}
else
{
nonlinear_solver_succeeded = solveOneTimeStepOneProcess(
x, timestep, t, delta_t, *spd,
ProcessLib::createVoidStaggeredCouplingTerm(),
*_output);
pcs.postTimestep(x);
}
pcs.computeSecondaryVariable(t, x); return nonlinear_solver_succeeded;
}
INFO( bool UncoupledProcessesTimeLoop::solveUncoupledEquationSystems(
"[time] Solving process #%u took %g s in timestep #%u " const double t, const double dt, const std::size_t timestep_id)
"uncouling iteration #%u", {
pcs_idx, time_timestep.elapsed(), timestep, i); // TODO use process name
unsigned pcs_idx = 0;
for (auto& spd : _per_process_data)
{
auto& pcs = spd->process;
BaseLib::RunTime time_timestep_process;
time_timestep_process.start();
if (!nonlinear_solver_succeeded) auto& x = *_process_solutions[pcs_idx];
{ pcs.preTimestep(x, t, dt);
ERR("The nonlinear solver failed in timestep #%u at t = %g "
"s"
" for process #%u.",
timestep, t, pcs_idx);
// save unsuccessful solution const auto nonlinear_solver_succeeded = solveOneTimeStepOneProcess(
_output->doOutputAlways(pcs, spd->process_output, timestep, x, timestep_id, t, dt, *spd,
t, x); ProcessLib::createVoidStaggeredCouplingTerm(), *_output);
pcs.postTimestep(x);
pcs.computeSecondaryVariable(t, x);
break; INFO("[time] Solving process #%u took %g s in time step #%u ", pcs_idx,
} time_timestep_process.elapsed(), timestep_id);
else
{
if (!is_staggered_coupling)
_output->doOutput(pcs, spd->process_output, timestep, t,
x);
}
// Check the convergence of the coupling iteration if (!nonlinear_solver_succeeded)
if (is_staggered_coupling) {
{ ERR("The nonlinear solver failed in time step #%u at t = %g "
auto& x_old = *_solutions_of_last_cpl_iteration[pcs_idx]; "s"
MathLib::LinAlg::axpy(x_old, -1.0, x); " for process #%u.",
_global_coupling_conv_crit->checkResidual(x_old); timestep_id, t, pcs_idx);
coupling_iteration_converged =
coupling_iteration_converged && // save unsuccessful solution
_global_coupling_conv_crit->isSatisfied(); _output->doOutputAlways(pcs, spd->process_output, timestep_id, t,
x);
if (coupling_iteration_converged)
break; return false;
MathLib::LinAlg::copy(x, x_old); }
} else
{
_output->doOutput(pcs, spd->process_output, timestep_id, t, x);
}
++pcs_idx;
}
return true;
}
++pcs_idx; bool UncoupledProcessesTimeLoop::solveCoupledEquationSystemsByStaggeredScheme(
const double t, const double dt, const std::size_t timestep_id)
{
// Coupling iteration
bool coupling_iteration_converged = true;
for (unsigned i = 0; i < _global_coupling_max_iterations; i++)
{
// TODO use process name
bool nonlinear_solver_succeeded = true;
unsigned pcs_idx = 0;
for (auto& spd : _per_process_data)
{
auto& pcs = spd->process;
BaseLib::RunTime time_timestep_process;
time_timestep_process.start();
auto& x = *_process_solutions[pcs_idx];
if (i == 0)
{
pcs.preTimestep(x, t, dt);
// Create a coupling term
_global_coupling_conv_crit->preFirstIteration();
}
else
{
_global_coupling_conv_crit->setNoFirstIteration();
} }
StaggeredCouplingTerm coupled_term(
spd->coupled_processes,
_solutions_of_coupled_processes[pcs_idx], dt);
if (is_staggered_coupling && coupling_iteration_converged) const auto nonlinear_solver_succeeded = solveOneTimeStepOneProcess(
break; x, timestep_id, t, dt, *spd, coupled_term, *_output);
INFO(
"[time] Solving process #%u took %g s in time step #%u "
" coupling iteration #%u",
pcs_idx, time_timestep_process.elapsed(), timestep_id, i);
if (!nonlinear_solver_succeeded) if (!nonlinear_solver_succeeded)
{ {
ERR("The nonlinear solver failed in time step #%u at t = %g "
"s"
" for process #%u.",
timestep_id, t, pcs_idx);
// save unsuccessful solution
_output->doOutputAlways(pcs, spd->process_output, timestep_id,
t, x);
break; break;
} }
}
if (is_staggered_coupling && coupling_iteration_converged) // Check the convergence of the coupling iteration
{ auto& x_old = *_solutions_of_last_cpl_iteration[pcs_idx];
unsigned pcs_idx = 0; MathLib::LinAlg::axpy(x_old, -1.0, x);
for (auto& spd : _per_process_data) _global_coupling_conv_crit->checkResidual(x_old);
{ coupling_iteration_converged =
auto& pcs = spd->process; coupling_iteration_converged &&
auto& x = *_process_solutions[pcs_idx]; _global_coupling_conv_crit->isSatisfied();
pcs.postTimestep(x);
_output->doOutput(pcs, spd->process_output, timestep, t, x); if (coupling_iteration_converged)
++pcs_idx; break;
} MathLib::LinAlg::copy(x, x_old);
++pcs_idx;
} }
INFO("[time] Timestep #%u took %g s.", timestep, if (coupling_iteration_converged)
time_timestep.elapsed()); break;
if (!nonlinear_solver_succeeded) if (!nonlinear_solver_succeeded)
break; {
return false;
}
} }
// output last timestep if (!coupling_iteration_converged)
if (nonlinear_solver_succeeded)
{ {
unsigned pcs_idx = 0; WARN(
for (auto& spd : _per_process_data) "The coupling iterations reaches its maximum number in time step"
{ "#%u at t = %g s",
auto& pcs = spd->process; timestep_id, t);
auto const& x = *_process_solutions[pcs_idx]; }
_output->doOutputLastTimestep(pcs, spd->process_output, timestep, t,
x);
++pcs_idx; unsigned pcs_idx = 0;
} for (auto& spd : _per_process_data)
{
auto& pcs = spd->process;
auto& x = *_process_solutions[pcs_idx];
pcs.postTimestep(x);
pcs.computeSecondaryVariable(t, x);
_output->doOutput(pcs, spd->process_output, timestep_id, t, x);
++pcs_idx;
} }
return nonlinear_solver_succeeded; return true;
} }
UncoupledProcessesTimeLoop::~UncoupledProcessesTimeLoop() UncoupledProcessesTimeLoop::~UncoupledProcessesTimeLoop()
......
...@@ -66,6 +66,33 @@ private: ...@@ -66,6 +66,33 @@ private:
/// Solutions of the previous coupling iteration for the convergence /// Solutions of the previous coupling iteration for the convergence
/// criteria of the coupling iteration. /// criteria of the coupling iteration.
std::vector<GlobalVector*> _solutions_of_last_cpl_iteration; std::vector<GlobalVector*> _solutions_of_last_cpl_iteration;
/**
* \brief Member to solver uncoupled systems of equations, which can be
* a single system of equations, or several systems of equations
* without any dependency among the different systems.
*
* @param t Current time
* @param dt Time step size
* @param timestep_id Index of the time step
* @return true: if all nonlinear solvers convergence.
* false: if any of nonlinear solvers divergences.
*/
bool solveUncoupledEquationSystems(const double t, const double dt,
const std::size_t timestep_id);
/**
* \brief Member to solver coupled systems of equations by the staggered
* scheme.
*
* @param t Current time
* @param dt Time step size
* @param timestep_id Index of the time step
* @return true: if all nonlinear solvers convergence.
* false: if any of nonlinear solvers divergences.
*/
bool solveCoupledEquationSystemsByStaggeredScheme(
const double t, const double dt, const std::size_t timestep_id);
}; };
//! Builds an UncoupledProcessesTimeLoop from the given configuration. //! Builds an UncoupledProcessesTimeLoop from the given configuration.
......
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