From 0739bb2c16a5918ac1e878d765bbd0b0724fe3e4 Mon Sep 17 00:00:00 2001 From: Dmitri Naumov <dmitri.naumov@ufz.de> Date: Thu, 8 Feb 2024 16:48:47 +0100 Subject: [PATCH] [NL] Change Dirichlet procedure for Newton Instead of setting the solution in the Dirichlet nodes, the solution is enforced through the r.h.s. This usually saves one global iteration and more importantly avoids big jumps in the first iteration for mechanics processes. --- NumLib/ODESolver/NonlinearSolver.cpp | 1 - NumLib/ODESolver/TimeDiscretizedODESystem.cpp | 22 ++++++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/NumLib/ODESolver/NonlinearSolver.cpp b/NumLib/ODESolver/NonlinearSolver.cpp index 59aac171411..324c11905c6 100644 --- a/NumLib/ODESolver/NonlinearSolver.cpp +++ b/NumLib/ODESolver/NonlinearSolver.cpp @@ -345,7 +345,6 @@ NonlinearSolverStatus NonlinearSolver<NonlinearSolverTag::Newton>::solve( timer_dirichlet.start(); sys.computeKnownSolutions(*x[process_id], process_id); - sys.applyKnownSolutions(*x[process_id]); time_dirichlet += timer_dirichlet.elapsed(); sys.preIteration(iteration, *x[process_id]); diff --git a/NumLib/ODESolver/TimeDiscretizedODESystem.cpp b/NumLib/ODESolver/TimeDiscretizedODESystem.cpp index 08d086c07e8..f45e91ffbef 100644 --- a/NumLib/ODESolver/TimeDiscretizedODESystem.cpp +++ b/NumLib/ODESolver/TimeDiscretizedODESystem.cpp @@ -10,6 +10,9 @@ #include "TimeDiscretizedODESystem.h" +#include <range/v3/numeric/accumulate.hpp> +#include <range/v3/view/transform.hpp> + #include "MathLib/LinAlg/ApplyKnownSolution.h" #include "MathLib/LinAlg/UnifiedMatrixSetters.h" #include "NumLib/Exceptions.h" @@ -142,14 +145,27 @@ void TimeDiscretizedODESystem<ODESystemTag::FirstOrderImplicitQuasilinear, } using IndexType = MathLib::MatrixVectorTraits<GlobalMatrix>::Index; + std::size_t const size = ranges::accumulate( + *_known_solutions | ranges::views::transform([](auto const& bc) + { return bc.ids.size(); }), + 0); std::vector<IndexType> ids; + ids.reserve(size); + std::vector<double> values; + values.reserve(size); + for (auto const& bc : *_known_solutions) { - ids.insert(end(ids), begin(bc.ids), end(bc.ids)); + for (std::size_t i = 0; i < bc.ids.size(); ++i) + { + auto const id = bc.ids[i]; + ids.push_back(id); + // minus_delta_x will be set to the difference between the current + // value and the Dirichlet BC value. + values.push_back(x[id] - bc.values[i]); + } } - // For the Newton method the values must be zero - std::vector<double> values(ids.size(), 0); MathLib::applyKnownSolution(Jac, res, minus_delta_x, ids, values); } -- GitLab