From 594c388a6afc701f0dc1ef1bb84b427a54e37c0d Mon Sep 17 00:00:00 2001 From: EvertBunschoten Date: Wed, 15 Apr 2026 16:57:44 +0200 Subject: [PATCH 1/3] Change nested classes to friend classes --- .../drivers/CDiscAdjMultizoneDriver.hpp | 52 ++++++++++--------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/SU2_CFD/include/drivers/CDiscAdjMultizoneDriver.hpp b/SU2_CFD/include/drivers/CDiscAdjMultizoneDriver.hpp index 784fae55a85d..544adaae61cd 100644 --- a/SU2_CFD/include/drivers/CDiscAdjMultizoneDriver.hpp +++ b/SU2_CFD/include/drivers/CDiscAdjMultizoneDriver.hpp @@ -36,38 +36,19 @@ * \brief Block Gauss-Seidel driver for multizone / multiphysics discrete adjoint problems. * \ingroup DiscAdj */ -class CDiscAdjMultizoneDriver : public CMultizoneDriver { - -protected: #ifdef CODI_FORWARD_TYPE using Scalar = su2double; #else using Scalar = passivedouble; #endif - class AdjointProduct : public CMatrixVectorProduct { - public: - CDiscAdjMultizoneDriver* const driver; - const unsigned short iZone = 0; - mutable unsigned long iInnerIter = 0; - - AdjointProduct(CDiscAdjMultizoneDriver* d, unsigned short i) : driver(d), iZone(i) {} - - inline void operator()(const CSysVector & u, CSysVector & v) const override { - driver->SetAllSolutions(iZone, true, u); - driver->Iterate(iZone, iInnerIter, true); - driver->GetAllSolutions(iZone, true, v); - v -= u; - ++iInnerIter; - } - }; +class CDiscAdjMultizoneDriver : public CMultizoneDriver { - class Identity : public CPreconditioner { - public: - inline bool IsIdentity() const override { return true; } - inline void operator()(const CSysVector & u, CSysVector & v) const override { v = u; } - }; +protected: + friend class AdjointProduct; + friend class Identity; + /*! * \brief Kinds of recordings. */ @@ -304,3 +285,26 @@ class CDiscAdjMultizoneDriver : public CMultizoneDriver { } }; + +class AdjointProduct : public CMatrixVectorProduct { +public: + CDiscAdjMultizoneDriver* const driver; + const unsigned short iZone = 0; + mutable unsigned long iInnerIter = 0; + + AdjointProduct(CDiscAdjMultizoneDriver* d, unsigned short i) : driver(d), iZone(i) {} + + inline void operator()(const CSysVector & u, CSysVector & v) const override { + driver->SetAllSolutions(iZone, true, u); + driver->Iterate(iZone, iInnerIter, true); + driver->GetAllSolutions(iZone, true, v); + v -= u; + ++iInnerIter; + } +}; + +class Identity : public CPreconditioner { +public: + inline bool IsIdentity() const override { return true; } + inline void operator()(const CSysVector & u, CSysVector & v) const override { v = u; } +}; \ No newline at end of file From 2821ba1325e34c748b61e1564d52068bdf53e22a Mon Sep 17 00:00:00 2001 From: EvertBunschoten Date: Wed, 15 Apr 2026 16:58:13 +0200 Subject: [PATCH 2/3] Include discrete adjoint multizone driver in python wrapper --- SU2_PY/pySU2/pySU2ad.i | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SU2_PY/pySU2/pySU2ad.i b/SU2_PY/pySU2/pySU2ad.i index 65ddbfe30369..d0b15fe5cee7 100644 --- a/SU2_PY/pySU2/pySU2ad.i +++ b/SU2_PY/pySU2/pySU2ad.i @@ -39,6 +39,7 @@ threads="1" %{ #include "../../Common/include/containers/CPyWrapperMatrixView.hpp" #include "../../SU2_CFD/include/drivers/CDiscAdjSinglezoneDriver.hpp" +#include "../../SU2_CFD/include/drivers/CDiscAdjMultizoneDriver.hpp" #include "../../SU2_CFD/include/drivers/CDriver.hpp" #include "../../SU2_CFD/include/drivers/CDriverBase.hpp" #include "../../SU2_CFD/include/drivers/CMultizoneDriver.hpp" @@ -98,4 +99,5 @@ const unsigned int ZONE_1 = 1; /*!< \brief Definition of the first grid domain. %include "../../SU2_CFD/include/drivers/CSinglezoneDriver.hpp" %include "../../SU2_CFD/include/drivers/CMultizoneDriver.hpp" %include "../../SU2_CFD/include/drivers/CDiscAdjSinglezoneDriver.hpp" +%include "../../SU2_CFD/include/drivers/CDiscAdjMultizoneDriver.hpp" %include "../../SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp" From f0d9facbb93a05fdc3be944340efe1338754c8d3 Mon Sep 17 00:00:00 2001 From: EvertBunschoten Date: Mon, 11 May 2026 12:04:13 +0200 Subject: [PATCH 3/3] Re-define AdjointProduct and Identity as template classes --- .../drivers/CDiscAdjMultizoneDriver.hpp | 33 +++++++++++-------- .../src/drivers/CDiscAdjMultizoneDriver.cpp | 4 +-- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/SU2_CFD/include/drivers/CDiscAdjMultizoneDriver.hpp b/SU2_CFD/include/drivers/CDiscAdjMultizoneDriver.hpp index 544adaae61cd..d2607a16e495 100644 --- a/SU2_CFD/include/drivers/CDiscAdjMultizoneDriver.hpp +++ b/SU2_CFD/include/drivers/CDiscAdjMultizoneDriver.hpp @@ -36,19 +36,21 @@ * \brief Block Gauss-Seidel driver for multizone / multiphysics discrete adjoint problems. * \ingroup DiscAdj */ -#ifdef CODI_FORWARD_TYPE - using Scalar = su2double; -#else - using Scalar = passivedouble; -#endif + +template class AdjointProduct; +template class Identity; class CDiscAdjMultizoneDriver : public CMultizoneDriver { protected: - - friend class AdjointProduct; - friend class Identity; - + #ifdef CODI_FORWARD_TYPE + using Scalar = su2double; + #else + using Scalar = passivedouble; + #endif + + friend class AdjointProduct; + friend class Identity; /*! * \brief Kinds of recordings. */ @@ -286,7 +288,9 @@ class CDiscAdjMultizoneDriver : public CMultizoneDriver { }; -class AdjointProduct : public CMatrixVectorProduct { + +template +class AdjointProduct : public CMatrixVectorProduct { public: CDiscAdjMultizoneDriver* const driver; const unsigned short iZone = 0; @@ -294,7 +298,7 @@ class AdjointProduct : public CMatrixVectorProduct { AdjointProduct(CDiscAdjMultizoneDriver* d, unsigned short i) : driver(d), iZone(i) {} - inline void operator()(const CSysVector & u, CSysVector & v) const override { + inline void operator()(const CSysVector & u, CSysVector & v) const override { driver->SetAllSolutions(iZone, true, u); driver->Iterate(iZone, iInnerIter, true); driver->GetAllSolutions(iZone, true, v); @@ -303,8 +307,9 @@ class AdjointProduct : public CMatrixVectorProduct { } }; -class Identity : public CPreconditioner { +template +class Identity : public CPreconditioner { public: inline bool IsIdentity() const override { return true; } - inline void operator()(const CSysVector & u, CSysVector & v) const override { v = u; } -}; \ No newline at end of file + inline void operator()(const CSysVector & u, CSysVector & v) const override { v = u; } +}; diff --git a/SU2_CFD/src/drivers/CDiscAdjMultizoneDriver.cpp b/SU2_CFD/src/drivers/CDiscAdjMultizoneDriver.cpp index f192d8ef9f98..2c47b0b5cf54 100644 --- a/SU2_CFD/src/drivers/CDiscAdjMultizoneDriver.cpp +++ b/SU2_CFD/src/drivers/CDiscAdjMultizoneDriver.cpp @@ -376,7 +376,7 @@ void CDiscAdjMultizoneDriver::KrylovInnerIters(unsigned short iZone) { GetAllSolutions(iZone, true, AdjSol[iZone]); const bool monitor = config_container[iZone]->GetWrt_ZoneConv(); - const auto product = AdjointProduct(this, iZone); + const auto product = AdjointProduct(this, iZone); /*--- Manipulate the screen output frequency to avoid printing garbage. ---*/ const auto wrtFreq = config_container[iZone]->GetScreen_Wrt_Freq(2); @@ -388,7 +388,7 @@ void CDiscAdjMultizoneDriver::KrylovInnerIters(unsigned short iZone) { Scalar eps_l = 0.0; Scalar tol_l = KrylovTol / eps; auto iter = min(totalIter-2ul, config_container[iZone]->GetnQuasiNewtonSamples()-2ul); - iter = LinSolver[iZone].FGCRODR_LinSolver(AdjRHS[iZone], AdjSol[iZone], product, Identity(), + iter = LinSolver[iZone].FGCRODR_LinSolver(AdjRHS[iZone], AdjSol[iZone], product, Identity(), tol_l, iter, eps_l, monitor, config_container[iZone], FgcrodrMode::SAME_MAT, iter); totalIter -= iter+1;