Compare commits

..

1 Commits

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

View File

@ -13,14 +13,7 @@ volVectorField U
);
// Initialise the velocity internal field to zero
// Note: explicitly bypass evaluation of contraint patch overrides
// (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();
}
U = dimensionedVector(U.dimensions(), Zero);
surfaceScalarField phi
(

View File

@ -51,7 +51,6 @@ See also
#include "IndirectList.H"
#include "SubList.H"
#include "SliceList.H"
#include "SubField.H"
#include "ListPolicy.H"
#include <list>
@ -204,6 +203,16 @@ int main(int argc, char *argv[])
Info<<" " << *iter;
}
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)
@ -272,33 +281,6 @@ int main(int argc, char *argv[])
};
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
{
{5, 3, 1},

View File

@ -1,3 +1,3 @@
Test-parallel-broadcast.cxx
Test-parallel-broadcast.C
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

View File

@ -1,3 +1,3 @@
Test-parallel-comm0.cxx
Test-parallel-comm0.C
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

View File

@ -1,3 +1,3 @@
Test-parallel-comm3a.cxx
Test-parallel-comm3a.C
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

View File

@ -1,3 +1,3 @@
Test-parallel-external-init.cxx
Test-parallel-external-init.C
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

View File

@ -131,6 +131,7 @@ int main(int argc, char *argv[])
if (probed.second > 0)
{
// Message found and had size: receive it
const label proci(probed.first);
const label count(probed.second);
@ -163,7 +164,8 @@ int main(int argc, char *argv[])
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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2025 OpenCFD Ltd.
Copyright (C) 2018-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
@ -136,7 +136,7 @@ Description
labelList patchIds;
if (doBoundary)
{
patchIds = patchSelector.indices(patches);
patchIds = getSelectedPatches(patches, patchSelector);
}
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
struct polyBoundaryPatchSelector
{
wordRes allow_;
wordRes deny_;
void clear()
if (patchSelector && !patchSelector().empty())
{
allow_.clear();
deny_.clear();
// Name-based selection
indices =
(
stringListOps::findMatching
(
patches,
patchSelector(),
nameOp<polyPatch>()
)
);
}
else
{
indices = identity(patches.size());
}
//- Forward to polyBoundaryMesh::indices() with additional handling.
// Prune emptyPolyPatch (always) and processorPolyPatch (in parallel)
labelList indices(const polyBoundaryMesh& pbm) const
// Remove undesirable patches
label count = 0;
for (const label patchi : indices)
{
labelList ids = pbm.indices(allow_, deny_);
const polyPatch& pp = patches[patchi];
const bool excludeProcPatches = UPstream::parRun();
// Prune undesirable patches
label count = 0;
for (const label patchi : ids)
if (isType<emptyPolyPatch>(pp))
{
const auto& pp = pbm[patchi];
if (isType<emptyPolyPatch>(pp))
{
continue;
}
else if (excludeProcPatches && bool(isA<processorPolyPatch>(pp)))
{
break; // No processor patches for parallel output
}
ids[count] = patchi;
++count;
continue;
}
else if (UPstream::parRun() && bool(isA<processorPolyPatch>(pp)))
{
break; // No processor patches for parallel output
}
ids.resize(count);
return ids;
indices[count] = patchi;
++count;
}
};
} // End namespace Foam
indices.resize(count);
return indices;
}
//
@ -550,38 +552,45 @@ int main(int argc, char *argv[])
}
// Patch selection/deselection
polyBoundaryPatchSelector patchSelector;
wordRes includedPatches, excludedPatches;
autoPtr<wordRes::filter> patchSelector(nullptr);
if (doBoundary)
{
if
(
auto& slot = patchSelector.allow_;
args.readListIfPresent<wordRe>("patches", slot)
)
bool resetFilter = false;
if (args.readListIfPresent<wordRe>("patches", includedPatches))
{
Info<< "Including patches " << flatOutput(slot) << nl << endl;
resetFilter = true;
Info<< "Including patches "
<< flatOutput(includedPatches) << nl << endl;
}
if
(
auto& slot = patchSelector.deny_;
args.readListIfPresent<wordRe>("exclude-patches", slot)
)
if (args.readListIfPresent<wordRe>("exclude-patches", excludedPatches))
{
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
wordRes includedFields, excludedFields;
autoPtr<wordRes::filter> fieldSelector(nullptr);
bool doConvertFields = !args.found("no-fields");
if (doConvertFields)
{
bool resetFilter = false;
if (args.readListIfPresent<wordRe>("fields", includedFields))
{
Info<< "Including fields "
<< flatOutput(includedFields) << nl << endl;
resetFilter = !includedFields.empty();
if (includedFields.empty())
{
// 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))
{
resetFilter = true;
Info<< "Excluding fields "
<< flatOutput(excludedFields) << nl << endl;
}
if (!doConvertFields)
if (resetFilter && doConvertFields)
{
includedFields.clear();
excludedFields.clear();
fieldSelector =
autoPtr<wordRes::filter>::New(includedFields, excludedFields);
}
}
else
else if (doConvertFields)
{
Info<< "Field conversion disabled with the '-no-fields' option" << nl;
}
const wordRes::filter fieldSelector(includedFields, excludedFields);
// Non-mandatory
const wordRes selectedFaceZones(args.getList<wordRe>("faceZones", false));
@ -790,10 +799,10 @@ int main(int argc, char *argv[])
IOobjectOption::NO_REGISTER
);
if (fieldSelector)
if (fieldSelector && !fieldSelector().empty())
{
objects.filterObjects(fieldSelector);
faObjects.filterObjects(fieldSelector);
objects.filterObjects(fieldSelector());
faObjects.filterObjects(fieldSelector());
}
// Remove "*_0" restart fields

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2025 OpenCFD Ltd.
Copyright (C) 2017-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
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
(
const polyBoundaryMesh& pbm,
const polyBoundaryMesh& patches,
const wordRes& allow,
const wordRes& deny,
const bool excludeProcPatches
const wordRes& deny
)
{
labelList ids = pbm.indices(allow, deny);
// Name-based selection
labelList indices
(
stringListOps::findMatching
(
patches,
allow,
deny,
nameOp<polyPatch>()
)
);
// Remove undesirable patches
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))
{
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;
}
ids.resize(count);
return ids;
indices.resize(count);
return indices;
}
@ -657,14 +668,11 @@ int main(int argc, char *argv[])
const labelList patchIds =
(
getSelectedPatches
(
bMesh,
includePatches,
excludePatches,
// No processor patches? (parallel output or excluded)
(UPstream::parRun() || !includeProcPatches)
)
(includePatches.size() || excludePatches.size())
? getSelectedPatches(bMesh, includePatches, excludePatches)
: includeProcPatches
? identity(bMesh.size())
: identity(bMesh.nNonProcessor())
);
labelList faceZoneIds;

View File

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

View File

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

View File

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

View File

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

View File

@ -1,83 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "MemoryPool.H"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
// bool Foam::MemoryPool::create(const std::string& ctrl, bool verbose)
// {
// return false;
// }
bool Foam::MemoryPool::create(bool verbose)
{
// No banner information since it is currently never an option
return false;
}
void Foam::MemoryPool::destroy(bool verbose)
{}
bool Foam::MemoryPool::active() noexcept
{
return false;
}
bool Foam::MemoryPool::suspend() noexcept
{
return false;
}
void Foam::MemoryPool::resume() noexcept
{}
bool Foam::MemoryPool::is_pool(void* ptr)
{
return false;
}
void* Foam::MemoryPool::try_allocate(std::size_t nbytes)
{
return nullptr;
}
bool Foam::MemoryPool::try_deallocate(void* ptr)
{
return (!ptr);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

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

View File

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

View File

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

View File

@ -1,510 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "MemoryPool.H"
#include "debug.H"
#include "dictionary.H"
#include "sigFpe.H"
#include "OSspecific.H" // For getEnv
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
#ifdef FOAM_USE_UMPIRE
// #include <cerrno>
#include <cinttypes>
#include <tuple>
#include "umpire/Allocator.hpp"
#include "umpire/ResourceManager.hpp"
#include "umpire/strategy/AlignedAllocator.hpp"
#include "umpire/strategy/DynamicPoolList.hpp"
static bool disabled_(false);
static umpire::Allocator aligned_allocator;
static umpire::Allocator pooled_allocator;
static umpire::ResourceManager* manager_(nullptr);
static umpire::ResourceManager* suspended_(nullptr);
#endif
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
#ifdef FOAM_USE_UMPIRE
namespace
{
// Different supported allocation types
enum class Types { undefined, none, host, device, managed };
typedef std::tuple<Types, std::size_t, std::size_t> ctrlTuple;
// Extract key=INT, the key includes the '='
int getIntParameter(const std::string& key, const std::string& ctrl)
{
int val(0);
const auto pos = ctrl.find(key);
if (pos == std::string::npos)
{
return val;
}
const char* buf = (ctrl.data() + pos + key.size());
char *endptr = nullptr;
errno = 0;
auto parsed = std::strtoimax(buf, &endptr, 10);
if (errno || endptr == buf)
{
// Some type of error OR no conversion
}
else
{
val = int(parsed);
}
return val;
}
ctrlTuple getControlValues(const std::string& ctrl)
{
ctrlTuple result(Types::undefined, 0, 0);
bool checkParam = false;
// Also find things that look like Switch constants.
// Unfortunately need to do this manually since Switch::find()
// itself would not manage to parse something like "true; size=10"
if (ctrl.empty())
{
// Nothing => undefined
}
else if
(
std::string::npos != ctrl.find("false") // ctrl.contains("false")
|| std::string::npos != ctrl.find("off") // ctrl.contains("off")
|| std::string::npos != ctrl.find("no") // ctrl.contains("no")
|| std::string::npos != ctrl.find("none") // ctrl.contains("none")
)
{
std::get<0>(result) = Types::none;
}
else if
(
std::string::npos != ctrl.find("true") // ctrl.contains("true")
|| std::string::npos != ctrl.find("on") // ctrl.contains("on")
|| std::string::npos != ctrl.find("yes") // ctrl.contains("yes")
|| std::string::npos != ctrl.find("host") // ctrl.contains("host")
|| std::string::npos != ctrl.find("system") // ctrl.contains("system")
)
{
std::get<0>(result) = Types::host;
checkParam = true;
}
// These need more testing
else if
(
std::string::npos != ctrl.find("device") // ctrl.contains("device")
)
{
std::get<0>(result) = Types::device;
checkParam = true;
}
else if
(
std::string::npos != ctrl.find("managed") // ctrl.contains("managed")
)
{
std::get<0>(result) = Types::managed;
checkParam = true;
}
if (checkParam)
{
std::get<1>(result) = getIntParameter("size=", ctrl);
std::get<2>(result) = getIntParameter("incr=", ctrl);
}
return result;
}
bool create_from(const ctrlTuple& controls, bool verbose)
{
using namespace Foam;
if (manager_ || suspended_)
{
// Already created
return true;
}
// Type, initial size, increment
auto [which, size, incr] = controls;
// std::cerr
// << "which=" << int(which)
// << ", size=" << int(size)
// << ", incr=" << int(incr) << '\n';
constexpr size_t MegaByte(1024*1024);
switch (which)
{
case Types::undefined :
{
if (verbose)
{
Info<< "memory pool : unused" << nl;
}
break;
}
case Types::none :
{
if (verbose)
{
Info<< "memory pool : disabled" << nl;
}
break;
}
case Types::host :
{
// Default sizing parameters
if (!size) size = 1024;
if (!incr) incr = 5;
auto& rm = umpire::ResourceManager::getInstance();
manager_ = &rm;
aligned_allocator =
rm.makeAllocator<umpire::strategy::AlignedAllocator>
(
"aligned_allocator",
rm.getAllocator("HOST"),
// alignment
256
);
pooled_allocator =
rm.makeAllocator<umpire::strategy::DynamicPoolList>
(
"openfoam_HOST_pool",
aligned_allocator,
// initial block allocation size
(size*MegaByte),
// incremental block allocation size
(incr*MegaByte)
);
if (verbose)
{
Info<< "memory pool : host (size="
<< int(size) << "MB, incr="
<< int(incr) << "MB)\n";
}
break;
}
case Types::device :
{
auto& rm = umpire::ResourceManager::getInstance();
manager_ = &rm;
aligned_allocator = rm.getAllocator("DEVICE");
pooled_allocator =
rm.makeAllocator<umpire::strategy::DynamicPoolList>
(
"openfoam_DEVICE_pool",
aligned_allocator
);
if (verbose)
{
Info<< "memory pool : device" << nl;
}
break;
}
case Types::managed :
{
// Default sizing parameters
if (!size) size = 10*1024;
if (!incr) incr = 10;
auto& rm = umpire::ResourceManager::getInstance();
manager_ = &rm;
aligned_allocator = rm.getAllocator("UM");
pooled_allocator =
rm.makeAllocator<umpire::strategy::DynamicPoolList>
(
"openfoam_UM_pool",
aligned_allocator,
// initial block allocation size
(size*MegaByte),
// incremental block allocation size
(incr*MegaByte)
);
if (verbose)
{
Info<< "memory pool : managed (size="
<< int(size) << "MB, incr="
<< int(incr) << "MB)\n";
}
break;
}
}
return (which != Types::undefined && which != Types::none);
}
} // End anonymous namespace
#endif // FOAM_USE_UMPIRE
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
// bool Foam::MemoryPool::create(const std::string& ctrl, bool verbose)
// {
// #ifdef FOAM_USE_UMPIRE
// if (manager_ || suspended_)
// {
// // Already created
// return true;
// }
//
// auto controls = getControlValues(ctrl);
//
// return create_from(controls, verbose);
// #else
// return false;
// #endif
// }
bool Foam::MemoryPool::create(bool verbose)
{
#ifdef FOAM_USE_UMPIRE
if (disabled_)
{
// Disallowed
return false;
}
else if (manager_ || suspended_)
{
// Already created
return true;
}
// First check environment
auto controls = getControlValues(Foam::getEnv("FOAM_MEMORY_POOL"));
if (std::get<0>(controls) == Types::none)
{
// Disabled from environment - has highest priority
disabled_ = true;
}
// Currently no easy way to handle <system>/controlDict...
// Fallback from etc/controlDict
if (std::get<0>(controls) == Types::undefined)
{
// From central etc/controlDict
const auto& dict = Foam::debug::optimisationSwitches();
if (auto* eptr = dict.findStream("memory_pool", keyType::LITERAL))
{
const token& firstToken = eptr->front();
if (firstToken.isStringType())
{
controls = getControlValues(firstToken.stringToken());
}
}
}
return create_from(controls, verbose);
#else
if (verbose)
{
Info<< "memory pool : not available" << nl;
}
return false;
#endif
}
void Foam::MemoryPool::destroy(bool verbose)
{
// Nothing currently needed but could add in something like this:
// if (manager_ || suspended_)
// {
// pooled_allocator.release();
// }
// However, need to find the proper sequence within
// Foam::exit() or UPstream::exit() ...
}
bool Foam::MemoryPool::active() noexcept
{
#ifdef FOAM_USE_UMPIRE
return bool(manager_);
#else
return false;
#endif
}
bool Foam::MemoryPool::suspend() noexcept
{
#ifdef FOAM_USE_UMPIRE
bool status(suspended_);
if (manager_) // <- and (!suspended_)
{
std::swap(manager_, suspended_);
}
return status;
#else
return false;
#endif
}
void Foam::MemoryPool::resume() noexcept
{
#ifdef FOAM_USE_UMPIRE
if (suspended_) // <- and (!manager_)
{
std::swap(manager_, suspended_);
}
#endif
}
bool Foam::MemoryPool::is_pool(void* ptr)
{
#ifdef FOAM_USE_UMPIRE
if (ptr)
{
if (manager_)
{
return manager_->hasAllocator(ptr);
}
else if (suspended_)
{
return suspended_->hasAllocator(ptr);
}
}
#endif
return false;
}
void* Foam::MemoryPool::try_allocate(std::size_t nbytes)
{
void* ptr = nullptr;
#ifdef FOAM_USE_UMPIRE
if (manager_)
{
ptr = pooled_allocator.allocate(nbytes);
// std::cerr<< "allocate(" << int(nbytes) << ")\n";
// Optionally fill with NaN (depends on current flags)
Foam::sigFpe::fillNan_if(ptr, nbytes);
if (!ptr)
{
// Pout<< "umpire failed to allocate memory\n";
}
}
#endif
return ptr;
}
bool Foam::MemoryPool::try_deallocate(void* ptr)
{
#ifdef FOAM_USE_UMPIRE
if (ptr)
{
if (manager_)
{
if (manager_->hasAllocator(ptr)) // <- ie, is_pool()
{
// std::cerr<< "deallocate()\n";
manager_->deallocate(ptr);
return true;
}
}
else if (suspended_)
{
// Deallocate even if nominally suspended
if (suspended_->hasAllocator(ptr)) // <- ie, is_pool()
{
// std::cerr<< "deallocate()\n";
suspended_->deallocate(ptr);
return true;
}
}
}
#endif
return (!ptr);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -203,7 +203,7 @@ public:
//- Change the value for the list capacity directly (ADVANCED, UNSAFE)
//- 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
//- space if required and \em retaining old content.
@ -251,6 +251,11 @@ public:
//- Shrink the allocated space to the number of elements used.
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

View File

@ -68,9 +68,7 @@ inline void Foam::DynamicList<T, SizeMin>::doCapacity
// Addressable length, possibly truncated by new capacity
const label currLen = Foam::min(List<T>::size(), newCapacity);
// Consistent allocated sizing
List<T>::setAddressableSize(capacity_);
if (nocopy)
{
List<T>::resize_nocopy(newCapacity);
@ -97,9 +95,6 @@ inline void Foam::DynamicList<T, SizeMin>::doReserve
// Preserve addressed size
const label currLen = List<T>::size();
// Consistent allocated sizing
List<T>::setAddressableSize(capacity_);
// Increase capacity (eg, doubling)
capacity_ =
Foam::ListPolicy::reserve_size<SizeMin, 2>(len, capacity_);
@ -110,10 +105,8 @@ inline void Foam::DynamicList<T, SizeMin>::doReserve
}
else
{
List<T>::resize_copy(currLen, capacity_);
List<T>::resize(capacity_);
}
capacity_ = List<T>::size();
List<T>::setAddressableSize(currLen);
}
}
@ -278,7 +271,7 @@ inline Foam::DynamicList<T, SizeMin>::DynamicList
List<T>(std::move(static_cast<List<T>&>(list))),
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))),
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
const label currLen = List<T>::size();
// Consistent allocated sizing
List<T>::setAddressableSize(capacity_);
// if (!nocopy)
{
List<T>::resize_copy(currLen, len);
}
capacity_ = List<T>::size();
capacity_ = len;
List<T>::resize(capacity_);
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>
inline void
Foam::DynamicList<T, SizeMin>::swap(List<T>& list)

View File

@ -236,6 +236,13 @@ public:
// Otherwise the contents will be uninitialized.
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()
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>
inline T& Foam::List<T>::newElmt(const label i)
{

View File

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

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2017-2025 OpenCFD Ltd.
Copyright (C) 2017-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
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.
//
// \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 val The value for searching/comparing
@ -507,7 +508,7 @@ label findSortedIndex
// <code> lessOp<T>(list[i], val) </code> for the test.
//
// \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
// returns true for sorting below.
//
@ -584,33 +585,23 @@ namespace ListOps
template<class T>
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
template<class T>
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
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
//- A list compare binary predicate for normal sort

View File

@ -1081,7 +1081,7 @@ template<class T>
void Foam::ListOps::appendEqOp<T>::operator()
(
List<T>& x,
const UList<T>& y
const List<T>& y
) const
{
if (y.size())
@ -1102,7 +1102,7 @@ template<class T>
void Foam::ListOps::uniqueEqOp<T>::operator()
(
List<T>& x,
const UList<T>& y
const List<T>& y
) const
{
if (y.size())
@ -1111,7 +1111,6 @@ void Foam::ListOps::uniqueEqOp<T>::operator()
{
for (const T& val : y)
{
// Not very efficient
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>
Foam::label Foam::ListOps::count_if
(

View File

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

View File

@ -112,26 +112,23 @@ public:
//- Change the value for the list capacity directly (ADVANCED, UNSAFE)
//- 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.
// New entries are initialized to nullptr.
inline void reserve(const label len);
//- Reserve allocation space for at least this size.
//- If allocation is required, uses the specified size
//- without any other resizing logic.
// New entries are initialized to nullptr.
inline void reserve_exact(const label len);
//- Alter the addressed list size.
// New entries are initialized to nullptr.
inline void resize(const label len);
inline void resize(const label newLen);
//- Set the addressed list to the given size,
//- deleting all existing 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.
// Allocated size does not change
@ -143,6 +140,11 @@ public:
//- Shrink the allocated space to the number of elements used.
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()
void shrink() { this->shrink_to_fit(); }

View File

@ -82,7 +82,10 @@ inline Foam::PtrDynList<T, SizeMin>::PtrDynList
PtrList<T>(std::move(list)),
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)),
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
const label currLen = PtrList<T>::size();
// Consistent allocated sizing
PtrList<T>::setAddressableSize(capacity_);
// Increase capacity (eg, doubling)
capacity_ =
Foam::ListPolicy::reserve_size<SizeMin, 2>(len, capacity_);
// No PtrList<T>::resize_copy(...) -> copying nullptr is cheap
PtrList<T>::resize(capacity_);
capacity_ = PtrList<T>::size();
PtrList<T>::setAddressableSize(currLen);
}
}
@ -153,13 +153,8 @@ inline void Foam::PtrDynList<T, SizeMin>::reserve_exact(const label len)
// Preserve addressed size
const label currLen = PtrList<T>::size();
// Consistent allocated sizing
PtrList<T>::setAddressableSize(capacity_);
// No PtrList<T>::resize_copy(...) -> copying nullptr is cheap
PtrList<T>::resize(len);
capacity_ = PtrList<T>::size();
capacity_ = len;
PtrList<T>::resize(capacity_);
PtrList<T>::setAddressableSize(currLen);
}
}
@ -169,12 +164,16 @@ template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::resize(const label newLen)
{
auto& ptrs = this->ptrs_;
const label oldLen = ptrs.size();
if (capacity_ < newLen)
{
// Extend list
this->reserve(newLen);
// Increase capacity (eg, doubling)
capacity_ =
Foam::ListPolicy::reserve_size<SizeMin, 2>(newLen, capacity_);
PtrList<T>::resize(capacity_);
}
else if (newLen != oldLen)
{
@ -192,16 +191,13 @@ inline void Foam::PtrDynList<T, SizeMin>::resize(const label newLen)
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)
capacity_ =
Foam::ListPolicy::reserve_size<SizeMin, 2>(len, capacity_);
Foam::ListPolicy::reserve_size<SizeMin, 2>(newLen, capacity_);
PtrList<T>::resize_null(capacity_);
}
@ -211,7 +207,7 @@ inline void Foam::PtrDynList<T, SizeMin>::resize_null(const label len)
}
// 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>
inline Foam::label Foam::PtrDynList<T, SizeMin>::squeezeNull()
{

View File

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

View File

@ -179,9 +179,6 @@ public:
// Public Classes
//- Wrapper for OpenFOAM internal communicator index
class communicator; // Forward Declaration
//- Wrapper for MPI_Comm
class Communicator; // Forward Declaration
@ -381,25 +378,6 @@ public:
//- Print un-directed graph in graphviz dot format
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
);
//- Create new communicator with sub-ranks on the parent communicator
//- Creaet new communicator with sub-ranks on the parent communicator
static label newCommunicator
(
//! The parent communicator
@ -918,6 +896,126 @@ public:
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
//- worldComm) given communicator and processor
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

View File

@ -470,10 +470,18 @@ public:
//- Copy append a list of tokens at the current tokenIndex,
//- 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);
//- Move append a list of tokens at the current tokenIndex,
//- 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);

View File

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

View File

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

View File

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

View File

@ -217,7 +217,7 @@ public:
//- Change the value for the list capacity directly (ADVANCED, UNSAFE)
//- 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
//- space if required and \em retaining old content.
@ -265,6 +265,11 @@ public:
//- Shrink the allocated space to the number of elements used.
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

View File

@ -66,9 +66,7 @@ inline void Foam::DynamicField<T, SizeMin>::doCapacity
// Addressable length, possibly truncated by new capacity
const label currLen = Foam::min(List<T>::size(), newCapacity);
// Consistent allocated sizing
List<T>::setAddressableSize(capacity_);
if (nocopy)
{
List<T>::resize_nocopy(newCapacity);
@ -95,9 +93,6 @@ inline void Foam::DynamicField<T, SizeMin>::doReserve
// Preserve addressed size
const label currLen = List<T>::size();
// Consistent allocated sizing
List<T>::setAddressableSize(capacity_);
// Increase capacity (eg, doubling)
capacity_ =
Foam::ListPolicy::reserve_size<SizeMin, 2>(len, capacity_);
@ -108,10 +103,8 @@ inline void Foam::DynamicField<T, SizeMin>::doReserve
}
else
{
List<T>::resize_copy(currLen, capacity_);
List<T>::resize(capacity_);
}
capacity_ = List<T>::size();
List<T>::setAddressableSize(currLen);
}
}
@ -253,7 +246,7 @@ inline Foam::DynamicField<T, SizeMin>::DynamicField
Field<T>(std::move(static_cast<List<T>&>(content))),
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))),
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))),
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));
capacity_ = content.capacity();
content.setCapacity_unsafe(0); // All contents moved
content.setCapacity_unsafe(0);
}
else
{
@ -324,7 +317,7 @@ inline Foam::DynamicField<T, SizeMin>::DynamicField
{
Field<T>::transfer(static_cast<List<T>&>(content));
capacity_ = content.capacity();
content.setCapacity_unsafe(0); // All contents moved
content.setCapacity_unsafe(0);
}
else
{
@ -469,15 +462,8 @@ inline void Foam::DynamicField<T, SizeMin>::reserve_exact
// Preserve addressed size
const label currLen = List<T>::size();
// Consistent allocated sizing
List<T>::setAddressableSize(capacity_);
// if (!nocopy)
{
List<T>::resize_copy(currLen, len);
}
capacity_ = List<T>::size();
capacity_ = len;
List<T>::resize(capacity_);
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>
inline void
Foam::DynamicField<T, SizeMin>::swap(List<T>& list)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,116 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::MemoryPool
Description
Optional memory management using a memory pool such as Umpire
(https://github.com/LLNL/Umpire).
When compiled with Umpire, its use can be controlled by the
\c FOAM_MEMORY_POOL environment variable, or the
\c memory_pool Optimisation switch (etc/controlDict).
It currently looks for any of the following entries, in this order:
- true - same as \em "host"
- false/none - disabled.
- \em "host" - uses host memory pool
- \em "system" - same as \em "host"
- \em "device" - uses device memory pool
- \em "managed" - uses managed host/device memory pool
.
The parameters "size=nn" and "incr=nn" (in MegaBytes) can be used
to specify alternatives to the default sizing.
\*---------------------------------------------------------------------------*/
#ifndef Foam_MemoryPool_H
#define Foam_MemoryPool_H
#include <cstdint> // For size_t
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class MemoryPool Declaration
\*---------------------------------------------------------------------------*/
class MemoryPool
{
public:
// Constructors
//- Create a memory pool instance (if not already active).
// Uses environment or etc/controlDict entry
static bool create(bool verbose = false);
// Destructor
//- Remove the memory pool instance (currently does nothing)
static void destroy(bool verbose = false);
// Member Functions
//- True if pool is active (ie, created and not suspended)
static bool active() noexcept;
//- Suspend use of memory pool (for allocation).
// \return previous suspend status
static bool suspend() noexcept;
//- Resume use of memory pool (if previously active)
static void resume() noexcept;
//- Test if given pointer belongs to the pool
static bool is_pool(void *ptr);
//- Allocate from pool (if active).
// \returns nullptr if the pool is not active
static void* try_allocate(std::size_t nbytes);
//- Deallocate a pointer managed by the pool
// \returns True if a nullptr (no-op) or when the pointer was
// managed by the pool.
static bool try_deallocate(void *ptr);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

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

View File

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

View File

@ -40,6 +40,96 @@ namespace Foam
// * * * * * * * * * * * * * 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
{
mapDistributeBase::printLayout(os);

View File

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

View File

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

View File

@ -35,7 +35,7 @@ License
template<class T, class CombineOp, class NegateOp>
void Foam::mapDistributeBase::flipAndCombine
(
UList<T>& lhs,
List<T>& lhs,
const UList<T>& rhs,
const labelUList& map,
@ -46,9 +46,6 @@ void Foam::mapDistributeBase::flipAndCombine
{
const label len = map.size();
// FULLDEBUG: if (lhs.size() < max(map)) FatalError ...;
// FULLDEBUG: if (rhs.size() < len) FatalError ...;
if (hasFlip)
{
for (label i = 0; i < len; ++i)
@ -85,7 +82,7 @@ void Foam::mapDistributeBase::flipAndCombine
template<class T, class NegateOp>
void Foam::mapDistributeBase::accessAndFlip
(
UList<T>& output,
List<T>& output,
const UList<T>& values,
const labelUList& map,
const bool hasFlip,
@ -94,7 +91,6 @@ void Foam::mapDistributeBase::accessAndFlip
{
const label len = map.size();
// FULLDEBUG: if (values.size() < max(map)) FatalError ...;
// FULLDEBUG: if (output.size() < len) FatalError ...;
if (hasFlip)
@ -451,7 +447,7 @@ template<class T, class CombineOp, class NegateOp>
void Foam::mapDistributeBase::distribute
(
const UPstream::commsTypes commsType,
const UList<labelPair>& schedule,
const List<labelPair>& schedule,
const label constructSize,
const labelListList& subMap,
const bool subHasFlip,
@ -898,7 +894,7 @@ template<class T, class NegateOp>
void Foam::mapDistributeBase::distribute
(
const UPstream::commsTypes commsType,
const UList<labelPair>& schedule,
const List<labelPair>& schedule,
const label constructSize,
const labelListList& subMap,
const bool subHasFlip,
@ -1336,7 +1332,7 @@ template<class T>
void Foam::mapDistributeBase::send
(
PstreamBuffers& pBufs,
const UList<T>& field
const List<T>& field
) const
{
// Stream data into buffer
@ -1486,11 +1482,13 @@ void Foam::mapDistributeBase::distribute
const int tag
) 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 * * * * * * * * * * * //
template<class T>
void Foam::mapDistribute::applyDummyTransforms(UList<T>& field) const
void Foam::mapDistribute::applyDummyTransforms(List<T>& field) const
{
forAll(transformElements_, trafoI)
{
@ -51,7 +51,7 @@ void Foam::mapDistribute::applyDummyTransforms(UList<T>& field) const
template<class T>
void Foam::mapDistribute::applyDummyInverseTransforms(UList<T>& field) const
void Foam::mapDistribute::applyDummyInverseTransforms(List<T>& field) const
{
forAll(transformElements_, trafoI)
{
@ -70,7 +70,7 @@ template<class T, class TransformOp> //, class CombineOp>
void Foam::mapDistribute::applyTransforms
(
const globalIndexAndTransform& globalTransforms,
UList<T>& field,
List<T>& field,
const TransformOp& top
) const
{
@ -100,7 +100,7 @@ template<class T, class TransformOp> //, class CombineOp>
void Foam::mapDistribute::applyInverseTransforms
(
const globalIndexAndTransform& globalTransforms,
UList<T>& field,
List<T>& field,
const TransformOp& top
) const
{
@ -193,11 +193,13 @@ void Foam::mapDistribute::distribute
const int tag
) 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
forAll(patches, patchi)
{
if (groupLookup.empty())
{
break; // Early termination
}
else if (groupLookup.erase(patches[patchi].name()))
if (groupLookup.erase(patches[patchi].name()))
{
WarningInFunction
<< "Removed group '" << patches[patchi].name()
@ -786,7 +782,7 @@ Foam::labelList Foam::polyBoundaryMesh::indices
// Only check groups if requested and they exist
const bool checkGroups = (useGroups && this->hasGroupIDs());
labelHashSet ids;
labelHashSet ids(0);
if (matcher.isPattern())
{
@ -854,7 +850,7 @@ Foam::labelList Foam::polyBoundaryMesh::indices
return this->indices(matcher.front(), useGroups);
}
labelHashSet ids;
labelHashSet ids(0);
// Only check groups if requested and they exist
if (useGroups && this->hasGroupIDs())
@ -887,20 +883,19 @@ Foam::labelList Foam::polyBoundaryMesh::indices
Foam::labelList Foam::polyBoundaryMesh::indices
(
const wordRes& allow,
const wordRes& deny,
const wordRes& select,
const wordRes& ignore,
const bool useGroups
) const
{
if (allow.empty() && deny.empty())
if (ignore.empty())
{
// Fast-path: select all
return identity(this->size());
return this->indices(select, useGroups);
}
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
if (useGroups && this->hasGroupIDs())
@ -1074,7 +1069,7 @@ Foam::labelHashSet Foam::polyBoundaryMesh::patchSet
const bool useGroups
) const
{
labelHashSet ids;
labelHashSet ids(0);
if (select.empty())
{
return ids;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -6,7 +6,6 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -61,13 +60,6 @@ Foam::vectorTensorTransform::vectorTensorTransform(Istream& is)
// * * * * * * * * * * * * * * * 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)
{
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 * * * * * * * * * * * * //
Foam::Istream& Foam::operator>>(Istream& is, vectorTensorTransform& tr)

View File

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

View File

@ -6,7 +6,6 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -67,10 +66,35 @@ inline Foam::vectorTensorTransform::vectorTensorTransform(const tensor& R)
// * * * * * * * * * * * * * * * 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
// hasR to true
hasR_ = true;
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
(
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 * * * * * * * * * * * * * //
inline void Foam::vectorTensorTransform::operator&=

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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