Compare commits

..

1 Commits

Author SHA1 Message Date
7b7229fc13 ENH: integrate memory pool support for List allocations
- provides an optional memory management using a memory pool.
  Currently can support Umpire (https://github.com/LLNL/Umpire)

  When available, its use can be controlled by the FOAM_MEMORY_POOL
  environment variable, or the memory_pool Optimisation switch
  (etc/controlDict).

Notes:

  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 (depending on the field size).

  The thresholds for aligned, unaligned, memory-pool allocation
  are still a compile-time option. Made by direct edit of the
  corrsponding functions.
2025-05-22 16:22:09 +02:00
252 changed files with 2829 additions and 3278 deletions

View File

@ -1,2 +1,2 @@
api=2502 api=2501
patch=0 patch=0

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

@ -210,7 +210,6 @@ autoPtr<labelIOList> faProcAddressing
// Return cached or read proc addressing from facesInstance // Return cached or read proc addressing from facesInstance
FOAM_NO_DANGLING_REFERENCE
const labelIOList& procAddressing const labelIOList& procAddressing
( (
const PtrList<fvMesh>& procMeshList, const PtrList<fvMesh>& procMeshList,

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
{
labelList ids = pbm.indices(allow_, deny_);
const bool excludeProcPatches = UPstream::parRun();
// Prune undesirable patches
label count = 0; label count = 0;
for (const label patchi : ids) for (const label patchi : indices)
{ {
const auto& 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 (UPstream::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;
}
};
} // End namespace Foam 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-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2018-2025 OpenCFD Ltd. Copyright (C) 2018-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -39,23 +39,74 @@ namespace Foam
{ {
template<class Type> template<class Type>
void evaluateConstraintTypes void evaluateConstraintTypes(GeometricField<Type, fvPatchField, volMesh>& fld)
(
GeometricField<Type, fvPatchField, volMesh>& fld
)
{ {
fld.boundaryFieldRef().evaluate_if auto& bfld = fld.boundaryFieldRef();
const UPstream::commsTypes commsType = UPstream::defaultCommsType;
if
( (
[](const auto& pfld) -> bool commsType == UPstream::commsTypes::buffered
|| commsType == UPstream::commsTypes::nonBlocking
)
{ {
return const label startOfRequests = UPstream::nRequests();
for (auto& pfld : bfld)
{
if
( (
pfld.type() == pfld.patch().patch().type() pfld.type() == pfld.patch().patch().type()
&& polyPatch::constraintType(pfld.patch().patch().type()) && polyPatch::constraintType(pfld.patch().patch().type())
); )
}, {
UPstream::defaultCommsType pfld.initEvaluate(commsType);
); }
}
// Wait for outstanding requests (non-blocking)
UPstream::waitRequests(startOfRequests);
for (auto& pfld : bfld)
{
if
(
pfld.type() == pfld.patch().patch().type()
&& polyPatch::constraintType(pfld.patch().patch().type())
)
{
pfld.evaluate(commsType);
}
}
}
else if (commsType == UPstream::commsTypes::scheduled)
{
const lduSchedule& patchSchedule =
fld.mesh().globalData().patchSchedule();
for (const auto& schedEval : patchSchedule)
{
const label patchi = schedEval.patch;
auto& pfld = bfld[patchi];
if
(
pfld.type() == pfld.patch().patch().type()
&& polyPatch::constraintType(pfld.patch().patch().type())
)
{
if (schedEval.init)
{
pfld.initEvaluate(commsType);
}
else
{
pfld.evaluate(commsType);
}
}
}
}
} }

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

@ -587,7 +587,7 @@ meshes/Identifiers/surface/geometricSurfacePatch.C
meshes/Identifiers/surface/surfZoneIdentifier.C meshes/Identifiers/surface/surfZoneIdentifier.C
meshes/Identifiers/zone/zoneIdentifier.C meshes/Identifiers/zone/zoneIdentifier.C
meshes/MeshObject/meshObject.cxx meshes/MeshObject/meshObject.C
polyMesh = meshes/polyMesh polyMesh = meshes/polyMesh

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

@ -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>>();
} }
@ -373,33 +373,6 @@ public:
Field<Type>&& iField Field<Type>&& iField
); );
//- Return tmp field (NO_READ, NO_WRITE)
//- from name, mesh, dimensions, primitive field (tmp).
//- [Takes current timeName from the mesh registry].
// For LEGACY_REGISTER, registration is determined by
// objectRegistry::is_cacheTemporaryObject().
static tmp<DimensionedField<Type, GeoMesh>> New
(
const word& name,
IOobjectOption::registerOption regOpt,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield
);
//- Return tmp field (NO_READ, NO_WRITE)
//- from name, mesh, dimensions, primitive field (tmp).
//- [Takes current timeName from the mesh registry].
// Registration/persistence determined by
// objectRegistry::is_cacheTemporaryObject().
static tmp<DimensionedField<Type, GeoMesh>> New
(
const word& name,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield
);
//- Return tmp field (NO_READ, NO_WRITE) //- Return tmp field (NO_READ, NO_WRITE)
//- from name, mesh, dimensions. //- from name, mesh, dimensions.
//- [Takes current timeName from the mesh registry]. //- [Takes current timeName from the mesh registry].

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2022-2025 OpenCFD Ltd. Copyright (C) 2022-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -163,49 +163,6 @@ Foam::DimensionedField<Type, GeoMesh>::New
} }
template<class Type, class GeoMesh>
Foam::tmp<Foam::DimensionedField<Type, GeoMesh>>
Foam::DimensionedField<Type, GeoMesh>::New
(
const word& name,
IOobjectOption::registerOption regOpt,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield
)
{
return DimensionedField<Type, GeoMesh>::New_impl
(
regOpt,
name,
mesh,
dims,
tfield
);
}
template<class Type, class GeoMesh>
Foam::tmp<Foam::DimensionedField<Type, GeoMesh>>
Foam::DimensionedField<Type, GeoMesh>::New
(
const word& name,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield
)
{
return DimensionedField<Type, GeoMesh>::New_impl
(
IOobjectOption::LEGACY_REGISTER,
name,
mesh,
dims,
tfield
);
}
template<class Type, class GeoMesh> template<class Type, class GeoMesh>
Foam::tmp<Foam::DimensionedField<Type, GeoMesh>> Foam::tmp<Foam::DimensionedField<Type, GeoMesh>>
Foam::DimensionedField<Type, GeoMesh>::New Foam::DimensionedField<Type, GeoMesh>::New

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

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017,2022 OpenFOAM Foundation Copyright (C) 2011-2017,2022 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.
@ -38,56 +38,53 @@ 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());
label nEvaluated(0);
// 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());
for (auto& pfld : bfld) for (auto& pfld : bfld)
{ {
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;
++nEvaluated; //oldManipulated[patchi] = pfld.manipulatedMatrix();
} }
} }
if (!nEvaluated) return true; // Early termination
// Re-evaluate // Re-evaluate
{ {
const label startOfRequests = UPstream::nRequests(); const label startOfRequests = UPstream::nRequests();
nEvaluated = 0;
for (auto& pfld : bfld) for (auto& pfld : bfld)
{ {
if (isA<CheckPatchFieldType>(pfld)) if (isA<CheckPatchFieldType>(pfld))
{ {
pfld.initEvaluate(UPstream::commsTypes::nonBlocking); pfld.initEvaluate(UPstream::commsTypes::nonBlocking);
++nEvaluated;
} }
} }
@ -99,49 +96,34 @@ bool Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::checkConsistency
if (isA<CheckPatchFieldType>(pfld)) if (isA<CheckPatchFieldType>(pfld))
{ {
pfld.evaluate(UPstream::commsTypes::nonBlocking); pfld.evaluate(UPstream::commsTypes::nonBlocking);
if (--nEvaluated == 0) break; // Early termination
} }
} }
} }
// Check // Check
bool allOk(true); bool ok = true;
for (auto& pfld : bfld) for (auto& pfld : bfld)
{ {
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);
if (allOk)
{
// Only check for first failed patch
forAll(pfld, facei) forAll(pfld, facei)
{ {
if (tol < Foam::mag(pfld[facei]-oldPfld[facei])) if (mag(pfld[facei]-oldPfld[facei]) > tol)
{ {
allOk = false; ok = false;
localOk = false;
break; break;
} }
} }
}
if (!localOk) if (!ok)
{ {
// Raise warning or error if (doExit)
OSstream& err = {
( FatalErrorInFunction << "Field "
exitIfBad
? FatalErrorInFunction
: WarningInFunction
);
err << "Field "
<< pfld.internalField().name() << pfld.internalField().name()
<< " is not evaluated?" << " is not evaluated?"
<< " On patch " << pfld.patch().name() << " On patch " << pfld.patch().name()
@ -151,29 +133,53 @@ bool Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::checkConsistency
<< ". Average of evaluated field = " << ". Average of evaluated field = "
<< average(pfld) << average(pfld)
<< ". Difference:" << average(pfld-oldPfld) << ". Difference:" << average(pfld-oldPfld)
<< ". Tolerance:" << tol << endl; << ". Tolerance:" << tol
<< exit(FatalError);
if (exitIfBad) }
else
{ {
FatalError<< exit(FatalError); 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;
// Skip other patches
break;
}
}
} }
} }
// Restore patch field values and states // Restore bfld, updated
static_cast<Field<Type>&>(pfld) = std::move(oldPfld); for (auto& pfld : bfld)
{
if (isA<CheckPatchFieldType>(pfld))
{
const label patchi = pfld.patch().index();
pfld.setUpdated(oldUpdated[patchi]); pfld.setUpdated(oldUpdated[patchi]);
pfld.setManipulated(oldManipulated[patchi]); Field<Type>& vals = pfld;
vals = 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() << " : " << ok << endl;
} }
return allOk; return ok;
} }
@ -620,7 +626,6 @@ void Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::evaluate_if
|| commsType == UPstream::commsTypes::nonBlocking || commsType == UPstream::commsTypes::nonBlocking
) )
{ {
label nEvaluated(0);
const label startOfRequests = UPstream::nRequests(); const label startOfRequests = UPstream::nRequests();
for (auto& pfld : *this) for (auto& pfld : *this)
@ -628,21 +633,17 @@ void Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::evaluate_if
if (pred(pfld)) if (pred(pfld))
{ {
pfld.initEvaluate(commsType); pfld.initEvaluate(commsType);
++nEvaluated;
} }
} }
// Wait for outstanding requests (non-blocking) // Wait for outstanding requests (non-blocking)
UPstream::waitRequests(startOfRequests); UPstream::waitRequests(startOfRequests);
if (!nEvaluated) return; // Early termination
for (auto& pfld : *this) for (auto& pfld : *this)
{ {
if (pred(pfld)) if (pred(pfld))
{ {
pfld.evaluate(commsType); pfld.evaluate(commsType);
if (--nEvaluated == 0) break; // Early termination
} }
} }
} }
@ -777,25 +778,81 @@ void Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::evaluateCoupled
const UPstream::commsTypes commsType const UPstream::commsTypes commsType
) )
{ {
if constexpr (std::is_void_v<CoupledPatchType>) // Alternative (C++14)
{ //
this->evaluate_if // this->evaluate_if
// (
// [](const auto& pfld) -> bool
// {
// const auto* cpp = isA<CoupledPatchType>(pfld.patch());
// return (cpp && cpp->coupled());
// },
// commsType
// );
// DebugInFunction << nl;
if
( (
[](const auto& pfld) { return pfld.coupled(); }, commsType == UPstream::commsTypes::buffered
commsType || commsType == UPstream::commsTypes::nonBlocking
); )
{
const label startOfRequests = UPstream::nRequests();
for (auto& pfld : *this)
{
const auto* cpp = isA<CoupledPatchType>(pfld.patch());
if (cpp && cpp->coupled())
{
pfld.initEvaluate(commsType);
}
}
// Wait for outstanding requests (non-blocking)
UPstream::waitRequests(startOfRequests);
for (auto& pfld : *this)
{
const auto* cpp = isA<CoupledPatchType>(pfld.patch());
if (cpp && cpp->coupled())
{
pfld.evaluate(commsType);
}
}
}
else if (commsType == UPstream::commsTypes::scheduled)
{
const lduSchedule& patchSchedule =
bmesh_.mesh().globalData().patchSchedule();
for (const auto& schedEval : patchSchedule)
{
const label patchi = schedEval.patch;
auto& pfld = (*this)[patchi];
const auto* cpp = isA<CoupledPatchType>(pfld.patch());
if (cpp && cpp->coupled())
{
if (schedEval.init)
{
pfld.initEvaluate(commsType);
} }
else else
{ {
this->evaluate_if pfld.evaluate(commsType);
( }
[](const auto& pfld) -> bool }
}
}
else
{ {
const auto* cpp = isA<CoupledPatchType>(pfld.patch()); FatalErrorInFunction
return (cpp && cpp->coupled()); << "Unsupported communications type " << int(commsType) << nl
}, << exit(FatalError);
commsType
);
} }
} }

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>
@ -206,12 +205,8 @@ public:
const UPstream::commsTypes commsType = UPstream::defaultCommsType const UPstream::commsTypes commsType = UPstream::defaultCommsType
); );
//- Evaluate boundary conditions on coupled patches of the given type, //- Evaluate boundary conditions on coupled patches of given type.
//- using specified or default comms. //- Uses specified or default comms.
//
// \tparam CoupledPatchType The coupled \b patch type that should
// be evaluated. For a \c void type,
// all coupled patch fields will be evaluated.
template<class CoupledPatchType> template<class CoupledPatchType>
void evaluateCoupled void evaluateCoupled
( (

View File

@ -63,10 +63,8 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::readFields
if (dict.readIfPresent("referenceLevel", refLevel)) if (dict.readIfPresent("referenceLevel", refLevel))
{ {
// Add to internal (primitive) field Field<Type>::operator+=(refLevel);
this->field() += refLevel;
// Add to boundary fields
forAll(boundaryField_, patchi) forAll(boundaryField_, patchi)
{ {
boundaryField_[patchi] == boundaryField_[patchi] + refLevel; boundaryField_[patchi] == boundaryField_[patchi] + refLevel;
@ -411,7 +409,7 @@ Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
boundaryField_(mesh.boundary(), *this, patchFieldType) boundaryField_(mesh.boundary(), *this, patchFieldType)
{ {
DebugInFunction DebugInFunction
<< "Copy construct from primitive field" << nl << this->info() << endl; << "Copy construct from internal field" << nl << this->info() << endl;
readIfPresent(); readIfPresent();
} }
@ -432,28 +430,7 @@ Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
boundaryField_(mesh.boundary(), *this, patchFieldType) boundaryField_(mesh.boundary(), *this, patchFieldType)
{ {
DebugInFunction DebugInFunction
<< "Move construct from primitive field" << nl << this->info() << endl; << "Move construct from internal field" << nl << this->info() << endl;
readIfPresent();
}
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
(
const IOobject& io,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield,
const word& patchFieldType
)
:
Internal(io, mesh, dims, tfield),
timeIndex_(this->time().timeIndex()),
boundaryField_(mesh.boundary(), *this, patchFieldType)
{
DebugInFunction
<< "Construct from tmp primitive field" << nl << this->info() << endl;
readIfPresent(); readIfPresent();
} }
@ -1414,7 +1391,10 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::operator=
// Make sure any e.g. jump-cyclic are updated. // Make sure any e.g. jump-cyclic are updated.
boundaryFieldRef().evaluate_if boundaryFieldRef().evaluate_if
( (
[](const auto& pfld) { return pfld.constraintOverride(); } [](const auto& pfld) -> bool
{
return pfld.constraintOverride();
}
); );
} }
@ -1456,7 +1436,10 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::operator=
// Make sure any e.g. jump-cyclic are updated. // Make sure any e.g. jump-cyclic are updated.
boundaryFieldRef().evaluate_if boundaryFieldRef().evaluate_if
( (
[](const auto& pfld) { return pfld.constraintOverride(); } [](const auto& pfld) -> bool
{
return pfld.constraintOverride();
}
); );
} }
@ -1473,7 +1456,10 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::operator=
// Make sure any e.g. jump-cyclic are updated. // Make sure any e.g. jump-cyclic are updated.
boundaryFieldRef().evaluate_if boundaryFieldRef().evaluate_if
( (
[](const auto& pfld) { return pfld.constraintOverride(); } [](const auto& pfld) -> bool
{
return pfld.constraintOverride();
}
); );
} }
@ -1498,7 +1484,10 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::operator==
// Make sure any e.g. jump-cyclic are updated. // Make sure any e.g. jump-cyclic are updated.
boundaryFieldRef().evaluate_if boundaryFieldRef().evaluate_if
( (
[](const auto& pfld) { return pfld.constraintOverride(); } [](const auto& pfld) -> bool
{
return pfld.constraintOverride();
}
); );
} }
@ -1515,7 +1504,10 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::operator==
// Make sure any e.g. jump-cyclic are updated. // Make sure any e.g. jump-cyclic are updated.
boundaryFieldRef().evaluate_if boundaryFieldRef().evaluate_if
( (
[](const auto& pfld) { return pfld.constraintOverride(); } [](const auto& pfld) -> bool
{
return pfld.constraintOverride();
}
); );
} }
@ -1535,7 +1527,10 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::operator op \
\ \
boundaryFieldRef().evaluate_if \ boundaryFieldRef().evaluate_if \
( \ ( \
[](const auto& pfld) { return pfld.constraintOverride(); } \ [](const auto& pfld) -> bool \
{ \
return pfld.constraintOverride(); \
} \
); \ ); \
} \ } \
\ \
@ -1550,7 +1545,10 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::operator op \
\ \
boundaryFieldRef().evaluate_if \ boundaryFieldRef().evaluate_if \
( \ ( \
[](const auto& pfld) { return pfld.constraintOverride(); } \ [](const auto& pfld) -> bool \
{ \
return pfld.constraintOverride(); \
} \
); \ ); \
} \ } \
\ \
@ -1565,7 +1563,10 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::operator op \
\ \
boundaryFieldRef().evaluate_if \ boundaryFieldRef().evaluate_if \
( \ ( \
[](const auto& pfld) { return pfld.constraintOverride(); } \ [](const auto& pfld) -> bool \
{ \
return pfld.constraintOverride(); \
} \
); \ ); \
} }

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>>();
} }
@ -251,7 +251,7 @@ public:
const PtrList<PatchField<Type>>& ptfl const PtrList<PatchField<Type>>& ptfl
); );
//- Construct from internal field (tmp) and a patch list to clone //- Move construct from internal field and a patch list to clone
GeometricField GeometricField
( (
const IOobject& io, const IOobject& io,
@ -273,7 +273,7 @@ public:
const PtrList<PatchField<Type>>& ptfl const PtrList<PatchField<Type>>& ptfl
); );
//- Copy construct from primitive field, with specified patch type //- Copy construct from internal field, with specified patch type
GeometricField GeometricField
( (
const IOobject& io, const IOobject& io,
@ -283,7 +283,7 @@ public:
const word& patchFieldType = PatchField<Type>::calculatedType() const word& patchFieldType = PatchField<Type>::calculatedType()
); );
//- Move construct from primitive field, with specified patch type //- Move construct from internal field, with specified patch type
GeometricField GeometricField
( (
const IOobject& io, const IOobject& io,
@ -293,17 +293,7 @@ public:
const word& patchFieldType = PatchField<Type>::calculatedType() const word& patchFieldType = PatchField<Type>::calculatedType()
); );
//- Construct from primitive field (tmp), with specified patch type //- Copy construct from components
GeometricField
(
const IOobject& io,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield,
const word& patchFieldType = PatchField<Type>::calculatedType()
);
//- Copy construct from primitive field and a patch list to clone
GeometricField GeometricField
( (
const IOobject& io, const IOobject& io,
@ -313,7 +303,7 @@ public:
const PtrList<PatchField<Type>>& ptfl const PtrList<PatchField<Type>>& ptfl
); );
//- Move construct from primitive field and a patch list to clone //- Move construct from internal field and a patch list to clone
GeometricField GeometricField
( (
const IOobject& io, const IOobject& io,
@ -329,7 +319,7 @@ public:
const IOobject& io, const IOobject& io,
const Mesh& mesh, const Mesh& mesh,
const dimensionSet& dims, const dimensionSet& dims,
const tmp<Field<Type>>& tfield, const tmp<Field<Type>>& tiField,
const PtrList<PatchField<Type>>& ptfl const PtrList<PatchField<Type>>& ptfl
); );
@ -518,37 +508,6 @@ public:
const word& patchFieldType = PatchField<Type>::calculatedType() const word& patchFieldType = PatchField<Type>::calculatedType()
); );
//- Return tmp field (NO_READ, NO_WRITE)
//- from name, mesh, dimensions, tmp of primitive field
//- and patch type.
//- [Takes current timeName from the mesh registry].
// For LEGACY_REGISTER, registration is determined by
// objectRegistry::is_cacheTemporaryObject().
static tmp<GeometricField<Type, PatchField, GeoMesh>> New
(
const word& name,
IOobjectOption::registerOption regOpt,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield,
const word& patchFieldType = PatchField<Type>::calculatedType()
);
//- Return tmp field (NO_READ, NO_WRITE)
//- from name, mesh, dimensions, tmp of primitive field
//- and patch type.
//- [Takes current timeName from the mesh registry].
// Registration/persistence determined by
// objectRegistry::is_cacheTemporaryObject().
static tmp<GeometricField<Type, PatchField, GeoMesh>> New
(
const word& name,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield,
const word& patchFieldType = PatchField<Type>::calculatedType()
);
//- Return tmp field (NO_READ, NO_WRITE) //- Return tmp field (NO_READ, NO_WRITE)
//- from name, mesh, dimensions, copy of internal field contents //- from name, mesh, dimensions, copy of internal field contents
//- and patch list to clone. //- and patch list to clone.

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017 OpenFOAM Foundation Copyright (C) 2017 OpenFOAM Foundation
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.
@ -215,53 +215,6 @@ Foam::GeometricField<Type, PatchField, GeoMesh>::New
} }
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::tmp<Foam::GeometricField<Type, PatchField, GeoMesh>>
Foam::GeometricField<Type, PatchField, GeoMesh>::New
(
const word& name,
IOobjectOption::registerOption regOpt,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield,
const word& patchFieldType
)
{
return GeometricField<Type, PatchField, GeoMesh>::New_impl
(
regOpt,
name,
mesh,
dims,
tfield,
patchFieldType
);
}
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::tmp<Foam::GeometricField<Type, PatchField, GeoMesh>>
Foam::GeometricField<Type, PatchField, GeoMesh>::New
(
const word& name,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield,
const word& patchFieldType
)
{
return GeometricField<Type, PatchField, GeoMesh>::New_impl
(
IOobjectOption::LEGACY_REGISTER,
name,
mesh,
dims,
tfield,
patchFieldType
);
}
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
Foam::tmp<Foam::GeometricField<Type, PatchField, GeoMesh>> Foam::tmp<Foam::GeometricField<Type, PatchField, GeoMesh>>
Foam::GeometricField<Type, PatchField, GeoMesh>::New Foam::GeometricField<Type, PatchField, GeoMesh>::New

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.
@ -88,27 +87,20 @@ void Foam::basicSymmetryPointPatchField<Type>::evaluate
const Pstream::commsTypes const Pstream::commsTypes
) )
{ {
if constexpr (!is_rotational_vectorspace_v<Type>)
{
// Rotational-invariant type : no-op
}
else
{
const vectorField& nHat = this->patch().pointNormals(); const vectorField& nHat = this->patch().pointNormals();
const Field<Type> pif(this->patchInternalField()); tmp<Field<Type>> tvalues =
// Could write as loop instead...
tmp<Field<Type>> tvalues
( (
0.5*(pif + transform(I - 2.0*sqr(nHat), pif)) (
this->patchInternalField()
+ transform(I - 2.0*sqr(nHat), this->patchInternalField())
)/2.0
); );
// Get internal field to insert values into // Get internal field to insert values into
auto& iF = const_cast<Field<Type>&>(this->primitiveField()); Field<Type>& iF = const_cast<Field<Type>&>(this->primitiveField());
this->setInInternalField(iF, tvalues()); this->setInInternalField(iF, tvalues());
}
} }

View File

@ -27,6 +27,7 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "fixedValuePointPatchField.H" #include "fixedValuePointPatchField.H"
#include "boolList.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //

View File

@ -84,27 +84,20 @@ Foam::cyclicSlipPointPatchField<Type>::cyclicSlipPointPatchField
template<class Type> template<class Type>
void Foam::cyclicSlipPointPatchField<Type>::evaluate(const Pstream::commsTypes) void Foam::cyclicSlipPointPatchField<Type>::evaluate(const Pstream::commsTypes)
{ {
if constexpr (!is_rotational_vectorspace_v<Type>)
{
// Rotational-invariant type : no-op
}
else
{
const vectorField& nHat = this->patch().pointNormals(); const vectorField& nHat = this->patch().pointNormals();
const Field<Type> pif(this->patchInternalField()); tmp<Field<Type>> tvalues =
// Could write as loop instead...
tmp<Field<Type>> tvalues
( (
0.5*(pif + transform(I - 2.0*sqr(nHat), pif)) (
this->patchInternalField()
+ transform(I - 2.0*sqr(nHat), this->patchInternalField())
)/2.0
); );
// Get internal field to insert values into // Get internal field to insert values into
auto& iF = const_cast<Field<Type>&>(this->primitiveField()); Field<Type>& iF = const_cast<Field<Type>&>(this->primitiveField());
this->setInInternalField(iF, tvalues()); this->setInInternalField(iF, tvalues());
}
} }

View File

@ -91,27 +91,20 @@ void Foam::nonuniformTransformCyclicPointPatchField<Type>::evaluate
const Pstream::commsTypes const Pstream::commsTypes
) )
{ {
if constexpr (!is_rotational_vectorspace_v<Type>)
{
// Rotational-invariant type : no-op
}
else
{
const vectorField& nHat = this->patch().pointNormals(); const vectorField& nHat = this->patch().pointNormals();
const Field<Type> pif(this->patchInternalField()); tmp<Field<Type>> tvalues =
// Could write as loop instead...
tmp<Field<Type>> tvalues
( (
0.5*(pif + transform(I - 2.0*sqr(nHat), pif)) (
this->patchInternalField()
+ transform(I - 2.0*sqr(nHat), this->patchInternalField())
)/2.0
); );
// Get internal field to insert values into // Get internal field to insert values into
auto& iF = const_cast<Field<Type>&>(this->primitiveField()); Field<Type>& iF = const_cast<Field<Type>&>(this->primitiveField());
this->setInInternalField(iF, tvalues()); this->setInInternalField(iF, tvalues());
}
} }

View File

@ -106,27 +106,20 @@ void Foam::symmetryPlanePointPatchField<Type>::evaluate
const Pstream::commsTypes const Pstream::commsTypes
) )
{ {
if constexpr (!is_rotational_vectorspace_v<Type>) vector nHat = symmetryPlanePatch_.n();
{
// Rotational-invariant type : no-op
}
else
{
const symmTensor rot(I - 2.0*sqr(symmetryPlanePatch_.n()));
const Field<Type> pif(this->patchInternalField()); tmp<Field<Type>> tvalues =
// Could write as loop instead...
tmp<Field<Type>> tvalues
( (
0.5*(pif + transform(rot, pif)) (
this->patchInternalField()
+ transform(I - 2.0*sqr(nHat), this->patchInternalField())
)/2.0
); );
// Get internal field to insert values into // Get internal field to insert values into
auto& iF = const_cast<Field<Type>&>(this->primitiveField()); Field<Type>& iF = const_cast<Field<Type>&>(this->primitiveField());
this->setInInternalField(iF, tvalues()); this->setInInternalField(iF, tvalues());
}
} }

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.
@ -29,6 +28,7 @@ License
#include "wedgePointPatchField.H" #include "wedgePointPatchField.H"
#include "transformField.H" #include "transformField.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type> template<class Type>
@ -101,28 +101,17 @@ Foam::wedgePointPatchField<Type>::wedgePointPatchField
template<class Type> template<class Type>
void Foam::wedgePointPatchField<Type>::evaluate(const Pstream::commsTypes) void Foam::wedgePointPatchField<Type>::evaluate(const Pstream::commsTypes)
{ {
if constexpr (!is_rotational_vectorspace_v<Type>)
{
// Rotational-invariant type : no-op
}
else
{
// In order to ensure that the wedge patch is always flat, take the // In order to ensure that the wedge patch is always flat, take the
// normal vector from the first point // normal vector from the first point
const vector& nHat = this->patch().pointNormals()[0];
const symmTensor rot(I - 2.0*sqr(this->patch().pointNormals()[0])); tmp<Field<Type>> tvalues =
transform(I - nHat*nHat, this->patchInternalField());
// Could write as loop instead...
tmp<Field<Type>> tvalues
(
transform(rot, this->patchInternalField())
);
// Get internal field to insert values into // Get internal field to insert values into
auto& iF = const_cast<Field<Type>&>(this->primitiveField()); Field<Type>& iF = const_cast<Field<Type>&>(this->primitiveField());
this->setInInternalField(iF, tvalues()); this->setInInternalField(iF, tvalues());
}
} }

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.
@ -89,22 +88,13 @@ void Foam::fixedNormalSlipPointPatchField<Type>::evaluate
const Pstream::commsTypes const Pstream::commsTypes
) )
{ {
if constexpr (!is_rotational_vectorspace_v<Type>) tmp<Field<Type>> tvalues =
{ transform(I - n_*n_, this->patchInternalField());
// Rotational-invariant type : no-op
}
else
{
tmp<Field<Type>> tvalues
(
transform(I - n_*n_, this->patchInternalField())
);
// Get internal field to insert values into // Get internal field to insert values into
auto& iF = const_cast<Field<Type>&>(this->primitiveField()); Field<Type>& iF = const_cast<Field<Type>&>(this->primitiveField());
this->setInInternalField(iF, tvalues()); this->setInInternalField(iF, tvalues());
}
} }

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

@ -71,21 +71,6 @@ Description
# define FOAM_LIKELY(cond) (cond) # define FOAM_LIKELY(cond) (cond)
#endif #endif
// Shadow macro for __GNUC__, excluding compilers masquerading as gcc
#undef FOAM_REAL_GNUC
#if defined(__GNUC__) && !defined(__llvm__)
# define FOAM_REAL_GNUC __GNUC__
#endif
// Suppress false positives from -Wdangling-reference (gcc >= 14)
#if (FOAM_REAL_GNUC >= 14)
# define FOAM_NO_DANGLING_REFERENCE [[gnu::no_dangling]]
#endif
#ifndef FOAM_NO_DANGLING_REFERENCE
#define FOAM_NO_DANGLING_REFERENCE
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 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.
@ -168,12 +168,10 @@ public:
//- Get existing or create MeshObject registered with typeName //- Get existing or create MeshObject registered with typeName
template<class... Args> template<class... Args>
FOAM_NO_DANGLING_REFERENCE //< Reference stored in registry
static const Type& New(const Mesh& mesh, Args&&... args); static const Type& New(const Mesh& mesh, Args&&... args);
//- Get existing or create MeshObject with given registration name //- Get existing or create MeshObject with given registration name
template<class... Args> template<class... Args>
FOAM_NO_DANGLING_REFERENCE //< Reference stored in registry
static const Type& New static const Type& New
( (
const word& objName, const word& objName,
@ -322,7 +320,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository #ifdef NoRepository
#include "MeshObject.txx" #include "MeshObject.C"
#endif #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

@ -167,13 +167,13 @@ public:
} }
//- Return processor number //- Return processor number
int myProcNo() const noexcept int myProcNo() const
{ {
return procPolyPatch_.myProcNo(); return procPolyPatch_.myProcNo();
} }
//- Return neighbour processor number //- Return neighbour processor number
int neighbProcNo() const noexcept int neighbProcNo() const
{ {
return procPolyPatch_.neighbProcNo(); return procPolyPatch_.neighbProcNo();
} }
@ -191,13 +191,13 @@ public:
} }
//- Return the underlying processorPolyPatch //- Return the underlying processorPolyPatch
const processorPolyPatch& procPolyPatch() const noexcept const processorPolyPatch& procPolyPatch() const
{ {
return procPolyPatch_; return procPolyPatch_;
} }
//- Return mesh points in the correct order for the receiving side //- Return mesh points in the correct order for the receiving side
const labelList& reverseMeshPoints() const noexcept const labelList& reverseMeshPoints() const
{ {
return reverseMeshPoints_; return reverseMeshPoints_;
} }

View File

@ -34,8 +34,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef Foam_wedgePointPatch_H #ifndef wedgePointPatch_H
#define Foam_wedgePointPatch_H #define wedgePointPatch_H
#include "facePointPatch.H" #include "facePointPatch.H"
#include "wedgePolyPatch.H" #include "wedgePolyPatch.H"
@ -53,9 +53,9 @@ class wedgePointPatch
: :
public facePointPatch public facePointPatch
{ {
// Private Data // Private data
//- Local reference cast into the wedgePolyPatch patch //- Local reference cast into the symmetryPlane patch
const wedgePolyPatch& wedgePolyPatch_; const wedgePolyPatch& wedgePolyPatch_;
@ -120,8 +120,8 @@ public:
pointConstraint& pointConstraint&
) const; ) const;
//- Return the normal to the patch //- Return symmetry plane normal
const vector& n() const noexcept const vector& n() const
{ {
return wedgePolyPatch_.n(); return wedgePolyPatch_.n();
} }

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,42 +234,32 @@ 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);
}
} }
} }
//- Transform patch-based field //- Transform patch-based field
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);
} }
} }
}
//- Transform sparse field //- Transform sparse field
template<class Type, template<class> class Container> template<class Type, template<class> class Container>
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);
} }
} }
}
}; };
//- Default transformation behaviour for position //- Default transformation behaviour for position
@ -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

@ -34,8 +34,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef Foam_wedgePolyPatch_H #ifndef wedgePolyPatch_H
#define Foam_wedgePolyPatch_H #define wedgePolyPatch_H
#include "polyPatch.H" #include "polyPatch.H"
@ -52,7 +52,7 @@ class wedgePolyPatch
: :
public polyPatch public polyPatch
{ {
// Private Data // Private data
//- Axis of the wedge //- Axis of the wedge
vector axis_; vector axis_;
@ -173,27 +173,45 @@ public:
} }
// Member Functions // Member functions
// Access // Access
//- Return axis of the wedge //- Return axis of the wedge
const vector& axis() const noexcept { return axis_; } const vector& axis() const
{
return axis_;
}
//- Return plane normal between the wedge boundaries //- Return plane normal between the wedge boundaries
const vector& centreNormal() const noexcept { return centreNormal_; } const vector& centreNormal() const
{
return centreNormal_;
}
//- Return the normal to the patch //- Return the normal to the patch
const vector& n() const noexcept { return n_; } const vector& n() const
{
return n_;
}
//- Return the cosine of the wedge angle //- Return the cosine of the wedge angle
scalar cosAngle() const noexcept { return cosAngle_; } scalar cosAngle() const
{
return cosAngle_;
}
//- Return face transformation tensor //- Return face transformation tensor
const tensor& faceT() const noexcept { return faceT_; } const tensor& faceT() const
{
return faceT_;
}
//- Return neighbour-cell transformation tensor //- Return neighbour-cell transformation tensor
const tensor& cellT() const noexcept { return cellT_; } const tensor& cellT() const
{
return cellT_;
}
}; };

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,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2025 OpenCFD Ltd. Copyright (C) 2019-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -92,7 +92,7 @@ public:
// Constructors // Constructors
//- Construct initialized to zero //- Construct initialized to zero
inline DiagTensor(Foam::zero); inline DiagTensor(const Foam::zero);
//- Construct given VectorSpace //- Construct given VectorSpace
template<class Cmpt2> template<class Cmpt2>
@ -123,9 +123,6 @@ public:
// Diagonal access and manipulation // Diagonal access and manipulation
//- Extract the diagonal as a vector
inline Vector<Cmpt> diag() const;
//- The L2-norm squared of the diagonal //- The L2-norm squared of the diagonal
inline scalar diagSqr() const; inline scalar diagSqr() const;
}; };

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-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -32,9 +32,9 @@ License
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Cmpt> template<class Cmpt>
inline Foam::DiagTensor<Cmpt>::DiagTensor(Foam::zero) inline Foam::DiagTensor<Cmpt>::DiagTensor(const Foam::zero)
: :
VectorSpace<DiagTensor<Cmpt>, Cmpt, 3>(Foam::zero{}) VectorSpace<DiagTensor<Cmpt>, Cmpt, 3>(Zero)
{} {}
@ -81,13 +81,6 @@ inline Foam::DiagTensor<Cmpt>::DiagTensor(Istream& is)
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Cmpt>
inline Foam::Vector<Cmpt> Foam::DiagTensor<Cmpt>::diag() const
{
return Vector<Cmpt>(this->xx(), this->yy(), this->zz());
}
template<class Cmpt> template<class Cmpt>
inline Foam::scalar Foam::DiagTensor<Cmpt>::diagSqr() const inline Foam::scalar Foam::DiagTensor<Cmpt>::diagSqr() const
{ {

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2025 OpenCFD Ltd. Copyright (C) 2019-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -94,7 +94,7 @@ public:
// Constructors // Constructors
//- Construct initialized to zero //- Construct initialized to zero
inline SymmTensor(Foam::zero); inline SymmTensor(const Foam::zero);
//- Construct given VectorSpace of the same rank //- Construct given VectorSpace of the same rank
template<class Cmpt2> template<class Cmpt2>
@ -234,12 +234,6 @@ public:
inline scalar diagSqr() const; inline scalar diagSqr() const;
// Characteristics
//- Is identity tensor?
inline bool is_identity(const scalar tol = ROOTVSMALL) const;
// Tensor Operations // Tensor Operations
//- Return non-Hermitian transpose //- Return non-Hermitian transpose

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2025 OpenCFD Ltd. Copyright (C) 2019-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -31,9 +31,9 @@ License
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Cmpt> template<class Cmpt>
inline Foam::SymmTensor<Cmpt>::SymmTensor(Foam::zero) inline Foam::SymmTensor<Cmpt>::SymmTensor(const Foam::zero)
: :
SymmTensor::vsType(Foam::zero{}) SymmTensor::vsType(Zero)
{} {}
@ -238,21 +238,6 @@ inline Foam::scalar Foam::SymmTensor<Cmpt>::diagSqr() const
} }
template<class Cmpt>
inline bool Foam::SymmTensor<Cmpt>::is_identity(const scalar tol) const
{
return
(
Foam::mag(xx() - pTraits<Cmpt>::one) < tol
&& Foam::mag(yy() - pTraits<Cmpt>::one) < tol
&& Foam::mag(zz() - pTraits<Cmpt>::one) < tol
&& Foam::mag(xy()) < tol
&& Foam::mag(xz()) < tol
&& Foam::mag(yz()) < tol
);
}
template<class Cmpt> template<class Cmpt>
inline Cmpt Foam::SymmTensor<Cmpt>::det() const inline Cmpt Foam::SymmTensor<Cmpt>::det() const
{ {

View File

@ -410,12 +410,12 @@ inline bool Foam::Tensor<Cmpt>::is_identity(const scalar tol) const
{ {
return return
( (
Foam::mag(xx() - pTraits<Cmpt>::one) < tol mag(xx() - pTraits<Cmpt>::one) < tol
&& Foam::mag(yy() - pTraits<Cmpt>::one) < tol && mag(yy() - pTraits<Cmpt>::one) < tol
&& Foam::mag(zz() - pTraits<Cmpt>::one) < tol && mag(zz() - pTraits<Cmpt>::one) < tol
&& Foam::mag(xy()) < tol && Foam::mag(xz()) < tol && mag(xy()) < tol && mag(xz()) < tol
&& Foam::mag(yx()) < tol && Foam::mag(yz()) < tol && mag(yx()) < tol && mag(yz()) < tol
&& Foam::mag(zx()) < tol && Foam::mag(zy()) < tol && mag(zx()) < tol && mag(zy()) < tol
); );
} }

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"
@ -128,26 +128,18 @@ public:
// 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
@ -155,28 +147,18 @@ public:
//- 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
inline void transformPositionList(UList<point>& pts) const;
//- Inverse transform the given position //- Inverse transform the given position
inline vector invTransformPosition(const vector& v) const; inline vector invTransformPosition(const vector& v) const;
//- Inverse transform the given field of points //- Inverse transform the given pointField
inline pointField invTransformPosition(const pointField& pts) const; inline pointField invTransformPosition(const pointField& pts) const;
//- Inplace inverse transform the given points
inline void invTransformPositionList(UList<point>& pts) const;
//- Transform the given field //- Transform the given field
template<class Type> template<class Type>
tmp<Field<Type>> transform(const Field<Type>& fld) const; tmp<Field<Type>> transform(const Field<Type>&) 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,40 +33,14 @@ 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 else
{ {
return fld; return fld;
} }
}
else
{
return fld;
}
}
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);

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