From 6195b9e68a25c3b8ab84d4f189cbc0d54ac4601c Mon Sep 17 00:00:00 2001 From: eric Date: Fri, 2 Oct 2026 05:35:50 +0800 Subject: [PATCH 01/13] refactor(ns,ins): RAII for scoped solver temporaries in Rhs and SolverImp --- codes/ins/src/INsRhs.cpp | 51 +++++++++++++--------------------- codes/ins/src/INsSolverImp.cpp | 7 ++--- codes/ns/src/NsRhs.cpp | 16 ++++------- codes/ns/src/NsSolverImp.cpp | 7 ++--- 4 files changed, 31 insertions(+), 50 deletions(-) diff --git a/codes/ins/src/INsRhs.cpp b/codes/ins/src/INsRhs.cpp index ba15b6373..ef8837ddb 100644 --- a/codes/ins/src/INsRhs.cpp +++ b/codes/ins/src/INsRhs.cpp @@ -44,6 +44,7 @@ License //#include "UINsUnsteady.h" #include "UINsBcSolver.h" #include +#include BeginNameSpace( ONEFLOW ) @@ -65,10 +66,9 @@ void INsRhs::UpdateResiduals() void INsCalcBc() { - UINsBcSolver * uINsBcSolver = new UINsBcSolver(); + auto uINsBcSolver = std::make_unique(); uINsBcSolver->Init(); uINsBcSolver->CalcBc(); - delete uINsBcSolver; } void INsCalcGamaT(int flag) @@ -128,100 +128,87 @@ void INsCalcRHS() void INsCalcTimeStep() { - UINsInvterm * uINsInvterm = new UINsInvterm(); + auto uINsInvterm = std::make_unique(); uINsInvterm->CalcINsTimeStep(); - delete uINsInvterm; } void INsPreflux() { - UINsInvterm * uINsInvterm = new UINsInvterm(); + auto uINsInvterm = std::make_unique(); uINsInvterm->CalcINsPreflux(); - delete uINsInvterm; } void INsCalcInv() { - UINsInvterm * uINsInvterm = new UINsInvterm(); + auto uINsInvterm = std::make_unique(); uINsInvterm->CalcInvcoff(); - delete uINsInvterm; } void INsCalcVis() { - UINsVisterm * uINsVisterm = new UINsVisterm(); + auto uINsVisterm = std::make_unique(); uINsVisterm->CalcViscoff(); - delete uINsVisterm; } void INsCalcUnstead() { - UINsVisterm * uINsVisterm = new UINsVisterm(); + auto uINsVisterm = std::make_unique(); uINsVisterm->CalcUnsteadcoff(); - delete uINsVisterm; } void INsCalcSrc() { - UINsVisterm * uINsVisterm = new UINsVisterm(); + auto uINsVisterm = std::make_unique(); uINsVisterm->CalcINsSrc(); - delete uINsVisterm; } void INsMomPre() { - UINsInvterm * uINsInvterm = new UINsInvterm(); + auto uINsInvterm = std::make_unique(); uINsInvterm->MomPre(); - delete uINsInvterm; } void INsCalcFaceflux() { - UINsInvterm * uINsInvterm = new UINsInvterm(); + auto uINsInvterm = std::make_unique(); uINsInvterm->CalcFaceflux(); - delete uINsInvterm; } void INsCorrectPresscoef() { - UINsInvterm * uINsInvterm = new UINsInvterm(); + auto uINsInvterm = std::make_unique(); uINsInvterm->CalcCorrectPresscoef(); - delete uINsInvterm; } void INsCalcPressCorrectEquandUpdatePress() { - UINsInvterm * uINsInvterm = new UINsInvterm(); + auto uINsInvterm = std::make_unique(); uINsInvterm->CalcPressCorrectEqu(); - delete uINsInvterm; } void INsUpdateFaceflux() { - UINsInvterm * uINsInvterm = new UINsInvterm(); + auto uINsInvterm = std::make_unique(); uINsInvterm->UpdateFaceflux(); - delete uINsInvterm; } void INsCalcSpeedCorrectandUpdateSpeed() { - UINsInvterm * uINsInvterm = new UINsInvterm(); + auto uINsInvterm = std::make_unique(); uINsInvterm->UpdateSpeed(); - delete uINsInvterm; } void INsUpdateRes() { - UINsInvterm * uINsInvterm = new UINsInvterm(); + auto uINsInvterm = std::make_unique(); uINsInvterm->UpdateINsRes(); - delete uINsInvterm; } //void INsCorrectSpeed() //{ -// UINsInvterm * uINsInvterm = new UINsInvterm(); +// auto uINsInvterm = std::make_unique(); // uINsInvterm->CalcCorrectSpeed(); -// delete uINsInvterm; +// //} @@ -238,9 +225,9 @@ void INsCalcTurbEnergy() //void INsCalcDualTimeStepSrc() //{ -// UINsUnsteady * uinsUnsteady = new UINsUnsteady(); +// auto uinsUnsteady = std::make_unique(); // uinsUnsteady->CalcDualTimeSrc(); -// delete uinsUnsteady; +// //} diff --git a/codes/ins/src/INsSolverImp.cpp b/codes/ins/src/INsSolverImp.cpp index 599f765aa..e5b3bbd57 100644 --- a/codes/ins/src/INsSolverImp.cpp +++ b/codes/ins/src/INsSolverImp.cpp @@ -37,6 +37,7 @@ License #include "TurbPlate.h" #include "SolverRegister.h" #include "DataBase.h" +#include BeginNameSpace( ONEFLOW ) @@ -95,16 +96,14 @@ void INsCalcBoundary( StringField & data ) void INsCalcTimeStep( StringField & data ) { - UTimeStep * uTimeStep = new UTimeStep(); + auto uTimeStep = std::make_unique(); uTimeStep->CalcTimeStep(); - delete uTimeStep; } void INsUpdateResiduals( StringField & data ) { - Rhs * rhs = new INsRhs(); + auto rhs = std::make_unique(); rhs->UpdateResiduals(); - delete rhs; } void INsImplicitMethod( StringField & data ) diff --git a/codes/ns/src/NsRhs.cpp b/codes/ns/src/NsRhs.cpp index 24fd2f362..af3b849e2 100644 --- a/codes/ns/src/NsRhs.cpp +++ b/codes/ns/src/NsRhs.cpp @@ -37,6 +37,7 @@ License #include "Ctrl.h" #include +#include BeginNameSpace( ONEFLOW ) @@ -58,19 +59,17 @@ void NsRhs::UpdateResiduals() void NsCalcBc() { - UNsBcSolver * uNsBcSolver = new UNsBcSolver(); + auto uNsBcSolver = std::make_unique(); uNsBcSolver->Init(); uNsBcSolver->CalcBc(); - delete uNsBcSolver; } void NsCalcBcDebug( const std::string & title ) { std::cout << title << "\n"; - UNsBcSolver * uNsBcSolver = new UNsBcSolver(); + auto uNsBcSolver = std::make_unique(); uNsBcSolver->Init(); uNsBcSolver->CalcBc(); - delete uNsBcSolver; } @@ -110,16 +109,14 @@ void NsCalcRHS() void NsCalcInvFlux() { - UNsInvFlux * uNsInvFlux = new UNsInvFlux(); + auto uNsInvFlux = std::make_unique(); uNsInvFlux->CalcFlux(); - delete uNsInvFlux; } void NsCalcVisFlux() { - UNsVisFlux * uNsVisFlux = new UNsVisFlux(); + auto uNsVisFlux = std::make_unique(); uNsVisFlux->CalcFlux(); - delete uNsVisFlux; } void NsCalcSrcFlux() @@ -150,9 +147,8 @@ void NsCalcTurbEnergy() void NsCalcDualTimeStepSrc() { - UNsUnsteady * unsUnsteady = new UNsUnsteady(); + auto unsUnsteady = std::make_unique(); unsUnsteady->CalcDualTimeSrc(); - delete unsUnsteady; } EndNameSpace diff --git a/codes/ns/src/NsSolverImp.cpp b/codes/ns/src/NsSolverImp.cpp index b746e20b6..1512e1fff 100644 --- a/codes/ns/src/NsSolverImp.cpp +++ b/codes/ns/src/NsSolverImp.cpp @@ -39,6 +39,7 @@ License #include "SolverRegister.h" #include "DataBase.h" #include +#include BeginNameSpace( ONEFLOW ) @@ -99,16 +100,14 @@ void NsCalcBoundary( StringField & data ) void NsCalcTimeStep( StringField & data ) { - UTimeStep * uTimeStep = new UTimeStep(); + auto uTimeStep = std::make_unique(); uTimeStep->CalcTimeStep(); - delete uTimeStep; } void NsUpdateResiduals( StringField & data ) { - Rhs * rhs = new NsRhs(); + auto rhs = std::make_unique(); rhs->UpdateResiduals(); - delete rhs; } void NsImplicitMethod( StringField & data ) From cc04c0d21035dfb9943dc2b0646c8778c3b44283 Mon Sep 17 00:00:00 2001 From: eric Date: Fri, 2 Oct 2026 05:40:58 +0800 Subject: [PATCH 02/13] refactor(solver,geometry): RAII for SolverInfoFactory and UnsGrid DataBook --- codes/geometry/src/UnsGrid.cpp | 7 +++---- codes/solver/include/SolverInfo.h | 4 +++- codes/solver/src/SolverInfo.cpp | 27 ++++++++------------------- 3 files changed, 14 insertions(+), 24 deletions(-) diff --git a/codes/geometry/src/UnsGrid.cpp b/codes/geometry/src/UnsGrid.cpp index efae5a87b..b499c000d 100644 --- a/codes/geometry/src/UnsGrid.cpp +++ b/codes/geometry/src/UnsGrid.cpp @@ -21,6 +21,7 @@ License \*---------------------------------------------------------------------------*/ #include "UnsGrid.h" +#include #include "BcRecord.h" #include "InterFace.h" #include "HXMath.h" @@ -452,11 +453,9 @@ void UnsGrid::GetMinMaxDistance( Real & dismin, Real & dismax ) void UnsGrid::WriteGrid( std::fstream & file ) { - DataBook * databook = new DataBook(); - this->WriteGrid( databook ); + auto databook = std::make_unique< DataBook >(); + this->WriteGrid( databook.get() ); databook->WriteFile( file ); - delete databook; - } diff --git a/codes/solver/include/SolverInfo.h b/codes/solver/include/SolverInfo.h index 6f2cffc68..636456701 100644 --- a/codes/solver/include/SolverInfo.h +++ b/codes/solver/include/SolverInfo.h @@ -24,6 +24,7 @@ License #pragma once #include "HXDefine.h" #include +#include BeginNameSpace( ONEFLOW ) @@ -56,7 +57,8 @@ class SolverInfoFactory SolverInfoFactory(); ~SolverInfoFactory(); public: - static std::map< int, SolverInfo * > * data; + // Owning storage of SolverInfo instances. + static std::unique_ptr< std::map< int, std::unique_ptr< SolverInfo > > > data; public: static void Init(); static void Free(); diff --git a/codes/solver/src/SolverInfo.cpp b/codes/solver/src/SolverInfo.cpp index cc6103590..b5209af40 100644 --- a/codes/solver/src/SolverInfo.cpp +++ b/codes/solver/src/SolverInfo.cpp @@ -22,6 +22,7 @@ License #include "SolverInfo.h" #include +#include #include @@ -37,7 +38,7 @@ SolverInfo::~SolverInfo() ; } -std::map< int, SolverInfo * > * SolverInfoFactory::data = 0; +std::unique_ptr< std::map< int, std::unique_ptr< SolverInfo > > > SolverInfoFactory::data; SolverInfoFactory::SolverInfoFactory() { @@ -51,7 +52,7 @@ void SolverInfoFactory::Init() { if ( ! SolverInfoFactory::data ) { - SolverInfoFactory::data = new std::map< int, SolverInfo * >(); + SolverInfoFactory::data = std::make_unique< std::map< int, std::unique_ptr< SolverInfo > > >(); } } @@ -59,36 +60,24 @@ void SolverInfoFactory::AddSolverInfo( int solverType ) { SolverInfoFactory::Init(); - std::map< int, SolverInfo * >::iterator iter; - - iter = SolverInfoFactory::data->find( solverType ); + auto iter = SolverInfoFactory::data->find( solverType ); if ( iter == SolverInfoFactory::data->end() ) { - SolverInfo * solverInfo = new SolverInfo(); - ( * SolverInfoFactory::data )[ solverType ] = solverInfo; + ( * SolverInfoFactory::data )[ solverType ] = std::make_unique< SolverInfo >(); } } SolverInfo * SolverInfoFactory::GetSolverInfo( int solverType ) { - std::map< int, SolverInfo * >::iterator iter; - iter = SolverInfoFactory::data->find( solverType ); - return iter->second; + auto iter = SolverInfoFactory::data->find( solverType ); + return iter->second.get(); } void SolverInfoFactory::Free() { if ( ! SolverInfoFactory::data ) return; - std::map< int, SolverInfo * >::iterator iter; - for ( iter = SolverInfoFactory::data->begin(); iter != SolverInfoFactory::data->end(); ++ iter ) - { - delete iter->second; - } - SolverInfoFactory::data->clear(); - - delete SolverInfoFactory::data; - SolverInfoFactory::data = 0; + SolverInfoFactory::data.reset(); } From 8ee9a1d85340613f1bea20444e222d65e6cfa43c Mon Sep 17 00:00:00 2001 From: eric Date: Fri, 2 Oct 2026 05:46:25 +0800 Subject: [PATCH 03/13] refactor(chemical): RAII ownership for Chemical, MolecularProperty, Thermodynamic --- codes/chemical/include/Chemical.h | 11 ++++++----- codes/chemical/include/MolecularProperty.h | 3 ++- codes/chemical/include/Thermodynamic.h | 3 ++- codes/chemical/src/Chemical.cpp | 21 +++++++++++---------- codes/chemical/src/MolecularProperty.cpp | 4 ++-- codes/chemical/src/Thermodynamic.cpp | 8 ++------ 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/codes/chemical/include/Chemical.h b/codes/chemical/include/Chemical.h index 0863d703e..c3333f961 100644 --- a/codes/chemical/include/Chemical.h +++ b/codes/chemical/include/Chemical.h @@ -21,6 +21,7 @@ License \*---------------------------------------------------------------------------*/ #pragma once #include "HXDefine.h" +#include BeginNameSpace( ONEFLOW ) @@ -42,11 +43,11 @@ class Chemical Chemical(); ~Chemical(); public: - MolecularProperty * moleProp; - ReactionRate * reactionRate; - Stoichiometric * stoichiometric; - BlotterCurve * blotterCurve; - Thermodynamic * thermodynamic; + std::unique_ptr< MolecularProperty > moleProp; + std::unique_ptr< ReactionRate > reactionRate; + std::unique_ptr< Stoichiometric > stoichiometric; + std::unique_ptr< BlotterCurve > blotterCurve; + std::unique_ptr< Thermodynamic > thermodynamic; int nSpecies, nReaction; public: //working variables diff --git a/codes/chemical/include/MolecularProperty.h b/codes/chemical/include/MolecularProperty.h index 539e3f9f1..875018ddf 100644 --- a/codes/chemical/include/MolecularProperty.h +++ b/codes/chemical/include/MolecularProperty.h @@ -21,6 +21,7 @@ License \*---------------------------------------------------------------------------*/ #pragma once #include "HXDefine.h" +#include BeginNameSpace( ONEFLOW ) @@ -44,7 +45,7 @@ class MolecularProperty StringField species_name; IntField ion_type; RealField cs; //collision cross section - SchmidtNumber * schmidtNumber; + std::unique_ptr< SchmidtNumber > schmidtNumber; Real dim_amw; //dimensional average molecular weight Real amw; //average molecular weight public: diff --git a/codes/chemical/include/Thermodynamic.h b/codes/chemical/include/Thermodynamic.h index a40e030be..096dbf240 100644 --- a/codes/chemical/include/Thermodynamic.h +++ b/codes/chemical/include/Thermodynamic.h @@ -21,6 +21,7 @@ License \*---------------------------------------------------------------------------*/ #pragma once #include "HXDefine.h" +#include BeginNameSpace( ONEFLOW ) @@ -50,7 +51,7 @@ class Thermodynamic public: int nSpecies; int nTSpan, nPolyCoef; - HXVector< ThermodynamicFunction * > tfunction; + HXVector< std::unique_ptr< ThermodynamicFunction > > tfunction; RealField trange; public: void Init( int nSpecies ); diff --git a/codes/chemical/src/Chemical.cpp b/codes/chemical/src/Chemical.cpp index 05979d32e..96410f20d 100644 --- a/codes/chemical/src/Chemical.cpp +++ b/codes/chemical/src/Chemical.cpp @@ -20,6 +20,7 @@ License \*---------------------------------------------------------------------------*/ #include "Chemical.h" +#include #include "MolecularProperty.h" #include "ReactionRate.h" #include "Stoichiometric.h" @@ -53,20 +54,20 @@ Chemical::~Chemical() void Chemical::Alloc() { - moleProp = new MolecularProperty(); - reactionRate = new ReactionRate(); - stoichiometric = new Stoichiometric(); - blotterCurve = new BlotterCurve(); - thermodynamic = new Thermodynamic(); + moleProp = std::make_unique< MolecularProperty >(); + reactionRate = std::make_unique< ReactionRate >(); + stoichiometric = std::make_unique< Stoichiometric >(); + blotterCurve = std::make_unique< BlotterCurve >(); + thermodynamic = std::make_unique< Thermodynamic >(); } void Chemical::DeAlloc() { - delete moleProp; - delete reactionRate; - delete stoichiometric; - delete blotterCurve; - delete thermodynamic; + moleProp.reset(); + reactionRate.reset(); + stoichiometric.reset(); + blotterCurve.reset(); + thermodynamic.reset(); } void Chemical::InitGasModel() diff --git a/codes/chemical/src/MolecularProperty.cpp b/codes/chemical/src/MolecularProperty.cpp index f160fde2b..0905001c1 100644 --- a/codes/chemical/src/MolecularProperty.cpp +++ b/codes/chemical/src/MolecularProperty.cpp @@ -20,6 +20,7 @@ License \*---------------------------------------------------------------------------*/ #include "MolecularProperty.h" +#include #include "SchmidtNumber.h" #include "TextFileParser.h" #include "DataBook.h" @@ -29,12 +30,11 @@ BeginNameSpace( ONEFLOW ) MolecularProperty::MolecularProperty() { - schmidtNumber = new SchmidtNumber(); + schmidtNumber = std::make_unique< SchmidtNumber >(); } MolecularProperty::~MolecularProperty() { - delete schmidtNumber; } void MolecularProperty::Init( int nSpecies ) diff --git a/codes/chemical/src/Thermodynamic.cpp b/codes/chemical/src/Thermodynamic.cpp index 7615aeb2b..d93087619 100644 --- a/codes/chemical/src/Thermodynamic.cpp +++ b/codes/chemical/src/Thermodynamic.cpp @@ -20,6 +20,7 @@ License \*---------------------------------------------------------------------------*/ #include "Thermodynamic.h" +#include #include "TextFileParser.h" #include "DataBook.h" #include "DataBaseIO.h" @@ -91,11 +92,6 @@ Thermodynamic::Thermodynamic() Thermodynamic::~Thermodynamic() { - size_t nSize = tfunction.size(); - for ( int i = 0; i < nSize; ++ i ) - { - delete tfunction[ i ]; - } } void Thermodynamic::Init( int nSpecies ) @@ -104,7 +100,7 @@ void Thermodynamic::Init( int nSpecies ) tfunction.resize( nSpecies ); for ( int i = 0; i < nSpecies; ++ i ) { - tfunction[ i ] = new ThermodynamicFunction(); + tfunction[ i ] = std::make_unique< ThermodynamicFunction >(); } } From 621ea4044f370a318944c02f07e32ead3c39f617 Mon Sep 17 00:00:00 2001 From: eric Date: Fri, 2 Oct 2026 05:54:52 +0800 Subject: [PATCH 04/13] update --- codes/adt/include/AdtTree.h | 116 ----------- codes/adt/include/AdtTree.hpp | 269 ------------------------ codes/adt/include/HXAdtTree.h | 287 ++++++++++++++++++++++++++ codes/geometry/include/PointLocator.h | 2 +- codes/special/src/ADTTest.cpp | 2 +- tests/adt/adt_tree_test.cpp | 2 +- 6 files changed, 290 insertions(+), 388 deletions(-) delete mode 100644 codes/adt/include/AdtTree.h delete mode 100644 codes/adt/include/AdtTree.hpp create mode 100644 codes/adt/include/HXAdtTree.h diff --git a/codes/adt/include/AdtTree.h b/codes/adt/include/AdtTree.h deleted file mode 100644 index b41f3ae44..000000000 --- a/codes/adt/include/AdtTree.h +++ /dev/null @@ -1,116 +0,0 @@ -/*---------------------------------------------------------------------------*\ - OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2026 He Xin and the OneFLOW contributors. -------------------------------------------------------------------------------- -License - This file is part of OneFLOW. - - OneFLOW is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OneFLOW is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OneFLOW. If not, see . - -\*---------------------------------------------------------------------------*/ - - -#pragma once -#include "HXVector.h" -#include -#include - -#ifndef _WINDOWS -#include -#endif - -BeginNameSpace( ONEFLOW ) - -template < typename T, typename U > -class HXAdtNode -{ -public: - using AdtNode = HXAdtNode; - using AdtNodeList = HXVector; - using AdtNodeListIter = typename AdtNodeList::iterator; - -public: - HXVector point; // Replaced raw pointer with HXVector for automatic memory management - int level; // The level in the tree - AdtNode * left; // The left child (non-owning raw pointer) - AdtNode * right; // The right child (non-owning raw pointer) - T item; // Any data stored - int dim; -public: - HXAdtNode( int dim = 3 ); - HXAdtNode( int dim, U * coordinate, T data ); - - // Intentionally does NOT delete left/right. - // Memory is centrally managed by HXAdtTree to prevent recursive stack overflow. - ~HXAdtNode(); - - // Add an Adt node under the current node - void AddNode( AdtNode * node, U * nwmin, U * nwmax, const int & dim ); - - // Is the current node inside region ( pmin, pmax )? - bool IsInRegion( U * pmin, U * pmax, const int & dim ) const; - - // ld carries all the nodes inside region ( pmin, pmax ) - void FindNodesInRegion( U * pmin, U * pmax, U * nwmin, U * nwmax, const int & dim, AdtNodeList & ld ) const; - - int nCount() const; - T GetData() const { return item; } -}; - - -template < typename T, typename U > -class HXAdtTree -{ -public: - using AdtNode = typename HXAdtNode::AdtNode; - using AdtNodeList = typename HXAdtNode::AdtNodeList; - using AdtNodeListIter = typename HXAdtNode::AdtNodeListIter; - using AdtTree = HXAdtTree; - -public: - HXAdtTree( int dim = 3 ); - HXAdtTree( int dim, U * pmin_in, U * pmax_in ); - HXAdtTree( int dim, HXVector< U > & pmin_in, HXVector< U > & pmax_in ); - - // Destructor relies on ownedNodes to safely clean up all nodes without recursion - ~HXAdtTree(); - - // Add an Adt node to the AdtTree (Tree takes ownership of the node) - void AddNode( AdtNode * node ); - - // Find all nodes inside the region ( pmin, pmax ) from the tree - void FindNodesInRegion( U * pmin_in, U * pmax_in, AdtNodeList & ld ) const; - - int nCount() const; - - // Get the min coordinates of the tree - U * GetMin() const; - - // Get the max coordinates of the tree - U * GetMax() const; - -protected: - int dim; - HXVector pmin; // Replaced raw pointer with HXVector - HXVector pmax; // Replaced raw pointer with HXVector - AdtNode * root; - - // Centralized memory management: owns all nodes, preventing memory leaks and recursive destruction issues - std::vector< std::unique_ptr > ownedNodes; -}; - - -EndNameSpace - -#include "AdtTree.hpp" diff --git a/codes/adt/include/AdtTree.hpp b/codes/adt/include/AdtTree.hpp deleted file mode 100644 index 09a997127..000000000 --- a/codes/adt/include/AdtTree.hpp +++ /dev/null @@ -1,269 +0,0 @@ -/*---------------------------------------------------------------------------*\ - OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. -------------------------------------------------------------------------------- -License - This file is part of OneFLOW. - - OneFLOW is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OneFLOW is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OneFLOW. If not, see . - -\*---------------------------------------------------------------------------*/ - -BeginNameSpace( ONEFLOW ) - -// ============================================================================ -// Template Implementations: HXAdtNode -// ============================================================================ - -template < typename T, typename U > -HXAdtNode::HXAdtNode( int dim ) -{ - this->dim = dim; - point.resize(dim, static_cast(0)); - level = 0; - left = nullptr; - right = nullptr; -} - -template < typename T, typename U > -HXAdtNode::HXAdtNode( int dim, U * coordinate, T data ) -{ - this->dim = dim; - point.resize(dim); - std::memcpy( point.data(), coordinate, dim * sizeof( U ) ); - - level = 0; - left = nullptr; - right = nullptr; - item = data; -} - -template < typename T, typename U > -HXAdtNode::~HXAdtNode() -{ - // Do NOT delete left or right here. - // HXAdtTree centrally manages memory via std::unique_ptr to avoid deep recursion stack overflow. - // HXVector 'point' cleans up its own memory automatically. -} - -template < typename T, typename U > -int HXAdtNode::nCount() const -{ - int iCount = 1; - if ( this->left != nullptr ) - { - iCount += left->nCount(); - } - if ( this->right != nullptr ) - { - iCount += right->nCount(); - } - return iCount; -} - -// Add an Adt node under the current node -template < typename T, typename U > -void HXAdtNode::AddNode( AdtNode * node, U * nwmin, U * nwmax, const int & dim ) -{ - int axis = level % dim; - U mid = static_cast(0.5) * ( nwmin[ axis ] + nwmax[ axis ] ); - - if ( node->point[ axis ] <= mid ) - { - if ( left != nullptr ) - { - U originalMax = nwmax[ axis ]; - nwmax[ axis ] = mid; - left->AddNode( node, nwmin, nwmax, dim ); - nwmax[ axis ] = originalMax; // Backtrack - } - else - { - left = node; - node->level = level + 1; - } - } - else - { - if ( right != nullptr ) - { - U originalMin = nwmin[ axis ]; - nwmin[ axis ] = mid; - right->AddNode( node, nwmin, nwmax, dim ); - nwmin[ axis ] = originalMin; // Backtrack - } - else - { - right = node; - node->level = level + 1; - } - } -} - -// Is the current node inside region ( pmin, pmax )? -template < typename T, typename U > -bool HXAdtNode::IsInRegion( U * pmin, U * pmax, const int & dim ) const -{ - for ( int i = 0; i < dim; ++ i ) - { - if ( point[ i ] < pmin[ i ] || point[ i ] > pmax[ i ] ) - { - return false; - } - } - return true; -} - -// ld carries all the nodes inside region ( pmin, pmax ) -template < typename T, typename U > -void HXAdtNode::FindNodesInRegion( U * pmin, U * pmax, U * nwmin, U * nwmax, const int & dim, AdtNodeList & ld ) const -{ - if ( IsInRegion( pmin, pmax, dim ) ) - { - // Cast to non-const pointer to match the original AdtNodeList type requirement - ld.push_back( const_cast(this) ); - } - - int axis = level % dim; - U mid = static_cast(0.5) * ( nwmin[ axis ] + nwmax[ axis ] ); - - if ( left != nullptr ) - { - if ( pmin[ axis ] <= mid && pmax[ axis ] >= nwmin[ axis ] ) - { - U temp = nwmax[ axis ]; - nwmax[ axis ] = mid; - left->FindNodesInRegion( pmin, pmax, nwmin, nwmax, dim, ld ); - nwmax[ axis ] = temp; // Backtrack - } - } - - if ( right != nullptr ) - { - if ( pmax[ axis ] >= mid && pmin[ axis ] <= nwmax[ axis ] ) - { - U temp = nwmin[ axis ]; - nwmin[ axis ] = mid; - right->FindNodesInRegion( pmin, pmax, nwmin, nwmax, dim, ld ); - nwmin[ axis ] = temp; // Backtrack - } - } -} - -// ============================================================================ -// Template Implementations: HXAdtTree -// ============================================================================ - -template < typename T, typename U > -HXAdtTree::HXAdtTree( int dim ) -{ - this->dim = dim; - pmin.resize(dim, static_cast(0.0)); - pmax.resize(dim, static_cast(1.0)); - root = nullptr; -} - -template < typename T, typename U > -HXAdtTree::HXAdtTree( int dim, U * pmin_in, U * pmax_in ) -{ - this->dim = dim; - pmin.resize(dim); - pmax.resize(dim); - for ( int i = 0; i < dim; ++ i ) - { - this->pmin[ i ] = pmin_in[ i ]; - this->pmax[ i ] = pmax_in[ i ]; - } - root = nullptr; -} - -template < typename T, typename U > -HXAdtTree::HXAdtTree( int dim, HXVector< U > & pmin_in, HXVector< U > & pmax_in ) -{ - this->dim = dim; - pmin = pmin_in; - pmax = pmax_in; - root = nullptr; -} - -template < typename T, typename U > -HXAdtTree::~HXAdtTree() -{ - // std::vector of unique_ptr automatically cleans up all owned nodes safely. - // No manual delete[] or recursive delete is needed, preventing stack overflow. -} - -// Add an Adt node to the AdtTree -template < typename T, typename U > -void HXAdtTree::AddNode( AdtNode * node ) -{ - // Take ownership of the raw pointer immediately to prevent memory leaks - ownedNodes.emplace_back( node ); - - if ( root == nullptr ) - { - root = node; - return; - } - - // Use local HXVector to avoid heap allocation (new/delete) during recursion - HXVector localNwmin = this->pmin; - HXVector localNwmax = this->pmax; - - root->AddNode( node, localNwmin.data(), localNwmax.data(), dim ); -} - -// Find all nodes inside the region ( pmin, pmax ) from the tree -template < typename T, typename U > -void HXAdtTree::FindNodesInRegion( U * pmin_in, U * pmax_in, AdtNodeList & ld ) const -{ - if ( root == nullptr ) - { - return; - } - - // Use local HXVector to avoid heap allocation (new/delete) during recursion - HXVector localNwmin = this->pmin; - HXVector localNwmax = this->pmax; - - root->FindNodesInRegion( pmin_in, pmax_in, localNwmin.data(), localNwmax.data(), dim, ld ); -} - -template < typename T, typename U > -int HXAdtTree::nCount() const -{ - if ( root != nullptr ) - { - return root->nCount(); - } - return 0; -} - -template < typename T, typename U > -U * HXAdtTree::GetMin() const -{ - // Return pointer to internal data. - // Note: Caller should not modify this data, but signature is kept for backward compatibility. - return const_cast(pmin.data()); -} - -template < typename T, typename U > -U * HXAdtTree::GetMax() const -{ - // Return pointer to internal data. - return const_cast(pmax.data()); -} - - -EndNameSpace diff --git a/codes/adt/include/HXAdtTree.h b/codes/adt/include/HXAdtTree.h new file mode 100644 index 000000000..5fbdc6438 --- /dev/null +++ b/codes/adt/include/HXAdtTree.h @@ -0,0 +1,287 @@ +/*---------------------------------------------------------------------------*\ + OneFLOW - LargeScale Multiphysics Scientific Simulation Environment + Copyright (C) 2017-2026 He Xin and the OneFLOW contributors. +------------------------------------------------------------------------------- +License + This file is part of OneFLOW. + + OneFLOW is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OneFLOW is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OneFLOW. If not, see . + +\*---------------------------------------------------------------------------*/ + +#pragma once + +#include "HXVector.h" +#include +#include +#include +#include + +#ifndef _WINDOWS +#include +#endif + +BeginNameSpace( ONEFLOW ) + +// ============================================================================ +// Class Declaration & Implementation: HXAdtNode +// ============================================================================ + +template < typename T, typename U > +class HXAdtNode +{ +public: + using AdtNode = HXAdtNode; + using AdtNodeList = HXVector; + using AdtNodeListIter = typename AdtNodeList::iterator; + +public: + HXVector point; // Coordinate array managed automatically by HXVector + int level; // Depth level of the node in the tree + AdtNode * left; // Pointer to the left child node (non-owning) + AdtNode * right; // Pointer to the right child node (non-owning) + T item; // User data storage (payload) + int dim; // Spatial dimension count + +public: + explicit HXAdtNode( int dim = 3 ) + : level( 0 ), left( nullptr ), right( nullptr ), dim( dim ) + { + point.resize( dim, static_cast( 0 ) ); + } + + HXAdtNode( int dim, const U * coordinate, T data ) + : level( 0 ), left( nullptr ), right( nullptr ), item( std::move( data ) ), dim( dim ) + { + point.resize( dim ); + std::memcpy( point.data(), coordinate, dim * sizeof( U ) ); + } + + // Centralized memory management via HXAdtTree avoids recursive destruction stack overflow + ~HXAdtNode() = default; + + // Prevent accidental copying + HXAdtNode( const HXAdtNode& ) = delete; + HXAdtNode& operator=( const HXAdtNode& ) = delete; + + // Allow move semantics + HXAdtNode( HXAdtNode&& ) noexcept = default; + HXAdtNode& operator=( HXAdtNode&& ) noexcept = default; + + // Insert a child node into the current node + void AddNode( AdtNode * node, U * nwmin, U * nwmax, const int & dim ) + { + const int axis = level % dim; + const U mid = static_cast( 0.5 ) * ( nwmin[ axis ] + nwmax[ axis ] ); + + if ( node->point[ axis ] <= mid ) + { + if ( left != nullptr ) + { + const U originalMax = nwmax[ axis ]; + nwmax[ axis ] = mid; + left->AddNode( node, nwmin, nwmax, dim ); + nwmax[ axis ] = originalMax; // Backtrack + } + else + { + left = node; + node->level = level + 1; + } + } + else + { + if ( right != nullptr ) + { + const U originalMin = nwmin[ axis ]; + nwmin[ axis ] = mid; + right->AddNode( node, nwmin, nwmax, dim ); + nwmin[ axis ] = originalMin; // Backtrack + } + else + { + right = node; + node->level = level + 1; + } + } + } + + // Check if the current node is within the query bounding box + [[nodiscard]] bool IsInRegion( const U * pmin, const U * pmax, const int & dim ) const + { + for ( int i = 0; i < dim; ++ i ) + { + if ( point[ i ] < pmin[ i ] || point[ i ] > pmax[ i ] ) + { + return false; + } + } + return true; + } + + // Retrieve all nodes located inside region (pmin, pmax) + void FindNodesInRegion( const U * pmin, const U * pmax, U * nwmin, U * nwmax, const int & dim, AdtNodeList & ld ) const + { + if ( IsInRegion( pmin, pmax, dim ) ) + { + ld.push_back( const_cast( this ) ); + } + + const int axis = level % dim; + const U mid = static_cast( 0.5 ) * ( nwmin[ axis ] + nwmax[ axis ] ); + + if ( left != nullptr ) + { + if ( pmin[ axis ] <= mid && pmax[ axis ] >= nwmin[ axis ] ) + { + const U temp = nwmax[ axis ]; + nwmax[ axis ] = mid; + left->FindNodesInRegion( pmin, pmax, nwmin, nwmax, dim, ld ); + nwmax[ axis ] = temp; // Backtrack + } + } + + if ( right != nullptr ) + { + if ( pmax[ axis ] >= mid && pmin[ axis ] <= nwmax[ axis ] ) + { + const U temp = nwmin[ axis ]; + nwmin[ axis ] = mid; + right->FindNodesInRegion( pmin, pmax, nwmin, nwmax, dim, ld ); + nwmin[ axis ] = temp; // Backtrack + } + } + } + + [[nodiscard]] int nCount() const + { + int iCount = 1; + if ( this->left != nullptr ) iCount += left->nCount(); + if ( this->right != nullptr ) iCount += right->nCount(); + return iCount; + } + + [[nodiscard]] T GetData() const { return item; } +}; + + +// ============================================================================ +// Class Declaration & Implementation: HXAdtTree +// ============================================================================ + +template < typename T, typename U > +class HXAdtTree +{ +public: + using AdtNode = typename HXAdtNode::AdtNode; + using AdtNodeList = typename HXAdtNode::AdtNodeList; + using AdtNodeListIter = typename HXAdtNode::AdtNodeListIter; + using AdtTree = HXAdtTree; + +public: + explicit HXAdtTree( int dim = 3 ) + : dim( dim ), root( nullptr ) + { + pmin.resize( dim, static_cast( 0.0 ) ); + pmax.resize( dim, static_cast( 1.0 ) ); + } + + HXAdtTree( int dim, const U * pmin_in, const U * pmax_in ) + : dim( dim ), root( nullptr ) + { + pmin.resize( dim ); + pmax.resize( dim ); + std::memcpy( pmin.data(), pmin_in, dim * sizeof( U ) ); + std::memcpy( pmax.data(), pmax_in, dim * sizeof( U ) ); + } + + HXAdtTree( int dim, const HXVector & pmin_in, const HXVector & pmax_in ) + : dim( dim ), pmin( pmin_in ), pmax( pmax_in ), root( nullptr ) + { + } + + // Destructor automatically cleans up all nodes safely via unique_ptr + ~HXAdtTree() = default; + + // Prevent accidental copying + HXAdtTree( const HXAdtTree& ) = delete; + HXAdtTree& operator=( const HXAdtTree& ) = delete; + + // Allow move semantics + HXAdtTree( HXAdtTree&& ) noexcept = default; + HXAdtTree& operator=( HXAdtTree&& ) noexcept = default; + + // Insert a node into the ADT tree (tree takes memory ownership) + void AddNode( AdtNode * node ) + { + if ( node == nullptr ) return; + + // Take ownership of memory to prevent memory leaks and stack overflows + ownedNodes.emplace_back( node ); + + if ( root == nullptr ) + { + root = node; + return; + } + + // Allocate local vectors to ensure thread-safe backtracking without global side effects + HXVector localNwmin = this->pmin; + HXVector localNwmax = this->pmax; + + root->AddNode( node, localNwmin.data(), localNwmax.data(), dim ); + } + + // Find all nodes falling inside region (pmin, pmax) + void FindNodesInRegion( const U * pmin_in, const U * pmax_in, AdtNodeList & ld ) const + { + if ( root == nullptr ) + { + return; + } + + HXVector localNwmin = this->pmin; + HXVector localNwmax = this->pmax; + + root->FindNodesInRegion( pmin_in, pmax_in, localNwmin.data(), localNwmax.data(), dim, ld ); + } + + [[nodiscard]] int nCount() const + { + return root ? root->nCount() : 0; + } + + // Get min bounding coordinates + [[nodiscard]] U * GetMin() const + { + return const_cast( pmin.data() ); + } + + // Get max bounding coordinates + [[nodiscard]] U * GetMax() const + { + return const_cast( pmax.data() ); + } + +protected: + int dim; + HXVector pmin; // Min boundary array + HXVector pmax; // Max boundary array + AdtNode * root; + + // Centrally managed node memory: prevents memory leaks and recursive destruction stack overflows + std::vector< std::unique_ptr > ownedNodes; +}; + +EndNameSpace \ No newline at end of file diff --git a/codes/geometry/include/PointLocator.h b/codes/geometry/include/PointLocator.h index 458febfa9..46fc779bb 100644 --- a/codes/geometry/include/PointLocator.h +++ b/codes/geometry/include/PointLocator.h @@ -23,7 +23,7 @@ License #pragma once #include "HXDefine.h" -#include "AdtTree.h" +#include "HXAdtTree.h" #include "GridHandles.h" BeginNameSpace( ONEFLOW ) diff --git a/codes/special/src/ADTTest.cpp b/codes/special/src/ADTTest.cpp index 7fc6201ca..449f68546 100644 --- a/codes/special/src/ADTTest.cpp +++ b/codes/special/src/ADTTest.cpp @@ -21,7 +21,7 @@ License \*---------------------------------------------------------------------------*/ #include "ADTTest.h" #include "SimuBase.h" -#include "AdtTree.h" +#include "HXAdtTree.h" #include #include diff --git a/tests/adt/adt_tree_test.cpp b/tests/adt/adt_tree_test.cpp index f978fb47f..838be78c0 100644 --- a/tests/adt/adt_tree_test.cpp +++ b/tests/adt/adt_tree_test.cpp @@ -7,7 +7,7 @@ // Include OneFLOW namespaces and headers // Ensure CMake is configured with the correct include paths -#include "AdtTree.h" +#include "HXAdtTree.h" #include "HXDefine.h" // ============================================================================ From 51be6354c8f125f2ac3890c361e35d49916ff891 Mon Sep 17 00:00:00 2001 From: eric Date: Fri, 2 Oct 2026 06:27:43 +0800 Subject: [PATCH 05/13] update --- codes/special/src/ADTTest.cpp | 4 ---- codes/uns/src/UNsVisFlux.cpp | 8 +++++++- codes/visual/include/HeatFlux.h | 12 ++++++++--- codes/visual/src/HeatFlux.cpp | 33 ++++++++++++++----------------- codes/visual/src/HeatFluxTask.cpp | 13 ++++-------- 5 files changed, 35 insertions(+), 35 deletions(-) diff --git a/codes/special/src/ADTTest.cpp b/codes/special/src/ADTTest.cpp index 449f68546..dc1c39d4c 100644 --- a/codes/special/src/ADTTest.cpp +++ b/codes/special/src/ADTTest.cpp @@ -27,10 +27,6 @@ License BeginNameSpace( ONEFLOW ) -// ============================================================================ -// 3. Test Cases (²âÊÔÓÃÀý) -// ============================================================================ - void TestBasicInsertionAndCount() { std::cout << "Running Test 1: Basic Insertion and Count... "; diff --git a/codes/uns/src/UNsVisFlux.cpp b/codes/uns/src/UNsVisFlux.cpp index 3e5f22c4c..f1bc4ac73 100644 --- a/codes/uns/src/UNsVisFlux.cpp +++ b/codes/uns/src/UNsVisFlux.cpp @@ -165,7 +165,13 @@ void UNsVisFlux::SaveHeatFlux() { if ( ug.fId >= ug.nBFaces ) return; if ( ug.bcRecord->bcType[ ug.fId ] != BC::SOLID_SURFACE ) return; - SurfaceValue * heat_sur = heat_flux.heatflux[ ZoneState::zid ]; + + // FIX: Use .get() to obtain the non-owning raw pointer. + SurfaceValue * heat_sur = heat_flux.heatflux[ ZoneState::zid ].get(); + + // FIX: Dereference the unique_ptr to get the RealField reference. + RealField & hf = *(heat_sur->var); + Real non_dim_heatflux = - nscom.oreynolds * vis.qNormal; heat_sur->var->push_back( non_dim_heatflux ); } diff --git a/codes/visual/include/HeatFlux.h b/codes/visual/include/HeatFlux.h index 34a4c4ffa..c5f5a50b0 100644 --- a/codes/visual/include/HeatFlux.h +++ b/codes/visual/include/HeatFlux.h @@ -23,6 +23,7 @@ License #pragma once #include "HXDefine.h" +#include // Added for std::unique_ptr BeginNameSpace( ONEFLOW ) @@ -31,8 +32,10 @@ class SurfaceValue public: SurfaceValue(); ~SurfaceValue(); + public: - RealField * var; + // FIX: Replaced raw pointer with std::unique_ptr for automatic memory management. + std::unique_ptr var; }; class HeatFlux @@ -40,11 +43,14 @@ class HeatFlux public: HeatFlux (); ~HeatFlux(); + public: - HXVector< SurfaceValue * > heatflux; - HXVector< SurfaceValue * > fricflux; + // FIX: Replaced raw pointer arrays with std::unique_ptr arrays. + HXVector< std::unique_ptr > heatflux; + HXVector< std::unique_ptr > fricflux; IntField flag; bool init_flag; + public: void Init(); void InitGlobal(); diff --git a/codes/visual/src/HeatFlux.cpp b/codes/visual/src/HeatFlux.cpp index e945eadcc..63fd7ed41 100644 --- a/codes/visual/src/HeatFlux.cpp +++ b/codes/visual/src/HeatFlux.cpp @@ -30,12 +30,13 @@ HeatFlux heat_flux; SurfaceValue::SurfaceValue() { - var = new RealField(); + // FIX: Use std::make_unique for exception-safe allocation. + var = std::make_unique(); } SurfaceValue::~SurfaceValue() { - delete var; + // std::unique_ptr automatically cleans up the RealField. } HeatFlux::HeatFlux() @@ -53,10 +54,11 @@ void HeatFlux::Init() InitGlobal(); Allocate(); - SurfaceValue * heat_sur = heat_flux.heatflux[ ZoneState::zid ]; + // FIX: Use .get() to access the raw pointer from unique_ptr for short-term observation. + SurfaceValue * heat_sur = heat_flux.heatflux[ ZoneState::zid ].get(); heat_sur->var->resize( 0 ); - SurfaceValue * fric_sur = heat_flux.fricflux[ ZoneState::zid ]; + SurfaceValue * fric_sur = heat_flux.fricflux[ ZoneState::zid ].get(); fric_sur->var->resize( 0 ); } @@ -64,8 +66,8 @@ void HeatFlux::InitGlobal() { if ( init_flag ) return; init_flag = true; - this->heatflux.resize( ZoneState::nZones, 0 ); - this->fricflux.resize( ZoneState::nZones, 0 ); + this->heatflux.resize( ZoneState::nZones ); + this->fricflux.resize( ZoneState::nZones ); this->flag.resize( ZoneState::nZones, 0 ); } @@ -75,26 +77,21 @@ void HeatFlux::Allocate() if ( ! this->flag[ zId ] ) { this->flag[ zId ] = 1; - SurfaceValue * heat = new SurfaceValue(); - SurfaceValue * fric = new SurfaceValue(); - this->heatflux[ zId ] = heat; - this->fricflux[ zId ] = fric; + // FIX: Use std::make_unique instead of new. + this->heatflux[ zId ] = std::make_unique(); + this->fricflux[ zId ] = std::make_unique(); } } void HeatFlux::DeAllocate() { - int nSize = this->heatflux.size(); - for ( int i = 0; i < nSize; ++ i ) - { - delete this->heatflux[ i ]; - delete this->fricflux[ i ]; - } - + // FIX: clear() automatically invokes the destructor of std::unique_ptr, + // safely releasing all SurfaceValue and their internal RealField objects. + // No manual delete loop is needed, preventing memory leaks on exceptions. this->heatflux.clear(); this->fricflux.clear(); this->flag.clear(); this->init_flag = false; } -EndNameSpace +EndNameSpace \ No newline at end of file diff --git a/codes/visual/src/HeatFluxTask.cpp b/codes/visual/src/HeatFluxTask.cpp index 70e0e1c8c..ce13e0683 100644 --- a/codes/visual/src/HeatFluxTask.cpp +++ b/codes/visual/src/HeatFluxTask.cpp @@ -241,26 +241,21 @@ void CollectWallFaceValue() { ActionState::dataBook->MoveToBegin(); ActionState::dataBook->Resize( 0 ); - Grid * gridIn = Zone::GetGrid(); UnsGrid * grid = UnsGridCast( gridIn ); - int nSolidCells = GetNumberOfSolidCells( grid ); - HXWrite( ActionState::dataBook, nSolidCells ); - if ( nSolidCells == 0 ) return; int zId = ZoneState::zid; - SurfaceValue * heat_sur = heat_flux.heatflux[ zId ]; - SurfaceValue * fric_sur = heat_flux.fricflux[ zId ]; - - RealField & hf = * heat_sur->var; + // FIX: Use .get() to obtain the non-owning raw pointers. + SurfaceValue * heat_sur = heat_flux.heatflux[ zId ].get(); + SurfaceValue * fric_sur = heat_flux.fricflux[ zId ].get(); + RealField & hf = *(heat_sur->var); HXWrite( ActionState::dataBook, hf ); } - EndNameSpace From 8e865e7b92d29ff213246821d54eaddc2a7e8242 Mon Sep 17 00:00:00 2001 From: eric Date: Fri, 2 Oct 2026 06:41:29 +0800 Subject: [PATCH 06/13] continue --- codes/special/include/Mesh.h | 36 ++++++++++++++++++++++++------ codes/special/src/Mesh.cpp | 43 ++++++++++++++++++++---------------- 2 files changed, 53 insertions(+), 26 deletions(-) diff --git a/codes/special/include/Mesh.h b/codes/special/include/Mesh.h index 9e60ed4c7..b2216111f 100644 --- a/codes/special/include/Mesh.h +++ b/codes/special/include/Mesh.h @@ -26,15 +26,19 @@ License #include #include #include - +#include // Added for std::unique_ptr BeginNameSpace( ONEFLOW ) + class NodeMesh; class FaceMesh; class CellMesh; class Mesh; class DataBase; +// ===================================================================== +// HXRandomClass (Unchanged) +// ===================================================================== class HXRandomClass { public: @@ -46,6 +50,12 @@ class HXRandomClass static void RangeRandom( int rangeMin, int rangeMax, std::vector< int > & results ); }; +// ===================================================================== +// SimpleMesh2D (Unchanged) +// Note: It holds a raw Mesh* pointer. Because std::unique_ptr overloads +// operator->, existing code like mesh->nodeMesh->xN will continue to +// work without any modifications. +// ===================================================================== class SimpleMesh2D { public: @@ -75,21 +85,33 @@ class SimpleMesh2D void PushCircleNode( RealField & xArray, RealField & yArray, IntField & nodeArray ); }; -class NodeMesh; +// ===================================================================== +// Mesh (Refactored) +// ===================================================================== class Mesh { public: Mesh(); ~Mesh(); + + // Disable copy to prevent double-free of unique_ptrs + Mesh(const Mesh&) = delete; + Mesh& operator=(const Mesh&) = delete; + public: - NodeMesh * nodeMesh; - FaceMesh * faceMesh; - CellMesh * cellMesh; - DataBase * dataBase; + // FIX: Use std::unique_ptr for automatic memory management. + std::unique_ptr nodeMesh; + std::unique_ptr faceMesh; + std::unique_ptr cellMesh; + std::unique_ptr dataBase; + public: void CreateMesh(); + public: - DataBase * GetDataBase() { return dataBase; }; + // Return raw pointer for compatibility with APIs expecting DataBase* + DataBase * GetDataBase() { return dataBase.get(); } + public: void ConstructTopology(); void SwapBoundary(); diff --git a/codes/special/src/Mesh.cpp b/codes/special/src/Mesh.cpp index c53bedd78..dd7201534 100644 --- a/codes/special/src/Mesh.cpp +++ b/codes/special/src/Mesh.cpp @@ -341,35 +341,40 @@ void SimpleMesh2D::PushCircleNode( RealField & xArray, RealField & yArray, IntFi } } +// ===================================================================== +// Mesh Implementation (Refactored) +// ===================================================================== + Mesh::Mesh() { - nodeMesh = 0; - faceMesh = 0; - cellMesh = 0; - dataBase = new DataBase(); + // std::unique_ptr members are automatically initialized to nullptr. + // We only need to explicitly initialize dataBase as it was in the original code. + dataBase = std::make_unique(); } Mesh::~Mesh() { - delete nodeMesh; - delete faceMesh; - delete cellMesh; - delete dataBase; + // std::unique_ptr automatically cleans up resources. + // No manual delete needed. } void Mesh::CreateMesh() { std::cout << "Mesh::CreateMesh()\n"; - nodeMesh = new NodeMesh(); - faceMesh = new FaceMesh(); - cellMesh = new CellMesh(); + + // FIX: Use std::make_unique for exception-safe allocation. + // If CreateMesh is called multiple times, the old resources are + // automatically released before reassignment, preventing leaks. + nodeMesh = std::make_unique(); + faceMesh = std::make_unique(); + cellMesh = std::make_unique(); SimpleMesh2D simpleMesh2D; simpleMesh2D.SetMesh( this ); simpleMesh2D.GenerateMesh(); + this->ConstructTopology(); ONEFLOW::Visual::Show( this ); - this->CalcMetrics(); } @@ -513,7 +518,7 @@ void Mesh::SwapBoundary() void Mesh::AllocateMetrics() { this->faceMesh->AllocateMetrics(); - this->cellMesh->AllocateMetrics( this->faceMesh ); + this->cellMesh->AllocateMetrics( this->faceMesh.get() ); } void Mesh::CalcMetrics() @@ -558,22 +563,22 @@ void Mesh::CalcMetrics3D() void Mesh::CalcFaceNormal2D() { - this->faceMesh->CalcFaceNormal2D( this->nodeMesh ); + this->faceMesh->CalcFaceNormal2D( this->nodeMesh.get() ); } void Mesh::CalcFaceCenter2D() { - this->faceMesh->CalcFaceCenter2D( this->nodeMesh ); + this->faceMesh->CalcFaceCenter2D( this->nodeMesh.get() ); } void Mesh::CalcFaceCenter1D() { - this->faceMesh->CalcFaceCenter1D( this->nodeMesh ); + this->faceMesh->CalcFaceCenter1D( this->nodeMesh.get() ); } void Mesh::CalcFaceNormal1D() { - this->faceMesh->CalcFaceNormal1D( this->nodeMesh, this->cellMesh ); + this->faceMesh->CalcFaceNormal1D( this->nodeMesh.get(), this->cellMesh.get() ); } void Mesh::CalcCellCenterVol1D() @@ -913,12 +918,12 @@ void Mesh::CalcCellCenterVol3D() void Mesh::CalcFaceNormal3D() { - this->faceMesh->CalcFaceNormal3D( this->nodeMesh ); + this->faceMesh->CalcFaceNormal3D( this->nodeMesh.get() ); } void Mesh::CalcFaceCenter3D() { - this->faceMesh->CalcFaceCenter3D( this->nodeMesh ); + this->faceMesh->CalcFaceCenter3D( this->nodeMesh.get() ); } From 1f8d972271876034f78b6810b3db64c45eefb273 Mon Sep 17 00:00:00 2001 From: eric Date: Fri, 2 Oct 2026 06:59:33 +0800 Subject: [PATCH 07/13] update --- codes/scalar/src/ScalarGrid.cpp | 31 +++++---- codes/special/src/CgnsTest.cpp | 108 +++++++++++++------------------- codes/zone/src/GridGroup.cpp | 14 ++--- 3 files changed, 65 insertions(+), 88 deletions(-) diff --git a/codes/scalar/src/ScalarGrid.cpp b/codes/scalar/src/ScalarGrid.cpp index e42f253b7..3ba1a793b 100644 --- a/codes/scalar/src/ScalarGrid.cpp +++ b/codes/scalar/src/ScalarGrid.cpp @@ -548,13 +548,14 @@ void ScalarGrid::DumpCgnsGrid() { std::fstream file; std::string prjFileName = Prj::GetPrjFileName( "scalar.cgns" ); - CgnsZbase * cgnsZbase = new CgnsZbase(); - cgnsZbase->nBases = 1; - cgnsZbase->InitCgnsBase(); + // FIX: Use stack allocation instead of raw pointer + CgnsZbase cgnsZbase; + cgnsZbase.nBases = 1; + cgnsZbase.InitCgnsBase(); - for ( int iBase = 0; iBase < cgnsZbase->nBases; ++ iBase ) + for ( int iBase = 0; iBase < cgnsZbase.nBases; ++ iBase ) { - CgnsBase * cgnsBase = cgnsZbase->GetCgnsBase( iBase ); + CgnsBase * cgnsBase = cgnsZbase.GetCgnsBase( iBase ); cgnsBase->celldim = ONEFLOW::ONE_D; cgnsBase->phydim = ONEFLOW::ONE_D; @@ -567,20 +568,19 @@ void ScalarGrid::DumpCgnsGrid() this->SetCgnsZone( cgnsZone ); } - cgnsZbase->cgnsFile->OpenCgnsFile( prjFileName, CG_MODE_WRITE ); - cgnsZbase->DumpCgnsMultiBase(); - cgnsZbase->cgnsFile->CloseCgnsFile(); - delete cgnsZbase; + cgnsZbase.cgnsFile->OpenCgnsFile( prjFileName, CG_MODE_WRITE ); + cgnsZbase.DumpCgnsMultiBase(); + cgnsZbase.cgnsFile->CloseCgnsFile(); } void ScalarGrid::GenerateGridFromCgns( const std::string & prjFileName ) { - CgnsZbase * cgnsZbase = new CgnsZbase(); - cgnsZbase->OpenCgnsFile( prjFileName, CG_MODE_READ ); - cgnsZbase->ReadCgnsMultiBase(); - cgnsZbase->CloseCgnsFile(); - this->ReadFromCgnsZbase( cgnsZbase ); - delete cgnsZbase; + // FIX: Use stack allocation instead of raw pointer + CgnsZbase cgnsZbase; + cgnsZbase.OpenCgnsFile( prjFileName, CG_MODE_READ ); + cgnsZbase.ReadCgnsMultiBase(); + cgnsZbase.CloseCgnsFile(); + this->ReadFromCgnsZbase( &cgnsZbase ); } void ScalarGrid::ReadFromCgnsZbase( CgnsZbase * cgnsZbase ) @@ -590,7 +590,6 @@ void ScalarGrid::ReadFromCgnsZbase( CgnsZbase * cgnsZbase ) CgnsBase * cgnsBase = cgnsZbase->GetCgnsBase( 0 ); CgnsZone * cgnsZone = cgnsBase->GetCgnsZone( iZone ); this->ReadFromCgnsZone( cgnsZone ); - } void ScalarGrid::ReadFromCgnsZone( CgnsZone * cgnsZone ) diff --git a/codes/special/src/CgnsTest.cpp b/codes/special/src/CgnsTest.cpp index 27df7dbfe..7f52bf572 100644 --- a/codes/special/src/CgnsTest.cpp +++ b/codes/special/src/CgnsTest.cpp @@ -100,49 +100,44 @@ void CgnsTest::SetDefaultGridName() void CgnsTest::WriteSimpleMultiBaseTest() { - CgnsFile * cgnsFile = new CgnsFile( "smiplebase.cgns", CG_MODE_WRITE ); - cgnsFile->WriteBase( "OneFLOW1" ); - cgnsFile->WriteBase( "OneFLOW 2" ); - cgnsFile->WriteBase( "CGNS base 3" ); - cgnsFile->WriteBase( "Fluid" ); - cgnsFile->WriteBase( "CAE library" ); - delete cgnsFile; + // FIX: Stack allocation. Destructor automatically closes the file. + CgnsFile cgnsFile( "smiplebase.cgns", CG_MODE_WRITE ); + cgnsFile.WriteBase( "OneFLOW1" ); + cgnsFile.WriteBase( "OneFLOW 2" ); + cgnsFile.WriteBase( "CGNS base 3" ); + cgnsFile.WriteBase( "Fluid" ); + cgnsFile.WriteBase( "CAE library" ); } void CgnsTest::ReadSimpleMultiBaseTest() { - CgnsFile * cgnsFile = new CgnsFile( "smiplebase.cgns", CG_MODE_READ ); - cgnsFile->ReadBases(); - delete cgnsFile; + CgnsFile cgnsFile( "smiplebase.cgns", CG_MODE_READ ); + cgnsFile.ReadBases(); } void CgnsTest::WriteDescriptor() { - CgnsFile * cgnsFile = new CgnsFile( "descript.cgns", CG_MODE_WRITE ); - cgnsFile->WriteBaseDescriptor(); - delete cgnsFile; + CgnsFile cgnsFile( "descript.cgns", CG_MODE_WRITE ); + cgnsFile.WriteBaseDescriptor(); + } void CgnsTest::ReadDescriptor() { - CgnsFile * cgnsFile = new CgnsFile( "descript.cgns", CG_MODE_READ ); - cgnsFile->ReadBaseDescriptor(); - delete cgnsFile; + CgnsFile cgnsFile( "descript.cgns", CG_MODE_READ ); + cgnsFile.ReadBaseDescriptor(); } void CgnsTest::WriteEmptyCgnsFile() { //std::cout << " CgnsTest::WriteEmptyCgnsFile() " << "\n"; - CgnsFile * cgnsFile = new CgnsFile( "empty.cgns", CG_MODE_WRITE ); + CgnsFile cgnsFile( "empty.cgns", CG_MODE_WRITE ); //std::cout << " 111 " << "\n"; - delete cgnsFile; - //std::cout << " 222 " << "\n"; } void CgnsTest::ReadEmptyCgnsFile() { - CgnsFile * cgnsFile = new CgnsFile( "empty.cgns", CG_MODE_READ ); - delete cgnsFile; + CgnsFile cgnsFile( "empty.cgns", CG_MODE_READ ); } void CgnsTest::WriteDouble( const std::string & varName, const double & varValue ) @@ -173,18 +168,17 @@ void CgnsTest::TestCgnsLink() this->SetISize( isize ); int nZones = 5; - CgnsFile * fileZone = new CgnsFile( fname, CG_MODE_WRITE ); - CgnsBase * cgnsBase = fileZone->WriteBase( "Base" ); + CgnsFile fileZone( fname, CG_MODE_WRITE ); + CgnsBase * cgnsBase = fileZone.WriteBase( "Base" ); for ( int iZone = 0; iZone < nZones; ++ iZone ) { std::string name = AddString( "Zone", iZone + 1 ); cgnsBase->WriteZoneInfo( name, CGNS_ENUMV( Structured ), isize ); } - delete fileZone; - CgnsFile * fileZoneM = new CgnsFile( fname, CG_MODE_MODIFY ); - CgnsBase * cgnsBaseM = fileZoneM->WriteBase( "Base" ); + CgnsFile fileZoneM( fname, CG_MODE_MODIFY ); + CgnsBase * cgnsBaseM = fileZoneM.WriteBase( "Base" ); for ( int iZone = 0; iZone < nZones; ++ iZone ) { @@ -192,10 +186,8 @@ void CgnsTest::TestCgnsLink() cgnsBaseM->WriteZoneInfo( name, CGNS_ENUMV( Structured ), isize ); } - delete fileZoneM; - - CgnsFile * fileLink = new CgnsFile( linkname, CG_MODE_WRITE ); - CgnsBase * cgnsBaseLink = fileLink->WriteBase( "Base2" ); + CgnsFile fileLink( linkname, CG_MODE_WRITE ); + CgnsBase * cgnsBaseLink = fileLink.WriteBase( "Base2" ); cgnsBaseLink->GoToBase(); for ( int iZone = 0; iZone < nZones; ++ iZone ) @@ -206,7 +198,6 @@ void CgnsTest::TestCgnsLink() cg_link_write( name.c_str(), fname.c_str(), linkpath.c_str() ); } - delete fileLink; } void CgnsTest::GetArray( std::vector< std::vector< float > > & myfloat2d ) @@ -237,13 +228,11 @@ void CgnsTest::WriteArray() std::vector< std::vector< float > > myarray; this->GetArray( myarray ); - CgnsFile * cgnsFile = new CgnsFile( "array.cgns", CG_MODE_WRITE ); - CgnsBase * cgnsBase = cgnsFile->WriteBase( "BaseXXX" ); - this->WriteArray( cgnsFile, cgnsBase ); - cgnsBase = cgnsFile->WriteBase( "BaseYYY" ); - this->WriteArray( cgnsFile, cgnsBase ); - - delete cgnsFile; + CgnsFile cgnsFile( "array.cgns", CG_MODE_WRITE ); + CgnsBase * cgnsBase = cgnsFile.WriteBase( "BaseXXX" ); + this->WriteArray( &cgnsFile, cgnsBase ); + cgnsBase = cgnsFile.WriteBase( "BaseYYY" ); + this->WriteArray( &cgnsFile, cgnsBase ); } void CgnsTest::WriteArray( CgnsFile * cgnsFile, CgnsBase * cgnsBase ) @@ -346,15 +335,14 @@ void CgnsTest::WriteReferenceState() void CgnsTest::ReadReferenceState() { - CgnsFile * cgnsFile = new CgnsFile( "refstate.cgns", CG_MODE_READ ); - cgnsFile->ReadReferenceState(); - delete cgnsFile; + CgnsFile cgnsFile( "refstate.cgns", CG_MODE_READ ); + cgnsFile.ReadReferenceState(); } void CgnsTest::WriteConvergence() { - CgnsFile * cgnsFile = new CgnsFile( "convergence.cgns", CG_MODE_WRITE ); - CgnsBase * cgnsBase = cgnsFile->WriteBase( "Base" ); + CgnsFile cgnsFile( "convergence.cgns", CG_MODE_WRITE ); + CgnsBase * cgnsBase = cgnsFile.WriteBase( "Base" ); cgnsBase->GoToBase(); const int nIterations = 20; std::vector< double > cl( nIterations ), dl( 2 * nIterations ); @@ -380,14 +368,12 @@ void CgnsTest::WriteConvergence() cgsize_t muse = 2 * nIterations; cg_array_write("CoefLift",CGNS_ENUMV(RealDouble), 1, &nuse, &cl[ 0 ] ); cg_array_write("DoefLift",CGNS_ENUMV(RealDouble), 1, &muse, &dl[ 0 ] ); - delete cgnsFile; } void CgnsTest::ReadConvergence() { - CgnsFile * cgnsFile = new CgnsFile( "convergence.cgns", CG_MODE_READ ); - cgnsFile->ReadConvergence(); - delete cgnsFile; + CgnsFile cgnsFile( "convergence.cgns", CG_MODE_READ ); + cgnsFile.ReadConvergence(); } @@ -404,8 +390,8 @@ void CgnsTest::WriteFlowEqn() idata[4]=0; idata[5]=0; - CgnsFile * cgnsFile = new CgnsFile( "floweqn.cgns", CG_MODE_WRITE ); - CgnsBase * cgnsBase = cgnsFile->WriteBase( "Base1" ); + CgnsFile cgnsFile( "floweqn.cgns", CG_MODE_WRITE ); + CgnsBase * cgnsBase = cgnsFile.WriteBase( "Base1" ); CgnsZone * cgnsZone = cgnsBase->WriteZone( "Zone1" ); cgnsZone->GoToZone(); @@ -449,14 +435,12 @@ void CgnsTest::WriteFlowEqn() //Create 'TurbulenceModel' under 'FlowEquationSet' cgnsZone->GoToNode( "FlowEquationSet_t", 1 ); cg_model_write("TurbulenceModel_t",CGNS_ENUMV(OneEquation_SpalartAllmaras)); - delete cgnsFile; } void CgnsTest::ReadFlowEqn() { - CgnsFile * cgnsFile = new CgnsFile( "floweqn.cgns", CG_MODE_READ ); - cgnsFile->ReadFlowEqn(); - delete cgnsFile; + CgnsFile cgnsFile( "floweqn.cgns", CG_MODE_READ ); + cgnsFile.ReadFlowEqn(); } void CgnsTest::WriteTest() @@ -933,17 +917,17 @@ int CgnsTest::read_grid_unst() void CgnsTest::mytest_read() { - CgnsFile * cgnsFile = new CgnsFile( "mytest.cgns", CG_MODE_READ ); + CgnsFile cgnsFile( "mytest.cgns", CG_MODE_READ ); int index_base = -1; int icelldim = -1; int iphysdim = -1; - cgnsFile->ReadNumberOfBases(); - std::cout << " cgnsFile->nBases = " << cgnsFile->nBases << "\n"; + cgnsFile.ReadNumberOfBases(); + std::cout << " cgnsFile.nBases = " << cgnsFile.nBases << "\n"; - for ( int iBase = 0; iBase < cgnsFile->nBases; ++ iBase ) + for ( int iBase = 0; iBase < cgnsFile.nBases; ++ iBase ) { - CgnsBase * cgnsBase = cgnsFile->CreateCgnsBase(); + CgnsBase * cgnsBase = cgnsFile.CreateCgnsBase(); std::cout << " cgnsBase->baseId = " << cgnsBase->baseId << "\n"; cgnsBase->ReadCgnsBaseBasicInfo(); cgnsBase->ReadNumberOfCgnsZones(); @@ -957,16 +941,14 @@ void CgnsTest::mytest_read() cgnsZone->ReadCgnsGridBoundary(); } } - - delete cgnsFile; } void CgnsTest::mytest_write() { - CgnsFile * cgnsFile = new CgnsFile( "mytest.cgns", CG_MODE_WRITE ); + CgnsFile cgnsFile( "mytest.cgns", CG_MODE_WRITE ); int icelldim = 3; int iphysdim = 3; - CgnsBase * cgnsBase = cgnsFile->WriteBase( "Base", icelldim, iphysdim ); + CgnsBase * cgnsBase = cgnsFile.WriteBase( "Base", icelldim, iphysdim ); cgsize_t isize[ 3 ][ 1 ]; @@ -1006,8 +988,6 @@ void CgnsTest::mytest_write() cgnsBcBoco->WriteGridLocation( CGNS_ENUMV(Vertex) ); cgnsBcBoco = cgnsZbcBoco->WriteCgnsBoco( "Bc_3", CGNS_ENUMV(BCTunnelInflow), CGNS_ENUMV(PointList), icounts, ipnts ); cgnsBcBoco->WriteGridLocation( CGNS_ENUMV(CellCenter) ); - - delete cgnsFile; } EndNameSpace diff --git a/codes/zone/src/GridGroup.cpp b/codes/zone/src/GridGroup.cpp index fcdcb2d5f..ebf62f8e3 100644 --- a/codes/zone/src/GridGroup.cpp +++ b/codes/zone/src/GridGroup.cpp @@ -158,7 +158,6 @@ void GridGroup::ReadGrid( std::fstream & file, int zid ) { int spid = 0; int rpid = 0; - Parallel::GetSrPid( zid, spid, rpid ); if ( Parallel::pid == rpid ) @@ -166,13 +165,12 @@ void GridGroup::ReadGrid( std::fstream & file, int zid ) this->CreateGrid( zid ); } - DataBook * dataBook = new DataBook(); - - ONEFLOW::ReadAbstractData( file, dataBook, spid, rpid ); - - ONEFLOW::DataToGrid( dataBook, zid ); - - delete dataBook; + // FIX: Use stack allocation instead of raw pointers. + // This guarantees exception safety and eliminates memory leaks + // if ReadAbstractData or DataToGrid throws an exception. + DataBook dataBook; + ONEFLOW::ReadAbstractData( file, &dataBook, spid, rpid ); + ONEFLOW::DataToGrid( &dataBook, zid ); } void GridGroup::CreateGrid( int zoneId ) From 316ea8befab3d364e83dc80f5540b4bdc6528c94 Mon Sep 17 00:00:00 2001 From: eric Date: Fri, 2 Oct 2026 07:07:48 +0800 Subject: [PATCH 08/13] class FaceJoint --- codes/visual/include/FaceJoint.h | 39 +++++++++++++++++++++++-------- codes/visual/src/FaceJoint.cpp | 29 ++++++++++------------- codes/visual/src/HeatFluxTask.cpp | 12 +++++----- 3 files changed, 47 insertions(+), 33 deletions(-) diff --git a/codes/visual/include/FaceJoint.h b/codes/visual/include/FaceJoint.h index 0ff843220..74a57f423 100644 --- a/codes/visual/include/FaceJoint.h +++ b/codes/visual/include/FaceJoint.h @@ -20,14 +20,13 @@ License \*---------------------------------------------------------------------------*/ - #pragma once #include "Point.h" +#include // Added for std::unique_ptr BeginNameSpace( ONEFLOW ) class FaceJointManager; - class PointLocator; class FaceJoint; @@ -36,9 +35,16 @@ class FaceJointManager public: FaceJointManager(); ~FaceJointManager(); + + // FIX: Disable copy to prevent double-free of unique_ptrs + FaceJointManager(const FaceJointManager&) = delete; + FaceJointManager& operator=(const FaceJointManager&) = delete; + public: - HXVector< FaceJoint * > patch; - FaceJoint * global; + // FIX: Use std::unique_ptr for automatic memory management + HXVector< std::unique_ptr< FaceJoint > > patch; + std::unique_ptr< FaceJoint > global; + public: void ConstructPointIndex(); void CalcNodeValue(); @@ -52,31 +58,44 @@ class FaceJoint using PointType = Point< Real >; using PointField = HXVector< PointType >; using PointLink = HXVector< PointField >; + public: FaceJoint(); ~FaceJoint(); + + // FIX: Disable copy to prevent double-free of unique_ptrs + FaceJoint(const FaceJoint&) = delete; + FaceJoint& operator=(const FaceJoint&) = delete; + public: bool isValid; IntField l2g; + public: - PointLink fvp; //face vertex point; - LinkField fLink; //face link + PointLink fvp; + LinkField fLink; IntField weightId; - RealField fcv; //face center value - RealField fnv; //face node value + RealField fcv; + RealField fnv; + public: RealField pmin, pmax; Real dismin, dismax; - PointLocator * ps; - WallVisual * wallVisual; + + // FIX: Use std::unique_ptr for automatic memory management + std::unique_ptr< PointLocator > ps; + std::unique_ptr< WallVisual > wallVisual; + public: void CalcBoundBox(); void ConstructPointIndex(); void ConstructPointIndexMap( FaceJoint * globalBasicWall ); void CalcNodeValue(); void RemapNodeValue( FaceJoint * globalBasicWall ); + public: int GetSize() { return fvp.size(); } + public: void AddFacePoint( int nSolidCells, FaceJoint::PointLink & ptLink ); void AddFaceCenterValue( int nSolidCells, RealField & fcvIn ); diff --git a/codes/visual/src/FaceJoint.cpp b/codes/visual/src/FaceJoint.cpp index f307bb387..6be9ca133 100644 --- a/codes/visual/src/FaceJoint.cpp +++ b/codes/visual/src/FaceJoint.cpp @@ -31,41 +31,36 @@ BeginNameSpace( ONEFLOW ) FaceJointManager::FaceJointManager() { - global = new FaceJoint(); + // FIX: Use std::make_unique for exception-safe allocation + global = std::make_unique< FaceJoint >(); } FaceJointManager::~FaceJointManager() { - delete global; - int nZone = this->patch.size(); - for ( int zId = 0; zId < nZone; ++ zId ) - { - delete this->patch[ zId ]; - } + // std::unique_ptr automatically cleans up resources } void FaceJointManager::ConstructPointIndex() { this->global->ConstructPointIndex(); - int nLocal = this->patch.size(); for ( int iLocal = 0; iLocal < nLocal; ++ iLocal ) { - FaceJoint * local = this->patch[ iLocal ]; + // FIX: Use .get() to access the raw pointer for non-owning operations + FaceJoint * local = this->patch[ iLocal ].get(); local->ConstructPointIndex(); - local->ConstructPointIndexMap( this->global ); + local->ConstructPointIndexMap( this->global.get() ); } } void FaceJointManager::CalcNodeValue() { this->global->CalcNodeValue(); - int nLocal = this->patch.size(); for ( int iLocal = 0; iLocal < nLocal; ++ iLocal ) { - FaceJoint * local = this->patch[ iLocal ]; - local->RemapNodeValue( this->global ); + FaceJoint * local = this->patch[ iLocal ].get(); + local->RemapNodeValue( this->global.get() ); } } @@ -73,15 +68,15 @@ FaceJoint::FaceJoint() { pmin.resize( 3 ); pmax.resize( 3 ); - ps = new PointLocator(); - wallVisual = new WallVisual(); + // FIX: Use std::make_unique + ps = std::make_unique< PointLocator >(); + wallVisual = std::make_unique< WallVisual >(); isValid = false; } FaceJoint::~FaceJoint() { - delete ps; - delete wallVisual; + // std::unique_ptr automatically cleans up PointLocator and WallVisual } void FaceJoint::CalcBoundBox() diff --git a/codes/visual/src/HeatFluxTask.cpp b/codes/visual/src/HeatFluxTask.cpp index ce13e0683..92c328de5 100644 --- a/codes/visual/src/HeatFluxTask.cpp +++ b/codes/visual/src/HeatFluxTask.cpp @@ -77,7 +77,7 @@ void HeatFluxTask::AllocVariable() for ( int zId = 0; zId < ZoneState::nZones; ++ zId ) { ZoneState::zid = zId; - wallManager->patch.push_back( new FaceJoint() ); + wallManager->patch.push_back( std::make_unique< FaceJoint >() ); } } @@ -138,7 +138,7 @@ void HeatFluxTask::VisualizeWallNodeValue() int iCount = 0; for ( int iData = 0; iData < numberOfSubData; ++ iData ) { - FaceJoint * basicWall = wallManager->patch[ iData ]; + FaceJoint * basicWall = wallManager->patch[ iData ].get(); if ( basicWall->isValid ) iCount ++; basicWall->Visual( file ); } @@ -207,8 +207,8 @@ void AddWallFaceNode( FaceJointManager * walldata, int iZone ) if ( nSolidCells > 0 ) { - FaceJoint * global = walldata->global; - FaceJoint * local = walldata->patch[ iZone ]; + FaceJoint * global = walldata->global.get(); + FaceJoint * local = walldata->patch[ iZone ].get(); local->isValid = true; global->isValid = true; local->AddFacePoint( nSolidCells, ptLink ); @@ -229,8 +229,8 @@ void AddWallFaceValue( FaceJointManager * walldata, int iZone ) if ( nSolidCells > 0 ) { - FaceJoint * global = walldata->global; - FaceJoint * local = walldata->patch[ iZone ]; + FaceJoint * global = walldata->global.get(); + FaceJoint * local = walldata->patch[ iZone ].get(); global->AddFaceCenterValue( nSolidCells, fcv ); local->AddFaceCenterValue( nSolidCells, fcv ); From 631ea4f33258df3117ffb88c0616e96ef1ae0e0c Mon Sep 17 00:00:00 2001 From: eric Date: Fri, 2 Oct 2026 07:14:17 +0800 Subject: [PATCH 09/13] update HeatFluxTask --- codes/visual/include/HeatFluxTask.h | 17 +++++++--- codes/visual/src/HeatFluxTask.cpp | 52 +++++++++-------------------- 2 files changed, 28 insertions(+), 41 deletions(-) diff --git a/codes/visual/include/HeatFluxTask.h b/codes/visual/include/HeatFluxTask.h index b6f790e52..7752f6266 100644 --- a/codes/visual/include/HeatFluxTask.h +++ b/codes/visual/include/HeatFluxTask.h @@ -20,10 +20,10 @@ License \*---------------------------------------------------------------------------*/ - #pragma once #include "Task.h" #include "Point.h" +#include // Added for std::unique_ptr BeginNameSpace( ONEFLOW ) @@ -34,10 +34,18 @@ class HeatFluxTask : public Task public: HeatFluxTask (); ~HeatFluxTask() override; + + // FIX: Disable copy to prevent double-free of unique_ptr + HeatFluxTask(const HeatFluxTask&) = delete; + HeatFluxTask& operator=(const HeatFluxTask&) = delete; + public: - FaceJointManager * wallManager; + // FIX: Use std::unique_ptr for automatic memory management + std::unique_ptr< FaceJointManager > wallManager; + public: void Run() override; + public: void AllocVariable(); void CollectWallFaceNode(); @@ -49,13 +57,12 @@ class HeatFluxTask : public Task class PointLocator; class FaceJoint; - class Grid; +// Global helper functions (still use raw pointers for backward compatibility) void AddWallFaceNode( FaceJointManager * walldata, int iZone ); void AddWallFaceValue( FaceJointManager * walldata, int iZone ); - void CollectWallFaceNode(); void CollectWallFaceValue(); -EndNameSpace +EndNameSpace \ No newline at end of file diff --git a/codes/visual/src/HeatFluxTask.cpp b/codes/visual/src/HeatFluxTask.cpp index 92c328de5..ba0434ba4 100644 --- a/codes/visual/src/HeatFluxTask.cpp +++ b/codes/visual/src/HeatFluxTask.cpp @@ -23,7 +23,6 @@ License #include "HeatFluxTask.h" #include "HeatFlux.h" #include "FaceJoint.h" - #include "Prj.h" #include "WallVisual.h" #include "AeroForceTask.h" @@ -48,17 +47,17 @@ License #include #include - BeginNameSpace( ONEFLOW ) HeatFluxTask::HeatFluxTask() { - wallManager = new FaceJointManager(); + // FIX: Use std::make_unique for exception-safe allocation + wallManager = std::make_unique< FaceJointManager >(); } HeatFluxTask::~HeatFluxTask() { - delete wallManager; + // std::unique_ptr automatically cleans up FaceJointManager } void HeatFluxTask::Run() @@ -77,6 +76,7 @@ void HeatFluxTask::AllocVariable() for ( int zId = 0; zId < ZoneState::nZones; ++ zId ) { ZoneState::zid = zId; + // FIX: Use std::make_unique and push_back wallManager->patch.push_back( std::make_unique< FaceJoint >() ); } } @@ -84,43 +84,38 @@ void HeatFluxTask::AllocVariable() void HeatFluxTask::CollectWallFaceNode() { ActionState::dataBook = this->dataBook.get(); - for ( int zId = 0; zId < ZoneState::nZones; ++ zId ) { ZoneState::zid = zId; - if ( ZoneState::pid[ zId ] == Parallel::pid ) { ONEFLOW::CollectWallFaceNode(); } - HXBcast( ActionState::dataBook, ZoneState::pid[ zId ] ); - - AddWallFaceNode( wallManager, zId ); + // FIX: Use .get() to pass the raw pointer to legacy global functions + AddWallFaceNode( wallManager.get(), zId ); } } void HeatFluxTask::CollectWallFaceValue() { ActionState::dataBook = this->dataBook.get(); - for ( int zId = 0; zId < ZoneState::nZones; ++ zId ) { ZoneState::zid = zId; - if ( ZoneState::pid[ zId ] == Parallel::pid ) { ONEFLOW::CollectWallFaceValue(); } - HXBcast( ActionState::dataBook, ZoneState::pid[ zId ] ); - - AddWallFaceValue( wallManager, zId ); + // FIX: Use .get() + AddWallFaceValue( wallManager.get(), zId ); } } void HeatFluxTask::ConstructPointIndex() { + // unique_ptr overloads operator->, so no .get() needed here wallManager->ConstructPointIndex(); } @@ -133,11 +128,11 @@ void HeatFluxTask::VisualizeWallNodeValue() { std::fstream file; Prj::OpenPrjFile( file, ctrl.heatfluxFile, std::ios_base::out ); - int numberOfSubData = wallManager->patch.size(); int iCount = 0; for ( int iData = 0; iData < numberOfSubData; ++ iData ) { + // FIX: Use .get() to extract the raw pointer from the unique_ptr array FaceJoint * basicWall = wallManager->patch[ iData ].get(); if ( basicWall->isValid ) iCount ++; basicWall->Visual( file ); @@ -145,34 +140,30 @@ void HeatFluxTask::VisualizeWallNodeValue() Prj::CloseFile( file ); } +// ===================================================================== +// Global functions (Unchanged, they accept raw pointers) +// ===================================================================== + void CollectWallFaceNode() { Grid * gridIn = Zone::GetGrid(); UnsGrid * grid = UnsGridCast( gridIn ); - int nSolidCells = GetNumberOfSolidCells( grid ); - ActionState::dataBook->MoveToBegin(); - HXWrite( ActionState::dataBook, nSolidCells ); - if ( nSolidCells <= 0 ) return; WallStructure::PointLink ptLink; - RealField & x = grid->nodeMesh->xN; RealField & y = grid->nodeMesh->yN; RealField & z = grid->nodeMesh->zN; - LinkField & f2n = grid->faceTopo->faces; IntField & bcType = grid->faceTopo->bcManager->bcRecord->bcType; - int nBFaces = bcType.size(); for ( int iFace = 0; iFace < nBFaces; ++ iFace ) { int bc_type = bcType[ iFace ]; - if ( bc_type == BC::SOLID_SURFACE ) { WallStructure::PointField ptList; @@ -183,14 +174,12 @@ void CollectWallFaceNode() Real x0 = x[ index ]; Real y0 = y[ index ]; Real z0 = z[ index ]; - WallStructure::PointType pt( x0, y0, z0 ); ptList.push_back( pt ); } ptLink.push_back( ptList ); } } - HXWrite( ActionState::dataBook, ptLink ); } @@ -199,9 +188,7 @@ void AddWallFaceNode( FaceJointManager * walldata, int iZone ) ActionState::dataBook->MoveToBegin(); int nSolidCells; HXRead( ActionState::dataBook, nSolidCells ); - WallStructure::PointLink ptLink; - ptLink.resize( nSolidCells ); HXRead( ActionState::dataBook, ptLink ); @@ -221,9 +208,7 @@ void AddWallFaceValue( FaceJointManager * walldata, int iZone ) ActionState::dataBook->MoveToBegin(); int nSolidCells; HXRead( ActionState::dataBook, nSolidCells ); - RealField fcv; - fcv.resize( nSolidCells ); HXRead( ActionState::dataBook, fcv ); @@ -231,7 +216,6 @@ void AddWallFaceValue( FaceJointManager * walldata, int iZone ) { FaceJoint * global = walldata->global.get(); FaceJoint * local = walldata->patch[ iZone ].get(); - global->AddFaceCenterValue( nSolidCells, fcv ); local->AddFaceCenterValue( nSolidCells, fcv ); } @@ -248,14 +232,10 @@ void CollectWallFaceValue() if ( nSolidCells == 0 ) return; int zId = ZoneState::zid; - - // FIX: Use .get() to obtain the non-owning raw pointers. + // FIX: Use .get() to access the RealField from the unique_ptr SurfaceValue * heat_sur = heat_flux.heatflux[ zId ].get(); - SurfaceValue * fric_sur = heat_flux.fricflux[ zId ].get(); RealField & hf = *(heat_sur->var); - HXWrite( ActionState::dataBook, hf ); } - -EndNameSpace +EndNameSpace \ No newline at end of file From 2671717352b552f0a0402c6769cc969f4342a98c Mon Sep 17 00:00:00 2001 From: eric Date: Fri, 2 Oct 2026 07:33:51 +0800 Subject: [PATCH 10/13] update --- codes/usolver/include/UVisualize.h | 4 +- codes/usolver/src/UVisualize.cpp | 59 ++++++++++++++--------------- codes/visual/include/LaminarPlate.h | 6 +-- codes/visual/include/NodeField.h | 14 ++++--- codes/visual/include/Plate.h | 7 +++- codes/visual/include/TurbPlate.h | 5 ++- codes/visual/include/Visualize.h | 4 +- codes/visual/src/LaminarPlate.cpp | 19 ++++------ codes/visual/src/NodeField.cpp | 18 ++++----- codes/visual/src/Plate.cpp | 40 ++++++++----------- codes/visual/src/TurbPlate.cpp | 20 ++++------ 11 files changed, 91 insertions(+), 105 deletions(-) diff --git a/codes/usolver/include/UVisualize.h b/codes/usolver/include/UVisualize.h index 31ff18a6e..dc0d7039e 100644 --- a/codes/usolver/include/UVisualize.h +++ b/codes/usolver/include/UVisualize.h @@ -24,6 +24,7 @@ License #pragma once #include "Visualize.h" #include +#include BeginNameSpace( ONEFLOW ) @@ -37,7 +38,8 @@ class VisualTool ~VisualTool(); public: StringField title; - HXVector< MRField * > qNodeField; + // FIX: Use std::unique_ptr for automatic memory management + HXVector< std::unique_ptr > qNodeField; public: void Init(); void AddTitle( const std::string & varName ); diff --git a/codes/usolver/src/UVisualize.cpp b/codes/usolver/src/UVisualize.cpp index 2db9e26d0..284046d9c 100644 --- a/codes/usolver/src/UVisualize.cpp +++ b/codes/usolver/src/UVisualize.cpp @@ -47,18 +47,11 @@ License BeginNameSpace( ONEFLOW ) -VisualTool::VisualTool() -{ - ; -} +VisualTool::VisualTool() { ; } VisualTool::~VisualTool() { - int nSize = qNodeField.size(); - for ( int i = 0; i < nSize; ++ i ) - { - delete qNodeField[ i ]; - } + // std::unique_ptr automatically cleans up MRField objects } void VisualTool::Init() @@ -75,28 +68,31 @@ void VisualTool::AddTitle( const std::string & varName ) title.push_back( AddString( "\"", varName, "\"" ) ); } -MRField * VisualTool::AddField( const std::string & varName ) +MRField * VisualTool::AddField( RealField & qc, const std::string & varName ) { this->AddTitle( varName ); - MRField * fn = InterpolateCellToNode( varName ); - qNodeField.push_back( fn ); - return fn; + auto fn = InterpolateCellToNode( qc ); + MRField * rawPtr = fn.get(); // Keep a non-owning view for return + qNodeField.push_back( std::move(fn) ); + return rawPtr; } -MRField * VisualTool::AddField( RealField & qc, const std::string & varName ) +MRField * VisualTool::AddField( const std::string & varName ) { this->AddTitle( varName ); - MRField * fn = InterpolateCellToNode( qc ); - qNodeField.push_back( fn ); - return fn; + auto fn = InterpolateCellToNode( varName ); + MRField * rawPtr = fn.get(); + qNodeField.push_back( std::move(fn) ); + return rawPtr; } MRField * VisualTool::CreateField( const std::string & varName, int nEqu ) { this->AddTitle( varName ); - MRField * fn = AllocateNodeField( nEqu ); - qNodeField.push_back( fn ); - return fn; + auto fn = AllocateNodeField( nEqu ); + MRField * rawPtr = fn.get(); + qNodeField.push_back( std::move(fn) ); + return rawPtr; } @@ -571,20 +567,20 @@ void UVisualize::CalcNodeField( VisualTool * visualTool ) { UnsGrid * grid = Zone::GetUnsGrid(); MRField * q = ONEFLOW::GetFieldPointer< MRField >( grid, "q" ); - - MRField * rn = visualTool->AddField( ( * q )[ IDX::IR ], "r" ); - MRField * un = visualTool->AddField( ( * q )[ IDX::IU ], "u" ); - MRField * vn = visualTool->AddField( ( * q )[ IDX::IV ], "v" ); - MRField * wn = visualTool->AddField( ( * q )[ IDX::IW ], "w" ); - MRField * pn = visualTool->AddField( ( * q )[ IDX::IP ], "p" ); - - MRField * gaman = InterpolateCellToNode( "gama" ); + MRField * rn = visualTool->AddField( (*q)[IDX::IR], "r" ); + MRField * un = visualTool->AddField( (*q)[IDX::IU], "u" ); + MRField * vn = visualTool->AddField( (*q)[IDX::IV], "v" ); + MRField * wn = visualTool->AddField( (*q)[IDX::IW], "w" ); + MRField * pn = visualTool->AddField( (*q)[IDX::IP], "p" ); + + // FIX: Use std::unique_ptr to manage gaman's lifetime + auto gaman = InterpolateCellToNode( "gama" ); MRField * machn = visualTool->CreateField( "mach" ); - CalcMach( rn, un, vn, wn, pn, gaman, machn ); - delete gaman; + CalcMach( rn, un, vn, wn, pn, gaman.get(), machn ); + // gaman is automatically released here MRField * tempr = ONEFLOW::GetFieldPointer< MRField >( grid, "tempr" ); - visualTool->AddField( ( * tempr )[ IDX::ITT ], "tempr" ); + visualTool->AddField( (*tempr)[IDX::ITT], "tempr" ); if ( vis_model.vismodel > 0 ) { @@ -593,6 +589,7 @@ void UVisualize::CalcNodeField( VisualTool * visualTool ) } } + void CalcMach( MRField * r, MRField * u, MRField * v, MRField * w, MRField * p, MRField * gama, MRField * mach ) { UnsGrid * grid = Zone::GetUnsGrid(); diff --git a/codes/visual/include/LaminarPlate.h b/codes/visual/include/LaminarPlate.h index 1a24fdd0f..f4d080181 100644 --- a/codes/visual/include/LaminarPlate.h +++ b/codes/visual/include/LaminarPlate.h @@ -54,15 +54,15 @@ class LamFriCut : public CuttingClass void Dump( LamData * lamData, std::fstream & file, int axis ) override; }; - class LaminarFlatPlateTask : public Task { public: LaminarFlatPlateTask(); ~LaminarFlatPlateTask() override; public: - CuttingClass * velCut; - CuttingClass * friCut; + // FIX: Use std::unique_ptr for automatic memory management + std::unique_ptr velCut; + std::unique_ptr friCut; public: void Run() override; void OutProfile( CuttingClass * cut ); diff --git a/codes/visual/include/NodeField.h b/codes/visual/include/NodeField.h index a0ca65e25..35f0ccdbc 100644 --- a/codes/visual/include/NodeField.h +++ b/codes/visual/include/NodeField.h @@ -20,15 +20,18 @@ License \*---------------------------------------------------------------------------*/ - #pragma once #include "HXDefine.h" #include "HXArray.h" +#include // Added for std::unique_ptr + BeginNameSpace( ONEFLOW ) -MRField * AllocateNodeField( int nEqu = 1 ); -MRField * InterpolateCellToNode( const std::string & name ); -MRField * InterpolateCellToNode( RealField & qc ); +// FIX: Return std::unique_ptr to explicitly transfer ownership +std::unique_ptr AllocateNodeField( int nEqu = 1 ); +std::unique_ptr InterpolateCellToNode( const std::string & name ); +std::unique_ptr InterpolateCellToNode( RealField & qc ); + void InterpolateCellToNodeForComponent( RealField & qNodeField, RealField & qField ); void ApplyBoundaryConditionToNodeField( RealField & qNodeField, RealField & qField, RealField & nCount, int bcType, bool twoSide ); @@ -36,11 +39,10 @@ template < typename T > void ReorderList( HXVector< T > & x, IntField & indexList ) { HXVector< T > tmp = x; - for ( HXSize_t i = 0; i < indexList.size(); ++ i ) { x[ i ] = tmp[ indexList[ i ] ]; } } -EndNameSpace +EndNameSpace \ No newline at end of file diff --git a/codes/visual/include/Plate.h b/codes/visual/include/Plate.h index 5befe950c..98e158218 100644 --- a/codes/visual/include/Plate.h +++ b/codes/visual/include/Plate.h @@ -27,6 +27,7 @@ License #include "HXArray.h" #include #include +#include // Added for std::unique_ptr BeginNameSpace( ONEFLOW ) @@ -77,7 +78,8 @@ class LamData LamData(); ~LamData(); public: - HXVector< PlaneData * > data; + // FIX: Use std::unique_ptr for automatic memory management + HXVector< std::unique_ptr > data; public: void Init(); void AddVar( RealField & point, int p1, int p2, Real c1, Real c2 ); @@ -98,7 +100,8 @@ class CuttingClass public: StringField nameList; SliceInfo sliceInfo; - HXVector< LamData * > sliceData; + // FIX: Use std::unique_ptr for automatic memory management + HXVector< std::unique_ptr > sliceData; public: void Init(); void Slice(); diff --git a/codes/visual/include/TurbPlate.h b/codes/visual/include/TurbPlate.h index 580547e3a..8904002ee 100644 --- a/codes/visual/include/TurbPlate.h +++ b/codes/visual/include/TurbPlate.h @@ -66,8 +66,9 @@ class TurbFlatPlateTask : public Task TurbFlatPlateTask(); ~TurbFlatPlateTask() override; public: - CuttingClass * velCut; - CuttingClass * friCut; + // FIX: Use std::unique_ptr for automatic memory management + std::unique_ptr velCut; + std::unique_ptr friCut; public: void Run() override; void OutProfile( CuttingClass * cut ); diff --git a/codes/visual/include/Visualize.h b/codes/visual/include/Visualize.h index 8cdbc9f43..35faa1a31 100644 --- a/codes/visual/include/Visualize.h +++ b/codes/visual/include/Visualize.h @@ -20,12 +20,11 @@ License \*---------------------------------------------------------------------------*/ - #pragma once #include "HXDefine.h" #include "HXArray.h" #include - +#include // Added BeginNameSpace( ONEFLOW ) @@ -38,6 +37,7 @@ class Visualize virtual void Visual(){}; }; + class Plot { public: diff --git a/codes/visual/src/LaminarPlate.cpp b/codes/visual/src/LaminarPlate.cpp index 13ad7a2ea..9727f065a 100644 --- a/codes/visual/src/LaminarPlate.cpp +++ b/codes/visual/src/LaminarPlate.cpp @@ -91,7 +91,7 @@ void LamVelCut::Dump() int nSlice = sliceData.size(); for ( int i = 0; i < nSlice; ++ i ) { - LamData * lamData = sliceData[ i ]; + LamData * lamData = sliceData[ i ].get(); this->Dump( lamData, file, sliceInfo.dir2[ i ] ); } @@ -174,7 +174,7 @@ void LamFriCut::Dump() int nSlice = sliceData.size(); for ( int i = 0; i < nSlice; ++ i ) { - LamData * lamData = sliceData[ i ]; + LamData * lamData = sliceData[ i ].get(); this->Dump( lamData, file, sliceInfo.dir2[ i ] ); } @@ -227,20 +227,17 @@ void LamFriCut::Dump( LamData * lamData, std::fstream & file, int axis ) LaminarFlatPlateTask::LaminarFlatPlateTask() { - velCut = new LamVelCut(); - friCut = new LamFriCut(); + velCut = std::make_unique(); + friCut = std::make_unique(); } -LaminarFlatPlateTask::~LaminarFlatPlateTask() -{ - delete velCut; - delete friCut; -} +LaminarFlatPlateTask::~LaminarFlatPlateTask() = default; + void LaminarFlatPlateTask::Run() { - this->OutProfile( velCut ); - this->OutProfile( friCut ); + this->OutProfile( velCut.get() ); + this->OutProfile( friCut.get() ); } void LaminarFlatPlateTask::OutProfile( CuttingClass * cut ) diff --git a/codes/visual/src/NodeField.cpp b/codes/visual/src/NodeField.cpp index 4ffd2a47a..41d24b1e5 100644 --- a/codes/visual/src/NodeField.cpp +++ b/codes/visual/src/NodeField.cpp @@ -30,34 +30,32 @@ License BeginNameSpace( ONEFLOW ) -MRField * AllocateNodeField( int nEqu ) +std::unique_ptr AllocateNodeField( int nEqu ) { UnsGrid * grid = Zone::GetUnsGrid(); int nNodes = grid->nNodes; - MRField * nf = new MRField( nEqu, nNodes ); - return nf; + return std::make_unique( nEqu, nNodes ); } -MRField * InterpolateCellToNode( const std::string & name ) +std::unique_ptr InterpolateCellToNode( const std::string & name ) { UnsGrid * grid = Zone::GetUnsGrid(); MRField * cf = GetFieldPointer< MRField > ( grid, name ); int nNodes = grid->nNodes; int nEqu = cf->GetNEqu(); - MRField * nf = AllocateNodeField( nEqu ); + auto nf = AllocateNodeField( nEqu ); for ( int iEqu = 0; iEqu < nEqu; ++ iEqu ) { - InterpolateCellToNodeForComponent( ( * nf )[ iEqu ], ( * cf )[ iEqu ] ); + InterpolateCellToNodeForComponent( (*nf)[ iEqu ], (*cf)[ iEqu ] ); } return nf; } -MRField * InterpolateCellToNode( RealField & qc ) +std::unique_ptr InterpolateCellToNode( RealField & qc ) { - UnsGrid * grid = Zone::GetUnsGrid(); - MRField * fn = AllocateNodeField( 1 ); - InterpolateCellToNodeForComponent( ( * fn )[ 0 ], qc ); + auto fn = AllocateNodeField( 1 ); + InterpolateCellToNodeForComponent( (*fn)[ 0 ], qc ); return fn; } diff --git a/codes/visual/src/Plate.cpp b/codes/visual/src/Plate.cpp index 3acd9bba0..601aef9c6 100644 --- a/codes/visual/src/Plate.cpp +++ b/codes/visual/src/Plate.cpp @@ -237,13 +237,10 @@ LamData::LamData() LamData::~LamData() { - int nField = data.size(); - for ( int i = 0; i < nField; ++ i ) - { - delete data[ i ]; - } + // std::unique_ptr automatically cleans up PlaneData objects } + void LamData::Init() { int nField = data.size(); @@ -310,28 +307,27 @@ CuttingClass::CuttingClass() CuttingClass::~CuttingClass() { - int nSlice = sliceData.size(); - for ( int i = 0; i < nSlice; ++ i ) - { - delete sliceData[ i ]; - } + // std::unique_ptr automatically cleans up LamData objects } + void CuttingClass::Init() { int nSlice = sliceInfo.slicepos.size(); sliceData.resize( nSlice ); for ( int i = 0; i < nSlice; ++ i ) { - sliceData[ i ] = new LamData(); + // FIX: Use std::make_unique + sliceData[ i ] = std::make_unique(); } } void CuttingClass::Slice() { int nField = nameList.size(); - HXVector< MRField * > fields( nField ); + // FIX: Use std::unique_ptr array to prevent memory leaks if an exception occurs + HXVector< std::unique_ptr > fields( nField ); for ( int i = 0; i < nField; ++ i ) { fields[ i ] = InterpolateCellToNode( nameList[ i ] ); @@ -340,25 +336,19 @@ void CuttingClass::Slice() int nSlice = sliceData.size(); for ( int iSlice = 0; iSlice < nSlice; ++ iSlice ) { - LamData * lam = sliceData[ iSlice ]; - + LamData * lam = sliceData[ iSlice ].get(); for ( int j = 0; j < nField; ++ j ) { - PlaneData * pd = new PlaneData(); - pd->nodedata = fields[ j ]; - lam->data.push_back( pd ); + auto pd = std::make_unique(); + pd->nodedata = fields[ j ].get(); // Non-owning observer pointer + lam->data.push_back( std::move(pd) ); } lam->Init(); } for ( int iSlice = 0; iSlice < nSlice; ++ iSlice ) { - this->CutPlane( sliceInfo.slicepos[ iSlice ], sliceInfo.dir1[ iSlice ], this->sliceData[ iSlice ] ); - } - - for ( int i = 0; i < nField; ++ i ) - { - delete fields[ i ]; + this->CutPlane( sliceInfo.slicepos[ iSlice ], sliceInfo.dir1[ iSlice ], this->sliceData[ iSlice ].get() ); } } @@ -373,7 +363,7 @@ void CuttingClass::Write( DataBook * dataBook ) HXWrite( dataBook, sliceInfo.dir1[ i ] ); HXWrite( dataBook, sliceInfo.dir2[ i ] ); - LamData * lamData = sliceData[ i ]; + LamData * lamData = sliceData[ i ].get(); lamData->Write( dataBook ); } } @@ -391,7 +381,7 @@ void CuttingClass::Read( DataBook * dataBook ) HXRead( dataBook, dir1 ); HXRead( dataBook, dir2 ); - LamData * lamData = sliceData[ i ]; + LamData * lamData = sliceData[ i ].get(); lamData->Read( dataBook ); } } diff --git a/codes/visual/src/TurbPlate.cpp b/codes/visual/src/TurbPlate.cpp index c11194978..cca618410 100644 --- a/codes/visual/src/TurbPlate.cpp +++ b/codes/visual/src/TurbPlate.cpp @@ -99,7 +99,7 @@ void TurbVelCut::DumpNormal() size_t nSlice = sliceData.size(); for ( int i = 0; i < nSlice; ++ i ) { - LamData * lamData = sliceData[ i ]; + LamData * lamData = sliceData[ i ].get(); this->Dump( lamData, file, sliceInfo.dir2[ i ] ); } @@ -134,7 +134,7 @@ void TurbVelCut::DumpDetail() size_t nSlice = sliceData.size(); for ( int i = 0; i < nSlice; ++ i ) { - LamData * lamData = sliceData[ i ]; + LamData * lamData = sliceData[ i ].get(); this->DumpDetail( lamData, file, sliceInfo.dir2[ i ] ); } @@ -300,7 +300,7 @@ void TurbFriCut::Dump() size_t nSlice = sliceData.size(); for ( int i = 0; i < nSlice; ++ i ) { - LamData * lamData = sliceData[ i ]; + LamData * lamData = sliceData[ i ].get(); this->Dump( lamData, file, sliceInfo.dir2[ i ] ); } @@ -353,20 +353,16 @@ void TurbFriCut::Dump( LamData * lamData, std::fstream & file, int axis ) TurbFlatPlateTask::TurbFlatPlateTask() { - velCut = new TurbVelCut(); - friCut = new TurbFriCut(); + velCut = std::make_unique(); + friCut = std::make_unique(); } -TurbFlatPlateTask::~TurbFlatPlateTask() -{ - delete velCut; - delete friCut; -} +TurbFlatPlateTask::~TurbFlatPlateTask() = default; void TurbFlatPlateTask::Run() { - this->OutProfile( velCut ); - this->OutProfile( friCut ); + this->OutProfile( velCut.get() ); + this->OutProfile( friCut.get() ); } void TurbFlatPlateTask::OutProfile( CuttingClass * cut ) From 671f4e710c868016b68a88652ca46441c0499600 Mon Sep 17 00:00:00 2001 From: eric Date: Fri, 2 Oct 2026 09:29:31 +0800 Subject: [PATCH 11/13] update --- codes/residual/src/ResidualTaskReg.cpp | 5 ++-- codes/turb/src/TurbRhs.cpp | 39 +++++++++++--------------- codes/uins/src/UINsLusgs.cpp | 5 ++-- codes/uns/src/UNsLusgs.cpp | 5 ++-- codes/visual/src/VisualTaskReg.cpp | 6 ++-- 5 files changed, 24 insertions(+), 36 deletions(-) diff --git a/codes/residual/src/ResidualTaskReg.cpp b/codes/residual/src/ResidualTaskReg.cpp index bee50c92f..7bb18aa4d 100644 --- a/codes/residual/src/ResidualTaskReg.cpp +++ b/codes/residual/src/ResidualTaskReg.cpp @@ -46,9 +46,8 @@ void DumpResidual( StringField & data ) { int solverType = SolverState::solverType; - Residual * residual = new UResidual(); - residual->Dump( solverType ); - delete residual; + UResidual residual; + residual.Dump( solverType ); } EndNameSpace diff --git a/codes/turb/src/TurbRhs.cpp b/codes/turb/src/TurbRhs.cpp index 18c12dfe6..546d84407 100644 --- a/codes/turb/src/TurbRhs.cpp +++ b/codes/turb/src/TurbRhs.cpp @@ -28,6 +28,7 @@ License #include "UTurbSpectrum.h" #include "UTurbUnsteady.h" #include "UTurbBcSolver.h" +#include // Added for std::make_unique BeginNameSpace( ONEFLOW ) @@ -48,10 +49,9 @@ void TurbRhs::CalcRHS() void TurbCalcBc() { - UTurbBcSolver * uTurbBcSolver = new UTurbBcSolver(); - uTurbBcSolver->Init(); - uTurbBcSolver->CalcBc(); - delete uTurbBcSolver; + UTurbBcSolver uTurbBcSolver; + uTurbBcSolver.Init(); + uTurbBcSolver.CalcBc(); } void TurbCalcRHS() @@ -72,30 +72,26 @@ void TurbCalcRHS() void TurbCalcInvFlux() { - UTurbInvFlux * uTurbInvFlux = new UTurbInvFlux(); - uTurbInvFlux->CalcFlux(); - delete uTurbInvFlux; + UTurbInvFlux uTurbInvFlux; + uTurbInvFlux.CalcFlux(); } void TurbCalcVisFlux() { - UTurbVisFlux * uTurbVisFlux = new UTurbVisFlux(); - uTurbVisFlux->CalcVisFlux(); - delete uTurbVisFlux; + UTurbVisFlux uTurbVisFlux; + uTurbVisFlux.CalcVisFlux(); } void TurbCalcSrcFlux() { - UTurbSrcFlux * uTurbSrcFlux = new UTurbSrcFlux(); - uTurbSrcFlux->CalcSrcFlux(); - delete uTurbSrcFlux; + UTurbSrcFlux uTurbSrcFlux; + uTurbSrcFlux.CalcSrcFlux(); } void TurbCalcSpectrum() { - UTurbSpectrum * uTurbSpectrum = new UTurbSpectrum(); - uTurbSpectrum->CalcSpectrum(); - delete uTurbSpectrum; + UTurbSpectrum uTurbSpectrum; + uTurbSpectrum.CalcSpectrum(); } void TurbCalcDualTimeStepSrc() @@ -103,18 +99,15 @@ void TurbCalcDualTimeStepSrc() //dual time step source if ( ctrl.idualtime == 1 ) { - UTurbUnsteady * uTurbUnsteady = new UTurbUnsteady(); - uTurbUnsteady->CalcDualTimeSrc(); - delete uTurbUnsteady; + UTurbUnsteady uTurbUnsteady; + uTurbUnsteady.CalcDualTimeSrc(); } } void CalcTurbulentViscosity() { - UTurbSrcFlux * uTurbSrcFlux = new UTurbSrcFlux(); - uTurbSrcFlux->CalcVist(); - delete uTurbSrcFlux; - + UTurbSrcFlux uTurbSrcFlux; + uTurbSrcFlux.CalcVist(); } EndNameSpace diff --git a/codes/uins/src/UINsLusgs.cpp b/codes/uins/src/UINsLusgs.cpp index 6e779f5bd..6b18a9b9f 100644 --- a/codes/uins/src/UINsLusgs.cpp +++ b/codes/uins/src/UINsLusgs.cpp @@ -68,9 +68,8 @@ void UINsLusgs::Init() void UINsLusgs::CalcSpectrum() { - UINsSpectrum * unsSpectrum = new UINsSpectrum(); - unsSpectrum->CalcImplicitSpectrum(); - delete unsSpectrum; + UINsSpectrum unsSpectrum; + unsSpectrum.CalcImplicitSpectrum(); } void UINsLusgs::LowerSweep() diff --git a/codes/uns/src/UNsLusgs.cpp b/codes/uns/src/UNsLusgs.cpp index b12abc181..a169ba71a 100644 --- a/codes/uns/src/UNsLusgs.cpp +++ b/codes/uns/src/UNsLusgs.cpp @@ -67,9 +67,8 @@ void UNsLusgs::Init() void UNsLusgs::CalcSpectrum() { - UNsSpectrum * unsSpectrum = new UNsSpectrum(); - unsSpectrum->CalcImplicitSpectrum(); - delete unsSpectrum; + UNsSpectrum unsSpectrum; + unsSpectrum.CalcImplicitSpectrum(); } void UNsLusgs::LowerSweep() diff --git a/codes/visual/src/VisualTaskReg.cpp b/codes/visual/src/VisualTaskReg.cpp index e3c658b93..8af257bf7 100644 --- a/codes/visual/src/VisualTaskReg.cpp +++ b/codes/visual/src/VisualTaskReg.cpp @@ -64,11 +64,9 @@ void RegisterVisualTask() void Visualization( StringField & data ) { - Visualize * visualize = new UVisualize(); + UVisualize visualize; - visualize->Visual(); - - delete visualize; + visualize.Visual(); } EndNameSpace From 3ab4bbf7186254aa34abf6b2ab0e5b1f6c863c0e Mon Sep 17 00:00:00 2001 From: eric Date: Fri, 2 Oct 2026 09:49:48 +0800 Subject: [PATCH 12/13] continue --- codes/uins/include/UINsInvterm.h | 2 -- codes/uins/include/UINsLimiter.h | 1 - codes/uins/src/UINsInvterm.cpp | 2 +- codes/uins/src/UINsLimiter.cpp | 6 ------ codes/uns/src/UNsInvFlux.cpp | 2 +- codes/uns/src/UNsLimiter.cpp | 2 -- codes/usolver/include/ULimiter.h | 23 +++++++++++++++-------- codes/usolver/src/ULimiter.cpp | 26 +++++++++++--------------- codes/uturb/include/UTurbLimiter.h | 1 - codes/uturb/src/UTurbInvFlux.cpp | 2 +- codes/uturb/src/UTurbLimiter.cpp | 6 ------ codes/visual/src/VisualTaskReg.cpp | 1 - 12 files changed, 29 insertions(+), 45 deletions(-) diff --git a/codes/uins/include/UINsInvterm.h b/codes/uins/include/UINsInvterm.h index c8d88f20f..6b8380737 100644 --- a/codes/uins/include/UINsInvterm.h +++ b/codes/uins/include/UINsInvterm.h @@ -65,8 +65,6 @@ class UINsInvterm : public INsInvterm void PrepareFaceValue(); void PrepareProFaceValue(); void CalcPreGrad(); - //void CalcINsinvTerm(); - //void UpdateFaceInvFlux(); void ReadTmp(); public: void GetQlQrField(); diff --git a/codes/uins/include/UINsLimiter.h b/codes/uins/include/UINsLimiter.h index 1519d2201..0af5464c3 100644 --- a/codes/uins/include/UINsLimiter.h +++ b/codes/uins/include/UINsLimiter.h @@ -39,7 +39,6 @@ class INsLimiter : public Limiter { public: INsLimiter(); - ~INsLimiter() override; }; EndNameSpace diff --git a/codes/uins/src/UINsInvterm.cpp b/codes/uins/src/UINsInvterm.cpp index c8a641ce5..d686ead97 100644 --- a/codes/uins/src/UINsInvterm.cpp +++ b/codes/uins/src/UINsInvterm.cpp @@ -54,7 +54,7 @@ BeginNameSpace(ONEFLOW) UINsInvterm::UINsInvterm() { limiter = new INsLimiter(); - limf = limiter->limf; + limf = limiter->limf.get(); } UINsInvterm::~UINsInvterm() diff --git a/codes/uins/src/UINsLimiter.cpp b/codes/uins/src/UINsLimiter.cpp index c74cb53a2..522e91bc1 100644 --- a/codes/uins/src/UINsLimiter.cpp +++ b/codes/uins/src/UINsLimiter.cpp @@ -102,13 +102,7 @@ void INsLimField::BcQlQrFix() INsLimiter::INsLimiter() { - limf = new INsLimField(); limflag = ctrl.ilim; } -INsLimiter::~INsLimiter() -{ - delete limf; -} - EndNameSpace diff --git a/codes/uns/src/UNsInvFlux.cpp b/codes/uns/src/UNsInvFlux.cpp index b85e9b8c7..0fb006112 100644 --- a/codes/uns/src/UNsInvFlux.cpp +++ b/codes/uns/src/UNsInvFlux.cpp @@ -54,7 +54,7 @@ BeginNameSpace( ONEFLOW ) UNsInvFlux::UNsInvFlux() { limiter = new NsLimiter(); - limf = limiter->limf; + limf = limiter->limf.get(); } UNsInvFlux::~UNsInvFlux() diff --git a/codes/uns/src/UNsLimiter.cpp b/codes/uns/src/UNsLimiter.cpp index 097601955..83bac143b 100644 --- a/codes/uns/src/UNsLimiter.cpp +++ b/codes/uns/src/UNsLimiter.cpp @@ -97,13 +97,11 @@ void NsLimField::BcQlQrFix() NsLimiter::NsLimiter() { - limf = new NsLimField(); limflag = ctrl.ilim; } NsLimiter::~NsLimiter() { - delete limf; } EndNameSpace diff --git a/codes/usolver/include/ULimiter.h b/codes/usolver/include/ULimiter.h index 5c7caea0f..2a874a42a 100644 --- a/codes/usolver/include/ULimiter.h +++ b/codes/usolver/include/ULimiter.h @@ -24,6 +24,7 @@ License #pragma once #include "HXDefine.h" #include "HXArray.h" +#include BeginNameSpace( ONEFLOW ) @@ -43,15 +44,21 @@ class Lim public: Lim(); ~Lim(); + public: + // Non-owning pointers (managed by FieldManager/Grid) RealField *q, *dqdx, *dqdy, *dqdz; RealField *limiter; - RealField * minvf, * maxvf; + RealField *qf1, *qf2; Real minv1, minv2, maxv1, maxv2; Real dqdx1, dqdy1, dqdz1; Real dqdx2, dqdy2, dqdz2; Real lim1, lim2; Real qmin, qmax; + + // Owned fields managed by RAII + std::unique_ptr< RealField > minvf; + std::unique_ptr< RealField > maxvf; }; using CheckFun = bool ( * )( RealField & ); @@ -61,6 +68,7 @@ class LimField public: LimField(); virtual ~LimField(); + public: virtual void Init(){}; Real ModifyLimiter( Real phil, Real phir ); @@ -68,33 +76,32 @@ class LimField void CalcFaceValueWeighted(); void GetQlQr(); virtual void BcQlQrFix(); + public: int nEqu; + // Non-owning pointers MRField * q; MRField * dqdx, * dqdy, * dqdz; MRField * limiter; - MRField * qf1, * qf2; CheckFun ckfun; }; - class Limiter { public: Limiter(); virtual ~Limiter(); + public: - Lim * lim; - LimField * limf; + std::unique_ptr< Lim > lim; + std::unique_ptr< LimField > limf; int limflag; + public: - void Alloc(); - void DeAlloc(); void SetInitValue(); void CalcLimiter(); void CalcLimiterScalar(); - void CalcZeroLimiter(); void CalcNoLimiter(); void CalcBarthLimiter(); diff --git a/codes/usolver/src/ULimiter.cpp b/codes/usolver/src/ULimiter.cpp index d96df47aa..8e5166c2e 100644 --- a/codes/usolver/src/ULimiter.cpp +++ b/codes/usolver/src/ULimiter.cpp @@ -350,19 +350,24 @@ void LimField::CalcFaceValueWeighted() Limiter::Limiter() { - lim = new Lim(); + lim = std::make_unique< Lim >(); + limf = std::make_unique< LimField >(); } Limiter::~Limiter() { - delete lim; + // unique_ptr handles cleanup automatically } void Limiter::CalcLimiter() { ug.Init(); limf->Init(); - Alloc(); + + // Replace manual Alloc() with RAII allocation + lim->minvf = std::make_unique< RealField >( ug.nTCell ); + lim->maxvf = std::make_unique< RealField >( ug.nTCell ); + for ( int iEqu = 0; iEqu < limf->nEqu; ++ iEqu ) { lim->limiter = & ( * limf->limiter )[ iEqu ]; @@ -373,19 +378,10 @@ void Limiter::CalcLimiter() this->SetInitValue(); this->CalcLimiterScalar(); } - DeAlloc(); -} -void Limiter::Alloc() -{ - lim->minvf = new RealField( ug.nTCell ); - lim->maxvf = new RealField( ug.nTCell ); -} - -void Limiter::DeAlloc() -{ - delete lim->minvf; - delete lim->maxvf; + // Replace manual DeAlloc() with RAII release to match original lifecycle + lim->minvf.reset(); + lim->maxvf.reset(); } void Limiter::SetInitValue() diff --git a/codes/uturb/include/UTurbLimiter.h b/codes/uturb/include/UTurbLimiter.h index a63edf7dc..c3c7e92b1 100644 --- a/codes/uturb/include/UTurbLimiter.h +++ b/codes/uturb/include/UTurbLimiter.h @@ -38,7 +38,6 @@ class TurbLimiter : public Limiter { public: TurbLimiter(); - ~TurbLimiter() override; }; EndNameSpace diff --git a/codes/uturb/src/UTurbInvFlux.cpp b/codes/uturb/src/UTurbInvFlux.cpp index e34672bc5..dce5a46b9 100644 --- a/codes/uturb/src/UTurbInvFlux.cpp +++ b/codes/uturb/src/UTurbInvFlux.cpp @@ -42,7 +42,7 @@ UTurbInvFlux::UTurbInvFlux() limiter = new TurbLimiter(); nslimiter = new NsLimiter(); nslimiter->limflag = turbcom.tns_ilim; - limf = limiter->limf; + limf = limiter->limf.get(); limiter->limflag = turbcom.turb_ilim; } diff --git a/codes/uturb/src/UTurbLimiter.cpp b/codes/uturb/src/UTurbLimiter.cpp index b43d8bb88..8e9aec457 100644 --- a/codes/uturb/src/UTurbLimiter.cpp +++ b/codes/uturb/src/UTurbLimiter.cpp @@ -62,13 +62,7 @@ void TurbLimField::Init() TurbLimiter::TurbLimiter() { - limf = new TurbLimField(); limflag = ILMT_ZERO; } -TurbLimiter::~TurbLimiter() -{ - delete limf; -} - EndNameSpace diff --git a/codes/visual/src/VisualTaskReg.cpp b/codes/visual/src/VisualTaskReg.cpp index 8af257bf7..49b39a545 100644 --- a/codes/visual/src/VisualTaskReg.cpp +++ b/codes/visual/src/VisualTaskReg.cpp @@ -37,7 +37,6 @@ License #include "Lusgs.h" #include "Lhs.h" #include "FieldManager.h" -#include "FieldWrap.h" #include "SolverState.h" #include "Zone.h" #include "Grid.h" From 49bcb74964e273e8c001506f6b65774b8bbd995e Mon Sep 17 00:00:00 2001 From: eric Date: Fri, 2 Oct 2026 11:08:47 +0800 Subject: [PATCH 13/13] Revert "continue" This reverts commit 3ab4bbf7186254aa34abf6b2ab0e5b1f6c863c0e. --- codes/uins/include/UINsInvterm.h | 2 ++ codes/uins/include/UINsLimiter.h | 1 + codes/uins/src/UINsInvterm.cpp | 2 +- codes/uins/src/UINsLimiter.cpp | 6 ++++++ codes/uns/src/UNsInvFlux.cpp | 2 +- codes/uns/src/UNsLimiter.cpp | 2 ++ codes/usolver/include/ULimiter.h | 23 ++++++++--------------- codes/usolver/src/ULimiter.cpp | 26 +++++++++++++++----------- codes/uturb/include/UTurbLimiter.h | 1 + codes/uturb/src/UTurbInvFlux.cpp | 2 +- codes/uturb/src/UTurbLimiter.cpp | 6 ++++++ codes/visual/src/VisualTaskReg.cpp | 1 + 12 files changed, 45 insertions(+), 29 deletions(-) diff --git a/codes/uins/include/UINsInvterm.h b/codes/uins/include/UINsInvterm.h index 6b8380737..c8d88f20f 100644 --- a/codes/uins/include/UINsInvterm.h +++ b/codes/uins/include/UINsInvterm.h @@ -65,6 +65,8 @@ class UINsInvterm : public INsInvterm void PrepareFaceValue(); void PrepareProFaceValue(); void CalcPreGrad(); + //void CalcINsinvTerm(); + //void UpdateFaceInvFlux(); void ReadTmp(); public: void GetQlQrField(); diff --git a/codes/uins/include/UINsLimiter.h b/codes/uins/include/UINsLimiter.h index 0af5464c3..1519d2201 100644 --- a/codes/uins/include/UINsLimiter.h +++ b/codes/uins/include/UINsLimiter.h @@ -39,6 +39,7 @@ class INsLimiter : public Limiter { public: INsLimiter(); + ~INsLimiter() override; }; EndNameSpace diff --git a/codes/uins/src/UINsInvterm.cpp b/codes/uins/src/UINsInvterm.cpp index d686ead97..c8a641ce5 100644 --- a/codes/uins/src/UINsInvterm.cpp +++ b/codes/uins/src/UINsInvterm.cpp @@ -54,7 +54,7 @@ BeginNameSpace(ONEFLOW) UINsInvterm::UINsInvterm() { limiter = new INsLimiter(); - limf = limiter->limf.get(); + limf = limiter->limf; } UINsInvterm::~UINsInvterm() diff --git a/codes/uins/src/UINsLimiter.cpp b/codes/uins/src/UINsLimiter.cpp index 522e91bc1..c74cb53a2 100644 --- a/codes/uins/src/UINsLimiter.cpp +++ b/codes/uins/src/UINsLimiter.cpp @@ -102,7 +102,13 @@ void INsLimField::BcQlQrFix() INsLimiter::INsLimiter() { + limf = new INsLimField(); limflag = ctrl.ilim; } +INsLimiter::~INsLimiter() +{ + delete limf; +} + EndNameSpace diff --git a/codes/uns/src/UNsInvFlux.cpp b/codes/uns/src/UNsInvFlux.cpp index 0fb006112..b85e9b8c7 100644 --- a/codes/uns/src/UNsInvFlux.cpp +++ b/codes/uns/src/UNsInvFlux.cpp @@ -54,7 +54,7 @@ BeginNameSpace( ONEFLOW ) UNsInvFlux::UNsInvFlux() { limiter = new NsLimiter(); - limf = limiter->limf.get(); + limf = limiter->limf; } UNsInvFlux::~UNsInvFlux() diff --git a/codes/uns/src/UNsLimiter.cpp b/codes/uns/src/UNsLimiter.cpp index 83bac143b..097601955 100644 --- a/codes/uns/src/UNsLimiter.cpp +++ b/codes/uns/src/UNsLimiter.cpp @@ -97,11 +97,13 @@ void NsLimField::BcQlQrFix() NsLimiter::NsLimiter() { + limf = new NsLimField(); limflag = ctrl.ilim; } NsLimiter::~NsLimiter() { + delete limf; } EndNameSpace diff --git a/codes/usolver/include/ULimiter.h b/codes/usolver/include/ULimiter.h index 2a874a42a..5c7caea0f 100644 --- a/codes/usolver/include/ULimiter.h +++ b/codes/usolver/include/ULimiter.h @@ -24,7 +24,6 @@ License #pragma once #include "HXDefine.h" #include "HXArray.h" -#include BeginNameSpace( ONEFLOW ) @@ -44,21 +43,15 @@ class Lim public: Lim(); ~Lim(); - public: - // Non-owning pointers (managed by FieldManager/Grid) RealField *q, *dqdx, *dqdy, *dqdz; RealField *limiter; - RealField *qf1, *qf2; + RealField * minvf, * maxvf; Real minv1, minv2, maxv1, maxv2; Real dqdx1, dqdy1, dqdz1; Real dqdx2, dqdy2, dqdz2; Real lim1, lim2; Real qmin, qmax; - - // Owned fields managed by RAII - std::unique_ptr< RealField > minvf; - std::unique_ptr< RealField > maxvf; }; using CheckFun = bool ( * )( RealField & ); @@ -68,7 +61,6 @@ class LimField public: LimField(); virtual ~LimField(); - public: virtual void Init(){}; Real ModifyLimiter( Real phil, Real phir ); @@ -76,32 +68,33 @@ class LimField void CalcFaceValueWeighted(); void GetQlQr(); virtual void BcQlQrFix(); - public: int nEqu; - // Non-owning pointers MRField * q; MRField * dqdx, * dqdy, * dqdz; MRField * limiter; + MRField * qf1, * qf2; CheckFun ckfun; }; + class Limiter { public: Limiter(); virtual ~Limiter(); - public: - std::unique_ptr< Lim > lim; - std::unique_ptr< LimField > limf; + Lim * lim; + LimField * limf; int limflag; - public: + void Alloc(); + void DeAlloc(); void SetInitValue(); void CalcLimiter(); void CalcLimiterScalar(); + void CalcZeroLimiter(); void CalcNoLimiter(); void CalcBarthLimiter(); diff --git a/codes/usolver/src/ULimiter.cpp b/codes/usolver/src/ULimiter.cpp index 8e5166c2e..d96df47aa 100644 --- a/codes/usolver/src/ULimiter.cpp +++ b/codes/usolver/src/ULimiter.cpp @@ -350,24 +350,19 @@ void LimField::CalcFaceValueWeighted() Limiter::Limiter() { - lim = std::make_unique< Lim >(); - limf = std::make_unique< LimField >(); + lim = new Lim(); } Limiter::~Limiter() { - // unique_ptr handles cleanup automatically + delete lim; } void Limiter::CalcLimiter() { ug.Init(); limf->Init(); - - // Replace manual Alloc() with RAII allocation - lim->minvf = std::make_unique< RealField >( ug.nTCell ); - lim->maxvf = std::make_unique< RealField >( ug.nTCell ); - + Alloc(); for ( int iEqu = 0; iEqu < limf->nEqu; ++ iEqu ) { lim->limiter = & ( * limf->limiter )[ iEqu ]; @@ -378,10 +373,19 @@ void Limiter::CalcLimiter() this->SetInitValue(); this->CalcLimiterScalar(); } + DeAlloc(); +} - // Replace manual DeAlloc() with RAII release to match original lifecycle - lim->minvf.reset(); - lim->maxvf.reset(); +void Limiter::Alloc() +{ + lim->minvf = new RealField( ug.nTCell ); + lim->maxvf = new RealField( ug.nTCell ); +} + +void Limiter::DeAlloc() +{ + delete lim->minvf; + delete lim->maxvf; } void Limiter::SetInitValue() diff --git a/codes/uturb/include/UTurbLimiter.h b/codes/uturb/include/UTurbLimiter.h index c3c7e92b1..a63edf7dc 100644 --- a/codes/uturb/include/UTurbLimiter.h +++ b/codes/uturb/include/UTurbLimiter.h @@ -38,6 +38,7 @@ class TurbLimiter : public Limiter { public: TurbLimiter(); + ~TurbLimiter() override; }; EndNameSpace diff --git a/codes/uturb/src/UTurbInvFlux.cpp b/codes/uturb/src/UTurbInvFlux.cpp index dce5a46b9..e34672bc5 100644 --- a/codes/uturb/src/UTurbInvFlux.cpp +++ b/codes/uturb/src/UTurbInvFlux.cpp @@ -42,7 +42,7 @@ UTurbInvFlux::UTurbInvFlux() limiter = new TurbLimiter(); nslimiter = new NsLimiter(); nslimiter->limflag = turbcom.tns_ilim; - limf = limiter->limf.get(); + limf = limiter->limf; limiter->limflag = turbcom.turb_ilim; } diff --git a/codes/uturb/src/UTurbLimiter.cpp b/codes/uturb/src/UTurbLimiter.cpp index 8e9aec457..b43d8bb88 100644 --- a/codes/uturb/src/UTurbLimiter.cpp +++ b/codes/uturb/src/UTurbLimiter.cpp @@ -62,7 +62,13 @@ void TurbLimField::Init() TurbLimiter::TurbLimiter() { + limf = new TurbLimField(); limflag = ILMT_ZERO; } +TurbLimiter::~TurbLimiter() +{ + delete limf; +} + EndNameSpace diff --git a/codes/visual/src/VisualTaskReg.cpp b/codes/visual/src/VisualTaskReg.cpp index 49b39a545..8af257bf7 100644 --- a/codes/visual/src/VisualTaskReg.cpp +++ b/codes/visual/src/VisualTaskReg.cpp @@ -37,6 +37,7 @@ License #include "Lusgs.h" #include "Lhs.h" #include "FieldManager.h" +#include "FieldWrap.h" #include "SolverState.h" #include "Zone.h" #include "Grid.h"