Compare commits

...

54 Commits

Author SHA1 Message Date
bd41a2abdb WIP: issue #3348 2025-03-31 20:48:17 +02:00
a2df607998 CONFIG: set API level to 2501
- Pstream changes (one-sided), local AMI communicators,
  other adjustments
2025-03-31 18:53:43 +02:00
e121db6e86 ENH: extend sigFpe::fillNan() interfaces
- provide separate float/double UList interfaces, which improves
  flexibility (eg, with SPDP)

- sigFpe::fillNan_if() interface, for filling in when using alternative
  memory allocators
2025-03-31 18:50:29 +02:00
e720f823d3 ENH: simplify SubStrings class/handling (remove template parameters)
- previous code used derived string iterators, but these would
  be largely ignored anyhow since the underlying std::sub_match
  str() method would just yields a std::string anyhow.

  The SubStrings::str(size_t) method wasn't used in any code, so now
  just use std::string iterators only.

  This change simplfies overall handling, since it removes an unneeded
  template dependency.
2025-03-31 16:00:07 +02:00
bdac68ebc7 CONFIG: add Gcc rules for MacOS (darwin)
- /usr/bin/{gcc,g++} normally just symlinks to clang/clang++
  and may have unknown default flags.
  For a gcc toolchain, it would be better to use a homebrew
  installation.

  For these cases, the compiler will need to be specified with
  version=.. in WM_COMPILE_CONTROL.

  For example, with "version=14", to select gcc-14, g++-14 from the
  homebrew installation.

- needs a slight hack for locating the FlexLexer.h header.
  Added into src/OSspecific/POSIX similar to how it is handled
  in src/OSspecific/MSwindows

CONFIG: add simple config/detection support for libumpire (Linux)
2025-03-31 16:00:07 +02:00
edf9621ebe ENH: add foamConfigurePaths support for homebrew
- new options to set components specified by homebrew.
  Sets version as system, path from brew --prefix

    -adios-brew, -adios2-brew, -boost-brew, -cgal-brew,
    -fftw-brew, -kahip-brew, -metis-brew, -scotch-brew,
    -gmp-brew, -mpfr-brew

    -with-homebrew
     Shortcut for selecting all the above (except gmp, mpfr)

* additional special treatment for GMP and MPFR.

  If using non-system locations and not part of the ThirdParty
  compiler, they can additionally be set in the CGAL config file:

    -gmp-brew, -gmp-path
    -mpfr-brew, -mpfr-path
2025-03-31 16:00:07 +02:00
a9863d9a3f ENH: add size_type to Matrix and VectorSpace
- easier to create type-specific looping in templated code

STYLE: pass 'direction' and 'label' by value instead of reference

COMP: qualify Foam::min() in dense matrix classes
2025-03-31 15:58:55 +02:00
bdb890d4e2 COMP: disambiguate pTraits for long/unsigned long on Darwin 2025-03-25 16:02:42 +01:00
707db0b65b COMP: avoid deprecated headers for CGAL-6.0 2025-03-24 16:27:02 +01:00
8716795d86 COMP: more int/label consistency for communicator parameter 2025-03-24 16:27:02 +01:00
8bbfe6eb44 Merge branch 'remove-posix-regex' into 'develop'
DEFEATURE: remove POSIX regex interface (#3343)

See merge request Development/openfoam!733
2025-03-24 10:33:15 +00:00
aaa9af9ee8 DEFEATURE: remove POSIX regex interface (#3343)
- compiler versions are now sufficient that only the C++ regex
  interface is now being used. Can remove the old POSIX code
  accordingly.

  This change also removes any dependency on the SubStrings class to
  manage the matching results.

ENH: remove OpenFOAM dependencies from MacOS addr2line utility
2025-03-21 14:41:43 +01:00
4de0b84c2f Merge branch 'pstream-topo-aware' into 'develop'
additional topology-aware handling for Pstream

See merge request Development/openfoam!731
2025-03-20 12:02:45 +00:00
db871856c0 CONFIG: add named topoControls 2025-03-20 10:51:43 +00:00
a01f3ed8b7 ENH: add node-based gatherList() 2025-03-20 10:51:43 +00:00
c4b261c615 ENH: add node-based gather(), listGather(), mapGather() 2025-03-20 10:51:43 +00:00
7b0ab0dbb3 ENH: add node-based broadcasting and reduction 2025-03-20 10:51:43 +00:00
b9b0d1b3aa STYLE: use weighted average/sum in a few places
- minor adjustments to some BCs construction:
  * ensure origin/axis are zero-initialized
  * use dictionary get<> instead of lookup
2025-03-20 11:14:39 +01:00
034a0524af ENH: add weighted average and weighted sum functions (local and global)
- convenience, avoids creating intermediate fields and for
  gWeightedAverage() requires one fewer reduction

ENH: combine loops for FieldField averaging

STYLE: remove clip() function, superseded by clamp_range() - JAN-2023
2025-03-19 12:10:27 +01:00
eaa65913f4 CONFIG: combine flex/flex++ rules (minor cleanup)
- generate .cc (instead of .C) intermediate files, consistent with how
  we manage other generated code and makes them less case sensitive
2025-03-19 12:10:12 +01:00
6dd8804acb BUG: fixup. See #3334 2025-03-17 15:07:25 +00:00
a77aaa7582 BUG: AMIInterpolation: reset cached data. Fixes #3334 2025-03-17 14:11:38 +00:00
5cc36dc5b7 Merge branch 'issue-3211-fan-jumpCyclic' into 'develop'
BUG: fan: bc value not updated. See #3211

See merge request Development/openfoam!701
2025-03-17 14:11:12 +00:00
d4a959a93f BUG: fan: bc value not updated. See #3211 2025-03-17 14:11:12 +00:00
09e04003c4 CONFIG: support Allwmake with -bear-output-dir (#3322) 2025-03-17 11:58:25 +01:00
dcbd546d51 FIX: incorrect parameters for IN_PLACE MPI_Gather, MPI_Scatter
STYLE: mark Pstream::scatterList() as deprecated

- this entry point is not directly used anywhere, only the
  scatterList_algorithm backend is actually used.

  The scatterList() routine is misnomer since it actually works like a
  broadcast that skips overwriting the local rank, but only if used in
  combination with the gatherList() manual implementation that uses
  the same walk pattern.
2025-03-14 17:55:12 +01:00
d64c6371f1 ENH: foamDictionary now respects header format [ascii/binary] (#3329) 2025-03-14 09:08:04 +01:00
2d246cd5d1 ENH: add token::read(Istream&) method
- can be used to simplify some logic. For example,

      if
      (
          (tok.read(is) && tok.isWord("FoamFile"))
       && (tok.read(is) && tok.isPunctuation(token::BEGIN_BLOCK))
      )
      ...
  vs
      if
      (
          (is.good() && (is >> tok) && tok.isWord("FoamFile")) ...
       && (is.good() && (is >> tok) && tok.isPunctuation(token::BEGIN_BLOCK))
      ) ...
2025-03-12 20:09:00 +01:00
51bb06764a ENH: add polyBoundaryMesh::nNonProcessorFaces()
- the number boundary faces before the first processor patch.
  This approximately equals the 'real' number of boundary faces
2025-03-12 19:14:48 +01:00
795bce4519 COMP: suppress old-style cast warning (boost/cgal) 2025-03-12 12:14:58 +01:00
db0709f957 ENH: use DynamicList to SLList for ansysToFoam, kivaToFoam
- also fixes a compilation issue introduced by f13be4f62c
  (where the direct assignment from SLList to List was removed)
2025-03-12 11:50:58 +01:00
38e08fc092 COMP: avoid constructor ambiguity for ISpanStream
- compiler cannot decide between std::string and std::string_view
  when creating from 'const char*' without also supplying the size,
  so also supply a 'const char*' constructor.

ENH: additional string_view handling for ITstream and SubStrings
2025-03-12 10:04:43 +01:00
36ae93d017 ENH: components to support one-sided communication 2025-03-10 16:32:35 +01:00
ab7cfdcf49 ENH: add UList move construct and move assignment (shallow copy)
- the 'move' treatment performs a shallow copy but does not alter
  the passed parameter. Identical semantics as per std::span.

ENH: constexpr for basic HashTable constructors

STYLE: 'Foam::zero' instead of 'const Foam::zero' for containers

- this is simply a compiler dispatch flag, so the additional 'const'
  qualifier is unnecessary
2025-03-10 16:32:23 +01:00
f13be4f62c DEFEATURE: remove old/unused SLList -> List construct/assignment
- should ideally avoid SLList in most cases, since it is allocation
  intensive and most places can easily use DynamicList or
  CircularBuffer instead.

STYLE: use push_uniq instead of deprecated appendUniq method

- mark with a 'normal' deprecation instead of 'strict' deprecation
2025-03-10 16:32:22 +01:00
ae638c2b9c CONFIG: improvements to mpirunDebug
- the '-no-core' to limit coredumps to zero size
- the '-quick' option, which changes valgrind --leak-check from "full"
  to "summary", and implies -no-core as well.
- enforce tcp libfabrics provider under valgrind since valgrind
  does not otherwie work nicely with RMA
2025-03-10 16:29:47 +01:00
9cd0aa8816 COMP: avoid in-place reduce for OPEN-MPI as well (#3331)
- fails with MPI_ARG_ERR.
  Do not assume that any vendors actually support in-place handling
  for MPI_Reduce(), regardless of what their documentation may claim.
2025-03-07 09:29:28 +01:00
939ca03495 Merge branch 'pstream-typed-handling' into 'develop'
increased use of intrinsic data types and ops for communication

See merge request Development/openfoam!730
2025-03-06 16:16:01 +00:00
28818c73f9 COMP: workaround for broken in-place reduce INTEL-MPI (#3331)
- since that particular vendor version of MPI_Reduce() does not work
  with MPI_IN_PLACE, create a local copy of the data to pass into the
  routine.
2025-03-06 16:54:32 +01:00
20b2f46315 STYLE: prefer listReduce() to using listCombineReduce() when possible
- potentially allows access into the builtin MPI operations
2025-03-06 16:54:31 +01:00
5d9f8e9a9d ENH: remove gatherv/scatterv direct coding
- includes intrinsic MPI types, but no component aggregates since we
  barely wish to use gatherv/scatterv (slow!) in the first place
  and it makes no sense to recalculate the list of counts for
  component aggregates which we will never use.
2025-03-06 16:54:31 +01:00
3bf1399098 ENH: generalize mpiGather/mpiScatter/mpiAllGather
- include MPI and component aggregates
2025-03-06 16:54:31 +01:00
20b6aeb4dd ENH: generalize reduce/all-reduce to include MPI types
- for known data types (and component aggregates),
  and intrisic reduction operation can now use

     UPstream::mpiReduce(), UPstream::mpiAllReduce().

  This change permits more operations to use MPI calls directly.
  eg,

      reduce(vec, sumOp<vector>);

   now calls mpiAllReduce(..., op_sum) instead of point-to-point,
   followed by a broadcast.

   Similarly, when called as a simple reduction (not all-reduce)

      Pstream::gather(vec, sumOp<vector>);

   now calls mpiReduce(..., op_sum) instead of point-to-point

- extend use of MPI calls to list-wise reductions as well

- extend sumReduce() to bundle/unbundle vector-space types,
  which lowers overall communication.

  Before:
    1) send/recv + binary op through a communication tree
    2) broadcast
    3) all-reduce of the count

  Now:
    1) pack into a local bundle
    2) all-reduce
    3) unpack the bundle
2025-03-06 16:54:31 +01:00
c7fc9d4ddc ENH: extend MPI send/recv types
- support send/recv of basic types (int32, float, double, ...) in
  addition to common OpenFOAM vectorspace types (floatVector,
  doubleVector, ...)

  This permits sending NUM items of the given types instead of sending
  NUM sizeof() bytes.
  For a vector (as double): 1 item instead of 24 items (3*8 bytes).
  For a tensor (as double): 1 item instead of 72 items (9*8 bytes).
2025-03-06 16:54:31 +01:00
f0b844eb47 ENH: generalize MPI broadcast to basic and user-defined MPI types
- simplify and rationalize some of the broadcast methods for more code
  reuse.

  The bottom level UPstream::broadcast is now always to/from "root=0".
  This was previously passed as a default parameter, but never used
  anything other than '0' in the code. Fixing it as '0' makes it
  consistent with the 'top-down' logical for node-based broadcast.
2025-03-06 16:54:31 +01:00
151f4df546 ENH: add opaque data types to UPstream bridge code
- permits more flexible handling at the caller level
2025-03-06 16:54:31 +01:00
7ac83f22c7 ENH: refine the dataTypes handling
- now distinguish between basic MPI types and user-defined types.

  The new front-facing trait UPstream_basic_dataType unwinds components
  and other types, but only for MPI fundamental types
  (including any aliases)

- additional helper to combine a test for binary operator validity and
  basic data type validity, which better expresses intent:

     template<class BinaryOp, class T>
     UPstream_data_opType;

- relax bit-wise operators to also accept signed integrals
  and 'void' generic
2025-03-06 16:54:31 +01:00
8c395357f3 STYLE: more consistency in communicator types (int vs label) 2025-03-06 16:54:31 +01:00
d4b5280742 ENH: cleanup broadcast streams
- remove unused/unusable broadcast stream constructors/methods

- provide OPBstream::sends() and IPBstream::recvs() methods,
  refactored from Pstream::broadcasts. These will always use
  serializations, even for contiguous content.

- additional methods to support special handling of zero-sized lists.
  For example,

    if (UPstream::master(comm))
    {
        if (list.empty()) OPBstream::send(Foam::zero, comm);
        else              OPBstream::send(list, comm);
    }
    else
    {
        IPBstream is(comm);
        if (is.remaining()) { is >> list; }
        else { list.clear(); }
    }

   This avoids serialization of an empty list and the resulting double
   broadcast (size + content), using instead a single broadcast (size).

STYLE: more consistency in communicator types (int vs label)
2025-03-06 16:54:31 +01:00
be30598e3d ENH: add UPstream::localNode_parentProcs() method
- returns the (start/size) range of the commLocalNode ranks in terms
  of the (const) world communicator processors. This allows mapping
  back into lists defined in terms of the world ranks.
2025-03-06 16:54:30 +01:00
d64682a7af ENH: expand VectorSpaceOps to include copy_n/fill_n methods
- similar to what std::copy_n and std::fill_n would do, except with
  templated loops. This allows compile-time transcribing with loop
  unrolling. For example,

     vector vec1 = ..., vec2 = ...;

     FixedList<scalar, 6> values;

     VectorSpaceOps<3>::copy_n(vec1.begin(), values.begin());
     VectorSpaceOps<3>::copy_n(vec2.begin(), values.begin(3))

     // do something with all of these values

STYLE: make start index of VectorSpaceOps optional

ENH: add clamped begin(int) versions to FixedList as per UList
2025-03-06 16:54:30 +01:00
cf9fa16788 COMP: add pTraits for int16/uint16 types (simplifies messages) 2025-03-06 16:54:30 +01:00
9437e8d068 ENH: simplify operator calls for error, messageStream
- use move semantics for string parameters and reuse more code
2025-03-06 16:54:30 +01:00
dd09aa1289 ENH: PatchTools: version with supplied local points 2025-03-06 13:05:20 +00:00
472 changed files with 10968 additions and 5844 deletions

View File

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

View File

@ -36,11 +36,12 @@ Description
if (adjustTimeStep)
{
scalar maxDeltaTFact = maxCo/(CoNum + StCoNum + SMALL);
scalar deltaTFact = min(min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
scalar deltaTFact =
Foam::min(Foam::min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
runTime.setDeltaT
(
min
Foam::min
(
deltaTFact*runTime.deltaTValue(),
maxDeltaT

View File

@ -1,5 +1,5 @@
if (adjustTimeStep)
{
runTime.setDeltaT(min(dtChem, maxDeltaT));
runTime.setDeltaT(Foam::min(dtChem, maxDeltaT));
Info<< "deltaT = " << runTime.deltaTValue() << endl;
}

View File

@ -54,9 +54,18 @@ if (adjustTimeStep)
runTime.setDeltaT
(
min
Foam::min
(
dt0*min(min(TFactorFluid, min(TFactorFilm, TFactorSolid)), 1.2),
dt0
* Foam::min
(
Foam::min
(
TFactorFluid,
Foam::min(TFactorFilm, TFactorSolid)
),
1.2
),
maxDeltaT
)
);

View File

@ -75,8 +75,10 @@
)
{
rDeltaT =
(
rDeltaT0
*max(rDeltaT/rDeltaT0, scalar(1) - rDeltaTDampingCoeff);
* Foam::max(rDeltaT/rDeltaT0, scalar(1) - rDeltaTDampingCoeff)
);
Info<< "Damped flow time scale min/max = "
<< gMin(1/rDeltaT.primitiveField())

View File

@ -1,7 +1,7 @@
scalar CoNum = -GREAT;
forAll(fluidRegions, regionI)
{
CoNum = max
CoNum = Foam::max
(
compressibleCourantNo
(

View File

@ -31,7 +31,7 @@
);
CoNum =
scalar maxPhiCoNum =
0.5*gMax
(
sumPhi/fluidRegions[regioni].V().field()
@ -41,9 +41,9 @@
(
fvc::surfaceSum(mag(phi1 - phi2))().primitiveField()
/ fluidRegions[regioni].V().field()
)*runTime.deltaTValue(),
)*runTime.deltaTValue();
CoNum = max(UrCoNum, CoNum);
CoNum = Foam::max(CoNum, Foam::max(maxPhiCoNum, UrCoNum));
}
}

View File

@ -2,7 +2,7 @@
forAll(fluidRegions, regioni)
{
CoNum = max
CoNum = Foam::max
(
compressibleCourantNo
(
@ -17,7 +17,7 @@
/*
forAll(porousFluidRegions, porousi)
{
CoNum = max
CoNum = Foam::max
(
compressibleCourantNo
(

View File

@ -47,10 +47,10 @@ if (adjustTimeStep)
runTime.setDeltaT
(
min
Foam::min
(
min(maxCo/CoNum, maxDi/DiNum)*runTime.deltaTValue(),
min(runTime.deltaTValue(), maxDeltaT)
Foam::min(maxCo/CoNum, maxDi/DiNum)*runTime.deltaTValue(),
Foam::min(runTime.deltaTValue(), maxDeltaT)
)
);
Info<< "deltaT = " << runTime.deltaTValue() << endl;

View File

@ -49,17 +49,17 @@ if (adjustTimeStep)
scalar maxDeltaTSolid = maxDi/(DiNum + SMALL);
scalar deltaTFluid =
min
Foam::min
(
min(maxDeltaTFluid, 1.0 + 0.1*maxDeltaTFluid),
Foam::min(maxDeltaTFluid, 1.0 + 0.1*maxDeltaTFluid),
1.2
);
runTime.setDeltaT
(
min
Foam::min
(
min(deltaTFluid, maxDeltaTSolid)*runTime.deltaTValue(),
Foam::min(deltaTFluid, maxDeltaTSolid)*runTime.deltaTValue(),
maxDeltaT
)
);

View File

@ -22,7 +22,7 @@ forAll(solidRegions, i)
tmp<volScalarField> trho = thermo.rho();
const volScalarField& rho = trho();
DiNum = max
DiNum = Foam::max
(
solidRegionDiffNo
(

View File

@ -17,7 +17,7 @@ scalar DiNum = -GREAT;
tmp<volScalarField> trho = thermo.rho();
const volScalarField& rho = trho();
DiNum = max
DiNum = Foam::max
(
solidRegionDiffNo
(

View File

@ -36,13 +36,16 @@ Description
if (adjustTimeStep)
{
const scalar maxDeltaTFact =
min(maxCo/(CoNum + SMALL), maxCo/(surfaceFilm.CourantNumber() + SMALL));
Foam::min
(
maxCo/(CoNum + SMALL), maxCo/(surfaceFilm.CourantNumber() + SMALL)
);
const scalar deltaTFact =
min(min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
Foam::min(Foam::min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
runTime.setDeltaT
(
min
Foam::min
(
deltaTFact*runTime.deltaTValue(),
maxDeltaT

View File

@ -36,13 +36,14 @@ Description
if (adjustTimeStep)
{
scalar maxDeltaTFact =
min(maxCo/(CoNum + SMALL), maxAlphaCo/(alphaCoNum + SMALL));
Foam::min(maxCo/(CoNum + SMALL), maxAlphaCo/(alphaCoNum + SMALL));
scalar deltaTFact = min(min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
scalar deltaTFact =
Foam::min(Foam::min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
runTime.setDeltaT
(
min
Foam::min
(
deltaTFact*runTime.deltaTValue(),
maxDeltaT

View File

@ -36,13 +36,14 @@ Description
if (adjustTimeStep)
{
scalar maxDeltaTFact =
min(maxCo/(CoNum + SMALL), maxAcousticCo/(acousticCoNum + SMALL));
Foam::min(maxCo/(CoNum + SMALL), maxAcousticCo/(acousticCoNum + SMALL));
scalar deltaTFact = min(min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
scalar deltaTFact =
Foam::min(Foam::min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
runTime.setDeltaT
(
min
Foam::min
(
deltaTFact*runTime.deltaTValue(),
maxDeltaT

View File

@ -37,11 +37,15 @@ if (adjustTimeStep)
if (CoNum > SMALL)
{
scalar maxDeltaTFact =
min(maxCo/(CoNum + SMALL), maxAcousticCo/(acousticCoNum + SMALL));
Foam::min
(
maxCo/(CoNum + SMALL),
maxAcousticCo/(acousticCoNum + SMALL)
);
runTime.setDeltaT
(
min
Foam::min
(
maxDeltaTFact*runTime.deltaTValue(),
maxDeltaT

View File

@ -26,12 +26,12 @@ forAll(dgdt, celli)
{
if (dgdt[celli] > 0.0)
{
Sp[celli] -= dgdt[celli]/max(1.0 - alpha1[celli], 1e-4);
Su[celli] += dgdt[celli]/max(1.0 - alpha1[celli], 1e-4);
Sp[celli] -= dgdt[celli]/Foam::max(1.0 - alpha1[celli], 1e-4);
Su[celli] += dgdt[celli]/Foam::max(1.0 - alpha1[celli], 1e-4);
}
else if (dgdt[celli] < 0.0)
{
Sp[celli] += dgdt[celli]/max(alpha1[celli], 1e-4);
Sp[celli] += dgdt[celli]/Foam::max(alpha1[celli], 1e-4);
}
}

View File

@ -26,12 +26,12 @@ forAll(dgdt, celli)
{
if (dgdt[celli] > 0.0)
{
Sp[celli] -= dgdt[celli]/max(1.0 - alpha1[celli], 1e-4);
Su[celli] += dgdt[celli]/max(1.0 - alpha1[celli], 1e-4);
Sp[celli] -= dgdt[celli]/Foam::max(1.0 - alpha1[celli], 1e-4);
Su[celli] += dgdt[celli]/Foam::max(1.0 - alpha1[celli], 1e-4);
}
else if (dgdt[celli] < 0.0)
{
Sp[celli] += dgdt[celli]/max(alpha1[celli], 1e-4);
Sp[celli] += dgdt[celli]/Foam::max(alpha1[celli], 1e-4);
}
}

View File

@ -26,12 +26,12 @@ forAll(dgdt, celli)
{
if (dgdt[celli] > 0.0)
{
Sp[celli] -= dgdt[celli]/max(1.0 - alpha1[celli], 1e-4);
Su[celli] += dgdt[celli]/max(1.0 - alpha1[celli], 1e-4);
Sp[celli] -= dgdt[celli]/Foam::max(1.0 - alpha1[celli], 1e-4);
Su[celli] += dgdt[celli]/Foam::max(1.0 - alpha1[celli], 1e-4);
}
else if (dgdt[celli] < 0.0)
{
Sp[celli] += dgdt[celli]/max(alpha1[celli], 1e-4);
Sp[celli] += dgdt[celli]/Foam::max(alpha1[celli], 1e-4);
}
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2023 OpenCFD Ltd.
Copyright (C) 2017-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -679,7 +679,7 @@ void Foam::radiation::laserDTRM::calculate()
}
}
scalar totalQ = gSum(Q_.primitiveFieldRef()*mesh_.V());
scalar totalQ = gWeightedSum(mesh_.V(), Q_.primitiveField());
Info << "Total energy absorbed [W]: " << totalQ << endl;
if (mesh_.time().writeTime())

View File

@ -36,13 +36,13 @@ Description
if (adjustTimeStep)
{
scalar maxDeltaTFact =
min
Foam::min
(
maxCo/(CoNum + SMALL),
min
Foam::min
(
maxAlphaCo/(alphaCoNum + SMALL),
min
Foam::min
(
maxAlphaDdt/(ddtAlphaNum + SMALL),
maxDi/(DiNum + SMALL)
@ -50,11 +50,12 @@ if (adjustTimeStep)
)
);
scalar deltaTFact = min(min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
scalar deltaTFact =
Foam::min(Foam::min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
runTime.setDeltaT
(
min
Foam::min
(
deltaTFact*runTime.deltaTValue(),
maxDeltaT

View File

@ -8,5 +8,5 @@
Info<< "Max Ur Courant Number = " << UrCoNum << endl;
CoNum = max(CoNum, UrCoNum);
CoNum = Foam::max(CoNum, UrCoNum);
}

View File

@ -8,5 +8,5 @@
Info<< "Max Ur Courant Number = " << UrCoNum << endl;
CoNum = max(CoNum, UrCoNum);
CoNum = Foam::max(CoNum, UrCoNum);
}

View File

@ -51,17 +51,20 @@ Description
//- Mapping of some fundamental and aggregate types to MPI data types
enum class dataTypes : int
{
// Builtin Types [8]:
DataTypes_begin, //!< Begin builtin types (internal use)
type_byte = DataTypes_begin, // also for char, unsigned char
// Fundamental Types [10]:
Basic_begin,
type_byte = Basic_begin,
type_int16,
type_int32,
type_int64,
type_uint16,
type_uint32,
type_uint64,
type_float,
type_double,
type_long_double,
invalid
invalid,
Basic_end = invalid
};
@ -69,20 +72,19 @@ enum class dataTypes : int
// Partial copy from UPstreamTraits.H
//- A supported UPstream data type (intrinsic or user-defined)
//- UPstream data type corresponding to an intrinsic (MPI) type
template<class T>
struct UPstream_base_dataType : std::false_type
struct UPstream_mpi_dataType : std::false_type
{
static constexpr auto datatype_id = dataTypes::invalid;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Specializations of the above,
// each to match the elements of UPstream::dataTypes
// Specializations to match elements of UPstream::dataTypes
#undef defineUPstreamDataTraits
#define defineUPstreamDataTraits(TypeId, Type) \
template<> struct UPstream_base_dataType<Type> : std::true_type \
template<> struct UPstream_mpi_dataType<Type> : std::true_type \
{ \
static constexpr auto datatype_id = dataTypes::TypeId; \
};
@ -90,8 +92,10 @@ struct UPstream_base_dataType : std::false_type
defineUPstreamDataTraits(type_byte, char);
defineUPstreamDataTraits(type_byte, unsigned char);
defineUPstreamDataTraits(type_int16, int16_t);
defineUPstreamDataTraits(type_int32, int32_t);
defineUPstreamDataTraits(type_int64, int64_t);
defineUPstreamDataTraits(type_uint16, uint16_t);
defineUPstreamDataTraits(type_uint32, uint32_t);
defineUPstreamDataTraits(type_uint64, uint64_t);
defineUPstreamDataTraits(type_float, float);
@ -109,8 +113,8 @@ struct UPstream_alias_dataType
:
std::bool_constant
<
// Base type (no alias needed)
UPstream_base_dataType<std::remove_cv_t<T>>::value ||
// Basic MPI type
UPstream_mpi_dataType<std::remove_cv_t<T>>::value ||
(
// Or some int 32/64 type to re-map
std::is_integral_v<T>
@ -118,15 +122,11 @@ struct UPstream_alias_dataType
)
>
{
// Is it using the base type? (no alias needed)
static constexpr bool is_base =
UPstream_base_dataType<std::remove_cv_t<T>>::value;
using base = std::conditional_t
<
UPstream_base_dataType<std::remove_cv_t<T>>::value, // is_base
std::remove_cv_t<T>,
std::conditional_t
UPstream_mpi_dataType<std::remove_cv_t<T>>::value,
std::remove_cv_t<T>, // <- using mpi type (no alias)
std::conditional_t // <- using alias
<
(
std::is_integral_v<T>
@ -138,12 +138,32 @@ struct UPstream_alias_dataType
std::conditional_t<std::is_signed_v<T>, int32_t, uint32_t>,
std::conditional_t<std::is_signed_v<T>, int64_t, uint64_t>
>,
char // Fallback value (assuming it is contiguous)
char // Fallback is a byte (eg, arbitrary contiguous data)
>
>;
static constexpr auto datatype_id =
UPstream_base_dataType<base>::datatype_id;
UPstream_mpi_dataType<base>::datatype_id;
};
// Handle int8_t/uint8_t as aliases since 'signed char' etc may be
// ambiguous
//- Map \c int8_t to UPstream::dataTypes::type_byte
template<>
struct UPstream_alias_dataType<int8_t> : std::true_type
{
using base = char;
static constexpr auto datatype_id = dataTypes::type_byte;
};
//- Map \c uint8_t to UPstream::dataTypes::type_byte
template<>
struct UPstream_alias_dataType<uint8_t> : std::true_type
{
using base = unsigned char;
static constexpr auto datatype_id = dataTypes::type_byte;
};
@ -172,25 +192,30 @@ void print(const char* name, bool showLimits = true)
}
// A declared or deduced MPI type, or aliased
std::cout
<< " is_mpi=" << UPstream_base_dataType<T>::value
<< " (" << int(UPstream_base_dataType<T>::datatype_id) << ")";
if (UPstream_alias_dataType<T>::value)
if constexpr (UPstream_mpi_dataType<T>::value)
{
if (UPstream_alias_dataType<T>::is_base)
{
std::cout<< " is_base";
}
else
{
std::cout<< " is_alias ("
<< int(UPstream_alias_dataType<T>::datatype_id) << ")";
}
std::cout
<< " is_mpi=("
<< int(UPstream_mpi_dataType<T>::datatype_id) << ')';
}
else
{
std::cout<< " no_alias";
std::cout << " is_mpi=(null)";
}
// Any aliases?
if constexpr (UPstream_alias_dataType<T>::value)
{
if constexpr (UPstream_mpi_dataType<T>::value)
{
std::cout << " alias=base";
}
else
{
std::cout
<< " alias=("
<< int(UPstream_alias_dataType<T>::datatype_id) << ')';
}
}
std::cout<< '\n';
@ -217,6 +242,7 @@ int main(int argc, char *argv[])
std::cout << '\n';
print<char>("char");
print<signed char>("signed char");
print<unsigned char>("unsigned char");
print<short>("short");
print<int>("int");

View File

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

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2023 OpenCFD Ltd.
Copyright (C) 2017-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -74,15 +74,11 @@ Ostream& toString(Ostream& os, const List<char>& list)
void printTokens(Istream& is)
{
label count = 0;
token t;
while (is.good())
Info<< "stream tokens:" << endl;
for (token tok; tok.read(is); ++count)
{
is >> t;
if (t.good())
{
++count;
Info<< "token: " << t << endl;
}
Info<< " : " << tok << endl;
}
Info<< count << " tokens" << endl;
@ -455,6 +451,12 @@ int main(int argc, char *argv[])
"( const char input \"string\" to tokenize )\n"
"List<label> 5(0 1 2 3 4);";
// printTokens
{
ISpanStream is(charInput);
printTokens(is);
}
string stringInput("( string ; input \"string\" to tokenize )");
List<char> listInput

View File

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

View File

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

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017 OpenCFD Ltd.
Copyright (C) 2017-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -35,6 +35,7 @@ Description
#include "FixedList.H"
#include "labelList.H"
#include "vectorList.H"
#include "SubList.H"
#include "ListOps.H"
#include "IFstream.H"
#include "OFstream.H"
@ -200,6 +201,7 @@ int main(int argc, char *argv[])
argList::addBoolOption("order");
argList::addBoolOption("labelList");
argList::addBoolOption("vectorList");
argList::addBoolOption("ulist");
argList args(argc, argv);
@ -261,6 +263,37 @@ int main(int argc, char *argv[])
}
if (args.found("ulist"))
{
using span_type = stdFoam::span<vector>;
using ulist_type = UList<vector>;
ulist_type view1, view2;
span_type span1, span2;
List<vector> list(10, vector::one);
Info<< "List: " << Foam::name(list.data()) << nl;
Info<< "view: " << Foam::name(view1.data()) << nl;
Info<< "span: " << Foam::name(span1.data()) << nl;
view1 = list.slice(4);
span1 = span_type(list.begin(4), list.size()-4);
Info<< "view [4]:" << Foam::name(view1.data()) << nl;
Info<< "span [4]:" << Foam::name(span1.data()) << nl;
view2 = std::move(view1);
span2 = std::move(span1);
Info<< "view old:" << Foam::name(view1.data()) << nl;
Info<< "span old:" << Foam::name(span1.data()) << nl;
Info<< "view [4]:" << Foam::name(view2.data()) << nl;
Info<< "span [4]:" << Foam::name(span2.data()) << nl;
view1 = list.slice(7);
Info<< "view [7]:" << Foam::name(view1.data()) << nl;
}
Info<< nl << "Done" << nl << endl;
return 0;
}

View File

@ -37,35 +37,40 @@ Description
#include "vector.H"
#include "tensor.H"
#include "uLabel.H"
#include "MinMax.H"
#include "Switch.H"
#include "IOstreams.H"
#include "UPstream.H"
#include <functional>
#include <type_traits>
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Just for debugging
const List<std::string> dataType_names
({
"byte",
"int32",
"int64",
"uint32",
"uint64",
"float",
"double",
"long_double",
namespace Foam
{
// Add in some extras from functional
//- Map std::plus to \c UPstream::opCodes::op_sum
template<>
struct UPstream_opType<std::plus<void>> : std::true_type
{
static constexpr auto opcode_id = UPstream::opCodes::op_sum;
};
//- Map 'signed char' to UPstream::dataTypes::type_byte
// Caution with: may be identical to int8_t mapping!!
#if 0
template<>
struct UPstream_alias_dataType<signed char> : std::true_type
{
using base = char;
static constexpr auto datatype_id = UPstream::dataTypes::type_byte;
};
#endif
"float(2)",
"double(2)",
"float(3)",
"double(3)",
"float(6)",
"double(6)",
"float(9)",
"double(9)"
});
//- Test for pTraits typeName member : default is false
template<class T, class = void>
@ -82,24 +87,93 @@ struct check_has_typeName
std::true_type
{};
// Possible future change...
// //- A supported UPstream data type (intrinsic or user-defined)
// template<>
// struct UPstream_base_dataType<complex> : std::true_type
// {
// static constexpr auto datatype_id = []()
// {
// if constexpr (sizeof(complex) == 2*sizeof(float))
// return UPstream::dataTypes::type_2float;
// else
// return UPstream::dataTypes::type_2double;
// }();
// };
} // End namespace Foam
template<class T>
void printTypeName(const bool showSize = false)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Just for debugging
static const Foam::List<std::string> dataType_names
({
"byte",
"int16",
"int32",
"int64",
"uint16",
"uint32",
"uint64",
"float",
"double",
"long_double",
"float[3]",
"double[3]",
"float[6]",
"double[6]",
"float[9]",
"double[9]"
});
// Just for debugging
static const Foam::List<std::string> opType_names
({
"op_min",
"op_max",
"op_sum",
"op_prod",
"op_bool_and",
"op_bool_or",
"op_bool_xor",
"op_bit_and",
"op_bit_or",
"op_bit_xor",
"op_replace",
"op_no_op"
});
using namespace Foam;
void printDataTypeId(UPstream::dataTypes datatype_id)
{
if (datatype_id != UPstream::dataTypes::invalid)
{
const int index = int(datatype_id);
if (index < dataType_names.size())
{
Info<< dataType_names[index];
}
else
{
Info<< '(' << index << ')';
}
}
}
void printOpCodeId(UPstream::opCodes opcode_id)
{
if (opcode_id != UPstream::opCodes::invalid)
{
const int index = int(opcode_id);
if (index < opType_names.size())
{
Info<< ':' << opType_names[index].c_str();
}
else
{
Info<< '(' << index << ')';
}
}
else
{
Info<< "(null)";
}
}
template<class T, bool showSize = false>
void printTypeName()
{
// Both float and double have pTraits typeName = "scalar"!
if constexpr (std::is_same_v<float, std::remove_cv_t<T>>)
@ -118,12 +192,13 @@ void printTypeName(const bool showSize = false)
{
Info<< typeid(T).name();
}
if (showSize)
if constexpr (showSize)
{
Info<< " (" << sizeof(T) << " bytes)";
}
}
template<class Type, bool UseTypeName = true>
void printPstreamTraits(const std::string_view name = std::string_view())
{
@ -133,55 +208,111 @@ void printPstreamTraits(const std::string_view name = std::string_view())
{
Info<< name << ' ';
}
if constexpr (UseTypeName)
{
printTypeName<Type>(true);
printTypeName<Type, true>();
}
else
{
Info<< typeid(Type).name();
Info<< " (" << sizeof(Type) << " bytes)";
Info<< typeid(Type).name() << " (" << sizeof(Type) << " bytes)";
}
{
using cmpt = typename Foam::pTraits_cmptType<Type>::type;
if constexpr (!std::is_same_v<Type, cmpt>)
{
Info<< ", cmpt:";
if constexpr (UseTypeName)
{
printTypeName<cmpt, true>();
}
else
{
Info<< typeid(cmpt).name() << " (" << sizeof(cmpt) << " bytes)";
}
}
}
Info<< ", cmpt:";
printTypeName<typename Foam::pTraits_cmptType<Type>::type>(true);
Info<< nl
<< " is_contiguous:"
<< is_contiguous<Type>::value
<< ", is base:"
<< UPstream_base_dataType<Type>::value
<< ", is cmpt:"
<< UPstream_dataType<Type>::value << nl;
Info<< "is base:"
<< UPstream_base_dataType<Type>::value
<< " (type:" << int(UPstream_base_dataType<Type>::datatype_id)
<< ") is alias:" << UPstream_alias_dataType<Type>::value
<< " (type:" << int(UPstream_alias_dataType<Type>::datatype_id)
<< ")" << nl;
<< is_contiguous<Type>::value;
if constexpr (UPstream_mpi_dataType<Type>::value)
{
int index = int(UPstream_base_dataType<Type>::datatype_id);
Info<< "datatype: " << index;
Info<< ", is_mpi=("
<< int(UPstream_mpi_dataType<Type>::datatype_id) << ')';
}
else
{
std::cout << ", is_mpi=(null)";
}
if constexpr (UPstream_user_dataType<Type>::value)
{
Info<< ", is_user=("
<< int(UPstream_user_dataType<Type>::datatype_id) << ')';
}
else
{
std::cout << ", is_user=(null)";
}
if constexpr (UPstream_any_dataType<Type>::value)
{
Info<< ", is_any=("
<< int(UPstream_any_dataType<Type>::datatype_id) << ')';
}
else
{
std::cout << ", is_any=(null)";
}
if (index < dataType_names.size())
{
Info<< ' ' << dataType_names[index];
}
Info<< nl;
// Any aliases?
if constexpr
(
UPstream_alias_dataType<Type>::value
&& !UPstream_mpi_dataType<Type>::value
)
{
Info<< ", alias=("
<< int(UPstream_alias_dataType<Type>::datatype_id) << ')';
}
Info<< " base-type:" << int(UPstream_basic_dataType<Type>::datatype_id)
<< " data-type:" << int(UPstream_dataType<Type>::datatype_id)
<< nl;
if constexpr (UPstream_basic_dataType<Type>::value)
{
Info<< " base-type=";
printDataTypeId(UPstream_basic_dataType<Type>::datatype_id);
}
else if constexpr (UPstream_dataType<Type>::value)
{
Info<< " data-type=";
printDataTypeId(UPstream_dataType<Type>::datatype_id);
}
{
// Use element or component type (or byte-wise) for data type
using base = typename UPstream_dataType<Type>::base;
constexpr auto datatype = UPstream_dataType<Type>::datatype_id;
Info<< "datatype => ";
printTypeName<base>();
Info<< " (" << sizeof(Type)/sizeof(base) << " elems)" << nl
<< "datatype: " << static_cast<int>(datatype) << nl;
Info<< " : ";
if constexpr (UseTypeName)
{
printTypeName<base, true>();
}
else
{
Info<< typeid(base).name() << " (" << sizeof(base) << " bytes)";
}
Info<< " cmpt-type=";
printDataTypeId(UPstream_dataType<Type>::datatype_id);
Info<< " count=" << UPstream_dataType<Type>::size(1);
Info<< nl;
}
}
@ -190,15 +321,44 @@ template<class BinaryOp>
void printOpCodeTraits(BinaryOp bop, std::string_view name)
{
Info<< "op: " << name << ' ';
if constexpr (UPstream_opType<BinaryOp>::value)
printOpCodeId(UPstream_opType<BinaryOp>::opcode_id);
Info<< nl;
}
template<class DataType, class BinaryOp>
void printOpCodeTraits(BinaryOp bop, std::string_view name)
{
Info<< "op: " << name << ' ';
printOpCodeId(UPstream_opType<BinaryOp>::opcode_id);
if constexpr (!std::is_void_v<DataType>)
{
Info<< "supported";
if constexpr (UPstream_basic_dataType<DataType>::value)
{
Info<< " [supported type]";
}
else
{
Info<< " [disabled]";
}
}
else
{
Info<< "unknown";
}
Info<< ": " << int(UPstream_opType<BinaryOp>::opcode_id) << nl;
Info<< nl;
}
template<class DataType, class BinaryOp>
void print_data_opType(BinaryOp bop, std::string_view name)
{
Info<< "op: " << name << ' ';
printOpCodeId(UPstream_data_opType<BinaryOp, DataType>::opcode_id);
const bool ok = UPstream_data_opType<BinaryOp, DataType>::value;
Info<< " okay=" << ok << nl;
}
@ -210,6 +370,16 @@ int main()
printPstreamTraits<bool>();
printPstreamTraits<label>();
printPstreamTraits<char, false>("<char>");
printPstreamTraits<signed char, false>("<signed char>");
printPstreamTraits<unsigned char, false>("<unsigned char>");
printPstreamTraits<int8_t, false>("<int8_t>");
printPstreamTraits<uint8_t, false>("<uint8_t>");
printPstreamTraits<int16_t, false>("<int16_t>");
printPstreamTraits<uint16_t, false>("<uint16_t>");
printPstreamTraits<int>("<int>");
printPstreamTraits<long>("<long>");
printPstreamTraits<unsigned>("<unsigned>");
@ -258,6 +428,35 @@ int main()
printOpCodeTraits(bitAndOp<unsigned>{}, "bitAnd<unsigned>");
printOpCodeTraits(bitOrOp<unsigned>{}, "bitOr<unsigned>");
printOpCodeTraits<vector>(sumOp<vector>{}, "sum");
printOpCodeTraits(sumOp<scalarMinMax>{}, "sum");
printOpCodeTraits(std::plus<>{}, "sum");
printOpCodeTraits<bool>(std::plus<>{}, "sum");
printOpCodeTraits<vector>(std::plus<>{}, "sum");
// Expect success
Info<< nl << "expect success" << nl;
print_data_opType<vector>(maxOp<scalar>(), "maxOp(scalar)");
print_data_opType<unsigned>(bitOrOp<unsigned>(), "bitOrOp(unsigned)");
print_data_opType<uint8_t>(bitOrOp<uint8_t>(), "bitOrOp(uint8_t)");
print_data_opType<uint16_t>(bitOrOp<uint16_t>(), "bitOrOp(uint16_t)");
// Even allow signed integrals
print_data_opType<int>(bitOrOp<int>(), "bitOrOp(int)");
print_data_opType<int8_t>(bitOrOp<int8_t>(), "bitOrOp(int8_t)");
// Failure - supported op, unsupported data type.
Info<< nl << "expect failure" << nl;
print_data_opType<bool>(maxOp<scalar>(), "maxOp(scalar, bool)");
print_data_opType<bool>(bitOrOp<unsigned>(), "bitOrOp(unsigned, bool)");
// False positives. Failure - supported op, unsupported data type.
Info<< nl << "false positives" << nl;
print_data_opType<void>(maxOp<bool>(), "maxOp(bool, void)");
print_data_opType<float>(bitOrOp<unsigned>(), "bitOrOp(unsigned, float)");
Info<< nl << "End\n" << endl;
return 0;

View File

@ -0,0 +1,3 @@
Test-gather-scatter1.cxx
EXE = $(FOAM_USER_APPBIN)/Test-gather-scatter1

View File

@ -0,0 +1,2 @@
/* EXE_INC = */
/* EXE_LIBS = */

View File

@ -0,0 +1,282 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application
Test-gather-scatter1
Description
Simple tests for gather/scatter
\*---------------------------------------------------------------------------*/
#include "List.H"
#include "argList.H"
#include "Time.H"
#include "Pstream.H"
#include "IOstreams.H"
using namespace Foam;
//- Ostensibly the inverse of gatherList, but actually works like
//- a broadcast that skips overwriting the local rank!
template<class T>
void real_scatterList
(
//! [in,out]
UList<T>& values,
[[maybe_unused]] const int tag = UPstream::msgType(),
const int communicator = UPstream::worldComm
)
{
if (!UPstream::is_parallel(communicator))
{
// Nothing to do
return;
}
else if constexpr (is_contiguous_v<T>)
{
// This part is a real in-place scatter:
// In-place scatter for contiguous types - one element per rank
// - on master:
// * send pointer is the full list
// * recv pointer is first destination
// - on rank:
// * send pointer is irrelevant
// * recv pointer is destination in the list
//
// So can simply use identical pointers for send/recv
auto* ptr = values.data() + UPstream::myProcNo(communicator);
UPstream::mpiScatter(ptr, ptr, 1, communicator);
}
else
{
// Communication order
const auto& commOrder = UPstream::whichCommunication(communicator);
Pstream::scatterList_algorithm(commOrder, values, tag, communicator);
}
}
//- gatherList_algorithm, but with specific communication style
template<class T>
void gatherList_algo
(
const bool linear,
//! [in,out]
UList<T>& values,
[[maybe_unused]] const int tag = UPstream::msgType(),
const int communicator = UPstream::worldComm
)
{
if (UPstream::is_parallel(communicator))
{
Pstream::gatherList_algorithm
(
UPstream::whichCommunication(communicator, linear),
values,
tag,
communicator
);
}
}
//- scatterList_algorithm, but with specific communication style
template<class T>
void scatterList_algo
(
const bool linear,
//! [in,out]
UList<T>& values,
[[maybe_unused]] const int tag = UPstream::msgType(),
const int communicator = UPstream::worldComm
)
{
if (UPstream::is_parallel(communicator))
{
Pstream::scatterList_algorithm
(
UPstream::whichCommunication(communicator, linear),
values,
tag,
communicator
);
}
}
// Perform tests
template<class ListType, class ResetCode>
void doTest(ResetCode reset)
{
ListType values;
reset(values);
Pout<< nl << "before:" << flatOutput(values) << endl;
Pstream::broadcastList(values);
Pout<< "broadcast:" << flatOutput(values) << endl;
reset(values);
Pout<< nl << "before:" << flatOutput(values) << endl;
Pstream::scatterList(values);
Pout<< "scatter:" << flatOutput(values) << endl;
reset(values);
Pout<< "before:" << flatOutput(values) << endl;
real_scatterList(values);
Pout<< "inplace:" << flatOutput(values) << endl;
using control = std::pair<int, int>;
const char* algoType[2] = { "tree", "linear" };
for
(
auto [gather, scatter] :
{
control{0, 0},
control{1, 1},
control{0, 1},
control{1, 0}
}
)
{
reset(values);
Pout<< nl << "before:" << flatOutput(values) << endl;
gatherList_algo(gather, values);
Pout<< "gather[" << algoType[gather] << "]:"
<< flatOutput(values) << endl;
scatterList_algo(scatter, values);
Pout<< "scatter[" << algoType[scatter] << "]:"
<< flatOutput(values) << endl;
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
argList::noCheckProcessorDirectories();
argList::addVerboseOption("increase UPstream::debug level");
#include "setRootCase.H"
const int optVerbose = args.verbose();
if (optVerbose)
{
UPstream::debug = optVerbose;
}
Pout<< nl << "Test contiguous" << endl;
{
doTest<labelList>
(
[](auto& values){
if (UPstream::master())
{
values = identity(UPstream::nProcs());
}
else
{
values.resize(UPstream::nProcs());
values = -1;
values[UPstream::myProcNo()] = 10 * UPstream::myProcNo();
}
}
);
}
Pout<< nl << "Test non-contiguous" << endl;
{
doTest<wordList>
(
[](auto& values) {
values.resize(UPstream::nProcs());
if (UPstream::master())
{
forAll(values, i)
{
values[i] = "proc" + Foam::name(i);
}
}
else
{
values = "none";
values[UPstream::myProcNo()] =
"_" + Foam::name(UPstream::myProcNo());
}
}
);
}
// Test dummy broadcast as well
Pout<< nl << "Test broadcastList" << endl;
{
wordList list;
Pout<< nl << "before: " << flatOutput(list) << endl;
Pstream::broadcastList(list);
Pout<< "-> " << flatOutput(list) << endl;
}
// Test in-place reduce
Pout<< nl << "Test in-place reduce" << endl;
{
FixedList<label, 6> list;
list = UPstream::myProcNo();
Pout<< nl << "before: " << flatOutput(list) << endl;
UPstream::mpiReduce
(
list.data(),
list.size(),
UPstream::opCodes::op_sum,
UPstream::worldComm
);
Pout<< "-> " << flatOutput(list) << endl;
}
Info<< nl << "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -345,8 +345,8 @@ static void reportOffsets(const globalIndex& gi)
UPstream::broadcast
(
allOffsets.data_bytes(),
allOffsets.size_bytes(),
allOffsets.data(),
allOffsets.size(),
interNodeComm
);
}
@ -508,7 +508,7 @@ int main(int argc, char *argv[])
#include "setRootCase.H"
const bool useLocalComms = UPstream::usingNodeComms();
const bool useLocalComms = UPstream::usingNodeComms(UPstream::worldComm);
bool useWindow = args.found("window");
bool useBuiltin = args.found("builtin");

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -115,6 +115,13 @@ int main(int argc, char *argv[])
);
if (UPstream::parRun())
{
const auto& procs = UPstream::localNode_parentProcs();
Perr<< "local processors: [" << procs.min()
<< ".." << procs.max() << ']' << endl;
}
// Generate the graph
if (UPstream::master(UPstream::worldComm))
{

View File

@ -0,0 +1,3 @@
Test-one-sided1.cxx
EXE = $(FOAM_USER_APPBIN)/Test-one-sided1

View File

@ -0,0 +1,2 @@
/* EXE_INC = */
/* EXE_LIBS = */

View File

@ -0,0 +1,354 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application
Test-one-sided1
Description
Simple test of one-sided communication
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "Time.H"
#include "IPstream.H"
#include "OPstream.H"
#include "SubField.H"
#include "vector.H"
#include "IOstreams.H"
using namespace Foam;
template<class T>
Ostream& printSpanInfo(Ostream& os, const UList<T>& span)
{
os << "addr=" << Foam::name(span.cdata())
<< " size= " << span.size();
return os;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
argList::noCheckProcessorDirectories();
argList::addVerboseOption();
argList::addBoolOption("no-shared", "disable shared memory tests");
argList::addBoolOption("no-sleep", "disable sleep for async test");
#include "setRootCase.H"
const bool with_shared = !args.found("no-shared");
const bool with_sleep = !args.found("no-sleep");
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Info<< nl
<< "nProcs = " << UPstream::nProcs()
<< " with " << UPstream::nComms() << " predefined comm(s)" << nl;
if (!UPstream::parRun())
{
Info<< "###############" << nl
<< "Not running in parallel. Stopping now" << nl
<< "###############" << endl;
return 1;
}
const auto myProci = UPstream::myProcNo();
const auto numProc = UPstream::nProcs();
// Make some windows
Field<label> buffer(10 + myProci);
buffer = myProci;
Pout<< "input: " << flatOutput(buffer) << endl;
UPstream::Window win;
win.create(buffer, UPstream::worldComm);
// Pass 1
// - grab things from sub-ranks
if (UPstream::master())
{
win.lock_all(true);
win.get
(
buffer.slice(4, 2),
1, // target_rank
2 // target_disp
);
win.unlock_all();
}
Pout<< "output: " << flatOutput(buffer) << endl;
// Pass 2:
// accumulate into master
if (UPstream::is_subrank())
{
win.lock(0);
win.put
(
UPstream::opCodes::op_sum,
buffer.slice(2, 4),
UPstream::masterNo(),
2 // target_disp
);
win.unlock(0);
}
Pout<< "updated: " << flatOutput(buffer) << endl;
// Pass 3:
// Update some values - something very asynchronous
if (UPstream::is_subrank())
{
if (with_sleep)
{
if (UPstream::myProcNo() % 3)
{
Foam::sleep(3);
}
else
{
Foam::sleep(1);
}
}
buffer *= 10;
forAll(buffer, i)
{
buffer[i] *= 1 + (i % 3);
}
}
// Needs a process sync, otherwise master fetches old values
UPstream::barrier(UPstream::worldComm);
label lastValue(-1);
if (UPstream::master())
{
win.lock_all(true);
for (const auto proci : UPstream::subProcs())
{
win.fetch_and_op
(
UPstream::opCodes::op_sum,
buffer[0],
lastValue,
proci,
2 // target_disp
);
}
// Force changes to occur
win.flush_all();
win.unlock_all();
}
Pout<< "last-value : " << lastValue << nl
<< "final : " << flatOutput(buffer) << endl;
labelList allUpdates;
if (UPstream::master())
{
allUpdates.resize(UPstream::nProcs(), -10);
win.lock_all(true);
for (const auto proci : UPstream::subProcs())
{
win.get_value
(
allUpdates[proci],
proci,
2 // target_disp
);
}
win.flush_all();
win.unlock_all();
}
Info<< "gets: " << flatOutput(allUpdates) << endl;
// This should fail (runtime)
#if 0
if (UPstream::master())
{
labelPair value1(-1, -1);
win.lock_all(true);
for (const auto proci : UPstream::subProcs())
{
win.fetch_and_op
(
UPstream::opCodes::op_sum,
value1,
lastValue,
proci,
8 // target_disp
);
}
win.unlock_all();
}
#endif
// Last thing before closing out
// replace values. Not very efficient...
// Persistent data to move onto target:
const label newValue(333);
const label multiplier(-3);
if (UPstream::master())
{
win.lock_all(true);
for (const auto proci : UPstream::subProcs())
{
win.fetch_and_op
(
UPstream::opCodes::op_replace,
newValue,
lastValue,
proci, // target_rank
3 // target_disp
);
win.put_value
(
UPstream::opCodes::op_prod,
multiplier,
proci, // target_rank
5 // target_disp
);
}
win.unlock_all();
}
win.close(); // process collective
Pout<< "modified: " << flatOutput(buffer) << endl;
if (with_shared)
{
// Make some shared window
UList<label> newBuffer;
{
label localLen(0);
if
(
(myProci == 3)
|| (myProci == numProc-2)
)
{
localLen = 0;
}
else
{
localLen = (10 + UPstream::myProcNo());
}
// Just to prove that we can shallow copy the view...
newBuffer =
win.allocate_shared<label>(localLen, UPstream::worldComm);
}
newBuffer = UPstream::myProcNo();
Pout<< "Shared: " << flatOutput(newBuffer) << endl;
{
UList<label> local = win.view<label>();
Pout<< "local win: ";
printSpanInfo(Pout, local) << endl;
}
Pout<< "Query rank1" << endl;
{
// UPtrList<UList<label>> totalList(UPstream::nProcs());
//
// totalList.set(0, &newBuffer);
const label* ptr0 = nullptr;
{
UList<label> buf = win.view_shared<label>(0);
ptr0 = buf.cdata();
Pout<< "addr 0 = " << Foam::name(ptr0)
<< " diff = " << label(0)
<< " + " << buf.size() << endl;
}
// UList<label> other = win.global_view<label>();
for (const auto proci : UPstream::subProcs())
{
UList<label> other = win.view_shared<label>(proci);
const label* ptr = other.cdata();
Pout<< "addr " << proci << " = "
<< Foam::name(ptr)
<< " diff = " << label(ptr - ptr0)
<< " + " << other.size() << endl;
// totalList.set(proci, &other);
}
}
win.close();
}
// Since close() is ignored on null window,
// can call it an arbitrary number of times
win.close();
win.close();
win.close();
Info<< "\nEnd\n" << endl;
return 0;
}
// ************************************************************************* //

View File

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

View File

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

View File

@ -35,11 +35,8 @@ Description
#include "Switch.H"
#include "stringOps.H"
#include "SubStrings.H"
#include "regExp.H"
#include "regExpCxx.H"
#ifndef _WIN32
#include "regExpPosix.H"
#endif
using namespace Foam;
@ -89,20 +86,6 @@ static Ostream& operator<<(Ostream& os, const regExpCxx::results_type& sm)
}
// Simple output of match groups
#ifndef _WIN32
static Ostream& operator<<(Ostream& os, const regExpPosix::results_type& sm)
{
for (std::smatch::size_type i = 1; i < sm.size(); ++i)
{
os << " " << sm.str(i);
}
return os;
}
#endif
template<class RegexType>
void generalTests()
{
@ -299,10 +282,6 @@ int main(int argc, char *argv[])
argList::noFunctionObjects();
argList::noParallel();
argList::addBoolOption("cxx", "Test C++11 regular expressions");
#ifndef _WIN32
argList::addBoolOption("posix", "Test POSIX regular expressions");
#endif
argList::addOption
(
"regex",
@ -321,34 +300,16 @@ int main(int argc, char *argv[])
#ifdef _GLIBCXX_RELEASE
Info<< "_GLIBCXX_RELEASE = " << (_GLIBCXX_RELEASE) << nl;
#endif
if constexpr (std::is_same_v<regExp, regExpCxx>)
{
Info<< "Foam::regExp uses C++11 regex" << nl;
}
#ifndef _WIN32
if constexpr (std::is_same_v<regExp, regExpPosix>)
{
Info<< "Foam::regExp uses POSIX regex" << nl;
}
#ifdef __clang_major__
Info<< "__clang_major__ = " << (__clang_major__) << nl;
#endif
Info<< "sizeof std::regex: " << sizeof(std::regex) << nl;
Info<< "sizeof regex C++11: " << sizeof(regExpCxx) << nl;
#ifndef _WIN32
Info<< "sizeof regex POSIX: " << sizeof(regExpPosix) << nl;
#endif
Info<< "sizeof regExp: " << sizeof(Foam::regExp) << nl;
Info<< "sizeof word: " << sizeof(Foam::word) << nl;
Info<< "sizeof wordRe: " << sizeof(Foam::wordRe) << nl;
Info<< "sizeof keyType: " << sizeof(Foam::keyType) << nl;
if (!args.count({"cxx", "posix"}))
{
args.setOption("cxx");
Info<< "Assuming -cxx as default" << nl;
}
Info<< nl;
if (args.found("regex"))
{
std::string expr(args["regex"]);
@ -359,31 +320,15 @@ int main(int argc, char *argv[])
<< "quotemeta: "
<< stringOps::quotemeta(expr, regExpCxx::meta()) << nl
<< nl;
#ifndef _WIN32
Info<< "(posix):" << nl
<< "meta : " << Switch(regExpPosix::is_meta(expr)) << nl
<< "quotemeta: "
<< stringOps::quotemeta(expr, regExpPosix::meta()) << nl
<< nl;
#endif
Info<< nl;
}
else if (args.size() < 2)
{
Info<< "No test files specified .. restrict to general tests" << nl;
if (args.found("cxx"))
{
generalTests<regExpCxx>();
}
#ifndef _WIN32
if (args.found("posix"))
{
generalTests<regExpPosix>();
}
#endif
}
for (label argi = 1; argi < args.size(); ++argi)
@ -394,17 +339,9 @@ int main(int argc, char *argv[])
Info<< "Test expressions:" << tests << endl;
IOobject::writeDivider(Info) << endl;
if (args.found("cxx"))
{
testExpressions<regExpCxx>(tests);
}
#ifndef _WIN32
if (args.found("posix"))
{
testExpressions<regExpPosix>(tests);
}
#endif
}
Info<< "\nDone" << nl << endl;

View File

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

View File

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

View File

@ -89,7 +89,7 @@ int main(int argc, char *argv[])
inputType in1("move-construct-from");
Info<<"move construct from " << in1.length() << nl;
Info<<"move construct from " << in1.size() << nl;
outputType out1(std::move(in1));
@ -100,7 +100,7 @@ int main(int argc, char *argv[])
out1 = "some-text-rubbish";
out1.resize(10);
Info<<"move assign from " << in1.length() << nl;
Info<<"move assign from " << in1.size() << nl;
out1 = std::move(in1);
@ -329,7 +329,7 @@ int main(int argc, char *argv[])
string s2(s.expand());
cout<< "output string with " << s2.length() << " characters\n";
cout<< "output string with " << s2.size() << " characters\n";
cout<< "ostream<< >" << s2 << "<\n";
Info<< "Ostream<< >" << s2 << "<\n";
Info<< "hash:" << hex << string::hasher()(s2) << dec << endl;

View File

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

View File

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

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2024 OpenCFD Ltd.
Copyright (C) 2017-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -43,18 +43,19 @@ template<class StringType>
void printSubStrings
(
const StringType& str,
const SubStrings<StringType>& split
const SubStrings& split
)
{
Info<< "string {" << str.size() << " chars} = " << str << nl
<< split.size() << " elements {" << split.length() << " chars}"
<< nl;
unsigned i = 0;
for (const auto s : split)
for (unsigned i = 0; i < split.size(); ++i)
{
Info<< "[" << i++ << "] {" << s.length() << " chars} = "
<< s.str() << nl;
const auto& s = split[i];
Info<< "[" << i << "] {" << s.length() << " chars} = "
<< split.view(i) << " == " << s.str()
<< nl;
}
}

View File

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

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.
@ -32,7 +32,10 @@ Description
\*---------------------------------------------------------------------------*/
#include "vectorField.H"
#include "boolVector.H"
#include "labelVector.H"
#include "IOstreams.H"
#include "FixedList.H"
#include "Random.H"
#include <algorithm>
#include <random>
@ -125,6 +128,42 @@ void testNormalise(Field<Type>& fld)
}
// Transcribe vectorspace information into a FixedList
template<class Type>
void testTranscribe(Type& input)
{
if constexpr
(
is_vectorspace_v<Type>
&& std::is_floating_point_v<typename pTraits_cmptType<Type>::type>
)
{
constexpr auto nCmpts = pTraits_nComponents<Type>::value;
using cmpt = typename pTraits_cmptType<Type>::type;
FixedList<cmpt, nCmpts+1> values;
values.back() = 100; // some additional data
VectorSpaceOps<nCmpts>::copy_n(input.cdata(), values.data());
Info<< "Transcribed " << input << " => " << values << nl;
for (auto& val : values)
{
val *= -1;
}
VectorSpaceOps<nCmpts>::copy_n(values.cdata(), input.data());
Info<< " copied back (-1) as " << input
<< " from " << values << nl;
}
else
{
Info<< "Did not transcribe " << input << nl;
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
@ -240,6 +279,16 @@ int main(int argc, char *argv[])
testNormalise(vfld2);
}
Info<< nl
<< "Test transcribing components" << nl;
{
vector vec1(1.1, 2.2, 3.3);
testTranscribe(vec1);
labelVector vec2(10, 20, 30);
testTranscribe(vec2);
}
Info<< "\nEnd\n" << nl;
return 0;

View File

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

View File

@ -108,13 +108,13 @@ Input
if (numNbrs == 1)
{
//if (pointSetPtr) pointSetPtr->insert(mesh.edges()[meshEdgei]);
labelTyp = max(labelTyp, TopoType::OPEN);
labelTyp = Foam::max(labelTyp, TopoType::OPEN);
}
else if (numNbrs == 0 || numNbrs > 2)
{
if (pointSetPtr) pointSetPtr->insert(mesh.edges()[meshEdgei]);
if (badEdgesPtr) badEdgesPtr->insert(edgei);
labelTyp = max(labelTyp, TopoType::ILLEGAL);
labelTyp = Foam::max(labelTyp, TopoType::ILLEGAL);
}
}
reduce(labelTyp, maxOp<label>());

View File

@ -368,7 +368,8 @@ void subsetTopoSets
Info<< "Subsetting " << set.type() << ' ' << set.name() << endl;
labelHashSet subset(2*min(set.size(), map.size()));
labelHashSet subset;
subset.reserve(Foam::min(set.size(), map.size()));
// Map the data
forAll(map, i)

View File

@ -142,26 +142,26 @@ scalar getEdgeStats(const primitiveMesh& mesh, const direction excludeCmpt)
if (mag(eVec & x) > 1-edgeTol)
{
minX = min(minX, eMag);
maxX = max(maxX, eMag);
minX = Foam::min(minX, eMag);
maxX = Foam::max(maxX, eMag);
nX++;
}
else if (mag(eVec & y) > 1-edgeTol)
{
minY = min(minY, eMag);
maxY = max(maxY, eMag);
minY = Foam::min(minY, eMag);
maxY = Foam::max(maxY, eMag);
nY++;
}
else if (mag(eVec & z) > 1-edgeTol)
{
minZ = min(minZ, eMag);
maxZ = max(maxZ, eMag);
minZ = Foam::min(minZ, eMag);
maxZ = Foam::max(maxZ, eMag);
nZ++;
}
else
{
minOther = min(minOther, eMag);
maxOther = max(maxOther, eMag);
minOther = Foam::min(minOther, eMag);
maxOther = Foam::max(maxOther, eMag);
}
}
@ -179,19 +179,19 @@ scalar getEdgeStats(const primitiveMesh& mesh, const direction excludeCmpt)
if (excludeCmpt == 0)
{
return min(minY, min(minZ, minOther));
return Foam::min(minY, Foam::min(minZ, minOther));
}
else if (excludeCmpt == 1)
{
return min(minX, min(minZ, minOther));
return Foam::min(minX, Foam::min(minZ, minOther));
}
else if (excludeCmpt == 2)
{
return min(minX, min(minY, minOther));
return Foam::min(minX, Foam::min(minY, minOther));
}
else
{
return min(minX, min(minY, min(minZ, minOther)));
return Foam::min(minX, Foam::min(minY, Foam::min(minZ, minOther)));
}
}

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.
@ -49,7 +49,7 @@ Description
#include <cstdio>
#include "scalar.H"
#include "StringStream.H"
#include "SpanStream.H"
#include "argList.H"
#include "Time.H"
@ -57,25 +57,23 @@ Description
#include "emptyPolyPatch.H"
#include "preservePatchTypes.H"
#include "cellShape.H"
#include "SLList.H"
#include "SLPtrList.H"
// Flex may use register, which is deprecated and incompatible with C++17
#pragma clang diagnostic ignored "-Wdeprecated-register"
using namespace Foam;
SLList<point> slPoints;
SLList<label> slPointMap;
DynamicList<point> dynPoints;
DynamicList<label> dynPointMap;
label maxNodei = 0;
SLPtrList<labelList> slCellLabels;
SLList<label> slCellMap;
SLList<label> slCellType;
DynamicList<labelList> dynCellLabels;
DynamicList<label> dynCellMap;
DynamicList<label> dynCellType;
label maxCelli = 0;
PtrList<SLList<label>> slPatchCells;
PtrList<SLList<label>> slPatchCellFaces;
// Per patch index, the cell/face pairs
PtrList<DynamicList<labelPair>> patchCellFaces;
// Cell types
Map<word> cellTypes;
@ -126,22 +124,18 @@ elementType ^{space}"TYPE"{cspace}
%%
%{
labelList labels(8);
%}
/* ------------------------------------------------------------------------- *\
------ Start Lexing ------
\* ------------------------------------------------------------------------- */
{node}{label}{cspace}{x}{cspace}{y}{cspace}{z}{space}\n {
IStringStream nodeStream(YYText());
ISpanStream is(YYText());
char tag, c;
label nodei;
point node;
nodeStream
>> tag
point& node = dynPoints.emplace_back();
is
>> tag // skip 'N'
>> c >> nodei
>> c >> node.x()
>> c >> node.y()
@ -149,17 +143,18 @@ elementType ^{space}"TYPE"{cspace}
if (nodei > maxNodei) maxNodei = nodei;
slPointMap.append(nodei);
slPoints.append(node);
dynPointMap.push_back(nodei);
}
{element}{label}{cspace}{label}{cspace}{label}{cspace}{label}{cspace}{label}{cspace}{label}{cspace}{label}{cspace}{label}{cspace}{label}{space}\n {
IStringStream elementStream(YYText());
ISpanStream is(YYText());
char tag, c;
label celli;
elementStream
>> tag >> tag
labelList& labels = dynCellLabels.emplace_back(8);
is
>> tag >> tag // skip 'EN'
>> c >> celli
>> c >> labels[0]
>> c >> labels[1]
@ -172,66 +167,50 @@ elementType ^{space}"TYPE"{cspace}
if (celli > maxCelli) maxCelli = celli;
slCellMap.append(celli);
slCellLabels.append(new labelList(labels));
slCellType.append(currentTypei);
dynCellMap.push_back(celli);
dynCellType.push_back(currentTypei);
}
{bface}{label}{cspace}{label}{cspace}{identifier}{cspace}{integer}{cspace}{value}{space}\n {
IStringStream bfaceStream(YYText());
ISpanStream is(YYText());
char tag, c;
label elementi;
label facei;
label elementi, facei;
scalar indexValue, unknown;
bfaceStream
>> tag >> tag >> tag
is
>> tag >> tag >> tag // skip 'SFE'
>> c >> elementi
>> c >> facei
>> c >> tag >> tag >> tag >> tag
>> c >> unknown
>> c >> indexValue;
label patchi = label(indexValue);
const label patchi = label(indexValue);
if (patchi > slPatchCells.size())
if (patchCellFaces.size() < patchi)
{
slPatchCells.setSize(patchi);
label i = patchCellFaces.size();
forAll(slPatchCells, i)
patchCellFaces.resize(patchi);
for (; i < patchi; ++i)
{
if (!slPatchCells.set(i))
{
slPatchCells.set(i, new SLList<label>);
}
patchCellFaces.try_emplace(i);
}
}
if (patchi > slPatchCellFaces.size())
{
slPatchCellFaces.setSize(patchi);
forAll(slPatchCells, i)
{
if (!slPatchCellFaces.set(i))
{
slPatchCellFaces.set(i, new SLList<label>);
}
}
}
slPatchCells[patchi-1].append(elementi);
slPatchCellFaces[patchi-1].append(facei);
patchCellFaces[patchi-1].emplace_back(elementi, facei);
}
{elementTypeName}{label}{cspace}{identifier}{space}\n {
IStringStream elementStream(YYText());
ISpanStream is(YYText());
char tag,c;
label cellTypei;
word cellTypeName;
elementStream
is
>> tag >> tag // skip 'ET'
>> c >> cellTypei
>> c >> cellTypeName;
@ -244,10 +223,11 @@ elementType ^{space}"TYPE"{cspace}
{elementType}{label}{space}\n {
IStringStream elementStream(YYText());
ISpanStream is(YYText());
char tag,c;
label cellTypei;
elementStream
is
>> tag >> tag >> tag >> tag // skip 'TYPE'
>> c >> cellTypei;
@ -281,10 +261,8 @@ label findFace(const polyMesh& mesh, const face& f)
{
const labelList& pFaces = mesh.pointFaces()[f[0]];
forAll(pFaces, i)
for (const label facei : pFaces)
{
label facei = pFaces[i];
if (mesh.faces()[facei] == f)
{
return facei;
@ -323,7 +301,8 @@ int main(int argc, char *argv[])
FatalError.exit();
}
const scalar scaleFactor = args.getOrDefault<scalar>("scale", 1);
// Actually uses default=0 to skip unnecessary scaling by factor 1.
const scalar scaleFactor = args.getOrDefault<scalar>("scale", 0);
#include "createTime.H"
@ -344,32 +323,32 @@ int main(int argc, char *argv[])
Info<< "Creating points" << endl;
pointField points(slPoints.size());
pointField points(std::move(dynPoints));
label i = 0;
for (const point& pt : slPoints)
// Scale points by the given scale factor
if (scaleFactor > 0)
{
// Scale points for the given scale factor
points[i++] = scaleFactor * pt;
points *= scaleFactor;
}
labelList pointMap(maxNodei+1);
i = 0;
for (const label pointi : slPointMap)
{
pointMap[pointi] = i++;
label i = 0;
for (const label pointi : dynPointMap)
{
pointMap[pointi] = i++;
}
}
Info<< "Creating cells" << endl;
labelList cellMap(maxCelli+1);
i = 0;
for (const label celli : slCellMap)
{
cellMap[celli] = i++;
label i = 0;
for (const label celli : dynCellMap)
{
cellMap[celli] = i++;
}
}
@ -378,15 +357,15 @@ int main(int argc, char *argv[])
const cellModel& pyr = cellModel::ref(cellModel::PYR);
const cellModel& tet = cellModel::ref(cellModel::TET);
labelList labelsHex(8);
labelList labelsPrism(6);
labelList labelsPyramid(5);
labelList labelsTet(4);
FixedList<label, 8> labelsHex;
FixedList<label, 6> labelsPrism;
FixedList<label, 5> labelsPyramid;
FixedList<label, 4> labelsTet;
cellShapeList cellShapes(slCellLabels.size());
cellShapeList cellShapes(dynCellLabels.size());
label nCells = 0;
for (const labelList& labels : slCellLabels)
for (const labelList& labels : dynCellLabels)
{
if // Tetrahedron
(
@ -490,37 +469,29 @@ int main(int argc, char *argv[])
Info<< "Creating boundary patches" << endl;
faceListList boundary(slPatchCells.size());
wordList patchNames(slPatchCells.size());
faceListList boundary(patchCellFaces.size());
wordList patchNames(patchCellFaces.size());
forAll(slPatchCells, patchi)
forAll(patchCellFaces, patchi)
{
SLList<face> patchFaces;
DynamicList<face> patchFaces;
auto cellIter = slPatchCells[patchi].cbegin();
auto faceIter = slPatchCellFaces[patchi].cbegin();
patchFaces.reserve(patchCellFaces[patchi].size());
for
(
;
cellIter.good() && faceIter.good();
++cellIter, ++faceIter
)
for (const auto& tup : patchCellFaces[patchi])
{
const cellShape& shape = cellShapes[cellMap[cellIter()]];
const label celli = tup.first();
const label facei = tup.second();
patchFaces.append
const cellShape& shape = cellShapes[cellMap[celli]];
patchFaces.push_back
(
shape.faces()
[
faceIndex
[shape.nFaces()]
[faceIter()-1]
]
shape.faces()[faceIndex[shape.nFaces()][facei-1]]
);
}
boundary[patchi] = patchFaces;
boundary[patchi] = std::move(patchFaces);
patchNames[patchi] = polyPatch::defaultName(patchi + 1);
}
@ -543,8 +514,8 @@ int main(int argc, char *argv[])
// Now split the boundary faces into external and internal faces. All
// faces go into faceZones and external faces go into patches.
List<faceList> patchFaces(slPatchCells.size());
labelList patchNFaces(slPatchCells.size(), Zero);
List<faceList> patchFaces(patchCellFaces.size());
labelList patchNFaces(patchCellFaces.size(), Zero);
forAll(boundary, patchi)
{
const faceList& bFaces = boundary[patchi];
@ -644,7 +615,7 @@ int main(int argc, char *argv[])
Info<< "Creating faceZone " << patchNames[patchi]
<< " with " << bFaceLabels.size() << " faces" << endl;
fz.append
fz.push_back
(
new faceZone
(
@ -660,29 +631,20 @@ int main(int argc, char *argv[])
// CellZones
labelList types = cellTypes.sortedToc();
forAll(types, typei)
for (const label cellType : cellTypes.sortedToc())
{
const label cellType = types[typei];
// Pick up cells in zone
DynamicList<label> addr;
auto cellMapIter = slCellMap.cbegin();
auto typeIter = slCellType.cbegin();
auto cellMapIter = dynCellMap.cbegin();
for
(
;
typeIter.good();
++typeIter, ++cellMapIter
)
for (const auto& ctype : dynCellType)
{
if (typeIter() == cellType)
if (ctype == cellType)
{
addr.append(cellMap[cellMapIter()]);
addr.push_back(cellMap[*cellMapIter]);
}
++cellMapIter;
}
Info<< "Creating cellZone " << cellTypes[cellType]
@ -694,7 +656,7 @@ int main(int argc, char *argv[])
(
cellTypes[cellType],
addr,
typei,
cz.size(),
pShapeMesh.cellZones()
)
);

View File

@ -271,7 +271,7 @@ int main(int argc, char *argv[])
if (blockPFacePointi != blockPFacePointi2)
{
sqrMergeTol =
min
Foam::min
(
sqrMergeTol,
magSqr
@ -338,16 +338,16 @@ int main(int argc, char *argv[])
blockNFacePoints[blockNFacePointi]
+ blockOffsets[blockNlabel];
label minPN = min(PpointLabel, NpointLabel);
label minPN = Foam::min(PpointLabel, NpointLabel);
if (pointMergeList[PpointLabel] != -1)
{
minPN = min(minPN, pointMergeList[PpointLabel]);
minPN = Foam::min(minPN, pointMergeList[PpointLabel]);
}
if (pointMergeList[NpointLabel] != -1)
{
minPN = min(minPN, pointMergeList[NpointLabel]);
minPN = Foam::min(minPN, pointMergeList[NpointLabel]);
}
pointMergeList[PpointLabel]
@ -411,7 +411,7 @@ int main(int argc, char *argv[])
pointMergeList[PpointLabel]
= pointMergeList[NpointLabel]
= min
= Foam::min
(
pointMergeList[PpointLabel],
pointMergeList[NpointLabel]

View File

@ -645,7 +645,7 @@ bool Foam::fileFormats::ensightMeshReader::readGeometry
// Parse all
SubStrings<string> split;
SubStrings split;
while (is.good())
{

View File

@ -350,7 +350,7 @@ mtype {space}"MTYPE:"{space}
// Find out how many labels are expected. If less or equal to
// seven, read them all and finish with it. If there is more,
// set read of the next line
label labelsToRead = min(8, nVertices);
label labelsToRead = Foam::min(8, nVertices);
label labelI = 0;
for (; labelI < labelsToRead; labelI++)
{
@ -387,7 +387,7 @@ mtype {space}"MTYPE:"{space}
labelList& curLabels = cellLabels[curNumberOfCells];
label labelsToRead = min
label labelsToRead = Foam::min
(
(nCellContinuationLines + 1)*7,
curLabels.size()

View File

@ -269,7 +269,7 @@ void readCells
label maxUnvPoint = 0;
forAll(unvPointID, pointi)
{
maxUnvPoint = max(maxUnvPoint, unvPointID[pointi]);
maxUnvPoint = Foam::max(maxUnvPoint, unvPointID[pointi]);
}
labelList unvToFoam(invert(maxUnvPoint+1, unvPointID));
@ -784,7 +784,7 @@ int main(int argc, char *argv[])
label maxUnvPoint = 0;
forAll(unvPointID, pointi)
{
maxUnvPoint = max(maxUnvPoint, unvPointID[pointi]);
maxUnvPoint = Foam::max(maxUnvPoint, unvPointID[pointi]);
}
labelList unvToFoam(invert(maxUnvPoint+1, unvPointID));

View File

@ -8,10 +8,10 @@
{
if (kivaVersion == kiva3v)
{
regionIndex = max
regionIndex = Foam::max
(
max(idface[quadFace[0]], idface[quadFace[1]]),
max(idface[quadFace[2]], idface[quadFace[3]])
Foam::max(idface[quadFace[0]], idface[quadFace[1]]),
Foam::max(idface[quadFace[2]], idface[quadFace[3]])
);
if (regionIndex > 0)

View File

@ -148,7 +148,7 @@ for (label i=0; i<nPoints; i++)
end = pointMap[end];
}
label minLabel = min(start, end);
label minLabel = Foam::min(start, end);
pointMap[start] = pointMap[end] = minLabel;
}
@ -181,7 +181,7 @@ forAll(cellShapes, celli)
label bcIDs[11] = {-1, 0, 2, 4, -1, 5, -1, 6, 7, 8, 9};
const label nBCs = 12;
constexpr label nBCs = 12;
const word* kivaPatchTypes[nBCs] =
{
@ -232,7 +232,7 @@ const char* kivaPatchNames[nBCs] =
};
List<SLList<face>> pFaces[nBCs];
List<DynamicList<face>> pFaces[nBCs];
face quadFace(4);
face triFace(3);
@ -331,29 +331,29 @@ if
{
forAll(pf, pfi)
{
minz = min(minz, points[pf[pfi]].z());
minz = Foam::min(minz, points[pf[pfi]].z());
}
}
minz += SMALL;
SLList<face> newLinerFaces;
DynamicList<face> newLinerFaces;
for (const face& pf : pFaces[LINER][0])
{
scalar minfz = GREAT;
forAll(pf, pfi)
for (const label pointi : pf)
{
minfz = min(minfz, points[pf[pfi]].z());
minfz = Foam::min(minfz, points[pointi].z());
}
if (minfz > minz)
{
pFaces[CYLINDERHEAD][0].append(pf);
pFaces[CYLINDERHEAD][0].push_back(pf);
}
else
{
newLinerFaces.append(pf);
newLinerFaces.push_back(pf);
}
}
@ -361,33 +361,33 @@ if
{
Info<< "Transferred " << pFaces[LINER][0].size() - newLinerFaces.size()
<< " faces from liner region to cylinder head" << endl;
pFaces[LINER][0] = newLinerFaces;
pFaces[LINER][0] = std::move(newLinerFaces);
}
SLList<face> newCylinderHeadFaces;
DynamicList<face> newCylinderHeadFaces;
for (const face& pf : pFaces[CYLINDERHEAD][0])
{
scalar minfz = GREAT;
forAll(pf, pfi)
for (const label pointi : pf)
{
minfz = min(minfz, points[pf[pfi]].z());
minfz = Foam::min(minfz, points[pointi].z());
}
if (minfz < zHeadMin)
{
pFaces[LINER][0].append(pf);
pFaces[LINER][0].push_back(pf);
}
else
{
newCylinderHeadFaces.append(pf);
newCylinderHeadFaces.push_back(pf);
}
}
if (pFaces[CYLINDERHEAD][0].size() != newCylinderHeadFaces.size())
{
Info<< "Transferred faces from cylinder-head region to linder" << endl;
pFaces[CYLINDERHEAD][0] = newCylinderHeadFaces;
pFaces[CYLINDERHEAD][0] = std::move(newCylinderHeadFaces);
}
}
@ -396,9 +396,9 @@ if
label nPatches = 0;
for (int bci=0; bci<nBCs; bci++)
{
forAll(pFaces[bci], rgi)
for (const auto& faces : pFaces[bci])
{
if (pFaces[bci][rgi].size())
if (faces.size())
{
nPatches++;
}
@ -415,31 +415,34 @@ if (pFaces[WEDGE].size() && pFaces[WEDGE][0].size())
const scalar tanTheta = Foam::tan(degToRad(2.5));
auto iterf = pFaces[WEDGE][0].begin();
auto iterb = pFaces[WEDGE][1].begin();
auto iterf = pFaces[WEDGE][0].cbegin();
auto iterb = pFaces[WEDGE][1].cbegin();
const auto end_iterf = pFaces[WEDGE][0].cend();
const auto end_iterb = pFaces[WEDGE][1].cend();
for
(
;
iterf.good() && iterb.good();
(iterf != end_iterf) && (iterb != end_iterb);
++iterf, ++iterb
)
{
const auto& facef = *iterf;
const auto& faceb = *iterb;
for (direction d=0; d<4; d++)
{
points[iterf()[d]].y() = -tanTheta*points[iterf()[d]].x();
points[iterb()[d]].y() = tanTheta*points[iterb()[d]].x();
points[facef[d]].y() = -tanTheta*points[facef[d]].x();
points[faceb[d]].y() = tanTheta*points[faceb[d]].x();
}
}
}
else
{
pFaces[CYCLIC].setSize(1);
pFaces[CYCLIC].resize(1);
pFaces[CYCLIC][0] = pFaces[WEDGE][0];
for (const face& pf : pFaces[WEDGE][1])
{
pFaces[CYCLIC][0].append(pf);
}
pFaces[CYCLIC][0].push_back(pFaces[WEDGE][1]);
pFaces[WEDGE].clear();
nPatches--;

View File

@ -188,7 +188,7 @@ int main(int argc, char *argv[])
}
maxPatch = max(maxPatch, patchi);
maxPatch = Foam::max(maxPatch, patchi);
triFace tri(readLabel(str)-1, readLabel(str)-1, readLabel(str)-1);

View File

@ -556,8 +556,8 @@ void calcEdgeMinMaxZone
forAll(eFaces, i)
{
label zoneI = mappedZoneID[eFaces[i]];
minZoneID[edgeI] = min(minZoneID[edgeI], zoneI);
maxZoneID[edgeI] = max(maxZoneID[edgeI], zoneI);
minZoneID[edgeI] = Foam::min(minZoneID[edgeI], zoneI);
maxZoneID[edgeI] = Foam::max(maxZoneID[edgeI], zoneI);
}
}
}
@ -661,8 +661,8 @@ void countExtrudePatches
}
// Synchronise decision. Actual numbers are not important, just make
// sure that they're > 0 on all processors.
Pstream::listCombineReduce(zoneSidePatch, plusEqOp<label>());
Pstream::listCombineReduce(zoneZonePatch, plusEqOp<label>());
Pstream::listReduce(zoneSidePatch, sumOp<label>());
Pstream::listReduce(zoneZonePatch, sumOp<label>());
}
@ -813,8 +813,8 @@ void addCoupledPatches
forAll(eFaces, i)
{
label proci = procID[eFaces[i]];
minProcID[edgeI] = min(minProcID[edgeI], proci);
maxProcID[edgeI] = max(maxProcID[edgeI], proci);
minProcID[edgeI] = Foam::min(minProcID[edgeI], proci);
maxProcID[edgeI] = Foam::max(maxProcID[edgeI], proci);
}
}
}
@ -1291,7 +1291,7 @@ void extrudeGeometricProperties
label celli = regionMesh.faceOwner()[facei];
if (regionMesh.isInternalFace(facei))
{
celli = max(celli, regionMesh.faceNeighbour()[facei]);
celli = Foam::max(celli, regionMesh.faceNeighbour()[facei]);
}
// Calculate layer from cell numbering (see createShellMesh)
@ -2210,8 +2210,8 @@ int main(int argc, char *argv[])
if (addSidePatches && (zone0 != zone1)) // || (cos(angle) > blabla))
{
label minZone = min(zone0,zone1);
label maxZone = max(zone0,zone1);
label minZone = Foam::min(zone0,zone1);
label maxZone = Foam::max(zone0,zone1);
label index = minZone*zoneNames.size()+maxZone;
ePatches.setSize(eFaces.size());

View File

@ -3,6 +3,7 @@ MarchingCubes = fastdualoctree_sgp
include $(GENERAL_RULES)/cgal
EXE_INC = \
$(c++LESSWARN) \
-DUNIX \
/* -IMarchingCubes */ \
-I$(FASTDUALOCTREE_SRC_PATH) \

View File

@ -26,7 +26,7 @@ void maxFaceToCell
const cell& cFaces = cells[cellI];
forAll(cFaces, i)
{
cellFld[cellI] = max(cellFld[cellI], faceData[cFaces[i]]);
cellFld[cellI] = Foam::max(cellFld[cellI], faceData[cFaces[i]]);
}
}
@ -56,7 +56,7 @@ void minFaceToCell
const cell& cFaces = cells[cellI];
forAll(cFaces, i)
{
cellFld[cellI] = min(cellFld[cellI], faceData[cFaces[i]]);
cellFld[cellI] = Foam::min(cellFld[cellI], faceData[cFaces[i]]);
}
}
@ -87,8 +87,8 @@ void minFaceToCell
// Internal faces
forAll(own, facei)
{
cellFld[own[facei]] = min(cellFld[own[facei]], faceData[facei]);
cellFld[nei[facei]] = min(cellFld[nei[facei]], faceData[facei]);
cellFld[own[facei]] = Foam::min(cellFld[own[facei]], faceData[facei]);
cellFld[nei[facei]] = Foam::min(cellFld[nei[facei]], faceData[facei]);
}
// Patch faces
@ -99,7 +99,7 @@ void minFaceToCell
forAll(fc, i)
{
cellFld[fc[i]] = min(cellFld[fc[i]], fvp[i]);
cellFld[fc[i]] = Foam::min(cellFld[fc[i]], fvp[i]);
}
}
@ -178,7 +178,14 @@ void Foam::writeFields
(
radToDeg
(
Foam::acos(min(scalar(1), max(scalar(-1), faceOrthogonality)))
Foam::acos
(
Foam::min
(
scalar(1),
Foam::max(scalar(-1), faceOrthogonality)
)
)
)
);
@ -534,7 +541,7 @@ void Foam::writeFields
ownCc,
fc
).quality();
ownVol = min(ownVol, tetQual);
ownVol = Foam::min(ownVol, tetQual);
}
}
if (mesh.isInternalFace(facei))
@ -550,7 +557,7 @@ void Foam::writeFields
fc,
neiCc
).quality();
neiVol = min(neiVol, tetQual);
neiVol = Foam::min(neiVol, tetQual);
}
}
}
@ -602,8 +609,10 @@ void Foam::writeFields
// Internal faces
forAll(own, facei)
{
cellFld[own[facei]] = min(cellFld[own[facei]], ownPyrVol[facei]);
cellFld[nei[facei]] = min(cellFld[nei[facei]], neiPyrVol[facei]);
cellFld[own[facei]] =
Foam::min(cellFld[own[facei]], ownPyrVol[facei]);
cellFld[nei[facei]] =
Foam::min(cellFld[nei[facei]], neiPyrVol[facei]);
}
// Patch faces
@ -614,7 +623,8 @@ void Foam::writeFields
forAll(fc, i)
{
const label meshFacei = fvp.patch().start();
cellFld[fc[i]] = min(cellFld[fc[i]], ownPyrVol[meshFacei]);
cellFld[fc[i]] =
Foam::min(cellFld[fc[i]], ownPyrVol[meshFacei]);
}
}
@ -625,7 +635,7 @@ void Foam::writeFields
if (writeFaceFields)
{
scalarField minFacePyrVol(neiPyrVol);
minFacePyrVol = min
minFacePyrVol = Foam::min
(
minFacePyrVol,
SubField<scalar>(ownPyrVol, mesh.nInternalFaces())

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2019-2021 OpenCFD Ltd.
Copyright (C) 2019-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -37,7 +37,7 @@ Description
#include "argList.H"
#include "OFstream.H"
#include "StringStream.H"
#include "stringOps.H"
#include "point.H"
#include "DynamicList.H"
@ -58,58 +58,49 @@ string getLine(std::ifstream& is)
}
// Read space-separated vertices (with optional '/' arguments)
labelList parseVertices(const string& line)
// Token list with one of the following:
// f v1 v2 v3 ...
// f v1/vt1 v2/vt2 v3/vt3 ...
// l v1 v2 v3 ...
// l v1/vt1 v2/vt2 v3/vt3 ...
static label readObjVertices
(
const SubStrings& tokens,
DynamicList<label>& verts
)
{
DynamicList<label> verts;
verts.clear();
// Assume 'l' is followed by space.
string::size_type endNum = 1;
do
bool first = true;
for (const auto& tok : tokens)
{
string::size_type startNum = line.find_first_not_of(' ', endNum);
if (startNum == string::npos)
if (first)
{
break;
// skip initial "f" or "l"
first = false;
continue;
}
endNum = line.find(' ', startNum);
std::string vrtSpec(tok.str());
string vertexSpec;
if (endNum != string::npos)
if
(
const auto slash = vrtSpec.find('/');
slash != std::string::npos
)
{
vertexSpec = line.substr(startNum, endNum-startNum);
}
else
{
vertexSpec = line.substr(startNum, line.size() - startNum);
vrtSpec.erase(slash);
}
string::size_type slashPos = vertexSpec.find('/');
label vertId = readLabel(vrtSpec);
label vertI = 0;
if (slashPos != string::npos)
{
IStringStream intStream(vertexSpec.substr(0, slashPos));
intStream >> vertI;
}
else
{
IStringStream intStream(vertexSpec);
intStream >> vertI;
}
verts.append(vertI - 1);
verts.push_back(vertId - 1);
}
while (true);
return verts.shrink();
return verts.size();
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
@ -142,6 +133,8 @@ int main(int argc, char *argv[])
DynamicList<labelList> polyLines;
DynamicList<labelList> polygons;
DynamicList<label> dynVerts;
bool hasWarned = false;
label lineNo = 0;
@ -152,33 +145,58 @@ int main(int argc, char *argv[])
if (line.empty()) continue;
// Read first word
IStringStream lineStream(line);
word cmd(lineStream);
const auto tokens = stringOps::splitSpace(line);
// Require command and some arguments
if (tokens.size() < 2)
{
continue;
}
const word cmd = word::validate(tokens[0]);
if (cmd == "v")
{
scalar x, y, z;
// Vertex
// v x y z
lineStream >> x >> y >> z;
points.append(point(x, y, z));
points.emplace_back
(
readScalar(tokens[1]),
readScalar(tokens[2]),
readScalar(tokens[3])
);
}
else if (cmd == "vn")
{
scalar x, y, z;
// Vertex normals
// vn x y z
lineStream >> x >> y >> z;
pointNormals.append(vector(x, y, z));
pointNormals.emplace_back
(
readScalar(tokens[1]),
readScalar(tokens[2]),
readScalar(tokens[3])
);
}
else if (cmd == "l")
{
polyLines.append(parseVertices(line));
// Line
// l v1 v2 v3 ...
// OR
// l v1/vt1 v2/vt2 v3/vt3 ...
readObjVertices(tokens, dynVerts);
polyLines.emplace_back() = dynVerts;
}
else if (cmd == "f")
{
polygons.append(parseVertices(line));
// f v1 v2 v3 ...
// OR
// f v1/vt1 v2/vt2 v3/vt3 ...
readObjVertices(tokens, dynVerts);
polygons.emplace_back() = dynVerts;
}
else if (cmd != "")
{
@ -188,7 +206,7 @@ int main(int argc, char *argv[])
WarningInFunction
<< "Unrecognized OBJ command " << cmd << nl
<< "In line " << lineStream.str()
<< "In line " << line
<< " at linenumber " << lineNo << nl
<< "Only recognized commands are 'v' and 'l'.\n"
<< "If this is a surface command use surfaceConvert instead"
@ -230,46 +248,42 @@ int main(int argc, char *argv[])
}
label nItems = 0;
forAll(polyLines, polyI)
for (const labelList& line : polyLines)
{
nItems += polyLines[polyI].size() + 1;
nItems += line.size() + 1;
}
outFile
<< "LINES " << polyLines.size() << ' ' << nItems << nl;
forAll(polyLines, polyI)
for (const labelList& line : polyLines)
{
const labelList& line = polyLines[polyI];
outFile << line.size();
forAll(line, i)
for (const label vrt : line)
{
outFile << ' ' << line[i];
outFile << ' ' << vrt;
}
outFile << nl;
}
nItems = 0;
forAll(polygons, polyI)
for (const labelList& line : polygons)
{
nItems += polygons[polyI].size() + 1;
nItems += line.size() + 1;
}
outFile
<< "POLYGONS " << polygons.size() << ' ' << nItems << nl;
forAll(polygons, polyI)
for (const labelList& line : polygons)
{
const labelList& line = polygons[polyI];
outFile << line.size();
forAll(line, i)
for (const label vrt : line)
{
outFile << ' ' << line[i];
outFile << ' ' << vrt;
}
outFile << nl;
}

View File

@ -100,26 +100,26 @@ void printEdgeStats(const polyMesh& mesh)
if (mag(eVec & x) > 1-edgeTol)
{
minX = min(minX, eMag);
maxX = max(maxX, eMag);
minX = Foam::min(minX, eMag);
maxX = Foam::max(maxX, eMag);
nX++;
}
else if (mag(eVec & y) > 1-edgeTol)
{
minY = min(minY, eMag);
maxY = max(maxY, eMag);
minY = Foam::min(minY, eMag);
maxY = Foam::max(maxY, eMag);
nY++;
}
else if (mag(eVec & z) > 1-edgeTol)
{
minZ = min(minZ, eMag);
maxZ = max(maxZ, eMag);
minZ = Foam::min(minZ, eMag);
maxZ = Foam::max(maxZ, eMag);
nZ++;
}
else
{
minOther = min(minOther, eMag);
maxOther = max(maxOther, eMag);
minOther = Foam::min(minOther, eMag);
maxOther = Foam::max(maxOther, eMag);
}
}
}

View File

@ -465,7 +465,7 @@ labelList getRegionFaceOrder
// Do region interfaces
{
const label nRegions = max(cellToRegion)+1;
const label nRegions = Foam::max(cellToRegion)+1;
// Sort in increasing region
SortableList<label> sortKey(mesh.nInternalFaces(), labelMax);
@ -478,8 +478,10 @@ labelList getRegionFaceOrder
if (ownRegion != neiRegion)
{
sortKey[facei] =
min(ownRegion, neiRegion)*nRegions
+max(ownRegion, neiRegion);
(
Foam::min(ownRegion, neiRegion)*nRegions
+ Foam::max(ownRegion, neiRegion)
);
}
}

View File

@ -320,10 +320,10 @@ bool doCommand
const globalMeshData& parData = mesh.globalData();
label typSize =
max
Foam::max
(
parData.nTotalCells(),
max
Foam::max
(
parData.nTotalFaces(),
parData.nTotalPoints()
@ -375,7 +375,7 @@ bool doCommand
topoSet& currentSet = currentSetPtr();
// Presize it according to current mesh data.
currentSet.reserve(max(currentSet.size(), typSize));
currentSet.reserve(Foam::max(currentSet.size(), typSize));
}
}

View File

@ -269,11 +269,7 @@ void addToInterface
EdgeMap<Map<label>>& regionsToSize
)
{
edge interface
(
min(ownRegion, neiRegion),
max(ownRegion, neiRegion)
);
const edge interface(ownRegion, neiRegion, true); // sort=true
auto iter = regionsToSize.find(interface);
@ -509,11 +505,7 @@ void getInterfaceSizes
zoneID = mesh.faceZones().whichZone(facei);
}
edge interface
(
min(ownRegion, neiRegion),
max(ownRegion, neiRegion)
);
const edge interface(ownRegion, neiRegion, true); // sort=true
faceToInterface[facei] = regionsToInterface[interface][zoneID];
}
@ -532,11 +524,7 @@ void getInterfaceSizes
zoneID = mesh.faceZones().whichZone(facei);
}
edge interface
(
min(ownRegion, neiRegion),
max(ownRegion, neiRegion)
);
const edge interface(ownRegion, neiRegion, true); // sort=true
faceToInterface[facei] = regionsToInterface[interface][zoneID];
}
@ -1081,7 +1069,7 @@ label findCorrespondingRegion
}
}
Pstream::listCombineReduce(cellsInZone, plusEqOp<label>());
Pstream::listReduce(cellsInZone, sumOp<label>());
// Pick region with largest overlap of zoneI
label regionI = findMax(cellsInZone);

View File

@ -295,7 +295,8 @@ void subsetTopoSets
Info<< "Subsetting " << set.type() << " " << set.name() << endl;
labelHashSet subset(2*min(set.size(), map.size()));
labelHashSet subset;
subset.reserve(Foam::min(set.size(), map.size()));
// Map the data
forAll(map, i)

View File

@ -1,3 +1,3 @@
addr2line.C
addr2line.cxx
EXE = $(FOAM_APPBIN)/addr2line

View File

@ -1,2 +1,6 @@
/* Disable normal project defaults */
PROJECT_INC =
PROJECT_LIBS =
/* EXE_INC = */
/* EXE_LIBS = */

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 Alexey Matveichev
Copyright (C) 2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -33,12 +34,11 @@ Description
#include <getopt.h>
#include <cstdlib>
#include <regex>
#include <string>
#include <vector>
#include <iostream>
#include "regExp.H"
#include "SubStrings.H"
static void usage();
static void version();
@ -53,7 +53,6 @@ int main(int argc, char *argv[])
int optHelp = 0, optFunctions = 0, optVersion = 0;
int ch;
std::string filename = "a.out";
std::vector<std::string> addresses;
static struct option opts[] =
{
@ -100,15 +99,9 @@ int main(int argc, char *argv[])
argc -= optind;
argv += optind;
while (argc > 0)
{
addresses.push_back(std::string(*argv));
++argv;
--argc;
}
for (const auto& addr : addresses)
for (std::string addr; argc > 0; --argc, ++argv)
{
addr.assign(*argv);
std::cout<< '\n' << getLine(filename, addr).c_str() << '\n';
}
@ -190,10 +183,10 @@ std::string getLine(const std::string& filename, const std::string& addr)
);
Foam::regExp re(".+LineEntry: .+: (.+):([0-9]+):[0-9]+");
static std::regex re(".+LineEntry: .+: (.+):([0-9]+):[0-9]+");
std::smatch groups;
Foam::regExp::results_type groups;
if (!re.match(line, groups))
if (!std::regex_match(line, groups, re))
{
line = "??:0";
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2017 OpenFOAM Foundation
Copyright (C) 2017-2023 OpenCFD Ltd.
Copyright (C) 2017-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -140,6 +140,38 @@ using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Read dictionary from IFstream, setting the stream to ascii/binary mode
//- depending on the 'FoamFile' header content
dictionary readDictionary(Istream& is)
{
auto format = is.format();
// If the file starts with 'FoamFile { ... }'
token tok;
if
(
(tok.read(is) && tok.isWord("FoamFile"))
&& (tok.read(is) && tok.isPunctuation(token::BEGIN_BLOCK))
)
{
is.putBack(tok); // Put back '{'
// FoamFile sub-dictionary content
dictionary header(is);
// Get "format" if present
format = IOstreamOption::formatEnum("format", header, format);
}
// Start again. Probably does not work well with IPstream though
is.rewind();
is.format(format);
// Read, preserving headers
return dictionary(is, true);
}
//- Convert very old ':' scope syntax to less old '.' scope syntax,
// but leave anything with '/' delimiters untouched
bool upgradeScope(word& entryName)
@ -266,6 +298,8 @@ void removeDict(dictionary& dict, const dictionary& dictToRemove)
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
argList::addNote
@ -273,7 +307,7 @@ int main(int argc, char *argv[])
"Interrogate and manipulate dictionaries"
);
argList::noBanner();
argList::noBanner(); // Essential if redirecting stdout
argList::noJobInfo();
argList::addArgument("dict", "The dictionary file to process");
argList::addBoolOption("keywords", "List keywords");
@ -336,7 +370,7 @@ int main(int argc, char *argv[])
"disableFunctionEntries",
"Disable expansion of dictionary directives - #include, #codeStream etc"
);
profiling::disable(); // Disable profiling (and its output)
profiling::disable(); // Disable profiling (and its output)
argList args(argc, argv);
@ -369,7 +403,7 @@ int main(int argc, char *argv[])
const auto dictFileName = args.get<fileName>(1);
auto dictFile = autoPtr<IFstream>::New(dictFileName);
if (!dictFile().good())
if (!dictFile || !dictFile().good())
{
FatalErrorInFunction
<< "Cannot open file " << dictFileName
@ -379,8 +413,13 @@ int main(int argc, char *argv[])
bool changed = false;
// Read but preserve headers
dictionary dict(dictFile(), true);
// Read, preserving headers
//// dictionary dict(dictFile(), true);
dictionary dict = readDictionary(dictFile());
// The extracted dictionary format
const auto dictFormat = dictFile().format();
if (listIncludes)
{
@ -414,8 +453,10 @@ int main(int argc, char *argv[])
<< exit(FatalError, 1);
}
// Read but preserve headers
diffDict.read(diffFile, true);
// Read, preserving headers
//// diffDict.read(diffFile, true);
diffDict = readDictionary(diffFile);
optDiff = true;
}
else if (args.readIfPresent("diff-etc", diffFileName))
@ -436,8 +477,9 @@ int main(int argc, char *argv[])
<< exit(FatalError, 1);
}
// Read but preserve headers
diffDict.read(diffFile, true);
// Read, preserving headers
//// diffDict.read(diffFile, true);
diffDict = readDictionary(diffFile);
optDiff = true;
}
}
@ -592,10 +634,12 @@ int main(int argc, char *argv[])
dict.write(Info, false);
}
// Close the input file
dictFile.reset();
if (changed)
{
dictFile.clear();
OFstream os(dictFileName);
OFstream os(dictFileName, dictFormat);
IOobject::writeBanner(os);
IOobject::writeDivider(os);
dict.write(os, false);

View File

@ -1131,7 +1131,7 @@ int main(int argc, char *argv[])
for
(
label addedI=next;
addedI<min(proci+step, nProcs);
addedI < Foam::min(proci+step, nProcs);
addedI++
)
{

View File

@ -403,11 +403,11 @@ void printMeshData(const polyMesh& mesh)
<< nBndFaces-nProcFaces << endl;
}
maxProcCells = max(maxProcCells, nLocalCells);
maxProcCells = Foam::max(maxProcCells, nLocalCells);
totProcFaces += nProcFaces;
totProcPatches += nei.size();
maxProcFaces = max(maxProcFaces, nProcFaces);
maxProcPatches = max(maxProcPatches, nei.size());
maxProcFaces = Foam::max(maxProcFaces, nProcFaces);
maxProcPatches = Foam::max(maxProcPatches, nei.size());
}
// Summary stats

View File

@ -131,7 +131,7 @@ int main(int argc, char *argv[])
args.readIfPresent("format", setFormat);
args.readIfPresent("stride", sampleFrequency);
sampleFrequency = max(1, sampleFrequency); // sanity
sampleFrequency = Foam::max(1, sampleFrequency); // sanity
// Setup the writer
auto writerPtr =
@ -179,14 +179,14 @@ int main(int argc, char *argv[])
maxIds.resize(origProc+1, -1);
}
maxIds[origProc] = max(maxIds[origProc], origId);
maxIds[origProc] = Foam::max(maxIds[origProc], origId);
}
}
const label maxNProcs = returnReduce(maxIds.size(), maxOp<label>());
maxIds.resize(maxNProcs, -1);
Pstream::listCombineReduce(maxIds, maxEqOp<label>());
Pstream::listReduce(maxIds, maxOp<label>());
// From ids to count
const labelList numIds = maxIds + 1;

View File

@ -40,7 +40,7 @@ Foam::Field<T> Foam::channelIndex::regionSum(const Field<T>& cellField) const
}
// Global sum
Pstream::listCombineReduce(regionField, plusEqOp<T>());
Pstream::listReduce(regionField, sumOp<T>());
return regionField;
}

View File

@ -1056,7 +1056,7 @@ void calc_drag_etc
const scalar expon =
(
br > 0.0
? min(max((surr_br / br - 0.25) * 4.0 / 3.0, scalar(0)), scalar(1))
? Foam::clamp((surr_br / br - 0.25) * 4.0 / 3.0, Foam::zero_one{})
: 0.0
);
@ -1114,16 +1114,16 @@ void Foam::PDRarrays::blockageSummary() const
totVolBlock += v_block(ijk) * pdrBlock.V(ijk);
totArea += surf(ijk);
totCount += max(0, obs_count(ijk));
totCount += Foam::max(0, obs_count(ijk));
totDrag.x() += max(0, drag_s(ijk).xx());
totDrag.y() += max(0, drag_s(ijk).yy());
totDrag.z() += max(0, drag_s(ijk).zz());
totDrag.x() += Foam::max(0, drag_s(ijk).xx());
totDrag.y() += Foam::max(0, drag_s(ijk).yy());
totDrag.z() += Foam::max(0, drag_s(ijk).zz());
for (direction cmpt=0; cmpt < vector::nComponents; ++cmpt)
{
totBlock[cmpt] += max(0, area_block_s(ijk)[cmpt]);
totBlock[cmpt] += max(0, area_block_r(ijk)[cmpt]);
totBlock[cmpt] += Foam::max(0, area_block_s(ijk)[cmpt]);
totBlock[cmpt] += Foam::max(0, area_block_r(ijk)[cmpt]);
}
}
}

View File

@ -302,7 +302,7 @@ void Foam::PDRutils::circle_overlap
scalar da = ac - 0.5 * (a1 + a2);
scalar db = bc - 0.5 * (b1 + b2);
scalar dc = std::hypot(da, db);
scalar rat1 = min(max((dc / sqrt(area) - 0.3) * 1.4, 0), 1);
scalar rat1 = Foam::min(Foam::max((dc / sqrt(area) - 0.3) * 1.4, 0), 1);
scalar drg0 = c_drag(ia,ib).xx();
scalar drg1 = c_drag(ia,ib).yy();
scalar drg = std::hypot(drg0, drg1);
@ -449,8 +449,8 @@ scalar block_overlap
{
PDRobstacle over;
over.pt = max(blk1.pt, blk2.pt);
over.span = min(max1, max2) - over.pt;
over.pt = Foam::max(blk1.pt, blk2.pt);
over.span = Foam::min(max1, max2) - over.pt;
assert(cmptProduct(over.span) > 0.0);
@ -603,11 +603,11 @@ scalar block_cylinder_overlap
over.x() = a_centre - 0.5 * a_lblk;
over.y() = b_centre - 0.5 * b_lblk;
over.z() = max(blk1.z(), cyl2.z());
over.z() = Foam::max(blk1.z(), cyl2.z());
over.span.x() = a_lblk;
over.span.y() = b_lblk;
over.span.z() = min(max1.z(), cyl2.z() + cyl2.len()) - over.z();
over.span.z() = Foam::min(max1.z(), cyl2.z() + cyl2.len()) - over.z();
assert(over.x() > -200.0);
assert(over.x() < 2000.0);
}
@ -668,11 +668,11 @@ scalar block_cylinder_overlap
over.z() = a_centre - a_lblk * 0.5;
over.x() = b_centre - b_lblk * 0.5;
over.y() = max(blk1.y(), cyl2.y());
over.y() = Foam::max(blk1.y(), cyl2.y());
over.span.z() = a_lblk;
over.span.x() = b_lblk;
over.span.y() = min(max1.y(), cyl2.y() + cyl2.len()) - over.y();
over.span.y() = Foam::min(max1.y(), cyl2.y() + cyl2.len()) - over.y();
}
break;
@ -734,11 +734,11 @@ scalar block_cylinder_overlap
over.y() = a_centre - a_lblk * 0.5;
over.z() = b_centre - b_lblk * 0.5;
over.x() = max(blk1.x(), cyl2.x());
over.x() = Foam::max(blk1.x(), cyl2.x());
over.span.y() = a_lblk;
over.span.z() = b_lblk;
over.span.x() = min(max1.x(), cyl2.x() + cyl2.len()) - over.x();
over.span.x() = Foam::min(max1.x(), cyl2.x() + cyl2.len()) - over.x();
}
break;
}

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