diff --git a/src/OpenFOAM/db/typeInfo/typeInfo.H b/src/OpenFOAM/db/typeInfo/typeInfo.H index c6897a2064..5d9157d7b0 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 . -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: - \code - refCast(r) - \endcode - wraps dynamic_cast to handle failed casts and generate a FatalError. - - The isA function: + The isA functions: \code isA(obj) + isA_constCast(obj) \endcode - returns const pointer to the cast object, nullptr if cast is not possible - (can be tested as a bool). + which return const or non-const pointers to the cast object, + nullptr if cast is not possible (can be tested as a bool). + + The reference type cast template function: + \code + refCast(obj) + refConstCast(obj) + \endcode + 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 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 +inline Type* isA_constCast(const U& obj) +{ + const U* p = &obj; + return const_cast(dynamic_cast(p)); +} + + //- Check if typeid of the object and \c Type are identical template 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 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 +inline Type& refConstCast(const U& obj) +{ + const U* p = &obj; + const Type* casted = dynamic_cast(p); + + if (!casted) + { + FatalErrorInFunction + << "Attempt to cast type " << obj.type() + << " to type " << Type::typeName + << abort(FatalError); + } + + return const_cast(*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 struct isAOp diff --git a/src/dynamicFaMesh/interfaceTrackingFvMesh/functionObjects/writeFreeSurface/writeFreeSurface.C b/src/dynamicFaMesh/interfaceTrackingFvMesh/functionObjects/writeFreeSurface/writeFreeSurface.C index 93277dbaa3..900c223b8a 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 - auto* itm = - const_cast - ( - isA(mesh_) - ); + auto* itm = isA_constCast(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 a659bcf4c9..0039200efd 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 auto* itm = - const_cast + isA_constCast ( - isA(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 0128fa3c6a..2759e5dafa 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(intf); + const auto* ppp = isA(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(intf); + const auto* ppp = isA(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(intf); + const auto* ppp = isA(intf); if (ppp) { const label nbrColour = procColours[ppp->neighbProcNo()]; @@ -603,11 +603,11 @@ Foam::distributedDILUPreconditioner::distributedDILUPreconditioner << endl; } } - else //if (isA(intf)) + else //if (isA(intf)) { haveGlobalCoupled = true; - const auto* AMIpp = isA(intf); + const auto* AMIpp = isA(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(intf); + const auto* AMIpp = isA(intf); if (AMIpp) { nbrInti = AMIpp->neighbPatchID(); } - const auto* cycpp = isA(intf); + const auto* cycpp = isA(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 b655785b1d..c1a3888b2b 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(patches[inti]) + && !isA(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 5f5d119e68..7511c49949 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(mesh)) + const fvMesh* fvMeshPtr = nullptr; + if (debug && (fvMeshPtr = isA(mesh)) != nullptr) { - const auto& fvmesh = dynamicCast(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(); }