From ec8a7eb4e90d6909f0e76d21107b2a1b4de137e2 Mon Sep 17 00:00:00 2001 From: Maarten Hodzelmans Date: Tue, 23 Jun 2026 09:03:10 +0200 Subject: [PATCH 1/3] Add optional callback performed before step to gsDynamicBase.h --- src/gsDynamicSolvers/gsDynamicBase.h | 25 +++++++++++++++++++ .../gsStructuralAnalysisTypes.h | 2 ++ 2 files changed, 27 insertions(+) diff --git a/src/gsDynamicSolvers/gsDynamicBase.h b/src/gsDynamicSolvers/gsDynamicBase.h index 9f0d818..7e4742a 100644 --- a/src/gsDynamicSolvers/gsDynamicBase.h +++ b/src/gsDynamicSolvers/gsDynamicBase.h @@ -49,6 +49,9 @@ class gsDynamicBase public: + /// @brief Callback that is evaluated before each timestep. + typedef std::function StepCallback_t; + virtual ~gsDynamicBase() {}; /// Constructor @@ -193,8 +196,15 @@ class gsDynamicBase /// Perform one arc-length step virtual gsStatus step(T dt) { + if (m_preStepCallback && !m_preStepCallback(m_time,dt,m_options)) + { + m_status = gsStatus::OtherError; + return m_status; + } + gsStatus status = this->_step(m_time,dt,m_U,m_V,m_A); m_time += dt; + m_status = status; return status; } @@ -239,6 +249,19 @@ class gsDynamicBase virtual void setVelocities(const gsVector & V) {this->setV(V);} virtual void setAccelerations(const gsVector & A) {this->setA(A);} + /// @brief Set a function that is called before each timestep. WARNING: This + /// callback is only performed for the non-const step(). + virtual void setPreStepCallback(const StepCallback_t & callback) + { + m_preStepCallback = callback; + } + + /// @brief Clear the pre-step callback. + virtual void clearPreStepCallback() + { + m_preStepCallback = StepCallback_t(); + } + /// Access the options virtual gsOptionList & options() {return m_options;}; @@ -335,6 +358,8 @@ class gsDynamicBase Residual_t m_residual; TResidual_t m_Tresidual; + StepCallback_t m_preStepCallback; + mutable typename gsSparseSolver::uPtr m_solver; // Cholesky by default protected: diff --git a/src/gsStructuralAnalysisTools/gsStructuralAnalysisTypes.h b/src/gsStructuralAnalysisTools/gsStructuralAnalysisTypes.h index e58e8c1..86a5552 100644 --- a/src/gsStructuralAnalysisTools/gsStructuralAnalysisTypes.h +++ b/src/gsStructuralAnalysisTools/gsStructuralAnalysisTypes.h @@ -11,6 +11,8 @@ Author(s): H.M. Verhelst (2019-..., TU Delft) */ +#pragma once + #include #include From 9d1713ae50b420e1c7727ef4c9aeb126d6f92ca3 Mon Sep 17 00:00:00 2001 From: Maarten Hodzelmans Date: Tue, 23 Jun 2026 09:37:55 +0200 Subject: [PATCH 2/3] Update comments/docs in accordance with AI review. Base class no longer refers to arc-length methods. --- src/gsDynamicSolvers/gsDynamicBase.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/gsDynamicSolvers/gsDynamicBase.h b/src/gsDynamicSolvers/gsDynamicBase.h index 7e4742a..059027b 100644 --- a/src/gsDynamicSolvers/gsDynamicBase.h +++ b/src/gsDynamicSolvers/gsDynamicBase.h @@ -24,7 +24,8 @@ namespace gismo { /** - @brief Performs the arc length method to solve a nonlinear system of equations. + @brief Base class for solution strategies of nonlinear second-order dynamic + systems. \tparam T coefficient type @@ -193,7 +194,7 @@ class gsDynamicBase // Returns the current time step virtual T getTimeStep() const {return m_options.getReal("DT"); } - /// Perform one arc-length step + /// Perform one time step virtual gsStatus step(T dt) { if (m_preStepCallback && !m_preStepCallback(m_time,dt,m_options)) @@ -225,7 +226,7 @@ class gsDynamicBase } // Output - /// True if the Arc Length method converged + /// True if the method converged virtual bool converged() const {return m_status==gsStatus::Success;} /// Returns the number of Newton iterations performed @@ -249,8 +250,8 @@ class gsDynamicBase virtual void setVelocities(const gsVector & V) {this->setV(V);} virtual void setAccelerations(const gsVector & A) {this->setA(A);} - /// @brief Set a function that is called before each timestep. WARNING: This - /// callback is only performed for the non-const step(). + /// @brief Set a function that is executed when non-const step() is called before + /// the actual step is performed. virtual void setPreStepCallback(const StepCallback_t & callback) { m_preStepCallback = callback; @@ -372,7 +373,7 @@ class gsDynamicBase /// Number of iterations performed mutable index_t m_numIterations; - // /// Maximum number of Arc Length iterations allowed + // /// Maximum number of iterations allowed // index_t m_maxIterations; // /// Number of desired iterations From f00f6a563a67b65d37b59d5f190af16490d5922c Mon Sep 17 00:00:00 2001 From: Maarten Hodzelmans Date: Tue, 23 Jun 2026 09:41:50 +0200 Subject: [PATCH 3/3] Hugo suggestion --- src/gsDynamicSolvers/gsDynamicBase.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gsDynamicSolvers/gsDynamicBase.h b/src/gsDynamicSolvers/gsDynamicBase.h index 059027b..00630a2 100644 --- a/src/gsDynamicSolvers/gsDynamicBase.h +++ b/src/gsDynamicSolvers/gsDynamicBase.h @@ -51,8 +51,8 @@ class gsDynamicBase public: /// @brief Callback that is evaluated before each timestep. - typedef std::function StepCallback_t; - + typedef std::function StepCallback_t; virtual ~gsDynamicBase() {}; /// Constructor