From bf9d74ba8bf6e6e6ab12bbc600d11be731432685 Mon Sep 17 00:00:00 2001 From: Mark Olesen <Mark.Olesen@esi-group.com> Date: Thu, 6 Jun 2019 09:46:31 +0200 Subject: [PATCH] ENH: increase robustness of PrecisionAdaptor - overload the ref() method to allow modification of the referenced (non-const) field directly. Same as constCast(), but less typing and less prone to error. - construct ConstPrecisionAdaptor from tmp for improved efficiency. --- .../Field/PrecisionAdaptor/PrecisionAdaptor.H | 103 ++++++++++++++++-- .../lduMatrix/solvers/GAMG/GAMGSolverSolve.C | 17 +-- .../matrices/lduMatrix/solvers/PBiCG/PBiCG.C | 2 +- .../lduMatrix/solvers/PBiCGStab/PBiCGStab.C | 4 +- .../matrices/lduMatrix/solvers/PCG/PCG.C | 2 +- .../solvers/smoothSolver/smoothSolver.C | 2 +- .../faScalarMatrix/faScalarMatrix.C | 1 - .../fvMatrices/fvMatrix/fvMatrixSolve.C | 4 +- .../fvScalarMatrix/fvScalarMatrix.C | 4 +- 9 files changed, 107 insertions(+), 32 deletions(-) diff --git a/src/OpenFOAM/fields/Fields/Field/PrecisionAdaptor/PrecisionAdaptor.H b/src/OpenFOAM/fields/Fields/Field/PrecisionAdaptor/PrecisionAdaptor.H index 80f7dbc464f..0c33ed73886 100644 --- a/src/OpenFOAM/fields/Fields/Field/PrecisionAdaptor/PrecisionAdaptor.H +++ b/src/OpenFOAM/fields/Fields/Field/PrecisionAdaptor/PrecisionAdaptor.H @@ -49,28 +49,85 @@ class ConstPrecisionAdaptor : public tmp<Field<Type>> { + // Private Member Functions + + //- Copy in field + void copyInput(const Field<InputType>& input) + { + this->clear(); + + Field<Type>* p = new Field<Type>(input.size()); + this->reset(p); + std::copy(input.cbegin(), input.cend(), p->begin()); + } + + //- Construct from tmp Field, copy/move as required + void moveInput(tmp<Field<InputType>>& input) + { + if (std::is_same<Type, InputType>::value) + { + auto& tinput = reinterpret_cast<tmp<FieldType>&>(input); + + if (tinput.isTmp()) + { + this->clear(); + this->swap(tinput); + } + else + { + this->cref(tinput.cref()); + } + } + else + { + this->copyInput(input()); + } + input.clear(); + } + + public: + //- The adapted field type + typedef Field<Type> FieldType; + + // Constructors - //- Construct from InputType + //- Construct from Field<InputType>, copying on input as required ConstPrecisionAdaptor(const Field<InputType>& input) : tmp<Field<Type>>() { if (std::is_same<Type, InputType>::value) { - // Set reference - cast for compiler to handle different types - this->cref(reinterpret_cast<const Field<Type>&>(input)); + this->cref(reinterpret_cast<const FieldType&>(input)); } else { - this->reset(new Field<Type>(input.size())); - std::copy(input.cbegin(), input.cend(), this->ref().begin()); + this->copyInput(input); } } + //- Construct from tmp Field, copy/move as required + ConstPrecisionAdaptor(tmp<Field<InputType>>&& input) + : + tmp<Field<Type>>() + { + this->moveInput(input); + } + + + //- Construct from tmp Field, copy/move as required + ConstPrecisionAdaptor(const tmp<Field<InputType>>& input) + : + tmp<Field<Type>>() + { + this->moveInput(const_cast<tmp<Field<InputType>>&>(input)); + } + + // Member Functions //- Return the field @@ -82,7 +139,7 @@ public: { if (std::is_same<Type, InputType>::value) { - return reinterpret_cast<const Field<Type>&>(input); + return reinterpret_cast<const FieldType&>(input); } else { @@ -106,8 +163,25 @@ class PrecisionAdaptor Field<InputType>& ref_; + // Private Member Functions + + //- Copy in field + void copyInput(const Field<InputType>& input) + { + this->clear(); + + Field<Type>* p = new Field<Type>(input.size()); + this->reset(p); + std::copy(input.cbegin(), input.cend(), p->begin()); + } + + public: + //- The adapted field type + typedef Field<Type> FieldType; + + // Constructors //- Construct from Field<InputType>, copying on input as required @@ -118,13 +192,11 @@ public: { if (std::is_same<Type, InputType>::value) { - // Set reference - cast for compiler to handle different types - this->cref(reinterpret_cast<const Field<Type>&>(input)); + this->cref(reinterpret_cast<const FieldType&>(input)); } else { - this->reset(new Field<Type>(input.size())); - std::copy(input.cbegin(), input.cend(), this->ref().begin()); + this->copyInput(input); } } @@ -134,11 +206,20 @@ public: { if (this->isTmp()) { - const Field<Type>& store = this->cref(); + const FieldType& store = this->cref(); ref_.resize(store.size()); std::copy(store.cbegin(), store.cend(), ref_.begin()); } } + + + // Member Functions + + //- Allow modification without const-ref check + FieldType& ref() + { + return this->constCast(); + } }; diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverSolve.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverSolve.C index 0184d34ca08..25fc7a84814 100644 --- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverSolve.C +++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverSolve.C @@ -41,7 +41,7 @@ Foam::solverPerformance Foam::GAMGSolver::solve ) const { PrecisionAdaptor<solveScalar, scalar> tpsi(psi_s); - solveScalarField& psi = tpsi.constCast(); + solveScalarField& psi = tpsi.ref(); ConstPrecisionAdaptor<solveScalar, scalar> tsource(source); @@ -581,21 +581,16 @@ void Foam::GAMGSolver::solveCoarsestLevel { const label coarsestLevel = matrixLevels_.size() - 1; - label coarseComm = matrixLevels_[coarsestLevel].mesh().comm(); + const label coarseComm = matrixLevels_[coarsestLevel].mesh().comm(); if (directSolveCoarsest_) { - PrecisionAdaptor<scalar, solveScalar> tcorrField - ( - coarsestCorrField - ); + PrecisionAdaptor<scalar, solveScalar> tcorrField(coarsestCorrField); + coarsestLUMatrixPtr_->solve ( - tcorrField.constCast(), - ConstPrecisionAdaptor<scalar, solveScalar> - ( - coarsestSource - )() + tcorrField.ref(), + ConstPrecisionAdaptor<scalar, solveScalar>(coarsestSource)() ); } //else if diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCG/PBiCG.C b/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCG/PBiCG.C index 9545b9cf893..65371df0129 100644 --- a/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCG/PBiCG.C +++ b/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCG/PBiCG.C @@ -73,7 +73,7 @@ Foam::solverPerformance Foam::PBiCG::solve ) const { PrecisionAdaptor<solveScalar, scalar> tpsi(psi_s); - solveScalarField& psi = tpsi.constCast(); + solveScalarField& psi = tpsi.ref(); // --- Setup class containing solver performance data solverPerformance solverPerf diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCGStab/PBiCGStab.C b/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCGStab/PBiCGStab.C index 7ec60707c1b..2694a7c757b 100644 --- a/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCGStab/PBiCGStab.C +++ b/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCGStab/PBiCGStab.C @@ -282,11 +282,9 @@ Foam::solverPerformance Foam::PBiCGStab::solve ) const { PrecisionAdaptor<solveScalar, scalar> tpsi(psi_s); - solveScalarField& psi = tpsi.constCast(); - return scalarSolve ( - psi, + tpsi.ref(), ConstPrecisionAdaptor<solveScalar, scalar>(source)(), cmpt ); diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/PCG/PCG.C b/src/OpenFOAM/matrices/lduMatrix/solvers/PCG/PCG.C index 5c408d02dae..5131df1756b 100644 --- a/src/OpenFOAM/matrices/lduMatrix/solvers/PCG/PCG.C +++ b/src/OpenFOAM/matrices/lduMatrix/solvers/PCG/PCG.C @@ -220,7 +220,7 @@ Foam::solverPerformance Foam::PCG::solve PrecisionAdaptor<solveScalar, scalar> tpsi(psi_s); return scalarSolve ( - tpsi.constCast(), + tpsi.ref(), ConstPrecisionAdaptor<solveScalar, scalar>(source)(), cmpt ); diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/smoothSolver/smoothSolver.C b/src/OpenFOAM/matrices/lduMatrix/solvers/smoothSolver/smoothSolver.C index 47e11f4fdf3..65745e6d874 100644 --- a/src/OpenFOAM/matrices/lduMatrix/solvers/smoothSolver/smoothSolver.C +++ b/src/OpenFOAM/matrices/lduMatrix/solvers/smoothSolver/smoothSolver.C @@ -86,7 +86,7 @@ Foam::solverPerformance Foam::smoothSolver::solve ) const { PrecisionAdaptor<solveScalar, scalar> tpsi(psi_s); - solveScalarField& psi = tpsi.constCast(); + solveScalarField& psi = tpsi.ref(); // Setup class containing solver performance data solverPerformance solverPerf(typeName, fieldName_); diff --git a/src/finiteArea/faMatrices/faScalarMatrix/faScalarMatrix.C b/src/finiteArea/faMatrices/faScalarMatrix/faScalarMatrix.C index b7eefba1172..21f0a4dc2d7 100644 --- a/src/finiteArea/faMatrices/faScalarMatrix/faScalarMatrix.C +++ b/src/finiteArea/faMatrices/faScalarMatrix/faScalarMatrix.C @@ -119,7 +119,6 @@ Foam::tmp<Foam::scalarField> Foam::faMatrix<Foam::scalar>::residual() const ); ConstPrecisionAdaptor<scalar, solveScalar> tres_s(tres); - addBoundarySource(tres_s.ref()); return tres_s; diff --git a/src/finiteVolume/fvMatrices/fvMatrix/fvMatrixSolve.C b/src/finiteVolume/fvMatrices/fvMatrix/fvMatrixSolve.C index dec7e4b1f32..1d37d6d73ce 100644 --- a/src/finiteVolume/fvMatrices/fvMatrix/fvMatrixSolve.C +++ b/src/finiteVolume/fvMatrices/fvMatrix/fvMatrixSolve.C @@ -184,7 +184,7 @@ Foam::SolverPerformance<Type> Foam::fvMatrix<Type>::solveSegregated bouCoeffsCmpt, interfaces, psiCmpt_ss(), - sourceCmpt_ss.constCast(), + sourceCmpt_ss.ref(), cmpt ); @@ -194,7 +194,7 @@ Foam::SolverPerformance<Type> Foam::fvMatrix<Type>::solveSegregated bouCoeffsCmpt, interfaces, psiCmpt_ss(), - sourceCmpt_ss.constCast(), + sourceCmpt_ss.ref(), cmpt ); } diff --git a/src/finiteVolume/fvMatrices/fvScalarMatrix/fvScalarMatrix.C b/src/finiteVolume/fvMatrices/fvScalarMatrix/fvScalarMatrix.C index 1d15cbb7871..ba5a842267c 100644 --- a/src/finiteVolume/fvMatrices/fvScalarMatrix/fvScalarMatrix.C +++ b/src/finiteVolume/fvMatrices/fvScalarMatrix/fvScalarMatrix.C @@ -215,8 +215,10 @@ Foam::tmp<Foam::scalarField> Foam::fvMatrix<Foam::scalar>::residual() const 0 ) ); + ConstPrecisionAdaptor<scalar, solveScalar> tres_s(tres); - addBoundarySource(tres_s.constCast()); + addBoundarySource(tres_s.ref()); + return tres_s; } -- GitLab