OGS
StaggeredCoupling.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#include "StaggeredCoupling.h"
5
6#include <range/v3/view/filter.hpp>
7
8#include "BaseLib/Error.h"
9#include "BaseLib/RunTime.h"
13
14namespace NumLib
15{
23
25 std::vector<GlobalVector*> const& process_solutions)
26{
27 for (auto const* const x : process_solutions)
28 {
29 // Create a vector to store the solution of the last coupling iteration
30 auto& x0 = NumLib::GlobalVectorProvider::provider.getVector(*x);
32
33 // append a solution vector of suitable size
34 solutions_of_last_cpl_iteration_.emplace_back(&x0);
35 }
36}
37
39 std::vector<CouplingNodeVariant> const& coupling_nodes)
40{
41 auto is_regular_node = [](const CouplingNodeVariant& node)
42 { return std::holds_alternative<CouplingNode>(node); };
43
44 for (auto const& coupling_node :
45 coupling_nodes | ranges::views::filter(is_regular_node))
46 {
47 std::get<CouplingNode>(coupling_node)
48 .convergence_criterion->preFirstIteration();
49 }
50}
51
53 std::vector<CouplingNodeVariant> const& coupling_nodes)
54{
55 auto is_regular_node = [](const CouplingNodeVariant& node)
56 { return std::holds_alternative<CouplingNode>(node); };
57
58 for (auto& coupling_node :
59 coupling_nodes | ranges::views::filter(is_regular_node))
60 {
61 std::get<CouplingNode>(coupling_node).convergence_criterion->reset();
62 }
63}
64
66 const bool convergence_of_last_process,
67 CouplingNode const& coupling_node,
68 GlobalVector const& x) const
69{
70 bool is_coupling_iteration_converged = convergence_of_last_process;
71
72 auto& x_old = *solutions_of_last_cpl_iteration_[coupling_node.process_id];
73 // Since x_old can be immediately refreshed after computing dx,
74 // it is assigned with dx to save memory usage
75 MathLib::LinAlg::axpy(x_old, -1.0, x); // save dx = x - x_old to x_old.
76 INFO(
77 "------- Checking convergence criterion for coupled "
78 "solution of process {:s} with ID {:d} -------",
79 coupling_node.process_name, coupling_node.process_id);
80 // Note: x_old stores dx
81 coupling_node.convergence_criterion->checkDeltaX(x_old, x);
82
83 is_coupling_iteration_converged =
84 is_coupling_iteration_converged &&
85 coupling_node.convergence_criterion->isSatisfied();
86
87 return is_coupling_iteration_converged;
88}
89
91 GlobalVector const& x)
92{
93 auto& x_old = *solutions_of_last_cpl_iteration_[process_id];
94 MathLib::LinAlg::copy(x, x_old);
95}
96
97} // namespace NumLib
MathLib::EigenVector GlobalVector
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:28
void initializeCoupledSolutions(std::vector< GlobalVector * > const &process_solutions)
void resetCouplingConvergenceCriteria(std::vector< CouplingNodeVariant > const &coupling_nodes)
std::vector< GlobalVector * > solutions_of_last_cpl_iteration_
void setFirstIterationIndicator(std::vector< CouplingNodeVariant > const &coupling_nodes)
Set the indicator of the first staggered coupling iteration be true.
bool checkCouplingConvergence(const bool convergence_of_last_process, CouplingNode const &coupling_node, GlobalVector const &x) const
void updatePreviousSolution(int const process_id, GlobalVector const &x)
std::variant< CouplingNode, RootCouplingNode > CouplingNodeVariant
void copy(PETScVector const &x, PETScVector &y)
Definition LinAlg.cpp:30
void axpy(PETScVector &y, PetscScalar const a, PETScVector const &x)
Definition LinAlg.cpp:50
Information of a coupling node.
std::unique_ptr< NumLib::ConvergenceCriterion > convergence_criterion
static NUMLIB_EXPORT VectorProvider & provider