From de91806a245dd31990cc417e855d5e2312ea786b Mon Sep 17 00:00:00 2001 From: ksaurabh-amd <> Date: Thu, 9 Oct 2025 11:53:34 +0100 Subject: [PATCH 01/18] ENH: GAMGAgglomeration: increase repeatability. Fixes #3450 --- .../pairGAMGAgglomeration/pairGAMGAgglomerate.C | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/pairGAMGAgglomeration/pairGAMGAgglomerate.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/pairGAMGAgglomeration/pairGAMGAgglomerate.C index 7da7012658..dfc6d6e257 100644 --- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/pairGAMGAgglomeration/pairGAMGAgglomerate.C +++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/pairGAMGAgglomeration/pairGAMGAgglomerate.C @@ -221,9 +221,14 @@ Foam::tmp Foam::pairGAMGAgglomeration::agglomerate auto tcoarseCellMap = tmp::New(nFineCells, -1); auto& coarseCellMap = tcoarseCellMap.ref(); + // Small tolerance to account for faces potentially having slightly + // different truncation error in their weights from run to run + // (e.g. due to offloading). If all the largest faces per cell are + // within this tolerance use the first one. This guarantees repeatability. + const scalar tol = 1E-10; + nCoarseCells = 0; label celli; - for (label cellfi=0; cellfi Foam::pairGAMGAgglomeration::agglomerate ( coarseCellMap[upperAddr[facei]] < 0 && coarseCellMap[lowerAddr[facei]] < 0 - && faceWeights[facei] > maxFaceWeight + && faceWeights[facei] > maxFaceWeight*(1.0 + tol) ) { // Match found. Pick up all the necessary data @@ -282,7 +287,7 @@ Foam::tmp Foam::pairGAMGAgglomeration::agglomerate { label facei = cellFaces[faceOs]; - if (faceWeights[facei] > clusterMaxFaceCoeff) + if (faceWeights[facei] > clusterMaxFaceCoeff*(1.0 + tol)) { clusterMatchFaceNo = facei; clusterMaxFaceCoeff = faceWeights[facei]; From 22fd0b3e7218d13f7cb2498b0346ecdb73de10b7 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Thu, 9 Oct 2025 12:03:33 +0200 Subject: [PATCH 02/18] ENH: update globalIndex::mpiGather to use MPI intrinsic/user types - add provisional support for selecting MPI_Gatherv when merging fields in the surface writers. Uses the 'gatherv' keyword [experimental] BUG: gatherv/scatterv wrappers used the incorrect data type - incorrectly checked against UPstream_basic_dataType trait instead of UPstream_dataType, which resulted in a count mismatch for user-defined types (eg, vector, tensor,...). This was not visibly active bug, since previous internal uses of gatherv were restricted to primitive types. COMP: make UPstream dataType traits size(...) constexpr - allows static asserts and/or compile-time selection of code based on size(1) --- .../UPstreamTraits/Test-UPstreamTraits.cxx | 28 ++- applications/test/surface-sampling/Make/files | 4 +- ...e-sampling.C => Test-surface-sampling.cxx} | 0 ...rfaceWriter.C => mydebugSurfaceWriter.cxx} | 70 ++++-- .../db/IOstreams/Pstreams/UPstream.txx | 36 +++- .../db/IOstreams/Pstreams/UPstreamTraits.H | 9 +- .../parallel/globalIndex/globalIndex.txx | 202 ++++++------------ src/Pstream/mpi/UPstreamGatherScatter.C | 111 ++++++++-- src/surfMesh/writers/common/surfaceWriter.C | 57 ++++- src/surfMesh/writers/common/surfaceWriter.H | 9 +- .../writers/debug/debugSurfaceWriter.C | 7 +- .../simpleFoam/squareBend/Allclean | 11 + .../simpleFoam/squareBend/system/sampling | 3 +- .../squareBend/system/samplingDebug | 6 + 14 files changed, 351 insertions(+), 202 deletions(-) rename applications/test/surface-sampling/{Test-surface-sampling.C => Test-surface-sampling.cxx} (100%) rename applications/test/surface-sampling/{mydebugSurfaceWriter.C => mydebugSurfaceWriter.cxx} (89%) create mode 100755 tutorials/incompressible/simpleFoam/squareBend/Allclean diff --git a/applications/test/UPstreamTraits/Test-UPstreamTraits.cxx b/applications/test/UPstreamTraits/Test-UPstreamTraits.cxx index d8cb032749..0f2fbc273c 100644 --- a/applications/test/UPstreamTraits/Test-UPstreamTraits.cxx +++ b/applications/test/UPstreamTraits/Test-UPstreamTraits.cxx @@ -200,7 +200,7 @@ void printTypeName() template -void printPstreamTraits(const std::string_view name = std::string_view()) +void printPstreamTraits(std::string_view name = std::string_view()) { Info<< "========" << nl; Info<< "type: "; @@ -299,6 +299,9 @@ void printPstreamTraits(const std::string_view name = std::string_view()) // Use element or component type (or byte-wise) for data type using base = typename UPstream_dataType::base; + // The sizing factor is constexpr + constexpr std::streamsize count = UPstream_dataType::size(1); + Info<< " : "; if constexpr (UseTypeName) { @@ -311,8 +314,7 @@ void printPstreamTraits(const std::string_view name = std::string_view()) Info<< " cmpt-type="; printDataTypeId(UPstream_dataType::datatype_id); - Info<< " count=" << UPstream_dataType::size(1); - Info<< nl; + Info<< " count=" << count << nl; } } @@ -362,6 +364,24 @@ void print_data_opType(BinaryOp bop, std::string_view name) } + +template +int check_simple(std::string_view name = std::string_view()) +{ + // The sizing factor is constexpr + constexpr std::streamsize count = UPstream_dataType::size(1); + + static_assert + ( + (count == 1), + "Code does not (yet) work with aggregate types" + ); + + Info<< "check_simple: " << name << ": " << count << nl; + return count; +} + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // Main program: @@ -389,6 +409,8 @@ int main() printPstreamTraits(); printPstreamTraits(); + check_simple("vector"); + printPstreamTraits(); printPstreamTraits(); printPstreamTraits(); diff --git a/applications/test/surface-sampling/Make/files b/applications/test/surface-sampling/Make/files index e6db680175..39342be581 100644 --- a/applications/test/surface-sampling/Make/files +++ b/applications/test/surface-sampling/Make/files @@ -1,4 +1,4 @@ -mydebugSurfaceWriter.C -Test-surface-sampling.C +mydebugSurfaceWriter.cxx +Test-surface-sampling.cxx EXE = $(FOAM_USER_APPBIN)/Test-surface-sampling diff --git a/applications/test/surface-sampling/Test-surface-sampling.C b/applications/test/surface-sampling/Test-surface-sampling.cxx similarity index 100% rename from applications/test/surface-sampling/Test-surface-sampling.C rename to applications/test/surface-sampling/Test-surface-sampling.cxx diff --git a/applications/test/surface-sampling/mydebugSurfaceWriter.C b/applications/test/surface-sampling/mydebugSurfaceWriter.cxx similarity index 89% rename from applications/test/surface-sampling/mydebugSurfaceWriter.C rename to applications/test/surface-sampling/mydebugSurfaceWriter.cxx index f8ec340c89..fdc88fdb4f 100644 --- a/applications/test/surface-sampling/mydebugSurfaceWriter.C +++ b/applications/test/surface-sampling/mydebugSurfaceWriter.cxx @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2022-2023 OpenCFD Ltd. + Copyright (C) 2022-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -83,12 +83,10 @@ template<> struct narrowType> typedef SymmTensor type; }; -// FIXME: Not sure why this one seems to be broken... -// -// template<> struct narrowType> -// { -// typedef Tensor type; -// }; +template<> struct narrowType> +{ + typedef Tensor type; +}; } // End namespace Foam @@ -104,12 +102,18 @@ Foam::surfaceWriters::mydebugWriter::mergeField { addProfiling(merge, "debugWriter::merge-field"); - // This is largely identical to surfaceWriter::mergeField() + // Identical to surfaceWriter::mergeField() // but with narrowing for communication - if (narrowTransfer_ && parallel_ && UPstream::parRun()) + + if constexpr (std::is_same_v, Type>) + { + // Cannot narrow tensor. Does not compile since MatrixSpace + // does not (yet) allow assigments from different Cmpt types. + } + else if (narrowTransfer_ && parallel_ && UPstream::parRun()) { // The narrowed type - typedef typename narrowType::type narrowedType; + using narrowedType = typename narrowType::type; // Ensure geometry is also merged merge(); @@ -130,14 +134,29 @@ Foam::surfaceWriters::mydebugWriter::mergeField ConstPrecisionAdaptor input(fld); PrecisionAdaptor output(allFld); - globIndex.gather - ( - input.cref(), // fld, - output.ref(), // allFld, - UPstream::msgType(), - commType_, - UPstream::worldComm - ); + if (gatherv_) + { + globIndex.mpiGather + ( + input.cref(), // fld + output.ref(), // allFld + UPstream::worldComm, + // For fallback: + commType_, + UPstream::msgType() + ); + } + else + { + globIndex.gather + ( + input.cref(), // fld + output.ref(), // allFld + UPstream::msgType(), + commType_, + UPstream::worldComm + ); + } // Commit adapted content changes input.commit(); @@ -193,8 +212,19 @@ Foam::surfaceWriters::mydebugWriter::mydebugWriter { Info<< "Using debug surface writer (" << (this->isPointData() ? "point" : "face") << " data):" - << " commsType=" << UPstream::commsTypeNames[commType_] - << " merge=" << Switch::name(enableMerge_) + << " commsType="; + + if (UPstream::parRun()) + { + if (gatherv_) Info<< "gatherv+"; + Info<< UPstream::commsTypeNames[commType_]; + } + else + { + Info<< "serial"; + } + + Info<< " merge=" << Switch::name(enableMerge_) << " write=" << Switch::name(enableWrite_) << " narrow=" << Switch::name(narrowTransfer_) << endl; diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/UPstream.txx b/src/OpenFOAM/db/IOstreams/Pstreams/UPstream.txx index 35ab5448b8..9cb9a11efc 100644 --- a/src/OpenFOAM/db/IOstreams/Pstreams/UPstream.txx +++ b/src/OpenFOAM/db/IOstreams/Pstreams/UPstream.txx @@ -343,11 +343,22 @@ void Foam::UPstream::mpiGatherv } // Nothing further to do } - else if constexpr (UPstream_basic_dataType::value) + else if constexpr (UPstream_dataType::value) { // Restrict to basic (or aliased) MPI types to avoid recalculating // the list of counts/offsets. + // The sizing factor (constexpr) must be 1 otherwise + // [recvCounts,recvOffsets] are likely incorrect + + constexpr std::streamsize count = UPstream_dataType::size(1); + + static_assert + ( + (count == 1), + "Code does not (yet) work with aggregate types" + ); + UPstream::mpi_gatherv ( sendData, @@ -356,7 +367,7 @@ void Foam::UPstream::mpiGatherv recvCounts, recvOffsets, - UPstream_basic_dataType::datatype_id, + UPstream_dataType::datatype_id, communicator ); } @@ -364,7 +375,8 @@ void Foam::UPstream::mpiGatherv { static_assert ( - stdFoam::dependent_false_v, "Only basic MPI data types" + stdFoam::dependent_false_v, + "Only basic and user data types" ); } } @@ -392,11 +404,22 @@ void Foam::UPstream::mpiScatterv } // Nothing further to do } - else if constexpr (UPstream_basic_dataType::value) + else if constexpr (UPstream_dataType::value) { // Restrict to basic (or aliased) MPI types to avoid recalculating // the list of counts/offsets. + // The sizing factor (constexpr) must be 1 otherwise + // [sendCounts,sendOffsets] are likely incorrect + + constexpr std::streamsize count = UPstream_dataType::size(1); + + static_assert + ( + (count == 1), + "Code does not (yet) work with aggregate types" + ); + UPstream::mpi_scatterv ( sendData, @@ -405,7 +428,7 @@ void Foam::UPstream::mpiScatterv recvData, recvCount, - UPstream_basic_dataType::datatype_id, + UPstream_dataType::datatype_id, communicator ); } @@ -413,7 +436,8 @@ void Foam::UPstream::mpiScatterv { static_assert ( - stdFoam::dependent_false_v, "Only basic MPI data types" + stdFoam::dependent_false_v, + "Only basic and user data types" ); } } diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/UPstreamTraits.H b/src/OpenFOAM/db/IOstreams/Pstreams/UPstreamTraits.H index ec0d3ad863..2fec935f17 100644 --- a/src/OpenFOAM/db/IOstreams/Pstreams/UPstreamTraits.H +++ b/src/OpenFOAM/db/IOstreams/Pstreams/UPstreamTraits.H @@ -354,7 +354,7 @@ struct UPstream_basic_dataType UPstream_alias_dataType::datatype_id; //- The size in terms of the number of underlying data elements - static std::streamsize size(std::streamsize n) noexcept + static constexpr std::streamsize size(std::streamsize n) noexcept { if constexpr (UPstream_alias_dataType::value) { @@ -373,7 +373,10 @@ struct UPstream_basic_dataType template<> struct UPstream_basic_dataType : UPstream_mpi_dataType { using base = void; - static std::streamsize size(std::streamsize n) noexcept { return n; } + static constexpr std::streamsize size(std::streamsize n) noexcept + { + return n; + } }; @@ -410,7 +413,7 @@ struct UPstream_dataType UPstream_any_dataType::datatype_id; //- The size in terms of the number of base data elements - static std::streamsize size(std::streamsize n) noexcept + static constexpr std::streamsize size(std::streamsize n) noexcept { if constexpr (UPstream_any_dataType::value) { diff --git a/src/OpenFOAM/parallel/globalIndex/globalIndex.txx b/src/OpenFOAM/parallel/globalIndex/globalIndex.txx index 6ada3d890c..f0b6b2615a 100644 --- a/src/OpenFOAM/parallel/globalIndex/globalIndex.txx +++ b/src/OpenFOAM/parallel/globalIndex/globalIndex.txx @@ -27,6 +27,7 @@ License \*---------------------------------------------------------------------------*/ #include "globalIndex.H" +#include // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // @@ -696,159 +697,94 @@ void Foam::globalIndex::mpiGather const UList& sendData, OutputContainer& allData, const label comm, - UPstream::commsTypes commsType, - const int tag + [[maybe_unused]] UPstream::commsTypes commsType, + [[maybe_unused]] const int tag ) const { - if (!UPstream::parRun()) + if (!UPstream::is_parallel(comm)) { // Serial: direct copy allData = sendData; return; } - // MPI_Gatherv requires contiguous data, but a byte-wise transfer can - // quickly exceed the 'int' limits used for MPI sizes/offsets. - // Thus gather label/scalar components when possible to increase the - // effective size limit. - // - // Note: cannot rely on pTraits (cmptType, nComponents) since this method - // needs to compile (and work) even with things like strings etc. - - // Single char ad hoc "enum": - // - b(yte): gather bytes - // - f(loat): gather scalars components - // - i(nt): gather label components - // - 0: gather with Pstream read/write etc. - - List recvCounts; - List recvOffsets; - - char dataMode(0); - int nCmpts(0); - - if constexpr (is_contiguous_v) + if (UPstream::master(comm)) { - if constexpr (is_contiguous_scalar::value) - { - dataMode = 'f'; - nCmpts = static_cast(sizeof(Type)/sizeof(scalar)); - } - else if constexpr (is_contiguous_label::value) - { - dataMode = 'i'; - nCmpts = static_cast(sizeof(Type)/sizeof(label)); - } - else - { - dataMode = 'b'; - nCmpts = static_cast(sizeof(Type)); - } + allData.resize_nocopy(offsets_.back()); // == totalSize() + } + else + { + allData.clear(); // zero-size on non-master + } + + if constexpr (UPstream_dataType::value) + { + // Restrict to basic (or aliased) MPI types + // - simplifies calculating counts/offsets + // and can call UPstream::mpiGatherv directly + + // The sizing factor is constexpr + constexpr std::streamsize count = UPstream_dataType::size(1); + + static_assert + ( + (count == 1), + "Code does not (yet) work with aggregate types" + ); + + List recvCounts; + List recvOffsets; - // Offsets must fit into int if (UPstream::master(comm)) { - const globalIndex& globalAddr = *this; + // Must be same as Pstream::nProcs(comm), at least on master! + // if (UPstream::nProcs(comm) != this->nProcs()) ... - if (globalAddr.totalSize() > (INT_MAX/nCmpts)) - { - // Offsets do not fit into int - revert to manual. - dataMode = 0; - } - else - { - // Must be same as Pstream::nProcs(comm), at least on master! - const label nproc = globalAddr.nProcs(); + recvCounts.resize(offsets_.size()-1); + recvOffsets.resize(offsets_.size()); - allData.resize_nocopy(globalAddr.totalSize()); + // Copy offsets + std::copy(offsets_.begin(), offsets_.end(), recvOffsets.begin()); - recvCounts.resize(nproc); - recvOffsets.resize(nproc+1); + // Calculate sizes. Currently without std::minus + std::transform + ( + offsets_.begin()+1, offsets_.end(), + offsets_.begin(), recvCounts.begin(), + std::minus<>{} + ); - for (label proci = 0; proci < nproc; ++proci) - { - recvCounts[proci] = globalAddr.localSize(proci)*nCmpts; - recvOffsets[proci] = globalAddr.localStart(proci)*nCmpts; - } - recvOffsets[nproc] = globalAddr.totalSize()*nCmpts; - - // Assign local data directly - - recvCounts[0] = 0; // ie, ignore for MPI_Gatherv - SubList(allData, globalAddr.range(0)) = - SubList(sendData, globalAddr.range(0)); - } + // FUTURE .. fix sizes and offsets by the element factor... + // if constexpr (UPstream_basic_dataType::size(1) > 1) } - // Consistent information for everyone - UPstream::broadcast(&dataMode, 1, comm); + int sendSize = static_cast(sendData.size()); + + // Note we let MPI_Gatherv copy back the local data as well... + + UPstream::mpiGatherv + ( + sendData.cdata(), + sendSize, + allData.data(), + recvCounts, + recvOffsets, + comm + ); } - - // Dispatch - switch (dataMode) + else { - case 'b': // Byte-wise - { - UPstream::mpiGatherv - ( - sendData.cdata_bytes(), - sendData.size_bytes(), - allData.data_bytes(), - recvCounts, - recvOffsets, - comm - ); - break; - } - case 'f': // Float (scalar) components - { - typedef scalar cmptType; - - UPstream::mpiGatherv - ( - reinterpret_cast(sendData.cdata()), - (sendData.size()*nCmpts), - reinterpret_cast(allData.data()), - recvCounts, - recvOffsets, - comm - ); - break; - } - case 'i': // Int (label) components - { - typedef label cmptType; - - UPstream::mpiGatherv - ( - reinterpret_cast(sendData.cdata()), - (sendData.size()*nCmpts), - reinterpret_cast(allData.data()), - recvCounts, - recvOffsets, - comm - ); - break; - } - default: // Regular (manual) gathering - { - globalIndex::gather - ( - offsets_, // needed on master only - comm, - UPstream::allProcs(comm), // All communicator ranks - sendData, - allData, - tag, - commsType - ); - break; - } - } - - if (!UPstream::master(comm)) - { - allData.clear(); // safety: zero-size on non-master + // Regular (manual) gathering + globalIndex::gather + ( + offsets_, // needed on master only + comm, + UPstream::allProcs(comm), // All communicator ranks + sendData, + allData, + tag, + commsType + ); } } diff --git a/src/Pstream/mpi/UPstreamGatherScatter.C b/src/Pstream/mpi/UPstreamGatherScatter.C index ec82a80721..d9875f7f88 100644 --- a/src/Pstream/mpi/UPstreamGatherScatter.C +++ b/src/Pstream/mpi/UPstreamGatherScatter.C @@ -28,33 +28,45 @@ License #include "Pstream.H" #include "PstreamGlobals.H" #include "UPstreamWrapping.H" +#include "vector.H" // for debugging + +#undef STRINGIFY +#undef STRING_QUOTE + +#define STRINGIFY(content) #content +#define STRING_QUOTE(input) STRINGIFY(input) // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * // -static inline bool is_basic_dataType(Foam::UPstream::dataTypes id) noexcept +namespace +{ + +inline bool is_nonAggregate(Foam::UPstream::dataTypes id) noexcept { return ( int(id) >= int(Foam::UPstream::dataTypes::Basic_begin) && int(id) < int(Foam::UPstream::dataTypes::Basic_end) + ) + || + ( + int(id) >= int(Foam::UPstream::dataTypes::User_begin) + && int(id) < int(Foam::UPstream::dataTypes::User_end) ); } -namespace -{ - -using namespace Foam; - // Local function to print some error information inline void printErrorNonIntrinsic ( const char* context, - UPstream::dataTypes dataTypeId + Foam::UPstream::dataTypes dataTypeId ) { + using namespace Foam; + FatalError << "Bad input for " << context << ": likely a programming problem\n" - << " Non-intrinsic data (" << int(dataTypeId) << ")\n" + << " Non-intrinsic/non-user data (type:" << int(dataTypeId) << ")\n" << Foam::endl; } @@ -214,19 +226,37 @@ void Foam::UPstream::mpi_gatherv { MPI_Datatype datatype = PstreamGlobals::getDataType(dataTypeId); - if - ( - FOAM_UNLIKELY - ( - !is_basic_dataType(dataTypeId) - ) - ) + // Runtime assert that we are not using aggregated data types + if (FOAM_UNLIKELY(!is_nonAggregate(dataTypeId))) { FatalErrorInFunction; printErrorNonIntrinsic("MPI_Gatherv()", dataTypeId); FatalError << Foam::abort(FatalError); } + const label np = UPstream::nProcs(communicator); + + // For total-size calculation, + // don't rely on recvOffsets being (np+1) + const int totalSize = + ( + (UPstream::master(communicator) && np > 1) + ? (recvOffsets[np-1] + recvCounts[np-1]) + : 0 + ); + + if (FOAM_UNLIKELY(UPstream::debug)) + { + Perr<< "[mpi_gatherv] :" + << " type:" << int(dataTypeId) + << " count:" << sendCount + << " total:" << totalSize + << " comm:" << communicator + << " recvCounts:" << flatOutput(recvCounts) + << " recvOffsets:" << flatOutput(recvOffsets) + << Foam::endl; + } + { PstreamDetail::gatherv ( @@ -235,6 +265,48 @@ void Foam::UPstream::mpi_gatherv datatype, communicator ); } + + // Extended debugging. Limit to master: + + #if 0 + if (FOAM_UNLIKELY(UPstream::debug)) + { + if (UPstream::master(communicator)) + { + switch (dataTypeId) + { + #undef dataPrinter + #define dataPrinter(enumType, nativeType) \ + case UPstream::dataTypes::enumType : \ + { \ + UList combined \ + ( \ + static_cast(recvData), \ + totalSize \ + ); \ + \ + Info<< "[mpi_gatherv] => " \ + "List<" STRING_QUOTE(nativeType) "> "; \ + combined.writeList(Info) << Foam::endl; \ + \ + break; \ + } + + // Some common types + dataPrinter(type_int32, int32_t); + dataPrinter(type_int64, int64_t); + dataPrinter(type_float, float); + dataPrinter(type_double, double); + dataPrinter(type_3float, floatVector); + dataPrinter(type_3double, doubleVector); + + // Some other type + default: break; + #undef dataPrinter + } + } + } + #endif } @@ -255,13 +327,8 @@ void Foam::UPstream::mpi_scatterv { MPI_Datatype datatype = PstreamGlobals::getDataType(dataTypeId); - if - ( - FOAM_UNLIKELY - ( - !is_basic_dataType(dataTypeId) - ) - ) + // Runtime assert that we are not using aggregated data types + if (FOAM_UNLIKELY(!is_nonAggregate(dataTypeId))) { FatalErrorInFunction; printErrorNonIntrinsic("MPI_Scatterv()", dataTypeId); diff --git a/src/surfMesh/writers/common/surfaceWriter.C b/src/surfMesh/writers/common/surfaceWriter.C index 59e6285427..9ca7c5dafa 100644 --- a/src/surfMesh/writers/common/surfaceWriter.C +++ b/src/surfMesh/writers/common/surfaceWriter.C @@ -201,6 +201,7 @@ Foam::surfaceWriter::surfaceWriter() isPointData_(false), verbose_(false), commType_(UPstream::commsTypes::scheduled), + gatherv_(false), nFields_(0), currTime_(), outputPath_(), @@ -218,6 +219,8 @@ Foam::surfaceWriter::surfaceWriter(const dictionary& options) options.readIfPresent("verbose", verbose_); UPstream::commsTypeNames.readIfPresent("commsType", options, commType_); + gatherv_ = false; + options.readIfPresent("gatherv", gatherv_); geometryScale_ = 1; geometryCentre_ = Zero; @@ -244,7 +247,19 @@ Foam::surfaceWriter::surfaceWriter(const dictionary& options) { Info<< "Create surfaceWriter (" << (this->isPointData() ? "point" : "face") << " data):" - << " commsType=" << UPstream::commsTypeNames[commType_] << endl; + << " commsType="; + + if (UPstream::parRun()) + { + if (gatherv_) Info<< "gatherv+"; + Info<< UPstream::commsTypeNames[commType_]; + } + else + { + Info<< "serial"; + } + + Info<< endl; } } @@ -605,14 +620,29 @@ Foam::tmp> Foam::surfaceWriter::mergeFieldTemplate : mergedSurf_.faceGlobalIndex() ); - globIndex.gather - ( - fld, - allFld, - UPstream::msgType(), - commType_, - UPstream::worldComm - ); + if (gatherv_) + { + globIndex.mpiGather + ( + fld, + allFld, + UPstream::worldComm, + // For fallback: + commType_, + UPstream::msgType() + ); + } + else + { + globIndex.gather + ( + fld, + allFld, + UPstream::msgType(), + commType_, + UPstream::worldComm + ); + } // Renumber (point data) to correspond to merged points if @@ -626,6 +656,15 @@ Foam::tmp> Foam::surfaceWriter::mergeFieldTemplate allFld.resize(mergedSurf_.points().size()); } + // Extended debugging. Limit to master: + #if 0 + if (UPstream::master()) + { + Info<< "merged List<" << pTraits::typeName << "> : "; + allFld.writeList(Info) << endl; + } + #endif + return tfield; } diff --git a/src/surfMesh/writers/common/surfaceWriter.H b/src/surfMesh/writers/common/surfaceWriter.H index d67c7b3f4f..54f018e1ad 100644 --- a/src/surfMesh/writers/common/surfaceWriter.H +++ b/src/surfMesh/writers/common/surfaceWriter.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2012 OpenFOAM Foundation - Copyright (C) 2015-2024 OpenCFD Ltd. + Copyright (C) 2015-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -82,6 +82,7 @@ Description Property | Description | Reqd | Default verbose | Additional output verbosity | no | no commsType | Communication type | no | scheduled + gatherv | Use MPI gatherv [experimental] | no | false scale | Output geometry scaling | no | 1 transform | Output coordinate transform | no | fieldLevel | Subtract field level before scaling | no | empty dict @@ -97,6 +98,9 @@ Note it is the responsibility of the implementation (not the caller) to ensure that this occurs. + Using MPI gatherv [experimental] is not well tested and may change + or be removed in the future! + SourceFiles surfaceWriter.C surfaceWriterI.H @@ -191,6 +195,9 @@ protected: //- Communication type (for field merging) UPstream::commsTypes commType_; + //- Prefer MPI gatherv intrinsic (for field merging) [experimental] + bool gatherv_; + //- The number of fields label nFields_; diff --git a/src/surfMesh/writers/debug/debugSurfaceWriter.C b/src/surfMesh/writers/debug/debugSurfaceWriter.C index b707d18552..3c8a5ff0b1 100644 --- a/src/surfMesh/writers/debug/debugSurfaceWriter.C +++ b/src/surfMesh/writers/debug/debugSurfaceWriter.C @@ -88,8 +88,11 @@ Foam::surfaceWriters::debugWriter::debugWriter streamOpt_(IOstreamOption::BINARY) { Info<< "Using debug surface writer (" - << (this->isPointData() ? "point" : "face") << " data):" - << " commsType=" << UPstream::commsTypeNames[commType_] + << (this->isPointData() ? "point" : "face") << " data):"; + + if (gatherv_) Info<< " "; + + Info<< " commsType=" << UPstream::commsTypeNames[commType_] << " merge=" << Switch::name(enableMerge_) << " write=" << Switch::name(enableWrite_) << endl; } diff --git a/tutorials/incompressible/simpleFoam/squareBend/Allclean b/tutorials/incompressible/simpleFoam/squareBend/Allclean new file mode 100755 index 0000000000..53b43d2e6d --- /dev/null +++ b/tutorials/incompressible/simpleFoam/squareBend/Allclean @@ -0,0 +1,11 @@ +#!/bin/sh +cd "${0%/*}" || exit # Run from this directory +. ${WM_PROJECT_DIR:?}/bin/tools/CleanFunctions # Tutorial clean functions +#------------------------------------------------------------------------------ + +cleanCase0 + +# Remove surface and features +rm -rf constant/triSurface + +#------------------------------------------------------------------------------ diff --git a/tutorials/incompressible/simpleFoam/squareBend/system/sampling b/tutorials/incompressible/simpleFoam/squareBend/system/sampling index dc69207e9b..db75382db8 100644 --- a/tutorials/incompressible/simpleFoam/squareBend/system/sampling +++ b/tutorials/incompressible/simpleFoam/squareBend/system/sampling @@ -49,7 +49,8 @@ __surfaceFieldValue { default { - verbose true; + verbose true; + //gatherv true; } } diff --git a/tutorials/incompressible/simpleFoam/squareBend/system/samplingDebug b/tutorials/incompressible/simpleFoam/squareBend/system/samplingDebug index 8b938c7f17..182eb3b1a9 100644 --- a/tutorials/incompressible/simpleFoam/squareBend/system/samplingDebug +++ b/tutorials/incompressible/simpleFoam/squareBend/system/samplingDebug @@ -19,6 +19,12 @@ debug formatOptions { + default + { + verbose true; + //gatherv true; + } + ensight { collateTimes true; From c83bdc14221ad9fb924b4d592e0d2bd053250308 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Wed, 13 Aug 2025 17:59:20 +0200 Subject: [PATCH 03/18] STYLE: surface/volume writing function objects - further hide implementation (cxx ending) STYLE: better distinction between code/templates for fileFormats/conversion - for ensight and vtk, a large part of the code is header only. Make this easier to identify --- src/conversion/Make/files | 2 +- .../ensight/output/ensightOutputAreaField.H | 2 +- ...Templates.C => ensightOutputAreaField.txx} | 0 .../ensight/output/ensightOutputVolField.H | 2 +- ...dTemplates.C => ensightOutputVolField.txx} | 0 src/conversion/vtk/adaptor/foamVtkTools.H | 4 +-- ...amVtkToolsTemplates.C => foamVtkTools.txx} | 0 .../vtk/adaptor/foamVtkVtuAdaptor.H | 4 +-- ...aptorTemplates.C => foamVtkVtuAdaptor.txx} | 0 .../foamVtkGenericPatchGeoFieldsWriter.H | 4 +-- ...=> foamVtkGenericPatchGeoFieldsWriter.txx} | 0 .../vtk/output/foamVtkInternalWriter.H | 4 +-- ...rTemplates.C => foamVtkInternalWriter.txx} | 0 .../vtk/output/foamVtkPatchWriter.H | 4 +-- ...iterTemplates.C => foamVtkPatchWriter.txx} | 0 .../vtk/output/foamVtkSurfaceFieldWriter.H | 2 +- ...Writer.C => foamVtkSurfaceFieldWriter.cxx} | 0 src/fileFormats/ensight/file/ensightCase.H | 4 +-- ...ensightCaseTemplates.C => ensightCase.txx} | 0 src/fileFormats/ensight/file/ensightFile.H | 2 +- ...ensightFileTemplates.C => ensightFile.txx} | 0 .../ensight/output/ensightOutput.H | 4 +-- ...ghtOutputTemplates.C => ensightOutput.txx} | 0 .../part/surface/ensightOutputSurface.H | 4 +-- ...ceTemplates.C => ensightOutputSurface.txx} | 0 src/fileFormats/vtk/file/foamVtkFileWriter.H | 4 +-- ...riterTemplates.C => foamVtkFileWriter.txx} | 0 src/fileFormats/vtk/format/foamVtkFormatter.H | 5 +-- ...matterTemplates.C => foamVtkFormatter.txx} | 0 src/fileFormats/vtk/output/foamVtkOutput.H | 5 +-- ...VtkOutputTemplates.C => foamVtkOutput.txx} | 0 .../vtk/read/vtkUnstructuredReader.H | 2 +- ...rTemplates.C => vtkUnstructuredReader.txx} | 0 src/fileFormats/vtk/write/foamVtkPolyWriter.H | 4 +-- ...riterTemplates.C => foamVtkPolyWriter.txx} | 0 src/functionObjects/lagrangian/Make/files | 2 +- .../lagrangian/vtkCloud/vtkCloud.H | 10 ++---- .../vtkCloud/{vtkCloud.C => vtkCloud.cxx} | 6 ++++ .../{vtkCloudTemplates.C => vtkCloudImpl.cxx} | 0 src/functionObjects/utilities/Make/files | 10 +++--- .../utilities/areaWrite/areaWrite.H | 36 ++++++++++--------- .../areaWrite/{areaWrite.C => areaWrite.cxx} | 31 ++++++++-------- .../{areaWriteImpl.C => areaWriteImpl.cxx} | 4 --- .../utilities/ensightWrite/ensightWrite.H | 35 +++++++----------- .../{ensightWrite.C => ensightWrite.cxx} | 11 ++---- ...nsightWriteImpl.C => ensightWriteImpl.cxx} | 0 ...htWriteUpdate.C => ensightWriteUpdate.cxx} | 0 .../utilities/vtkWrite/vtkWrite.H | 20 +++++------ .../vtkWrite/{vtkWrite.C => vtkWrite.cxx} | 16 ++------- .../{vtkWriteImpl.C => vtkWriteImpl.cxx} | 0 .../{vtkWriteUpdate.C => vtkWriteUpdate.cxx} | 0 src/lagrangian/intermediate/Make/files | 4 +-- .../conversion/ensight/ensightOutputCloud.H | 6 ++-- ...htOutputCloud.C => ensightOutputCloud.cxx} | 0 ...loudTemplates.C => ensightOutputCloud.txx} | 0 .../conversion/vtk/foamVtkLagrangianWriter.H | 6 ++-- ...anWriter.C => foamVtkLagrangianWriter.cxx} | 0 ...emplates.C => foamVtkLagrangianWriter.txx} | 0 src/meshTools/Make/files | 4 +-- .../vtk/mesh/foamVtkInternalMeshWriter.H | 6 ++-- ...Writer.C => foamVtkInternalMeshWriter.cxx} | 0 ...plates.C => foamVtkInternalMeshWriter.txx} | 0 .../output/vtk/patch/foamVtkPatchMeshWriter.H | 6 ++-- ...eshWriter.C => foamVtkPatchMeshWriter.cxx} | 0 ...Templates.C => foamVtkPatchMeshWriter.txx} | 0 .../boundary/boundaryDataSurfaceReader.H | 4 +-- ...plates.C => boundaryDataSurfaceReader.txx} | 0 .../readers/ensight/ensightSurfaceReader.H | 4 +-- ...erTemplates.C => ensightSurfaceReader.txx} | 0 69 files changed, 127 insertions(+), 156 deletions(-) rename src/conversion/ensight/output/{ensightOutputAreaFieldTemplates.C => ensightOutputAreaField.txx} (100%) rename src/conversion/ensight/output/{ensightOutputVolFieldTemplates.C => ensightOutputVolField.txx} (100%) rename src/conversion/vtk/adaptor/{foamVtkToolsTemplates.C => foamVtkTools.txx} (100%) rename src/conversion/vtk/adaptor/{foamVtkVtuAdaptorTemplates.C => foamVtkVtuAdaptor.txx} (100%) rename src/conversion/vtk/output/{foamVtkGenericPatchGeoFieldsWriter.C => foamVtkGenericPatchGeoFieldsWriter.txx} (100%) rename src/conversion/vtk/output/{foamVtkInternalWriterTemplates.C => foamVtkInternalWriter.txx} (100%) rename src/conversion/vtk/output/{foamVtkPatchWriterTemplates.C => foamVtkPatchWriter.txx} (100%) rename src/conversion/vtk/output/{foamVtkSurfaceFieldWriter.C => foamVtkSurfaceFieldWriter.cxx} (100%) rename src/fileFormats/ensight/file/{ensightCaseTemplates.C => ensightCase.txx} (100%) rename src/fileFormats/ensight/file/{ensightFileTemplates.C => ensightFile.txx} (100%) rename src/fileFormats/ensight/output/{ensightOutputTemplates.C => ensightOutput.txx} (100%) rename src/fileFormats/ensight/part/surface/{ensightOutputSurfaceTemplates.C => ensightOutputSurface.txx} (100%) rename src/fileFormats/vtk/file/{foamVtkFileWriterTemplates.C => foamVtkFileWriter.txx} (100%) rename src/fileFormats/vtk/format/{foamVtkFormatterTemplates.C => foamVtkFormatter.txx} (100%) rename src/fileFormats/vtk/output/{foamVtkOutputTemplates.C => foamVtkOutput.txx} (100%) rename src/fileFormats/vtk/read/{vtkUnstructuredReaderTemplates.C => vtkUnstructuredReader.txx} (100%) rename src/fileFormats/vtk/write/{foamVtkPolyWriterTemplates.C => foamVtkPolyWriter.txx} (100%) rename src/functionObjects/lagrangian/vtkCloud/{vtkCloud.C => vtkCloud.cxx} (99%) rename src/functionObjects/lagrangian/vtkCloud/{vtkCloudTemplates.C => vtkCloudImpl.cxx} (100%) rename src/functionObjects/utilities/areaWrite/{areaWrite.C => areaWrite.cxx} (95%) rename src/functionObjects/utilities/areaWrite/{areaWriteImpl.C => areaWriteImpl.cxx} (97%) rename src/functionObjects/utilities/ensightWrite/{ensightWrite.C => ensightWrite.cxx} (97%) rename src/functionObjects/utilities/ensightWrite/{ensightWriteImpl.C => ensightWriteImpl.cxx} (100%) rename src/functionObjects/utilities/ensightWrite/{ensightWriteUpdate.C => ensightWriteUpdate.cxx} (100%) rename src/functionObjects/utilities/vtkWrite/{vtkWrite.C => vtkWrite.cxx} (98%) rename src/functionObjects/utilities/vtkWrite/{vtkWriteImpl.C => vtkWriteImpl.cxx} (100%) rename src/functionObjects/utilities/vtkWrite/{vtkWriteUpdate.C => vtkWriteUpdate.cxx} (100%) rename src/lagrangian/intermediate/conversion/ensight/{ensightOutputCloud.C => ensightOutputCloud.cxx} (100%) rename src/lagrangian/intermediate/conversion/ensight/{ensightOutputCloudTemplates.C => ensightOutputCloud.txx} (100%) rename src/lagrangian/intermediate/conversion/vtk/{foamVtkLagrangianWriter.C => foamVtkLagrangianWriter.cxx} (100%) rename src/lagrangian/intermediate/conversion/vtk/{foamVtkLagrangianWriterTemplates.C => foamVtkLagrangianWriter.txx} (100%) rename src/meshTools/output/vtk/mesh/{foamVtkInternalMeshWriter.C => foamVtkInternalMeshWriter.cxx} (100%) rename src/meshTools/output/vtk/mesh/{foamVtkInternalMeshWriterTemplates.C => foamVtkInternalMeshWriter.txx} (100%) rename src/meshTools/output/vtk/patch/{foamVtkPatchMeshWriter.C => foamVtkPatchMeshWriter.cxx} (100%) rename src/meshTools/output/vtk/patch/{foamVtkPatchMeshWriterTemplates.C => foamVtkPatchMeshWriter.txx} (100%) rename src/surfMesh/readers/boundary/{boundaryDataSurfaceReaderTemplates.C => boundaryDataSurfaceReader.txx} (100%) rename src/surfMesh/readers/ensight/{ensightSurfaceReaderTemplates.C => ensightSurfaceReader.txx} (100%) diff --git a/src/conversion/Make/files b/src/conversion/Make/files index b3d457edd5..b730f0187e 100644 --- a/src/conversion/Make/files +++ b/src/conversion/Make/files @@ -16,6 +16,6 @@ starcd/STARCDMeshWriter.C polyDualMesh/polyDualMesh.C -vtk/output/foamVtkSurfaceFieldWriter.C +vtk/output/foamVtkSurfaceFieldWriter.cxx LIB = $(FOAM_LIBBIN)/libconversion diff --git a/src/conversion/ensight/output/ensightOutputAreaField.H b/src/conversion/ensight/output/ensightOutputAreaField.H index 416c764ca3..ac42bdb760 100644 --- a/src/conversion/ensight/output/ensightOutputAreaField.H +++ b/src/conversion/ensight/output/ensightOutputAreaField.H @@ -98,7 +98,7 @@ bool writeAreaField // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository - #include "ensightOutputAreaFieldTemplates.C" + #include "ensightOutputAreaField.txx" #endif #endif diff --git a/src/conversion/ensight/output/ensightOutputAreaFieldTemplates.C b/src/conversion/ensight/output/ensightOutputAreaField.txx similarity index 100% rename from src/conversion/ensight/output/ensightOutputAreaFieldTemplates.C rename to src/conversion/ensight/output/ensightOutputAreaField.txx diff --git a/src/conversion/ensight/output/ensightOutputVolField.H b/src/conversion/ensight/output/ensightOutputVolField.H index 1c489e11c5..69671fe812 100644 --- a/src/conversion/ensight/output/ensightOutputVolField.H +++ b/src/conversion/ensight/output/ensightOutputVolField.H @@ -177,7 +177,7 @@ bool writePointField // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository - #include "ensightOutputVolFieldTemplates.C" + #include "ensightOutputVolField.txx" #endif #endif diff --git a/src/conversion/ensight/output/ensightOutputVolFieldTemplates.C b/src/conversion/ensight/output/ensightOutputVolField.txx similarity index 100% rename from src/conversion/ensight/output/ensightOutputVolFieldTemplates.C rename to src/conversion/ensight/output/ensightOutputVolField.txx diff --git a/src/conversion/vtk/adaptor/foamVtkTools.H b/src/conversion/vtk/adaptor/foamVtkTools.H index 4a1a1b3641..6b83e33c9f 100644 --- a/src/conversion/vtk/adaptor/foamVtkTools.H +++ b/src/conversion/vtk/adaptor/foamVtkTools.H @@ -39,7 +39,7 @@ Note SourceFiles foamVtkToolsI.H - foamVtkToolsTemplates.C + foamVtkTools.txx \*---------------------------------------------------------------------------*/ @@ -358,7 +358,7 @@ void Foam::vtk::Tools::remapTuple(double data[]) // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository - #include "foamVtkToolsTemplates.C" + #include "foamVtkTools.txx" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/conversion/vtk/adaptor/foamVtkToolsTemplates.C b/src/conversion/vtk/adaptor/foamVtkTools.txx similarity index 100% rename from src/conversion/vtk/adaptor/foamVtkToolsTemplates.C rename to src/conversion/vtk/adaptor/foamVtkTools.txx diff --git a/src/conversion/vtk/adaptor/foamVtkVtuAdaptor.H b/src/conversion/vtk/adaptor/foamVtkVtuAdaptor.H index 8af6644317..54c67ddfa7 100644 --- a/src/conversion/vtk/adaptor/foamVtkVtuAdaptor.H +++ b/src/conversion/vtk/adaptor/foamVtkVtuAdaptor.H @@ -39,7 +39,7 @@ Note SourceFiles foamVtkVtuAdaptorI.H - foamVtkVtuAdaptorTemplates.C + foamVtkVtuAdaptor.txx \*---------------------------------------------------------------------------*/ @@ -156,7 +156,7 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository - #include "foamVtkVtuAdaptorTemplates.C" + #include "foamVtkVtuAdaptor.txx" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/conversion/vtk/adaptor/foamVtkVtuAdaptorTemplates.C b/src/conversion/vtk/adaptor/foamVtkVtuAdaptor.txx similarity index 100% rename from src/conversion/vtk/adaptor/foamVtkVtuAdaptorTemplates.C rename to src/conversion/vtk/adaptor/foamVtkVtuAdaptor.txx diff --git a/src/conversion/vtk/output/foamVtkGenericPatchGeoFieldsWriter.H b/src/conversion/vtk/output/foamVtkGenericPatchGeoFieldsWriter.H index b76971eec8..d85291a35d 100644 --- a/src/conversion/vtk/output/foamVtkGenericPatchGeoFieldsWriter.H +++ b/src/conversion/vtk/output/foamVtkGenericPatchGeoFieldsWriter.H @@ -32,7 +32,7 @@ Description Caution, currently only works properly for indirect patches. SourceFiles - foamVtkGenericPatchGeoFieldsWriter.C + foamVtkGenericPatchGeoFieldsWriter.txx \*---------------------------------------------------------------------------*/ @@ -117,7 +117,7 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository - #include "foamVtkGenericPatchGeoFieldsWriter.C" + #include "foamVtkGenericPatchGeoFieldsWriter.txx" #endif diff --git a/src/conversion/vtk/output/foamVtkGenericPatchGeoFieldsWriter.C b/src/conversion/vtk/output/foamVtkGenericPatchGeoFieldsWriter.txx similarity index 100% rename from src/conversion/vtk/output/foamVtkGenericPatchGeoFieldsWriter.C rename to src/conversion/vtk/output/foamVtkGenericPatchGeoFieldsWriter.txx diff --git a/src/conversion/vtk/output/foamVtkInternalWriter.H b/src/conversion/vtk/output/foamVtkInternalWriter.H index 5e29d2be47..a931280adf 100644 --- a/src/conversion/vtk/output/foamVtkInternalWriter.H +++ b/src/conversion/vtk/output/foamVtkInternalWriter.H @@ -44,7 +44,7 @@ See Also Foam::vtk::internalMeshWriter SourceFiles - foamVtkInternalWriterTemplates.C + foamVtkInternalWriter.txx \*---------------------------------------------------------------------------*/ @@ -183,7 +183,7 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository - #include "foamVtkInternalWriterTemplates.C" + #include "foamVtkInternalWriter.txx" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/conversion/vtk/output/foamVtkInternalWriterTemplates.C b/src/conversion/vtk/output/foamVtkInternalWriter.txx similarity index 100% rename from src/conversion/vtk/output/foamVtkInternalWriterTemplates.C rename to src/conversion/vtk/output/foamVtkInternalWriter.txx diff --git a/src/conversion/vtk/output/foamVtkPatchWriter.H b/src/conversion/vtk/output/foamVtkPatchWriter.H index 429c212b1c..4df5686a27 100644 --- a/src/conversion/vtk/output/foamVtkPatchWriter.H +++ b/src/conversion/vtk/output/foamVtkPatchWriter.H @@ -43,7 +43,7 @@ See Also Foam::vtk::patchMeshWriter SourceFiles - foamVtkPatchWriterTemplates.C + foamVtkPatchWriter.txx \*---------------------------------------------------------------------------*/ @@ -202,7 +202,7 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository - #include "foamVtkPatchWriterTemplates.C" + #include "foamVtkPatchWriter.txx" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/conversion/vtk/output/foamVtkPatchWriterTemplates.C b/src/conversion/vtk/output/foamVtkPatchWriter.txx similarity index 100% rename from src/conversion/vtk/output/foamVtkPatchWriterTemplates.C rename to src/conversion/vtk/output/foamVtkPatchWriter.txx diff --git a/src/conversion/vtk/output/foamVtkSurfaceFieldWriter.H b/src/conversion/vtk/output/foamVtkSurfaceFieldWriter.H index 420fb0fca6..412f554f4a 100644 --- a/src/conversion/vtk/output/foamVtkSurfaceFieldWriter.H +++ b/src/conversion/vtk/output/foamVtkSurfaceFieldWriter.H @@ -47,7 +47,7 @@ Note may be addressed using ghost points. SourceFiles - surfaceFieldWriter.C + foamVtkSurfaceFieldWriter.cxx \*---------------------------------------------------------------------------*/ diff --git a/src/conversion/vtk/output/foamVtkSurfaceFieldWriter.C b/src/conversion/vtk/output/foamVtkSurfaceFieldWriter.cxx similarity index 100% rename from src/conversion/vtk/output/foamVtkSurfaceFieldWriter.C rename to src/conversion/vtk/output/foamVtkSurfaceFieldWriter.cxx diff --git a/src/fileFormats/ensight/file/ensightCase.H b/src/fileFormats/ensight/file/ensightCase.H index e07601d954..27449ce04d 100644 --- a/src/fileFormats/ensight/file/ensightCase.H +++ b/src/fileFormats/ensight/file/ensightCase.H @@ -34,7 +34,7 @@ SourceFiles ensightCase.C ensightCaseI.H ensightCaseOptions.C - ensightCaseTemplates.C + ensightCase.txx \*---------------------------------------------------------------------------*/ @@ -548,7 +548,7 @@ public: #include "ensightCaseI.H" #ifdef NoRepository - #include "ensightCaseTemplates.C" + #include "ensightCase.txx" #endif #endif diff --git a/src/fileFormats/ensight/file/ensightCaseTemplates.C b/src/fileFormats/ensight/file/ensightCase.txx similarity index 100% rename from src/fileFormats/ensight/file/ensightCaseTemplates.C rename to src/fileFormats/ensight/file/ensightCase.txx diff --git a/src/fileFormats/ensight/file/ensightFile.H b/src/fileFormats/ensight/file/ensightFile.H index a0231593c1..03b9b66c4f 100644 --- a/src/fileFormats/ensight/file/ensightFile.H +++ b/src/fileFormats/ensight/file/ensightFile.H @@ -394,7 +394,7 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository - #include "ensightFileTemplates.C" + #include "ensightFile.txx" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/fileFormats/ensight/file/ensightFileTemplates.C b/src/fileFormats/ensight/file/ensightFile.txx similarity index 100% rename from src/fileFormats/ensight/file/ensightFileTemplates.C rename to src/fileFormats/ensight/file/ensightFile.txx diff --git a/src/fileFormats/ensight/output/ensightOutput.H b/src/fileFormats/ensight/output/ensightOutput.H index 4c26ff69dc..cf11bc2490 100644 --- a/src/fileFormats/ensight/output/ensightOutput.H +++ b/src/fileFormats/ensight/output/ensightOutput.H @@ -31,7 +31,7 @@ Description SourceFiles ensightOutput.C - ensightOutputTemplates.C + ensightOutput.txx \*---------------------------------------------------------------------------*/ @@ -557,7 +557,7 @@ bool writeFaceLocalField // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository - #include "ensightOutputTemplates.C" + #include "ensightOutput.txx" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/fileFormats/ensight/output/ensightOutputTemplates.C b/src/fileFormats/ensight/output/ensightOutput.txx similarity index 100% rename from src/fileFormats/ensight/output/ensightOutputTemplates.C rename to src/fileFormats/ensight/output/ensightOutput.txx diff --git a/src/fileFormats/ensight/part/surface/ensightOutputSurface.H b/src/fileFormats/ensight/part/surface/ensightOutputSurface.H index 90b9ed1808..493c6c0115 100644 --- a/src/fileFormats/ensight/part/surface/ensightOutputSurface.H +++ b/src/fileFormats/ensight/part/surface/ensightOutputSurface.H @@ -38,7 +38,7 @@ Note SourceFiles ensightOutputSurface.C - ensightOutputSurfaceTemplates.C + ensightOutputSurface.txx \*---------------------------------------------------------------------------*/ @@ -136,7 +136,7 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository - #include "ensightOutputSurfaceTemplates.C" + #include "ensightOutputSurface.txx" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/fileFormats/ensight/part/surface/ensightOutputSurfaceTemplates.C b/src/fileFormats/ensight/part/surface/ensightOutputSurface.txx similarity index 100% rename from src/fileFormats/ensight/part/surface/ensightOutputSurfaceTemplates.C rename to src/fileFormats/ensight/part/surface/ensightOutputSurface.txx diff --git a/src/fileFormats/vtk/file/foamVtkFileWriter.H b/src/fileFormats/vtk/file/foamVtkFileWriter.H index abf068a42f..8ec75beb44 100644 --- a/src/fileFormats/vtk/file/foamVtkFileWriter.H +++ b/src/fileFormats/vtk/file/foamVtkFileWriter.H @@ -42,8 +42,8 @@ Description SourceFiles foamVtkFileWriter.C + foamVtkFileWriter.txx foamVtkFileWriterI.H - foamVtkFileWriterTemplates.C \*---------------------------------------------------------------------------*/ @@ -350,7 +350,7 @@ public: #include "foamVtkFileWriterI.H" #ifdef NoRepository - #include "foamVtkFileWriterTemplates.C" + #include "foamVtkFileWriter.txx" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/fileFormats/vtk/file/foamVtkFileWriterTemplates.C b/src/fileFormats/vtk/file/foamVtkFileWriter.txx similarity index 100% rename from src/fileFormats/vtk/file/foamVtkFileWriterTemplates.C rename to src/fileFormats/vtk/file/foamVtkFileWriter.txx diff --git a/src/fileFormats/vtk/format/foamVtkFormatter.H b/src/fileFormats/vtk/format/foamVtkFormatter.H index b8f83229fc..015d2f3d11 100644 --- a/src/fileFormats/vtk/format/foamVtkFormatter.H +++ b/src/fileFormats/vtk/format/foamVtkFormatter.H @@ -34,7 +34,8 @@ Description SourceFiles foamVtkFormatter.C - foamVtkFormatterTemplates.C + foamVtkFormatter.txx + foamVtkFormatterI.H \*---------------------------------------------------------------------------*/ @@ -560,7 +561,7 @@ inline uint64_t sizeofData(label count) #include "foamVtkFormatterI.H" #ifdef NoRepository - #include "foamVtkFormatterTemplates.C" + #include "foamVtkFormatter.txx" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/fileFormats/vtk/format/foamVtkFormatterTemplates.C b/src/fileFormats/vtk/format/foamVtkFormatter.txx similarity index 100% rename from src/fileFormats/vtk/format/foamVtkFormatterTemplates.C rename to src/fileFormats/vtk/format/foamVtkFormatter.txx diff --git a/src/fileFormats/vtk/output/foamVtkOutput.H b/src/fileFormats/vtk/output/foamVtkOutput.H index 0f67899c29..21fcbca136 100644 --- a/src/fileFormats/vtk/output/foamVtkOutput.H +++ b/src/fileFormats/vtk/output/foamVtkOutput.H @@ -38,7 +38,8 @@ Description SourceFiles foamVtkOutput.C - foamVtkOutputTemplates.C + foamVtkOutput.txx + foamVtkOutputI.H \*---------------------------------------------------------------------------*/ @@ -352,7 +353,7 @@ namespace legacy #include "foamVtkOutputI.H" #ifdef NoRepository - #include "foamVtkOutputTemplates.C" + #include "foamVtkOutput.txx" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/fileFormats/vtk/output/foamVtkOutputTemplates.C b/src/fileFormats/vtk/output/foamVtkOutput.txx similarity index 100% rename from src/fileFormats/vtk/output/foamVtkOutputTemplates.C rename to src/fileFormats/vtk/output/foamVtkOutput.txx diff --git a/src/fileFormats/vtk/read/vtkUnstructuredReader.H b/src/fileFormats/vtk/read/vtkUnstructuredReader.H index 99bc480078..1fec1a95c8 100644 --- a/src/fileFormats/vtk/read/vtkUnstructuredReader.H +++ b/src/fileFormats/vtk/read/vtkUnstructuredReader.H @@ -358,7 +358,7 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository - #include "vtkUnstructuredReaderTemplates.C" + #include "vtkUnstructuredReader.txx" #endif diff --git a/src/fileFormats/vtk/read/vtkUnstructuredReaderTemplates.C b/src/fileFormats/vtk/read/vtkUnstructuredReader.txx similarity index 100% rename from src/fileFormats/vtk/read/vtkUnstructuredReaderTemplates.C rename to src/fileFormats/vtk/read/vtkUnstructuredReader.txx diff --git a/src/fileFormats/vtk/write/foamVtkPolyWriter.H b/src/fileFormats/vtk/write/foamVtkPolyWriter.H index 73acd63281..7c9d385bcd 100644 --- a/src/fileFormats/vtk/write/foamVtkPolyWriter.H +++ b/src/fileFormats/vtk/write/foamVtkPolyWriter.H @@ -42,7 +42,7 @@ Note SourceFiles foamVtkPolyWriter.C - foamVtkPolyWriterTemplates.C + foamVtkPolyWriter.txx \*---------------------------------------------------------------------------*/ @@ -253,7 +253,7 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository - #include "foamVtkPolyWriterTemplates.C" + #include "foamVtkPolyWriter.txx" #endif diff --git a/src/fileFormats/vtk/write/foamVtkPolyWriterTemplates.C b/src/fileFormats/vtk/write/foamVtkPolyWriter.txx similarity index 100% rename from src/fileFormats/vtk/write/foamVtkPolyWriterTemplates.C rename to src/fileFormats/vtk/write/foamVtkPolyWriter.txx diff --git a/src/functionObjects/lagrangian/Make/files b/src/functionObjects/lagrangian/Make/files index 51e5c3b112..40712a62e2 100644 --- a/src/functionObjects/lagrangian/Make/files +++ b/src/functionObjects/lagrangian/Make/files @@ -4,7 +4,7 @@ cloudInfo/cloudInfo.C icoUncoupledKinematicCloud/icoUncoupledKinematicCloud.C dsmcFields/dsmcFields.C -vtkCloud/vtkCloud.C +vtkCloud/vtkCloud.cxx ensightCloud/ensightCloudWriteObject.cxx LIB = $(FOAM_LIBBIN)/liblagrangianFunctionObjects diff --git a/src/functionObjects/lagrangian/vtkCloud/vtkCloud.H b/src/functionObjects/lagrangian/vtkCloud/vtkCloud.H index b8f0b413fd..72d9ab9a55 100644 --- a/src/functionObjects/lagrangian/vtkCloud/vtkCloud.H +++ b/src/functionObjects/lagrangian/vtkCloud/vtkCloud.H @@ -129,8 +129,8 @@ See also Foam::functionObjects::timeControl SourceFiles - vtkCloud.C - vtkCloudTemplates.C + vtkCloud.cxx + vtkCloudImpl.cxx \*---------------------------------------------------------------------------*/ @@ -262,12 +262,6 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -#ifdef NoRepository - #include "vtkCloudTemplates.C" -#endif - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - #endif // ************************************************************************* // diff --git a/src/functionObjects/lagrangian/vtkCloud/vtkCloud.C b/src/functionObjects/lagrangian/vtkCloud/vtkCloud.cxx similarity index 99% rename from src/functionObjects/lagrangian/vtkCloud/vtkCloud.C rename to src/functionObjects/lagrangian/vtkCloud/vtkCloud.cxx index 223fa2feab..013447e2a4 100644 --- a/src/functionObjects/lagrangian/vtkCloud/vtkCloud.C +++ b/src/functionObjects/lagrangian/vtkCloud/vtkCloud.cxx @@ -47,6 +47,12 @@ namespace functionObjects } +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// Implementation +#include "vtkCloudImpl.cxx" + + // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // void Foam::functionObjects::vtkCloud::writeVerts diff --git a/src/functionObjects/lagrangian/vtkCloud/vtkCloudTemplates.C b/src/functionObjects/lagrangian/vtkCloud/vtkCloudImpl.cxx similarity index 100% rename from src/functionObjects/lagrangian/vtkCloud/vtkCloudTemplates.C rename to src/functionObjects/lagrangian/vtkCloud/vtkCloudImpl.cxx diff --git a/src/functionObjects/utilities/Make/files b/src/functionObjects/utilities/Make/files index 9da1341dfa..6730f52128 100644 --- a/src/functionObjects/utilities/Make/files +++ b/src/functionObjects/utilities/Make/files @@ -4,10 +4,10 @@ caseInfo/caseInfo.C codedFunctionObject/codedFunctionObject.C -areaWrite/areaWrite.C +areaWrite/areaWrite.cxx -ensightWrite/ensightWrite.C -ensightWrite/ensightWriteUpdate.C +ensightWrite/ensightWrite.cxx +ensightWrite/ensightWriteUpdate.cxx foamReport/foamReport.C foamReport/substitutionModels/substitutionModel/substitutionModel.C @@ -20,8 +20,8 @@ foamReport/substitutionModels/userValue/userValue.C graphFunctionObject/graphFunctionObject.C -vtkWrite/vtkWrite.C -vtkWrite/vtkWriteUpdate.C +vtkWrite/vtkWrite.cxx +vtkWrite/vtkWriteUpdate.cxx multiRegion/multiRegion.C diff --git a/src/functionObjects/utilities/areaWrite/areaWrite.H b/src/functionObjects/utilities/areaWrite/areaWrite.H index 7790265c86..2cff33acf8 100644 --- a/src/functionObjects/utilities/areaWrite/areaWrite.H +++ b/src/functionObjects/utilities/areaWrite/areaWrite.H @@ -72,8 +72,8 @@ Usage libs | Library name: utilityFunctionObjects | word | yes | - fields | Name of operand fields | wordRes | yes | - surfaceFormat | Output surface format | word | yes | - - areas | Names of multiple areas | wordRes | no | - - area | Name of the selected area | word | no | - + areas | Names of finite-area regions | wordRes | no | - + area | Name of finite-area region | word | no | - formatOptions | Dictionary of format options | dict | no | - \endtable @@ -82,8 +82,8 @@ Usage - \link surfaceWriter.H \endlink SourceFiles - areaWrite.C - areaWriteTemplates.C + areaWrite.cxx + areaWriteImpl.cxx \*---------------------------------------------------------------------------*/ @@ -95,7 +95,6 @@ SourceFiles #include "areaFieldsFwd.H" #include "surfaceWriter.H" #include "HashPtrTable.H" -#include "IOobjectList.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -105,6 +104,7 @@ namespace Foam // Forward Declarations class faMesh; class polySurface; +class IOobjectList; /*---------------------------------------------------------------------------*\ Class areaWrite Declaration @@ -145,7 +145,7 @@ class areaWrite //- Hold intermediate surfaces. // The faMesh has an indirect face list but we require real ones. - autoPtr surfaces_; + std::unique_ptr surfaces_; // Output control @@ -156,6 +156,9 @@ class areaWrite // Private Member Functions + //- Mark intermediate surfaces and writers as needing an update. + void expire(); + //- Write fieldName on surface and on outputDir path. // Can have a field nullptr for partially missing fields, // but the caller should generally filter out completely @@ -177,8 +180,13 @@ class areaWrite const IOobjectList& objects ); - //- Mark intermediate surfaces and writers as needing an update. - void expire(); +public: + + //- Runtime type information + TypeName("areaWrite"); + + + // Generated Methods //- No copy construct areaWrite(const areaWrite&) = delete; @@ -187,12 +195,6 @@ class areaWrite void operator=(const areaWrite&) = delete; -public: - - //- Runtime type information - TypeName("areaWrite"); - - // Constructors //- Construct from name, Time and dictionary @@ -215,14 +217,14 @@ public: //- Destructor - virtual ~areaWrite() = default; + virtual ~areaWrite(); // Member Functions //- Enable/disable verbose output // \return old value - bool verbose(const bool on) noexcept; + bool verbose(bool on) noexcept; //- Read the function-object dictionary virtual bool read(const dictionary& dict); @@ -246,7 +248,7 @@ public: static scalar mergeTol() noexcept; //- Set merge tolerance and return old value - static scalar mergeTol(const scalar tol) noexcept; + static scalar mergeTol(scalar tol) noexcept; }; diff --git a/src/functionObjects/utilities/areaWrite/areaWrite.C b/src/functionObjects/utilities/areaWrite/areaWrite.cxx similarity index 95% rename from src/functionObjects/utilities/areaWrite/areaWrite.C rename to src/functionObjects/utilities/areaWrite/areaWrite.cxx index e245381dcf..2d8a10911d 100644 --- a/src/functionObjects/utilities/areaWrite/areaWrite.C +++ b/src/functionObjects/utilities/areaWrite/areaWrite.cxx @@ -28,11 +28,13 @@ License #include "areaWrite.H" #include "polySurface.H" +#include "faMesh.H" #include "fvMesh.H" #include "mapPolyMesh.H" #include "areaFields.H" #include "HashOps.H" #include "ListOps.H" +#include "IOobjectList.H" #include "Time.H" #include "IndirectList.H" #include "addToRunTimeSelectionTable.H" @@ -55,7 +57,7 @@ Foam::scalar Foam::areaWrite::mergeTol_ = 1e-10; // Implementation -#include "areaWriteImpl.C" +#include "areaWriteImpl.cxx" // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // @@ -72,12 +74,7 @@ Foam::areaWrite::areaWrite outputPath_ ( time_.globalPath()/functionObject::outputPrefix/name - ), - selectAreas_(), - fieldSelection_(), - meshes_(), - surfaces_(nullptr), - writers_() + ) { outputPath_.clean(); // Remove unneeded ".." @@ -99,12 +96,7 @@ Foam::areaWrite::areaWrite outputPath_ ( time_.globalPath()/functionObject::outputPrefix/name - ), - selectAreas_(), - fieldSelection_(), - meshes_(), - surfaces_(nullptr), - writers_() + ) { outputPath_.clean(); // Remove unneeded ".." @@ -112,9 +104,15 @@ Foam::areaWrite::areaWrite } +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::areaWrite::~areaWrite() +{} // Define here: header had forward declared classes + + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -bool Foam::areaWrite::verbose(const bool on) noexcept +bool Foam::areaWrite::verbose(bool on) noexcept { bool old(verbose_); verbose_ = on; @@ -393,6 +391,7 @@ bool Foam::areaWrite::write() void Foam::areaWrite::expire() { + // Clear the registry contents surfaces_->clear(); // Dimension as fraction of mesh bounding box @@ -434,13 +433,15 @@ void Foam::areaWrite::readUpdate(const polyMesh::readUpdateState state) } +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + Foam::scalar Foam::areaWrite::mergeTol() noexcept { return mergeTol_; } -Foam::scalar Foam::areaWrite::mergeTol(const scalar tol) noexcept +Foam::scalar Foam::areaWrite::mergeTol(scalar tol) noexcept { scalar old(mergeTol_); mergeTol_ = tol; diff --git a/src/functionObjects/utilities/areaWrite/areaWriteImpl.C b/src/functionObjects/utilities/areaWrite/areaWriteImpl.cxx similarity index 97% rename from src/functionObjects/utilities/areaWrite/areaWriteImpl.C rename to src/functionObjects/utilities/areaWrite/areaWriteImpl.cxx index 86aae84602..be6095c504 100644 --- a/src/functionObjects/utilities/areaWrite/areaWriteImpl.C +++ b/src/functionObjects/utilities/areaWrite/areaWriteImpl.cxx @@ -25,10 +25,6 @@ License \*---------------------------------------------------------------------------*/ -#include "areaWrite.H" -#include "areaFields.H" -#include "faMesh.H" - // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // template diff --git a/src/functionObjects/utilities/ensightWrite/ensightWrite.H b/src/functionObjects/utilities/ensightWrite/ensightWrite.H index 3ba712be80..6284d62150 100644 --- a/src/functionObjects/utilities/ensightWrite/ensightWrite.H +++ b/src/functionObjects/utilities/ensightWrite/ensightWrite.H @@ -135,8 +135,8 @@ See also SourceFiles ensightWrite.C - ensightWriteImpl.C - ensightWriteUpdate.C + ensightWriteImpl.cxx + ensightWriteUpdate.cxx \*---------------------------------------------------------------------------*/ @@ -158,10 +158,6 @@ SourceFiles namespace Foam { - -// Forward Declarations -class dictionary; - namespace functionObjects { @@ -173,7 +169,7 @@ class ensightWrite : public fvMeshFunctionObject { - // Private data + // Private Data //- Ensight writer options ensightMesh::options writeOpts_; @@ -188,7 +184,7 @@ class ensightWrite bool consecutive_; //- Track changes in mesh geometry - enum polyMesh::readUpdateState meshState_; + polyMesh::readUpdateState meshState_; //- Requested selection of fields to process wordRes selectFields_; @@ -212,16 +208,10 @@ class ensightWrite // Private Member Functions //- Ensight case handler - ensightCase& ensCase() - { - return *ensCase_; - } + ensightCase& ensCase() { return *ensCase_; } //- Ensight mesh handler - ensightMesh& ensMesh() - { - return *ensMesh_; - } + ensightMesh& ensMesh() { return *ensMesh_; } //- Update mesh subset according to zones, geometry, bounds @@ -252,13 +242,6 @@ class ensightWrite const wordHashSet& candidateNames ); - //- No copy construct - ensightWrite(const ensightWrite&) = delete; - - //- No copy assignment - void operator=(const ensightWrite&) = delete; - - public: //- Runtime type information @@ -275,6 +258,12 @@ public: const dictionary& dict ); + //- No copy construct + ensightWrite(const ensightWrite&) = delete; + + //- No copy assignment + void operator=(const ensightWrite&) = delete; + //- Destructor virtual ~ensightWrite() = default; diff --git a/src/functionObjects/utilities/ensightWrite/ensightWrite.C b/src/functionObjects/utilities/ensightWrite/ensightWrite.cxx similarity index 97% rename from src/functionObjects/utilities/ensightWrite/ensightWrite.C rename to src/functionObjects/utilities/ensightWrite/ensightWrite.cxx index 85ef3c6be6..0cc5c6b56a 100644 --- a/src/functionObjects/utilities/ensightWrite/ensightWrite.C +++ b/src/functionObjects/utilities/ensightWrite/ensightWrite.cxx @@ -49,7 +49,7 @@ namespace functionObjects } // Implementation -#include "ensightWriteImpl.C" +#include "ensightWriteImpl.cxx" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // @@ -96,17 +96,10 @@ Foam::functionObjects::ensightWrite::ensightWrite ) : fvMeshFunctionObject(name, runTime, dict), - writeOpts_(), caseOpts_("format", dict, IOstreamOption::BINARY), - outputDir_(), consecutive_(false), meshState_(polyMesh::TOPO_CHANGE), - selectFields_(), - blockFields_(), - selection_(), - meshSubset_(mesh_), - ensCase_(nullptr), - ensMesh_(nullptr) + meshSubset_(mesh_) { // May still want this? (OCT-2018) // if (postProcess) diff --git a/src/functionObjects/utilities/ensightWrite/ensightWriteImpl.C b/src/functionObjects/utilities/ensightWrite/ensightWriteImpl.cxx similarity index 100% rename from src/functionObjects/utilities/ensightWrite/ensightWriteImpl.C rename to src/functionObjects/utilities/ensightWrite/ensightWriteImpl.cxx diff --git a/src/functionObjects/utilities/ensightWrite/ensightWriteUpdate.C b/src/functionObjects/utilities/ensightWrite/ensightWriteUpdate.cxx similarity index 100% rename from src/functionObjects/utilities/ensightWrite/ensightWriteUpdate.C rename to src/functionObjects/utilities/ensightWrite/ensightWriteUpdate.cxx diff --git a/src/functionObjects/utilities/vtkWrite/vtkWrite.H b/src/functionObjects/utilities/vtkWrite/vtkWrite.H index 3f22b7c963..6a4e5c8eb2 100644 --- a/src/functionObjects/utilities/vtkWrite/vtkWrite.H +++ b/src/functionObjects/utilities/vtkWrite/vtkWrite.H @@ -130,8 +130,9 @@ See also Foam::cellBitSet::select SourceFiles - vtkWrite.C - vtkWriteImpl.C + vtkWrite.cxx + vtkWriteImpl.cxx + vtkWriteUpdate.cxx \*---------------------------------------------------------------------------*/ @@ -193,7 +194,7 @@ class vtkWrite bool writeIds_; //- Track changes in mesh geometry - enum polyMesh::readUpdateState meshState_; + polyMesh::readUpdateState meshState_; //- Requested names of regions to process wordRes selectRegions_; @@ -294,13 +295,6 @@ class vtkWrite ) const; - //- No copy construct - vtkWrite(const vtkWrite&) = delete; - - //- No copy assignment - void operator=(const vtkWrite&) = delete; - - public: //- Runtime type information @@ -317,6 +311,12 @@ public: const dictionary& dict ); + //- No copy construct + vtkWrite(const vtkWrite&) = delete; + + //- No copy assignment + void operator=(const vtkWrite&) = delete; + //- Destructor virtual ~vtkWrite() = default; diff --git a/src/functionObjects/utilities/vtkWrite/vtkWrite.C b/src/functionObjects/utilities/vtkWrite/vtkWrite.cxx similarity index 98% rename from src/functionObjects/utilities/vtkWrite/vtkWrite.C rename to src/functionObjects/utilities/vtkWrite/vtkWrite.cxx index 3ccc27c01f..161d9d8de9 100644 --- a/src/functionObjects/utilities/vtkWrite/vtkWrite.C +++ b/src/functionObjects/utilities/vtkWrite/vtkWrite.cxx @@ -49,7 +49,7 @@ namespace functionObjects // Implementation -#include "vtkWriteImpl.C" +#include "vtkWriteImpl.cxx" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // @@ -134,8 +134,6 @@ Foam::functionObjects::vtkWrite::vtkWrite ) : timeFunctionObject(name, runTime), - outputDir_(), - printf_(), writeOpts_(vtk::formatType::INLINE_BASE64), verbose_(true), doInternal_(true), @@ -144,17 +142,7 @@ Foam::functionObjects::vtkWrite::vtkWrite interpolate_(false), decompose_(false), writeIds_(false), - meshState_(polyMesh::TOPO_CHANGE), - selectRegions_(), - selectPatches_(), - blockPatches_(), - selectFields_(), - blockFields_(), - selection_(), - meshes_(), - meshSubsets_(), - vtuMappings_(), - series_() + meshState_(polyMesh::TOPO_CHANGE) { // May still want this? (OCT-2018) // if (postProcess) diff --git a/src/functionObjects/utilities/vtkWrite/vtkWriteImpl.C b/src/functionObjects/utilities/vtkWrite/vtkWriteImpl.cxx similarity index 100% rename from src/functionObjects/utilities/vtkWrite/vtkWriteImpl.C rename to src/functionObjects/utilities/vtkWrite/vtkWriteImpl.cxx diff --git a/src/functionObjects/utilities/vtkWrite/vtkWriteUpdate.C b/src/functionObjects/utilities/vtkWrite/vtkWriteUpdate.cxx similarity index 100% rename from src/functionObjects/utilities/vtkWrite/vtkWriteUpdate.C rename to src/functionObjects/utilities/vtkWrite/vtkWriteUpdate.cxx diff --git a/src/lagrangian/intermediate/Make/files b/src/lagrangian/intermediate/Make/files index 445cbc2a20..c005bf2abc 100644 --- a/src/lagrangian/intermediate/Make/files +++ b/src/lagrangian/intermediate/Make/files @@ -126,8 +126,8 @@ submodels/CloudFunctionObjects/CloudFunctionObject/cloudFunctionObjectTools.C submodels/MPPIC/AveragingMethods/makeAveragingMethods.C /* conversion methods */ -conversion/ensight/ensightOutputCloud.C -conversion/vtk/foamVtkLagrangianWriter.C +conversion/ensight/ensightOutputCloud.cxx +conversion/vtk/foamVtkLagrangianWriter.cxx LIB = $(FOAM_LIBBIN)/liblagrangianIntermediate diff --git a/src/lagrangian/intermediate/conversion/ensight/ensightOutputCloud.H b/src/lagrangian/intermediate/conversion/ensight/ensightOutputCloud.H index 323296eb26..0aa40eb05d 100644 --- a/src/lagrangian/intermediate/conversion/ensight/ensightOutputCloud.H +++ b/src/lagrangian/intermediate/conversion/ensight/ensightOutputCloud.H @@ -30,8 +30,8 @@ Description A collection of functions for writing clouds as ensight file content. SourceFiles - ensightOutputCloud.C - ensightOutputCloudTemplates.C + ensightOutputCloud.cxx + ensightOutputCloud.txx \*---------------------------------------------------------------------------*/ @@ -181,7 +181,7 @@ label writeCloudFieldContent // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository - #include "ensightOutputCloudTemplates.C" + #include "ensightOutputCloud.txx" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/lagrangian/intermediate/conversion/ensight/ensightOutputCloud.C b/src/lagrangian/intermediate/conversion/ensight/ensightOutputCloud.cxx similarity index 100% rename from src/lagrangian/intermediate/conversion/ensight/ensightOutputCloud.C rename to src/lagrangian/intermediate/conversion/ensight/ensightOutputCloud.cxx diff --git a/src/lagrangian/intermediate/conversion/ensight/ensightOutputCloudTemplates.C b/src/lagrangian/intermediate/conversion/ensight/ensightOutputCloud.txx similarity index 100% rename from src/lagrangian/intermediate/conversion/ensight/ensightOutputCloudTemplates.C rename to src/lagrangian/intermediate/conversion/ensight/ensightOutputCloud.txx diff --git a/src/lagrangian/intermediate/conversion/vtk/foamVtkLagrangianWriter.H b/src/lagrangian/intermediate/conversion/vtk/foamVtkLagrangianWriter.H index 36e0024622..eed2779258 100644 --- a/src/lagrangian/intermediate/conversion/vtk/foamVtkLagrangianWriter.H +++ b/src/lagrangian/intermediate/conversion/vtk/foamVtkLagrangianWriter.H @@ -40,8 +40,8 @@ Note must be decided at construction time. SourceFiles - lagrangianWriter.C - lagrangianWriterTemplates.C + foamVtkLagrangianWriter.cxx + foamVtkLagrangianWriter.txx \*---------------------------------------------------------------------------*/ @@ -229,7 +229,7 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository - #include "foamVtkLagrangianWriterTemplates.C" + #include "foamVtkLagrangianWriter.txx" #endif diff --git a/src/lagrangian/intermediate/conversion/vtk/foamVtkLagrangianWriter.C b/src/lagrangian/intermediate/conversion/vtk/foamVtkLagrangianWriter.cxx similarity index 100% rename from src/lagrangian/intermediate/conversion/vtk/foamVtkLagrangianWriter.C rename to src/lagrangian/intermediate/conversion/vtk/foamVtkLagrangianWriter.cxx diff --git a/src/lagrangian/intermediate/conversion/vtk/foamVtkLagrangianWriterTemplates.C b/src/lagrangian/intermediate/conversion/vtk/foamVtkLagrangianWriter.txx similarity index 100% rename from src/lagrangian/intermediate/conversion/vtk/foamVtkLagrangianWriterTemplates.C rename to src/lagrangian/intermediate/conversion/vtk/foamVtkLagrangianWriter.txx diff --git a/src/meshTools/Make/files b/src/meshTools/Make/files index eb64fa51a0..1e6d481bd0 100644 --- a/src/meshTools/Make/files +++ b/src/meshTools/Make/files @@ -344,8 +344,8 @@ meshStructure/meshStructure.C coupling/externalFileCoupler.C vtk = output/vtk -$(vtk)/mesh/foamVtkInternalMeshWriter.C -$(vtk)/patch/foamVtkPatchMeshWriter.C +$(vtk)/mesh/foamVtkInternalMeshWriter.cxx +$(vtk)/patch/foamVtkPatchMeshWriter.cxx $(vtk)/topoSet/foamVtkWriteTopoSet.C $(vtk)/topoSet/foamVtkWriteFaceSet.C $(vtk)/topoSet/foamVtkWritePointSet.C diff --git a/src/meshTools/output/vtk/mesh/foamVtkInternalMeshWriter.H b/src/meshTools/output/vtk/mesh/foamVtkInternalMeshWriter.H index 00da9739a7..67e3609a59 100644 --- a/src/meshTools/output/vtk/mesh/foamVtkInternalMeshWriter.H +++ b/src/meshTools/output/vtk/mesh/foamVtkInternalMeshWriter.H @@ -44,8 +44,8 @@ See Also Foam::vtk::internalWriter SourceFiles - foamVtkInternalMeshWriter.C - foamVtkInternalMeshWriterTemplates.C + foamVtkInternalMeshWriter.cxx + foamVtkInternalMeshWriter.txx \*---------------------------------------------------------------------------*/ @@ -240,7 +240,7 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository - #include "foamVtkInternalMeshWriterTemplates.C" + #include "foamVtkInternalMeshWriter.txx" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/meshTools/output/vtk/mesh/foamVtkInternalMeshWriter.C b/src/meshTools/output/vtk/mesh/foamVtkInternalMeshWriter.cxx similarity index 100% rename from src/meshTools/output/vtk/mesh/foamVtkInternalMeshWriter.C rename to src/meshTools/output/vtk/mesh/foamVtkInternalMeshWriter.cxx diff --git a/src/meshTools/output/vtk/mesh/foamVtkInternalMeshWriterTemplates.C b/src/meshTools/output/vtk/mesh/foamVtkInternalMeshWriter.txx similarity index 100% rename from src/meshTools/output/vtk/mesh/foamVtkInternalMeshWriterTemplates.C rename to src/meshTools/output/vtk/mesh/foamVtkInternalMeshWriter.txx diff --git a/src/meshTools/output/vtk/patch/foamVtkPatchMeshWriter.H b/src/meshTools/output/vtk/patch/foamVtkPatchMeshWriter.H index de259f740d..a0fe5dcbd8 100644 --- a/src/meshTools/output/vtk/patch/foamVtkPatchMeshWriter.H +++ b/src/meshTools/output/vtk/patch/foamVtkPatchMeshWriter.H @@ -43,8 +43,8 @@ See Also Foam::vtk::patchWriter SourceFiles - foamVtkPatchMeshWriter.C - foamVtkPatchMeshWriterTemplates.C + foamVtkPatchMeshWriter.cxx + foamVtkPatchMeshWriter.txx \*---------------------------------------------------------------------------*/ @@ -234,7 +234,7 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository - #include "foamVtkPatchMeshWriterTemplates.C" + #include "foamVtkPatchMeshWriter.txx" #endif diff --git a/src/meshTools/output/vtk/patch/foamVtkPatchMeshWriter.C b/src/meshTools/output/vtk/patch/foamVtkPatchMeshWriter.cxx similarity index 100% rename from src/meshTools/output/vtk/patch/foamVtkPatchMeshWriter.C rename to src/meshTools/output/vtk/patch/foamVtkPatchMeshWriter.cxx diff --git a/src/meshTools/output/vtk/patch/foamVtkPatchMeshWriterTemplates.C b/src/meshTools/output/vtk/patch/foamVtkPatchMeshWriter.txx similarity index 100% rename from src/meshTools/output/vtk/patch/foamVtkPatchMeshWriterTemplates.C rename to src/meshTools/output/vtk/patch/foamVtkPatchMeshWriter.txx diff --git a/src/surfMesh/readers/boundary/boundaryDataSurfaceReader.H b/src/surfMesh/readers/boundary/boundaryDataSurfaceReader.H index 102f2ccc25..b57d461d95 100644 --- a/src/surfMesh/readers/boundary/boundaryDataSurfaceReader.H +++ b/src/surfMesh/readers/boundary/boundaryDataSurfaceReader.H @@ -55,7 +55,7 @@ Description SourceFiles boundaryDataSurfaceReader.C - boundaryDataSurfaceReaderTemplates.C + boundaryDataSurfaceReader.txx \*---------------------------------------------------------------------------*/ @@ -242,7 +242,7 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository - #include "boundaryDataSurfaceReaderTemplates.C" + #include "boundaryDataSurfaceReader.txx" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/surfMesh/readers/boundary/boundaryDataSurfaceReaderTemplates.C b/src/surfMesh/readers/boundary/boundaryDataSurfaceReader.txx similarity index 100% rename from src/surfMesh/readers/boundary/boundaryDataSurfaceReaderTemplates.C rename to src/surfMesh/readers/boundary/boundaryDataSurfaceReader.txx diff --git a/src/surfMesh/readers/ensight/ensightSurfaceReader.H b/src/surfMesh/readers/ensight/ensightSurfaceReader.H index e8921db814..7aae755b39 100644 --- a/src/surfMesh/readers/ensight/ensightSurfaceReader.H +++ b/src/surfMesh/readers/ensight/ensightSurfaceReader.H @@ -49,7 +49,7 @@ Description SourceFiles ensightSurfaceReader.C - ensightSurfaceReaderTemplates.C + ensightSurfaceReader.txx \*---------------------------------------------------------------------------*/ @@ -285,7 +285,7 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository - #include "ensightSurfaceReaderTemplates.C" + #include "ensightSurfaceReader.txx" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/surfMesh/readers/ensight/ensightSurfaceReaderTemplates.C b/src/surfMesh/readers/ensight/ensightSurfaceReader.txx similarity index 100% rename from src/surfMesh/readers/ensight/ensightSurfaceReaderTemplates.C rename to src/surfMesh/readers/ensight/ensightSurfaceReader.txx From ccb57c0499ead542b1ef852298bf99cfc3caef61 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Mon, 29 Sep 2025 10:18:11 +0200 Subject: [PATCH 04/18] ENH: increase some string_view coverage - remove some stdFoam::span handling, which was just a stop-gap measure --- .../test/string_view1/Test-string_view1.cxx | 5 -- src/OpenFOAM/db/IOstreams/IOstreams/Ostream.H | 16 ---- src/OpenFOAM/db/IOstreams/Tstreams/ITstream.C | 28 +++++-- src/OpenFOAM/db/IOstreams/Tstreams/ITstream.H | 74 +++---------------- .../db/IOstreams/memory/ISpanStream.H | 48 ------------ .../primitives/strings/lists/CStringList.H | 20 ++++- .../primitives/strings/lists/CStringList.cxx | 10 --- .../primitives/strings/lists/CStringListI.H | 43 ++++++++++- 8 files changed, 94 insertions(+), 150 deletions(-) diff --git a/applications/test/string_view1/Test-string_view1.cxx b/applications/test/string_view1/Test-string_view1.cxx index bbb24dc8fe..87c420ea80 100644 --- a/applications/test/string_view1/Test-string_view1.cxx +++ b/applications/test/string_view1/Test-string_view1.cxx @@ -59,11 +59,6 @@ int main(int argc, char *argv[]) << " type: " << typeid(cstr).name() << " len:" << len << nl; Info<< " view: " << std::string_view(cstr) << nl; - - Info<< " span: " - << stdFoam::span(cstr, len) << nl; - Info<< " span: " - << stdFoam::span(const_cast(cstr), len) << nl; } } diff --git a/src/OpenFOAM/db/IOstreams/IOstreams/Ostream.H b/src/OpenFOAM/db/IOstreams/IOstreams/Ostream.H index beb8687bb1..38c09dd2ee 100644 --- a/src/OpenFOAM/db/IOstreams/IOstreams/Ostream.H +++ b/src/OpenFOAM/db/IOstreams/IOstreams/Ostream.H @@ -341,22 +341,6 @@ inline Ostream& operator<<(Ostream& os, std::string_view s) return os; } -//- Write operator for character span. Output like string data -inline Ostream& operator<<(Ostream& os, stdFoam::span s) -{ - os.writeQuoted(s.data(), s.size(), true); // quoted - os.check("Foam::operator<<(Ostream&, stdFoam::span)"); - return os; -} - -//- Write operator for const character span. Output like string data -inline Ostream& operator<<(Ostream& os, stdFoam::span s) -{ - os.writeQuoted(s.data(), s.size(), true); // quoted - os.check("Foam::operator<<(Ostream&, stdFoam::span)"); - return os; -} - /*---------------------------------------------------------------------------*\ Manipulators (without arguments) diff --git a/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.C b/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.C index a487f0fe21..a4a3df399a 100644 --- a/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.C +++ b/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.C @@ -95,10 +95,12 @@ Foam::tokenList Foam::ITstream::parse_chars IOstreamOption streamOpt ) { - ISpanStream is(s, nbytes, streamOpt); - tokenList tokens; - parseStream(is, tokens); + if (s && nbytes > 0) // extra safety + { + ISpanStream is(s, nbytes, streamOpt); + parseStream(is, tokens); + } return tokens; } @@ -107,10 +109,19 @@ Foam::tokenList Foam::ITstream::parse_chars void Foam::ITstream::reset(const char* input, size_t nbytes) { - ISpanStream is(input, nbytes, static_cast(*this)); + tokenList tokens; + if (input && nbytes > 0) // extra safety + { + ISpanStream is(input, nbytes, static_cast(*this)); - parseStream(is, static_cast(*this)); - ITstream::seek(0); // rewind() bypassing virtual + parseStream(is, static_cast(*this)); + ITstream::seek(0); // rewind() bypassing virtual + } + else + { + ITstream::seek(0); // rewind() bypassing virtual + tokenList::clear(); + } } @@ -248,7 +259,10 @@ Foam::ITstream::ITstream : ITstream(streamOpt, name) { - reset(input, strlen(input)); + if (input) + { + reset(input, strlen(input)); + } } diff --git a/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.H b/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.H index cf2e2239bb..d0c127bb53 100644 --- a/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.H +++ b/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.H @@ -77,7 +77,8 @@ class ITstream // but leave any excess capacity (ie, like reserve). void reserveCapacity(const label newCapacity); - //- Convert input sequence into a list of tokens, + //- Convert input sequence into a list of tokens. + // Includes nullptr guard static tokenList parse_chars ( const char* s, @@ -87,6 +88,7 @@ class ITstream //- Convert input sequence into a list of tokens, //- using the existing stream format. Rewinds the stream + // Includes nullptr guard void reset(const char* input, size_t nbytes); //- Failsafe read-access to token at specified location @@ -175,32 +177,6 @@ public: reset(s.data(), s.size()); } - //- Construct token list by parsing the input character sequence - // Uses static parse function internally. - explicit ITstream - ( - stdFoam::span s, - IOstreamOption streamOpt = IOstreamOption() - ) - : - ITstream(streamOpt) - { - reset(s.data(), s.size()); - } - - //- Construct token list by parsing the input character sequence - // Uses static parse function internally. - explicit ITstream - ( - stdFoam::span s, - IOstreamOption streamOpt = IOstreamOption() - ) - : - ITstream(streamOpt) - { - reset(s.data(), s.size()); - } - // Additional constructors @@ -255,17 +231,6 @@ public: return parse_chars(input.cdata(), input.size(), streamOpt); } - //- Create token list by parsing the input string - //- until no good tokens remain. - static tokenList parse - ( - const std::string& input, - IOstreamOption streamOpt = IOstreamOption() - ) - { - return parse_chars(input.data(), input.size(), streamOpt); - } - //- Create token list by parsing the input character sequence //- until no good tokens remain. static tokenList parse @@ -274,7 +239,14 @@ public: IOstreamOption streamOpt = IOstreamOption() ) { - return parse_chars(input, strlen(input), streamOpt); + if (input) + { + return parse_chars(input, strlen(input), streamOpt); + } + else + { + return tokenList(); + } } //- Create token list by parsing the input character sequence @@ -288,28 +260,6 @@ public: return parse_chars(s.data(), s.size(), streamOpt); } - //- Create token list by parsing the input character sequence - //- until no good tokens remain. - static tokenList parse - ( - stdFoam::span s, - IOstreamOption streamOpt = IOstreamOption() - ) - { - return parse_chars(s.data(), s.size(), streamOpt); - } - - //- Create token list by parsing the input character sequence - //- until no good tokens remain. - static tokenList parse - ( - stdFoam::span s, - IOstreamOption streamOpt = IOstreamOption() - ) - { - return parse_chars(s.data(), s.size(), streamOpt); - } - // Member Functions @@ -387,7 +337,7 @@ public: label& tokenIndex() noexcept { return tokenIndex_; } //- Set the token index (no checks). \return the previous value - label tokenIndex(const label num) noexcept + label tokenIndex(label num) noexcept { label old(tokenIndex_); tokenIndex_ = num; diff --git a/src/OpenFOAM/db/IOstreams/memory/ISpanStream.H b/src/OpenFOAM/db/IOstreams/memory/ISpanStream.H index ae73dbf42c..89c11699bc 100644 --- a/src/OpenFOAM/db/IOstreams/memory/ISpanStream.H +++ b/src/OpenFOAM/db/IOstreams/memory/ISpanStream.H @@ -123,20 +123,6 @@ public: stream_type(static_cast(this)) {} - //- Construct (shallow copy) from span character content - explicit ispanstream(stdFoam::span s) - : - buffer_type(const_cast(s.data()), s.size()), - stream_type(static_cast(this)) - {} - - //- Construct (shallow copy) from span character content - explicit ispanstream(stdFoam::span s) - : - buffer_type(const_cast(s.data()), s.size()), - stream_type(static_cast(this)) - {} - // Member Functions @@ -325,26 +311,6 @@ public: ISpanStream(buffer.cdata(), buffer.size(), streamOpt) {} - //- Construct (shallow copy) from span character content - explicit ISpanStream - ( - stdFoam::span s, - IOstreamOption streamOpt = IOstreamOption() - ) - : - ISpanStream(s.data(), s.size(), streamOpt) - {} - - //- Construct (shallow copy) from span character content - explicit ISpanStream - ( - stdFoam::span s, - IOstreamOption streamOpt = IOstreamOption() - ) - : - ISpanStream(s.data(), s.size(), streamOpt) - {} - // Member Functions @@ -402,20 +368,6 @@ public: syncState(); } - //- Reset input area to use data from span character content - void reset(stdFoam::span s) - { - stream_.reset(s.data(), s.size()); - syncState(); - } - - //- Reset input area to use data from span character content - void reset(stdFoam::span s) - { - stream_.reset(s.data(), s.size()); - syncState(); - } - //- Rewind the stream, clearing any old errors virtual void rewind() override { diff --git a/src/OpenFOAM/primitives/strings/lists/CStringList.H b/src/OpenFOAM/primitives/strings/lists/CStringList.H index c4977a298d..fd24374be1 100644 --- a/src/OpenFOAM/primitives/strings/lists/CStringList.H +++ b/src/OpenFOAM/primitives/strings/lists/CStringList.H @@ -58,6 +58,8 @@ Description #include // std::copy #include // std::initializer_list +#include +#include // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -93,6 +95,11 @@ class CStringList // \return location one-past end of dest (ie, the next destination) static inline char* stringCopy(char* dest, const char* src); + //- Copy string characters into dest as NUL-terminated string. + // + // \return location one-past end of dest (ie, the next destination) + static inline char* stringCopy(char *dest, std::string_view src); + //- Copy string characters into dest as NUL-terminated string. // Forces conversion of std::sub_match to string form // @@ -133,9 +140,17 @@ public: template inline explicit CStringList(const UList& input); + //- Copy construct from a list of string_views + // Copies the input characters. + inline explicit CStringList(const UList& input); + + //- Copy construct from a list of string_views + // Copies the input characters. + inline explicit CStringList(const std::vector& input); + //- Copy construct from a list of sub-string references // Copies the input characters. - explicit CStringList(const SubStrings& input); + inline explicit CStringList(const SubStrings& input); //- Destructor. Invokes clear() to free memory. @@ -157,6 +172,9 @@ public: //- Return the number of C-strings (ie, argc) int size() const noexcept { return argc_; } + //- The flattened character content, with interspersed nul-chars + inline std::string_view view() const; + //- The flattened character content, with interspersed nul-chars const char* cdata_bytes() const noexcept { return data_; } diff --git a/src/OpenFOAM/primitives/strings/lists/CStringList.cxx b/src/OpenFOAM/primitives/strings/lists/CStringList.cxx index 0eead0d803..e7b182f49f 100644 --- a/src/OpenFOAM/primitives/strings/lists/CStringList.cxx +++ b/src/OpenFOAM/primitives/strings/lists/CStringList.cxx @@ -28,16 +28,6 @@ License #include "CStringList.H" #include "Ostream.H" -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -Foam::CStringList::CStringList(const SubStrings& input) -: - CStringList() -{ - resetContent(input); -} - - // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // Largely identical to resetContent() except with 'c-string' diff --git a/src/OpenFOAM/primitives/strings/lists/CStringListI.H b/src/OpenFOAM/primitives/strings/lists/CStringListI.H index 87dbc7bac3..9d1a8840fe 100644 --- a/src/OpenFOAM/primitives/strings/lists/CStringListI.H +++ b/src/OpenFOAM/primitives/strings/lists/CStringListI.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2016-2024 OpenCFD Ltd. + Copyright (C) 2016-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -35,6 +35,14 @@ inline char* Foam::CStringList::stringCopy(char* dest, const char* src) } +inline char* Foam::CStringList::stringCopy(char *dest, std::string_view src) +{ + dest = std::copy_n(src.data(), src.size(), dest); + *(dest++) = '\0'; + return dest; +} + + inline char* Foam::CStringList::stringCopy(char *dest, const std::string& src) { dest = std::copy_n(src.data(), src.size(), dest); @@ -90,6 +98,33 @@ inline Foam::CStringList::CStringList(const UList& input) } +inline Foam::CStringList::CStringList(const UList& input) +: + CStringList() +{ + resetContent(input); +} + + +inline Foam::CStringList::CStringList +( + const std::vector& input +) +: + CStringList() +{ + resetContent(input); +} + + +inline Foam::CStringList::CStringList(const SubStrings& input) +: + CStringList() +{ + resetContent(input); +} + + // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // inline Foam::CStringList::~CStringList() @@ -100,6 +135,12 @@ inline Foam::CStringList::~CStringList() // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +inline std::string_view Foam::CStringList::view() const +{ + return std::string_view(data_, nbytes_); +} + + inline void Foam::CStringList::clear() { argc_ = 0; From c7b5f1e3ebab5075556bd60beefc991a58442d52 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Thu, 9 Oct 2025 23:58:44 +0200 Subject: [PATCH 05/18] ENH: added clean up function remove0DirFields (RunFunctions) - less typing than before and avoids relying on bash-specific behaviour (fixes #3448) ENH: add -region support for cleanFaMesh and cleanPolyMesh CONFIG: add bash completion help for -area-region ENH: general improvements for regionProperties - robustness and failsafe for foamListRegions, regionProperties - additional global model switches for regionModels --- .../foamListRegions/foamListRegions.C | 113 ++++++++------ bin/foamCleanFaMesh | 138 ++++++++++++++++++ bin/foamCleanPolyMesh | 133 ++++++++++------- bin/tools/CleanFunctions | 100 ++++++++++--- bin/tools/RunFunctions | 59 ++++++++ etc/config.sh/bash_completion | 5 + src/meshTools/Make/files | 3 +- .../regionModelProperties.cxx | 49 +++++++ .../regionProperties/regionProperties.H | 36 ++++- ...egionProperties.C => regionProperties.cxx} | 27 ++++ .../2DImplicitCyclic/Allmesh | 5 +- .../externalCoupledHeater/Allrun.pre | 5 +- .../externalSolarLoad/Allrun.pre | 5 +- .../multiRegionHeater/Allrun.pre | 5 +- .../snappyMultiRegionHeater/Allrun-parallel | 5 +- .../snappyMultiRegionHeater/Allrun-serial | 5 +- .../snappyMultiRegionHeaterImplicit/Allrun | 5 +- .../solarBeamWithTrees/Allrun.pre | 5 +- .../externalCoupledHeater/Allrun.pre | 5 +- .../multiRegionHeaterRadiation/Allrun.pre | 5 +- 20 files changed, 571 insertions(+), 142 deletions(-) create mode 100755 bin/foamCleanFaMesh create mode 100644 src/meshTools/regionModel/regionProperties/regionModelProperties.cxx rename src/meshTools/regionModel/regionProperties/{regionProperties.C => regionProperties.cxx} (86%) diff --git a/applications/utilities/miscellaneous/foamListRegions/foamListRegions.C b/applications/utilities/miscellaneous/foamListRegions/foamListRegions.C index fa7ef04e77..4f655c23a8 100644 --- a/applications/utilities/miscellaneous/foamListRegions/foamListRegions.C +++ b/applications/utilities/miscellaneous/foamListRegions/foamListRegions.C @@ -30,7 +30,8 @@ Group grpPostProcessingUtilities Description - List regions from constant/regionProperties. + List volume regions from constant/regionProperties + or area regions from constant/finite-area/regionProperties Usage \b foamListRegions [OPTION] @@ -72,6 +73,12 @@ int main(int argc, char *argv[]) "List constant/finite-area/regionProperties (if available)" ); + argList::addBoolOption + ( + "optional", + "A missing regionProperties is not treated as an error" + ); + argList::addDryRunOption ( "Make reading optional and add verbosity" @@ -92,14 +99,20 @@ int main(int argc, char *argv[]) ++optVerbose; } + // File is optional, not an error + const bool isOptional = args.found("optional"); + // Use finite-area regions const bool doFiniteArea = args.found("finite-area"); + // The number of optional region filters to apply + const label nFilters = (args.size()-1); + IOobjectOption::readOption readOpt(IOobjectOption::MUST_READ); - if (dryRun || doFiniteArea) + if (dryRun || isOptional || doFiniteArea) { - // Always treat finite-area regionProperties as optional + // The finite-area regionProperties are also considered optional readOpt = IOobjectOption::READ_IF_PRESENT; } @@ -116,58 +129,70 @@ int main(int argc, char *argv[]) if (doFiniteArea) { regionProps = regionProperties(runTime, faMeshPrefix, readOpt); - - if (regionProps.empty()) - { - InfoErr<< "No finite-area region types" << nl; - } - else if (optVerbose) - { - InfoErr - << "Have " << regionProps.size() - << " finite-area region types, " - << regionProps.count() << " regions" << nl << nl; - } } else { regionProps = regionProperties(runTime, readOpt); - - if (regionProps.empty()) - { - // Probably only occurs with -dry-run option - InfoErr<< "No region types" << nl; - } - else if (optVerbose) - { - InfoErr - << "Have " << regionProps.size() << " region types, " - << regionProps.count() << " regions" << nl << nl; - } } - // We now handle checking args and general sanity etc. - wordList regionTypes; - - if (args.size() > 1) + // Some reporting... + if (regionProps.empty()) { - regionTypes.resize(args.size()-1); + if (doFiniteArea) + { + InfoErr<< "No finite-area region types" << nl; + } + else if (isOptional) + { + InfoErr<< "No region types" << nl; + } + } + else if (optVerbose) + { + InfoErr << "Have " << regionProps.size(); - // No duplicates + if (doFiniteArea) + { + InfoErr<< " finite-area"; + } + InfoErr + << " region types, " + << regionProps.count() << " regions" << nl << nl; + } + + + // We now handle checking args and general sanity etc. + + DynamicList regionTypes; + + if (isOptional && regionProps.empty()) + { + // Nothing to do... + } + else if (nFilters > 0) + { + // Apply region filters + + regionTypes.reserve_exact + ( + Foam::min(nFilters, regionProps.size()) + ); + + // No duplicates, and no duplicate warnings wordHashSet uniq; - label nTypes = 0; for (label argi = 1; argi < args.size(); ++argi) { - regionTypes[nTypes] = args[argi]; - - const word& regType = regionTypes[nTypes]; + word regType(args[argi]); if (uniq.insert(regType)) { if (regionProps.contains(regType)) { - ++nTypes; + if (!regionTypes.contains(regType)) + { + regionTypes.push_back(std::move(regType)); + } } else { @@ -175,22 +200,22 @@ int main(int argc, char *argv[]) } } } - - regionTypes.resize(nTypes); } else { + // Take all regions regionTypes = regionProps.sortedToc(); } for (const word& regionType : regionTypes) { - const wordList& regionNames = regionProps[regionType]; - - for (const word& regionName : regionNames) + if (const auto iter = regionProps.cfind(regionType); iter.good()) { - Info<< regionName << nl; + for (const word& regionName : iter.val()) + { + Info<< regionName << nl; + } } } diff --git a/bin/foamCleanFaMesh b/bin/foamCleanFaMesh new file mode 100755 index 0000000000..08359d082d --- /dev/null +++ b/bin/foamCleanFaMesh @@ -0,0 +1,138 @@ +#!/bin/sh +#------------------------------------------------------------------------------ +# ========= | +# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox +# \\ / O peration | +# \\ / A nd | www.openfoam.com +# \\/ M anipulation | +#------------------------------------------------------------------------------- +# Copyright (C) 2011 OpenFOAM Foundation +# Copyright (C) 2025 OpenCFD Ltd. +#------------------------------------------------------------------------------ +# License +# This file is part of OpenFOAM, distributed under GPL-3.0-or-later. +# +# Script +# foamCleanFaMesh +# +# Description +# Remove the contents of the constant/finite-area/faMesh directory +# as per the Foam::faMesh::removeFiles() method. +# +#------------------------------------------------------------------------------ +usage() { + exec 1>&2 + while [ "$#" -ge 1 ]; do echo "$1"; shift; done + cat < case directory, default is the cwd + -area-region area-mesh region + -dry-run | -n report actions but do not remove + -help print the usage + +Remove the contents of the constant/finite-area/faMesh directory as per the +Foam::faMesh::removeFiles() method. + +USAGE + exit 1 +} + +#------------------------------------------------------------------------------ +# Parse options +unset caseDir areaRegion optDryRun + +while [ "$#" -gt 0 ] +do + case "$1" in + -h | -help*) + usage + ;; + -dry-run | -n) + optDryRun="(dry-run) " + ;; + + -case=*) + caseDir="${1#*=}" + ;; + + -case) + [ "$#" -ge 2 ] || usage "'$1' option requires an argument" + cd "$2" 2>/dev/null || usage "directory does not exist: '$2'" + caseDir=$2 + shift + ;; + + -area-region) + [ "$#" -ge 2 ] || usage "'$1' option requires an argument" + areaRegion=$2 + shift + ;; + + (*) + usage "unknown option/argument: '$*'" + ;; + esac + shift +done + +#------------------------------------------------------------------------------ + +# Remove files (mesh etc) +# also remove .gz versions of the same files + +removeFiles() +{ + local directory="$1" + + for i in \ + faceLabels \ + faBoundary \ + ; + do + if [ -n "$optDryRun" ] + then + echo "${optDryRun} rm -rf $directory/{$i,$i.gz}" + else + rm -rf -- "$directory/$i" "$directory/$i.gz" + fi + done +} + +#------------------------------------------------------------------------------ + +meshDir="constant/finite-area/${areaRegion}${areaRegion:+/}faMesh" + +if [ -d "$meshDir" ] +then + # [OK] has constant/finite-areaRegion//faMesh + : + +elif [ -n "$caseDir" ] +then + # Specified -case, so no extra magic... + echo "Error: no <$meshDir> in $caseDir" 1>&2 + exit 1 + +else + # Try some other combinations + other="${meshDir#constant/}" + + if [ -d "$other" ] + then + # Probably already within constant/ + meshDir="$other}" + elif [ "${PWD##*/}" = faMesh ] && [ -z "$areaRegion" ] + then + # Apparently already within faMesh/ + meshDir=. + fi +fi + + +echo "Cleaning ${caseDir:-.}/$meshDir" 1>&2 + +removeFiles "$meshDir" + +#------------------------------------------------------------------------------ diff --git a/bin/foamCleanPolyMesh b/bin/foamCleanPolyMesh index 5965c15bd5..b9a91400f2 100755 --- a/bin/foamCleanPolyMesh +++ b/bin/foamCleanPolyMesh @@ -7,7 +7,7 @@ # \\/ M anipulation | #------------------------------------------------------------------------------- # Copyright (C) 2011-2016 OpenFOAM Foundation -# Copyright (C) 2022 OpenCFD Ltd. +# Copyright (C) 2022,2025 OpenCFD Ltd. #------------------------------------------------------------------------------ # License # This file is part of OpenFOAM, distributed under GPL-3.0-or-later. @@ -27,9 +27,10 @@ usage() { Usage: ${0##*/} [OPTION] options: - -case specify alternative case directory, default is the cwd - -region specify alternative mesh region - -help print the usage + -case case directory, default is the cwd + -region mesh region + -dry-run | -n report actions but do not remove + -help print the usage Remove the contents of the constant/polyMesh directory as per the Foam::polyMesh::removeFiles() method. @@ -38,58 +39,101 @@ USAGE exit 1 } -unset caseDir regionName +#------------------------------------------------------------------------------ +# Parse options +unset caseDir regionName optDryRun -# Parse a single option while [ "$#" -gt 0 ] do case "$1" in -h | -help*) usage ;; + -dry-run | -n) + optDryRun="(dry-run) " + ;; + + -case=*) + caseDir="${1#*=}" + ;; + -case) + caseDir="$2" [ "$#" -ge 2 ] || usage "'$1' option requires an argument" cd "$2" 2>/dev/null || usage "directory does not exist: '$2'" caseDir=$2 - shift 2 + shift ;; + -region) [ "$#" -ge 2 ] || usage "'$1' option requires an argument" - regionName=$2 - shift 2 + regionName="$2" + shift ;; - *) + + (*) usage "unknown option/argument: '$*'" ;; esac + shift done -meshDir=polyMesh -if [ -n "$regionName" ] -then - meshDir="$regionName/$meshDir" -fi +#------------------------------------------------------------------------------ -# If -case was specified: insist upon 'constant/polyMesh' -if [ -n "$caseDir" ] +# Remove files (mesh itself, modifiers, snappyHexMesh ones) and subdirectories +# also remove .gz versions of the same files + +removeFiles() +{ + local directory="$1" + + for i in \ + points faces \ + owner neighbour \ + boundary \ + cells \ + cellZones faceZones pointZones \ + meshModifiers \ + parallelData \ + sets \ + cellLevel pointLevel \ + level0Edge \ + refinementHistory \ + surfaceIndex \ + ; + do + if [ -n "$optDryRun" ] + then + echo "${optDryRun} rm -rf $directory/{$i,$i.gz}" + else + rm -rf -- "$directory/$i" "$directory/$i.gz" + fi + done +} + +#------------------------------------------------------------------------------ + +meshDir="constant/${regionName}${regionName:+/}polyMesh" + +if [ -d "$meshDir" ] then - if [ -d constant/"$meshDir" ] - then - # Use constant/polyMesh - meshDir=constant/"$meshDir" - else - echo "Error: no 'constant/$meshDir' in $caseDir" 1>&2 - exit 1 - fi + # [OK] has constant//polyMesh + : + +elif [ -n "$caseDir" ] +then + # Specified -case, so no extra magic... + echo "Error: no <$meshDir> in $caseDir" 1>&2 + exit 1 + else - if [ -d constant/"$meshDir" ] + # Try some other combinations + other="${meshDir#constant/}" + + if [ -d "$other" ] then - # Use constant/polyMesh - meshDir=constant/"$meshDir" - elif [ -d "$meshDir" ] - then - # Likely already in constant/ - do not adjust anything - : + # Probably already within constant/ + meshDir="$other}" elif [ "${PWD##*/}" = polyMesh ] && [ -z "$regionName" ] then # Apparently already within polyMesh/ @@ -98,31 +142,8 @@ else fi -# Remove files (mesh itself, modifiers, snappyHexMesh ones) and subdirectories -# also remove .gz versions of the same files echo "Cleaning ${caseDir:-.}/$meshDir" 1>&2 -for i in \ - points \ - faces \ - owner \ - neighbour \ - cells \ - boundary \ - pointZones \ - faceZones \ - cellZones \ - meshModifiers \ - parallelData \ - sets \ - cellLevel \ - pointLevel \ - level0Edge \ - refinementHistory \ - surfaceIndex \ -; -do - rm -rf "$meshDir/$i" "$meshDir/$i.gz" -done +removeFiles "$meshDir" #------------------------------------------------------------------------------ diff --git a/bin/tools/CleanFunctions b/bin/tools/CleanFunctions index ae434a5ef0..11657af980 100644 --- a/bin/tools/CleanFunctions +++ b/bin/tools/CleanFunctions @@ -108,54 +108,116 @@ cleanPostProcessing() } +# --------------- +# Remove constant/finite-area/faMesh or constant/finite-area/{region}/faMesh +# +# Accepts following options: +# -region The region name +# -- End of options +# --------------- cleanFaMesh() { - if [ -e constant/finite-area/faMesh ] + local region + + # Parse options + while [ "$#" -gt 0 ] + do + case "$1" in + ('') ;; # Ignore empty option + (--) shift; break ;; # Stop option parsing + + (-region) region="$2"; shift ;; + (*) break ;; + esac + shift + done + + # safety + if [ "$region" = "--" ]; then unset region; fi + + local meshDir="constant/finite-area/${region}${region:+/}faMesh" + + if [ -e "$meshDir" ] then - rm -rf constant/finite-area/faMesh + [ -n "$region" ] && echo "Clearing $meshDir" 1>&2 + rm -rf -- "$meshDir" fi - if [ -e constant/faMesh ] + + # Legacy location + # - may still have remnant + + meshDir="constant/faMesh" + if [ -e "$meshDir" ] && [ -z "$region" ] then - if [ -e constant/faMesh/faMeshDefinition ] + if [ -e "$meshDir"/faMeshDefinition ] then - # Old constant/faMesh location for faMeshDefinition still in use: - # - warn but don't remove anything + # VERY OLD LOCATION echo - echo "Warning: not removing constant/faMesh/" + echo "WARNING: not removing $meshDir/" echo " It contains a 'faMeshDefinition' file" - echo " Please relocate file(s) to system/ !!" + echo " Please relocate file(s) to system/finite-area/ !!" echo else # Can remove constant/faMesh/ entirely (no faMeshDefinition) - rm -rf constant/faMesh + echo "Clearing $meshDir" 1>&2 + rm -rf -- "$meshDir" fi fi } +# --------------- +# Remove constant/polyMesh or constant//polyMesh +# +# Accepts following options: +# -region The region name +# -- End of options +# --------------- cleanPolyMesh() { - if [ -e constant/polyMesh ] + local region + + # Parse options + while [ "$#" -gt 0 ] + do + case "$1" in + ('') ;; # Ignore empty option + (--) shift; break ;; # Stop option parsing + + (-region) region="$2"; shift ;; + (*) break ;; + esac + shift + done + + # safety + if [ "$region" = "--" ]; then unset region; fi + + local meshDir="constant/${region}${region:+/}polyMesh" + + if [ -e "$meshDir" ] then - if [ -e constant/polyMesh/blockMeshDict ] \ - || [ -e constant/polyMesh/blockMeshDict.m4 ] + [ -n "$region" ] && echo "Clearing $meshDir" 1>&2 + + if [ -e "$meshDir"/blockMeshDict ] \ + || [ -e "$meshDir"/blockMeshDict.m4 ] then - # Old constant/polyMesh location for blockMeshDict still in use: - # - warn but don't remove anything + # VERY OLD LOCATION echo - echo "Warning: not removing constant/polyMesh/" + echo "WARNING: not removing $meshDir/" echo " It contains a 'blockMeshDict' or 'blockMeshDict.m4' file" echo " Please relocate file(s) to system/ !!" echo else # Can remove constant/polyMesh/ entirely (no blockMeshDict) - rm -rf constant/polyMesh + rm -rf -- "$meshDir" fi fi - if [ -e system/blockMeshDict.m4 ] + meshDir="system${region:+/}${region}" + if [ -e "$meshDir"/blockMeshDict.m4 ] then - rm -f system/blockMeshDict + rm -f -- "$meshDir"/blockMeshDict fi } @@ -212,7 +274,7 @@ cleanCase0() removeCase() { echo "Removing case ${1:-unknown}" - [ "$#" -ge 1 ] && rm -rf "$1" + [ "$#" -ge 1 ] && rm -rf -- "$1" } diff --git a/bin/tools/RunFunctions b/bin/tools/RunFunctions index 249d1894cf..62f3090af4 100644 --- a/bin/tools/RunFunctions +++ b/bin/tools/RunFunctions @@ -517,9 +517,11 @@ cloneParallelCase() } +# --------------- # If 0.orig/ exists, copy (overwrite) into 0/ [ie, serial case] # * -processor : copy into processor directories instead # * -all : copy into serial and processor directories +# --------------- restore0Dir() { if [ ! -d 0.orig ] @@ -553,4 +555,61 @@ restore0Dir() } +# --------------- +# Helper routine to remove specified fields from the 0/ directory. +# Often used in combination with foamListRegions. +# +# Accepts following options: +# -region The region name +# -- End of options +# +# any remaining parameters are taken to be fields names +# --------------- +remove0DirFields() +{ + local region + + # Parse options + while [ "$#" -gt 0 ] + do + case "$1" in + ('') ;; # Ignore empty option + (--) shift; break ;; # Stop option parsing + + (-region) region="$2"; shift ;; + (*) break ;; + esac + shift + done + + # safety + if [ "$region" = "--" ]; then unset region; fi + + if [ "$#" -eq 0 ] + then + echo "No fields specified for ${region:+region=$region }" 1>&2 + return 0 + fi + + echo "Remove 0/ fields${region:+ [$region]} : $@" 1>&2 + + local subdir + for subdir in 0/"$region" processor*/0/"$region" + do + if [ -d "$subdir" ] + then + for field in $@ ## unquoted for IFS splitting [SIC] + do + # Cautious with removal + if [ -f "$subdir/$field" ] + then + rm -f -- "$subdir/$field" + fi + done + fi + done + return 0 +} + + #------------------------------------------------------------------------------ diff --git a/etc/config.sh/bash_completion b/etc/config.sh/bash_completion index 8134ad7204..6fe671bbb5 100644 --- a/etc/config.sh/bash_completion +++ b/etc/config.sh/bash_completion @@ -140,6 +140,11 @@ _of_complete_() # Could use "foamListTimes -withZero", but still doesn't address ranges COMPREPLY=($(compgen -d -X '![-0-9]*' -- ${cur})) ;; + -area-region) + # Or: $(find system/finite-area -mindepth 1 -maxdepth 1 -type d 2>/dev/null | sed -e 's%.*/%%') + choices=$(\ls -d system/finite-area/*/ 2>/dev/null | sed -e 's%/$%%; s%^.*/%%') + COMPREPLY=($(compgen -W "$choices" -- ${cur})) + ;; -region) # Or: $(find system -mindepth 1 -maxdepth 1 -type d 2>/dev/null | sed -e 's%.*/%%') choices=$(\ls -d system/*/ 2>/dev/null | sed -e 's%/$%%; s%^.*/%%') diff --git a/src/meshTools/Make/files b/src/meshTools/Make/files index 1e6d481bd0..6a0eb78d80 100644 --- a/src/meshTools/Make/files +++ b/src/meshTools/Make/files @@ -351,7 +351,8 @@ $(vtk)/topoSet/foamVtkWriteFaceSet.C $(vtk)/topoSet/foamVtkWritePointSet.C $(vtk)/topoSet/foamVtkWriteCellSetFaces.C -regionModel/regionProperties/regionProperties.C +regionModel/regionProperties/regionProperties.cxx +regionModel/regionProperties/regionModelProperties.cxx tetOverlapVolume/tetOverlapVolume.C diff --git a/src/meshTools/regionModel/regionProperties/regionModelProperties.cxx b/src/meshTools/regionModel/regionProperties/regionModelProperties.cxx new file mode 100644 index 0000000000..7b83ef5071 --- /dev/null +++ b/src/meshTools/regionModel/regionProperties/regionModelProperties.cxx @@ -0,0 +1,49 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2025 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM 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. + + OpenFOAM 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 OpenFOAM. If not, see . + +\*---------------------------------------------------------------------------*/ + +#include "regionProperties.H" + +// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // + +// The enable/disable flag for allowFaModels() +static bool allowFaModels_ = true; + +bool Foam::regionModels::allowFaModels() noexcept +{ + return allowFaModels_; +} + + +bool Foam::regionModels::allowFaModels(bool on) noexcept +{ + bool old(allowFaModels_); + allowFaModels_ = on; + return old; +} + + +// ************************************************************************* // diff --git a/src/meshTools/regionModel/regionProperties/regionProperties.H b/src/meshTools/regionModel/regionProperties/regionProperties.H index 8669b18330..9198f930e6 100644 --- a/src/meshTools/regionModel/regionProperties/regionProperties.H +++ b/src/meshTools/regionModel/regionProperties/regionProperties.H @@ -46,18 +46,39 @@ Description \endverbatim SourceFiles - regionProperties.C + regionProperties.cxx + regionModelProperties.cxx \*---------------------------------------------------------------------------*/ #ifndef Foam_regionProperties_H #define Foam_regionProperties_H -#include "HashTable.H" #include "fileName.H" #include "wordList.H" +#include "HashTable.H" #include "IOobjectOption.H" +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// General controls + +namespace Foam +{ +namespace regionModels +{ + +//- The enable/disable state for regionFaModel (default: true) +bool allowFaModels() noexcept; + +//- Set enable/disable state for regionFaModel +// \return previous state +bool allowFaModels(bool on) noexcept; + +} // End namespace regionModels +} // End namespace Foam + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam @@ -119,6 +140,17 @@ public: ~regionProperties() = default; + // Static Member Functions + + //- The expected search path (eg, constant/regionProperties). + // Can be useful when generation error messages + static fileName objectRelPath + ( + const Time& runTime, + const fileName& local = fileName::null + ); + + // Member Functions //- Total count of all region names. diff --git a/src/meshTools/regionModel/regionProperties/regionProperties.C b/src/meshTools/regionModel/regionProperties/regionProperties.cxx similarity index 86% rename from src/meshTools/regionModel/regionProperties/regionProperties.C rename to src/meshTools/regionModel/regionProperties/regionProperties.cxx index 2e3f897080..76933507fb 100644 --- a/src/meshTools/regionModel/regionProperties/regionProperties.C +++ b/src/meshTools/regionModel/regionProperties/regionProperties.cxx @@ -31,6 +31,21 @@ License #include "Time.H" #include "wordRes.H" +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +Foam::fileName Foam::regionProperties::objectRelPath +( + const Time& runTime, + const fileName& local +) +{ + return + ( + runTime.time().constant()/local/"regionProperties" + ); +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::regionProperties::regionProperties @@ -56,6 +71,18 @@ Foam::regionProperties::regionProperties ) ); + // For optional reading: + // - applies to the file and its overall contents. + // - if read and has content, "regions" becomes mandatory + + if (IOobjectOption::isReadOptional(rOpt)) + { + if (iodict.hasHeaderClass() && !iodict.empty()) + { + rOpt = IOobjectOption::MUST_READ; + } + } + iodict.readEntry("regions", props, keyType::LITERAL, rOpt); } diff --git a/tutorials/basic/chtMultiRegionFoam/2DImplicitCyclic/Allmesh b/tutorials/basic/chtMultiRegionFoam/2DImplicitCyclic/Allmesh index ca9d4f3653..9722728e02 100755 --- a/tutorials/basic/chtMultiRegionFoam/2DImplicitCyclic/Allmesh +++ b/tutorials/basic/chtMultiRegionFoam/2DImplicitCyclic/Allmesh @@ -13,10 +13,11 @@ restore0Dir runApplication splitMeshRegions -cellZones -overwrite # Remove fluid fields from solid regions (important for post-processing) +fields="nut alphat epsilon k U p_rgh" + for region in $(foamListRegions solid) do - rm -f 0/$region/{nut,alphat,epsilon,k,U,p_rgh} - rm -f processor*/0/$region/{nut,alphat,epsilon,k,U,p_rgh} + remove0DirFields -region "$region" -- $fields done for region in $(foamListRegions) diff --git a/tutorials/heatTransfer/chtMultiRegionFoam/externalCoupledHeater/Allrun.pre b/tutorials/heatTransfer/chtMultiRegionFoam/externalCoupledHeater/Allrun.pre index 01b40e1149..65876c828d 100755 --- a/tutorials/heatTransfer/chtMultiRegionFoam/externalCoupledHeater/Allrun.pre +++ b/tutorials/heatTransfer/chtMultiRegionFoam/externalCoupledHeater/Allrun.pre @@ -12,10 +12,11 @@ restore0Dir runApplication splitMeshRegions -cellZones -overwrite # Remove fluid fields from solid regions (important for post-processing) +fields="nut alphat epsilon k U p_rgh" + for region in $(foamListRegions solid) do - rm -f 0/$region/{nut,alphat,epsilon,k,U,p_rgh} - rm -f processor*/0/$region/{nut,alphat,epsilon,k,U,p_rgh} + remove0DirFields -region "$region" -- $fields done for region in $(foamListRegions) diff --git a/tutorials/heatTransfer/chtMultiRegionFoam/externalSolarLoad/Allrun.pre b/tutorials/heatTransfer/chtMultiRegionFoam/externalSolarLoad/Allrun.pre index 3f6ac68313..7b9aff8280 100755 --- a/tutorials/heatTransfer/chtMultiRegionFoam/externalSolarLoad/Allrun.pre +++ b/tutorials/heatTransfer/chtMultiRegionFoam/externalSolarLoad/Allrun.pre @@ -11,10 +11,11 @@ runApplication splitMeshRegions -cellZones -overwrite rm -rf 0/domain3 constant/domain3 system/domain3 # Remove fluid fields from solid regions (important for post-processing) +fields="rho nut alphat epsilon k U p_rgh qr G IDefault" + for region in $(foamListRegions solid) do - rm -f 0/$region/{rho,nut,alphat,epsilon,k,U,p_rgh,qr,G,IDefault} - rm -f processor*/0/$region/{rho,nut,alphat,epsilon,k,U,p_rgh,qr,G,IDefault} + remove0DirFields -region "$region" -- $fields done # Set the initial fields diff --git a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/Allrun.pre b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/Allrun.pre index 6e57095006..a8dd4562c1 100755 --- a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/Allrun.pre +++ b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/Allrun.pre @@ -12,10 +12,11 @@ restore0Dir runApplication splitMeshRegions -cellZones -overwrite # Remove fluid fields from solid regions (important for post-processing) +fields="nut alphat epsilon k U p_rgh" + for region in $(foamListRegions solid) do - rm -f 0/$region/{nut,alphat,epsilon,k,U,p_rgh} - rm -f processor*/0/$region/{nut,alphat,epsilon,k,U,p_rgh} + remove0DirFields -region "$region" -- $fields done for region in $(foamListRegions) diff --git a/tutorials/heatTransfer/chtMultiRegionFoam/snappyMultiRegionHeater/Allrun-parallel b/tutorials/heatTransfer/chtMultiRegionFoam/snappyMultiRegionHeater/Allrun-parallel index d7b78bfb03..44933da0fc 100755 --- a/tutorials/heatTransfer/chtMultiRegionFoam/snappyMultiRegionHeater/Allrun-parallel +++ b/tutorials/heatTransfer/chtMultiRegionFoam/snappyMultiRegionHeater/Allrun-parallel @@ -26,10 +26,11 @@ restore0Dir -processor runParallel $decompDict splitMeshRegions -cellZones -overwrite # Remove fluid fields from solid regions (important for post-processing) +fields="nut alphat epsilon k U p_rgh" + for region in $(foamListRegions solid) do - rm -f 0/"$region"/{nut,alphat,epsilon,k,U,p_rgh} - rm -f processor*/0/"$region"/{nut,alphat,epsilon,k,U,p_rgh} + remove0DirFields -region "$region" -- $fields done for region in $(foamListRegions) diff --git a/tutorials/heatTransfer/chtMultiRegionFoam/snappyMultiRegionHeater/Allrun-serial b/tutorials/heatTransfer/chtMultiRegionFoam/snappyMultiRegionHeater/Allrun-serial index de426ea49d..19c03b4a7d 100755 --- a/tutorials/heatTransfer/chtMultiRegionFoam/snappyMultiRegionHeater/Allrun-serial +++ b/tutorials/heatTransfer/chtMultiRegionFoam/snappyMultiRegionHeater/Allrun-serial @@ -21,10 +21,11 @@ restore0Dir runApplication splitMeshRegions -cellZones -overwrite # Remove fluid fields from solid regions (important for post-processing) +fields="nut alphat epsilon k U p_rgh" + for region in $(foamListRegions solid) do - rm -f 0/"$region"/{nut,alphat,epsilon,k,U,p_rgh} - rm -f processor*/0/"$region"/{nut,alphat,epsilon,k,U,p_rgh} + remove0DirFields -region "$region" -- $fields done for region in $(foamListRegions) diff --git a/tutorials/heatTransfer/chtMultiRegionFoam/snappyMultiRegionHeaterImplicit/Allrun b/tutorials/heatTransfer/chtMultiRegionFoam/snappyMultiRegionHeaterImplicit/Allrun index 0e3d605ef8..d50e65532d 100755 --- a/tutorials/heatTransfer/chtMultiRegionFoam/snappyMultiRegionHeaterImplicit/Allrun +++ b/tutorials/heatTransfer/chtMultiRegionFoam/snappyMultiRegionHeaterImplicit/Allrun @@ -32,10 +32,11 @@ restore0Dir -processor runParallel $decompDict splitMeshRegions -cellZones -overwrite # Remove fluid fields from solid regions (important for post-processing) +fields="nut alphat epsilon k U p_rgh" + for region in $(foamListRegions solid) do - rm -f 0/$region/{nut,alphat,epsilon,k,U,p_rgh} - rm -f processor*/0/$region/{nut,alphat,epsilon,k,U,p_rgh} + remove0DirFields -region "$region" -- $fields done for region in $(foamListRegions) diff --git a/tutorials/heatTransfer/chtMultiRegionFoam/solarBeamWithTrees/Allrun.pre b/tutorials/heatTransfer/chtMultiRegionFoam/solarBeamWithTrees/Allrun.pre index 1ca5a5bad8..d09ba74967 100755 --- a/tutorials/heatTransfer/chtMultiRegionFoam/solarBeamWithTrees/Allrun.pre +++ b/tutorials/heatTransfer/chtMultiRegionFoam/solarBeamWithTrees/Allrun.pre @@ -13,10 +13,11 @@ runApplication splitMeshRegions -cellZones -overwrite rm -rf 0/domain3 constant/domain3 system/domain3 # Remove fluid fields from solid regions (important for post-processing) +fields="rho nut alphat epsilon k U p_rgh qr G IDefault" + for region in $(foamListRegions solid) do - rm -f 0/"$region"/{rho,nut,alphat,epsilon,k,U,p_rgh,qr,G,IDefault} - rm -f processor*/0/"$region"/{rho,nut,alphat,epsilon,k,U,p_rgh,qr,G,IDefault} + remove0DirFields -region "$region" -- $fields done # Set the initial fields diff --git a/tutorials/heatTransfer/chtMultiRegionSimpleFoam/externalCoupledHeater/Allrun.pre b/tutorials/heatTransfer/chtMultiRegionSimpleFoam/externalCoupledHeater/Allrun.pre index ee6ca23a66..50391a329b 100755 --- a/tutorials/heatTransfer/chtMultiRegionSimpleFoam/externalCoupledHeater/Allrun.pre +++ b/tutorials/heatTransfer/chtMultiRegionSimpleFoam/externalCoupledHeater/Allrun.pre @@ -13,10 +13,11 @@ restore0Dir runApplication splitMeshRegions -cellZones -overwrite # Remove fluid fields from solid regions (important for post-processing) +fields="nut alphat epsilon k U p_rgh" + for region in $(foamListRegions solid) do - rm -f 0/"$region"/{nut,alphat,epsilon,k,U,p_rgh} - rm -f processor*/0/"$region"/{nut,alphat,epsilon,k,U,p_rgh} + remove0DirFields -region "$region" -- $fields done for region in $(foamListRegions) diff --git a/tutorials/heatTransfer/chtMultiRegionSimpleFoam/multiRegionHeaterRadiation/Allrun.pre b/tutorials/heatTransfer/chtMultiRegionSimpleFoam/multiRegionHeaterRadiation/Allrun.pre index b5fa7348a8..594f0507e6 100755 --- a/tutorials/heatTransfer/chtMultiRegionSimpleFoam/multiRegionHeaterRadiation/Allrun.pre +++ b/tutorials/heatTransfer/chtMultiRegionSimpleFoam/multiRegionHeaterRadiation/Allrun.pre @@ -13,10 +13,11 @@ restore0Dir runApplication splitMeshRegions -cellZones -overwrite # Remove fluid fields from solid regions (important for post-processing) +fields="rho nut alphat epsilon k U p_rgh qr G IDefault" + for region in $(foamListRegions solid) do - rm -f 0/"$region"/{rho,nut,alphat,epsilon,k,U,p_rgh,qr,G,IDefault} - rm -f processor*/0/"$region"/{rho,nut,alphat,epsilon,k,U,p_rgh,qr,G,IDefault} + remove0DirFields -region "$region" -- $fields done for region in $(foamListRegions) From e02b4be7ca34488abcbce4535a0bcfd171b2f39b Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Thu, 9 Oct 2025 13:46:45 +0200 Subject: [PATCH 06/18] ENH: allow delayed construction of regionFaModel in volume bcs (#3419) Ideally wish to delay construction of the finite-area mesh until updateCoeffs(), when it is actually needed. This helps avoid difficult to trace errors and avoids inadvertent parallel communication during construction from a dictionary. However, lazy evaluation fails at the later stage while attempting to load the corresponding initial fields, since the timeIndex has already advanced. Use the newly introduced regionModels::allowFaModels() switch to locally enable or disable lazy evaluation as needed. This allows selective disabling (eg, in post-processing utilities) where loading the volume field should not activate the associated regionFaModel and loading a finite-area mesh too (which may not exist or be defined at that point). --- .../decomposePar/decomposePar.C | 6 ++ .../reconstructPar/reconstructPar.C | 5 ++ .../reconstructParMesh/reconstructParMesh.C | 6 ++ .../redistributePar/redistributePar.C | 3 + .../foamToEnsight/foamToEnsight.C | 3 + .../dataConversion/foamToVTK/foamToVTK.C | 6 ++ .../velocityFilmShellFvPatchVectorField.C | 59 +++++++++++------- .../velocityFilmShellFvPatchVectorField.H | 33 +++++++--- .../thermalShellFvPatchScalarField.C | 61 ++++++++++++------- .../thermalShellFvPatchScalarField.H | 31 ++++++++-- .../vibrationShellFvPatchScalarField.C | 56 ++++++++++------- .../vibrationShellFvPatchScalarField.H | 31 ++++++++-- .../thermalBaffleFvPatchScalarField.C | 52 ++++++++-------- .../thermalBaffleFvPatchScalarField.H | 17 +++--- 14 files changed, 251 insertions(+), 118 deletions(-) diff --git a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C index 8b9a7f6b08..7d44c87d46 100644 --- a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C +++ b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C @@ -418,8 +418,14 @@ int main(int argc, char *argv[]) // Allow explicit -constant, have zero from time range timeSelector::addOptions(true, false); // constant(true), zero(false) + // Prevent volume BCs from triggering finite-area + regionModels::allowFaModels(false); + #include "setRootCase.H" + // ------------------------------------------------------------------------ + // Configuration + const bool writeCellDist = args.found("cellDist"); // Most of these are ignored for dry-run (not triggered anywhere) diff --git a/applications/utilities/parallelProcessing/reconstructPar/reconstructPar.C b/applications/utilities/parallelProcessing/reconstructPar/reconstructPar.C index 0e8f7f7b39..2b99ec0ea4 100644 --- a/applications/utilities/parallelProcessing/reconstructPar/reconstructPar.C +++ b/applications/utilities/parallelProcessing/reconstructPar/reconstructPar.C @@ -135,9 +135,14 @@ int main(int argc, char *argv[]) "Only reconstruct new times (i.e. that do not exist already)" ); + // Prevent volume BCs from triggering finite-area + regionModels::allowFaModels(false); + #include "setRootCase.H" #include "createTime.H" + // ------------------------------------------------------------------------ + // Configuration const bool doFields = !args.found("no-fields"); wordRes selectedFields; diff --git a/applications/utilities/parallelProcessing/reconstructParMesh/reconstructParMesh.C b/applications/utilities/parallelProcessing/reconstructParMesh/reconstructParMesh.C index 35add85435..199eabc597 100644 --- a/applications/utilities/parallelProcessing/reconstructParMesh/reconstructParMesh.C +++ b/applications/utilities/parallelProcessing/reconstructParMesh/reconstructParMesh.C @@ -780,11 +780,17 @@ int main(int argc, char *argv[]) #include "addAllRegionOptions.H" + // Prevent volume BCs from triggering finite-area + regionModels::allowFaModels(false); + #include "setRootCase.H" #include "createTime.H" printWarning(); + // ------------------------------------------------------------------------ + // Configuration + const bool fullMatch = args.found("fullMatch"); const bool procMatch = args.found("procMatch"); const bool writeCellDist = args.found("cellDist"); diff --git a/applications/utilities/parallelProcessing/redistributePar/redistributePar.C b/applications/utilities/parallelProcessing/redistributePar/redistributePar.C index f1461bac18..cbcba498cc 100644 --- a/applications/utilities/parallelProcessing/redistributePar/redistributePar.C +++ b/applications/utilities/parallelProcessing/redistributePar/redistributePar.C @@ -1257,6 +1257,8 @@ int main(int argc, char *argv[]) true // Advanced option ); + // Prevent volume BCs from triggering finite-area + regionModels::allowFaModels(false); //- Disable caching of times/processor dirs etc. Cause massive parallel // problems when e.g decomposing. @@ -1269,6 +1271,7 @@ int main(int argc, char *argv[]) argList args(argc, argv); + // ------------------------------------------------------------------------ // As much as possible avoid synchronised operation. To be looked at more // closely for the three scenarios: diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C b/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C index d9b66824cf..034a9466b8 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C @@ -323,6 +323,9 @@ int main(int argc, char *argv[]) ); argList::addOptionCompat("cellZones", {"cellZone", 1912}); + // Prevent volume BCs from triggering finite-area + regionModels::allowFaModels(false); + #include "setRootCase.H" // ------------------------------------------------------------------------ diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK.C index 1350626163..ea29a0dfe5 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK.C +++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK.C @@ -479,8 +479,14 @@ int main(int argc, char *argv[]) "Directory name for VTK output (default: 'VTK')" ); + // Prevent volume BCs from triggering finite-area + regionModels::allowFaModels(false); + #include "setRootCase.H" + // ------------------------------------------------------------------------ + // Configuration + /// const int optVerbose = args.verbose(); const bool decomposePoly = args.found("poly-decomp"); const bool doBoundary = !args.found("no-boundary"); diff --git a/src/regionFaModels/derivedFvPatchFields/filmShell/velocityFilmShellFvPatchVectorField.C b/src/regionFaModels/derivedFvPatchFields/filmShell/velocityFilmShellFvPatchVectorField.C index d764b4a36f..682a4f2c93 100644 --- a/src/regionFaModels/derivedFvPatchFields/filmShell/velocityFilmShellFvPatchVectorField.C +++ b/src/regionFaModels/derivedFvPatchFields/filmShell/velocityFilmShellFvPatchVectorField.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2020-2022 OpenCFD Ltd. + Copyright (C) 2020-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -27,6 +27,7 @@ License #include "velocityFilmShellFvPatchVectorField.H" #include "dictionaryContent.H" +#include "regionProperties.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -34,6 +35,20 @@ License namespace Foam { +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void velocityFilmShellFvPatchVectorField::create_baffle() +{ + if (!baffle_) + { + baffle_.reset + ( + baffleType::New(this->patch().boundaryMesh().mesh(), dict_) + ); + } +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // velocityFilmShellFvPatchVectorField::velocityFilmShellFvPatchVectorField @@ -42,8 +57,7 @@ velocityFilmShellFvPatchVectorField::velocityFilmShellFvPatchVectorField const DimensionedField& iF ) : - mixedFvPatchField(p, iF), - baffle_(nullptr), + parent_bctype(p, iF), dict_(), curTimeIndex_(-1), zeroWallVelocity_(true) @@ -62,14 +76,7 @@ velocityFilmShellFvPatchVectorField::velocityFilmShellFvPatchVectorField const fvPatchFieldMapper& mapper ) : - mixedFvPatchField - ( - ptf, - p, - iF, - mapper - ), - baffle_(nullptr), + parent_bctype(ptf, p, iF, mapper), dict_(ptf.dict_), curTimeIndex_(-1), zeroWallVelocity_(true) @@ -83,8 +90,7 @@ velocityFilmShellFvPatchVectorField::velocityFilmShellFvPatchVectorField const dictionary& dict ) : - mixedFvPatchField(p, iF), - baffle_(nullptr), + parent_bctype(p, iF), dict_ ( // Copy dictionary, but without "heavy" data chunks @@ -116,9 +122,11 @@ velocityFilmShellFvPatchVectorField::velocityFilmShellFvPatchVectorField valueFraction() = 1; } - if (!baffle_) + // Create baffle now. + // Lazy evaluation has issues with loading the finite-area fields + if (regionModels::allowFaModels()) { - baffle_.reset(baffleType::New(p.boundaryMesh().mesh(), dict_)); + create_baffle(); } } @@ -129,8 +137,7 @@ velocityFilmShellFvPatchVectorField::velocityFilmShellFvPatchVectorField const DimensionedField& iF ) : - mixedFvPatchField(ptf, iF), - baffle_(nullptr), + parent_bctype(ptf, iF), dict_(ptf.dict_), curTimeIndex_(-1), zeroWallVelocity_(true) @@ -146,14 +153,22 @@ void velocityFilmShellFvPatchVectorField::updateCoeffs() return; } + // Create baffle if needed + if (!baffle_) + { + create_baffle(); + } + // Execute the change only once per time-step if (curTimeIndex_ != this->db().time().timeIndex()) { - baffle_->evolve(); - vectorField& pfld = *this; - baffle_->vsm().mapToVolumePatch(baffle_->Us(), pfld, patch().index()); + auto& baffle = baffle_(); + + baffle.evolve(); + + baffle.vsm().mapToVolumePatch(baffle.Us(), pfld, patch().index()); refGrad() = Zero; valueFraction() = 1; @@ -170,13 +185,13 @@ void velocityFilmShellFvPatchVectorField::updateCoeffs() curTimeIndex_ = this->db().time().timeIndex(); } - mixedFvPatchField::updateCoeffs(); + parent_bctype::updateCoeffs(); } void velocityFilmShellFvPatchVectorField::write(Ostream& os) const { - mixedFvPatchField::write(os); + parent_bctype::write(os); dict_.write(os, false); } diff --git a/src/regionFaModels/derivedFvPatchFields/filmShell/velocityFilmShellFvPatchVectorField.H b/src/regionFaModels/derivedFvPatchFields/filmShell/velocityFilmShellFvPatchVectorField.H index a24587a23d..97d204e1cb 100644 --- a/src/regionFaModels/derivedFvPatchFields/filmShell/velocityFilmShellFvPatchVectorField.H +++ b/src/regionFaModels/derivedFvPatchFields/filmShell/velocityFilmShellFvPatchVectorField.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2020 OpenCFD Ltd. + Copyright (C) 2020-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -134,15 +134,15 @@ class velocityFilmShellFvPatchVectorField { // Typedefs + //- The parent boundary condition type + typedef mixedFvPatchField parent_bctype; + //- The finite-area region model typedef regionModels::areaSurfaceFilmModels::liquidFilmBase baffleType; // Private Data - //- The liquid film model - autoPtr baffle_; - //- Dictionary mutable dictionary dict_; @@ -152,6 +152,15 @@ class velocityFilmShellFvPatchVectorField //- Flag to set velocity to zero or film velocity bool zeroWallVelocity_; + //- The liquid film model + autoPtr baffle_; + + + // Private Methods + + //- Create film baffle (if required) + void create_baffle(); + public: @@ -186,13 +195,23 @@ public: const fvPatchFieldMapper& ); - //- Construct as copy setting internal field reference + //- Copy construct with internal field reference velocityFilmShellFvPatchVectorField ( - const velocityFilmShellFvPatchVectorField&, - const DimensionedField& + const velocityFilmShellFvPatchVectorField& pfld, + const DimensionedField& iF ); + //- Copy construct + velocityFilmShellFvPatchVectorField + ( + const velocityFilmShellFvPatchVectorField& pfld + ) + : + velocityFilmShellFvPatchVectorField(pfld, pfld.internalField()) + {} + + //- Return a clone virtual tmp> clone() const { diff --git a/src/regionFaModels/derivedFvPatchFields/thermalShell/thermalShellFvPatchScalarField.C b/src/regionFaModels/derivedFvPatchFields/thermalShell/thermalShellFvPatchScalarField.C index f778792db8..5b2a1d7694 100644 --- a/src/regionFaModels/derivedFvPatchFields/thermalShell/thermalShellFvPatchScalarField.C +++ b/src/regionFaModels/derivedFvPatchFields/thermalShell/thermalShellFvPatchScalarField.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2019-2022 OpenCFD Ltd. + Copyright (C) 2019-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -26,8 +26,9 @@ License \*---------------------------------------------------------------------------*/ #include "thermalShellFvPatchScalarField.H" -#include "addToRunTimeSelectionTable.H" #include "dictionaryContent.H" +#include "regionProperties.H" +#include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -36,6 +37,20 @@ namespace Foam namespace compressible { +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void thermalShellFvPatchScalarField::create_baffle() +{ + if (!baffle_) + { + baffle_.reset + ( + baffleType::New(this->patch().boundaryMesh().mesh(), dict_) + ); + } +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // thermalShellFvPatchScalarField::thermalShellFvPatchScalarField @@ -44,8 +59,7 @@ thermalShellFvPatchScalarField::thermalShellFvPatchScalarField const DimensionedField& iF ) : - fixedValueFvPatchField(p, iF), - baffle_(nullptr), + parent_bctype(p, iF), dict_() {} @@ -58,14 +72,7 @@ thermalShellFvPatchScalarField::thermalShellFvPatchScalarField const fvPatchFieldMapper& mapper ) : - fixedValueFvPatchField - ( - ptf, - p, - iF, - mapper - ), - baffle_(nullptr), + parent_bctype(ptf, p, iF, mapper), dict_(ptf.dict_) {} @@ -77,8 +84,7 @@ thermalShellFvPatchScalarField::thermalShellFvPatchScalarField const dictionary& dict ) : - fixedValueFvPatchField(p, iF, dict), - baffle_(nullptr), + parent_bctype(p, iF, dict), dict_ ( // Copy dictionary, but without "heavy" data chunks @@ -94,9 +100,11 @@ thermalShellFvPatchScalarField::thermalShellFvPatchScalarField ) ) { - if (!baffle_) + // Create baffle now. + // Lazy evaluation has issues with loading the finite-area fields + if (regionModels::allowFaModels()) { - baffle_.reset(baffleType::New(p.boundaryMesh().mesh(), dict_)); + create_baffle(); } } @@ -107,8 +115,7 @@ thermalShellFvPatchScalarField::thermalShellFvPatchScalarField const DimensionedField& iF ) : - fixedValueFvPatchField(ptf, iF), - baffle_(nullptr), + parent_bctype(ptf, iF), dict_(ptf.dict_) {} @@ -122,19 +129,27 @@ void thermalShellFvPatchScalarField::updateCoeffs() return; } - baffle_->evolve(); - scalarField& pfld = *this; - baffle_->vsm().mapToVolumePatch(baffle_->T(), pfld, patch().index()); + // Create baffle if needed + if (!baffle_) + { + create_baffle(); + } - fixedValueFvPatchField::updateCoeffs(); + auto& baffle = baffle_(); + + baffle.evolve(); + + baffle.vsm().mapToVolumePatch(baffle.T(), pfld, patch().index()); + + parent_bctype::updateCoeffs(); } void thermalShellFvPatchScalarField::write(Ostream& os) const { - fixedValueFvPatchField::write(os); + parent_bctype::write(os); dict_.write(os, false); } diff --git a/src/regionFaModels/derivedFvPatchFields/thermalShell/thermalShellFvPatchScalarField.H b/src/regionFaModels/derivedFvPatchFields/thermalShell/thermalShellFvPatchScalarField.H index a229a43666..d8980b8d5d 100644 --- a/src/regionFaModels/derivedFvPatchFields/thermalShell/thermalShellFvPatchScalarField.H +++ b/src/regionFaModels/derivedFvPatchFields/thermalShell/thermalShellFvPatchScalarField.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2019-2022 OpenCFD Ltd. + Copyright (C) 2019-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -91,17 +91,26 @@ class thermalShellFvPatchScalarField { // Typedefs + //- The parent boundary condition type + typedef fixedValueFvPatchField parent_bctype; + //- The finite-area region model typedef regionModels::thermalShellModel baffleType; // Private Data + //- Dictionary + dictionary dict_; + //- The thermal baffle autoPtr baffle_; - //- Dictionary - dictionary dict_; + + // Private Methods + + //- Create thermal baffle (if required) + void create_baffle(); public: @@ -137,13 +146,23 @@ public: const fvPatchFieldMapper& ); - //- Construct as copy setting internal field reference + //- Copy construct with internal field reference thermalShellFvPatchScalarField ( - const thermalShellFvPatchScalarField&, - const DimensionedField& + const thermalShellFvPatchScalarField& pfld, + const DimensionedField& iF ); + //- Copy construct + thermalShellFvPatchScalarField + ( + const thermalShellFvPatchScalarField& pfld + ) + : + thermalShellFvPatchScalarField(pfld, pfld.internalField()) + {} + + //- Return a clone virtual tmp> clone() const { diff --git a/src/regionFaModels/derivedFvPatchFields/vibrationShell/vibrationShellFvPatchScalarField.C b/src/regionFaModels/derivedFvPatchFields/vibrationShell/vibrationShellFvPatchScalarField.C index 460539ed54..f67ed831c4 100644 --- a/src/regionFaModels/derivedFvPatchFields/vibrationShell/vibrationShellFvPatchScalarField.C +++ b/src/regionFaModels/derivedFvPatchFields/vibrationShell/vibrationShellFvPatchScalarField.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2019-2022 OpenCFD Ltd. + Copyright (C) 2019-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -27,6 +27,7 @@ License #include "vibrationShellFvPatchScalarField.H" #include "dictionaryContent.H" +#include "regionProperties.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -34,6 +35,20 @@ License namespace Foam { +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void vibrationShellFvPatchScalarField::create_baffle() +{ + if (!baffle_) + { + baffle_.reset + ( + baffleType::New(this->patch().boundaryMesh().mesh(), dict_) + ); + } +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // vibrationShellFvPatchScalarField::vibrationShellFvPatchScalarField @@ -42,8 +57,7 @@ vibrationShellFvPatchScalarField::vibrationShellFvPatchScalarField const DimensionedField& iF ) : - mixedFvPatchField(p, iF), - baffle_(nullptr), + parent_bctype(p, iF), dict_() { refValue() = Zero; @@ -60,14 +74,7 @@ vibrationShellFvPatchScalarField::vibrationShellFvPatchScalarField const fvPatchFieldMapper& mapper ) : - mixedFvPatchField - ( - ptf, - p, - iF, - mapper - ), - baffle_(nullptr), + parent_bctype(ptf, p, iF, mapper), dict_(ptf.dict_) {} @@ -79,8 +86,7 @@ vibrationShellFvPatchScalarField::vibrationShellFvPatchScalarField const dictionary& dict ) : - mixedFvPatchField(p, iF), - baffle_(nullptr), + parent_bctype(p, iF), dict_ ( // Copy dictionary, but without "heavy" data chunks @@ -110,9 +116,11 @@ vibrationShellFvPatchScalarField::vibrationShellFvPatchScalarField valueFraction() = 1; } - if (!baffle_) + // Create baffle now. + // Lazy evaluation has issues with loading the finite-area fields + if (regionModels::allowFaModels()) { - baffle_.reset(baffleType::New(p.boundaryMesh().mesh(), dict_)); + create_baffle(); } } @@ -123,8 +131,7 @@ vibrationShellFvPatchScalarField::vibrationShellFvPatchScalarField const DimensionedField& iF ) : - mixedFvPatchField(ptf, iF), - baffle_(nullptr), + parent_bctype(ptf, iF), dict_(ptf.dict_) {} @@ -138,31 +145,38 @@ void vibrationShellFvPatchScalarField::updateCoeffs() return; } + // Create baffle if needed + if (!baffle_) + { + create_baffle(); + } + auto& baffle = baffle_(); + const auto& transportProperties = db().lookupObject("transportProperties"); dimensionedScalar rho("rho", dimDensity, transportProperties); - baffle_->evolve(); + baffle.evolve(); // rho * acceleration refGrad() = Zero; // safety (for any unmapped values) - baffle_->vsm().mapToVolumePatch(baffle_->a(), refGrad(), patch().index()); + baffle.vsm().mapToVolumePatch(baffle.a(), refGrad(), patch().index()); refGrad() *= rho.value(); refValue() = Zero; valueFraction() = Zero; - mixedFvPatchField::updateCoeffs(); + parent_bctype::updateCoeffs(); } void vibrationShellFvPatchScalarField::write(Ostream& os) const { - mixedFvPatchField::write(os); + parent_bctype::write(os); dict_.write(os, false); } diff --git a/src/regionFaModels/derivedFvPatchFields/vibrationShell/vibrationShellFvPatchScalarField.H b/src/regionFaModels/derivedFvPatchFields/vibrationShell/vibrationShellFvPatchScalarField.H index 7a41512e1e..0ba5770430 100644 --- a/src/regionFaModels/derivedFvPatchFields/vibrationShell/vibrationShellFvPatchScalarField.H +++ b/src/regionFaModels/derivedFvPatchFields/vibrationShell/vibrationShellFvPatchScalarField.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2019-2020 OpenCFD Ltd. + Copyright (C) 2019-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -82,17 +82,26 @@ class vibrationShellFvPatchScalarField { // Typedefs + //- The parent boundary condition type + typedef mixedFvPatchField parent_bctype; + //- The finite-area region model typedef regionModels::vibrationShellModel baffleType; // Private Data + //- Dictionary + dictionary dict_; + //- The vibration shell model autoPtr baffle_; - //- Dictionary - dictionary dict_; + + // Private Methods + + //- Create vibration baffle (if required) + void create_baffle(); public: @@ -128,13 +137,23 @@ public: const fvPatchFieldMapper& ); - //- Construct as copy setting internal field reference + //- Copy construct with internal field reference vibrationShellFvPatchScalarField ( - const vibrationShellFvPatchScalarField&, - const DimensionedField& + const vibrationShellFvPatchScalarField& pfld, + const DimensionedField& iF ); + //- Copy construct + vibrationShellFvPatchScalarField + ( + const vibrationShellFvPatchScalarField& pfld + ) + : + vibrationShellFvPatchScalarField(pfld, pfld.internalField()) + {} + + //- Return a clone virtual tmp> clone() const { diff --git a/src/regionModels/thermalBaffleModels/derivedFvPatchFields/thermalBaffle/thermalBaffleFvPatchScalarField.C b/src/regionModels/thermalBaffleModels/derivedFvPatchFields/thermalBaffle/thermalBaffleFvPatchScalarField.C index 408f3ddadc..0f3d318e28 100644 --- a/src/regionModels/thermalBaffleModels/derivedFvPatchFields/thermalBaffle/thermalBaffleFvPatchScalarField.C +++ b/src/regionModels/thermalBaffleModels/derivedFvPatchFields/thermalBaffle/thermalBaffleFvPatchScalarField.C @@ -27,6 +27,7 @@ License \*---------------------------------------------------------------------------*/ #include "thermalBaffleFvPatchScalarField.H" +#include "dictionaryContent.H" #include "addToRunTimeSelectionTable.H" #include "emptyPolyPatch.H" #include "mappedWallPolyPatch.H" @@ -46,12 +47,10 @@ thermalBaffleFvPatchScalarField::thermalBaffleFvPatchScalarField const DimensionedField& iF ) : - turbulentTemperatureRadCoupledMixedFvPatchScalarField(p, iF), + parent_bctype(p, iF), owner_(false), internal_(true), - baffle_(nullptr), - dict_(), - extrudeMeshPtr_() + dict_() {} @@ -63,18 +62,10 @@ thermalBaffleFvPatchScalarField::thermalBaffleFvPatchScalarField const fvPatchFieldMapper& mapper ) : - turbulentTemperatureRadCoupledMixedFvPatchScalarField - ( - ptf, - p, - iF, - mapper - ), + parent_bctype(ptf, p, iF, mapper), owner_(ptf.owner_), internal_(ptf.internal_), - baffle_(nullptr), - dict_(ptf.dict_), - extrudeMeshPtr_() + dict_(ptf.dict_) {} @@ -85,12 +76,23 @@ thermalBaffleFvPatchScalarField::thermalBaffleFvPatchScalarField const dictionary& dict ) : - turbulentTemperatureRadCoupledMixedFvPatchScalarField(p, iF, dict), + parent_bctype(p, iF, dict), owner_(false), internal_(true), - baffle_(nullptr), - dict_(dict), - extrudeMeshPtr_() + dict_ + ( + // Copy dictionary, but without "heavy" data chunks + dictionaryContent::copyDict + ( + dict, + wordList(), // allow + wordList // deny + ({ + "type", // redundant + "value" + }) + ) + ) { const fvMesh& thisMesh = patch().boundaryMesh().mesh(); @@ -104,8 +106,8 @@ thermalBaffleFvPatchScalarField::thermalBaffleFvPatchScalarField if ( - !thisMesh.time().foundObject(regionName) - && regionName != "none" + (regionName != "none") + && !thisMesh.time().foundObject(regionName) ) { if (!extrudeMeshPtr_) @@ -126,12 +128,10 @@ thermalBaffleFvPatchScalarField::thermalBaffleFvPatchScalarField const DimensionedField& iF ) : - turbulentTemperatureRadCoupledMixedFvPatchScalarField(ptf, iF), + parent_bctype(ptf, iF), owner_(ptf.owner_), internal_(ptf.internal_), - baffle_(nullptr), - dict_(ptf.dict_), - extrudeMeshPtr_() + dict_(ptf.dict_) {} @@ -309,13 +309,13 @@ void thermalBaffleFvPatchScalarField::updateCoeffs() baffle_->evolve(); } - turbulentTemperatureRadCoupledMixedFvPatchScalarField::updateCoeffs(); + parent_bctype::updateCoeffs(); } void thermalBaffleFvPatchScalarField::write(Ostream& os) const { - turbulentTemperatureRadCoupledMixedFvPatchScalarField::write(os); + parent_bctype::write(os); if (owner_) { diff --git a/src/regionModels/thermalBaffleModels/derivedFvPatchFields/thermalBaffle/thermalBaffleFvPatchScalarField.H b/src/regionModels/thermalBaffleModels/derivedFvPatchFields/thermalBaffle/thermalBaffleFvPatchScalarField.H index 0402f973e0..f468536753 100644 --- a/src/regionModels/thermalBaffleModels/derivedFvPatchFields/thermalBaffle/thermalBaffleFvPatchScalarField.H +++ b/src/regionModels/thermalBaffleModels/derivedFvPatchFields/thermalBaffle/thermalBaffleFvPatchScalarField.H @@ -203,11 +203,9 @@ SourceFiles \*---------------------------------------------------------------------------*/ -#ifndef thermalBaffleFvPatchScalarField_H -#define thermalBaffleFvPatchScalarField_H +#ifndef Foam_thermalBaffleFvPatchScalarField_H +#define Foam_thermalBaffleFvPatchScalarField_H - -#include "autoPtr.H" #include "regionModel.H" #include "thermalBaffleModel.H" #include "extrudePatchMesh.H" @@ -231,6 +229,11 @@ class thermalBaffleFvPatchScalarField { // Typedefs + //- The parent boundary condition type + typedef + turbulentTemperatureRadCoupledMixedFvPatchScalarField + parent_bctype; + //- The baffle region model typedef regionModels::thermalBaffleModels::thermalBaffleModel @@ -253,12 +256,12 @@ class thermalBaffleFvPatchScalarField //- Is the baffle internal bool internal_; - //- Thermal baffle - autoPtr baffle_; - //- Dictionary dictionary dict_; + //- Thermal baffle + autoPtr baffle_; + //- Auto pointer to extrapolated mesh from patch autoPtr extrudeMeshPtr_; From 09521d1304aa6fe70f1f22bbd1b726ed10187c51 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Sat, 11 Oct 2025 09:38:39 +0200 Subject: [PATCH 07/18] ENH: add default "constant" name for fileOperations::findTimes() - makes fileHandler calling resemble Time more closely ENH: provide natural_sort less/greater functions - more succinct than (compare < 0) or (compare > 0). The corresponding wrappers for UList renamed as list_less, etc but they were only used in unit tests ENH: handle (-allRegions | -all-regions, ..) directly when retrieving args - makes handling independent of aliasing order STYLE: include when including - the standard does not guarantee which headers (if any) actually include string_view --- applications/test/sort/Test-sortList.cxx | 6 +- .../db/IOstreams/memory/memoryStreamBuffer.H | 1 + src/OpenFOAM/db/dictionary/dictionary.H | 1 + src/OpenFOAM/db/error/messageStream.H | 2 + .../global/debug/simpleObjectRegistry.H | 1 + .../fileOperation/fileOperation.C | 2 +- .../fileOperation/fileOperation.H | 12 +- .../masterUncollatedFileOperation.H | 8 +- src/OpenFOAM/include/addAllRegionOptions.H | 9 +- src/OpenFOAM/include/getAllRegionOptions.H | 46 +++-- src/OpenFOAM/primitives/bools/Switch/Switch.H | 3 + .../primitives/strings/lists/CStringList.H | 1 + .../primitives/strings/lists/SubStrings.H | 1 + .../primitives/strings/regex/regExpCxx.H | 1 + .../primitives/strings/string/string.H | 1 + .../strings/stringOps/stringOpsSort.H | 165 ++++++++++-------- .../vtk/file/foamVtkSeriesWriter.C | 14 +- .../include/addAllFaRegionOptions.H | 12 +- .../include/getAllFaRegionOptions.H | 56 ++++-- 19 files changed, 224 insertions(+), 118 deletions(-) diff --git a/applications/test/sort/Test-sortList.cxx b/applications/test/sort/Test-sortList.cxx index 907f6436c9..1269c2cb8b 100644 --- a/applications/test/sort/Test-sortList.cxx +++ b/applications/test/sort/Test-sortList.cxx @@ -296,7 +296,7 @@ int main(int argc, char *argv[]) ( strings, order, - stringOps::natural_sort::less(strings) + stringOps::natural_sort::list_less(strings) ); Info<< "natural sortedOrder: " << flatOutput(order) << endl; } @@ -321,7 +321,7 @@ int main(int argc, char *argv[]) /// sortable = hashed.toc(); /// sortable.sort /// ( - /// stringOps::natural_sort::less(sortable) + /// stringOps::natural_sort::list_less(sortable) /// ); /// Info<< nl << "natural:" << sortable << endl; @@ -329,7 +329,7 @@ int main(int argc, char *argv[]) /// sortable = hashed.toc(); /// sortable.sort /// ( - /// stringOps::natural_sort::greater(sortable) + /// stringOps::natural_sort::list_greater(sortable) /// ); /// Info<< nl << "natural:" << sortable << endl; } diff --git a/src/OpenFOAM/db/IOstreams/memory/memoryStreamBuffer.H b/src/OpenFOAM/db/IOstreams/memory/memoryStreamBuffer.H index 446053a890..5c49b1d5b5 100644 --- a/src/OpenFOAM/db/IOstreams/memory/memoryStreamBuffer.H +++ b/src/OpenFOAM/db/IOstreams/memory/memoryStreamBuffer.H @@ -38,6 +38,7 @@ Description #include "DynamicList.H" #include +#include #include #include diff --git a/src/OpenFOAM/db/dictionary/dictionary.H b/src/OpenFOAM/db/dictionary/dictionary.H index 67f771e3d2..38ded49d1d 100644 --- a/src/OpenFOAM/db/dictionary/dictionary.H +++ b/src/OpenFOAM/db/dictionary/dictionary.H @@ -113,6 +113,7 @@ SeeAlso #include "label.H" #include "scalar.H" #include "regExpFwd.H" +#include "Switch.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/db/error/messageStream.H b/src/OpenFOAM/db/error/messageStream.H index e07345bb05..0f55064928 100644 --- a/src/OpenFOAM/db/error/messageStream.H +++ b/src/OpenFOAM/db/error/messageStream.H @@ -55,6 +55,8 @@ SourceFiles #include "label.H" #include "word.H" + +#include #include #include diff --git a/src/OpenFOAM/global/debug/simpleObjectRegistry.H b/src/OpenFOAM/global/debug/simpleObjectRegistry.H index 5823c5a516..a7fc5a4139 100644 --- a/src/OpenFOAM/global/debug/simpleObjectRegistry.H +++ b/src/OpenFOAM/global/debug/simpleObjectRegistry.H @@ -40,6 +40,7 @@ SourceFiles #include "Dictionary.H" #include "simpleRegIOobject.H" +#include #include // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/global/fileOperations/fileOperation/fileOperation.C b/src/OpenFOAM/global/fileOperations/fileOperation/fileOperation.C index dd39a58954..b9eecd144f 100644 --- a/src/OpenFOAM/global/fileOperations/fileOperation/fileOperation.C +++ b/src/OpenFOAM/global/fileOperations/fileOperation/fileOperation.C @@ -333,7 +333,7 @@ Foam::fileMonitor& Foam::fileOperation::monitor() const void Foam::fileOperation::mergeTimes ( - const instantList& extraTimes, + const UList& extraTimes, const word& constantName, instantList& times ) diff --git a/src/OpenFOAM/global/fileOperations/fileOperation/fileOperation.H b/src/OpenFOAM/global/fileOperations/fileOperation/fileOperation.H index bd19e08c25..27e931ef02 100644 --- a/src/OpenFOAM/global/fileOperations/fileOperation/fileOperation.H +++ b/src/OpenFOAM/global/fileOperations/fileOperation/fileOperation.H @@ -198,8 +198,10 @@ protected: //- Merge two times static void mergeTimes ( - const instantList& extraTimes, + const UList& extraTimes, + //! The "constant" name const word& constantName, + //! [in,out] Updated with any extra times instantList& times ); @@ -870,7 +872,13 @@ public: ) const; //- Get sorted list of times - virtual instantList findTimes(const fileName&, const word&) const; + virtual instantList findTimes + ( + //! The directory to search + const fileName& directory, + //! The "constant" name + const word& constantName = "constant" + ) const; //- Find time instance where IOobject is located. //- The name of the IOobject can be empty, in which case only the diff --git a/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.H b/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.H index 37f49fc1ed..c68ea352dc 100644 --- a/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.H +++ b/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.H @@ -748,7 +748,13 @@ public: // Other //- Get sorted list of times - virtual instantList findTimes(const fileName&, const word&) const; + virtual instantList findTimes + ( + //! The directory to search + const fileName& directory, + //! The "constant" name + const word& constantName = "constant" + ) const; //- Find time instance where IOobject is located. //- The name of the IOobject can be empty, in which case only the diff --git a/src/OpenFOAM/include/addAllRegionOptions.H b/src/OpenFOAM/include/addAllRegionOptions.H index 67e10b234e..fb9eced092 100644 --- a/src/OpenFOAM/include/addAllRegionOptions.H +++ b/src/OpenFOAM/include/addAllRegionOptions.H @@ -11,7 +11,10 @@ License This file is part of OpenFOAM, distributed under GPL-3.0-or-later. Description - Add multi-region command-line options: -allRegions, -regions, -region + Add multi-region command-line options: + -allRegions | -all-regions + -regions + -region Required Classes - Foam::argList @@ -24,10 +27,10 @@ See Also { Foam::argList::addBoolOption ( - "all-regions", + "allRegions", "Use all regions in regionProperties" ); - Foam::argList::addOptionCompat("all-regions", { "allRegions", -2506 }); + Foam::argList::addOptionCompat("allRegions", { "all-regions", 0 }); Foam::argList::addOption ( diff --git a/src/OpenFOAM/include/getAllRegionOptions.H b/src/OpenFOAM/include/getAllRegionOptions.H index 887646b9d6..dcea9facdc 100644 --- a/src/OpenFOAM/include/getAllRegionOptions.H +++ b/src/OpenFOAM/include/getAllRegionOptions.H @@ -45,12 +45,19 @@ See Also wordList regionNames; { - // Local alias - auto& names = regionNames; // Exit or fallback if nothing matches constexpr bool exitOnNoMatches = true; - if (args.found("all-regions")) + // Local aliases + auto& names = regionNames; + const auto& fallback = Foam::polyMesh::defaultRegion; + + if + ( + // Handle both here (independent of which is an alias) + args.found("all-regions") + || args.found("allRegions") + ) { names = ( @@ -81,11 +88,11 @@ wordList regionNames; { select.uniq(); // Normally a no-op - if (select.size() == 1 && select.front().isLiteral()) + if (select.size() == 1 && select[0].isLiteral()) { // Identical to -region NAME names.resize(1); - names.front() = select.front(); + names[0] = select[0]; } else if (select.size()) { @@ -116,12 +123,12 @@ wordList regionNames; } else { - InfoErr<< "... ignoring and using default region" + InfoErr + << "... ignoring and using default region" << nl << endl; - // Arbitrary fallback, but can handle this further on names.resize(1); - names.front() = Foam::polyMesh::defaultRegion; + names[0] = fallback; } } else @@ -160,7 +167,7 @@ wordList regionNames; else { names.resize(1); - names.front() = Foam::polyMesh::defaultRegion; + names[0] = fallback; InfoErr << "Warning: No regionProperties, " @@ -169,17 +176,30 @@ wordList regionNames; } } } - else if (args.found("region")) + else { + // Single region option or fallback names.resize(1); - names.front() = args.get("region"); + auto& name = names[0]; + + if + ( + !args.readIfPresent("region", name) + ) + { + name = fallback; + } } - // Fallback to defaultRegion + // Final sanity checks and/or fallback if (names.empty()) { names.resize(1); - names.front() = Foam::polyMesh::defaultRegion; + names[0] = fallback; + } + else if (names.size() == 1 && names[0].empty()) + { + names[0] = fallback; } } diff --git a/src/OpenFOAM/primitives/bools/Switch/Switch.H b/src/OpenFOAM/primitives/bools/Switch/Switch.H index ddef797909..af8effc2f1 100644 --- a/src/OpenFOAM/primitives/bools/Switch/Switch.H +++ b/src/OpenFOAM/primitives/bools/Switch/Switch.H @@ -43,6 +43,9 @@ SourceFiles #include "bool.H" #include "stdFoam.H" +#include +#include + // Avoid any pre-processor conflicts with enum names #undef FALSE #undef TRUE diff --git a/src/OpenFOAM/primitives/strings/lists/CStringList.H b/src/OpenFOAM/primitives/strings/lists/CStringList.H index fd24374be1..1e88bc84a2 100644 --- a/src/OpenFOAM/primitives/strings/lists/CStringList.H +++ b/src/OpenFOAM/primitives/strings/lists/CStringList.H @@ -60,6 +60,7 @@ Description #include // std::initializer_list #include #include +#include // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/primitives/strings/lists/SubStrings.H b/src/OpenFOAM/primitives/strings/lists/SubStrings.H index eb98de37ee..dcb8b6b943 100644 --- a/src/OpenFOAM/primitives/strings/lists/SubStrings.H +++ b/src/OpenFOAM/primitives/strings/lists/SubStrings.H @@ -37,6 +37,7 @@ Description #include // For std::ssub_match #include +#include #include #include diff --git a/src/OpenFOAM/primitives/strings/regex/regExpCxx.H b/src/OpenFOAM/primitives/strings/regex/regExpCxx.H index d2f288e1be..49e523d89f 100644 --- a/src/OpenFOAM/primitives/strings/regex/regExpCxx.H +++ b/src/OpenFOAM/primitives/strings/regex/regExpCxx.H @@ -69,6 +69,7 @@ SourceFiles #define Foam_regExpCxx_H #include +#include #include // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/primitives/strings/string/string.H b/src/OpenFOAM/primitives/strings/string/string.H index 878028e6b8..14d0de250b 100644 --- a/src/OpenFOAM/primitives/strings/string/string.H +++ b/src/OpenFOAM/primitives/strings/string/string.H @@ -54,6 +54,7 @@ SourceFiles #include "Hasher.H" #include #include +#include #include // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/primitives/strings/stringOps/stringOpsSort.H b/src/OpenFOAM/primitives/strings/stringOps/stringOpsSort.H index 3574b3e6b6..6c169f3f93 100644 --- a/src/OpenFOAM/primitives/strings/stringOps/stringOpsSort.H +++ b/src/OpenFOAM/primitives/strings/stringOps/stringOpsSort.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2017 OpenCFD Ltd. + Copyright (C) 2017-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -46,85 +46,106 @@ namespace Foam namespace stringOps { - //- 'Natural' compare for C-strings - // Uses algorithm and code from Jan-Marten Spit - // - // In the 'natural' comparison, strings are compared alphabetically - // and numerically. Thus 'file010.txt' sorts after 'file2.txt' - // - // \param s1 left string - // \param s2 right string +//- 'Natural' compare for C-strings +// Uses algorithm and code from Jan-Marten Spit +// +// In the 'natural' comparison, strings are compared alphabetically +// and numerically. Thus 'file010.txt' sorts after 'file2.txt' +// +// \param s1 left string +// \param s2 right string +// \return -1 when s1 < s2, 0 when s1 == s2, 1 when s1 > s2 +int natstrcmp(const char* s1, const char* s2); + + +//- Encapsulation of natural order sorting for algorithms +struct natural_sort +{ + //- Natural compare for std::string // \return -1 when s1 < s2, 0 when s1 == s2, 1 when s1 > s2 - int natstrcmp(const char* s1, const char* s2); - - - //- Encapsulation of natural order sorting for algorithms - struct natural_sort + static inline int compare + ( + const std::string& s1, + const std::string& s2 + ) { - //- Natural compare for std::string - // \return -1 when s1 < s2, 0 when s1 == s2, 1 when s1 > s2 - static inline int compare - ( - const std::string& s1, - const std::string& s2 - ) - { - return natstrcmp(s1.data(), s2.data()); - } + return stringOps::natstrcmp(s1.data(), s2.data()); + } - //- Default (forward) natural sorting + //- Natural compare two strings for a less-than relationship + static inline bool less + ( + const std::string& s1, + const std::string& s2 + ) + { + return (natural_sort::compare(s1, s2) < 0); + } + + //- Natural compare two strings for a greater-than relationship + static inline bool greater + ( + const std::string& s1, + const std::string& s2 + ) + { + return (natural_sort::compare(s1, s2) > 0); + } + + //- Default (forward) natural sorting + bool operator()(const std::string& s1, const std::string& s2) const + { + return (natural_sort::compare(s1, s2) < 0); + } + + //- Reverse natural sorting + struct reverse + { + //- Reverse natural sorting bool operator()(const std::string& s1, const std::string& s2) const { - return natural_sort::compare(s1, s2) < 0; + return (natural_sort::compare(s1, s2) > 0); } - - //- Reverse natural sorting - struct reverse - { - //- Reverse natural sorting - bool operator()(const std::string& s1, const std::string& s2) const - { - return natural_sort::compare(s1, s2) > 0; - } - }; - - - //- A list compare binary predicate for natural sort - template - struct less - { - const UList& values; - - less(const UList& list) - : - values(list) - {} - - bool operator()(const label a, const label b) const - { - return natural_sort::compare(values[a], values[b]) < 0; - } - }; - - - //- A list compare binary predicate for reverse natural sort - template - struct greater - { - const UList& values; - - greater(const UList& list) - : - values(list) - {} - - bool operator()(const label a, const label b) const - { - return natural_sort::compare(values[a], values[b]) > 0; - } - }; }; + + //- A UList compare binary predicate for natural sort + template + struct list_less + { + const UList& values; + + list_less(const UList& list) noexcept + : + values(list) + {} + + bool operator()(label a, label b) const + { + return (natural_sort::compare(values[a], values[b]) < 0); + } + }; + + + //- A Ulist compare binary predicate for reverse natural sort + template + struct list_greater + { + const UList& values; + + list_greater(const UList& list) noexcept + : + values(list) + {} + + bool operator()(label a, label b) const + { + return (natural_sort::compare(values[a], values[b]) > 0); + } + }; +}; + + } // End namespace stringOps } // End namespace Foam diff --git a/src/fileFormats/vtk/file/foamVtkSeriesWriter.C b/src/fileFormats/vtk/file/foamVtkSeriesWriter.C index 0950fe2a59..7a2a85c5c2 100644 --- a/src/fileFormats/vtk/file/foamVtkSeriesWriter.C +++ b/src/fileFormats/vtk/file/foamVtkSeriesWriter.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2018-2023 OpenCFD Ltd. + Copyright (C) 2018-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -64,13 +64,17 @@ namespace Foam // 2. natural sort (name) struct seriesLess { - bool operator()(const fileNameInstant a, const fileNameInstant b) const + template + bool operator() + ( + const Instant& a, + const Instant& b + ) const { scalar val = compareOp()(a.value(), b.value()); if (val == 0) { - return - stringOps::natural_sort::compare(a.name(), b.name()) < 0; + return stringOps::natural_sort::less(a.name(), b.name()); } return val < 0; } @@ -78,7 +82,7 @@ namespace Foam // Check if value is less than upper, with some tolerance. - static inline bool lessThan(const scalar& val, const scalar& upper) + static inline bool lessThan(scalar val, scalar upper) { return (val < upper && Foam::mag(val - upper) > ROOTVSMALL); } diff --git a/src/finiteArea/include/addAllFaRegionOptions.H b/src/finiteArea/include/addAllFaRegionOptions.H index cefac98abc..9b203ebba0 100644 --- a/src/finiteArea/include/addAllFaRegionOptions.H +++ b/src/finiteArea/include/addAllFaRegionOptions.H @@ -12,7 +12,9 @@ License Description Add multi-region command-line options: - -all-area-regions, -area-regions, -area-region + -allAreas | -all-area-regions + -area-regions + -area-region Required Classes - Foam::argList @@ -25,9 +27,10 @@ See Also { Foam::argList::addBoolOption ( - "all-area-regions", + "allAreas", "Use all regions in finite-area regionProperties" ); + Foam::argList::addOptionCompat("allAreas", { "all-area-regions", 0 }); Foam::argList::addOption ( @@ -41,8 +44,11 @@ See Also ( "area-region", "name", - "Specify area-mesh region. Eg, -region shell" + "Specify area-mesh region. Eg, -area-region shell" ); + + // TBD: + //? Foam::argList::addOptionCompat("area-region", { "areaRegion", 0 }); } diff --git a/src/finiteArea/include/getAllFaRegionOptions.H b/src/finiteArea/include/getAllFaRegionOptions.H index 7e456a6d00..bd1cd32991 100644 --- a/src/finiteArea/include/getAllFaRegionOptions.H +++ b/src/finiteArea/include/getAllFaRegionOptions.H @@ -15,7 +15,7 @@ Description (-all-area-regions | -area-regions | -area-region) Priority - 1. -all-area-regions + 1. -all-area-regions (-allAreas) 2. -area-regions = specify multiple area regions to select, or a single area region 3. -area-region = specify a single area region @@ -46,12 +46,19 @@ See Also wordList areaRegionNames; { - // Local alias - auto& names = areaRegionNames; // Exit or fallback if nothing matches constexpr bool exitOnNoMatches = false; - if (args.found("all-area-regions")) + // Local aliases + auto& names = areaRegionNames; + const auto& fallback = Foam::polyMesh::defaultRegion; + + if + ( + // Handle both here (independent of which is an alias) + args.found("all-area-regions") + || args.found("allAreas") + ) { names = ( @@ -78,16 +85,20 @@ wordList areaRegionNames; else if ( wordRes select; - args.readListIfPresent("area-regions", select) + ( + // Handle both here (independent of which is an alias) + args.readListIfPresent("area-regions", select) + || args.readListIfPresent("areaRegions", select) + ) ) { select.uniq(); // Normally a no-op - if (select.size() == 1 && select.front().isLiteral()) + if (select.size() == 1 && select[0].isLiteral()) { // Identical to -area-region NAME names.resize(1); - names.front() = select.front(); + names[0] = select[0]; } else if (select.size()) { @@ -119,12 +130,12 @@ wordList areaRegionNames; } else { - InfoErr<< "... ignoring and using default region" + InfoErr + << "... ignoring and using default region" << nl << endl; - // Arbitrary fallback, but can handle this further on names.resize(1); - names.front() = Foam::polyMesh::defaultRegion; + names[0] = fallback; } } else @@ -162,7 +173,7 @@ wordList areaRegionNames; else { names.resize(1); - names.front() = Foam::polyMesh::defaultRegion; + names[0] = fallback; InfoErr << "Warning: No finite-area regionProperties, " @@ -171,17 +182,32 @@ wordList areaRegionNames; } } } - else if (args.found("area-region")) + else { + // Single region option or fallback names.resize(1); - names.front() = args.get("area-region"); + auto& name = names[0]; + + if + ( + // Handle both here (independent of which is an alias) + !args.readIfPresent("area-region", name) + && !args.readIfPresent("areaRegion", name) + ) + { + name = fallback; + } } - // Fallback to defaultRegion + // Final sanity checks and/or fallback if (names.empty()) { names.resize(1); - names.front() = Foam::polyMesh::defaultRegion; + names[0] = fallback; + } + else if (names.size() == 1 && names[0].empty()) + { + names[0] = fallback; } } From e7b9d57158bdc379aee6bfa4c27ecf1ddbfb8b13 Mon Sep 17 00:00:00 2001 From: Andrew Heather <> Date: Wed, 10 May 2023 21:29:07 +0100 Subject: [PATCH 08/18] ENH: AMI - added caching of weights and addressing Applicable to rotational cases: - stores AMI weights and addressing on the first revolution - cached evaluations performed on subsequent revolutions to reduce computational costs Cached values are stored in angular bins, specified using the [optional] `cacheSize` entry when defining the patch in the polyMesh/boundary file, e.g. AMI1 { type cyclicAMI; AMIMethod faceAreaWeightAMI; neighbourPatch AMI2; cacheSize 360; // New entry transform rotational; rotationAxis (0 0 1); rotationCentre (0 0 0); } Note that the transform must also be set to rotational; the additional `rotationAxis` and `rotationCentre` entries are used to construct a local AMI co-ordinate system to determine the rotation angle as the mesh moves. 360 bins are created in the example above, equating to a uniform bin width of 1 degree. --- .../AMIInterpolation/AMIInterpolation.C | 490 +++++++++++++++++- .../AMIInterpolation/AMIInterpolation.H | 51 +- .../AMIInterpolation/AMIInterpolationI.H | 5 + .../AMIInterpolationTemplates.C | 468 +++++++++++++---- .../cyclicAMIPolyPatch/cyclicAMIPolyPatch.C | 48 +- .../cyclicAMIPolyPatch/cyclicAMIPolyPatch.H | 3 + .../algorithms/MeshWave/FaceCellWave.C | 11 +- 7 files changed, 947 insertions(+), 129 deletions(-) diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C index 3fdc581593..d66d8c2227 100644 --- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C +++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C @@ -58,14 +58,206 @@ registerOptSwitch Foam::AMIInterpolation::useLocalComm_ ); +Foam::scalar Foam::AMIInterpolation::cacheThetaTolerance_ = 1e-8; // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // -Foam::autoPtr> -Foam::AMIInterpolation::createTree +Foam::scalar Foam::AMIInterpolation::getRotationAngle(const point& p) const +{ + if (!coordSysPtr_) + { + FatalErrorInFunction + << "No co-ordinate system available for theta evaluation" + << abort(FatalError); + } + + scalar theta = -GREAT; + if (p != point::max) + { + theta = coordSysPtr_->localPosition(p)[1]; + } + reduce(theta, maxOp()); + + // Ensure 0 < theta < 2pi + if (mag(theta) < cacheThetaTolerance_) + { + theta = 0; + } + else if (theta < 0) + { + theta += constant::mathematical::twoPi; + } + + return theta; +} + + +void Foam::AMIInterpolation::addToCache ( - const primitivePatch& patch -) const + const point& refPt, + const vector& rotationAxis, + const vector& rotationCentre +) +{ + if (cacheSize_ == -1) + { + DebugInfo<< "-- addToCache - deactivated" << endl; + return; + } + + DebugInfo<< "-- addToCache" << endl; + + if (!coordSysPtr_) + { + DebugInfo + << "Creating rotation co-ordinate system:" + << " rotationCentre:" << rotationCentre + << " rotationAxis:" << rotationAxis + << " p:" << refPt + << endl; + + vector axis(normalised(refPt - rotationCentre)); + coordSysPtr_.reset + ( + new coordSystem::cylindrical(rotationCentre, rotationAxis, axis) + ); + DebugInfo<< "Coord sys:" << coordSysPtr_() << endl; + } + + // Check if cache is complete + if (!cacheComplete_) + { + forAll(cachedTheta_, i) + { + if (cachedTheta_[i] > constant::mathematical::twoPi) + { + cacheComplete_ = false; + break; + } + } + } + + if (!cacheComplete_) + { + const scalar theta = getRotationAngle(refPt); + const label bini = theta/constant::mathematical::twoPi*cacheSize_; + + DebugInfo<< "-- bini:" << bini << " for theta:" << theta << endl; + + if (cachedTheta_[bini] > constant::mathematical::twoPi) + { + DebugInfo<< "-- setting cache at index " << bini << endl; + + // New entry + cachedTheta_[bini] = theta; + + cachedSrcAddress_[bini] = srcAddress_; + cachedSrcWeights_[bini] = srcWeights_; + cachedSrcWeightsSum_[bini] = srcWeightsSum_; + cachedSrcMapPtr_[bini] = srcMapPtr_.clone(); + + cachedTgtAddress_[bini] = tgtAddress_; + cachedTgtWeights_[bini] = tgtWeights_; + cachedTgtWeightsSum_[bini] = tgtWeightsSum_; + cachedTgtMapPtr_[bini] = tgtMapPtr_.clone(); + } + } +} + + +bool Foam::AMIInterpolation::restoreCache(const point& refPt) +{ + DebugInfo<< "-- restoreCache" << endl; + + upToDate_ = false; + cachedIndex0_ = -1; + cachedIndex1_ = -1; + cachedWeight_ = -1; + + if (!coordSysPtr_ || cacheSize_ == -1) + { + return upToDate_; + } + + const scalar theta = getRotationAngle(refPt); + const label bini = theta/constant::mathematical::twoPi*cacheSize_; + + DebugInfo<< "-- bini:" << bini << " for theta:" << theta << endl; + + auto validIndex = [&](const scalar bini) + { + return cachedTheta_[bini] < constant::mathematical::twoPi; + }; + + if (validIndex(bini)) + { + // Find participating bins + if (mag(theta - cachedTheta_[bini]) < cacheThetaTolerance_) + { + // Hit cached value - no interpolation needed + cachedIndex0_ = bini; + upToDate_ = true; + } + else if (theta > cachedTheta_[bini]) + { + // Check that previous bin is valid + const label i1 = cachedTheta_.fcIndex(bini); + if (validIndex(i1)) + { + cachedIndex0_ = bini; + cachedIndex1_ = i1; + upToDate_ = true; + } + } + else // (theta < cachedTheta_[bini]) + { + // Check that previous bin is valid + const label i1 = cachedTheta_.rcIndex(bini); + if (validIndex(i1)) + { + cachedIndex0_ = i1; + cachedIndex1_ = bini; + upToDate_ = true; + } + } + + if (!upToDate_) + { + DebugInfo<< "-- no cache available" << endl; + return false; + } + + + // Calculate weighting factor + if (cachedIndex1_ != -1) + { + const scalar t0 = cachedTheta_[cachedIndex0_]; + scalar t1 = cachedTheta_[cachedIndex1_]; + + if (cachedIndex1_ < cachedIndex0_) + { + t1 += constant::mathematical::twoPi; + } + + // Set time-based weighting factor + cachedWeight_ = (theta - t0)/(t1 - t0); + + DebugInfo + << "-- i0:" << cachedIndex0_ << " i1:" << cachedIndex1_ + << " w:" << cachedWeight_ << endl; + } + } + else + { + DebugInfo<< " -- no cache available" << endl; + } + + return upToDate_; +} + + +Foam::autoPtr> +Foam::AMIInterpolation::createTree(const primitivePatch &patch) const { treeBoundBox bb(patch.points(), patch.meshPoints()); bb.inflate(0.01); @@ -700,8 +892,36 @@ Foam::AMIInterpolation::AMIInterpolation tgtWeightsSum_(), tgtCentroids_(), tgtMapPtr_(nullptr), - upToDate_(false) -{} + upToDate_(false), + cacheSize_(dict.getOrDefault("cacheSize", -1)), + cacheComplete_(false), + cachedIndex0_(-1), + cachedIndex1_(-1), + cachedWeight_(0), + coordSysPtr_(nullptr), + cachedTheta_(), + cachedSrcAddress_(), + cachedSrcWeights_(), + cachedSrcWeightsSum_(), + cachedSrcMapPtr_(), + cachedTgtAddress_(), + cachedTgtWeights_(), + cachedTgtWeightsSum_(), + cachedTgtMapPtr_() +{ + if (cacheSize_ != -1) + { + cachedTheta_.resize(cacheSize_, GREAT); + cachedSrcAddress_.resize(cacheSize_); + cachedSrcWeights_.resize(cacheSize_); + cachedSrcWeightsSum_.resize(cacheSize_); + cachedSrcMapPtr_.resize(cacheSize_); + cachedTgtAddress_.resize(cacheSize_); + cachedTgtWeights_.resize(cacheSize_); + cachedTgtWeightsSum_.resize(cacheSize_); + cachedTgtMapPtr_.resize(cacheSize_); + } +} Foam::AMIInterpolation::AMIInterpolation @@ -730,7 +950,22 @@ Foam::AMIInterpolation::AMIInterpolation tgtCentroids_(), tgtPatchPts_(), tgtMapPtr_(nullptr), - upToDate_(false) + upToDate_(false), + cacheSize_(0), + cacheComplete_(false), + cachedIndex0_(-1), + cachedIndex1_(-1), + cachedWeight_(0), + coordSysPtr_(nullptr), + cachedTheta_(), + cachedSrcAddress_(), + cachedSrcWeights_(), + cachedSrcWeightsSum_(), + cachedSrcMapPtr_(), + cachedTgtAddress_(), + cachedTgtWeights_(), + cachedTgtWeightsSum_(), + cachedTgtMapPtr_() {} @@ -743,7 +978,7 @@ Foam::AMIInterpolation::AMIInterpolation : requireMatch_(fineAMI.requireMatch_), reverseTarget_(fineAMI.reverseTarget_), - lowWeightCorrection_(-1.0), + lowWeightCorrection_(-1.0), // Deactivated? singlePatchProc_(fineAMI.singlePatchProc_), comm_(fineAMI.comm()), // use fineAMI geomComm if present, comm otherwise geomComm_(), @@ -759,16 +994,31 @@ Foam::AMIInterpolation::AMIInterpolation tgtWeightsSum_(), tgtPatchPts_(), tgtMapPtr_(nullptr), - upToDate_(false) + upToDate_(false), + cacheSize_(fineAMI.cacheSize_), + cacheComplete_(fineAMI.cacheComplete_), + cachedIndex0_(fineAMI.cachedIndex0_), + cachedIndex1_(fineAMI.cachedIndex1_), + cachedWeight_(fineAMI.cachedWeight_), + coordSysPtr_(nullptr), + cachedTheta_(fineAMI.cachedTheta_), + cachedSrcAddress_(fineAMI.cachedSrcAddress_.size()), + cachedSrcWeights_(fineAMI.cachedSrcWeights_.size()), + cachedSrcWeightsSum_(fineAMI.cachedSrcWeightsSum_.size()), + cachedSrcMapPtr_(fineAMI.cachedSrcMapPtr_.size()), + cachedTgtAddress_(fineAMI.cachedTgtAddress_.size()), + cachedTgtWeights_(fineAMI.cachedTgtWeights_.size()), + cachedTgtWeightsSum_(fineAMI.cachedTgtWeightsSum_.size()), + cachedTgtMapPtr_(fineAMI.cachedTgtMapPtr_.size()) { - label sourceCoarseSize = + const label sourceCoarseSize = ( sourceRestrictAddressing.size() ? max(sourceRestrictAddressing)+1 : 0 ); - label neighbourCoarseSize = + const label neighbourCoarseSize = ( targetRestrictAddressing.size() ? max(targetRestrictAddressing)+1 @@ -879,6 +1129,76 @@ Foam::AMIInterpolation::AMIInterpolation comm() ); } + + if (cacheSize_ > 0) + { + FixedList indices({cachedIndex0_, cachedIndex1_}); + + for (label cachei : indices) + { + if (cachei == -1) continue; + + scalarField dummySrcMagSf; + + labelListList cSrcAddress; + scalarListList cSrcWeights; + autoPtr cTgtMapPtr; + scalarField cSrcWeightsSum; + + labelListList cTgtAddress; + scalarListList cTgtWeights; + autoPtr cSrcMapPtr; + scalarField cTgtWeightsSum; + + agglomerate + ( + fineAMI.cachedTgtMapPtr_[cachei], + fineAMI.srcMagSf(), + fineAMI.cachedSrcAddress_[cachei], + fineAMI.cachedSrcWeights_[cachei], + + sourceRestrictAddressing, + targetRestrictAddressing, + + dummySrcMagSf, + cSrcAddress, + cSrcWeights, + cSrcWeightsSum, + cTgtMapPtr, + comm() + ); + + scalarField dummyTgtMagSf; + + agglomerate + ( + fineAMI.cachedSrcMapPtr_[cachei], + fineAMI.tgtMagSf(), + fineAMI.cachedTgtAddress_[cachei], + fineAMI.cachedTgtWeights_[cachei], + + targetRestrictAddressing, + sourceRestrictAddressing, + + dummyTgtMagSf, + cTgtAddress, + cTgtWeights, + cTgtWeightsSum, + cSrcMapPtr, + comm() + ); + + cachedSrcAddress_[cachei] = cSrcAddress; + cachedSrcWeights_[cachei] = cSrcWeights; + cachedSrcWeightsSum_[cachei] = cSrcWeightsSum; + cachedSrcMapPtr_[cachei] = cSrcMapPtr.clone(); + + cachedTgtAddress_[cachei] = cTgtAddress; + cachedTgtWeights_[cachei] = cTgtWeights; + cachedTgtWeightsSum_[cachei] = cTgtWeightsSum; + cachedTgtMapPtr_[cachei] = cTgtMapPtr.clone(); + } + } } @@ -895,15 +1215,40 @@ Foam::AMIInterpolation::AMIInterpolation(const AMIInterpolation& ami) srcWeights_(ami.srcWeights_), srcWeightsSum_(ami.srcWeightsSum_), srcCentroids_(ami.srcCentroids_), - srcMapPtr_(nullptr), + srcMapPtr_(ami.srcMapPtr_.clone()), tgtMagSf_(ami.tgtMagSf_), tgtAddress_(ami.tgtAddress_), tgtWeights_(ami.tgtWeights_), tgtWeightsSum_(ami.tgtWeightsSum_), tgtCentroids_(ami.tgtCentroids_), - tgtMapPtr_(nullptr), - upToDate_(false) -{} + tgtMapPtr_(ami.tgtMapPtr_.clone()), + upToDate_(ami.upToDate_), + cacheSize_(ami.cacheSize_), + cacheComplete_(ami.cacheComplete_), + cachedIndex0_(ami.cachedIndex0_), + cachedIndex1_(ami.cachedIndex1_), + cachedWeight_(ami.cachedWeight_), + coordSysPtr_(nullptr), // TODO: ami.coordSysPtr_.clone()), + cachedTheta_(ami.cachedTheta_), + cachedSrcAddress_(ami.cachedSrcAddress_), + cachedSrcWeights_(ami.cachedSrcWeights_), + cachedSrcWeightsSum_(ami.cachedSrcWeightsSum_), + cachedSrcMapPtr_(ami.cachedSrcMapPtr_.size()), // Need to clone + cachedTgtAddress_(ami.cachedTgtAddress_), + cachedTgtWeights_(ami.cachedTgtWeights_), + cachedTgtWeightsSum_(ami.cachedTgtWeightsSum_), + cachedTgtMapPtr_(ami.cachedTgtMapPtr_.size()) // Need to clone +{ + forAll(cachedSrcMapPtr_, cachei) + { + cachedSrcMapPtr_[cachei].reset(ami.cachedSrcMapPtr_[cachei].clone()); + } + + forAll(cachedTgtMapPtr_, cachei) + { + cachedTgtMapPtr_[cachei].reset(ami.cachedTgtMapPtr_[cachei].clone()); + } +} Foam::AMIInterpolation::AMIInterpolation(Istream& is) @@ -930,7 +1275,24 @@ Foam::AMIInterpolation::AMIInterpolation(Istream& is) //tgtPatchPts_(is), tgtMapPtr_(nullptr), - upToDate_(readBool(is)) + upToDate_(readBool(is)), + + cacheSize_(readLabel(is)), + cacheComplete_(readBool(is)), + + cachedIndex0_(-1), + cachedIndex1_(-1), + cachedWeight_(0), + coordSysPtr_(nullptr), + cachedTheta_(), + cachedSrcAddress_(), + cachedSrcWeights_(), + cachedSrcWeightsSum_(), + cachedSrcMapPtr_(), + cachedTgtAddress_(), + cachedTgtWeights_(), + cachedTgtWeightsSum_(), + cachedTgtMapPtr_() { // Hopefully no need to stream geomComm_ since only used in processor // agglomeration? @@ -940,6 +1302,51 @@ Foam::AMIInterpolation::AMIInterpolation(Istream& is) srcMapPtr_.reset(new mapDistribute(is)); tgtMapPtr_.reset(new mapDistribute(is)); } + + // Caching + + const bitSet goodMap(is); + + if (goodMap.size()) + { + is >> cachedIndex0_ + >> cachedIndex1_ + >> cachedWeight_ + >> cachedTheta_; + + const bool goodCoord(readBool(is)); + if (goodCoord) + { + coordSysPtr_.reset(new coordSystem::cylindrical(is)); + } + + is >> cachedSrcAddress_ + >> cachedSrcWeights_ + >> cachedSrcWeightsSum_; + + cachedSrcMapPtr_.setSize(goodMap.size()); + forAll(goodMap, cachei) + { + if (goodMap[cachei]) + { + cachedSrcMapPtr_[cachei].reset(new mapDistribute(is)); + } + } + + is >> cachedTgtAddress_ + >> cachedTgtWeights_ + >> cachedTgtWeightsSum_; + + + cachedTgtMapPtr_.setSize(goodMap.size()); + forAll(goodMap, cachei) + { + if (goodMap[cachei]) + { + cachedTgtMapPtr_[cachei].reset(new mapDistribute(is)); + } + } + } } @@ -1361,7 +1768,6 @@ const } else if (ray.distance() < nearest.distance()) { - nearest = ray; nearestFacei = srcFacei; } @@ -1539,6 +1945,11 @@ void Foam::AMIInterpolation::write(Ostream& os) const { os.writeEntry("lowWeightCorrection", lowWeightCorrection_); } + + if (cacheSize_ > 0) + { + os.writeEntry("cacheSize", cacheSize_); + } } @@ -1562,7 +1973,11 @@ bool Foam::AMIInterpolation::writeData(Ostream& os) const << token::SPACE<< tgtWeightsSum() << token::SPACE<< tgtCentroids_ - << token::SPACE<< upToDate(); + << token::SPACE<< upToDate() + + << token::SPACE<< cacheSize_ + << token::SPACE<< cacheComplete_; + if (distributed() && comm() != -1) { @@ -1570,6 +1985,45 @@ bool Foam::AMIInterpolation::writeData(Ostream& os) const << token::SPACE<< tgtMap(); } + bitSet goodMap(cachedSrcMapPtr_.size()); + forAll(goodMap, cachei) + { + goodMap.set(cachei, cachedSrcMapPtr_[cachei].good()); + } + os << token::SPACE << goodMap; + + + os << token::SPACE << cachedIndex0_ + << token::SPACE << cachedIndex1_ + << token::SPACE << cachedWeight_ + << token::SPACE << cachedTheta_; + + os << token::SPACE << coordSysPtr_.good(); + + if (coordSysPtr_.good()) + { + os << token::SPACE << coordSysPtr_(); + } + + os << token::SPACE << cachedSrcAddress_ + << token::SPACE << cachedSrcWeights_ + << token::SPACE << cachedSrcWeightsSum_; + + + for (const auto& index : goodMap) + { + os << token::SPACE << cachedSrcMapPtr_[index](); + } + + os << token::SPACE << cachedTgtAddress_ + << token::SPACE << cachedTgtWeights_ + << token::SPACE << cachedTgtWeightsSum_; + + for (const auto& index : goodMap) + { + os << token::SPACE << cachedTgtMapPtr_[index](); + } + return os.good(); } diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H index fee80cd6ba..4a6e04bc94 100644 --- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H +++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H @@ -61,7 +61,7 @@ SourceFiles #include "indexedOctree.H" #include "treeDataPrimitivePatch.H" #include "runTimeSelectionTables.H" - +#include "cylindricalCS.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -78,6 +78,7 @@ public: // Public Data Types + //- Flag to store face-to-face intersection triangles; default = false static bool cacheIntersections_; //- Control use of local communicator for AMI communication @@ -86,6 +87,10 @@ public: // localComm : 2 : like 1 but always include master (for messages) static int useLocalComm_; + //- Tolerance used when caching the AMI to identify e.g. if the + //- current rotation angle has already been captured + static scalar cacheThetaTolerance_; + protected: @@ -145,7 +150,6 @@ protected: autoPtr srcMapPtr_; - // Target patch //- Target face areas @@ -173,9 +177,32 @@ protected: //- Target map pointer - parallel running only autoPtr tgtMapPtr_; + //- Up-to-date flag bool upToDate_; + // Cache + + label cacheSize_; + bool cacheComplete_; + label cachedIndex0_; + label cachedIndex1_; + scalar cachedWeight_; + autoPtr coordSysPtr_; + List cachedTheta_; + + //- + + List cachedSrcAddress_; + List cachedSrcWeights_; + List cachedSrcWeightsSum_; + List> cachedSrcMapPtr_; + + List cachedTgtAddress_; + List cachedTgtWeights_; + List cachedTgtWeightsSum_; + List> cachedTgtMapPtr_; + // Protected Member Functions @@ -212,12 +239,15 @@ protected: // Access - //- Return the orginal src patch with optionally updated points + //- Return the original src patch with optionally updated points inline const primitivePatch& srcPatch0() const; - //- Return the orginal tgt patch with optionally updated points + //- Return the original tgt patch with optionally updated points inline const primitivePatch& tgtPatch0() const; + //- Get rotation angle for cached AMI cases + scalar getRotationAngle(const point& p) const; + // Evaluation @@ -411,6 +441,8 @@ public: // \returns old value inline label comm(label communicator) noexcept; + //- Return true if caching is active + inline bool cacheActive() const; // Source patch @@ -671,6 +703,17 @@ public: ) const; + //- Restore AMI weights and addressing from the cache + bool restoreCache(const point& refPt); + + //- Add AMI weights and addressing to the cache + void addToCache + ( + const point& refPt, + const vector& rotationAxis, + const vector& rotationCentre + ); + // Checks diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolationI.H b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolationI.H index 7e4bdabaa7..9cfaff7a7e 100644 --- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolationI.H +++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolationI.H @@ -122,6 +122,11 @@ inline Foam::label Foam::AMIInterpolation::comm(label communicator) noexcept return old; } +inline bool Foam::AMIInterpolation::cacheActive() const +{ + return cacheSize_ > 0; +} + inline const Foam::List& Foam::AMIInterpolation::srcMagSf() const { diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolationTemplates.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolationTemplates.C index 48daacba69..73f27cc97d 100644 --- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolationTemplates.C +++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolationTemplates.C @@ -44,6 +44,14 @@ void Foam::AMIInterpolation::weightedSum const UList& defaultValues ) { +// DebugVar("AMIInterpolation::weightedSum"); + +// Info<< "allSlots.size():" << allSlots.size() << nl +// << "allWeights.size():" << allWeights.size() << nl +// << "weightsSum.size():" << weightsSum.size() << nl +// << "fld.size():" << fld.size() << nl +// << "defaultValues.size():" << defaultValues.size() << nl; + if (lowWeightCorrection > 0) { forAll(result, facei) @@ -89,17 +97,61 @@ void Foam::AMIInterpolation::weightedSum const UList& defaultValues ) const { - weightedSum - ( - lowWeightCorrection_, - (interpolateToSource ? srcAddress_ : tgtAddress_), - (interpolateToSource ? srcWeights_ : tgtWeights_), - (interpolateToSource ? srcWeightsSum_ : tgtWeightsSum_), - fld, - multiplyWeightedOp>(plusEqOp()), - result, - defaultValues - ); + // DebugVar("AMIInterpolation::weightedSum"); +// Info<< "cachedIndex0:" << cachedIndex0_ << " cachedIndex1:" << cachedIndex1_ << endl; + +// Info<< "cachedSrcAddress_.size():" << cachedSrcAddress_.size() << nl +// << "cachedTgtAddress_.size():" << cachedTgtAddress_.size() << nl +// << "cachedSrcWeights_.size():" << cachedSrcWeights_.size() << nl +// << "cachedTgtWeights_.size():" << cachedTgtWeights_.size() << nl +// << "cachedSrcWeightsSum_.size():" << cachedSrcWeightsSum_.size() << nl +// << "cachedTgtWeightsSum_.size():" << cachedTgtWeightsSum_.size() << nl; + + auto wsum = [&](List& res, const label i){ + weightedSum + ( + lowWeightCorrection_, + (interpolateToSource ? cachedSrcAddress_[i] : cachedTgtAddress_[i]), + (interpolateToSource ? cachedSrcWeights_[i] : cachedTgtWeights_[i]), + (interpolateToSource ? scalarField(cachedSrcWeightsSum_[i]) : scalarField(cachedTgtWeightsSum_[i])), + fld, + multiplyWeightedOp>(plusEqOp()), + res, + defaultValues + ); + }; + + if (cachedIndex0_ != -1 && cachedIndex1_ == -1) + { + wsum(result, cachedIndex0_); + } + else if (cachedIndex0_ == -1 && cachedIndex1_ != -1) + { + wsum(result, cachedIndex1_); + } + else if (cachedIndex0_ != -1 && cachedIndex1_ != -1) + { + List r0(result); + wsum(r0, cachedIndex0_); + List r1(result); + wsum(r1, cachedIndex1_); + result = (r1 - r0)*cachedWeight_ + r0; + } + else + { + // Both -1 => equates to non-caching + weightedSum + ( + lowWeightCorrection_, + (interpolateToSource ? srcAddress_ : tgtAddress_), + (interpolateToSource ? srcWeights_ : tgtWeights_), + (interpolateToSource ? srcWeightsSum_ : tgtWeightsSum_), + fld, + multiplyWeightedOp>(plusEqOp()), + result, + defaultValues + ); + } } @@ -114,59 +166,164 @@ void Foam::AMIInterpolation::interpolateToTarget { addProfiling(ami, "AMIInterpolation::interpolateToTarget"); - if (fld.size() != srcAddress_.size()) - { - FatalErrorInFunction - << "Supplied field size is not equal to source patch size" << nl - << " source patch = " << srcAddress_.size() << nl - << " target patch = " << tgtAddress_.size() << nl - << " supplied field = " << fld.size() - << abort(FatalError); - } - else if - ( - (lowWeightCorrection_ > 0) - && (defaultValues.size() != tgtAddress_.size()) + auto checkSizes = [&]( + const UList& fld, + const labelListList& srcAddr, + const labelListList& tgtAddr, + const UList& defVals ) { - FatalErrorInFunction - << "Employing default values when sum of weights falls below " - << lowWeightCorrection_ - << " but supplied default field size is not equal to target " - << "patch size" << nl - << " default values = " << defaultValues.size() << nl - << " target patch = " << tgtAddress_.size() << nl - << abort(FatalError); - } - - result.setSize(tgtAddress_.size()); - List work; - - if (distributed() && srcMapPtr_) - { - const mapDistribute& map = srcMapPtr_(); - - if (map.comm() == -1) + if (fld.size() != srcAddr.size()) { - return; + FatalErrorInFunction + << "Supplied field size is not equal to source patch size" << nl + << " source patch = " << srcAddr.size() << nl + << " target patch = " << tgtAddr.size() << nl + << " supplied field = " << fld.size() + << abort(FatalError); + } + else if + ( + (lowWeightCorrection_ > 0) && (defVals.size() != tgtAddr.size()) + ) + { + FatalErrorInFunction + << "Employing default values when sum of weights falls below " + << lowWeightCorrection_ + << " but number of default values is not equal to target " + << "patch size" << nl + << " default values = " << defVals.size() << nl + << " target patch = " << tgtAddr.size() << nl + << abort(FatalError); + } + }; + + List result0; + if (cachedIndex0_ != -1) + { + result0 = result; + + const auto& srcAddr = cachedSrcAddress_[cachedIndex0_]; + const auto& tgtAddr = cachedTgtAddress_[cachedIndex0_]; + + checkSizes(fld, srcAddr, tgtAddr, defaultValues); + + result0.setSize(tgtAddr.size()); + List work; + + if (distributed() && cachedSrcMapPtr_[cachedIndex0_]) + { + const mapDistribute& map = cachedSrcMapPtr_[cachedIndex0_]; + + if (map.comm() == -1) + { + return; + } + + work.resize_nocopy(map.constructSize()); + SubList(work, fld.size()) = fld; // deep copy + map.distribute(work); } - work.resize_nocopy(map.constructSize()); - SubList(work, fld.size()) = fld; // deep copy - map.distribute(work); + weightedSum + ( + lowWeightCorrection_, + tgtAddr, + cachedTgtWeights_[cachedIndex0_], + scalarField(cachedTgtWeightsSum_[cachedIndex0_]), + (distributed() ? work : fld), + cop, + result0, + defaultValues + ); } - weightedSum - ( - lowWeightCorrection_, - tgtAddress_, - tgtWeights_, - tgtWeightsSum_, - (distributed() ? work : fld), - cop, - result, - defaultValues - ); + List result1; + if (cachedIndex1_ != -1) + { + result1 = result; + + const auto& srcAddr = cachedSrcAddress_[cachedIndex1_]; + const auto& tgtAddr = cachedTgtAddress_[cachedIndex1_]; + + checkSizes(fld, srcAddr, tgtAddr, defaultValues); + + result1.setSize(tgtAddr.size()); + List work; + + if (distributed() && cachedSrcMapPtr_[cachedIndex1_]) + { + const mapDistribute& map = cachedSrcMapPtr_[cachedIndex1_]; + + if (map.comm() == -1) + { + return; + } + + work.resize_nocopy(map.constructSize()); + SubList(work, fld.size()) = fld; // deep copy + map.distribute(work); + } + + weightedSum + ( + lowWeightCorrection_, + tgtAddr, + cachedTgtWeights_[cachedIndex1_], + scalarField(cachedTgtWeightsSum_[cachedIndex1_]), + (distributed() ? work : fld), + cop, + result1, + defaultValues + ); + } + + if (cachedIndex0_ != -1 && cachedIndex1_ == -1) + { + result = result0; + } + else if (cachedIndex0_ == -1 && cachedIndex1_ != -1) + { + result = result1; + } + else if (cachedIndex0_ != -1 && cachedIndex1_ != -1) + { + result = (result1 - result0)*cachedWeight_ + result0; + } + else + { + // No cache - evaluate the AMI + checkSizes(fld, srcAddress_, tgtAddress_, defaultValues); + + result.setSize(tgtAddress_.size()); + List work; + + if (distributed() && srcMapPtr_) + { + const mapDistribute& map = srcMapPtr_(); + + if (map.comm() == -1) + { + return; + } + + work.resize_nocopy(map.constructSize()); + SubList(work, fld.size()) = fld; // deep copy + map.distribute(work); + } + + weightedSum + ( + lowWeightCorrection_, + tgtAddress_, + tgtWeights_, + tgtWeightsSum_, + (distributed() ? work : fld), + cop, + result, + defaultValues + ); + } } @@ -181,59 +338,164 @@ void Foam::AMIInterpolation::interpolateToSource { addProfiling(ami, "AMIInterpolation::interpolateToSource"); - if (fld.size() != tgtAddress_.size()) - { - FatalErrorInFunction - << "Supplied field size is not equal to target patch size" << nl - << " source patch = " << srcAddress_.size() << nl - << " target patch = " << tgtAddress_.size() << nl - << " supplied field = " << fld.size() - << abort(FatalError); - } - else if - ( - (lowWeightCorrection_ > 0) - && (defaultValues.size() != srcAddress_.size()) + auto checkSizes = [&]( + const UList& fld, + const labelListList& srcAddr, + const labelListList& tgtAddr, + const UList& defVals ) { - FatalErrorInFunction - << "Employing default values when sum of weights falls below " - << lowWeightCorrection_ - << " but number of default values is not equal to source " - << "patch size" << nl - << " default values = " << defaultValues.size() << nl - << " source patch = " << srcAddress_.size() << nl - << abort(FatalError); - } - - result.setSize(srcAddress_.size()); - List work; - - if (distributed() && tgtMapPtr_) - { - const mapDistribute& map = tgtMapPtr_(); - - if (map.comm() == -1) + if (fld.size() != tgtAddr.size()) { - return; + FatalErrorInFunction + << "Supplied field size is not equal to target patch size" << nl + << " source patch = " << srcAddr.size() << nl + << " target patch = " << tgtAddr.size() << nl + << " supplied field = " << fld.size() + << abort(FatalError); + } + else if + ( + (lowWeightCorrection_ > 0) && (defVals.size() != srcAddr.size()) + ) + { + FatalErrorInFunction + << "Employing default values when sum of weights falls below " + << lowWeightCorrection_ + << " but number of default values is not equal to source " + << "patch size" << nl + << " default values = " << defVals.size() << nl + << " source patch = " << srcAddr.size() << nl + << abort(FatalError); + } + }; + + List result0; + if (cachedIndex0_ != -1) + { + result0 = result; + + const auto& srcAddr = cachedSrcAddress_[cachedIndex0_]; + const auto& tgtAddr = cachedTgtAddress_[cachedIndex0_]; + + checkSizes(fld, srcAddr, tgtAddr, defaultValues); + + result0.setSize(srcAddr.size()); + List work; + + if (distributed() && cachedTgtMapPtr_[cachedIndex0_]) + { + const mapDistribute& map = cachedTgtMapPtr_[cachedIndex0_]; + + if (map.comm() == -1) + { + return; + } + + work.resize_nocopy(map.constructSize()); + SubList(work, fld.size()) = fld; // deep copy + map.distribute(work); } - work.resize_nocopy(map.constructSize()); - SubList(work, fld.size()) = fld; // deep copy - map.distribute(work); + weightedSum + ( + lowWeightCorrection_, + srcAddr, + cachedSrcWeights_[cachedIndex0_], + scalarField(cachedSrcWeightsSum_[cachedIndex0_]), + (distributed() ? work : fld), + cop, + result0, + defaultValues + ); } - weightedSum - ( - lowWeightCorrection_, - srcAddress_, - srcWeights_, - srcWeightsSum_, - (distributed() ? work : fld), - cop, - result, - defaultValues - ); + List result1; + if (cachedIndex1_ != -1) + { + result1 = result; + + const auto& srcAddr = cachedSrcAddress_[cachedIndex1_]; + const auto& tgtAddr = cachedTgtAddress_[cachedIndex1_]; + + checkSizes(fld, srcAddr, tgtAddr, defaultValues); + + result0.setSize(srcAddr.size()); + List work; + + if (distributed() && cachedTgtMapPtr_[cachedIndex1_]) + { + const mapDistribute& map = cachedTgtMapPtr_[cachedIndex1_]; + + if (map.comm() == -1) + { + return; + } + + work.resize_nocopy(map.constructSize()); + SubList(work, fld.size()) = fld; // deep copy + map.distribute(work); + } + + weightedSum + ( + lowWeightCorrection_, + srcAddr, + cachedSrcWeights_[cachedIndex1_], + scalarField(cachedSrcWeightsSum_[cachedIndex1_]), + (distributed() ? work : fld), + cop, + result1, + defaultValues + ); + } + + if (cachedIndex0_ != -1 && cachedIndex1_ == -1) + { + result = result0; + } + else if (cachedIndex0_ == -1 && cachedIndex1_ != -1) + { + result = result1; + } + else if (cachedIndex0_ != -1 && cachedIndex1_ != -1) + { + result = (result1 - result0)*cachedWeight_ + result0; + } + else + { + // No cache - evaluate the AMI + checkSizes(fld, srcAddress_, tgtAddress_, defaultValues); + + result.setSize(srcAddress_.size()); + List work; + + if (distributed() && tgtMapPtr_) + { + const mapDistribute& map = tgtMapPtr_(); + + if (map.comm() == -1) + { + return; + } + + work.resize_nocopy(map.constructSize()); + SubList(work, fld.size()) = fld; // deep copy + map.distribute(work); + } + + weightedSum + ( + lowWeightCorrection_, + srcAddress_, + srcWeights_, + srcWeightsSum_, + (distributed() ? work : fld), + cop, + result, + defaultValues + ); + } } diff --git a/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C index 62a18bbc54..886d158d89 100644 --- a/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C +++ b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C @@ -381,6 +381,43 @@ void Foam::cyclicAMIPolyPatch::resetAMI(const UList& points) const return; } + point refPt = point::max; + + bool restoredFromCache = false; + if (AMIPtr_->cacheActive()) + { + if (UPstream::parRun()) + { + label refProci = -1; + if (size() > 0) + { + refProci = UPstream::myProcNo(); + } + reduce(refProci, maxOp