From 92c329a8a9daedb4ea619a82993a85eb23596053 Mon Sep 17 00:00:00 2001 From: Mark Olesen <Mark.Olesen@esi-group.com> Date: Fri, 12 Apr 2024 11:32:55 +0200 Subject: [PATCH] ENH: add const_cast variants for isA<> and refCast<> - an example of the new, more succinct refConstCast version: auto& abc = refConstCast<adjointVectorBoundaryCondition>(Uab); older: adjointVectorBoundaryCondition& abc = refCast<adjointVectorBoundaryCondition> ( const_cast<fvPatchVectorField&>(Uab) ); or: adjointVectorBoundaryCondition& abc = const_cast<adjointVectorBoundaryCondition&> ( refCast<const adjointVectorBoundaryCondition>(Uab) ); - an example of the new, more succinct isA_constCast version: auto* acapPtr = isA_constCast<fieldType>(abf[patchi]); if (acapPtr) { auto& acap = *acapPtr; ... } older: if (isA<fieldType>(abf[patchi])) { fieldType& acap = const_cast<fieldType&> ( refCast<const fieldType>(abf[patchi]) ); ... } STYLE: remove spurious 'const' qualifier from isA<> use --- src/OpenFOAM/db/typeInfo/typeInfo.H | 71 ++++++++++++++----- .../writeFreeSurface/writeFreeSurface.C | 12 ++-- .../freeSurfacePressureFvPatchScalarField.C | 14 ++-- .../distributedDILUPreconditioner.C | 14 ++-- .../processorColour.C | 2 +- .../surface/cutting/cuttingPlaneCuts.C | 31 ++++---- 6 files changed, 84 insertions(+), 60 deletions(-) diff --git a/src/OpenFOAM/db/typeInfo/typeInfo.H b/src/OpenFOAM/db/typeInfo/typeInfo.H index c6897a20644..5d9157d7b00 100644 --- a/src/OpenFOAM/db/typeInfo/typeInfo.H +++ b/src/OpenFOAM/db/typeInfo/typeInfo.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2018-2023 OpenCFD Ltd. + Copyright (C) 2018-2024 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -24,9 +24,6 @@ License You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. -Typedef - Foam::typeInfo - Description Basic run-time type information using word as the type's name. Used to enhance the standard RTTI to cover I/O. @@ -36,18 +33,20 @@ Description type() \endcode - The reference type cast template function: + The isA functions: \code - refCast<Type>(r) + isA<Type>(obj) + isA_constCast<Type>(obj) \endcode - wraps dynamic_cast to handle failed casts and generate a FatalError. + which return const or non-const pointers to the cast object, + nullptr if cast is not possible (can be tested as a bool). - The isA function: + The reference type cast template function: \code - isA<Type>(obj) + refCast<Type>(obj) + refConstCast<Type>(obj) \endcode - returns const pointer to the cast object, nullptr if cast is not possible - (can be tested as a bool). + wraps dynamic_cast to handle failed casts and generate a FatalError. \*---------------------------------------------------------------------------*/ @@ -80,9 +79,9 @@ namespace Foam // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // -//- Check if dynamic_cast to \c Type is possible. -// The template types should \em not include any \c const qualifier. -// \returns const pointer to cast object, nullptr if cast is not possible +//- Attempt dynamic_cast to \c Type. +// \note The template types should \em not include any \c const qualifier. +// \return const pointer to cast object, nullptr if cast is not possible template<class Type, class U> inline const Type* isA(const U& obj) { @@ -91,6 +90,17 @@ inline const Type* isA(const U& obj) } +//- Attempt dynamic_cast to \c Type followed by a const_cast of the result. +// \note The template types should \em not include any \c const qualifier. +// \return non-const pointer to cast object, nullptr if cast is not possible +template<class Type, class U> +inline Type* isA_constCast(const U& obj) +{ + const U* p = &obj; + return const_cast<Type*>(dynamic_cast<const Type*>(p)); +} + + //- Check if typeid of the object and \c Type are identical template<class Type, class U> inline bool isType(const U& obj) @@ -139,10 +149,10 @@ inline Type& dynamicCast(U& obj, const dictionary& dict) } -//- A dynamic_cast (for references). -//- Generates a FatalError on failed casts and uses the virtual type() -//- method for error messages. -// Respects the constness of the template types. +//- A dynamic_cast (for references) to \c Type reference. +// \note Respects the constness of the template types. +// \return reference to cast object, or FatalError on failed casts +// and use the virtual type() method for error messages. template<class Type, class U> inline Type& refCast(U& obj) { @@ -161,6 +171,29 @@ inline Type& refCast(U& obj) } +//- A dynamic_cast (for const references) to \c Type reference, +//- followed by a const_cast of the result. +// \note The template types should \em not include any \c const qualifier. +// \return non-const reference to cast object, or FatalError on failed casts +// and use the virtual type() method for error messages. +template<class Type, class U> +inline Type& refConstCast(const U& obj) +{ + const U* p = &obj; + const Type* casted = dynamic_cast<const Type*>(p); + + if (!casted) + { + FatalErrorInFunction + << "Attempt to cast type " << obj.type() + << " to type " << Type::typeName + << abort(FatalError); + } + + return const_cast<Type&>(*casted); +} + + //- A dynamic_cast (for references) that generates FatalIOError on failed casts, //- uses the virtual type() method for error messages. // Respects the constness of the template types. @@ -205,6 +238,8 @@ inline Type& refCast(U& obj, const label index) } +// * * * * * * * * * * * * * * * * Functors * * * * * * * * * * * * * * * * // + //- Test if dynamic_cast to Type is possible, as a functor template<class Type> struct isAOp diff --git a/src/dynamicFaMesh/interfaceTrackingFvMesh/functionObjects/writeFreeSurface/writeFreeSurface.C b/src/dynamicFaMesh/interfaceTrackingFvMesh/functionObjects/writeFreeSurface/writeFreeSurface.C index 93277dbaa33..900c223b8aa 100644 --- a/src/dynamicFaMesh/interfaceTrackingFvMesh/functionObjects/writeFreeSurface/writeFreeSurface.C +++ b/src/dynamicFaMesh/interfaceTrackingFvMesh/functionObjects/writeFreeSurface/writeFreeSurface.C @@ -51,19 +51,15 @@ namespace functionObjects void Foam::functionObjects::writeFreeSurface::writeData() { // refCast<interfaceTrackingFvMesh> - auto* itm = - const_cast<interfaceTrackingFvMesh*> - ( - isA<interfaceTrackingFvMesh>(mesh_) - ); + auto* itm = isA_constCast<interfaceTrackingFvMesh>(mesh_); - if (!itm) + if (itm) { - // FatalError + itm->writeVTKControlPoints(); } else { - itm->writeVTKControlPoints(); + // FatalError } } diff --git a/src/dynamicFaMesh/interfaceTrackingFvMesh/fvPatchFields/freeSurfacePressure/freeSurfacePressureFvPatchScalarField.C b/src/dynamicFaMesh/interfaceTrackingFvMesh/fvPatchFields/freeSurfacePressure/freeSurfacePressureFvPatchScalarField.C index a659bcf4c9c..0039200efd2 100644 --- a/src/dynamicFaMesh/interfaceTrackingFvMesh/fvPatchFields/freeSurfacePressure/freeSurfacePressureFvPatchScalarField.C +++ b/src/dynamicFaMesh/interfaceTrackingFvMesh/fvPatchFields/freeSurfacePressure/freeSurfacePressureFvPatchScalarField.C @@ -139,22 +139,22 @@ void Foam::freeSurfacePressureFvPatchScalarField::updateCoeffs() // refCast<interfaceTrackingFvMesh> auto* itm = - const_cast<interfaceTrackingFvMesh*> + isA_constCast<interfaceTrackingFvMesh> ( - isA<interfaceTrackingFvMesh>(patch().boundaryMesh().mesh()) + patch().boundaryMesh().mesh() ); - if (!itm) - { - // FatalError - } - else + if (itm) { operator== ( pa_ + itm->freeSurfacePressureJump() ); } + else + { + // FatalError + } fixedValueFvPatchScalarField::updateCoeffs(); } diff --git a/src/meshTools/matrices/lduMatrix/preconditioners/distributedDILUPreconditioner/distributedDILUPreconditioner.C b/src/meshTools/matrices/lduMatrix/preconditioners/distributedDILUPreconditioner/distributedDILUPreconditioner.C index 0128fa3c6ae..2759e5dafa9 100644 --- a/src/meshTools/matrices/lduMatrix/preconditioners/distributedDILUPreconditioner/distributedDILUPreconditioner.C +++ b/src/meshTools/matrices/lduMatrix/preconditioners/distributedDILUPreconditioner/distributedDILUPreconditioner.C @@ -189,7 +189,7 @@ void Foam::distributedDILUPreconditioner::receive for (const label inti : selectedInterfaces) { const auto& intf = interfaces[inti].interface(); - const auto* ppp = isA<const processorLduInterface>(intf); + const auto* ppp = isA<processorLduInterface>(intf); auto& recvBuf = recvBufs_[inti]; recvBuf.resize_nocopy(interfaceBouCoeffs[inti].size()); @@ -221,7 +221,7 @@ void Foam::distributedDILUPreconditioner::send for (const label inti : selectedInterfaces) { const auto& intf = interfaces[inti].interface(); - const auto* ppp = isA<const processorLduInterface>(intf); + const auto* ppp = isA<processorLduInterface>(intf); const auto& faceCells = intf.faceCells(); auto& sendBuf = sendBufs_[inti]; @@ -581,7 +581,7 @@ Foam::distributedDILUPreconditioner::distributedDILUPreconditioner if (interfaces.set(inti)) { const auto& intf = interfaces[inti].interface(); - const auto* ppp = isA<const processorLduInterface>(intf); + const auto* ppp = isA<processorLduInterface>(intf); if (ppp) { const label nbrColour = procColours[ppp->neighbProcNo()]; @@ -603,11 +603,11 @@ Foam::distributedDILUPreconditioner::distributedDILUPreconditioner << endl; } } - else //if (isA<const cyclicAMILduInterface>(intf)) + else //if (isA<cyclicAMILduInterface>(intf)) { haveGlobalCoupled = true; - const auto* AMIpp = isA<const cyclicAMILduInterface>(intf); + const auto* AMIpp = isA<cyclicAMILduInterface>(intf); if (AMIpp) { //const auto& AMI = @@ -681,12 +681,12 @@ Foam::distributedDILUPreconditioner::distributedDILUPreconditioner const auto& intf = interfaces[inti].interface(); label nbrInti = -1; - const auto* AMIpp = isA<const cyclicAMILduInterface>(intf); + const auto* AMIpp = isA<cyclicAMILduInterface>(intf); if (AMIpp) { nbrInti = AMIpp->neighbPatchID(); } - const auto* cycpp = isA<const cyclicLduInterface>(intf); + const auto* cycpp = isA<cyclicLduInterface>(intf); if (cycpp) { nbrInti = cycpp->neighbPatchID(); diff --git a/src/meshTools/matrices/lduMatrix/preconditioners/distributedDILUPreconditioner/processorColour.C b/src/meshTools/matrices/lduMatrix/preconditioners/distributedDILUPreconditioner/processorColour.C index b655785b1d4..c1a3888b2b7 100644 --- a/src/meshTools/matrices/lduMatrix/preconditioners/distributedDILUPreconditioner/processorColour.C +++ b/src/meshTools/matrices/lduMatrix/preconditioners/distributedDILUPreconditioner/processorColour.C @@ -279,7 +279,7 @@ Foam::label Foam::processorColour::cellColour if ( patches.set(inti) - && !isA<const processorLduInterface>(patches[inti]) + && !isA<processorLduInterface>(patches[inti]) ) { // 'global' interface. Seed faceCells with patch index diff --git a/src/sampling/surface/cutting/cuttingPlaneCuts.C b/src/sampling/surface/cutting/cuttingPlaneCuts.C index 5f5d119e681..7511c499494 100644 --- a/src/sampling/surface/cutting/cuttingPlaneCuts.C +++ b/src/sampling/surface/cutting/cuttingPlaneCuts.C @@ -160,34 +160,27 @@ Foam::label Foam::cuttingPlane::calcCellCuts } - if (debug && isA<fvMesh>(mesh)) + const fvMesh* fvMeshPtr = nullptr; + if (debug && (fvMeshPtr = isA<fvMesh>(mesh)) != nullptr) { - const auto& fvmesh = dynamicCast<const fvMesh>(mesh); - - volScalarField cCuts + auto tcellCutsDebug = volScalarField::New ( - IOobject - ( - "cuttingPlane.cellCuts", - fvmesh.time().timeName(), - fvmesh.time(), - IOobject::NO_READ, - IOobject::NO_WRITE, - IOobject::NO_REGISTER - ), - fvmesh, - dimensionedScalar(dimless, Zero) + "cuttingPlane.cellCuts", + IOobjectOption::NO_REGISTER, + *fvMeshPtr, + dimensionedScalar(dimless, Foam::zero{}) ); + auto& cellCutsDebug = tcellCutsDebug.ref(); - auto& cCutsFld = cCuts.primitiveFieldRef(); + auto& fld = cellCutsDebug.primitiveFieldRef(); for (const label celli : cellCuts) { - cCutsFld[celli] = 1; + fld[celli] = 1; } - Pout<< "Writing cut types:" << cCuts.objectPath() << endl; - cCuts.write(); + Pout<< "Writing cut types:" << cellCutsDebug.objectPath() << endl; + cellCutsDebug.write(); } -- GitLab