Compare commits

...

33 Commits

Author SHA1 Message Date
c6f87c961a ENH: GAMGAgglomeration: updateInterval also for static mesh. Fixes #3387 2025-07-08 14:32:39 +01:00
4eaa76c835 ENH: GAMGAgglomeration: optional name. Fixes #3332 2025-06-18 17:16:24 +01:00
2b0e4dc97a ENH: potentialFoam: allow swirl bc. See #3211
Bypasses the constraint override. Contentious -
does field algebra or boundary constraints take
priority.
2025-06-16 17:13:31 +01:00
e803646228 Merge branch 'consistent-handling-of-filtered-names' into 'develop'
consistent handling of filtered patch/zone names. More inGroups handling for utilities etc.

See merge request Development/openfoam!748
2025-06-13 14:17:48 +01:00
be278abcc0 ENH: revise patch group selection to ensightMesh
- supports inGroup while also respecting allow/deny semantics

- support inGroup for cellZone/faceZone selection
2025-06-13 10:29:32 +02:00
93f980834b ENH: support patch group selection
- vtkWrite, foamToVTK, surfaceMeshExtract
2025-06-13 10:29:32 +02:00
e8dce32b0a ENH: consistent handling of filtered patch/zone names
- the indices(const wordRes& allow, const wordRes& deny) methods
  were not defined consistently with the wordRes::filter handling.

  wordRes::filter - allow/deny both empty:
      = no filtering (ie, accept everything)

  indices(allow,deny) - allow/deny both empty:
     = return identity list (NEW behaviour)
     = return empty list (OLD behaviour)

  Consider the old behaviour a minor bug since the limited number of
  callers had their own checks that avoided the poor behaviour.

  Example of the inconsistent behaviour:

     pbm.indices(wordRes(), wordRes({"non-existent"}))
        --> identity list (old, new behaviour)

     pbm.indices(wordRes(), wordRes())
         --> identity list (new behaviour)
         --> empty list    (old behaviour)
2025-06-13 09:15:58 +02:00
91925871d9 Merge branch 'fix-3374-questionable-const_cast' into 'develop'
avoid casting workarounds for syncTools::syncBoundaryFaceList

See merge request Development/openfoam!747
2025-06-12 12:49:26 +00:00
a5090c37a3 ENH: minor improvements to UPstream::communicator wrapper class
- robuster reset() method that handles self-assignment
- additional swap() and constCast() methods

STYLE: relocate UPstream::communicator declarations within header
2025-06-12 13:13:26 +02:00
0d7816b7fd ENH: avoid questionable const_cast of SubList (#3374) 2025-06-12 13:13:26 +02:00
9bdb75eeef ENH: add ListOps::equal() function
- tests for list equality with different but compatible data types.
  Eg, when comparing lists of int32 and int64 values.

STYLE: pass UList instead of List references into ListOps functors
2025-06-12 13:13:26 +02:00
a860d48637 ENH: make some vectorTensorTransform methods inplace
- avoids intermediate allocation and re-assignment to self (#3374)

BUG: checkMesh (application) with questionable memory handling (#3374)

- move the contents of the new points instead of attempting to transfer
  the entire list

COMP: replace mapDistribute specializations with if constexpr handling

- simplify future maintenance
2025-06-12 13:13:26 +02:00
97296043c0 ENH: snappyHexMesh: more warnings. See #3377
This one only tackles the per-region for refinementSurfaces.
Other ones tbd.
2025-06-12 10:10:16 +01:00
6bdceaf29f BUG: AMI: local communicators. Fixes #3376 2025-06-11 16:39:48 +01:00
34df4eaf40 ENH: ensightWrite: allow inGroup names in patches and excludePatches 2025-06-11 13:36:14 +01:00
75b2d0b656 BUG: masterStream forwards without communicator (fixes #3373)
- in messageStream::masterStream(int), it forwarded to stream()
  without the communicator, which meant it would incorrectly check
  UPstream::master(worldComm) and possibly not produce any output (or
  block).
2025-06-10 15:20:11 +02:00
9bc6f2f91f ENH: support 'rpm' input for propeller functionObject (as per rotorDisk)
- update code style for forces/propeller.
- simplify coordinate handling in propeller functionObject
2025-06-10 10:32:03 +02:00
96872f031f Merge branch 'feature-orientedSurface' into 'develop'
ENH: snappyHexMesh: work better on non-manifold. Fixes ##3361

See merge request Development/openfoam!740
2025-06-09 15:12:47 +00:00
55d89ac4d6 ENH: snappyHexMesh: work better on non-manifold. Fixes ##3361 2025-06-09 15:12:47 +00:00
fe0ba07a7a SUBMODULE: update OpenQBMM for v2506 2025-06-05 16:06:56 +02:00
164a3e8330 ENH: IOstream::unsetf() now returns old flags (eg, for toggling)
ENH: align MPI_Probe non-blocking handling with header description

- the header states that the commsType is non-blocking or not,
  but the implementation actually checked for 'buffered' or not.

STYLE: fix some spacing and some documentation
2025-06-05 16:06:56 +02:00
2f6581133c ENH: preserve matrix manipulation state in boundary consistency check
- add placeholder methods in faPatchField and move setter functions
  from protected to public access.
2025-06-05 15:09:25 +02:00
9e8e14e448 TUT: minor tutorial cleanup
- use functionObject writeInterval not timeInterval.
  No change in behaviour since the missing writeInterval is treated
  as '1' anyhow when using 'timeStep' for the writeControl

- consistent use of 'adjustable' vs 'adjustableRunTime'

- prefer '#eval{ vector(...) }' to calling '#eval' multiple times
2025-06-04 16:39:34 +02:00
ffea136955 BUG: correct constant definition in sigma LES model (fixes #3371) 2025-06-03 20:04:17 +01:00
5dbc2e5890 Merge branch 'patch_specializations' into 'develop'
Simplify specialization of patch fields, consolidate boundary evaluation

See merge request Development/openfoam!743
2025-05-29 11:20:25 +00:00
1be6991d3f CONFIG: set API level to 2502
- changes in patchField signatures
2025-05-28 17:50:55 +02:00
25139e492e ENH: replace patchField specializations with if constexpr
- simplifies future code changes

STYLE: noexcept access for wedgePatch methods
2025-05-28 17:50:55 +02:00
0189311026 ENH: avoid unneeded transform operations for scalar pointField BCs 2025-05-28 17:50:55 +02:00
d6e6450834 ENH: add missing construct GeometricField from primitive field (tmp)
ENH: improvements for GeometricBoundaryField evaluation

- early termination from evaluate_if() and evaluateCoupled().

- evaluateCoupled() now forwards to evaluate_if() and receives
  additional handling for a 'void' parameter type.

BREAKING: extra template parameter for overset correctBoundaryCondition

- the true/false flag as a template parameter instead of as an
  argument to use 'if constexpr' code
2025-05-28 17:50:55 +02:00
1d6c77f8f4 ENH: complement lookupPatchField with cfindPatchField
- encapsulates (foundObject && lookupPatchField) together,
  similar to cfindObject

STYLE: remove unnecessary dummy parameters from lookupPatchField

- these were a workaround for a very old gcc bug and are no longer
  needed. However, retain the (unneeded) second template parameter to
  continue with not breaking existing old code - it has no overhead.
2025-05-28 14:42:27 +02:00
83e73e4024 BREAKING: change in signature for {fa,fv}PatchField::patchInternalField()
Signature:

    void patchInternalField(UList<Type>& pfld) const;
    // OLD: void patchInternalField(Field<Type>& pfld) const;

    This change is necessary to allow collection into slices of a
    larger list.

ENH: add {fa,fv}PatchField::patchNeighbourField(UList<Type>&)

- a retrieval version similar to patchInternalField(...)

STYLE: adjust AMI patch field private method names

- rename private method

      patchNeighbourField(...) -> getNeighbourField(...)

  to avoid access clashes with public methods

- remove undefined method neighbourSideField()
2025-05-28 14:42:18 +02:00
8d9f4c54f3 COMP: suppress false positives from -Wdangling-reference (gcc)
- the number of false positives has reduced, but in a few remaining
  cases, the compiler cannot possibly "know" that the pointer stored
  on the registry will outlive the scope of the method (for example)

  gcc-13: suppressing these spurious warnings needs to be done at each
  caller, which is simply not worth it, since later compiler versions
  provide a cleaner solution.

  gcc-14: the [[gnu::no_dangling]] attribute on the declaration
  lets the compiler know the intent.

- additional FOAM_REAL_GNUC macro (defined in stdFoam.H) to define
  the "real" gcc version and ignoring other compilers masquerading
  as gcc.

COMP: rename MeshObject code to {cxx,txx}

- avoids issues on case-insensitive filesystems (#3316)
2025-05-27 18:25:58 +02:00
f7c8bfdce0 STYLE: retrieve tensor diagonal directly instead of via diagTensor 2025-05-27 11:09:27 +02:00
245 changed files with 3207 additions and 2723 deletions

View File

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

View File

@ -13,7 +13,14 @@ volVectorField U
);
// Initialise the velocity internal field to zero
U = dimensionedVector(U.dimensions(), 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();
}
surfaceScalarField phi
(

View File

@ -51,6 +51,7 @@ See also
#include "IndirectList.H"
#include "SubList.H"
#include "SliceList.H"
#include "SubField.H"
#include "ListPolicy.H"
#include <list>
@ -281,6 +282,33 @@ 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.C
Test-parallel-broadcast.cxx
EXE = $(FOAM_USER_APPBIN)/Test-parallel-broadcast

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -131,7 +131,6 @@ 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);
@ -164,8 +163,7 @@ int main(int argc, char *argv[])
scalarField fld(is);
Info<< "from [" << probed.first
<< "] : " << flatOutput(fld) << endl;
Info<< "from [" << proci << "] : " << flatOutput(fld) << endl;
}
}

View File

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

View File

@ -1,3 +1,3 @@
Test-parallel-waitSome.C
Test-parallel-waitSome.cxx
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: v2412 |
| \\ / O peration | Version: v2506 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
@ -26,7 +26,7 @@ stopAt writeNow;
endTime 4;
writeControl adjustableRunTime;
writeControl adjustable;
writeInterval 0.1;

View File

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

View File

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

View File

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

View File

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

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021-2023 OpenCFD Ltd.
Copyright (C) 2021-2025 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 && !fieldSelector().empty())
if (fieldSelector)
{
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-2022 OpenCFD Ltd.
Copyright (C) 2016-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -406,34 +406,27 @@ 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 if (doConvertFields)
else
{
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-2023 OpenCFD Ltd.
Copyright (C) 2018-2025 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 = getSelectedPatches(patches, patchSelector);
patchIds = patchSelector.indices(patches);
}
if (oneBoundary && patchIds.size())

View File

@ -166,56 +166,54 @@ Note
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
labelList getSelectedPatches
(
const polyBoundaryMesh& patches,
const autoPtr<wordRes::filter>& patchSelector
)
namespace Foam
{
labelList indices;
if (patchSelector && !patchSelector().empty())
// Simple wrapper for polyBoundaryMesh::indices() with some additional logic
struct polyBoundaryPatchSelector
{
wordRes allow_;
wordRes deny_;
void clear()
{
// Name-based selection
indices =
(
stringListOps::findMatching
(
patches,
patchSelector(),
nameOp<polyPatch>()
)
);
}
else
{
indices = identity(patches.size());
allow_.clear();
deny_.clear();
}
// Remove undesirable patches
label count = 0;
for (const label patchi : indices)
//- Forward to polyBoundaryMesh::indices() with additional handling.
// Prune emptyPolyPatch (always) and processorPolyPatch (in parallel)
labelList indices(const polyBoundaryMesh& pbm) const
{
const polyPatch& pp = patches[patchi];
labelList ids = pbm.indices(allow_, deny_);
if (isType<emptyPolyPatch>(pp))
const bool excludeProcPatches = UPstream::parRun();
// Prune undesirable patches
label count = 0;
for (const label patchi : ids)
{
continue;
}
else if (UPstream::parRun() && bool(isA<processorPolyPatch>(pp)))
{
break; // No processor patches for parallel output
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;
}
indices[count] = patchi;
++count;
ids.resize(count);
return ids;
}
};
indices.resize(count);
return indices;
}
} // End namespace Foam
//
@ -552,45 +550,38 @@ int main(int argc, char *argv[])
}
// Patch selection/deselection
wordRes includedPatches, excludedPatches;
autoPtr<wordRes::filter> patchSelector(nullptr);
polyBoundaryPatchSelector patchSelector;
if (doBoundary)
{
bool resetFilter = false;
if (args.readListIfPresent<wordRe>("patches", includedPatches))
if
(
auto& slot = patchSelector.allow_;
args.readListIfPresent<wordRe>("patches", slot)
)
{
resetFilter = true;
Info<< "Including patches "
<< flatOutput(includedPatches) << nl << endl;
Info<< "Including patches " << flatOutput(slot) << nl << endl;
}
if (args.readListIfPresent<wordRe>("exclude-patches", excludedPatches))
if
(
auto& slot = patchSelector.deny_;
args.readListIfPresent<wordRe>("exclude-patches", slot)
)
{
resetFilter = true;
Info<< "Excluding patches "
<< flatOutput(excludedPatches) << nl << endl;
}
if (resetFilter)
{
patchSelector =
autoPtr<wordRes::filter>::New(includedPatches, excludedPatches);
Info<< "Excluding patches " << flatOutput(slot) << nl << endl;
}
}
// 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)
@ -603,22 +594,22 @@ int main(int argc, char *argv[])
}
if (args.readListIfPresent<wordRe>("exclude-fields", excludedFields))
{
resetFilter = true;
Info<< "Excluding fields "
<< flatOutput(excludedFields) << nl << endl;
}
if (resetFilter && doConvertFields)
if (!doConvertFields)
{
fieldSelector =
autoPtr<wordRes::filter>::New(includedFields, excludedFields);
includedFields.clear();
excludedFields.clear();
}
}
else if (doConvertFields)
else
{
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));
@ -799,10 +790,10 @@ int main(int argc, char *argv[])
IOobjectOption::NO_REGISTER
);
if (fieldSelector && !fieldSelector().empty())
if (fieldSelector)
{
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-2017 OpenFOAM Foundation
Copyright (C) 2018-2023 OpenCFD Ltd.
Copyright (C) 2018-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -39,74 +39,23 @@ namespace Foam
{
template<class Type>
void evaluateConstraintTypes(GeometricField<Type, fvPatchField, volMesh>& fld)
void evaluateConstraintTypes
(
GeometricField<Type, fvPatchField, volMesh>& fld
)
{
auto& bfld = fld.boundaryFieldRef();
const UPstream::commsTypes commsType = UPstream::defaultCommsType;
if
fld.boundaryFieldRef().evaluate_if
(
commsType == UPstream::commsTypes::buffered
|| commsType == UPstream::commsTypes::nonBlocking
)
{
const label startOfRequests = UPstream::nRequests();
for (auto& pfld : bfld)
[](const auto& pfld) -> bool
{
if
return
(
pfld.type() == pfld.patch().patch().type()
&& polyPatch::constraintType(pfld.patch().patch().type())
)
{
pfld.initEvaluate(commsType);
}
}
// Wait for outstanding requests (non-blocking)
UPstream::waitRequests(startOfRequests);
for (auto& pfld : bfld)
{
if
(
pfld.type() == pfld.patch().patch().type()
&& polyPatch::constraintType(pfld.patch().patch().type())
)
{
pfld.evaluate(commsType);
}
}
}
else if (commsType == UPstream::commsTypes::scheduled)
{
const lduSchedule& patchSchedule =
fld.mesh().globalData().patchSchedule();
for (const auto& schedEval : patchSchedule)
{
const label patchi = schedEval.patch;
auto& pfld = bfld[patchi];
if
(
pfld.type() == pfld.patch().patch().type()
&& polyPatch::constraintType(pfld.patch().patch().type())
)
{
if (schedEval.init)
{
pfld.initEvaluate(commsType);
}
else
{
pfld.evaluate(commsType);
}
}
}
}
);
},
UPstream::defaultCommsType
);
}

View File

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

View File

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

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2018-2024 OpenCFD Ltd.
Copyright (C) 2018-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -28,8 +28,6 @@ License
#include "ListOps.H"
#include "CompactListList.H"
#include "HashSet.H"
#include <numeric>
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
@ -115,7 +113,8 @@ Foam::Map<Foam::label> Foam::invertToMap(const labelUList& values)
{
const label len = values.size();
Map<label> inverse(2*len);
Map<label> inverse;
inverse.reserve(len);
for (label i = 0 ; i < len; ++i)
{
@ -280,13 +279,14 @@ void Foam::inplaceReorder
void Foam::ListOps::unionEqOp::operator()
(
labelList& x,
const labelList& y
const labelUList& 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-2024 OpenCFD Ltd.
Copyright (C) 2017-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -485,7 +485,6 @@ 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
@ -508,7 +507,7 @@ label findSortedIndex
// <code> lessOp<T>(list[i], val) </code> for the test.
//
// \tparam ListType The input list type
// \tparam T The value type (is often the same as ListType::value_type)
// \tparam T The value type (usually the same as ListType::value_type)
// \tparam ComparePredicate The type of the comparison functor that
// returns true for sorting below.
//
@ -585,23 +584,33 @@ namespace ListOps
template<class T>
struct appendEqOp
{
void operator()(List<T>& x, const List<T>& y) const;
void operator()(List<T>& x, const UList<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 List<T>& y) const;
void operator()(List<T>& x, const UList<T>& y) const;
};
//- List helper to add y unique elements to x
struct unionEqOp
{
void operator()(labelList& x, const labelList& y) const;
void operator()(labelList& x, const labelUList& 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 List<T>& y
const UList<T>& y
) const
{
if (y.size())
@ -1102,7 +1102,7 @@ template<class T>
void Foam::ListOps::uniqueEqOp<T>::operator()
(
List<T>& x,
const List<T>& y
const UList<T>& y
) const
{
if (y.size())
@ -1111,6 +1111,7 @@ void Foam::ListOps::uniqueEqOp<T>::operator()
{
for (const T& val : y)
{
// Not very efficient
x.push_uniq(val);
}
}
@ -1122,6 +1123,37 @@ 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

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

View File

@ -179,6 +179,9 @@ public:
// Public Classes
//- Wrapper for OpenFOAM internal communicator index
class communicator; // Forward Declaration
//- Wrapper for MPI_Comm
class Communicator; // Forward Declaration
@ -378,6 +381,25 @@ 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);
}
};
@ -850,7 +872,7 @@ public:
const bool withComponents = true
);
//- Creaet new communicator with sub-ranks on the parent communicator
//- Create new communicator with sub-ranks on the parent communicator
static label newCommunicator
(
//! The parent communicator
@ -896,126 +918,6 @@ 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);
@ -1839,6 +1741,168 @@ 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,18 +470,10 @@ 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 "Pstream.H"
#include "UPstream.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -106,22 +106,34 @@ Foam::messageStream::messageStream(const dictionary& dict)
Foam::OSstream& Foam::messageStream::stream
(
OSstream* alternative
OSstream* alternative,
int communicator
)
{
if (communicator < 0)
{
communicator = UPstream::worldComm;
}
if (level)
{
// Serlal (master only) output?
const bool serialOnly
// Master-only output?
const bool masterOnly
(
!UPstream::parRun()
|| ((severity_ & ~errorSeverity::USE_STDERR) == errorSeverity::INFO)
|| ((severity_ & ~errorSeverity::USE_STDERR) == errorSeverity::WARNING)
);
if (serialOnly && (UPstream::parRun() && !UPstream::master()))
if
(
masterOnly
&& (UPstream::parRun() && !UPstream::master(communicator))
)
{
return Snull; // Non-serial, non-master: exit early
// Requested master-only output but is non-master (in parallel)
// -> early exit
return Snull;
}
@ -139,10 +151,9 @@ Foam::OSstream& Foam::messageStream::stream
OSstream* osptr;
if (serialOnly)
if (masterOnly)
{
// Use supplied alternative? Valid for serial only
// Use supplied alternative? Valid for master-only output
osptr =
(
alternative
@ -152,7 +163,6 @@ Foam::OSstream& Foam::messageStream::stream
}
else
{
// Non-serial
osptr = (use_stderr ? &Perr : &Pout);
}
@ -175,8 +185,13 @@ Foam::OSstream& Foam::messageStream::stream
}
Foam::OSstream& Foam::messageStream::masterStream(const int communicator)
Foam::OSstream& Foam::messageStream::masterStream(int communicator)
{
if (communicator < 0)
{
communicator = UPstream::worldComm;
}
if (UPstream::warnComm >= 0 && communicator != UPstream::warnComm)
{
Perr<< "** messageStream with comm:" << communicator << endl;
@ -185,7 +200,7 @@ Foam::OSstream& Foam::messageStream::masterStream(const int communicator)
if (communicator == UPstream::worldComm || UPstream::master(communicator))
{
return this->stream();
return this->stream(nullptr, communicator);
}
return Snull;
@ -194,6 +209,7 @@ Foam::OSstream& Foam::messageStream::masterStream(const int communicator)
std::ostream& Foam::messageStream::stdStream()
{
// Currently do not need communicator != worldComm
return this->stream().stdStream();
}
@ -400,13 +416,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,12 +191,15 @@ public:
OSstream& stream
(
//! An alternative output stream (serial-only)
OSstream* alternative = nullptr
OSstream* alternative = nullptr,
//! Communicator. Negative is treated like UPstream::worldComm
int communicator = -1
);
//- Return OSstream for output operations on the master process only,
//- Snull on other processes.
OSstream& masterStream(const int communicator);
// A negative communicator is treated like UPstream::worldComm
OSstream& masterStream(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 DimensionedField<Type, GeoMesh>& null() noexcept
static const this_type& null() noexcept
{
return NullObjectRef<DimensionedField<Type, GeoMesh>>();
return NullObjectRef<this_type>();
}
@ -373,6 +373,33 @@ public:
Field<Type>&& iField
);
//- Return tmp field (NO_READ, NO_WRITE)
//- from name, mesh, dimensions, primitive field (tmp).
//- [Takes current timeName from the mesh registry].
// For LEGACY_REGISTER, registration is determined by
// objectRegistry::is_cacheTemporaryObject().
static tmp<DimensionedField<Type, GeoMesh>> New
(
const word& name,
IOobjectOption::registerOption regOpt,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield
);
//- Return tmp field (NO_READ, NO_WRITE)
//- from name, mesh, dimensions, primitive field (tmp).
//- [Takes current timeName from the mesh registry].
// Registration/persistence determined by
// objectRegistry::is_cacheTemporaryObject().
static tmp<DimensionedField<Type, GeoMesh>> New
(
const word& name,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield
);
//- Return tmp field (NO_READ, NO_WRITE)
//- from name, mesh, dimensions.
//- [Takes current timeName from the mesh registry].

View File

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

View File

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

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017,2022 OpenFOAM Foundation
Copyright (C) 2015-2024 OpenCFD Ltd.
Copyright (C) 2015-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -88,7 +88,8 @@ private:
// Private Member Functions
//- Helper: check if patchfields have been evaluated. If not:
//- Check if patch fields have been consistently evaluated.
// If not:
// exit = true : FatalError
// exit = false : return bool
template<class CheckPatchField>
@ -205,8 +206,12 @@ public:
const UPstream::commsTypes commsType = UPstream::defaultCommsType
);
//- Evaluate boundary conditions on coupled patches of given type.
//- Uses specified or default comms.
//- Evaluate boundary conditions on coupled patches of the given type,
//- using specified or default comms.
//
// \tparam CoupledPatchType The coupled \b patch type that should
// be evaluated. For a \c void type,
// all coupled patch fields will be evaluated.
template<class CoupledPatchType>
void evaluateCoupled
(

View File

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

View File

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

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017 OpenFOAM Foundation
Copyright (C) 2019-2024 OpenCFD Ltd.
Copyright (C) 2019-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -215,6 +215,53 @@ Foam::GeometricField<Type, PatchField, GeoMesh>::New
}
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::tmp<Foam::GeometricField<Type, PatchField, GeoMesh>>
Foam::GeometricField<Type, PatchField, GeoMesh>::New
(
const word& name,
IOobjectOption::registerOption regOpt,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield,
const word& patchFieldType
)
{
return GeometricField<Type, PatchField, GeoMesh>::New_impl
(
regOpt,
name,
mesh,
dims,
tfield,
patchFieldType
);
}
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::tmp<Foam::GeometricField<Type, PatchField, GeoMesh>>
Foam::GeometricField<Type, PatchField, GeoMesh>::New
(
const word& name,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield,
const word& patchFieldType
)
{
return GeometricField<Type, PatchField, GeoMesh>::New_impl
(
IOobjectOption::LEGACY_REGISTER,
name,
mesh,
dims,
tfield,
patchFieldType
);
}
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::tmp<Foam::GeometricField<Type, PatchField, GeoMesh>>
Foam::GeometricField<Type, PatchField, GeoMesh>::New

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -87,20 +88,27 @@ void Foam::basicSymmetryPointPatchField<Type>::evaluate
const Pstream::commsTypes
)
{
const vectorField& nHat = this->patch().pointNormals();
if constexpr (!is_rotational_vectorspace_v<Type>)
{
// Rotational-invariant type : no-op
}
else
{
const vectorField& nHat = this->patch().pointNormals();
tmp<Field<Type>> tvalues =
(
const Field<Type> pif(this->patchInternalField());
// Could write as loop instead...
tmp<Field<Type>> tvalues
(
this->patchInternalField()
+ transform(I - 2.0*sqr(nHat), this->patchInternalField())
)/2.0
);
0.5*(pif + transform(I - 2.0*sqr(nHat), pif))
);
// Get internal field to insert values into
Field<Type>& iF = const_cast<Field<Type>&>(this->primitiveField());
// Get internal field to insert values into
auto& iF = const_cast<Field<Type>&>(this->primitiveField());
this->setInInternalField(iF, tvalues());
this->setInInternalField(iF, tvalues());
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -88,13 +89,22 @@ void Foam::fixedNormalSlipPointPatchField<Type>::evaluate
const Pstream::commsTypes
)
{
tmp<Field<Type>> tvalues =
transform(I - n_*n_, this->patchInternalField());
if constexpr (!is_rotational_vectorspace_v<Type>)
{
// Rotational-invariant type : no-op
}
else
{
tmp<Field<Type>> tvalues
(
transform(I - n_*n_, this->patchInternalField())
);
// Get internal field to insert values into
Field<Type>& iF = const_cast<Field<Type>&>(this->primitiveField());
// Get internal field to insert values into
auto& iF = const_cast<Field<Type>&>(this->primitiveField());
this->setInInternalField(iF, tvalues());
this->setInInternalField(iF, tvalues());
}
}

View File

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

View File

@ -98,16 +98,6 @@ 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:
@ -228,13 +218,24 @@ public:
return updated_;
}
//- Set updated state
void setUpdated(bool state) noexcept
{
updated_ = state;
}
//- True if the matrix has already been manipulated.
//- Currently ignored (always false) for pointPatchField
//- Currently 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
@ -262,6 +263,9 @@ 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

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

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2024 OpenCFD Ltd.
Copyright (C) 2019-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -243,7 +243,15 @@ Foam::GAMGAgglomeration::GAMGAgglomeration
const dictionary& controlDict
)
:
MeshObject_type(mesh),
MeshObject_type
(
controlDict.getOrDefault<word>
(
"name",
GAMGAgglomeration::typeName
),
mesh
),
maxLevels_(50),
@ -308,10 +316,17 @@ const Foam::GAMGAgglomeration& Foam::GAMGAgglomeration::New
const dictionary& controlDict
)
{
const GAMGAgglomeration* agglomPtr =
mesh.thisDb().cfindObject<GAMGAgglomeration>
(
GAMGAgglomeration::typeName
controlDict.getOrDefault<word>
(
"name",
GAMGAgglomeration::typeName
)
);
if (agglomPtr)
@ -373,12 +388,16 @@ const Foam::GAMGAgglomeration& Foam::GAMGAgglomeration::New
const GAMGAgglomeration* agglomPtr =
mesh.thisDb().cfindObject<GAMGAgglomeration>
(
GAMGAgglomeration::typeName
controlDict.getOrDefault<word>
(
"name",
GAMGAgglomeration::typeName
)
);
if (agglomPtr)
{
if (agglomPtr->requireUpdate_)
if (agglomPtr->requireUpdate_ || agglomPtr->requiresUpdate())
{
mesh.thisDb().checkOut(const_cast<GAMGAgglomeration*>(agglomPtr));
return GAMGAgglomeration::New(matrix, controlDict);
@ -431,12 +450,16 @@ const Foam::GAMGAgglomeration& Foam::GAMGAgglomeration::New
const GAMGAgglomeration* agglomPtr =
mesh.thisDb().cfindObject<GAMGAgglomeration>
(
GAMGAgglomeration::typeName
controlDict.getOrDefault<word>
(
"name",
GAMGAgglomeration::typeName
)
);
if (agglomPtr)
{
if (agglomPtr->requireUpdate_)
if (agglomPtr->requireUpdate_ || agglomPtr->requiresUpdate())
{
mesh.thisDb().checkOut(const_cast<GAMGAgglomeration*>(agglomPtr));
return GAMGAgglomeration::New(mesh, controlDict);

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2023 OpenCFD Ltd.
Copyright (C) 2019-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -38,8 +38,12 @@ Description
// Whether to cache the agglomeration
cacheAgglomeration yes;
// Optionally update every updateInterval mesh motion. Default is 1.
// Optionally update every updateInterval time steps. Default is 1.
// - only applies if cacheAgglomeration
// - applies also for static mesh cases
updateInterval 10;
// Optional name (default is GAMGAgglomeration)
//name pAgglomeration;
// Optionally agglomerate coarsest-level across processors
processorAgglomerator masterCoarsest;
@ -188,7 +192,7 @@ protected:
// Protected Member Functions
//- Does the agglomeration need to be fully updated?
bool requiresUpdate() const;
virtual bool requiresUpdate() const;
//- Assemble coarse mesh addressing
void agglomerateLduAddressing(const label fineLevelIndex);

View File

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

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2018-2024 OpenCFD Ltd.
Copyright (C) 2018-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -89,7 +89,11 @@ void Foam::pointBoundaryMesh::calcGroupIDs() const
// Remove groups that clash with patch names
forAll(patches, patchi)
{
if (groupLookup.erase(patches[patchi].name()))
if (groupLookup.empty())
{
break; // Early termination
}
else if (groupLookup.erase(patches[patchi].name()))
{
WarningInFunction
<< "Removed group '" << patches[patchi].name()
@ -370,7 +374,7 @@ Foam::labelList Foam::pointBoundaryMesh::indices
// Only check groups if requested and they exist
const bool checkGroups = (useGroups && this->hasGroupIDs());
labelHashSet ids(0);
labelHashSet ids;
if (matcher.isPattern())
{
@ -381,7 +385,7 @@ Foam::labelList Foam::pointBoundaryMesh::indices
{
if (matcher(iter.key()))
{
// Add patch ids associated with the group
// Add ids associated with the group
ids.insert(iter.val());
}
}
@ -413,7 +417,7 @@ Foam::labelList Foam::pointBoundaryMesh::indices
if (iter.good())
{
// Hash ids associated with the group
// Add ids associated with the group
ids.insert(iter.val());
}
}
@ -438,7 +442,7 @@ Foam::labelList Foam::pointBoundaryMesh::indices
return this->indices(matcher.front(), useGroups);
}
labelHashSet ids(0);
labelHashSet ids;
// Only check groups if requested and they exist
if (useGroups && this->hasGroupIDs())
@ -450,7 +454,7 @@ Foam::labelList Foam::pointBoundaryMesh::indices
{
if (matcher(iter.key()))
{
// Add patch ids associated with the group
// Add ids associated with the group
ids.insert(iter.val());
}
}
@ -471,20 +475,20 @@ Foam::labelList Foam::pointBoundaryMesh::indices
Foam::labelList Foam::pointBoundaryMesh::indices
(
const wordRes& select,
const wordRes& ignore,
const wordRes& allow,
const wordRes& deny,
const bool useGroups
) const
{
//return mesh().boundaryMesh().indices(select, ignore, useGroups);
if (ignore.empty())
if (allow.empty() && deny.empty())
{
return this->indices(select, useGroups);
// Fast-path: select all
return identity(this->size());
}
const wordRes::filter matcher(select, ignore);
const wordRes::filter matcher(allow, deny);
labelHashSet ids(0);
labelHashSet ids;
// Only check groups if requested and they exist
if (useGroups && this->hasGroupIDs())
@ -496,7 +500,7 @@ Foam::labelList Foam::pointBoundaryMesh::indices
{
if (matcher(iter.key()))
{
// Add patch ids associated with the group
// Add 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-2024 OpenCFD Ltd.
Copyright (C) 2018-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -28,7 +28,9 @@ Class
Foam::pointBoundaryMesh
Description
Foam::pointBoundaryMesh
A pointBoundaryMesh is a pointPatch list with registered IO,
a reference to the associated pointMesh,
with additional search methods etc.
SourceFiles
pointBoundaryMesh.C
@ -102,10 +104,10 @@ public:
// Constructors
//- Construct from polyBoundaryMesh
//- Construct from pointMesh and polyBoundaryMesh
pointBoundaryMesh(const pointMesh&, const polyBoundaryMesh&);
//- Construct from IOobject and polyBoundaryMesh
//- Construct from IOobject, pointMesh and polyBoundaryMesh
pointBoundaryMesh
(
const IOobject& io,
@ -141,24 +143,29 @@ public:
//- Return a list of physical types
wordList physicalTypes() const;
//- Return (sorted) patch indices for all matches.
// A no-op (returns empty list) for an empty matcher
//- The (sorted) patch indices for all matches,
//- optionally matching patch groups.
// \returns an empty list for an empty matcher
labelList indices(const wordRe& matcher, const bool useGroups) const;
//- Return (sorted) patch indices for all matches.
// A no-op (returns empty list) for an empty matcher
//- The (sorted) patch indices for all matches,
//- optionally matching patch groups.
// \returns an empty list for an empty matcher
labelList indices(const wordRes& matcher, const bool useGroups) const;
//- 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
//- 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.
labelList indices
(
const wordRes& select,
const wordRes& ignore,
const bool useGroups
const wordRes& allow,
const wordRes& deny,
const bool useGroups //!< Match patch groups
) const;
//- Find patch index given a name

View File

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

View File

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

View File

@ -40,96 +40,6 @@ 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-2023 OpenCFD Ltd.
Copyright (C) 2015-2025 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(List<T>& field) const;
void applyDummyTransforms(UList<T>& field) const;
template<class T, class TransformOp>
void applyTransforms
(
const globalIndexAndTransform& globalTransforms,
List<T>& field,
UList<T>& field,
const TransformOp& top
) const;
//- Helper function: copy transformElements without transformation
template<class T>
void applyDummyInverseTransforms(List<T>& field) const;
void applyDummyInverseTransforms(UList<T>& field) const;
template<class T, class TransformOp>
void applyInverseTransforms
(
const globalIndexAndTransform& globalTransforms,
List<T>& field,
UList<T>& field,
const TransformOp& top
) const;
@ -219,11 +219,14 @@ public:
(
const vectorTensorTransform& vt,
const bool forward,
List<Type>& fld
UList<Type>& fld
) const
{
const tensor T(forward ? vt.R() : vt.R().T());
transformList(T, fld);
if constexpr (is_rotational_vectorspace_v<Type>)
{
const tensor rot(forward ? vt.R() : vt.R().T());
transformList(rot, fld);
}
}
template<class Type>
@ -234,9 +237,13 @@ public:
List<List<Type>>& flds
) const
{
for (List<Type>& fld : flds)
if constexpr (is_rotational_vectorspace_v<Type>)
{
operator()(vt, forward, fld);
const tensor rot(forward ? vt.R() : vt.R().T());
for (auto& fld : flds)
{
transformList(rot, fld);
}
}
}
@ -244,9 +251,12 @@ public:
template<class Type>
void operator()(const coupledPolyPatch& cpp, UList<Type>& fld) const
{
if (!cpp.parallel())
if constexpr (is_rotational_vectorspace_v<Type>)
{
transformList(cpp.forwardT(), fld);
if (!cpp.parallel())
{
transformList(cpp.forwardT(), fld);
}
}
}
@ -255,9 +265,12 @@ public:
void operator()(const coupledPolyPatch& cpp, Container<Type>& map)
const
{
if (!cpp.parallel())
if constexpr (is_rotational_vectorspace_v<Type>)
{
transformList(cpp.forwardT(), map);
if (!cpp.parallel())
{
transformList(cpp.forwardT(), map);
}
}
}
};
@ -271,17 +284,16 @@ public:
(
const vectorTensorTransform& vt,
const bool forward,
List<point>& fld
UList<point>& fld
) const
{
pointField pfld(std::move(fld));
if (forward)
{
fld = vt.transformPosition(pfld);
vt.transformPositionList(fld);
}
else
{
fld = vt.invTransformPosition(pfld);
vt.invTransformPositionList(fld);
}
}
@ -292,9 +304,19 @@ public:
List<List<point>>& flds
) const
{
for (List<point>& fld : flds)
if (forward)
{
operator()(vt, forward, fld);
for (auto& fld : flds)
{
vt.transformPositionList(fld);
}
}
else
{
for (auto& fld : flds)
{
vt.invTransformPositionList(fld);
}
}
}
@ -682,86 +704,6 @@ 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
List<T>& lhs,
UList<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
List<T>& output,
//! [out] The input values
UList<T>& output,
//! 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
(
//! [out] The input values
//! 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 List<labelPair>& schedule,
const UList<labelPair>& schedule,
const label constructSize,
const labelListList& subMap,
const bool subHasFlip,
@ -918,7 +918,7 @@ public:
static void distribute
(
const UPstream::commsTypes commsType,
const List<labelPair>& schedule,
const UList<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 List<T>& field) const;
void send(PstreamBuffers& pBufs, const UList<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
(
List<T>& lhs,
UList<T>& lhs,
const UList<T>& rhs,
const labelUList& map,
@ -46,6 +46,9 @@ 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)
@ -82,7 +85,7 @@ void Foam::mapDistributeBase::flipAndCombine
template<class T, class NegateOp>
void Foam::mapDistributeBase::accessAndFlip
(
List<T>& output,
UList<T>& output,
const UList<T>& values,
const labelUList& map,
const bool hasFlip,
@ -91,6 +94,7 @@ void Foam::mapDistributeBase::accessAndFlip
{
const label len = map.size();
// FULLDEBUG: if (values.size() < max(map)) FatalError ...;
// FULLDEBUG: if (output.size() < len) FatalError ...;
if (hasFlip)
@ -447,7 +451,7 @@ template<class T, class CombineOp, class NegateOp>
void Foam::mapDistributeBase::distribute
(
const UPstream::commsTypes commsType,
const List<labelPair>& schedule,
const UList<labelPair>& schedule,
const label constructSize,
const labelListList& subMap,
const bool subHasFlip,
@ -894,7 +898,7 @@ template<class T, class NegateOp>
void Foam::mapDistributeBase::distribute
(
const UPstream::commsTypes commsType,
const List<labelPair>& schedule,
const UList<labelPair>& schedule,
const label constructSize,
const labelListList& subMap,
const bool subHasFlip,
@ -1332,7 +1336,7 @@ template<class T>
void Foam::mapDistributeBase::send
(
PstreamBuffers& pBufs,
const List<T>& field
const UList<T>& field
) const
{
// Stream data into buffer
@ -1482,13 +1486,11 @@ void Foam::mapDistributeBase::distribute
const int tag
) const
{
values.shrink();
List<T> work(std::move(values));
List<T>& list = static_cast<List<T>&>(values);
distribute(commsType, work, tag);
distribute(commsType, list, tag);
values.setCapacity(list.size());
values = std::move(work);
}

View File

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

View File

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

View File

@ -28,8 +28,9 @@ Class
Foam::polyBoundaryMesh
Description
A polyBoundaryMesh is a polyPatch list with additional search methods
and registered IO.
A polyBoundaryMesh is a polyPatch list with registered IO,
a reference to the associated polyMesh,
with additional search methods etc.
SourceFiles
polyBoundaryMesh.C
@ -259,34 +260,37 @@ public:
labelRange range(const label patchi) const;
//- Return (sorted) patch indices for all matches.
// Optionally matches patch groups.
// A no-op (returns empty list) for an empty matcher
//- The (sorted) patch indices for all matches,
//- optionally matching patch groups.
// \returns an empty list for an empty matcher
labelList indices
(
const wordRe& matcher,
const bool useGroups = true
) const;
//- Return (sorted) patch indices for all matches.
// Optionally matches patch groups.
// A no-op (returns empty list) for an empty matcher
//- The (sorted) patch indices for all matches,
//- optionally matching patch groups.
// \returns an empty list for an empty matcher
labelList indices
(
const wordRes& matcher,
const bool useGroups = true
const bool useGroups = true //!< Match patch groups
) const;
//- 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
//- 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.
labelList indices
(
const wordRes& select,
const wordRes& ignore,
const bool useGroups = true
const wordRes& allow,
const wordRes& deny,
const bool useGroups = true //!< Match patch groups
) const;
//- Return (sorted) patch indices for patches that match the

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -66,35 +67,10 @@ inline Foam::vectorTensorTransform::vectorTensorTransform(const tensor& R)
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
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()
inline Foam::tensor& Foam::vectorTensorTransform::R() noexcept
{
// Assume that non-const access to R changes it from I, so set
// hasR to true
hasR_ = true;
return R_;
@ -136,6 +112,28 @@ 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
@ -171,6 +169,30 @@ 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

@ -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-2022 OpenCFD Ltd.
Copyright (C) 2017-2025 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.
// Uses a combination of allow and deny lists
//- Return ids for items with matching names,
//- using a combination of allow and deny lists as per wordRes::filter
//
// 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'.
// 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.
//
// Example (when applied to a list of words),
// \verbatim
@ -386,7 +386,7 @@ labelList findMatching
// result: (abc other val val1 wall1 wall2)
// \endverbatim
//
// \return List indices for matches
// \returns identity list when allow/deny are both empty.
template<class StringListType, class AccessOp = identityOp>
labelList findMatching
(

View File

@ -143,7 +143,7 @@ Foam::labelList Foam::stringListOps::findMatching
if (pred.empty())
{
// Accept all
// Fast-path: select all
return identity(len);
}
@ -177,11 +177,10 @@ Foam::labelList Foam::stringListOps::findMatching
{
if (allow.empty() && deny.empty())
{
// Accept all
// Fast-path: select 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-2024 OpenCFD Ltd.
Copyright (C) 2016-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -99,7 +99,10 @@ public:
// No distinction made between literals and regular expressions.
static wordRes uniq(const UList<wordRe>& input);
//- Test for a match
//- 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
inline static bool match
(
const UList<wordRe>& selectors,
@ -197,9 +200,10 @@ public:
//- No selectors defined
inline bool empty() const noexcept;
//- True if text matches ANY of the selectors.
//- Always false if entries are empty.
// Allows use as a predicate.
//- Apply matcher predicate
//
// \return \c false if no selectors are specified
// \return \c true if text matches \em any of the selectors
inline bool operator()(const std::string& text) const;
private:
@ -209,9 +213,10 @@ public:
//- Functor wrapper of allow/deny lists of wordRe for filtering
//
// 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'.
// 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.
//
// Example (when applied to a list of words),
// \verbatim
@ -223,17 +228,23 @@ public:
// \endverbatim
struct filter
{
//- Construct with 'allow' and 'deny' matchers
//- Construct with \em allow and \em deny matchers
inline filter
(
const UList<wordRe>& allow,
const UList<wordRe>& deny
) noexcept;
//- Nothing defined
//- No filtering defined
inline bool empty() const noexcept;
//- True if matched but not blocked
//- 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
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-2022 OpenCFD Ltd.
Copyright (C) 2017-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -225,6 +225,7 @@ inline bool Foam::wordRes::matcher::empty() const noexcept
return select_.empty();
}
inline bool Foam::wordRes::filter::empty() const noexcept
{
return (allow_.empty() && deny_.empty());
@ -241,12 +242,14 @@ inline bool Foam::wordRes::filter::operator()(const std::string& text) const
{
if (allow_.empty())
{
// No allow specified, so accept everything that is NOT blocked
// Did not specify allow
// => accept everything that is NOT blocked
return (deny_.empty() || !wordRes::match(deny_, text));
}
else if (deny_.empty())
{
// Nothing blocked, apply accept filter
// Specified allow but did not specify blocked
// => select with 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::buffered == commsType)
{
// Blocking
profilingPstream::beginTiming();
if
(
MPI_Probe
(
source,
tag,
PstreamGlobals::MPICommunicators_[communicator],
&status
)
)
{
FatalErrorInFunction
<< "MPI_Probe returned with error"
<< Foam::abort(FatalError);
}
profilingPstream::addProbeTime();
flag = 1;
}
else
if (UPstream::commsTypes::nonBlocking == commsType)
{
// Non-blocking
profilingPstream::beginTiming();
@ -1437,8 +1413,8 @@ Foam::UPstream::probeMessage
source,
tag,
PstreamGlobals::MPICommunicators_[communicator],
&flag,
&status
&flag,
&status
)
)
{
@ -1449,6 +1425,30 @@ Foam::UPstream::probeMessage
profilingPstream::addRequestTime();
}
else
{
// Blocking
profilingPstream::beginTiming();
if
(
MPI_Probe
(
source,
tag,
PstreamGlobals::MPICommunicators_[communicator],
&status
)
)
{
FatalErrorInFunction
<< "MPI_Probe returned with error"
<< Foam::abort(FatalError);
}
profilingPstream::addProbeTime();
flag = 1;
}
if (flag)
{

View File

@ -43,8 +43,8 @@ template<class BasicTurbulenceModel>
void sigma<BasicTurbulenceModel>::correctNut()
{
this->nut_ =
sqr(this->delta())
*DESModel<BasicTurbulenceModel>::Ssigma(fvc::grad(this->U_), Csigma_);
sqr(this->delta()*Csigma_)
*DESModel<BasicTurbulenceModel>::Ssigma(fvc::grad(this->U_), scalar(1));
this->nut_.correctBoundaryConditions();
fv::options::New(this->mesh_).correct(this->nut_);

View File

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

View File

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

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