Compare commits

..

1 Commits

Author SHA1 Message Date
dc8dba2286 BUG: snappyHexMesh: revert inside/outside test for triSurface. See #3349
Not yet working for distributedTriSurfaceMesh
2025-06-04 16:38:40 +01:00
164 changed files with 1485 additions and 2900 deletions

View File

@ -13,14 +13,7 @@ volVectorField U
); );
// Initialise the velocity internal field to zero // Initialise the velocity internal field to zero
// Note: explicitly bypass evaluation of contraint patch overrides U = dimensionedVector(U.dimensions(), Zero);
// (e.g. swirlFanVelocity might lookup phi,rho)
//U = dimensionedVector(U.dimensions(), Zero);
{
const dimensionedVector dt(U.dimensions(), Zero);
U.internalFieldRef() = dt;
U.boundaryFieldRef() = dt.value();
}
surfaceScalarField phi surfaceScalarField phi
( (

View File

@ -51,7 +51,6 @@ See also
#include "IndirectList.H" #include "IndirectList.H"
#include "SubList.H" #include "SubList.H"
#include "SliceList.H" #include "SliceList.H"
#include "SubField.H"
#include "ListPolicy.H" #include "ListPolicy.H"
#include <list> #include <list>
@ -204,6 +203,16 @@ int main(int argc, char *argv[])
Info<<" " << *iter; Info<<" " << *iter;
} }
Info<< nl; Info<< nl;
Info<< "data:" << Foam::name(ident.cdata())
<< " size:" << ident.size() << nl;
Info<< "resize_unsafe(10)" << nl;
ident.resize_unsafe(10);
Info<< "data:" << Foam::name(ident.cdata())
<< " size:" << ident.size() << nl;
} }
if (false) if (false)
@ -272,33 +281,6 @@ int main(int argc, char *argv[])
}; };
Info<< "list4: " << list4 << endl; Info<< "list4: " << list4 << endl;
{
List<scalar> list4Mag = ListOps::create<scalar>
(
list4,
[](const auto& a){ return a.mag(); }
);
const auto equalMag = [](const auto& a, const auto& b)
{
return (Foam::mag(a) == Foam::mag(b));
};
Info<< "list4 (mag): " << list4Mag << endl;
bool same = ListOps::equal(list4, list4Mag, equalMag);
Info<< "mag(list4) == list4(mag): " << same << nl;
SubField<scalar>(list4Mag) *= -1;
same = ListOps::equal(list4, list4Mag, equalMag);
Info<< "mag(list4) == list4(mag): " << same << nl;
SubField<scalar>(list4Mag) *= 1.1;
same = ListOps::equal(list4, list4Mag, equalMag);
Info<< "mag(list4) == list4(mag): " << same << nl;
}
List<vector> list5 List<vector> list5
{ {
{5, 3, 1}, {5, 3, 1},

View File

@ -1,3 +1,3 @@
Test-parallel-broadcast.cxx Test-parallel-broadcast.C
EXE = $(FOAM_USER_APPBIN)/Test-parallel-broadcast EXE = $(FOAM_USER_APPBIN)/Test-parallel-broadcast

View File

@ -1,3 +1,3 @@
Test-parallel-chunks.cxx Test-parallel-chunks.C
EXE = $(FOAM_USER_APPBIN)/Test-parallel-chunks EXE = $(FOAM_USER_APPBIN)/Test-parallel-chunks

View File

@ -1,3 +1,3 @@
Test-parallel-comm0.cxx Test-parallel-comm0.C
EXE = $(FOAM_USER_APPBIN)/Test-parallel-comm0 EXE = $(FOAM_USER_APPBIN)/Test-parallel-comm0

View File

@ -1,3 +1,3 @@
Test-parallel-comm1.cxx Test-parallel-comm1.C
EXE = $(FOAM_USER_APPBIN)/Test-parallel-comm1 EXE = $(FOAM_USER_APPBIN)/Test-parallel-comm1

View File

@ -1,3 +1,3 @@
Test-parallel-comm3a.cxx Test-parallel-comm3a.C
EXE = $(FOAM_USER_APPBIN)/Test-parallel-comm3a EXE = $(FOAM_USER_APPBIN)/Test-parallel-comm3a

View File

@ -1,3 +1,3 @@
Test-parallel-comm3b.cxx Test-parallel-comm3b.C
EXE = $(FOAM_USER_APPBIN)/Test-parallel-comm3b EXE = $(FOAM_USER_APPBIN)/Test-parallel-comm3b

View File

@ -1,3 +1,3 @@
Test-parallel-external-init.cxx Test-parallel-external-init.C
EXE = $(FOAM_USER_APPBIN)/Test-parallel-external-init EXE = $(FOAM_USER_APPBIN)/Test-parallel-external-init

View File

@ -1,3 +1,3 @@
Test-parallel-nbx2.cxx Test-parallel-nbx2.C
EXE = $(FOAM_USER_APPBIN)/Test-parallel-nbx2 EXE = $(FOAM_USER_APPBIN)/Test-parallel-nbx2

View File

@ -131,6 +131,7 @@ int main(int argc, char *argv[])
if (probed.second > 0) if (probed.second > 0)
{ {
// Message found and had size: receive it // Message found and had size: receive it
const label proci(probed.first); const label proci(probed.first);
const label count(probed.second); const label count(probed.second);
@ -163,7 +164,8 @@ int main(int argc, char *argv[])
scalarField fld(is); scalarField fld(is);
Info<< "from [" << proci << "] : " << flatOutput(fld) << endl; Info<< "from [" << probed.first
<< "] : " << flatOutput(fld) << endl;
} }
} }

View File

@ -1,3 +1,3 @@
Test-parallel-nonBlocking.cxx Test-parallel-nonBlocking.C
EXE = $(FOAM_USER_APPBIN)/Test-parallel-nonBlocking EXE = $(FOAM_USER_APPBIN)/Test-parallel-nonBlocking

View File

@ -1,3 +1,3 @@
Test-parallel-waitSome.cxx Test-parallel-waitSome.C
EXE = $(FOAM_USER_APPBIN)/Test-parallel-waitSome EXE = $(FOAM_USER_APPBIN)/Test-parallel-waitSome

View File

@ -1,7 +1,7 @@
/*--------------------------------*- C++ -*----------------------------------*\ /*--------------------------------*- C++ -*----------------------------------*\
| ========= | | | ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2506 | | \\ / O peration | Version: v2412 |
| \\ / A nd | Website: www.openfoam.com | | \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | | | \\/ M anipulation | |
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -26,7 +26,7 @@ stopAt writeNow;
endTime 4; endTime 4;
writeControl adjustable; writeControl adjustableRunTime;
writeInterval 0.1; writeInterval 0.1;

View File

@ -1,7 +1,7 @@
/*--------------------------------*- C++ -*----------------------------------*\ /*--------------------------------*- C++ -*----------------------------------*\
| ========= | | | ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2506 | | \\ / O peration | Version: v2412 |
| \\ / A nd | Website: www.openfoam.com | | \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | | | \\/ M anipulation | |
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -27,7 +27,7 @@ endTime 0.1;
deltaT 0.0001; deltaT 0.0001;
writeControl adjustable; writeControl adjustableRunTime;
writeInterval 0.01; writeInterval 0.01;

View File

@ -525,7 +525,6 @@ public:
} }
} }
}; };
class edgePointTransformOp class edgePointTransformOp
{ {
public: public:
@ -544,24 +543,25 @@ public:
points1[i] = fld[i].second(); points1[i] = fld[i].second();
} }
pointField points0New;
pointField points1New;
if (forward) if (forward)
{ {
vt.transformPositionList(points0); points0New = vt.transformPosition(points0);
vt.transformPositionList(points1); points1New = vt.transformPosition(points1);
} }
else else
{ {
vt.invTransformPositionList(points0); points0New = vt.invTransformPosition(points0);
vt.invTransformPositionList(points1); points1New = vt.invTransformPosition(points1);
} }
forAll(fld, i) forAll(fld, i)
{ {
fld[i] = PointPair(points0[i], points1[i]); fld[i] = PointPair(points0New[i], points1New[i]);
} }
} }
}; };
class edgePointFlipOp class edgePointFlipOp
{ {
public: public:
@ -572,7 +572,6 @@ public:
return newVal; return newVal;
} }
}; };
void testEdgeFlip2(const polyMesh& mesh, Random& rndGen) void testEdgeFlip2(const polyMesh& mesh, Random& rndGen)
{ {
Info<< nl << "Testing edge-wise (oriented) data synchronisation." << endl; Info<< nl << "Testing edge-wise (oriented) data synchronisation." << endl;
@ -760,11 +759,13 @@ class pointListOps
{ {
public: public:
void operator()(UList<point>& lhs, const UList<point>& rhs) const void operator()(pointList& lhs, const pointList& rhs) const
{ {
forAll(lhs, i) forAll(lhs, i)
{ {
maxMagSqrEqOp<vector>()(lhs[i], rhs[i]); point& l = lhs[i];
const point& r = rhs[i];
maxMagSqrEqOp<vector>()(l, r);
} }
} }
@ -772,31 +773,38 @@ public:
( (
const vectorTensorTransform& vt, const vectorTensorTransform& vt,
const bool forward, const bool forward,
UList<pointList>& fld List<pointList>& fld
) const ) const
{ {
if (forward) if (forward)
{ {
for (auto& pts : fld) for (auto& elems : fld)
{ {
vt.transformPositionList(pts); for (auto& elem : elems)
{
elem = vt.transformPosition(elem);
}
} }
} }
else else
{ {
for (auto& pts : fld) for (auto& elems : fld)
{ {
vt.invTransformPositionList(pts); for (auto& elem : elems)
{
elem = vt.invTransformPosition(elem);
}
} }
} }
} }
//- Transform patch-based field //- Transform patch-based field
void operator()(const coupledPolyPatch& cpp, UList<pointList>& fld) const void operator()(const coupledPolyPatch& cpp, List<pointList>& fld) const
{ {
forAll(fld, facei) forAll(fld, facei)
{ {
for (auto& pt : fld[facei]) pointList& pts = fld[facei];
for (auto& pt : pts)
{ {
cpp.transformPosition(pt, facei); cpp.transformPosition(pt, facei);
} }

View File

@ -39,7 +39,8 @@ Foam::label Foam::findOppositeWedge
&& isA<wedgePolyPatch>(patches[patchi]) && isA<wedgePolyPatch>(patches[patchi])
) )
{ {
const auto& pp = refCast<const wedgePolyPatch>(patches[patchi]); const wedgePolyPatch& pp =
refCast<const wedgePolyPatch>(patches[patchi]);
// Calculate (cos of) angle to wpp (not pp!) centre normal // Calculate (cos of) angle to wpp (not pp!) centre normal
scalar ppCosAngle = wpp.centreNormal() & pp.n(); scalar ppCosAngle = wpp.centreNormal() & pp.n();
@ -79,7 +80,8 @@ bool Foam::checkWedges
{ {
if (patches[patchi].size() && isA<wedgePolyPatch>(patches[patchi])) if (patches[patchi].size() && isA<wedgePolyPatch>(patches[patchi]))
{ {
const auto& pp = refCast<const wedgePolyPatch>(patches[patchi]); const wedgePolyPatch& pp =
refCast<const wedgePolyPatch>(patches[patchi]);
scalar wedgeAngle = acos(pp.cosAngle()); scalar wedgeAngle = acos(pp.cosAngle());
@ -103,7 +105,7 @@ bool Foam::checkWedges
return true; return true;
} }
const auto& opp = const wedgePolyPatch& opp =
refCast<const wedgePolyPatch>(patches[oppositePatchi]); refCast<const wedgePolyPatch>(patches[oppositePatchi]);
@ -273,27 +275,25 @@ namespace Foam
void operator() void operator()
( (
const coupledPolyPatch& cpp, const coupledPolyPatch& cpp,
UList<pointField>& pts List<pointField>& pts
) const ) const
{ {
// Each element of pts is all the points in the face. // Each element of pts is all the points in the face. Convert into
// Convert into lists of size cpp to transform. // lists of size cpp to transform.
List<pointField> newPts(pts.size()); List<pointField> newPts(pts.size());
forAll(pts, facei) forAll(pts, facei)
{ {
newPts[facei].resize(pts[facei].size()); newPts[facei].setSize(pts[facei].size());
} }
pointField ptsAtIndex(pts.size());
label index = 0; label index = 0;
while (true) while (true)
{ {
label n = 0; label n = 0;
// Extract for every face the i'th position // Extract for every face the i'th position
ptsAtIndex = Zero; pointField ptsAtIndex(pts.size(), Zero);
forAll(cpp, facei) forAll(cpp, facei)
{ {
const pointField& facePts = pts[facei]; const pointField& facePts = pts[facei];
@ -326,8 +326,7 @@ namespace Foam
index++; index++;
} }
// Transfer newPts -> pts pts.transfer(newPts);
std::move(newPts.begin(), newPts.end(), pts.begin());
} }
}; };
} }
@ -353,7 +352,10 @@ bool Foam::checkCoupledPoints
{ {
if (patches[patchi].coupled()) if (patches[patchi].coupled())
{ {
const auto& cpp = refCast<const coupledPolyPatch>(patches[patchi]); const coupledPolyPatch& cpp = refCast<const coupledPolyPatch>
(
patches[patchi]
);
forAll(cpp, i) forAll(cpp, i)
{ {
@ -385,7 +387,8 @@ bool Foam::checkCoupledPoints
{ {
if (patches[patchi].coupled()) if (patches[patchi].coupled())
{ {
const auto& cpp = refCast<const coupledPolyPatch>(patches[patchi]); const coupledPolyPatch& cpp =
refCast<const coupledPolyPatch>(patches[patchi]);
if (cpp.owner()) if (cpp.owner())
{ {
@ -1020,7 +1023,7 @@ Foam::label Foam::checkGeometry
{ {
if (isA<cyclicAMIPolyPatch>(pbm[patchi])) if (isA<cyclicAMIPolyPatch>(pbm[patchi]))
{ {
const auto& cpp = const cyclicAMIPolyPatch& cpp =
refCast<const cyclicAMIPolyPatch>(pbm[patchi]); refCast<const cyclicAMIPolyPatch>(pbm[patchi]);
if (cpp.owner()) if (cpp.owner())
@ -1055,7 +1058,7 @@ Foam::label Foam::checkGeometry
if (isA<cyclicACMIPolyPatch>(pbm[patchi])) if (isA<cyclicACMIPolyPatch>(pbm[patchi]))
{ {
const auto& pp = const cyclicACMIPolyPatch& pp =
refCast<const cyclicACMIPolyPatch>(pbm[patchi]); refCast<const cyclicACMIPolyPatch>(pbm[patchi]);
scalarField mergedMask; scalarField mergedMask;
@ -1105,9 +1108,8 @@ Foam::label Foam::checkGeometry
if (isA<cyclicACMIPolyPatch>(pbm[patchi])) if (isA<cyclicACMIPolyPatch>(pbm[patchi]))
{ {
const auto& pp = const cyclicACMIPolyPatch& pp =
refCast<const cyclicACMIPolyPatch>(pbm[patchi]); refCast<const cyclicACMIPolyPatch>(pbm[patchi]);
scalarField mergedMask; scalarField mergedMask;
globalFaces().gather globalFaces().gather
( (

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2021-2025 OpenCFD Ltd. Copyright (C) 2021-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM, distributed under GPL-3.0-or-later. This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
@ -44,10 +44,10 @@ forAll(meshes, regioni)
IOobjectOption::NO_REGISTER IOobjectOption::NO_REGISTER
); );
if (fieldSelector) if (fieldSelector && !fieldSelector().empty())
{ {
objects.filterObjects(fieldSelector); objects.filterObjects(fieldSelector());
faObjects.filterObjects(fieldSelector); faObjects.filterObjects(fieldSelector());
} }
// Remove "*_0" restart fields // Remove "*_0" restart fields

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2025 OpenCFD Ltd. Copyright (C) 2016-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -406,27 +406,34 @@ int main(int argc, char *argv[])
// Field selection/deselection // Field selection/deselection
wordRes includedFields, excludedFields; wordRes includedFields, excludedFields;
autoPtr<wordRes::filter> fieldSelector(nullptr);
const bool doConvertFields = !args.found("no-fields"); const bool doConvertFields = !args.found("no-fields");
if (doConvertFields) if (doConvertFields)
{ {
bool resetFilter = false;
if (args.readListIfPresent<wordRe>("fields", includedFields)) if (args.readListIfPresent<wordRe>("fields", includedFields))
{ {
resetFilter = true;
Info<< "Including fields " Info<< "Including fields "
<< flatOutput(includedFields) << nl << endl; << flatOutput(includedFields) << nl << endl;
} }
if (args.readListIfPresent<wordRe>("exclude-fields", excludedFields)) if (args.readListIfPresent<wordRe>("exclude-fields", excludedFields))
{ {
resetFilter = true;
Info<< "Excluding fields " Info<< "Excluding fields "
<< flatOutput(excludedFields) << nl << endl; << flatOutput(excludedFields) << nl << endl;
} }
if (resetFilter)
{
fieldSelector =
autoPtr<wordRes::filter>::New(includedFields, excludedFields);
}
} }
else else if (doConvertFields)
{ {
Info<< "Field conversion disabled with the '-no-fields' option" << nl; Info<< "Field conversion disabled with the '-no-fields' option" << nl;
} }
const wordRes::filter fieldSelector(includedFields, excludedFields);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
#include "createTime.H" #include "createTime.H"

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2018-2025 OpenCFD Ltd. Copyright (C) 2018-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM, distributed under GPL-3.0-or-later. This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
@ -136,7 +136,7 @@ Description
labelList patchIds; labelList patchIds;
if (doBoundary) if (doBoundary)
{ {
patchIds = patchSelector.indices(patches); patchIds = getSelectedPatches(patches, patchSelector);
} }
if (oneBoundary && patchIds.size()) if (oneBoundary && patchIds.size())

View File

@ -166,54 +166,56 @@ Note
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam labelList getSelectedPatches
(
const polyBoundaryMesh& patches,
const autoPtr<wordRes::filter>& patchSelector
)
{ {
labelList indices;
// Simple wrapper for polyBoundaryMesh::indices() with some additional logic if (patchSelector && !patchSelector().empty())
struct polyBoundaryPatchSelector
{
wordRes allow_;
wordRes deny_;
void clear()
{ {
allow_.clear(); // Name-based selection
deny_.clear(); indices =
(
stringListOps::findMatching
(
patches,
patchSelector(),
nameOp<polyPatch>()
)
);
}
else
{
indices = identity(patches.size());
} }
//- Forward to polyBoundaryMesh::indices() with additional handling. // Remove undesirable patches
// Prune emptyPolyPatch (always) and processorPolyPatch (in parallel)
labelList indices(const polyBoundaryMesh& pbm) const label count = 0;
for (const label patchi : indices)
{ {
labelList ids = pbm.indices(allow_, deny_); const polyPatch& pp = patches[patchi];
const bool excludeProcPatches = UPstream::parRun(); if (isType<emptyPolyPatch>(pp))
// Prune undesirable patches
label count = 0;
for (const label patchi : ids)
{ {
const auto& pp = pbm[patchi]; continue;
}
if (isType<emptyPolyPatch>(pp)) else if (UPstream::parRun() && bool(isA<processorPolyPatch>(pp)))
{ {
continue; break; // No processor patches for parallel output
}
else if (excludeProcPatches && bool(isA<processorPolyPatch>(pp)))
{
break; // No processor patches for parallel output
}
ids[count] = patchi;
++count;
} }
ids.resize(count); indices[count] = patchi;
return ids; ++count;
} }
};
} // End namespace Foam indices.resize(count);
return indices;
}
// //
@ -550,38 +552,45 @@ int main(int argc, char *argv[])
} }
// Patch selection/deselection // Patch selection/deselection
polyBoundaryPatchSelector patchSelector; wordRes includedPatches, excludedPatches;
autoPtr<wordRes::filter> patchSelector(nullptr);
if (doBoundary) if (doBoundary)
{ {
if bool resetFilter = false;
( if (args.readListIfPresent<wordRe>("patches", includedPatches))
auto& slot = patchSelector.allow_;
args.readListIfPresent<wordRe>("patches", slot)
)
{ {
Info<< "Including patches " << flatOutput(slot) << nl << endl; resetFilter = true;
Info<< "Including patches "
<< flatOutput(includedPatches) << nl << endl;
} }
if if (args.readListIfPresent<wordRe>("exclude-patches", excludedPatches))
(
auto& slot = patchSelector.deny_;
args.readListIfPresent<wordRe>("exclude-patches", slot)
)
{ {
Info<< "Excluding patches " << flatOutput(slot) << nl << endl; resetFilter = true;
Info<< "Excluding patches "
<< flatOutput(excludedPatches) << nl << endl;
}
if (resetFilter)
{
patchSelector =
autoPtr<wordRes::filter>::New(includedPatches, excludedPatches);
} }
} }
// Field selection/deselection // Field selection/deselection
wordRes includedFields, excludedFields; wordRes includedFields, excludedFields;
autoPtr<wordRes::filter> fieldSelector(nullptr);
bool doConvertFields = !args.found("no-fields"); bool doConvertFields = !args.found("no-fields");
if (doConvertFields) if (doConvertFields)
{ {
bool resetFilter = false;
if (args.readListIfPresent<wordRe>("fields", includedFields)) if (args.readListIfPresent<wordRe>("fields", includedFields))
{ {
Info<< "Including fields " Info<< "Including fields "
<< flatOutput(includedFields) << nl << endl; << flatOutput(includedFields) << nl << endl;
resetFilter = !includedFields.empty();
if (includedFields.empty()) if (includedFields.empty())
{ {
// Compat: Can be specified as empty (ie, no fields) // Compat: Can be specified as empty (ie, no fields)
@ -594,22 +603,22 @@ int main(int argc, char *argv[])
} }
if (args.readListIfPresent<wordRe>("exclude-fields", excludedFields)) if (args.readListIfPresent<wordRe>("exclude-fields", excludedFields))
{ {
resetFilter = true;
Info<< "Excluding fields " Info<< "Excluding fields "
<< flatOutput(excludedFields) << nl << endl; << flatOutput(excludedFields) << nl << endl;
} }
if (!doConvertFields) if (resetFilter && doConvertFields)
{ {
includedFields.clear(); fieldSelector =
excludedFields.clear(); autoPtr<wordRes::filter>::New(includedFields, excludedFields);
} }
} }
else else if (doConvertFields)
{ {
Info<< "Field conversion disabled with the '-no-fields' option" << nl; Info<< "Field conversion disabled with the '-no-fields' option" << nl;
} }
const wordRes::filter fieldSelector(includedFields, excludedFields);
// Non-mandatory // Non-mandatory
const wordRes selectedFaceZones(args.getList<wordRe>("faceZones", false)); const wordRes selectedFaceZones(args.getList<wordRe>("faceZones", false));
@ -790,10 +799,10 @@ int main(int argc, char *argv[])
IOobjectOption::NO_REGISTER IOobjectOption::NO_REGISTER
); );
if (fieldSelector) if (fieldSelector && !fieldSelector().empty())
{ {
objects.filterObjects(fieldSelector); objects.filterObjects(fieldSelector());
faObjects.filterObjects(fieldSelector); faObjects.filterObjects(fieldSelector());
} }
// Remove "*_0" restart fields // Remove "*_0" restart fields

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2025 OpenCFD Ltd. Copyright (C) 2017-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -155,39 +155,50 @@ void writeOBJ
} }
} }
// Simple wrapper for polyBoundaryMesh::indices() with some additional logic
// - prune emptyPolyPatch (always) and (maybe) processorPolyPatch
labelList getSelectedPatches labelList getSelectedPatches
( (
const polyBoundaryMesh& pbm, const polyBoundaryMesh& patches,
const wordRes& allow, const wordRes& allow,
const wordRes& deny, const wordRes& deny
const bool excludeProcPatches
) )
{ {
labelList ids = pbm.indices(allow, deny); // Name-based selection
labelList indices
(
stringListOps::findMatching
(
patches,
allow,
deny,
nameOp<polyPatch>()
)
);
// Remove undesirable patches // Remove undesirable patches
label count = 0; label count = 0;
for (const label patchi : ids) for (const label patchi : indices)
{ {
const polyPatch& pp = pbm[patchi]; const polyPatch& pp = patches[patchi];
if (isType<emptyPolyPatch>(pp)) if (isType<emptyPolyPatch>(pp))
{ {
continue; continue;
} }
else if (excludeProcPatches && bool(isA<processorPolyPatch>(pp))) else if (Pstream::parRun() && bool(isA<processorPolyPatch>(pp)))
{ {
break; // No processor patches for parallel output break; // No processor patches for parallel output
} }
ids[count] = patchi; indices[count] = patchi;
++count; ++count;
} }
ids.resize(count); indices.resize(count);
return ids;
return indices;
} }
@ -657,14 +668,11 @@ int main(int argc, char *argv[])
const labelList patchIds = const labelList patchIds =
( (
getSelectedPatches (includePatches.size() || excludePatches.size())
( ? getSelectedPatches(bMesh, includePatches, excludePatches)
bMesh, : includeProcPatches
includePatches, ? identity(bMesh.size())
excludePatches, : identity(bMesh.nNonProcessor())
// No processor patches? (parallel output or excluded)
(UPstream::parRun() || !includeProcPatches)
)
); );
labelList faceZoneIds; labelList faceZoneIds;

View File

@ -132,11 +132,6 @@ projectDir="$HOME/OpenFOAM/OpenFOAM-$WM_PROJECT_VERSION"
# projectDir="@PROJECT_DIR@" # projectDir="@PROJECT_DIR@"
: # Safety statement (if the user removed all fallback values) : # Safety statement (if the user removed all fallback values)
# [FOAM_MEMORY_POOL] - Optional memory management
# - overrides the 'memory_pool' etc/controlDict entry
# = "true | false | host [size=nn] [incr=nn]"
#export FOAM_MEMORY_POOL="host"
# [FOAM_SIGFPE] - Trap floating-point exceptions. # [FOAM_SIGFPE] - Trap floating-point exceptions.
# - overrides the 'trapFpe' controlDict entry # - overrides the 'trapFpe' controlDict entry
# = true | false # = true | false

View File

@ -221,9 +221,6 @@ OptimisationSwitches
// Other // Other
// ===== // =====
// Optional memory management (sizing in MB)
// memory_pool "host; size=1024; incr=5"
// Trap floating point exception. // Trap floating point exception.
// Can override with FOAM_SIGFPE env variable (true|false) // Can override with FOAM_SIGFPE env variable (true|false)
trapFpe 1; trapFpe 1;

View File

@ -134,11 +134,6 @@ set projectDir=`lsof +p $$ |& sed -ne 's#^[^/]*##;\@/'"$projectName"'[^/]*/etc/c
# Or optionally hard-coded (eg, with autoconfig) # Or optionally hard-coded (eg, with autoconfig)
# set projectDir="@PROJECT_DIR@" # set projectDir="@PROJECT_DIR@"
# [FOAM_MEMORY_POOL] - Optional memory management
# - overrides the 'memory_pool' etc/controlDict entry
# = "true | false | host [size=nn] [incr=nn]"
#setenv FOAM_MEMORY_POOL "host"
# [FOAM_SIGFPE] - Trap floating-point exceptions. # [FOAM_SIGFPE] - Trap floating-point exceptions.
# - overrides the 'trapFpe' controlDict entry # - overrides the 'trapFpe' controlDict entry
# = true | false # = true | false

View File

@ -3,8 +3,6 @@ MSwindows.C
cpuInfo/cpuInfo.C cpuInfo/cpuInfo.C
memInfo/memInfo.C memInfo/memInfo.C
memory/MemoryPool.cxx
signals/sigFpe.cxx signals/sigFpe.cxx
signals/sigInt.cxx signals/sigInt.cxx
signals/sigQuit.cxx signals/sigQuit.cxx

View File

@ -1,83 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "MemoryPool.H"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
// bool Foam::MemoryPool::create(const std::string& ctrl, bool verbose)
// {
// return false;
// }
bool Foam::MemoryPool::create(bool verbose)
{
// No banner information since it is currently never an option
return false;
}
void Foam::MemoryPool::destroy(bool verbose)
{}
bool Foam::MemoryPool::active() noexcept
{
return false;
}
bool Foam::MemoryPool::suspend() noexcept
{
return false;
}
void Foam::MemoryPool::resume() noexcept
{}
bool Foam::MemoryPool::is_pool(void* ptr)
{
return false;
}
void* Foam::MemoryPool::try_allocate(std::size_t nbytes)
{
return nullptr;
}
bool Foam::MemoryPool::try_deallocate(void* ptr)
{
return (!ptr);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -2,7 +2,6 @@
cd "${0%/*}" || exit # Run from this directory cd "${0%/*}" || exit # Run from this directory
targetType=libo # Preferred library type targetType=libo # Preferred library type
. ${WM_PROJECT_DIR:?}/wmake/scripts/AllwmakeParseArguments $* . ${WM_PROJECT_DIR:?}/wmake/scripts/AllwmakeParseArguments $*
. ${WM_PROJECT_DIR:?}/wmake/scripts/have_umpire
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# Hack for MacOS (with Gcc). # Hack for MacOS (with Gcc).
@ -60,47 +59,6 @@ then
export COMP_FLAGS="-DFOAM_USE_INOTIFY" export COMP_FLAGS="-DFOAM_USE_INOTIFY"
fi fi
#------------------------------------------------------------------------------
# Have -lumpire, but also -lcamp etc.
# Also need to follow the link order
get_umpire_libs()
{
if [ -d "${UMPIRE_LIB_DIR}" ]
then
set -- $(
# Expected link order
for name in umpire fmt camp
do
[ -f "$UMPIRE_LIB_DIR/lib${name}.a" ] && echo "-l$name"
done
)
echo "$@"
else
echo
fi
}
if have_umpire
then
libNames="$(get_umpire_libs)"
if [ -n "$libNames" ]
then
echo " found umpire -- enabling memory pool interface" 1>&2
echo " umpire libs: $libNames" 1>&2
COMP_FLAGS="$COMP_FLAGS -DFOAM_USE_UMPIRE -I${UMPIRE_INC_DIR}"
LINK_FLAGS="$LINK_FLAGS -L${UMPIRE_LIB_DIR} $libNames"
export COMP_FLAGS LINK_FLAGS
else
echo " expecting umpire, but did not resolve the libraries" 1>&2
fi
fi
#------------------------------------------------------------------------------
# Make object (non-shared by default) # Make object (non-shared by default)
# Never want/need openmp, especially for static objects # Never want/need openmp, especially for static objects
wmake -no-openmp $targetType wmake -no-openmp $targetType

View File

@ -4,8 +4,6 @@ cpuInfo/cpuInfo.C
cpuTime/cpuTimePosix.C cpuTime/cpuTimePosix.C
memInfo/memInfo.C memInfo/memInfo.C
memory/MemoryPool.cxx
signals/sigFpe.cxx signals/sigFpe.cxx
signals/sigSegv.cxx signals/sigSegv.cxx
signals/sigInt.cxx signals/sigInt.cxx

View File

@ -1,4 +1 @@
/* umpire uses old-style cast etc */ EXE_INC = $(COMP_FLAGS)
EXE_INC = $(COMP_FLAGS) $(c++LESSWARN)
LIBO_LIBS = $(LINK_FLAGS)

View File

@ -1,510 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "MemoryPool.H"
#include "debug.H"
#include "dictionary.H"
#include "sigFpe.H"
#include "OSspecific.H" // For getEnv
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
#ifdef FOAM_USE_UMPIRE
// #include <cerrno>
#include <cinttypes>
#include <tuple>
#include "umpire/Allocator.hpp"
#include "umpire/ResourceManager.hpp"
#include "umpire/strategy/AlignedAllocator.hpp"
#include "umpire/strategy/DynamicPoolList.hpp"
static bool disabled_(false);
static umpire::Allocator aligned_allocator;
static umpire::Allocator pooled_allocator;
static umpire::ResourceManager* manager_(nullptr);
static umpire::ResourceManager* suspended_(nullptr);
#endif
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
#ifdef FOAM_USE_UMPIRE
namespace
{
// Different supported allocation types
enum class Types { undefined, none, host, device, managed };
typedef std::tuple<Types, std::size_t, std::size_t> ctrlTuple;
// Extract key=INT, the key includes the '='
int getIntParameter(const std::string& key, const std::string& ctrl)
{
int val(0);
const auto pos = ctrl.find(key);
if (pos == std::string::npos)
{
return val;
}
const char* buf = (ctrl.data() + pos + key.size());
char *endptr = nullptr;
errno = 0;
auto parsed = std::strtoimax(buf, &endptr, 10);
if (errno || endptr == buf)
{
// Some type of error OR no conversion
}
else
{
val = int(parsed);
}
return val;
}
ctrlTuple getControlValues(const std::string& ctrl)
{
ctrlTuple result(Types::undefined, 0, 0);
bool checkParam = false;
// Also find things that look like Switch constants.
// Unfortunately need to do this manually since Switch::find()
// itself would not manage to parse something like "true; size=10"
if (ctrl.empty())
{
// Nothing => undefined
}
else if
(
std::string::npos != ctrl.find("false") // ctrl.contains("false")
|| std::string::npos != ctrl.find("off") // ctrl.contains("off")
|| std::string::npos != ctrl.find("no") // ctrl.contains("no")
|| std::string::npos != ctrl.find("none") // ctrl.contains("none")
)
{
std::get<0>(result) = Types::none;
}
else if
(
std::string::npos != ctrl.find("true") // ctrl.contains("true")
|| std::string::npos != ctrl.find("on") // ctrl.contains("on")
|| std::string::npos != ctrl.find("yes") // ctrl.contains("yes")
|| std::string::npos != ctrl.find("host") // ctrl.contains("host")
|| std::string::npos != ctrl.find("system") // ctrl.contains("system")
)
{
std::get<0>(result) = Types::host;
checkParam = true;
}
// These need more testing
else if
(
std::string::npos != ctrl.find("device") // ctrl.contains("device")
)
{
std::get<0>(result) = Types::device;
checkParam = true;
}
else if
(
std::string::npos != ctrl.find("managed") // ctrl.contains("managed")
)
{
std::get<0>(result) = Types::managed;
checkParam = true;
}
if (checkParam)
{
std::get<1>(result) = getIntParameter("size=", ctrl);
std::get<2>(result) = getIntParameter("incr=", ctrl);
}
return result;
}
bool create_from(const ctrlTuple& controls, bool verbose)
{
using namespace Foam;
if (manager_ || suspended_)
{
// Already created
return true;
}
// Type, initial size, increment
auto [which, size, incr] = controls;
// std::cerr
// << "which=" << int(which)
// << ", size=" << int(size)
// << ", incr=" << int(incr) << '\n';
constexpr size_t MegaByte(1024*1024);
switch (which)
{
case Types::undefined :
{
if (verbose)
{
Info<< "memory pool : unused" << nl;
}
break;
}
case Types::none :
{
if (verbose)
{
Info<< "memory pool : disabled" << nl;
}
break;
}
case Types::host :
{
// Default sizing parameters
if (!size) size = 1024;
if (!incr) incr = 5;
auto& rm = umpire::ResourceManager::getInstance();
manager_ = &rm;
aligned_allocator =
rm.makeAllocator<umpire::strategy::AlignedAllocator>
(
"aligned_allocator",
rm.getAllocator("HOST"),
// alignment
256
);
pooled_allocator =
rm.makeAllocator<umpire::strategy::DynamicPoolList>
(
"openfoam_HOST_pool",
aligned_allocator,
// initial block allocation size
(size*MegaByte),
// incremental block allocation size
(incr*MegaByte)
);
if (verbose)
{
Info<< "memory pool : host (size="
<< int(size) << "MB, incr="
<< int(incr) << "MB)\n";
}
break;
}
case Types::device :
{
auto& rm = umpire::ResourceManager::getInstance();
manager_ = &rm;
aligned_allocator = rm.getAllocator("DEVICE");
pooled_allocator =
rm.makeAllocator<umpire::strategy::DynamicPoolList>
(
"openfoam_DEVICE_pool",
aligned_allocator
);
if (verbose)
{
Info<< "memory pool : device" << nl;
}
break;
}
case Types::managed :
{
// Default sizing parameters
if (!size) size = 10*1024;
if (!incr) incr = 10;
auto& rm = umpire::ResourceManager::getInstance();
manager_ = &rm;
aligned_allocator = rm.getAllocator("UM");
pooled_allocator =
rm.makeAllocator<umpire::strategy::DynamicPoolList>
(
"openfoam_UM_pool",
aligned_allocator,
// initial block allocation size
(size*MegaByte),
// incremental block allocation size
(incr*MegaByte)
);
if (verbose)
{
Info<< "memory pool : managed (size="
<< int(size) << "MB, incr="
<< int(incr) << "MB)\n";
}
break;
}
}
return (which != Types::undefined && which != Types::none);
}
} // End anonymous namespace
#endif // FOAM_USE_UMPIRE
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
// bool Foam::MemoryPool::create(const std::string& ctrl, bool verbose)
// {
// #ifdef FOAM_USE_UMPIRE
// if (manager_ || suspended_)
// {
// // Already created
// return true;
// }
//
// auto controls = getControlValues(ctrl);
//
// return create_from(controls, verbose);
// #else
// return false;
// #endif
// }
bool Foam::MemoryPool::create(bool verbose)
{
#ifdef FOAM_USE_UMPIRE
if (disabled_)
{
// Disallowed
return false;
}
else if (manager_ || suspended_)
{
// Already created
return true;
}
// First check environment
auto controls = getControlValues(Foam::getEnv("FOAM_MEMORY_POOL"));
if (std::get<0>(controls) == Types::none)
{
// Disabled from environment - has highest priority
disabled_ = true;
}
// Currently no easy way to handle <system>/controlDict...
// Fallback from etc/controlDict
if (std::get<0>(controls) == Types::undefined)
{
// From central etc/controlDict
const auto& dict = Foam::debug::optimisationSwitches();
if (auto* eptr = dict.findStream("memory_pool", keyType::LITERAL))
{
const token& firstToken = eptr->front();
if (firstToken.isStringType())
{
controls = getControlValues(firstToken.stringToken());
}
}
}
return create_from(controls, verbose);
#else
if (verbose)
{
Info<< "memory pool : not available" << nl;
}
return false;
#endif
}
void Foam::MemoryPool::destroy(bool verbose)
{
// Nothing currently needed but could add in something like this:
// if (manager_ || suspended_)
// {
// pooled_allocator.release();
// }
// However, need to find the proper sequence within
// Foam::exit() or UPstream::exit() ...
}
bool Foam::MemoryPool::active() noexcept
{
#ifdef FOAM_USE_UMPIRE
return bool(manager_);
#else
return false;
#endif
}
bool Foam::MemoryPool::suspend() noexcept
{
#ifdef FOAM_USE_UMPIRE
bool status(suspended_);
if (manager_) // <- and (!suspended_)
{
std::swap(manager_, suspended_);
}
return status;
#else
return false;
#endif
}
void Foam::MemoryPool::resume() noexcept
{
#ifdef FOAM_USE_UMPIRE
if (suspended_) // <- and (!manager_)
{
std::swap(manager_, suspended_);
}
#endif
}
bool Foam::MemoryPool::is_pool(void* ptr)
{
#ifdef FOAM_USE_UMPIRE
if (ptr)
{
if (manager_)
{
return manager_->hasAllocator(ptr);
}
else if (suspended_)
{
return suspended_->hasAllocator(ptr);
}
}
#endif
return false;
}
void* Foam::MemoryPool::try_allocate(std::size_t nbytes)
{
void* ptr = nullptr;
#ifdef FOAM_USE_UMPIRE
if (manager_)
{
ptr = pooled_allocator.allocate(nbytes);
// std::cerr<< "allocate(" << int(nbytes) << ")\n";
// Optionally fill with NaN (depends on current flags)
Foam::sigFpe::fillNan_if(ptr, nbytes);
if (!ptr)
{
// Pout<< "umpire failed to allocate memory\n";
}
}
#endif
return ptr;
}
bool Foam::MemoryPool::try_deallocate(void* ptr)
{
#ifdef FOAM_USE_UMPIRE
if (ptr)
{
if (manager_)
{
if (manager_->hasAllocator(ptr)) // <- ie, is_pool()
{
// std::cerr<< "deallocate()\n";
manager_->deallocate(ptr);
return true;
}
}
else if (suspended_)
{
// Deallocate even if nominally suspended
if (suspended_->hasAllocator(ptr)) // <- ie, is_pool()
{
// std::cerr<< "deallocate()\n";
suspended_->deallocate(ptr);
return true;
}
}
}
#endif
return (!ptr);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -203,7 +203,7 @@ public:
//- Change the value for the list capacity directly (ADVANCED, UNSAFE) //- Change the value for the list capacity directly (ADVANCED, UNSAFE)
//- Does not perform any memory management or resizing. //- Does not perform any memory management or resizing.
void setCapacity_unsafe(label len) noexcept { capacity_ = len; } void setCapacity_unsafe(const label len) noexcept { capacity_ = len; }
//- Reserve allocation space for at least this size, allocating new //- Reserve allocation space for at least this size, allocating new
//- space if required and \em retaining old content. //- space if required and \em retaining old content.
@ -251,6 +251,11 @@ public:
//- Shrink the allocated space to the number of elements used. //- Shrink the allocated space to the number of elements used.
inline void shrink_to_fit(); inline void shrink_to_fit();
//- Shrink the internal bookkeeping of the allocated space to the
//- number of addressed elements without affecting allocation.
// \note when empty() it will delete any allocated memory.
inline void shrink_unsafe();
// Edit // Edit

View File

@ -68,9 +68,7 @@ inline void Foam::DynamicList<T, SizeMin>::doCapacity
// Addressable length, possibly truncated by new capacity // Addressable length, possibly truncated by new capacity
const label currLen = Foam::min(List<T>::size(), newCapacity); const label currLen = Foam::min(List<T>::size(), newCapacity);
// Consistent allocated sizing
List<T>::setAddressableSize(capacity_); List<T>::setAddressableSize(capacity_);
if (nocopy) if (nocopy)
{ {
List<T>::resize_nocopy(newCapacity); List<T>::resize_nocopy(newCapacity);
@ -97,9 +95,6 @@ inline void Foam::DynamicList<T, SizeMin>::doReserve
// Preserve addressed size // Preserve addressed size
const label currLen = List<T>::size(); const label currLen = List<T>::size();
// Consistent allocated sizing
List<T>::setAddressableSize(capacity_);
// Increase capacity (eg, doubling) // Increase capacity (eg, doubling)
capacity_ = capacity_ =
Foam::ListPolicy::reserve_size<SizeMin, 2>(len, capacity_); Foam::ListPolicy::reserve_size<SizeMin, 2>(len, capacity_);
@ -110,10 +105,8 @@ inline void Foam::DynamicList<T, SizeMin>::doReserve
} }
else else
{ {
List<T>::resize_copy(currLen, capacity_); List<T>::resize(capacity_);
} }
capacity_ = List<T>::size();
List<T>::setAddressableSize(currLen); List<T>::setAddressableSize(currLen);
} }
} }
@ -278,7 +271,7 @@ inline Foam::DynamicList<T, SizeMin>::DynamicList
List<T>(std::move(static_cast<List<T>&>(list))), List<T>(std::move(static_cast<List<T>&>(list))),
capacity_(list.capacity()) capacity_(list.capacity())
{ {
list.setCapacity_unsafe(0); // All contents moved list.setCapacity_unsafe(0); // Same as shrink_unsafe() but noexcept
} }
@ -292,7 +285,7 @@ inline Foam::DynamicList<T, SizeMin>::DynamicList
List<T>(std::move(static_cast<List<T>&>(list))), List<T>(std::move(static_cast<List<T>&>(list))),
capacity_(list.capacity()) capacity_(list.capacity())
{ {
list.setCapacity_unsafe(0); // All contents moved list.setCapacity_unsafe(0); // Same as shrink_unsafe() but noexcept
} }
@ -368,15 +361,8 @@ inline void Foam::DynamicList<T, SizeMin>::reserve_exact
// Preserve addressed size // Preserve addressed size
const label currLen = List<T>::size(); const label currLen = List<T>::size();
// Consistent allocated sizing capacity_ = len;
List<T>::setAddressableSize(capacity_); List<T>::resize(capacity_);
// if (!nocopy)
{
List<T>::resize_copy(currLen, len);
}
capacity_ = List<T>::size();
List<T>::setAddressableSize(currLen); List<T>::setAddressableSize(currLen);
} }
} }
@ -463,6 +449,18 @@ inline void Foam::DynamicList<T, SizeMin>::shrink_to_fit()
} }
template<class T, int SizeMin>
inline void Foam::DynamicList<T, SizeMin>::shrink_unsafe()
{
if (List<T>::empty())
{
// Delete storage if empty
List<T>::clear();
}
capacity_ = List<T>::size();
}
template<class T, int SizeMin> template<class T, int SizeMin>
inline void inline void
Foam::DynamicList<T, SizeMin>::swap(List<T>& list) Foam::DynamicList<T, SizeMin>::swap(List<T>& list)

View File

@ -236,6 +236,13 @@ public:
// Otherwise the contents will be uninitialized. // Otherwise the contents will be uninitialized.
inline void resize_nocopy(const label len); inline void resize_nocopy(const label len);
//- Change the addressed list size directly without affecting
//- any memory management (advanced usage).
//
// It is left to the caller to avoid \em unsafe lengthening beyond
// the allocated memory region.
inline void resize_unsafe(const label len) noexcept;
//- Alias for resize() //- Alias for resize()
void setSize(const label n) { this->resize(n); } void setSize(const label n) { this->resize(n); }

View File

@ -178,6 +178,13 @@ inline void Foam::List<T>::resize_nocopy(const label len)
} }
template<class T>
inline void Foam::List<T>::resize_unsafe(const label len) noexcept
{
UList<T>::setAddressableSize(len);
}
template<class T> template<class T>
inline T& Foam::List<T>::newElmt(const label i) inline T& Foam::List<T>::newElmt(const label i)
{ {

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2018-2025 OpenCFD Ltd. Copyright (C) 2018-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -28,6 +28,8 @@ License
#include "ListOps.H" #include "ListOps.H"
#include "CompactListList.H" #include "CompactListList.H"
#include "HashSet.H"
#include <numeric>
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
@ -113,8 +115,7 @@ Foam::Map<Foam::label> Foam::invertToMap(const labelUList& values)
{ {
const label len = values.size(); const label len = values.size();
Map<label> inverse; Map<label> inverse(2*len);
inverse.reserve(len);
for (label i = 0 ; i < len; ++i) for (label i = 0 ; i < len; ++i)
{ {
@ -279,14 +280,13 @@ void Foam::inplaceReorder
void Foam::ListOps::unionEqOp::operator() void Foam::ListOps::unionEqOp::operator()
( (
labelList& x, labelList& x,
const labelUList& y const labelList& y
) const ) const
{ {
if (y.size()) if (y.size())
{ {
if (x.size()) if (x.size())
{ {
// Using HashSet will likely change the order of list
labelHashSet set(x); labelHashSet set(x);
set.insert(y); set.insert(y);
x = set.toc(); x = set.toc();

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2017-2025 OpenCFD Ltd. Copyright (C) 2017-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -485,6 +485,7 @@ labelPair findMinMax(const ListType& input, label start=0);
// <code> (list[i] < val) </code> for the test. // <code> (list[i] < val) </code> for the test.
// //
// \tparam ListType The input list type // \tparam ListType The input list type
// \tparam T The value type (should normally be ListType::value_type)
// //
// \param input The sorted list to search // \param input The sorted list to search
// \param val The value for searching/comparing // \param val The value for searching/comparing
@ -507,7 +508,7 @@ label findSortedIndex
// <code> lessOp<T>(list[i], val) </code> for the test. // <code> lessOp<T>(list[i], val) </code> for the test.
// //
// \tparam ListType The input list type // \tparam ListType The input list type
// \tparam T The value type (usually the same as ListType::value_type) // \tparam T The value type (is often the same as ListType::value_type)
// \tparam ComparePredicate The type of the comparison functor that // \tparam ComparePredicate The type of the comparison functor that
// returns true for sorting below. // returns true for sorting below.
// //
@ -584,33 +585,23 @@ namespace ListOps
template<class T> template<class T>
struct appendEqOp struct appendEqOp
{ {
void operator()(List<T>& x, const UList<T>& y) const; void operator()(List<T>& x, const List<T>& y) const;
}; };
//- List helper to append y unique elements onto the end of x //- List helper to append y unique elements onto the end of x
template<class T> template<class T>
struct uniqueEqOp struct uniqueEqOp
{ {
void operator()(List<T>& x, const UList<T>& y) const; void operator()(List<T>& x, const List<T>& y) const;
}; };
//- List helper to add y unique elements to x //- List helper to add y unique elements to x
struct unionEqOp struct unionEqOp
{ {
void operator()(labelList& x, const labelUList& y) const; void operator()(labelList& x, const labelList& y) const;
}; };
//- Test for list equality with different but compatible data types.
//- Eg, int32 and int64
template<class Type1, class Type2>
bool equal(const UList<Type1>& a, const UList<Type2>& b);
//- Test for list equality with different but compatible data types.
template<class Type1, class Type2, class BinaryPredicate>
bool equal(const UList<Type1>& a, const UList<Type2>& b, BinaryPredicate pred);
// Public classes // Public classes
//- A list compare binary predicate for normal sort //- A list compare binary predicate for normal sort

View File

@ -1081,7 +1081,7 @@ template<class T>
void Foam::ListOps::appendEqOp<T>::operator() void Foam::ListOps::appendEqOp<T>::operator()
( (
List<T>& x, List<T>& x,
const UList<T>& y const List<T>& y
) const ) const
{ {
if (y.size()) if (y.size())
@ -1102,7 +1102,7 @@ template<class T>
void Foam::ListOps::uniqueEqOp<T>::operator() void Foam::ListOps::uniqueEqOp<T>::operator()
( (
List<T>& x, List<T>& x,
const UList<T>& y const List<T>& y
) const ) const
{ {
if (y.size()) if (y.size())
@ -1111,7 +1111,6 @@ void Foam::ListOps::uniqueEqOp<T>::operator()
{ {
for (const T& val : y) for (const T& val : y)
{ {
// Not very efficient
x.push_uniq(val); x.push_uniq(val);
} }
} }
@ -1123,37 +1122,6 @@ void Foam::ListOps::uniqueEqOp<T>::operator()
} }
template<class Type1, class Type2>
bool Foam::ListOps::equal
(
const UList<Type1>& a,
const UList<Type2>& b
)
{
return
(
(a.size() == b.size())
&& std::equal(a.cbegin(), a.cend(), b.cbegin())
);
}
template<class Type1, class Type2, class BinaryPredicate>
bool Foam::ListOps::equal
(
const UList<Type1>& a,
const UList<Type2>& b,
BinaryPredicate pred
)
{
return
(
(a.size() == b.size())
&& std::equal(a.cbegin(), a.cend(), b.cbegin(), pred)
);
}
template<class ListType, class UnaryPredicate> template<class ListType, class UnaryPredicate>
Foam::label Foam::ListOps::count_if Foam::label Foam::ListOps::count_if
( (

View File

@ -34,7 +34,6 @@ Description
#ifndef Foam_ListPolicy_H #ifndef Foam_ListPolicy_H
#define Foam_ListPolicy_H #define Foam_ListPolicy_H
#include "MemoryPool.H" // Also includes <cstdint>
#include "contiguous.H" // Also includes <type_traits> #include "contiguous.H" // Also includes <type_traits>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -104,18 +103,6 @@ template<> struct no_linebreak<wordRe> : std::true_type {};
// - use_offload(n) : // - use_offload(n) :
// Lower threshold for switching to device offloading // Lower threshold for switching to device offloading
// //
//
// Use of the memory-pool is controlled by the 'is_aligned_type()' test
// and the minimum field size, controlled by the 'use_memory_pool()' test.
//
// If the memory-pool is not enabled or not required according to the two
// above tests, the allocation falls back to either an aligned or unaligned
// allocation.
//
// The decision about when to choose aligned vs unaligned allocation
// is still a compile-time option. Made by direct edit of the
// appropriate functions.
//
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Consider aligned allocation for the given type? //- Consider aligned allocation for the given type?
@ -159,104 +146,27 @@ inline constexpr bool use_offload(IntType n) noexcept
} }
//- Default alignment for larger fields
inline constexpr std::align_val_t default_alignment() noexcept
{
return std::align_val_t(256);
}
//- Allocate from memory pool (if active), or aligned, or normal
template<class T, class IntType> template<class T, class IntType>
inline T* allocate(IntType n) inline T* allocate(IntType n)
{ {
if constexpr (ListPolicy::is_aligned_type<T>()) // Plain new
{ return new T[n];
// Note: threshold for use_memory_pool() >= use_alignment()
if (ListPolicy::use_alignment(n))
{
if
(
void *pool_ptr
(
// Consider memory pool for large amounts of data
ListPolicy::use_memory_pool(n)
? Foam::MemoryPool::try_allocate(sizeof(T)*n)
: nullptr
);
pool_ptr
)
{
// Placement new
return new (pool_ptr) T[n];
}
else
{
return new (ListPolicy::default_alignment()) T[n];
}
}
else
{
// Plain new
return new T[n];
}
}
else
{
// Plain new
return new T[n];
}
} }
//- Deallocate from memory pool, or normal
template<class T, class IntType> template<class T, class IntType>
inline void deallocate(T* ptr) inline void deallocate(T* ptr)
{ {
if constexpr (ListPolicy::is_aligned_type<T>()) // Plain new
{ delete[] ptr;
if (ptr && !Foam::MemoryPool::try_deallocate(ptr))
{
// Plain new
delete[] ptr;
}
}
else
{
// Plain new
delete[] ptr;
}
} }
//- Deallocate from memory pool, or aligned, or normal
template<class T, class IntType> template<class T, class IntType>
inline void deallocate(T* ptr, [[maybe_unused]] IntType n) inline void deallocate(T* ptr, [[maybe_unused]] IntType n)
{ {
if constexpr (ListPolicy::is_aligned_type<T>()) // Plain new
{ delete[] ptr;
// Note: threshold for use_memory_pool() >= use_alignment()
if (ListPolicy::use_alignment(n))
{
if (ptr && !Foam::MemoryPool::try_deallocate(ptr))
{
// Alignment depends on the number of elements
::operator delete[](ptr, ListPolicy::default_alignment());
}
}
else
{
// Plain new
delete[] ptr;
}
}
else
{
// Plain new
delete[] ptr;
}
} }

View File

@ -112,26 +112,23 @@ public:
//- Change the value for the list capacity directly (ADVANCED, UNSAFE) //- Change the value for the list capacity directly (ADVANCED, UNSAFE)
//- Does not perform any memory management or resizing. //- Does not perform any memory management or resizing.
void setCapacity_unsafe(label len) noexcept { capacity_ = len; } void setCapacity_unsafe(const label len) noexcept { capacity_ = len; }
//- Reserve allocation space for at least this size. //- Reserve allocation space for at least this size.
// New entries are initialized to nullptr.
inline void reserve(const label len); inline void reserve(const label len);
//- Reserve allocation space for at least this size. //- Reserve allocation space for at least this size.
//- If allocation is required, uses the specified size //- If allocation is required, uses the specified size
//- without any other resizing logic. //- without any other resizing logic.
// New entries are initialized to nullptr.
inline void reserve_exact(const label len); inline void reserve_exact(const label len);
//- Alter the addressed list size. //- Alter the addressed list size.
// New entries are initialized to nullptr. inline void resize(const label newLen);
inline void resize(const label len);
//- Set the addressed list to the given size, //- Set the addressed list to the given size,
//- deleting all existing entries. //- deleting all existing entries.
//- Afterwards the list contains all \c nullptr entries. //- Afterwards the list contains all \c nullptr entries.
inline void resize_null(const label len); inline void resize_null(const label newLen);
//- Clear the addressed list, i.e. set the size to zero. //- Clear the addressed list, i.e. set the size to zero.
// Allocated size does not change // Allocated size does not change
@ -143,6 +140,11 @@ public:
//- Shrink the allocated space to the number of elements used. //- Shrink the allocated space to the number of elements used.
inline void shrink_to_fit(); inline void shrink_to_fit();
//- Shrink the internal bookkeeping of the allocated space to the
//- number of addressed elements without affecting allocation.
// \note when empty() it will delete any allocated memory.
inline void shrink_unsafe();
//- Alias for shrink_to_fit() //- Alias for shrink_to_fit()
void shrink() { this->shrink_to_fit(); } void shrink() { this->shrink_to_fit(); }

View File

@ -82,7 +82,10 @@ inline Foam::PtrDynList<T, SizeMin>::PtrDynList
PtrList<T>(std::move(list)), PtrList<T>(std::move(list)),
capacity_(list.capacity()) capacity_(list.capacity())
{ {
list.setCapacity_unsafe(0); // All contents moved // FUTURE:
// list.setCapacity_unsafe(0); // Same as shrink_unsafe() but noexcept
list.clearStorage(); // capacity=0 etc.
} }
@ -96,7 +99,10 @@ inline Foam::PtrDynList<T, SizeMin>::PtrDynList
PtrList<T>(std::move(list)), PtrList<T>(std::move(list)),
capacity_(list.capacity()) capacity_(list.capacity())
{ {
list.setCapacity_unsafe(0); // All contents moved // FUTURE:
// list.setCapacity_unsafe(0); // Same as shrink_unsafe() but noexcept
list.clearStorage(); // capacity=0 etc.
} }
@ -129,17 +135,11 @@ inline void Foam::PtrDynList<T, SizeMin>::reserve(const label len)
// Preserve addressed size // Preserve addressed size
const label currLen = PtrList<T>::size(); const label currLen = PtrList<T>::size();
// Consistent allocated sizing
PtrList<T>::setAddressableSize(capacity_);
// Increase capacity (eg, doubling) // Increase capacity (eg, doubling)
capacity_ = capacity_ =
Foam::ListPolicy::reserve_size<SizeMin, 2>(len, capacity_); Foam::ListPolicy::reserve_size<SizeMin, 2>(len, capacity_);
// No PtrList<T>::resize_copy(...) -> copying nullptr is cheap
PtrList<T>::resize(capacity_); PtrList<T>::resize(capacity_);
capacity_ = PtrList<T>::size();
PtrList<T>::setAddressableSize(currLen); PtrList<T>::setAddressableSize(currLen);
} }
} }
@ -153,13 +153,8 @@ inline void Foam::PtrDynList<T, SizeMin>::reserve_exact(const label len)
// Preserve addressed size // Preserve addressed size
const label currLen = PtrList<T>::size(); const label currLen = PtrList<T>::size();
// Consistent allocated sizing capacity_ = len;
PtrList<T>::setAddressableSize(capacity_); PtrList<T>::resize(capacity_);
// No PtrList<T>::resize_copy(...) -> copying nullptr is cheap
PtrList<T>::resize(len);
capacity_ = PtrList<T>::size();
PtrList<T>::setAddressableSize(currLen); PtrList<T>::setAddressableSize(currLen);
} }
} }
@ -169,12 +164,16 @@ template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::resize(const label newLen) inline void Foam::PtrDynList<T, SizeMin>::resize(const label newLen)
{ {
auto& ptrs = this->ptrs_; auto& ptrs = this->ptrs_;
const label oldLen = ptrs.size(); const label oldLen = ptrs.size();
if (capacity_ < newLen) if (capacity_ < newLen)
{ {
// Extend list // Increase capacity (eg, doubling)
this->reserve(newLen); capacity_ =
Foam::ListPolicy::reserve_size<SizeMin, 2>(newLen, capacity_);
PtrList<T>::resize(capacity_);
} }
else if (newLen != oldLen) else if (newLen != oldLen)
{ {
@ -192,16 +191,13 @@ inline void Foam::PtrDynList<T, SizeMin>::resize(const label newLen)
template<class T, int SizeMin> template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::resize_null(const label len) inline void Foam::PtrDynList<T, SizeMin>::resize_null(const label newLen)
{ {
if (capacity_ < len) if (capacity_ < newLen)
{ {
// Consistent allocated sizing
PtrList<T>::setAddressableSize(capacity_);
// Increase capacity (eg, doubling) // Increase capacity (eg, doubling)
capacity_ = capacity_ =
Foam::ListPolicy::reserve_size<SizeMin, 2>(len, capacity_); Foam::ListPolicy::reserve_size<SizeMin, 2>(newLen, capacity_);
PtrList<T>::resize_null(capacity_); PtrList<T>::resize_null(capacity_);
} }
@ -211,7 +207,7 @@ inline void Foam::PtrDynList<T, SizeMin>::resize_null(const label len)
} }
// Adjust addressed size // Adjust addressed size
PtrList<T>::setAddressableSize(len); PtrList<T>::setAddressableSize(newLen);
} }
@ -244,6 +240,18 @@ inline void Foam::PtrDynList<T, SizeMin>::shrink_to_fit()
} }
template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::shrink_unsafe()
{
if (PtrList<T>::empty())
{
// Delete empty list
PtrList<T>::clear();
}
capacity_ = PtrList<T>::size();
}
template<class T, int SizeMin> template<class T, int SizeMin>
inline Foam::label Foam::PtrDynList<T, SizeMin>::squeezeNull() inline Foam::label Foam::PtrDynList<T, SizeMin>::squeezeNull()
{ {

View File

@ -257,13 +257,13 @@ public:
return ioState_ & std::ios_base::badbit; return ioState_ & std::ios_base::badbit;
} }
//- True if the stream has not failed //- Return true if the stream has not failed
explicit operator bool() const noexcept explicit operator bool() const noexcept
{ {
return !fail(); return !fail();
} }
//- True if the stream has failed //- Return true if the stream has failed
bool operator!() const noexcept bool operator!() const noexcept
{ {
return fail(); return fail();
@ -406,10 +406,10 @@ public:
return flags((flags() & ~mask) | (f & mask)); return flags((flags() & ~mask) | (f & mask));
} }
//- Unset stream flags, return old stream flags //- Unset flags of stream
std::ios_base::fmtflags unsetf(std::ios_base::fmtflags f) void unsetf(std::ios_base::fmtflags f)
{ {
return flags(flags() & ~f); flags(flags() & ~f);
} }

View File

@ -179,9 +179,6 @@ public:
// Public Classes // Public Classes
//- Wrapper for OpenFOAM internal communicator index
class communicator; // Forward Declaration
//- Wrapper for MPI_Comm //- Wrapper for MPI_Comm
class Communicator; // Forward Declaration class Communicator; // Forward Declaration
@ -381,25 +378,6 @@ public:
//- Print un-directed graph in graphviz dot format //- Print un-directed graph in graphviz dot format
void printGraph(Ostream& os, int proci = 0) const; void printGraph(Ostream& os, int proci = 0) const;
//- Write the communication tree
Ostream& writeList(Ostream& os) const
{
return tree_.writeList(os);
}
// Member / Friend Operators
//- Write the communication tree
friend Ostream& operator<<
(
Ostream& os,
const commsStructList& rhs
)
{
return rhs.writeList(os);
}
}; };
@ -872,7 +850,7 @@ public:
const bool withComponents = true const bool withComponents = true
); );
//- Create new communicator with sub-ranks on the parent communicator //- Creaet new communicator with sub-ranks on the parent communicator
static label newCommunicator static label newCommunicator
( (
//! The parent communicator //! The parent communicator
@ -918,6 +896,126 @@ public:
const bool withComponents = true const bool withComponents = true
); );
//- Wrapper class for allocating/freeing communicators. Always invokes
//- allocateCommunicatorComponents() and freeCommunicatorComponents()
class communicator
{
label comm_;
public:
//- No copy construct
communicator(const communicator&) = delete;
//- No copy assignment
void operator=(const communicator&) = delete;
//- Default construct (a placeholder communicator)
communicator() noexcept : comm_(-1) {}
//- Move construct, takes ownership
communicator(communicator&& c) : comm_(c.comm_) { c.comm_ = -1; }
//- Allocate communicator for contiguous sub-ranks on given parent
communicator
(
//! The parent communicator
const label parentComm,
//! The contiguous sub-ranks of parent to use
const labelRange& subRanks
)
:
comm_(UPstream::newCommunicator(parentComm, subRanks))
{}
//- Allocate communicator for sub-ranks on given parent
communicator
(
//! The parent communicator
const label parentComm,
//! The sub-ranks of parent to use (negative values ignored)
const labelUList& subRanks
)
:
comm_(UPstream::newCommunicator(parentComm, subRanks))
{}
//- Factory Method :
//- Duplicate the given communicator
static communicator duplicate(const label parentComm)
{
communicator c;
c.comm_ = UPstream::dupCommunicator(parentComm);
return c;
}
//- Factory Method :
//- Split the communicator on the given \em colour.
static communicator split
(
//! The parent communicator
const label parentComm,
//! The colouring to select which ranks to include.
//! Negative values correspond to 'ignore'
const int colour,
//! Use MPI_Allgather+MPI_Comm_create_group vs MPI_Comm_split
const bool two_step = true
)
{
communicator c;
c.comm_ =
UPstream::splitCommunicator(parentComm, colour, two_step);
return c;
}
//- Free allocated communicator
~communicator() { UPstream::freeCommunicator(comm_); }
//- True if communicator is non-negative (ie, was allocated)
bool good() const noexcept { return (comm_ >= 0); }
//- The communicator label
label comm() const noexcept { return comm_; }
//- Release ownership of the communicator, return old value.
// Leave further management to the caller
label release() noexcept { label c(comm_); comm_ = -1; return c; }
//- Free allocated communicator
void reset() { UPstream::freeCommunicator(comm_); comm_ = -1; }
//- Allocate with contiguous sub-ranks of parent communicator
void reset(label parent, const labelRange& subRanks)
{
UPstream::freeCommunicator(comm_);
comm_ = UPstream::newCommunicator(parent, subRanks);
}
//- Allocate with sub-ranks of parent communicator
void reset(label parent, const labelUList& subRanks)
{
UPstream::freeCommunicator(comm_);
comm_ = UPstream::newCommunicator(parent, subRanks);
}
//- Take ownership, free allocated communicator
// \caution do not call as self-assignment
void reset(communicator&& c)
{
if (comm_ != c.comm_) UPstream::freeCommunicator(comm_);
comm_ = c.comm_;
c.comm_ = -1;
}
//- Move assignment, takes ownership
// \caution do not call as self-assignment
void operator=(communicator&& c) { reset(std::move(c)); }
//- Cast to label - the same as comm()
operator label() const noexcept { return comm_; }
};
//- Return physical processor number (i.e. processor number in //- Return physical processor number (i.e. processor number in
//- worldComm) given communicator and processor //- worldComm) given communicator and processor
static int baseProcNo(label comm, int procID); static int baseProcNo(label comm, int procID);
@ -1741,168 +1839,6 @@ public:
} }
}; };
/*---------------------------------------------------------------------------*\
Class UPstream::communicator Declaration
\*---------------------------------------------------------------------------*/
//- Wrapper for internally indexed communicator label.
//- Always invokes UPstream::allocateCommunicatorComponents()
//- and UPstream::freeCommunicatorComponents()
class UPstream::communicator
{
// Private Data
//- The communicator label
label comm_;
public:
// Generated Methods
//- No copy construct
communicator(const communicator&) = delete;
//- No copy assignment
void operator=(const communicator&) = delete;
// Constructors
//- Default construct (a placeholder communicator)
communicator() noexcept : comm_(-1) {}
//- Move construct, takes ownership
communicator(communicator&& c) : comm_(c.comm_) { c.comm_ = -1; }
//- Allocate communicator for contiguous sub-ranks on given parent
communicator
(
//! The parent communicator
const label parentComm,
//! The contiguous sub-ranks of parent to use
const labelRange& subRanks
)
:
comm_(UPstream::newCommunicator(parentComm, subRanks))
{}
//- Allocate communicator for sub-ranks on given parent
communicator
(
//! The parent communicator
const label parentComm,
//! The sub-ranks of parent to use (negative values ignored)
const labelUList& subRanks
)
:
comm_(UPstream::newCommunicator(parentComm, subRanks))
{}
// Destructor
//- Free allocated communicator
~communicator() { UPstream::freeCommunicator(comm_); }
// Factory Methods
//- Duplicate the given communicator
static communicator duplicate(const label parentComm)
{
communicator c;
c.comm_ = UPstream::dupCommunicator(parentComm);
return c;
}
//- Factory Method :
//- Split the communicator on the given \em colour.
static communicator split
(
//! The parent communicator
const label parentComm,
//! The colouring to select which ranks to include.
//! Negative values correspond to 'ignore'
const int colour,
//! Use MPI_Allgather+MPI_Comm_create_group vs MPI_Comm_split
const bool two_step = true
)
{
communicator c;
c.comm_ = UPstream::splitCommunicator(parentComm, colour, two_step);
return c;
}
// Member Functions
//- True if communicator is non-negative (ie, was allocated)
bool good() const noexcept { return (comm_ >= 0); }
//- The communicator label
label comm() const noexcept { return comm_; }
//- Return non-const reference to this
communicator& constCast() const noexcept
{
return const_cast<communicator&>(*this);
}
//- Release ownership of the communicator, return old value.
// Leave further management to the caller
label release() noexcept { label c(comm_); comm_ = -1; return c; }
//- Free allocated communicator
void reset() { UPstream::freeCommunicator(comm_); comm_ = -1; }
//- Allocate with contiguous sub-ranks of parent communicator
void reset(label parent, const labelRange& subRanks)
{
UPstream::freeCommunicator(comm_);
comm_ = UPstream::newCommunicator(parent, subRanks);
}
//- Allocate with sub-ranks of parent communicator
void reset(label parent, const labelUList& subRanks)
{
UPstream::freeCommunicator(comm_);
comm_ = UPstream::newCommunicator(parent, subRanks);
}
//- Take ownership, free managed communicator
void reset(communicator&& c)
{
if (this == &c) return; // No self-assignment
if (comm_ != c.comm_) UPstream::freeCommunicator(comm_);
comm_ = c.comm_;
c.comm_ = -1;
}
//- Swap communicator labels
void swap(communicator& c) { std::swap(comm_, c.comm_); }
// Member Operators
//- Implicit cast to label - the same as comm()
operator label() const noexcept { return comm_; }
//- Move assignment, takes ownership
void operator=(communicator&& c) { reset(std::move(c)); }
//- Test for equality
bool operator==(const communicator& c) const noexcept
{
return (comm_ == c.comm_);
}
//- Test for inequality
bool operator!=(const communicator& c) const noexcept
{
return (comm_ != c.comm_);
}
};
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class UPstream::Communicator Declaration Class UPstream::Communicator Declaration

View File

@ -470,10 +470,18 @@ public:
//- Copy append a list of tokens at the current tokenIndex, //- Copy append a list of tokens at the current tokenIndex,
//- incrementing the index. //- incrementing the index.
//
// \param newTokens the list of tokens to copy append
// \param lazy leaves any excess capacity for further appends.
// The caller will be responsible for resizing later.
void add_tokens(const UList<token>& toks); void add_tokens(const UList<token>& toks);
//- Move append a list of tokens at the current tokenIndex, //- Move append a list of tokens at the current tokenIndex,
//- incrementing the index. //- incrementing the index.
//
// \param newTokens the list of tokens to move append
// \param lazy leaves any excess capacity for further appends.
// The caller will be responsible for resizing later.
void add_tokens(List<token>&& toks); void add_tokens(List<token>&& toks);

View File

@ -32,7 +32,7 @@ Note
#include "error.H" #include "error.H"
#include "dictionary.H" #include "dictionary.H"
#include "foamVersion.H" #include "foamVersion.H"
#include "UPstream.H" #include "Pstream.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -106,34 +106,22 @@ Foam::messageStream::messageStream(const dictionary& dict)
Foam::OSstream& Foam::messageStream::stream Foam::OSstream& Foam::messageStream::stream
( (
OSstream* alternative, OSstream* alternative
int communicator
) )
{ {
if (communicator < 0)
{
communicator = UPstream::worldComm;
}
if (level) if (level)
{ {
// Master-only output? // Serlal (master only) output?
const bool masterOnly const bool serialOnly
( (
!UPstream::parRun() !UPstream::parRun()
|| ((severity_ & ~errorSeverity::USE_STDERR) == errorSeverity::INFO) || ((severity_ & ~errorSeverity::USE_STDERR) == errorSeverity::INFO)
|| ((severity_ & ~errorSeverity::USE_STDERR) == errorSeverity::WARNING) || ((severity_ & ~errorSeverity::USE_STDERR) == errorSeverity::WARNING)
); );
if if (serialOnly && (UPstream::parRun() && !UPstream::master()))
(
masterOnly
&& (UPstream::parRun() && !UPstream::master(communicator))
)
{ {
// Requested master-only output but is non-master (in parallel) return Snull; // Non-serial, non-master: exit early
// -> early exit
return Snull;
} }
@ -151,9 +139,10 @@ Foam::OSstream& Foam::messageStream::stream
OSstream* osptr; OSstream* osptr;
if (masterOnly) if (serialOnly)
{ {
// Use supplied alternative? Valid for master-only output // Use supplied alternative? Valid for serial only
osptr = osptr =
( (
alternative alternative
@ -163,6 +152,7 @@ Foam::OSstream& Foam::messageStream::stream
} }
else else
{ {
// Non-serial
osptr = (use_stderr ? &Perr : &Pout); osptr = (use_stderr ? &Perr : &Pout);
} }
@ -185,13 +175,8 @@ Foam::OSstream& Foam::messageStream::stream
} }
Foam::OSstream& Foam::messageStream::masterStream(int communicator) Foam::OSstream& Foam::messageStream::masterStream(const int communicator)
{ {
if (communicator < 0)
{
communicator = UPstream::worldComm;
}
if (UPstream::warnComm >= 0 && communicator != UPstream::warnComm) if (UPstream::warnComm >= 0 && communicator != UPstream::warnComm)
{ {
Perr<< "** messageStream with comm:" << communicator << endl; Perr<< "** messageStream with comm:" << communicator << endl;
@ -200,7 +185,7 @@ Foam::OSstream& Foam::messageStream::masterStream(int communicator)
if (communicator == UPstream::worldComm || UPstream::master(communicator)) if (communicator == UPstream::worldComm || UPstream::master(communicator))
{ {
return this->stream(nullptr, communicator); return this->stream();
} }
return Snull; return Snull;
@ -209,7 +194,6 @@ Foam::OSstream& Foam::messageStream::masterStream(int communicator)
std::ostream& Foam::messageStream::stdStream() std::ostream& Foam::messageStream::stdStream()
{ {
// Currently do not need communicator != worldComm
return this->stream().stdStream(); return this->stream().stdStream();
} }
@ -416,13 +400,13 @@ Foam::OSstream& Foam::messageStream::operator()
Foam::messageStream Foam::Info Foam::messageStream Foam::Info
( (
// No title "", // No title
Foam::messageStream::INFO Foam::messageStream::INFO
); );
Foam::messageStream Foam::InfoErr Foam::messageStream Foam::InfoErr
( (
// No title "", // No title
Foam::messageStream::INFO, Foam::messageStream::INFO,
0, 0,
true // use_stderr = true true // use_stderr = true

View File

@ -179,7 +179,7 @@ public:
// \return the previous value for maxErrors // \return the previous value for maxErrors
int maxErrors(int nErrors) noexcept int maxErrors(int nErrors) noexcept
{ {
int old(maxErrors_); int old = maxErrors_;
maxErrors_ = nErrors; maxErrors_ = nErrors;
return old; return old;
} }
@ -191,15 +191,12 @@ public:
OSstream& stream OSstream& stream
( (
//! An alternative output stream (serial-only) //! An alternative output stream (serial-only)
OSstream* alternative = nullptr, OSstream* alternative = nullptr
//! Communicator. Negative is treated like UPstream::worldComm
int communicator = -1
); );
//- Return OSstream for output operations on the master process only, //- Return OSstream for output operations on the master process only,
//- Snull on other processes. //- Snull on other processes.
// A negative communicator is treated like UPstream::worldComm OSstream& masterStream(const int communicator);
OSstream& masterStream(int communicator);
//- Return std::ostream for output operations. //- Return std::ostream for output operations.
std::ostream& stdStream(); std::ostream& stdStream();

View File

@ -145,9 +145,9 @@ public:
// Static Member Functions // Static Member Functions
//- Return a null DimensionedField (reference to a nullObject). //- Return a null DimensionedField (reference to a nullObject).
static const this_type& null() noexcept static const DimensionedField<Type, GeoMesh>& null() noexcept
{ {
return NullObjectRef<this_type>(); return NullObjectRef<DimensionedField<Type, GeoMesh>>();
} }

View File

@ -217,7 +217,7 @@ public:
//- Change the value for the list capacity directly (ADVANCED, UNSAFE) //- Change the value for the list capacity directly (ADVANCED, UNSAFE)
//- Does not perform any memory management or resizing. //- Does not perform any memory management or resizing.
void setCapacity_unsafe(label len) noexcept { capacity_ = len; } void setCapacity_unsafe(const label len) noexcept { capacity_ = len; }
//- Reserve allocation space for at least this size, allocating new //- Reserve allocation space for at least this size, allocating new
//- space if required and \em retaining old content. //- space if required and \em retaining old content.
@ -265,6 +265,11 @@ public:
//- Shrink the allocated space to the number of elements used. //- Shrink the allocated space to the number of elements used.
inline void shrink_to_fit(); inline void shrink_to_fit();
//- Shrink the internal bookkeeping of the allocated space to the
//- number of addressed elements without affecting allocation.
// \note when empty() it will delete any allocated memory.
inline void shrink_unsafe();
// Edit // Edit

View File

@ -66,9 +66,7 @@ inline void Foam::DynamicField<T, SizeMin>::doCapacity
// Addressable length, possibly truncated by new capacity // Addressable length, possibly truncated by new capacity
const label currLen = Foam::min(List<T>::size(), newCapacity); const label currLen = Foam::min(List<T>::size(), newCapacity);
// Consistent allocated sizing
List<T>::setAddressableSize(capacity_); List<T>::setAddressableSize(capacity_);
if (nocopy) if (nocopy)
{ {
List<T>::resize_nocopy(newCapacity); List<T>::resize_nocopy(newCapacity);
@ -95,9 +93,6 @@ inline void Foam::DynamicField<T, SizeMin>::doReserve
// Preserve addressed size // Preserve addressed size
const label currLen = List<T>::size(); const label currLen = List<T>::size();
// Consistent allocated sizing
List<T>::setAddressableSize(capacity_);
// Increase capacity (eg, doubling) // Increase capacity (eg, doubling)
capacity_ = capacity_ =
Foam::ListPolicy::reserve_size<SizeMin, 2>(len, capacity_); Foam::ListPolicy::reserve_size<SizeMin, 2>(len, capacity_);
@ -108,10 +103,8 @@ inline void Foam::DynamicField<T, SizeMin>::doReserve
} }
else else
{ {
List<T>::resize_copy(currLen, capacity_); List<T>::resize(capacity_);
} }
capacity_ = List<T>::size();
List<T>::setAddressableSize(currLen); List<T>::setAddressableSize(currLen);
} }
} }
@ -253,7 +246,7 @@ inline Foam::DynamicField<T, SizeMin>::DynamicField
Field<T>(std::move(static_cast<List<T>&>(content))), Field<T>(std::move(static_cast<List<T>&>(content))),
capacity_(content.capacity()) capacity_(content.capacity())
{ {
content.setCapacity_unsafe(0); // All contents moved content.setCapacity_unsafe(0); // Same as shrink_unsafe() but noexcept
} }
@ -266,7 +259,7 @@ inline Foam::DynamicField<T, SizeMin>::DynamicField
Field<T>(std::move(static_cast<List<T>&>(content))), Field<T>(std::move(static_cast<List<T>&>(content))),
capacity_(content.capacity()) capacity_(content.capacity())
{ {
content.setCapacity_unsafe(0); // All contents moved content.setCapacity_unsafe(0); // Same as shrink_unsafe() but noexcept
} }
@ -280,7 +273,7 @@ inline Foam::DynamicField<T, SizeMin>::DynamicField
Field<T>(std::move(static_cast<List<T>&>(content))), Field<T>(std::move(static_cast<List<T>&>(content))),
capacity_(content.capacity()) capacity_(content.capacity())
{ {
content.setCapacity_unsafe(0); // All contents moved content.setCapacity_unsafe(0); // Same as shrink_unsafe() but noexcept
} }
@ -299,7 +292,7 @@ inline Foam::DynamicField<T, SizeMin>::DynamicField
{ {
Field<T>::transfer(static_cast<List<T>&>(content)); Field<T>::transfer(static_cast<List<T>&>(content));
capacity_ = content.capacity(); capacity_ = content.capacity();
content.setCapacity_unsafe(0); // All contents moved content.setCapacity_unsafe(0);
} }
else else
{ {
@ -324,7 +317,7 @@ inline Foam::DynamicField<T, SizeMin>::DynamicField
{ {
Field<T>::transfer(static_cast<List<T>&>(content)); Field<T>::transfer(static_cast<List<T>&>(content));
capacity_ = content.capacity(); capacity_ = content.capacity();
content.setCapacity_unsafe(0); // All contents moved content.setCapacity_unsafe(0);
} }
else else
{ {
@ -469,15 +462,8 @@ inline void Foam::DynamicField<T, SizeMin>::reserve_exact
// Preserve addressed size // Preserve addressed size
const label currLen = List<T>::size(); const label currLen = List<T>::size();
// Consistent allocated sizing capacity_ = len;
List<T>::setAddressableSize(capacity_); List<T>::resize(capacity_);
// if (!nocopy)
{
List<T>::resize_copy(currLen, len);
}
capacity_ = List<T>::size();
List<T>::setAddressableSize(currLen); List<T>::setAddressableSize(currLen);
} }
} }
@ -565,6 +551,18 @@ inline void Foam::DynamicField<T, SizeMin>::shrink_to_fit()
} }
template<class T, int SizeMin>
inline void Foam::DynamicField<T, SizeMin>::shrink_unsafe()
{
if (List<T>::empty())
{
// Delete storage if empty
List<T>::clear();
}
capacity_ = List<T>::size();
}
template<class T, int SizeMin> template<class T, int SizeMin>
inline void inline void
Foam::DynamicField<T, SizeMin>::swap(List<T>& list) Foam::DynamicField<T, SizeMin>::swap(List<T>& list)

View File

@ -38,27 +38,31 @@ template<class CheckPatchFieldType>
bool Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::checkConsistency bool Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::checkConsistency
( (
const scalar tol, const scalar tol,
const bool exitIfBad const bool doExit
) const ) const
{ {
auto& bfld = this->constCast(); if (!this->size())
if (!bfld.size())
{ {
return true; return true;
} }
if (debug&2) if (debug&2)
{ {
const auto& pfld0 = this->operator[](0);
PoutInFunction PoutInFunction
<< " Checking boundary consistency for field " << " Checking boundary consistency for field "
<< bfld[0].internalField().name() << endl; << pfld0.internalField().name()
<< endl;
} }
// Store old values and states auto& bfld = this->constCast();
List<Field<Type>> oldFields(bfld.size());
boolList oldUpdated(bfld.size());
boolList oldManipulated(bfld.size()); // Store old value
List<Field<Type>> oldBfld(this->size());
boolList oldUpdated(this->size());
//Note: areaFields (finiteArea) do not have manipulatedMatrix() flag. TBD.
//boolList oldManipulated(this->size());
label nEvaluated(0); label nEvaluated(0);
@ -67,9 +71,9 @@ bool Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::checkConsistency
if (isA<CheckPatchFieldType>(pfld)) if (isA<CheckPatchFieldType>(pfld))
{ {
const label patchi = pfld.patch().index(); const label patchi = pfld.patch().index();
oldFields[patchi] = pfld;
oldUpdated[patchi] = pfld.updated(); oldUpdated[patchi] = pfld.updated();
oldManipulated[patchi] = pfld.manipulatedMatrix(); oldBfld[patchi] = pfld;
//oldManipulated[patchi] = pfld.manipulatedMatrix();
++nEvaluated; ++nEvaluated;
} }
} }
@ -113,16 +117,16 @@ bool Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::checkConsistency
if (isA<CheckPatchFieldType>(pfld)) if (isA<CheckPatchFieldType>(pfld))
{ {
const label patchi = pfld.patch().index(); const label patchi = pfld.patch().index();
auto& oldPfld = oldFields[patchi]; const auto& oldPfld = oldBfld[patchi];
bool localOk(true); bool localOk(true);
if (allOk) if (allOk)
{ {
// Only check for first failed patch // Only check once
forAll(pfld, facei) forAll(pfld, facei)
{ {
if (tol < Foam::mag(pfld[facei]-oldPfld[facei])) if (mag(pfld[facei]-oldPfld[facei]) > tol)
{ {
allOk = false; allOk = false;
localOk = false; localOk = false;
@ -133,44 +137,50 @@ bool Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::checkConsistency
if (!localOk) if (!localOk)
{ {
// Raise warning or error if (doExit)
OSstream& err =
(
exitIfBad
? FatalErrorInFunction
: WarningInFunction
);
err << "Field "
<< pfld.internalField().name()
<< " is not evaluated?"
<< " On patch " << pfld.patch().name()
<< " type " << pfld.type()
<< " : average of field = "
<< average(oldPfld)
<< ". Average of evaluated field = "
<< average(pfld)
<< ". Difference:" << average(pfld-oldPfld)
<< ". Tolerance:" << tol << endl;
if (exitIfBad)
{ {
FatalError<< exit(FatalError); FatalErrorInFunction << "Field "
<< pfld.internalField().name()
<< " is not evaluated?"
<< " On patch " << pfld.patch().name()
<< " type " << pfld.type()
<< " : average of field = "
<< average(oldPfld)
<< ". Average of evaluated field = "
<< average(pfld)
<< ". Difference:" << average(pfld-oldPfld)
<< ". Tolerance:" << tol << endl
<< exit(FatalError);
}
else
{
WarningInFunction << "Field "
<< pfld.internalField().name()
<< " is not evaluated?"
<< " On patch " << pfld.patch().name()
<< " type " << pfld.type()
<< " : average of field = "
<< average(oldPfld)
<< ". Average of evaluated field = "
<< average(pfld)
<< ". Difference:" << average(pfld-oldPfld)
<< ". Tolerance:" << tol << endl;
} }
} }
// Restore patch field values and states // Restore bfld, updated
static_cast<Field<Type>&>(pfld) = std::move(oldPfld);
pfld.setUpdated(oldUpdated[patchi]); pfld.setUpdated(oldUpdated[patchi]);
pfld.setManipulated(oldManipulated[patchi]); static_cast<Field<Type>&>(pfld) = std::move(oldBfld[patchi]);
//pfld.setManipulated(oldManipulated[patchi]);
} }
} }
if (debug&2) if (debug&2)
{ {
const auto& pfld0 = this->operator[](0);
PoutInFunction PoutInFunction
<< " Result of checking for field " << " Result of checking for field "
<< bfld[0].internalField().name() << " : " << allOk << endl; << pfld0.internalField().name() << " : " << allOk << endl;
} }
return allOk; return allOk;

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017,2022 OpenFOAM Foundation Copyright (C) 2011-2017,2022 OpenFOAM Foundation
Copyright (C) 2015-2025 OpenCFD Ltd. Copyright (C) 2015-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -88,8 +88,7 @@ private:
// Private Member Functions // Private Member Functions
//- Check if patch fields have been consistently evaluated. //- Helper: check if patchfields have been evaluated. If not:
// If not:
// exit = true : FatalError // exit = true : FatalError
// exit = false : return bool // exit = false : return bool
template<class CheckPatchField> template<class CheckPatchField>

View File

@ -156,9 +156,9 @@ public:
// Static Member Functions // Static Member Functions
//- Return a null GeometricField (reference to a nullObject). //- Return a null GeometricField (reference to a nullObject).
static const this_type& null() noexcept static const GeometricField<Type, PatchField, GeoMesh>& null() noexcept
{ {
return NullObjectRef<this_type>(); return NullObjectRef<GeometricField<Type, PatchField, GeoMesh>>();
} }

View File

@ -318,7 +318,6 @@ void Foam::pointPatchField<Type>::evaluate(const Pstream::commsTypes)
} }
pointPatchFieldBase::setUpdated(false); pointPatchFieldBase::setUpdated(false);
pointPatchFieldBase::setManipulated(false);
} }

View File

@ -98,6 +98,16 @@ protected:
// Useful when initially constructed without a dictionary // Useful when initially constructed without a dictionary
virtual void readDict(const dictionary& dict); virtual void readDict(const dictionary& dict);
//- Set updated state
void setUpdated(bool state) noexcept
{
updated_ = state;
}
//- Set matrix manipulated state. Currently a no-op for pointPatchField.
void setManipulated(bool state) noexcept
{}
public: public:
@ -218,24 +228,13 @@ public:
return updated_; return updated_;
} }
//- Set updated state
void setUpdated(bool state) noexcept
{
updated_ = state;
}
//- True if the matrix has already been manipulated. //- True if the matrix has already been manipulated.
//- Currently always false for pointPatchField //- Currently ignored (always false) for pointPatchField
bool manipulatedMatrix() const noexcept bool manipulatedMatrix() const noexcept
{ {
return false; return false;
} }
//- Set matrix manipulated state.
//- Currently a no-op for pointPatchField.
void setManipulated(bool state) noexcept
{}
// Check // Check
@ -263,9 +262,6 @@ public:
//- The value_type for the patch field //- The value_type for the patch field
typedef Type value_type; typedef Type value_type;
//- The component type for patch field
typedef typename pTraits<Type>::cmptType cmptType;
//- The internal field type associated with the patch field //- The internal field type associated with the patch field
typedef DimensionedField<Type, pointMesh> Internal; typedef DimensionedField<Type, pointMesh> Internal;

View File

@ -37,7 +37,6 @@ License
#include "IOobject.H" #include "IOobject.H"
#include "dynamicCode.H" #include "dynamicCode.H"
#include "simpleObjectRegistry.H" #include "simpleObjectRegistry.H"
#include "MemoryPool.H"
#include "sigFpe.H" #include "sigFpe.H"
#include "sigInt.H" #include "sigInt.H"
#include "sigQuit.H" #include "sigQuit.H"
@ -2183,9 +2182,6 @@ void Foam::argList::parse
sigQuit::set(bannerEnabled()); sigQuit::set(bannerEnabled());
sigSegv::set(bannerEnabled()); sigSegv::set(bannerEnabled());
// Create memory pool (if any) after MPI has been setup
MemoryPool::create(bannerEnabled());
if (UPstream::master() && bannerEnabled()) if (UPstream::master() && bannerEnabled())
{ {
Info<< "fileModificationChecking : " Info<< "fileModificationChecking : "

View File

@ -1,116 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::MemoryPool
Description
Optional memory management using a memory pool such as Umpire
(https://github.com/LLNL/Umpire).
When compiled with Umpire, its use can be controlled by the
\c FOAM_MEMORY_POOL environment variable, or the
\c memory_pool Optimisation switch (etc/controlDict).
It currently looks for any of the following entries, in this order:
- true - same as \em "host"
- false/none - disabled.
- \em "host" - uses host memory pool
- \em "system" - same as \em "host"
- \em "device" - uses device memory pool
- \em "managed" - uses managed host/device memory pool
.
The parameters "size=nn" and "incr=nn" (in MegaBytes) can be used
to specify alternatives to the default sizing.
\*---------------------------------------------------------------------------*/
#ifndef Foam_MemoryPool_H
#define Foam_MemoryPool_H
#include <cstdint> // For size_t
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class MemoryPool Declaration
\*---------------------------------------------------------------------------*/
class MemoryPool
{
public:
// Constructors
//- Create a memory pool instance (if not already active).
// Uses environment or etc/controlDict entry
static bool create(bool verbose = false);
// Destructor
//- Remove the memory pool instance (currently does nothing)
static void destroy(bool verbose = false);
// Member Functions
//- True if pool is active (ie, created and not suspended)
static bool active() noexcept;
//- Suspend use of memory pool (for allocation).
// \return previous suspend status
static bool suspend() noexcept;
//- Resume use of memory pool (if previously active)
static void resume() noexcept;
//- Test if given pointer belongs to the pool
static bool is_pool(void *ptr);
//- Allocate from pool (if active).
// \returns nullptr if the pool is not active
static void* try_allocate(std::size_t nbytes);
//- Deallocate a pointer managed by the pool
// \returns True if a nullptr (no-op) or when the pointer was
// managed by the pool.
static bool try_deallocate(void *ptr);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2018-2025 OpenCFD Ltd. Copyright (C) 2018-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -89,11 +89,7 @@ void Foam::pointBoundaryMesh::calcGroupIDs() const
// Remove groups that clash with patch names // Remove groups that clash with patch names
forAll(patches, patchi) forAll(patches, patchi)
{ {
if (groupLookup.empty()) if (groupLookup.erase(patches[patchi].name()))
{
break; // Early termination
}
else if (groupLookup.erase(patches[patchi].name()))
{ {
WarningInFunction WarningInFunction
<< "Removed group '" << patches[patchi].name() << "Removed group '" << patches[patchi].name()
@ -374,7 +370,7 @@ Foam::labelList Foam::pointBoundaryMesh::indices
// Only check groups if requested and they exist // Only check groups if requested and they exist
const bool checkGroups = (useGroups && this->hasGroupIDs()); const bool checkGroups = (useGroups && this->hasGroupIDs());
labelHashSet ids; labelHashSet ids(0);
if (matcher.isPattern()) if (matcher.isPattern())
{ {
@ -385,7 +381,7 @@ Foam::labelList Foam::pointBoundaryMesh::indices
{ {
if (matcher(iter.key())) if (matcher(iter.key()))
{ {
// Add ids associated with the group // Add patch ids associated with the group
ids.insert(iter.val()); ids.insert(iter.val());
} }
} }
@ -417,7 +413,7 @@ Foam::labelList Foam::pointBoundaryMesh::indices
if (iter.good()) if (iter.good())
{ {
// Add ids associated with the group // Hash ids associated with the group
ids.insert(iter.val()); ids.insert(iter.val());
} }
} }
@ -442,7 +438,7 @@ Foam::labelList Foam::pointBoundaryMesh::indices
return this->indices(matcher.front(), useGroups); return this->indices(matcher.front(), useGroups);
} }
labelHashSet ids; labelHashSet ids(0);
// Only check groups if requested and they exist // Only check groups if requested and they exist
if (useGroups && this->hasGroupIDs()) if (useGroups && this->hasGroupIDs())
@ -454,7 +450,7 @@ Foam::labelList Foam::pointBoundaryMesh::indices
{ {
if (matcher(iter.key())) if (matcher(iter.key()))
{ {
// Add ids associated with the group // Add patch ids associated with the group
ids.insert(iter.val()); ids.insert(iter.val());
} }
} }
@ -475,20 +471,20 @@ Foam::labelList Foam::pointBoundaryMesh::indices
Foam::labelList Foam::pointBoundaryMesh::indices Foam::labelList Foam::pointBoundaryMesh::indices
( (
const wordRes& allow, const wordRes& select,
const wordRes& deny, const wordRes& ignore,
const bool useGroups const bool useGroups
) const ) const
{ {
if (allow.empty() && deny.empty()) //return mesh().boundaryMesh().indices(select, ignore, useGroups);
if (ignore.empty())
{ {
// Fast-path: select all return this->indices(select, useGroups);
return identity(this->size());
} }
const wordRes::filter matcher(allow, deny); const wordRes::filter matcher(select, ignore);
labelHashSet ids; labelHashSet ids(0);
// Only check groups if requested and they exist // Only check groups if requested and they exist
if (useGroups && this->hasGroupIDs()) if (useGroups && this->hasGroupIDs())
@ -500,7 +496,7 @@ Foam::labelList Foam::pointBoundaryMesh::indices
{ {
if (matcher(iter.key())) if (matcher(iter.key()))
{ {
// Add ids associated with the group // Add patch ids associated with the group
ids.insert(iter.val()); ids.insert(iter.val());
} }
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2013 OpenFOAM Foundation Copyright (C) 2011-2013 OpenFOAM Foundation
Copyright (C) 2018-2025 OpenCFD Ltd. Copyright (C) 2018-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -28,9 +28,7 @@ Class
Foam::pointBoundaryMesh Foam::pointBoundaryMesh
Description Description
A pointBoundaryMesh is a pointPatch list with registered IO, Foam::pointBoundaryMesh
a reference to the associated pointMesh,
with additional search methods etc.
SourceFiles SourceFiles
pointBoundaryMesh.C pointBoundaryMesh.C
@ -104,10 +102,10 @@ public:
// Constructors // Constructors
//- Construct from pointMesh and polyBoundaryMesh //- Construct from polyBoundaryMesh
pointBoundaryMesh(const pointMesh&, const polyBoundaryMesh&); pointBoundaryMesh(const pointMesh&, const polyBoundaryMesh&);
//- Construct from IOobject, pointMesh and polyBoundaryMesh //- Construct from IOobject and polyBoundaryMesh
pointBoundaryMesh pointBoundaryMesh
( (
const IOobject& io, const IOobject& io,
@ -143,29 +141,24 @@ public:
//- Return a list of physical types //- Return a list of physical types
wordList physicalTypes() const; wordList physicalTypes() const;
//- The (sorted) patch indices for all matches, //- Return (sorted) patch indices for all matches.
//- optionally matching patch groups. // A no-op (returns empty list) for an empty matcher
// \returns an empty list for an empty matcher
labelList indices(const wordRe& matcher, const bool useGroups) const; labelList indices(const wordRe& matcher, const bool useGroups) const;
//- The (sorted) patch indices for all matches, //- Return (sorted) patch indices for all matches.
//- optionally matching patch groups. // A no-op (returns empty list) for an empty matcher
// \returns an empty list for an empty matcher
labelList indices(const wordRes& matcher, const bool useGroups) const; labelList indices(const wordRes& matcher, const bool useGroups) const;
//- The (sorted) patch indices: logic as per Foam::wordRes::filter, //- Return (sorted) patch indices for all selected matches that
//- optionally matching patch groups. //- are not ignored.
// //- The selection logic as per Foam::wordRes::filter.
// An empty \em allow accepts everything not in \em deny. // Optionally matches patch groups.
// A literal \em allow match has higher priority than any \em deny. // A no-op (returns empty list) for an empty select matcher
// A regex \em allow match has lower priority than any \em deny.
//
// \returns identity list when allow/deny are both empty.
labelList indices labelList indices
( (
const wordRes& allow, const wordRes& select,
const wordRes& deny, const wordRes& ignore,
const bool useGroups //!< Match patch groups const bool useGroups
) const; ) const;
//- Find patch index given a name //- Find patch index given a name

View File

@ -40,6 +40,96 @@ namespace Foam
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<>
void Foam::mapDistribute::transform::operator()
(
const vectorTensorTransform&,
const bool,
List<label>&
) const {}
template<>
void Foam::mapDistribute::transform::operator()
(
const coupledPolyPatch&,
UList<label>&
) const {}
template<>
void Foam::mapDistribute::transform::operator()
(
const coupledPolyPatch&,
Map<label>&
) const {}
template<>
void Foam::mapDistribute::transform::operator()
(
const coupledPolyPatch&,
EdgeMap<label>&
) const {}
template<>
void Foam::mapDistribute::transform::operator()
(
const vectorTensorTransform&,
const bool,
List<scalar>&
) const {}
template<>
void Foam::mapDistribute::transform::operator()
(
const coupledPolyPatch&,
UList<scalar>&
) const {}
template<>
void Foam::mapDistribute::transform::operator()
(
const coupledPolyPatch&,
Map<scalar>&
) const {}
template<>
void Foam::mapDistribute::transform::operator()
(
const coupledPolyPatch&,
EdgeMap<scalar>&
) const {}
template<>
void Foam::mapDistribute::transform::operator()
(
const vectorTensorTransform&,
const bool,
List<bool>&
) const {}
template<>
void Foam::mapDistribute::transform::operator()
(
const coupledPolyPatch&,
UList<bool>&
) const {}
template<>
void Foam::mapDistribute::transform::operator()
(
const coupledPolyPatch&,
Map<bool>&
) const {}
template<>
void Foam::mapDistribute::transform::operator()
(
const coupledPolyPatch&,
EdgeMap<bool>&
) const {}
void Foam::mapDistribute::printLayout(Ostream& os) const void Foam::mapDistribute::printLayout(Ostream& os) const
{ {
mapDistributeBase::printLayout(os); mapDistributeBase::printLayout(os);

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2015-2025 OpenCFD Ltd. Copyright (C) 2015-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -176,25 +176,25 @@ class mapDistribute
//- Helper function: copy transformElements without transformation //- Helper function: copy transformElements without transformation
template<class T> template<class T>
void applyDummyTransforms(UList<T>& field) const; void applyDummyTransforms(List<T>& field) const;
template<class T, class TransformOp> template<class T, class TransformOp>
void applyTransforms void applyTransforms
( (
const globalIndexAndTransform& globalTransforms, const globalIndexAndTransform& globalTransforms,
UList<T>& field, List<T>& field,
const TransformOp& top const TransformOp& top
) const; ) const;
//- Helper function: copy transformElements without transformation //- Helper function: copy transformElements without transformation
template<class T> template<class T>
void applyDummyInverseTransforms(UList<T>& field) const; void applyDummyInverseTransforms(List<T>& field) const;
template<class T, class TransformOp> template<class T, class TransformOp>
void applyInverseTransforms void applyInverseTransforms
( (
const globalIndexAndTransform& globalTransforms, const globalIndexAndTransform& globalTransforms,
UList<T>& field, List<T>& field,
const TransformOp& top const TransformOp& top
) const; ) const;
@ -219,14 +219,11 @@ public:
( (
const vectorTensorTransform& vt, const vectorTensorTransform& vt,
const bool forward, const bool forward,
UList<Type>& fld List<Type>& fld
) const ) const
{ {
if constexpr (is_rotational_vectorspace_v<Type>) const tensor T(forward ? vt.R() : vt.R().T());
{ transformList(T, fld);
const tensor rot(forward ? vt.R() : vt.R().T());
transformList(rot, fld);
}
} }
template<class Type> template<class Type>
@ -237,13 +234,9 @@ public:
List<List<Type>>& flds List<List<Type>>& flds
) const ) const
{ {
if constexpr (is_rotational_vectorspace_v<Type>) for (List<Type>& fld : flds)
{ {
const tensor rot(forward ? vt.R() : vt.R().T()); operator()(vt, forward, fld);
for (auto& fld : flds)
{
transformList(rot, fld);
}
} }
} }
@ -251,12 +244,9 @@ public:
template<class Type> template<class Type>
void operator()(const coupledPolyPatch& cpp, UList<Type>& fld) const void operator()(const coupledPolyPatch& cpp, UList<Type>& fld) const
{ {
if constexpr (is_rotational_vectorspace_v<Type>) if (!cpp.parallel())
{ {
if (!cpp.parallel()) transformList(cpp.forwardT(), fld);
{
transformList(cpp.forwardT(), fld);
}
} }
} }
@ -265,12 +255,9 @@ public:
void operator()(const coupledPolyPatch& cpp, Container<Type>& map) void operator()(const coupledPolyPatch& cpp, Container<Type>& map)
const const
{ {
if constexpr (is_rotational_vectorspace_v<Type>) if (!cpp.parallel())
{ {
if (!cpp.parallel()) transformList(cpp.forwardT(), map);
{
transformList(cpp.forwardT(), map);
}
} }
} }
}; };
@ -284,16 +271,17 @@ public:
( (
const vectorTensorTransform& vt, const vectorTensorTransform& vt,
const bool forward, const bool forward,
UList<point>& fld List<point>& fld
) const ) const
{ {
pointField pfld(std::move(fld));
if (forward) if (forward)
{ {
vt.transformPositionList(fld); fld = vt.transformPosition(pfld);
} }
else else
{ {
vt.invTransformPositionList(fld); fld = vt.invTransformPosition(pfld);
} }
} }
@ -304,19 +292,9 @@ public:
List<List<point>>& flds List<List<point>>& flds
) const ) const
{ {
if (forward) for (List<point>& fld : flds)
{ {
for (auto& fld : flds) operator()(vt, forward, fld);
{
vt.transformPositionList(fld);
}
}
else
{
for (auto& fld : flds)
{
vt.invTransformPositionList(fld);
}
} }
} }
@ -704,6 +682,86 @@ public:
}; };
// Template specialisation for primitives that do not need transform
template<>
void mapDistribute::transform::operator()
(
const vectorTensorTransform&,
const bool,
List<label>&
) const;
template<>
void mapDistribute::transform::operator()
(
const coupledPolyPatch&,
UList<label>&
) const;
template<>
void mapDistribute::transform::operator()
(
const coupledPolyPatch&,
Map<label>&
) const;
template<>
void mapDistribute::transform::operator()
(
const coupledPolyPatch&,
EdgeMap<label>&
) const;
template<>
void mapDistribute::transform::operator()
(
const coupledPolyPatch&,
UList<scalar>&
) const;
template<>
void mapDistribute::transform::operator()
(
const vectorTensorTransform&,
const bool,
List<scalar>&
) const;
template<>
void mapDistribute::transform::operator()
(
const coupledPolyPatch&,
Map<scalar>&
) const;
template<>
void mapDistribute::transform::operator()
(
const coupledPolyPatch&,
EdgeMap<scalar>&
) const;
template<>
void mapDistribute::transform::operator()
(
const coupledPolyPatch& cpp,
UList<bool>& fld
) const;
template<>
void mapDistribute::transform::operator()
(
const vectorTensorTransform&,
const bool,
List<bool>&
) const;
template<>
void mapDistribute::transform::operator()
(
const coupledPolyPatch&,
Map<bool>&
) const;
template<>
void mapDistribute::transform::operator()
(
const coupledPolyPatch&,
EdgeMap<bool>&
) const;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam } // End namespace Foam

View File

@ -235,7 +235,7 @@ protected:
static void flipAndCombine static void flipAndCombine
( (
//! [in,out] The left of binary combine operation //! [in,out] The left of binary combine operation
UList<T>& lhs, List<T>& lhs,
//! The right of binary combine operation //! The right of binary combine operation
const UList<T>& rhs, const UList<T>& rhs,
//! The mapping indices //! The mapping indices
@ -254,8 +254,8 @@ protected:
static void accessAndFlip static void accessAndFlip
( (
//! [out] The result values //! [out] The result values
UList<T>& output, List<T>& output,
//! The input values //! [out] The input values
const UList<T>& values, const UList<T>& values,
//! The mapping indices //! The mapping indices
const labelUList& map, const labelUList& map,
@ -270,7 +270,7 @@ protected:
template<class T, class NegateOp> template<class T, class NegateOp>
static List<T> accessAndFlip static List<T> accessAndFlip
( (
//! The input values //! [out] The input values
const UList<T>& values, const UList<T>& values,
//! The mapping indices //! The mapping indices
const labelUList& map, const labelUList& map,
@ -895,7 +895,7 @@ public:
static void distribute static void distribute
( (
const UPstream::commsTypes commsType, const UPstream::commsTypes commsType,
const UList<labelPair>& schedule, const List<labelPair>& schedule,
const label constructSize, const label constructSize,
const labelListList& subMap, const labelListList& subMap,
const bool subHasFlip, const bool subHasFlip,
@ -918,7 +918,7 @@ public:
static void distribute static void distribute
( (
const UPstream::commsTypes commsType, const UPstream::commsTypes commsType,
const UList<labelPair>& schedule, const List<labelPair>& schedule,
const label constructSize, const label constructSize,
const labelListList& subMap, const labelListList& subMap,
const bool subHasFlip, const bool subHasFlip,
@ -1078,7 +1078,7 @@ public:
//- Do all sends using PstreamBuffers //- Do all sends using PstreamBuffers
template<class T> template<class T>
void send(PstreamBuffers& pBufs, const UList<T>& field) const; void send(PstreamBuffers& pBufs, const List<T>& field) const;
//- Do all receives using PstreamBuffers //- Do all receives using PstreamBuffers
template<class T> template<class T>

View File

@ -35,7 +35,7 @@ License
template<class T, class CombineOp, class NegateOp> template<class T, class CombineOp, class NegateOp>
void Foam::mapDistributeBase::flipAndCombine void Foam::mapDistributeBase::flipAndCombine
( (
UList<T>& lhs, List<T>& lhs,
const UList<T>& rhs, const UList<T>& rhs,
const labelUList& map, const labelUList& map,
@ -46,9 +46,6 @@ void Foam::mapDistributeBase::flipAndCombine
{ {
const label len = map.size(); const label len = map.size();
// FULLDEBUG: if (lhs.size() < max(map)) FatalError ...;
// FULLDEBUG: if (rhs.size() < len) FatalError ...;
if (hasFlip) if (hasFlip)
{ {
for (label i = 0; i < len; ++i) for (label i = 0; i < len; ++i)
@ -85,7 +82,7 @@ void Foam::mapDistributeBase::flipAndCombine
template<class T, class NegateOp> template<class T, class NegateOp>
void Foam::mapDistributeBase::accessAndFlip void Foam::mapDistributeBase::accessAndFlip
( (
UList<T>& output, List<T>& output,
const UList<T>& values, const UList<T>& values,
const labelUList& map, const labelUList& map,
const bool hasFlip, const bool hasFlip,
@ -94,7 +91,6 @@ void Foam::mapDistributeBase::accessAndFlip
{ {
const label len = map.size(); const label len = map.size();
// FULLDEBUG: if (values.size() < max(map)) FatalError ...;
// FULLDEBUG: if (output.size() < len) FatalError ...; // FULLDEBUG: if (output.size() < len) FatalError ...;
if (hasFlip) if (hasFlip)
@ -451,7 +447,7 @@ template<class T, class CombineOp, class NegateOp>
void Foam::mapDistributeBase::distribute void Foam::mapDistributeBase::distribute
( (
const UPstream::commsTypes commsType, const UPstream::commsTypes commsType,
const UList<labelPair>& schedule, const List<labelPair>& schedule,
const label constructSize, const label constructSize,
const labelListList& subMap, const labelListList& subMap,
const bool subHasFlip, const bool subHasFlip,
@ -898,7 +894,7 @@ template<class T, class NegateOp>
void Foam::mapDistributeBase::distribute void Foam::mapDistributeBase::distribute
( (
const UPstream::commsTypes commsType, const UPstream::commsTypes commsType,
const UList<labelPair>& schedule, const List<labelPair>& schedule,
const label constructSize, const label constructSize,
const labelListList& subMap, const labelListList& subMap,
const bool subHasFlip, const bool subHasFlip,
@ -1336,7 +1332,7 @@ template<class T>
void Foam::mapDistributeBase::send void Foam::mapDistributeBase::send
( (
PstreamBuffers& pBufs, PstreamBuffers& pBufs,
const UList<T>& field const List<T>& field
) const ) const
{ {
// Stream data into buffer // Stream data into buffer
@ -1486,11 +1482,13 @@ void Foam::mapDistributeBase::distribute
const int tag const int tag
) const ) const
{ {
List<T> work(std::move(values)); values.shrink();
distribute(commsType, work, tag); List<T>& list = static_cast<List<T>&>(values);
values = std::move(work); distribute(commsType, list, tag);
values.setCapacity(list.size());
} }

View File

@ -35,7 +35,7 @@ License
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class T> template<class T>
void Foam::mapDistribute::applyDummyTransforms(UList<T>& field) const void Foam::mapDistribute::applyDummyTransforms(List<T>& field) const
{ {
forAll(transformElements_, trafoI) forAll(transformElements_, trafoI)
{ {
@ -51,7 +51,7 @@ void Foam::mapDistribute::applyDummyTransforms(UList<T>& field) const
template<class T> template<class T>
void Foam::mapDistribute::applyDummyInverseTransforms(UList<T>& field) const void Foam::mapDistribute::applyDummyInverseTransforms(List<T>& field) const
{ {
forAll(transformElements_, trafoI) forAll(transformElements_, trafoI)
{ {
@ -70,7 +70,7 @@ template<class T, class TransformOp> //, class CombineOp>
void Foam::mapDistribute::applyTransforms void Foam::mapDistribute::applyTransforms
( (
const globalIndexAndTransform& globalTransforms, const globalIndexAndTransform& globalTransforms,
UList<T>& field, List<T>& field,
const TransformOp& top const TransformOp& top
) const ) const
{ {
@ -100,7 +100,7 @@ template<class T, class TransformOp> //, class CombineOp>
void Foam::mapDistribute::applyInverseTransforms void Foam::mapDistribute::applyInverseTransforms
( (
const globalIndexAndTransform& globalTransforms, const globalIndexAndTransform& globalTransforms,
UList<T>& field, List<T>& field,
const TransformOp& top const TransformOp& top
) const ) const
{ {
@ -193,11 +193,13 @@ void Foam::mapDistribute::distribute
const int tag const int tag
) const ) const
{ {
List<T> work(std::move(fld)); fld.shrink();
distribute(commsType, work, dummyTransform, tag); List<T>& list = static_cast<List<T>&>(fld);
fld = std::move(work); distribute(commsType, list, dummyTransform, tag);
fld.setCapacity(list.size());
} }

View File

@ -93,11 +93,7 @@ void Foam::polyBoundaryMesh::calcGroupIDs() const
// Remove groups that clash with patch names // Remove groups that clash with patch names
forAll(patches, patchi) forAll(patches, patchi)
{ {
if (groupLookup.empty()) if (groupLookup.erase(patches[patchi].name()))
{
break; // Early termination
}
else if (groupLookup.erase(patches[patchi].name()))
{ {
WarningInFunction WarningInFunction
<< "Removed group '" << patches[patchi].name() << "Removed group '" << patches[patchi].name()
@ -786,7 +782,7 @@ Foam::labelList Foam::polyBoundaryMesh::indices
// Only check groups if requested and they exist // Only check groups if requested and they exist
const bool checkGroups = (useGroups && this->hasGroupIDs()); const bool checkGroups = (useGroups && this->hasGroupIDs());
labelHashSet ids; labelHashSet ids(0);
if (matcher.isPattern()) if (matcher.isPattern())
{ {
@ -854,7 +850,7 @@ Foam::labelList Foam::polyBoundaryMesh::indices
return this->indices(matcher.front(), useGroups); return this->indices(matcher.front(), useGroups);
} }
labelHashSet ids; labelHashSet ids(0);
// Only check groups if requested and they exist // Only check groups if requested and they exist
if (useGroups && this->hasGroupIDs()) if (useGroups && this->hasGroupIDs())
@ -887,20 +883,19 @@ Foam::labelList Foam::polyBoundaryMesh::indices
Foam::labelList Foam::polyBoundaryMesh::indices Foam::labelList Foam::polyBoundaryMesh::indices
( (
const wordRes& allow, const wordRes& select,
const wordRes& deny, const wordRes& ignore,
const bool useGroups const bool useGroups
) const ) const
{ {
if (allow.empty() && deny.empty()) if (ignore.empty())
{ {
// Fast-path: select all return this->indices(select, useGroups);
return identity(this->size());
} }
const wordRes::filter matcher(allow, deny); const wordRes::filter matcher(select, ignore);
labelHashSet ids; labelHashSet ids(0);
// Only check groups if requested and they exist // Only check groups if requested and they exist
if (useGroups && this->hasGroupIDs()) if (useGroups && this->hasGroupIDs())
@ -1074,7 +1069,7 @@ Foam::labelHashSet Foam::polyBoundaryMesh::patchSet
const bool useGroups const bool useGroups
) const ) const
{ {
labelHashSet ids; labelHashSet ids(0);
if (select.empty()) if (select.empty())
{ {
return ids; return ids;

View File

@ -28,9 +28,8 @@ Class
Foam::polyBoundaryMesh Foam::polyBoundaryMesh
Description Description
A polyBoundaryMesh is a polyPatch list with registered IO, A polyBoundaryMesh is a polyPatch list with additional search methods
a reference to the associated polyMesh, and registered IO.
with additional search methods etc.
SourceFiles SourceFiles
polyBoundaryMesh.C polyBoundaryMesh.C
@ -260,37 +259,34 @@ public:
labelRange range(const label patchi) const; labelRange range(const label patchi) const;
//- The (sorted) patch indices for all matches, //- Return (sorted) patch indices for all matches.
//- optionally matching patch groups. // Optionally matches patch groups.
// \returns an empty list for an empty matcher // A no-op (returns empty list) for an empty matcher
labelList indices labelList indices
( (
const wordRe& matcher, const wordRe& matcher,
const bool useGroups = true const bool useGroups = true
) const; ) const;
//- The (sorted) patch indices for all matches, //- Return (sorted) patch indices for all matches.
//- optionally matching patch groups. // Optionally matches patch groups.
// \returns an empty list for an empty matcher // A no-op (returns empty list) for an empty matcher
labelList indices labelList indices
( (
const wordRes& matcher, const wordRes& matcher,
const bool useGroups = true //!< Match patch groups const bool useGroups = true
) const; ) const;
//- The (sorted) patch indices: logic as per Foam::wordRes::filter, //- Return (sorted) patch indices for all selected matches that
//- optionally matching patch groups. //- are not ignored.
// //- The selection logic as per Foam::wordRes::filter.
// An empty \em allow accepts everything not in \em deny. // Optionally matches patch groups.
// A literal \em allow match has higher priority than any \em deny. // A no-op (returns empty list) for an empty select matcher
// A regex \em allow match has lower priority than any \em deny.
//
// \returns identity list when allow/deny are both empty.
labelList indices labelList indices
( (
const wordRes& allow, const wordRes& select,
const wordRes& deny, const wordRes& ignore,
const bool useGroups = true //!< Match patch groups const bool useGroups = true
) const; ) const;
//- Return (sorted) patch indices for patches that match the //- Return (sorted) patch indices for patches that match the

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2020-2025 OpenCFD Ltd. Copyright (C) 2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -47,27 +47,17 @@ namespace Foam
class dummyTransform class dummyTransform
{ {
public: public:
template<class T> template<class T>
void operator() void operator()
( (
const vectorTensorTransform& vt, const vectorTensorTransform& vt,
const bool forward, const bool forward,
UList<T>& fld List<T>& fld
) const
{}
template<class Type>
void operator()
(
const vectorTensorTransform& vt,
const bool forward,
List<List<Type>>& flds
) const ) const
{} {}
template<class T> template<class T>
void operator()(const coupledPolyPatch& cpp, UList<T>& fld) const void operator()(const coupledPolyPatch& cpp, Field<T>& fld) const
{} {}
template<class T, template<class> class Container> template<class T, template<class> class Container>

View File

@ -1135,7 +1135,11 @@ void Foam::syncTools::syncBoundaryFaceList
pp.start()-boundaryOffset pp.start()-boundaryOffset
); );
top(procPatch, recvFld); auto& fakeList = const_cast<List<T>&>
(
static_cast<const List<T>&>(recvFld)
);
top(procPatch, fakeList);
SubList<T> patchValues SubList<T> patchValues
( (

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2025 OpenCFD Ltd. Copyright (C) 2016-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -205,11 +205,7 @@ void Foam::ZoneMesh<ZoneType, MeshType>::calcGroupIDs() const
// Remove groups that clash with zone names // Remove groups that clash with zone names
forAll(zones, zonei) forAll(zones, zonei)
{ {
if (groupLookup.empty()) if (groupLookup.erase(zones[zonei].name()))
{
break; // Early termination
}
else if (groupLookup.erase(zones[zonei].name()))
{ {
WarningInFunction WarningInFunction
<< "Removed group '" << zones[zonei].name() << "Removed group '" << zones[zonei].name()
@ -545,7 +541,7 @@ Foam::labelList Foam::ZoneMesh<ZoneType, MeshType>::indices
// Only check groups if requested and they exist // Only check groups if requested and they exist
const bool checkGroups = (useGroups && this->hasGroupIDs()); const bool checkGroups = (useGroups && this->hasGroupIDs());
labelHashSet ids; labelHashSet ids(0);
if (checkGroups) if (checkGroups)
{ {
@ -561,7 +557,7 @@ Foam::labelList Foam::ZoneMesh<ZoneType, MeshType>::indices
{ {
if (matcher(iter.key())) if (matcher(iter.key()))
{ {
// Add ids associated with the group // Hash ids associated with the group
ids.insert(iter.val()); ids.insert(iter.val());
} }
} }
@ -593,7 +589,7 @@ Foam::labelList Foam::ZoneMesh<ZoneType, MeshType>::indices
if (iter.good()) if (iter.good())
{ {
// Add ids associated with the group // Hash ids associated with the group
ids.insert(iter.val()); ids.insert(iter.val());
} }
} }
@ -619,7 +615,7 @@ Foam::labelList Foam::ZoneMesh<ZoneType, MeshType>::indices
return this->indices(matcher.front(), useGroups); return this->indices(matcher.front(), useGroups);
} }
labelHashSet ids; labelHashSet ids(0);
// Only check groups if requested and they exist // Only check groups if requested and they exist
if (useGroups && this->hasGroupIDs()) if (useGroups && this->hasGroupIDs())
@ -631,7 +627,7 @@ Foam::labelList Foam::ZoneMesh<ZoneType, MeshType>::indices
{ {
if (matcher(iter.key())) if (matcher(iter.key()))
{ {
// Add ids associated with the group // Hash the ids associated with the group
ids.insert(iter.val()); ids.insert(iter.val());
} }
} }
@ -653,20 +649,19 @@ Foam::labelList Foam::ZoneMesh<ZoneType, MeshType>::indices
template<class ZoneType, class MeshType> template<class ZoneType, class MeshType>
Foam::labelList Foam::ZoneMesh<ZoneType, MeshType>::indices Foam::labelList Foam::ZoneMesh<ZoneType, MeshType>::indices
( (
const wordRes& allow, const wordRes& select,
const wordRes& deny, const wordRes& ignore,
const bool useGroups const bool useGroups
) const ) const
{ {
if (allow.empty() && deny.empty()) if (ignore.empty())
{ {
// Fast-path: select all return this->indices(select, useGroups);
return identity(this->size());
} }
const wordRes::filter matcher(allow, deny); const wordRes::filter matcher(select, ignore);
labelHashSet ids; labelHashSet ids(0);
// Only check groups if requested and they exist // Only check groups if requested and they exist
if (useGroups && this->hasGroupIDs()) if (useGroups && this->hasGroupIDs())
@ -678,7 +673,7 @@ Foam::labelList Foam::ZoneMesh<ZoneType, MeshType>::indices
{ {
if (matcher(iter.key())) if (matcher(iter.key()))
{ {
// Add ids associated with the group // Add patch ids associated with the group
ids.insert(iter.val()); ids.insert(iter.val());
} }
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2025 OpenCFD Ltd. Copyright (C) 2016-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -227,37 +227,34 @@ public:
wordList sortedNames(const wordRes& matcher) const; wordList sortedNames(const wordRes& matcher) const;
//- The (sorted) patch indices for all matches, //- Return (sorted) zone indices for all matches
//- optionally matching zone groups. // Optionally matches zone groups.
// \returns an empty list for an empty matcher // A no-op (returns empty list) for an empty matcher
labelList indices labelList indices
( (
const wordRe& matcher, const wordRe& matcher,
const bool useGroups = true const bool useGroups = true
) const; ) const;
//- The (sorted) patch indices for all matches, //- Return (sorted) zone indices for all matches
//- optionally matching zone groups. // Optionally matches zone groups.
// \returns an empty list for an empty matcher // A no-op (returns empty list) for an empty matcher
labelList indices labelList indices
( (
const wordRes& matcher, const wordRes& matcher,
const bool useGroups = true const bool useGroups = true
) const; ) const;
//- The (sorted) patch indices: logic as per Foam::wordRes::filter, //- Return (sorted) zone indices for all selected matches that
//- optionally matching zone groups. //- are not ignored.
// //- The selection logic as per Foam::wordRes::filter.
// An empty \em allow accepts everything not in \em deny. // Optionally matches patch groups.
// A literal \em allow match has higher priority than any \em deny. // A no-op (returns empty list) for an empty select matcher
// A regex \em allow match has lower priority than any \em deny.
//
// \returns identity list when allow/deny are both empty.
labelList indices labelList indices
( (
const wordRes& allow, const wordRes& select,
const wordRes& deny, const wordRes& ignore,
const bool useGroups = true //!< Match zone groups const bool useGroups = true
) const; ) const;
//- Zone index for the first match, return -1 if not found //- Zone index for the first match, return -1 if not found

View File

@ -6,7 +6,6 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -61,13 +60,6 @@ Foam::vectorTensorTransform::vectorTensorTransform(Istream& is)
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::vectorTensorTransform::checkRotation(const scalar tol)
{
// Detect identity and zero rotations
hasR_ = !(R_.is_identity(tol) || Foam::mag(R_) < tol);
}
Foam::word Foam::name(const vectorTensorTransform& s) Foam::word Foam::name(const vectorTensorTransform& s)
{ {
OStringStream buf; OStringStream buf;
@ -78,6 +70,32 @@ Foam::word Foam::name(const vectorTensorTransform& s)
} }
template<>
Foam::tmp<Foam::Field<bool>> Foam::vectorTensorTransform::transform
(
const Field<bool>& fld
) const
{
return fld;
}
template<>
Foam::tmp<Foam::Field<Foam::label>> Foam::vectorTensorTransform::transform
(
const Field<label>& fld
) const
{
return fld;
}
template<>
Foam::tmp<Foam::Field<Foam::scalar>> Foam::vectorTensorTransform::transform
(
const Field<scalar>& fld
) const
{
return fld;
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * // // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
Foam::Istream& Foam::operator>>(Istream& is, vectorTensorTransform& tr) Foam::Istream& Foam::operator>>(Istream& is, vectorTensorTransform& tr)

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2020-2025 OpenCFD Ltd. Copyright (C) 2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -34,12 +34,12 @@ Description
SourceFiles SourceFiles
vectorTensorTransformI.H vectorTensorTransformI.H
vectorTensorTransform.C vectorTensorTransform.C
vectorTensorTransform.txx vectorTensorTransformTemplates.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef Foam_vectorTensorTransform_H #ifndef vectorTensorTransform_H
#define Foam_vectorTensorTransform_H #define vectorTensorTransform_H
#include "tensor.H" #include "tensor.H"
#include "word.H" #include "word.H"
@ -126,57 +126,39 @@ public:
// Member Functions // Member Functions
// Access // Access
//- True if it has a non-identity rotation tensor inline const vector& t() const;
bool hasR() const noexcept { return hasR_; }
//- The translation vector inline const tensor& R() const;
const vector& t() const noexcept { return t_; }
//- The (forward) rotation tensor inline bool hasR() const;
const tensor& R() const noexcept { return R_; }
// Edit // Edit
//- Non-const access to the translation vector inline vector& t();
vector& t() noexcept { return t_; }
//- Non-const access to the rotation tensor. Sets hasR = true inline tensor& R();
inline tensor& R() noexcept;
//- Test for identity rotation and set hasR accordingly
void checkRotation(const scalar tol = ROOTVSMALL);
// Transform // Transform
//- Transform the given position //- Transform the given position
inline vector transformPosition(const vector& v) const; inline vector transformPosition(const vector& v) const;
//- Transform the given field of points //- Transform the given pointField
inline pointField transformPosition(const pointField& pts) const; inline pointField transformPosition(const pointField& pts) const;
//- Inplace transform the given points //- Inverse transform the given position
inline void transformPositionList(UList<point>& pts) const; inline vector invTransformPosition(const vector& v) const;
//- Inverse transform the given position //- Inverse transform the given pointField
inline vector invTransformPosition(const vector& v) const; inline pointField invTransformPosition(const pointField& pts) const;
//- Inverse transform the given field of points //- Transform the given field
inline pointField invTransformPosition(const pointField& pts) const; template<class Type>
tmp<Field<Type>> transform(const Field<Type>&) const;
//- Inplace inverse transform the given points
inline void invTransformPositionList(UList<point>& pts) const;
//- Transform the given field
template<class Type>
tmp<Field<Type>> transform(const Field<Type>& fld) const;
//- Inplace transform the given field
template<class Type>
void transformList(UList<Type>& fld) const;
// Member Operators // Member Operators
@ -214,6 +196,18 @@ inline vectorTensorTransform inv(const vectorTensorTransform& tr);
//- Return a string representation of a vectorTensorTransform //- Return a string representation of a vectorTensorTransform
word name(const vectorTensorTransform&); word name(const vectorTensorTransform&);
//- Template specialisations
template<>
tmp<Field<bool>> vectorTensorTransform::transform(const Field<bool>&) const;
template<>
tmp<Field<label>> vectorTensorTransform::transform(const Field<label>&) const;
template<>
tmp<Field<scalar>> vectorTensorTransform::transform(const Field<scalar>&)
const;
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
inline bool operator== inline bool operator==
@ -268,7 +262,7 @@ inline vectorTensorTransform operator&
#include "vectorTensorTransformI.H" #include "vectorTensorTransformI.H"
#ifdef NoRepository #ifdef NoRepository
#include "vectorTensorTransform.txx" #include "vectorTensorTransformTemplates.C"
#endif #endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -6,7 +6,6 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -67,10 +66,35 @@ inline Foam::vectorTensorTransform::vectorTensorTransform(const tensor& R)
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline Foam::tensor& Foam::vectorTensorTransform::R() noexcept inline const Foam::vector& Foam::vectorTensorTransform::t() const
{
return t_;
}
inline const Foam::tensor& Foam::vectorTensorTransform::R() const
{
return R_;
}
inline bool Foam::vectorTensorTransform::hasR() const
{
return hasR_;
}
inline Foam::vector& Foam::vectorTensorTransform::t()
{
return t_;
}
inline Foam::tensor& Foam::vectorTensorTransform::R()
{ {
// Assume that non-const access to R changes it from I, so set // Assume that non-const access to R changes it from I, so set
// hasR to true // hasR to true
hasR_ = true; hasR_ = true;
return R_; return R_;
@ -112,28 +136,6 @@ inline Foam::pointField Foam::vectorTensorTransform::transformPosition
} }
inline void Foam::vectorTensorTransform::transformPositionList
(
UList<point>& pts
) const
{
if (hasR_)
{
for (auto& p : pts)
{
p = t() + (R() & p);
}
}
else
{
for (auto& p : pts)
{
p += t();
}
}
}
inline Foam::vector Foam::vectorTensorTransform::invTransformPosition inline Foam::vector Foam::vectorTensorTransform::invTransformPosition
( (
const vector& v const vector& v
@ -169,30 +171,6 @@ inline Foam::pointField Foam::vectorTensorTransform::invTransformPosition
} }
inline void Foam::vectorTensorTransform::invTransformPositionList
(
UList<point>& pts
) const
{
if (hasR_)
{
const auto rot = R().T();
for (auto& p : pts)
{
p = (rot & (p - t()));
}
}
else
{
for (auto& p : pts)
{
p -= t();
}
}
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
inline void Foam::vectorTensorTransform::operator&= inline void Foam::vectorTensorTransform::operator&=

View File

@ -6,7 +6,6 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -34,16 +33,9 @@ Foam::tmp<Foam::Field<Type>> Foam::vectorTensorTransform::transform
const Field<Type>& fld const Field<Type>& fld
) const ) const
{ {
if constexpr (is_rotational_vectorspace_v<Type>) if (hasR_)
{ {
if (hasR_) return R() & fld;
{
return (R() & fld);
}
else
{
return fld;
}
} }
else else
{ {
@ -52,23 +44,4 @@ Foam::tmp<Foam::Field<Type>> Foam::vectorTensorTransform::transform
} }
template<class Type>
void Foam::vectorTensorTransform::transformList
(
UList<Type>& fld
) const
{
if constexpr (is_rotational_vectorspace_v<Type>)
{
if (hasR_)
{
for (auto& val : fld)
{
val = (R() & val);
}
}
}
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -447,7 +447,7 @@ public:
inline constexpr IntType operator- inline constexpr IntType operator-
( (
const const_reverse_iterator& iter const const_reverse_iterator& iter
) const noexcept; )const noexcept;
// Comparison // Comparison

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2025 OpenCFD Ltd. Copyright (C) 2017-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -370,12 +370,12 @@ labelList findMatching
AccessOp aop = identityOp() AccessOp aop = identityOp()
); );
//- Return ids for items with matching names, //- Return ids for items with matching names.
//- using a combination of allow and deny lists as per wordRes::filter // Uses a combination of allow and deny lists
// //
// An empty \em allow accepts everything not in \em deny. // An empty 'allow' accepts everything not in 'deny'.
// A literal \em allow match has higher priority than any \em deny. // A literal 'allow' match has higher priority than any 'deny'.
// A regex \em allow match has lower priority than any \em deny. // A regex 'allow' match has lower priority than any 'deny'.
// //
// Example (when applied to a list of words), // Example (when applied to a list of words),
// \verbatim // \verbatim
@ -386,7 +386,7 @@ labelList findMatching
// result: (abc other val val1 wall1 wall2) // result: (abc other val val1 wall1 wall2)
// \endverbatim // \endverbatim
// //
// \returns identity list when allow/deny are both empty. // \return List indices for matches
template<class StringListType, class AccessOp = identityOp> template<class StringListType, class AccessOp = identityOp>
labelList findMatching labelList findMatching
( (

View File

@ -143,7 +143,7 @@ Foam::labelList Foam::stringListOps::findMatching
if (pred.empty()) if (pred.empty())
{ {
// Fast-path: select all // Accept all
return identity(len); return identity(len);
} }
@ -177,10 +177,11 @@ Foam::labelList Foam::stringListOps::findMatching
{ {
if (allow.empty() && deny.empty()) if (allow.empty() && deny.empty())
{ {
// Fast-path: select all // Accept all
return identity(input.size()); return identity(input.size());
} }
// Use combined accept/reject filter
const wordRes::filter pred(allow, deny); const wordRes::filter pred(allow, deny);
return stringListOps::findMatching(input, pred, aop); return stringListOps::findMatching(input, pred, aop);

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016-2025 OpenCFD Ltd. Copyright (C) 2016-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -99,10 +99,7 @@ public:
// No distinction made between literals and regular expressions. // No distinction made between literals and regular expressions.
static wordRes uniq(const UList<wordRe>& input); static wordRes uniq(const UList<wordRe>& input);
//- Test for a match of any selectors against the text. //- Test for a match
//
// \return \c false if no selectors are specified
// \return \c true if text matches \em any of the selectors
inline static bool match inline static bool match
( (
const UList<wordRe>& selectors, const UList<wordRe>& selectors,
@ -200,10 +197,9 @@ public:
//- No selectors defined //- No selectors defined
inline bool empty() const noexcept; inline bool empty() const noexcept;
//- Apply matcher predicate //- True if text matches ANY of the selectors.
// //- Always false if entries are empty.
// \return \c false if no selectors are specified // Allows use as a predicate.
// \return \c true if text matches \em any of the selectors
inline bool operator()(const std::string& text) const; inline bool operator()(const std::string& text) const;
private: private:
@ -213,10 +209,9 @@ public:
//- Functor wrapper of allow/deny lists of wordRe for filtering //- Functor wrapper of allow/deny lists of wordRe for filtering
// //
// An empty filter accepts everything. // An empty 'allow' accepts everything not in 'deny'.
// An empty \em allow accepts everything not in \em deny. // A literal 'allow' match has higher priority than any 'deny'.
// A literal \em allow match has higher priority than any \em deny. // A regex 'allow' match has lower priority than any 'deny'.
// A regex \em allow match has lower priority than any \em deny.
// //
// Example (when applied to a list of words), // Example (when applied to a list of words),
// \verbatim // \verbatim
@ -228,23 +223,17 @@ public:
// \endverbatim // \endverbatim
struct filter struct filter
{ {
//- Construct with \em allow and \em deny matchers //- Construct with 'allow' and 'deny' matchers
inline filter inline filter
( (
const UList<wordRe>& allow, const UList<wordRe>& allow,
const UList<wordRe>& deny const UList<wordRe>& deny
) noexcept; ) noexcept;
//- No filtering defined //- Nothing defined
inline bool empty() const noexcept; inline bool empty() const noexcept;
//- True if filtering is defined //- True if matched but not blocked
explicit operator bool() const noexcept { return !empty(); }
//- Apply filter against specified text
//
// \return \c true if no filtering has been defined
// \return \c true if matched but not blocked
inline bool operator()(const std::string& text) const; inline bool operator()(const std::string& text) const;
private: private:

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017-2025 OpenCFD Ltd. Copyright (C) 2017-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -225,7 +225,6 @@ inline bool Foam::wordRes::matcher::empty() const noexcept
return select_.empty(); return select_.empty();
} }
inline bool Foam::wordRes::filter::empty() const noexcept inline bool Foam::wordRes::filter::empty() const noexcept
{ {
return (allow_.empty() && deny_.empty()); return (allow_.empty() && deny_.empty());
@ -242,14 +241,12 @@ inline bool Foam::wordRes::filter::operator()(const std::string& text) const
{ {
if (allow_.empty()) if (allow_.empty())
{ {
// Did not specify allow // No allow specified, so accept everything that is NOT blocked
// => accept everything that is NOT blocked
return (deny_.empty() || !wordRes::match(deny_, text)); return (deny_.empty() || !wordRes::match(deny_, text));
} }
else if (deny_.empty()) else if (deny_.empty())
{ {
// Specified allow but did not specify blocked // Nothing blocked, apply accept filter
// => select with accept filter
return wordRes::match(allow_, text); return wordRes::match(allow_, text);
} }
else else

View File

@ -1401,31 +1401,7 @@ Foam::UPstream::probeMessage
int flag = 0; int flag = 0;
MPI_Status status; MPI_Status status;
if (UPstream::commsTypes::nonBlocking == commsType) if (UPstream::commsTypes::buffered == commsType)
{
// Non-blocking
profilingPstream::beginTiming();
if
(
MPI_Iprobe
(
source,
tag,
PstreamGlobals::MPICommunicators_[communicator],
&flag,
&status
)
)
{
FatalErrorInFunction
<< "MPI_Iprobe returned with error"
<< Foam::abort(FatalError);
}
profilingPstream::addRequestTime();
}
else
{ {
// Blocking // Blocking
profilingPstream::beginTiming(); profilingPstream::beginTiming();
@ -1437,7 +1413,7 @@ Foam::UPstream::probeMessage
source, source,
tag, tag,
PstreamGlobals::MPICommunicators_[communicator], PstreamGlobals::MPICommunicators_[communicator],
&status &status
) )
) )
{ {
@ -1449,6 +1425,30 @@ Foam::UPstream::probeMessage
profilingPstream::addProbeTime(); profilingPstream::addProbeTime();
flag = 1; flag = 1;
} }
else
{
// Non-blocking
profilingPstream::beginTiming();
if
(
MPI_Iprobe
(
source,
tag,
PstreamGlobals::MPICommunicators_[communicator],
&flag,
&status
)
)
{
FatalErrorInFunction
<< "MPI_Iprobe returned with error"
<< Foam::abort(FatalError);
}
profilingPstream::addRequestTime();
}
if (flag) if (flag)
{ {

View File

@ -50,9 +50,10 @@ defineTypeNameAndDebug(removePoints, 0);
template<class T, template<class> class CombineOp> template<class T, template<class> class CombineOp>
class faceEqOp class faceEqOp
{ {
public: public:
void operator()(List<T>& x, const UList<T>& y) const void operator()(List<T>& x, const List<T>& y) const
{ {
if (y.size() > 0) if (y.size() > 0)
{ {

View File

@ -294,9 +294,9 @@ void Foam::tetDecomposer::splitBoundaryFaces
( (
mesh_, mesh_,
boundaryTris, boundaryTris,
[](faceList& result, const UList<face>& input) [](faceList& result, const faceList& input)
{ {
if (result.empty()) if (!result.size())
{ {
result = input; result = input;
} }
@ -307,9 +307,9 @@ void Foam::tetDecomposer::splitBoundaryFaces
( (
mesh_, mesh_,
boundaryQuads, boundaryQuads,
[](faceList& result, const UList<face>& input) [](faceList& result, const faceList& input)
{ {
if (result.empty()) if (!result.size())
{ {
result = input; result = input;
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2025 OpenCFD Ltd. Copyright (C) 2016-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -31,13 +31,36 @@ License
#include "polyMesh.H" #include "polyMesh.H"
#include "emptyPolyPatch.H" #include "emptyPolyPatch.H"
#include "processorPolyPatch.H" #include "processorPolyPatch.H"
#include "ListOps.H" #include "stringListOps.H" // For stringListOps::findMatching()
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
const Foam::label Foam::ensightMesh::internalZone = -1; const Foam::label Foam::ensightMesh::internalZone = -1;
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
// Patch names without processor patches
static wordList nonProcessorPatchNames(const polyBoundaryMesh& bmesh)
{
#ifdef FULLDEBUG
// Patches are output. Check that they are synced.
bmesh.checkParallelSync(true);
#endif
wordList patchNames(bmesh.names());
patchNames.resize(bmesh.nNonProcessor());
return patchNames;
}
} // End namespace Foam
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::ensightMesh::clear() void Foam::ensightMesh::clear()
@ -118,69 +141,63 @@ void Foam::ensightMesh::correct()
{ {
clear(); clear();
const auto& pbm = mesh_.boundaryMesh(); const wordRes& czMatcher = option().cellZoneSelection();
const wordRes& fzMatcher = option().faceZoneSelection();
// Selected patch indices // Possible cellZones
labelList patchIds; const wordList czNames =
(
if (option().useBoundaryMesh())
{
patchIds = pbm.indices
( (
option().useCellZones()
&& (!czMatcher.empty() || option().useInternalMesh())
)
? mesh_.cellZones().names()
: wordList()
);
const labelList czoneIds =
(
czMatcher.empty()
? identity(czNames.size()) // All
: czMatcher.matching(czNames) // Selected names
);
// Possible faceZones
const wordList fzNames =
(
option().useFaceZones()
? mesh_.faceZones().names()
: wordList()
);
const labelList fzoneIds =
(
fzMatcher.empty()
? identity(fzNames.size()) // All
: fzMatcher.matching(fzNames) // Selected names
);
// Possible patchNames
const wordList patchNames =
(
option().useBoundaryMesh()
? nonProcessorPatchNames(mesh_.boundaryMesh())
: wordList()
);
const labelList patchIds =
(
option().useBoundaryMesh()
? stringListOps::findMatching
(
patchNames,
option().patchSelection(), option().patchSelection(),
option().patchExclude() option().patchExclude()
); )
: labelList()
// Prune undesirable patches - empty and processor patches );
label count = 0;
for (const label patchi : patchIds)
{
const auto& pp = pbm[patchi];
if (isType<emptyPolyPatch>(pp))
{
continue;
}
else if (isA<processorPolyPatch>(pp))
{
break; // No processor patches
}
patchIds[count] = patchi;
++count;
}
patchIds.resize(count);
}
// Selection of cellZones
const auto& czMatcher = option().cellZoneSelection();
// Selected cell zone indices
labelList czoneIds;
if (option().useCellZones())
{
// Use allow/deny to have desired behaviour with empty selection
czoneIds = mesh_.cellZones().indices
(
option().cellZoneSelection(),
option().cellZoneExclude()
);
}
// Selected face zone indices
labelList fzoneIds;
if (option().useFaceZones())
{
// Use allow/deny to have desired behaviour with empty selection
fzoneIds = mesh_.faceZones().indices
(
option().faceZoneSelection(),
option().faceZoneExclude()
);
}
// Track which cells are in a zone or not // Track which cells are in a zone or not
@ -193,8 +210,8 @@ void Foam::ensightMesh::correct()
// cellZones first // cellZones first
for (const label zoneId : czoneIds) for (const label zoneId : czoneIds)
{ {
const auto& zn = mesh_.cellZones()[zoneId]; const word& zoneName = czNames[zoneId];
const auto& zoneName = zn.name(); const cellZone& zn = mesh_.cellZones()[zoneId];
if (returnReduceOr(!zn.empty())) if (returnReduceOr(!zn.empty()))
{ {
@ -306,7 +323,7 @@ void Foam::ensightMesh::correct()
// Ensure full mesh coverage // Ensure full mesh coverage
excludeFace.resize(mesh_.nFaces()); excludeFace.resize(mesh_.nFaces());
for (const polyPatch& p : pbm) for (const polyPatch& p : mesh_.boundaryMesh())
{ {
const auto* cpp = isA<coupledPolyPatch>(p); const auto* cpp = isA<coupledPolyPatch>(p);
@ -327,8 +344,8 @@ void Foam::ensightMesh::correct()
// Patches // Patches
for (const label patchId : patchIds) for (const label patchId : patchIds)
{ {
const auto& p = pbm[patchId]; const word& patchName = patchNames[patchId];
const auto& patchName = p.name(); const polyPatch& p = mesh_.boundaryMesh()[patchId];
if (isA<emptyPolyPatch>(p)) if (isA<emptyPolyPatch>(p))
{ {
@ -369,10 +386,11 @@ void Foam::ensightMesh::correct()
// Face zones // Face zones
for (const label zoneId : fzoneIds) for (const label zoneId : fzoneIds)
{ {
const auto& zn = mesh_.faceZones()[zoneId]; const word& zoneName = fzNames[zoneId];
const auto& zoneName = zn.name(); const faceZone& zn = mesh_.faceZones()[zoneId];
ensightFaces& part = faceZoneParts_(zoneId); ensightFaces& part = faceZoneParts_(zoneId);

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2025 OpenCFD Ltd. Copyright (C) 2016-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -292,46 +292,34 @@ public:
//- Using boundary? //- Using boundary?
bool useBoundaryMesh() const noexcept; bool useBoundaryMesh() const noexcept;
//- Using cellZones?
bool useCellZones() const noexcept;
//- Using faceZones? //- Using faceZones?
bool useFaceZones() const noexcept; bool useFaceZones() const noexcept;
//- Using cellZones?
bool useCellZones() const noexcept;
//- Selection of patches. Empty if unspecified. //- Selection of patches. Empty if unspecified.
const wordRes& patchSelection() const noexcept const wordRes& patchSelection() const noexcept
{ {
return patchInclude_; return patchInclude_;
} }
//- Excluded patches. Empty if unspecified. //- Selection of black listed patches. Empty if unspecified.
const wordRes& patchExclude() const noexcept const wordRes& patchExclude() const noexcept
{ {
return patchExclude_; return patchExclude_;
} }
//- Selection of cell zones. Empty if unspecified. //- Selection of faceZones. Empty if unspecified.
const wordRes& cellZoneSelection() const noexcept
{
return cellZoneInclude_;
}
//- Excluded cell zones. Future use
const wordRes& cellZoneExclude() const noexcept
{
return wordRes::null();
}
//- Selection of face zones. Empty if unspecified.
const wordRes& faceZoneSelection() const noexcept const wordRes& faceZoneSelection() const noexcept
{ {
return faceZoneInclude_; return faceZoneInclude_;
} }
//- Excluded face zones. Future use //- Selection of faceZones. Empty if unspecified.
const wordRes& faceZoneExclude() const noexcept const wordRes& cellZoneSelection() const noexcept
{ {
return wordRes::null(); return cellZoneInclude_;
} }
@ -368,18 +356,18 @@ public:
//- Define patch selection to exclude //- Define patch selection to exclude
void patchExclude(List<wordRe>&& patterns); void patchExclude(List<wordRe>&& patterns);
//- Define cellZone selection matcher
void cellZoneSelection(const UList<wordRe>& patterns);
//- Define cellZone selection matcher
void cellZoneSelection(List<wordRe>&& patterns);
//- Define faceZone selection matcher //- Define faceZone selection matcher
void faceZoneSelection(const UList<wordRe>& patterns); void faceZoneSelection(const UList<wordRe>& patterns);
//- Define faceZone selection matcher //- Define faceZone selection matcher
void faceZoneSelection(List<wordRe>&& patterns); void faceZoneSelection(List<wordRe>&& patterns);
//- Define cellZone selection matcher
void cellZoneSelection(const UList<wordRe>& patterns);
//- Define cellZone selection matcher
void cellZoneSelection(List<wordRe>&& patterns);
// Output // Output

View File

@ -88,11 +88,7 @@ void Foam::faBoundaryMesh::calcGroupIDs() const
// Remove groups that clash with patch names // Remove groups that clash with patch names
forAll(patches, patchi) forAll(patches, patchi)
{ {
if (groupLookup.empty()) if (groupLookup.erase(patches[patchi].name()))
{
break; // Early termination
}
else if (groupLookup.erase(patches[patchi].name()))
{ {
WarningInFunction WarningInFunction
<< "Removed group '" << patches[patchi].name() << "Removed group '" << patches[patchi].name()
@ -588,7 +584,7 @@ Foam::labelList Foam::faBoundaryMesh::indices
// Only check groups if requested and they exist // Only check groups if requested and they exist
const bool checkGroups = (useGroups && this->hasGroupIDs()); const bool checkGroups = (useGroups && this->hasGroupIDs());
labelHashSet ids; labelHashSet ids(0);
if (matcher.isPattern()) if (matcher.isPattern())
{ {
@ -601,7 +597,7 @@ Foam::labelList Foam::faBoundaryMesh::indices
{ {
if (matcher(iter.key())) if (matcher(iter.key()))
{ {
// Add ids associated with the group // Add patch ids associated with the group
ids.insert(iter.val()); ids.insert(iter.val());
} }
} }
@ -633,7 +629,7 @@ Foam::labelList Foam::faBoundaryMesh::indices
if (iter.good()) if (iter.good())
{ {
// Add ids associated with the group // Add patch ids associated with the group
ids.insert(iter.val()); ids.insert(iter.val());
} }
} }
@ -658,7 +654,7 @@ Foam::labelList Foam::faBoundaryMesh::indices
return this->indices(matcher.front(), useGroups); return this->indices(matcher.front(), useGroups);
} }
labelHashSet ids; labelHashSet ids(0);
// Only check groups if requested and they exist // Only check groups if requested and they exist
if (useGroups && this->hasGroupIDs()) if (useGroups && this->hasGroupIDs())
@ -670,7 +666,7 @@ Foam::labelList Foam::faBoundaryMesh::indices
{ {
if (matcher(iter.key())) if (matcher(iter.key()))
{ {
// Add ids associated with the group // Add patch ids associated with the group
ids.insert(iter.val()); ids.insert(iter.val());
} }
} }
@ -691,20 +687,19 @@ Foam::labelList Foam::faBoundaryMesh::indices
Foam::labelList Foam::faBoundaryMesh::indices Foam::labelList Foam::faBoundaryMesh::indices
( (
const wordRes& allow, const wordRes& select,
const wordRes& deny, const wordRes& ignore,
const bool useGroups const bool useGroups
) const ) const
{ {
if (allow.empty() && deny.empty()) if (ignore.empty())
{ {
// Fast-path: select all return this->indices(select, useGroups);
return identity(this->size());
} }
const wordRes::filter matcher(allow, deny); const wordRes::filter matcher(select, ignore);
labelHashSet ids; labelHashSet ids(0);
// Only check groups if requested and they exist // Only check groups if requested and they exist
if (useGroups && this->hasGroupIDs()) if (useGroups && this->hasGroupIDs())
@ -716,7 +711,7 @@ Foam::labelList Foam::faBoundaryMesh::indices
{ {
if (matcher(iter.key())) if (matcher(iter.key()))
{ {
// Add ids associated with the group // Add patch ids associated with the group
ids.insert(iter.val()); ids.insert(iter.val());
} }
} }

View File

@ -28,9 +28,7 @@ Class
Foam::faBoundaryMesh Foam::faBoundaryMesh
Description Description
Finite area boundary mesh, which is a faPatch list with registered IO, Finite area boundary mesh
a reference to the associated faMesh,
with additional search methods etc.
SourceFiles SourceFiles
faBoundaryMesh.C faBoundaryMesh.C
@ -224,37 +222,34 @@ public:
labelRange range() const; labelRange range() const;
//- The (sorted) patch indices for all matches, //- Return (sorted) patch indices for all matches.
//- optionally matching patch groups. // Optionally matches patch groups.
// \returns an empty list for an empty matcher // A no-op (returns empty list) for an empty matcher
labelList indices labelList indices
( (
const wordRe& matcher, const wordRe& matcher,
const bool useGroups = true const bool useGroups = true
) const; ) const;
//- The (sorted) patch indices for all matches, //- Return (sorted) patch indices for all matches.
//- optionally matching patch groups. // Optionally matches patch groups.
// \returns an empty list for an empty matcher // A no-op (returns empty list) for an empty matcher
labelList indices labelList indices
( (
const wordRes& matcher, const wordRes& matcher,
const bool useGroups = true const bool useGroups = true
) const; ) const;
//- The (sorted) patch indices: logic as per Foam::wordRes::filter, //- Return (sorted) patch indices for all selected matches that
//- optionally matching patch groups. //- are not ignored.
// //- The selection logic as per Foam::wordRes::filter.
// An empty \em allow accepts everything not in \em deny. // Optionally matches patch groups.
// A literal \em allow match has higher priority than any \em deny. // A no-op (returns empty list) for an empty select matcher
// A regex \em allow match has lower priority than any \em deny.
//
// \returns identity list when allow/deny are both empty.
labelList indices labelList indices
( (
const wordRes& allow, const wordRes& select,
const wordRes& deny, const wordRes& ignore,
const bool useGroups = true //!< Match patch groups const bool useGroups = true
) const; ) const;
//- Return patch index for the first match, return -1 if not found //- Return patch index for the first match, return -1 if not found

View File

@ -86,15 +86,7 @@ Foam::transformFaPatchField<Type>::valueInternalCoeffs
const tmp<scalarField>& const tmp<scalarField>&
) const ) const
{ {
// OR (!is_rotational_vectorspace_v<Type>) return pTraits<Type>::one - snGradTransformDiag();
if constexpr (std::is_arithmetic_v<Type>)
{
return tmp<Field<Type>>::New(this->size(), pTraits<Type>::one);
}
else
{
return pTraits<Type>::one - snGradTransformDiag();
}
} }
@ -119,15 +111,7 @@ template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::tmp<Foam::Field<Type>>
Foam::transformFaPatchField<Type>::gradientInternalCoeffs() const Foam::transformFaPatchField<Type>::gradientInternalCoeffs() const
{ {
// OR (!is_rotational_vectorspace_v<Type>) return -this->patch().deltaCoeffs()*snGradTransformDiag();
if constexpr (std::is_arithmetic_v<Type>)
{
return tmp<Field<Type>>::New(this->size(), Foam::zero{});
}
else
{
return -this->patch().deltaCoeffs()*snGradTransformDiag();
}
} }

View File

@ -255,7 +255,6 @@ void Foam::faPatchField<Type>::evaluate(const Pstream::commsTypes)
} }
faPatchFieldBase::setUpdated(false); faPatchFieldBase::setUpdated(false);
faPatchFieldBase::setManipulated(false);
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016-2017 Wikki Ltd Copyright (C) 2016-2017 Wikki Ltd
Copyright (C) 2019-2025 OpenCFD Ltd. Copyright (C) 2019-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -226,17 +226,6 @@ public:
updated_ = state; updated_ = state;
} }
//- True if the matrix has already been manipulated.
//- Currently always false for faPatchField
bool manipulatedMatrix() const noexcept
{
return false;
}
//- Set matrix manipulated state. Currently a no-op for faPatchField
void setManipulated(bool state) noexcept
{}
// Check // Check
@ -265,9 +254,6 @@ public:
//- The value_type for the patch field //- The value_type for the patch field
typedef Type value_type; typedef Type value_type;
//- The component type for patch field
typedef typename pTraits<Type>::cmptType cmptType;
//- The internal field type associated with the patch field //- The internal field type associated with the patch field
typedef DimensionedField<Type, areaMesh> Internal; typedef DimensionedField<Type, areaMesh> Internal;

View File

@ -98,6 +98,14 @@ protected:
// Useful when initially constructed without a dictionary // Useful when initially constructed without a dictionary
virtual void readDict(const dictionary& dict); virtual void readDict(const dictionary& dict);
//- Set updated state. This is a no-op for faePatchField
void setUpdated(bool state) noexcept
{}
//- Set matrix manipulated state. This is a no-op for faePatchField
void setManipulated(bool state) noexcept
{}
public: public:
@ -203,22 +211,13 @@ public:
return true; return true;
} }
//- Set updated state. This is a no-op for faePatchField
void setUpdated(bool state) noexcept
{}
//- True if the matrix has already been manipulated. //- True if the matrix has already been manipulated.
//- Always false for faePatchField //- Currently ignored (always false) for faePatchField
bool manipulatedMatrix() const noexcept bool manipulatedMatrix() const noexcept
{ {
return false; return false;
} }
//- Set matrix manipulated state.
//- This is a no-op for faePatchField
void setManipulated(bool state) noexcept
{}
// Check // Check
@ -247,9 +246,6 @@ public:
//- The value_type for the patch field //- The value_type for the patch field
typedef Type value_type; typedef Type value_type;
//- The component type for patch field
typedef typename pTraits<Type>::cmptType cmptType;
//- The internal field type associated with the patch field //- The internal field type associated with the patch field
typedef DimensionedField<Type, edgeMesh> Internal; typedef DimensionedField<Type, edgeMesh> Internal;

View File

@ -97,15 +97,7 @@ Foam::transformFvPatchField<Type>::valueInternalCoeffs
const tmp<scalarField>& const tmp<scalarField>&
) const ) const
{ {
// OR (!is_rotational_vectorspace_v<Type>) return pTraits<Type>::one - snGradTransformDiag();
if constexpr (std::is_arithmetic_v<Type>)
{
return tmp<Field<Type>>::New(this->size(), pTraits<Type>::one);
}
else
{
return pTraits<Type>::one - snGradTransformDiag();
}
} }
@ -130,15 +122,7 @@ template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::tmp<Foam::Field<Type>>
Foam::transformFvPatchField<Type>::gradientInternalCoeffs() const Foam::transformFvPatchField<Type>::gradientInternalCoeffs() const
{ {
// OR (!is_rotational_vectorspace_v<Type>) return -this->patch().deltaCoeffs()*snGradTransformDiag();
if constexpr (std::is_arithmetic_v<Type>)
{
return tmp<Field<Type>>::New(this->size(), Foam::zero{});
}
else
{
return -this->patch().deltaCoeffs()*snGradTransformDiag();
}
} }

Some files were not shown because too many files have changed in this diff Show More