From c5d02448e7e2f3a98c5ef5ecffe17fd08db2e280 Mon Sep 17 00:00:00 2001 From: Christoph Lehmann <christoph.lehmann@ufz.de> Date: Wed, 15 Jun 2016 16:57:22 +0200 Subject: [PATCH] optionally do output after each iteration --- .../UncoupledProcessesTimeLoop.cpp | 16 ++++++++++---- .../UncoupledProcessesTimeLoop.h | 4 ++-- NumLib/ODESolver/NonlinearSolver-impl.h | 22 ++++++++++++------- NumLib/ODESolver/NonlinearSolver.h | 13 ++++++++--- NumLib/ODESolver/TimeLoopSingleODE.h | 2 +- 5 files changed, 39 insertions(+), 18 deletions(-) diff --git a/Applications/ApplicationsLib/UncoupledProcessesTimeLoop.cpp b/Applications/ApplicationsLib/UncoupledProcessesTimeLoop.cpp index ff891e6503b..985fb0a4f89 100644 --- a/Applications/ApplicationsLib/UncoupledProcessesTimeLoop.cpp +++ b/Applications/ApplicationsLib/UncoupledProcessesTimeLoop.cpp @@ -108,9 +108,10 @@ setInitialConditions(ProjectData& project, bool UncoupledProcessesTimeLoop:: solveOneTimeStepOneProcess( - GlobalVector& x, double const t, double const delta_t, + GlobalVector& x, std::size_t timestep, double const t, double const delta_t, SingleProcessData& process_data, - UncoupledProcessesTimeLoop::Process& process) + UncoupledProcessesTimeLoop::Process& process, + ProcessLib::Output const& output_control) { auto& time_disc = process.getTimeDiscretization(); auto& ode_sys = *process_data.tdisc_ode_sys; @@ -130,7 +131,13 @@ solveOneTimeStepOneProcess( process.preTimestep(x, t, delta_t); - bool nonlinear_solver_succeeded = nonlinear_solver.solve(x); + auto const post_iteration_callback = [&](unsigned iteration, + GlobalVector const& x) { + output_control.doOutputIteration(process, timestep, t, x, iteration); + }; + + bool nonlinear_solver_succeeded = + nonlinear_solver.solve(x, post_iteration_callback); auto& mat_strg = process_data.mat_strg; time_disc.pushState(t, x, mat_strg); @@ -186,7 +193,8 @@ bool UncoupledProcessesTimeLoop::loop(ProjectData& project) auto& x = *_process_solutions[pcs_idx]; nonlinear_solver_succeeded = solveOneTimeStepOneProcess( - x, t, delta_t, per_process_data[pcs_idx], **p); + x, timestep, t, delta_t, per_process_data[pcs_idx], **p, + out_ctrl); if (!nonlinear_solver_succeeded) { ERR("The nonlinear solver failed in timestep #%u at t = %g s" diff --git a/Applications/ApplicationsLib/UncoupledProcessesTimeLoop.h b/Applications/ApplicationsLib/UncoupledProcessesTimeLoop.h index a89d8d15826..2a9435f2eb4 100644 --- a/Applications/ApplicationsLib/UncoupledProcessesTimeLoop.h +++ b/Applications/ApplicationsLib/UncoupledProcessesTimeLoop.h @@ -155,9 +155,9 @@ private: //! Solves one timestep for the given \c process. bool solveOneTimeStepOneProcess( - GlobalVector& x, double const t, double const delta_t, + GlobalVector& x, std::size_t timestep, double const t, double const delta_t, SingleProcessData& process_data, - Process& process); + Process& process, ProcessLib::Output const& output_control); //! Sets the EquationSystem for the given nonlinear solver, //! which is Picard or Newton depending on the NLTag. diff --git a/NumLib/ODESolver/NonlinearSolver-impl.h b/NumLib/ODESolver/NonlinearSolver-impl.h index 418bcea5104..8b1fb2ece36 100644 --- a/NumLib/ODESolver/NonlinearSolver-impl.h +++ b/NumLib/ODESolver/NonlinearSolver-impl.h @@ -32,10 +32,10 @@ assemble(Vector const& x) const _equation_system->assembleMatricesPicard(x); } -template<typename Matrix, typename Vector> -bool -NonlinearSolver<Matrix, Vector, NonlinearSolverTag::Picard>:: -solve(Vector &x) +template <typename Matrix, typename Vector> +bool NonlinearSolver<Matrix, Vector, NonlinearSolverTag::Picard>::solve( + Vector& x, + std::function<void(unsigned, Vector const&)> const& postIterationCallback) { namespace BLAS = MathLib::BLAS; auto& sys = *_equation_system; @@ -71,6 +71,9 @@ solve(Vector &x) } else { + if (postIterationCallback) + postIterationCallback(iteration, x_new); + switch(sys.postIteration(x_new)) { case IterationResult::SUCCESS: @@ -143,10 +146,10 @@ assemble(Vector const& x) const // equation every time and could not forget it. } -template<typename Matrix, typename Vector> -bool -NonlinearSolver<Matrix, Vector, NonlinearSolverTag::Newton>:: -solve(Vector &x) +template <typename Matrix, typename Vector> +bool NonlinearSolver<Matrix, Vector, NonlinearSolverTag::Newton>::solve( + Vector& x, + std::function<void(unsigned, Vector const&)> const& postIterationCallback) { namespace BLAS = MathLib::BLAS; auto& sys = *_equation_system; @@ -195,6 +198,9 @@ solve(Vector &x) MathLib::GlobalVectorProvider<Vector>::provider.getVector(x, _x_new_id); BLAS::axpy(x_new, -_alpha, minus_delta_x); + if (postIterationCallback) + postIterationCallback(iteration, x_new); + switch(sys.postIteration(x_new)) { case IterationResult::SUCCESS: diff --git a/NumLib/ODESolver/NonlinearSolver.h b/NumLib/ODESolver/NonlinearSolver.h index aa4d4cad511..aaed26ca277 100644 --- a/NumLib/ODESolver/NonlinearSolver.h +++ b/NumLib/ODESolver/NonlinearSolver.h @@ -53,11 +53,14 @@ public: /*! Assemble and solve the equation system. * * \param x in: the initial guess, out: the solution. + * \param postIterationCallback called after each iteration if set. * * \retval true if the equation system could be solved * \retval false otherwise */ - virtual bool solve(Vector& x) = 0; + virtual bool solve(Vector& x, + std::function<void(unsigned, Vector const&)> const& + postIterationCallback) = 0; virtual ~NonlinearSolverBase() = default; }; @@ -108,7 +111,9 @@ public: void assemble(Vector const& x) const override; - bool solve(Vector& x) override; + bool solve(Vector& x, + std::function<void(unsigned, Vector const&)> const& + postIterationCallback) override; private: LinearSolver& _linear_solver; @@ -159,7 +164,9 @@ public: void assemble(Vector const& x) const override; - bool solve(Vector& x) override; + bool solve(Vector& x, + std::function<void(unsigned, Vector const&)> const& + postIterationCallback) override; private: LinearSolver& _linear_solver; diff --git a/NumLib/ODESolver/TimeLoopSingleODE.h b/NumLib/ODESolver/TimeLoopSingleODE.h index f7c45ad92ce..a974e1ba12a 100644 --- a/NumLib/ODESolver/TimeLoopSingleODE.h +++ b/NumLib/ODESolver/TimeLoopSingleODE.h @@ -110,7 +110,7 @@ loop(const double t0, Vector const& x0, const double t_end, const double delta_t // INFO("time: %e, delta_t: %e", t, delta_t); time_disc.nextTimestep(t, delta_t); - nl_slv_succeeded = _nonlinear_solver->solve(x); + nl_slv_succeeded = _nonlinear_solver->solve(x, nullptr); if (!nl_slv_succeeded) break; time_disc.pushState(t, x, _ode_sys); -- GitLab