Compare commits

...

124 Commits

Author SHA1 Message Date
7207e9e3a9 TUT: add a multi-region finite-area example tutorial 2025-10-12 17:00:17 +02:00
6d2deda470 ENH: revise some regionFaModel parameter naming (#3419)
- the old naming grew organically and was previously restricted
  by avoiding name collisions with volume fields, which resulted
  in some minor consistencies

Common solid shell naming:

  | Keyword  | Default     | Description  | Key(old) | Old Naming     |
  | -------- | ----------- | ------------ | -------- | -------------- |
  | h        | hs (suffix) | thickness    | h        | "h_" + region  |
  | T        | Ts (suffix) | temperature  | -        | "Ts_" + region |

Vibration shells:

  | Keyword  | Default     | Description  | Key(old) | Old Naming     |
  | -------- | ----------- | ------------ | -------- | -------------- |
  |  as      | as (suffix) | acceleration | -        | "as_" + region |
  |  ps      | ps (suffix) | pres on shell| -        | "ps_" + region |
  |  ws      | ws (suffix) | displacement | -        | "ws_" + region |
  |  qs      | qs (suffix  | source field | -        | "qs_" + region |

Other:

  | Keyword  | Default     | Description  | Key(old) |
  | -------- | ----------- | ------------ | -------- |
  | Tprimary | T   | temperature (volume) | T        |

Joule heating: (possibly breaking naming changes)

  | Field    | Name                     | Name(old)                |
  | -------- | ------------------------ | ------------------------ |
  |  V       | \<scope\>:V (suffix)     | \<scope\>:V + region     |
  |  sigma   | \<scope\>:sigma (suffix) | \<scope\>:sigma + region |
2025-10-12 15:54:05 +02:00
c172b588c0 ENH: multi-region finiteArea support [parallel] (#3419)
- redistributePar (partly working)
2025-10-12 15:54:05 +02:00
c075af4f7b ENH: redistributePar cleanup
- remove old dead code (without file-handlers)
- update coding style
2025-10-12 15:54:05 +02:00
a1e5dcee43 ENH: redistributePar cleanup
- update and extend loadOrCreateMesh coding
- support bitSet return values
- accept checks with name/instance/local in IOobject parameter order
2025-10-12 15:54:05 +02:00
f2922f1ae9 ENH: multi-region finiteArea support [parallel] (#3419)
- decomposePar, reconstructPar, reconstructParMesh
2025-10-12 15:54:05 +02:00
1ae48880d2 ENH: multi-region finiteArea support [post-processing] (#3419)
- foamToEnsight, foamToVTK
2025-10-12 15:54:05 +02:00
9fc52d42eb ENH: multi-region finiteArea support [pre-processing] (#3419)
- checkFaMesh, makeFaMesh, setFields
2025-10-12 15:54:05 +02:00
c669f7b736 ENH: provide general static singleton for the faMeshesRegistry objects 2025-10-12 15:54:05 +02:00
27878797e2 ENH: add support for name suffixing in faOption and regionFaModel (#3419)
- in earlier versions, when area fields and volume fields were stored
  together, an automatic suffix of '_' + regionName was appended to
  many of the finite-area fields. This was needed to prevent name
  clashes between 'T' (area) and 'T' (volume) field names.

  This is no longer necessary, but some existing setups may rely on
  the old naming convention. To make this more flexible while also
  minimizing the number of changes, introduced a "suffixing"
  keyword for faOption and regionFaModel.

  Can specify suffixing as "default" to recover the (_ + region)
  naming scheme (can also currently also use true/false/none here).
  Or specify a suffix (eg, _shell) unrelated to any region name.

ENH: improve the code style and alignment in jouleHeatingSource

- make {fa,fv} versions more consistent, for better maintenance
2025-10-12 15:53:29 +02:00
e9fcd75ec4 ENH: add default "constant" name for fileOperations::findTimes()
- makes fileHandler calling resemble Time more closely

ENH: provide natural_sort less/greater functions

- more succinct than (compare < 0) or (compare > 0).
  The corresponding wrappers for UList renamed as list_less, etc
  but they were only used in unit tests

ENH: handle (-allRegions | -all-regions, ..) directly when retrieving args

- makes handling independent of aliasing order

STYLE: include <string_view> when including <string>

- the standard does not guarantee which headers (if any) actually
  include string_view
2025-10-12 15:53:26 +02:00
ac34d9fd29 ENH: allow delayed construction of regionFaModel in volume bcs (#3419)
Ideally wish to delay construction of the finite-area mesh until
  updateCoeffs(), when it is actually needed.

  This helps avoid difficult to trace errors and avoids inadvertent
  parallel communication during construction from a dictionary.

  However, lazy evaluation fails at the later stage while attempting
  to load the corresponding initial fields, since the timeIndex has
  already advanced.

  Use the newly introduced regionModels::allowFaModels() switch
  to locally enable or disable lazy evaluation as needed.

  This allows selective disabling (eg, in post-processing utilities)
  where loading the volume field should not activate the associated
  regionFaModel and loading a finite-area mesh too (which may not
  exist or be defined at that point).
2025-10-11 19:51:51 +02:00
14bece937b ENH: added clean up function remove0DirFields (RunFunctions)
- less typing than before and avoids relying on bash-specific behaviour
  (fixes #3448)

ENH: add -region support for cleanFaMesh and cleanPolyMesh

CONFIG: add bash completion help for -area-region

ENH: general improvements for regionProperties

- robustness and failsafe for foamListRegions, regionProperties
- additional global model switches for regionModels
2025-10-10 18:18:31 +02:00
2396828a60 ENH: increase some string_view coverage
- remove some stdFoam::span<char> handling, which was just a stop-gap
  measure
2025-10-10 09:05:23 +02:00
9223d238bd STYLE: surface/volume writing function objects
- further hide implementation (cxx ending)

STYLE: better distinction between code/templates for fileFormats/conversion

- for ensight and vtk, a large part of the code is header only.
  Make this easier to identify
2025-10-10 08:54:03 +02:00
4b92bb6533 ENH: update globalIndex::mpiGather to use MPI intrinsic/user types
- add provisional support for selecting MPI_Gatherv
  when merging fields in the surface writers.
  Uses the 'gatherv' keyword [experimental]

BUG: gatherv/scatterv wrappers used the incorrect data type

- incorrectly checked against UPstream_basic_dataType trait instead of
  UPstream_dataType, which resulted in a count mismatch for
  user-defined types (eg, vector, tensor,...).

  This was not visibly active bug, since previous internal uses of
  gatherv were restricted to primitive types.

COMP: make UPstream dataType traits size(...) constexpr

- allows static asserts and/or compile-time selection
  of code based on size(1)
2025-10-10 08:51:20 +02:00
55c81bce1b ENH: GAMGAgglomeration: increase repeatability. Fixes #3450 2025-10-09 11:55:06 +01:00
1cb0b7b6c9 Merge branch 'extend-field-distributors' into 'develop'
cleanup of decompose/reconstruct/redistribute, adding area-name support

See merge request Development/openfoam!761
2025-10-09 10:29:56 +00:00
7f939f6d2d ENH: increase coverage of bitSet support for field distributors 2025-10-08 21:26:37 +02:00
cbb66f7bc7 ENH: add area-name handling for faMesh decompose/reconstruct (#3419)
- using labelUList addressing

- support direct handling of pointers (as well as autoPtr)
2025-10-08 21:26:30 +02:00
5d7bd9c497 ENH: decompose/reconstruct using labelUList, UPtrList addressing
ENH: reduce some overhead for processorMeshes reconstructPoints
2025-10-08 21:26:22 +02:00
601239f59a Merge branch 'multi-finite-area.base-changes' into 'develop'
base changes to finite-area and faOptions to recognize different area regions.

See merge request Development/openfoam!760
2025-10-08 12:21:17 +01:00
b25147a4f8 ENH: finite-area region support to all faOptions and regionFaModels
- for a non-default mesh region, corresponding files:

     system/finite-area/faOptions.<name>
     system/finite-area/<name>/faSchemes, etc

  if the entries within the faOptions dictionary happen to contain an
  "area" entry and it conflicts with what is expected, it will be
  rejected when creating the list of options, which helps avoid
  unexpected behaviour and simplifies overall handling.
2025-10-08 13:17:40 +02:00
19628b9576 ENH: update faOptions handling to respect finite-area locations
- new locations
    * constant/finite-area/faOptions
    * system/finite-area/faOptions

- legacy locations are still supported
    * constant/faOptions
    * system/faOptions

TUT: update faOptions locations
2025-10-08 13:17:40 +02:00
b913463d95 ENH: correct handling of area-name for faMesh (#3419)
- unlike fvMesh and polyMesh, the faMesh mesh region name is passed
  separately into constructors and functions. Thus need the same for
  faMeshTools and faMeshSubset.

- ensure that an empty area name is treated like
  polyMesh::defaultRegion.
  The faMeshRegistry or other registries cannot have an empty name!
2025-10-08 13:17:40 +02:00
3ae725592d ENH: add area-regions option handling (based partly on regionProperties)
- extend the getAllRegionOptions and getAllFaRegionOptions handling
  to use the supplied string literals as fallback values.

  If regionProperties is missing (or empty) and the -regions/-area-regions
  option is supplied with literal names, these will be used directly
  instead of being used to filter the regionProperties.

STYLE: support both -all-regions and -allRegions
2025-10-08 13:17:39 +02:00
d6081a18f6 ENH: simpler mechanical or thermal use of solidProperties
- in some shell models, only the mechanical properties (rho,E,nu) are
  meaningful or just the basic thermal properties
  (rho,Cp,kappa,emissivity).

  Add a distinction when reading the dictionary entries
  if those properties are mandatory and the thermo properties
  (eg, molWt, Cp, etc) are optional or not.

  This simplifies user input for thermal and vibration shell models.
2025-10-08 13:17:39 +02:00
e46cc77a5b CONFIG: bump patch level to 2507
- changes in stream handling
- imminent API changes for finite-area
2025-10-08 13:11:07 +02:00
5321c92e3d SUBMODULE: update OpenQBMM (some compilation changes) 2025-10-08 13:05:57 +02:00
97cbe9c54e Merge branch 'update-UPstreamRequests-handling' into 'develop'
refine request handling to support MPI idioms

See merge request Development/openfoam!759
2025-10-08 10:49:29 +00:00
06b3e9bd0b ENH: update/refine UPstream request handling
- activeRequest() checks if given request is still active/pending

- finishedRequest() will now always call MPI_Test when running in
  parallel instead of using a fast-path for skipping a null request.
  This allows MPI a chance to progress operations even if that
  particular request is not active.

- sameProcs() is a convenience wrapper for the following:
  * check if indices resolve to the same underlying procs
  * check the communicator procs against a list of procs
  * to compare two lists of procs.

  For example, check if the communicator corresponds to a
  host-local communication:

     if (UPstream::sameProcs(UPstream::commLocalNode(), myComm)) ...

STYLE: UPstream::Request gets an 'active()' method

- more MPI idiomatic than 'good'
2025-10-07 21:04:23 +02:00
a6c924cf8f COMP: minor adjustments for MacOS
- to avoid the many overload warnings on that platform,
  may wish to use

      FOAM_EXTRA_CXXFLAGS="-Wno-overloaded-virtual"

GIT: remove some old compilation stub files
2025-10-07 19:43:07 +02:00
e5848196ef Merge branch 'mixed-precision-streams' into 'develop'
INT: token/stream support for reading/writing int32 and int64

See merge request Development/openfoam!756
2025-10-07 14:51:20 +00:00
aa96119de2 INT: token/stream support for reading/writing int32 and int64
integration-by: Mark Olesen <Mark.Olesen@keysight.com>
2025-10-07 14:50:37 +00:00
11166821f1 REGRESSION: corrected use of inotify 2025-10-06 16:16:26 +01:00
77b2687503 COMP: better constexpr isolation of List<char> specializations
- adjust the if/else-if/else-if cascade to have 'if constexpr (..)'
  first and the *entire* alternate branch within the following 'else'.
  This lets the compiler know that it can safely discarded the other
  parts.

  This change introduces a large amount of indentation change,
  so use `--ignore-space-change` when inspecting.

COMP: reintroduce UList<T>() initialization in List [silence gcc]

COMP: use std::min() instead of direct check [silence gcc]

- gcc complains about possible strict-overflow for this:
  ```
  if (count > len)
  {
      count = len;        // The count truncated by the new length
  }
  ```

  Using `count = std::min(count, len);` avoids these (spurious)
  warnings without adding a "diagnostic ignored" pragma

STYLE: pass std::pair<int,int> by copy [cheaper]

STYLE: make isdigit() and isspace() tests constexpr

- constexpr and C-locale only vs. the std counterparts
2025-10-06 15:54:00 +02:00
52c55543b5 COMP: no-rpath handling not found (darwin) 2025-10-06 15:01:59 +02:00
41231028da Merge branch 'feature-slicing.prerelease' into 'develop'
Adding scratch space for patchField data

See merge request Development/openfoam!757
2025-10-06 12:43:13 +00:00
35615174a3 Adding scratch space for patchField data 2025-10-06 12:43:13 +00:00
b9fecc3898 Merge branch 'time-paths' into 'develop'
Add handling of local/global layout for Time paths

See merge request Development/openfoam!758
2025-10-06 10:26:15 +00:00
c78b510928 ENH: improve search and addressing options for TimePaths
- extend time searching mechanisms to support searching in the case
  global path: times(), findClosestTime(), findInstancePath()

- extend IOobject path() and objectPath() methods with
  IOobjectOption::Layout variants

The changes are needed for addressing a global file structure
in parallel (#3431)
2025-10-05 21:52:51 +02:00
a91587e36a ENH: improve 'fuzzy' matching of time instant
- add '<=' and '>=' operators that include rounding.

  This means that typical code like the following would not have
  considered any rounding:

    instantList times = ...;
    scalar val = ..;

    // No rounding!
    if (times[i].value() <= val) { ... }

    // NEW: with rounding
    if (times[i] <= val) { ... }

    // old equivalent:
    if (times[i].value() <= val || times[i].equal(val)) { ... }

ENH: provide a default stopInstance for fileOperation::findInstance

- makes it more consistent with Time::findInstance and more convenient
  to use

STYLE: minor code style changes to TimePaths etc
2025-10-05 21:52:37 +02:00
9c4d0cdeef BUG: kinematicParcelFoam: correct source-term value (fixes #3446)
- likely results in output changes for denser carrier fluids

Co-authored-by: Kutalmis Bercin <kutalmis.bercin@esi-group.com>
2025-10-03 15:47:26 +01:00
7a266b566f DOC: functionObjects: overhaul of header documentation 2025-10-02 21:32:26 +01:00
278ad6fb44 Merge branch 'modifiable-memory-streams' into 'develop'
Improve handling and sizing behaviour of memory streams

See merge request Development/openfoam!755
2025-10-01 15:43:01 +01:00
b0d29ba8d6 ENH: add UPstream interface for MPI/IO
- supports writing, but without overlapping (begin/end) semantics.
2025-09-30 10:16:23 +02:00
a42fa7949b ENH: provide Istream::rewind() implementation
- base implementation drops any putback token
2025-09-30 09:32:50 +02:00
c6fc90b629 ENH: add in-place modification for OCharStream
- enables partial overwriting of content
- make default construct zero-sized, add reserve_exact() method

- improve sizing behaviour of OCharStream.
  Since char buffers will approach the INT_MAX size more quickly than
  other content, adapt the following strategy:

    | Capacity range     | Strategy                     |
    |--------------------|------------------------------|
    | 0    < N <= 0.25)  | fast growth (2)              |
    | 0.25 < N <= 0.5)   | slower growth (1.5)          |
    | 0.5  < N <= 0.75)  | very slow growth (1.25)      |
    | 0.75 < N           | already large - use max      |
2025-09-30 09:21:29 +02:00
1d1e0c5f13 ENH: make List::resize_copy() a public method
- improves usability of List as a general dynamic container as member
  data without inheritance. Provide the same method for DynamicList
  to enable more efficient use.

- additional string_view support for charList: useful when being used
  as a character buffer

STYLE: improve allocation handling in List

- consolidate routines. Only assign size after allocation to ensure
  that states are always consistent.
2025-09-29 13:18:29 +02:00
462d04dcd4 ENH: minor cleanup of memory streams and IOstreamOption
- make memory streams header-only (simpler)
- add sub-views and direct seek for span streams

New IOobject convenience methods

- IOobject::instanceValue() : return the IOobject instance as a scalar
  value (or 0). Effectively the same as instant(io.instance()).value()
  but with far less typing.

- IOobject::fileModificationChecking_masterOnly() : combines checks for
  time-stamp and inotify variants

STYLE: minor adjustments for Enum
2025-09-29 13:00:46 +02:00
d39b8a5c94 ENH: binField: remove an unused field
- skip the reduce operation for serial mode
- fix typos
2025-09-24 19:34:17 +01:00
b30d42c391 ENH: age: improve field access pattern
- cache the repeated evaluations
2025-09-24 11:55:42 +01:00
f3998b8833 TUT: scalarTransport: reorganise pitzDaily tutorial
- add application missing step to pimpleFoam/RAS/propeller1
2025-09-24 11:55:42 +01:00
1fa20428a8 STYLE: code cleanup for surfaceCourantNumber (#3422)
- simplify some handling. Use reference (not copy) for internalField
2025-09-23 17:02:01 +02:00
ac1c41a51b ENH: align zones writing pattern with polyBoundaryMesh, patchField etc.
STYLE: output the zone meta data (names) as an undecorated wordList

ENH: extra safety check in reorderZones to avoid any possible leaking
2025-09-23 12:57:02 +02:00
c378893bcb ENH: simplify direct creation of dictionary primitive entries
- can now create an empty entry and add/overwrite with tokens afterwards,
  or copy/move construct from a list of tokens.

ENH: provided named token setter methods (disambiguates bool/char/label)

COMP: use 'if constexpr' for FlatOutput

DOC: more description for Field
2025-09-23 12:53:30 +02:00
d4019e497d ENH: add/subtract/multiply: validate minimum field count requirement 2025-09-20 18:51:53 +01:00
8be698528a ENH: comfort: improve object performance and readability
- Cache wall patch metadata to avoid repeated computation
- Pre-calculate static dimensioned scalars
- Fix minor typos and enhance code readability
- Improve convergence checking with explicit loop vs max reduction
2025-09-19 20:14:21 +01:00
2d522e921f BUG: FriedrichModel: correct relative-speed calculation (fixes #3436) 2025-09-19 10:55:05 +01:00
f7fd9f8186 ENH: FA film models - added zonal Cf specification for Darcy model
Co-authored-by: Kutalmis Bercin <kutalmis.bercin@esi-group.com>
2025-09-12 14:36:25 +01:00
1e715d3847 STYLE: coneNozzleInjection: use Umag instead of UMag for consistency (fixes #1168) 2025-09-11 09:35:02 +01:00
f4b50daa3c TUT: excess files 2025-09-10 16:38:20 +01:00
6d2a6a5ef9 GIT: MacOS: filter extraneous files 2025-09-10 09:44:05 +01:00
d6e75fb289 TUT: column: use MPPICDyMFoam instead of MPPICFoam 2025-09-08 17:23:21 +01:00
63ef1f20e8 COMP: git: support for Darwin builds 2025-09-08 15:25:41 +01:00
b9d8f99bc2 ENH: tutorials: demoing mesh alignment before shm. Fixes #3409 2025-09-08 13:33:39 +01:00
ec2b71f324 BUG: Lee: fix the sign for the solid-to-liquid mass transfer model (fixes #3429) 2025-09-08 13:21:32 +01:00
52f2c42e54 BUG: InjectionModelList: avoid an FPE instance while using spray cloud (fixes #3413) 2025-09-08 11:19:51 +01:00
aee63e7418 TUT: airfoil2D: improve convergence (fixes #3159) 2025-09-06 21:48:20 +01:00
a26f7c243a BUG: ensure check file not written if 'none' option is set 2025-09-04 09:23:33 +01:00
88ff32b713 ENH: MSwindows implementation for memInfo (#3396)
- based on code provided by Daniel Jasinski
2025-09-01 09:34:48 +02:00
4c13fd8658 ENH: provide extended fileOperation::detectProcessorPath()
- returns collated grouping as an output parameter
2025-09-01 09:34:48 +02:00
bd57627955 ENH: extend bitSet functionality
- num_blocks(), test_set() as per boost
- broadcast(), reduceAnd(), reduceOr() to simplify parallel operations
- matrix-like output for PackedList::writeList()

BUG: Pstream::broadcastList() missing resize on sub-ranks

- latent bug since it was unused in any OpenFOAM code
2025-09-01 09:34:48 +02:00
19caabbd56 CONFIG: add stub for config.sh/readline (#3427)
- add homebrew support for readline in foamConfigurePaths
2025-08-28 17:01:25 +02:00
d8250512f6 Merge branch 'feature-inplace-patchFields' into 'develop'
Extend patchFields to support non-allocating members

See merge request Development/openfoam!753
2025-08-28 14:34:41 +00:00
7fa861f09b ENH: extend faPatchField, fvPatchField to support non-allocating snGrad()
Co-authored-by: <Mark.Olesen@keysight.com>
2025-08-28 14:18:25 +00:00
202b448b8f ENH: enforce snGradTransformDiag() as zero for rotational-invariant
- the snGradTransformDiag() is used in this type of code:

  ```
  if constexpr (!is_rotational_vectorspace_v<Type>)
  {
      // Rotational-invariant type
      return tmp<Field<Type>>::New(this->size(), pTraits<Type>::one);
  }
  else
  {
      return pTraits<Type>::one - snGradTransformDiag();
  }
  ```

  This implies that a rotational-invariant form should return 0
  and not 1 like the pow(..., 0) does.
  This is a backstop for any code that may inadvertently hit it,
  but also allows the possibility of having integer indicator fields
  without upsetting the compiler.

STYLE: doTransform() logic now uses is_rotational_vectorspace
2025-08-28 14:18:25 +00:00
4cc8423c94 ENH: support zeroValue boundary condition
- a special case of fixedValue with a value of zero:
    * non-assignable
    * no mapping needed
    * value internal coeffs are zero
    * value boundary coeffs are zero
2025-08-28 14:18:25 +00:00
f96c5fafb0 Merge branch 'improve-IOobject_PtrList_CompactIOList_List' into 'develop'
general list cleanups

See merge request Development/openfoam!754
2025-08-28 08:44:32 +00:00
376674d568 STYLE: remove redundant template parameter for CompactIOField, CompactIOList
- the packed content type can be determined directly from
  List<T>::value_type without need for an additional template parameter.
2025-08-27 12:12:19 +02:00
b2135600a8 ENH: add readContents to CompactIOList, CompactIOField
- align some of the internal handling with each other and with
  CompactListList

ENH: add readContentsSize to IOList, IOField etc.

- sometimes just need to know how many elements are stored on disk
  without actually caring about the content. In those cases, can
  frequently just get that information from the first label token
  without needing to read anything else.
2025-08-27 12:12:19 +02:00
697b8a1436 ENH: improved handling of PtrList copies/cloning
- the logic has been revised to allow list copying with nullptr entries.
  These previously would have thrown an error.

- remove PtrList trimTrailingNull() method.
  It was unused and would result in inconsistent addressing sizes.

FIX: inconsistent sizing used for DynamicList/PtrDynList clearStorage()

- older code did not reset addressable size prior to clearStorage()
  or transfer(). Only a latent bug until memory pools are used.
2025-08-27 12:12:19 +02:00
a85b0f0736 STYLE: replace UList<char> specializations with 'if constexpr' handling 2025-08-27 11:59:36 +02:00
3ad17ddf5e ENH: extend UList<bool> specializations to include any(), all(), none()
- simplifies code with boolList vs. bitSet
2025-08-27 11:59:36 +02:00
2446f3f0c7 ENH: handle 'void' type in IOobject::typeHeaderOk
- can be used in most places where checkType=false is used

ENH: add non-const get() method to HashPtrTable

- allows checking and modification (symmetric with PtrList methods)

STYLE: improve annotations in fileOperations headers
2025-08-27 11:59:36 +02:00
f3c97d41bd ENH: support wmake -all=FILE option
- allows specialized versions of ./Allwmake in the local directory
2025-08-21 20:36:20 +02:00
8aa69ad976 BUG: shm: filter out duplicates. Fixes #3333
Problem was duplicates in list of patches to
add buffer layers to
2025-08-21 17:42:35 +01:00
9c13057b80 ENH: createPatch: do not remove added patches. Fixes #2726 2025-08-20 15:13:48 +01:00
8357b7e28b CONFIG: handle mpirunDebug stdin redirection before execution (#3389)
- previously handled stdin redirection as part of the run command but
  (as Alexey Matveichev noted) this meant the command would actually
  require an `eval` for this to work. Instead redirect before executing
  the run command.

- can always use 'echo -e' (bash builtin) in mpirunDebug

CONFIG: add removal of mpirun.files/ to CleanFunctions

- leave mpirun.log/ files untouched, since they may still be useful
  for later diagnosis
2025-08-19 15:34:27 +02:00
828693bc90 ENH: explicitly handle empty name lookup (objectRegistry, IOobjectList)
- provides some additional safety and precludes any recursive searching

ENH: support local directory handling in regionProperties

- allows alternative locations. Eg, for finite-area (#3419)
2025-08-19 14:42:01 +02:00
1f5eb55eeb Merge branch 'remove-mixed-precision-particle-streaming_issue3412' into 'develop'
DEFEATURE: remove mixed precision support for streaming particles (#3412)

See merge request Development/openfoam!752
2025-08-19 10:56:45 +00:00
3a78203863 DEFEATURE: remove mixed precision support for streaming particles (#3412)
- since direct streaming of particles is only ever used internally and
  never for disk I/O (which is collated by property), mixed precision
  will never occur when constructing a particle from a stream.

  Due to padding issues, the previous code would have been faulty anyhow.
  Thus remove that code and replace with a simple sanity check.
2025-08-19 10:56:23 +00:00
14b68a7f05 ENH: createPatch: late adding patchfields. Fixes #3410
Thanks to Alexey Matveichev
2025-08-18 13:38:43 +01:00
45f34f558b BUG: snappyHexMesh: parallel consistency. Fixes #2320
non-adapt patches using zero values were only seen if on
same processor
2025-08-17 08:58:41 +01:00
f000a8e43d BUG: missed removal of pointMesh/boundaryProcAddressing (fixes #3412) 2025-08-14 10:56:18 +02:00
24b79d3469 ENH: surfaceHookUp: add maximum-iteration option (fixes #3401) 2025-08-13 16:43:53 +01:00
821cdf6681 ENH: energyTransport: transfer write control from controlDict to function object (#3303) 2025-08-13 16:30:51 +01:00
eaf17337aa ENH: support prefix and log-dir for RunFunctions (#3386)
- these new options permit alternative naming conventions.
  For example,

      runApplication -prefix 0001_ -suffix log blockMesh

      -> 0001_blockMesh.log
2025-08-13 12:39:42 +02:00
1642841868 ENH: allow modifiable access to IOobject local(), as per instance()
ENH: simplify code by using fieldTypes::is_xxx() tests
2025-08-13 11:57:15 +02:00
891ac808de FIX: robuster blockMesh, face::centre with SP mode (#3411)
- appears to hit single precision overflow with clang-15 in
  face::center(), cellModel::center() and blockMesh createPoints().

  The blockMesh might be particularly sensitive, since the points are
  frequently defined in millimeters (scaled later), which results
  in large intermediate summations.

  Similar to primitiveMesh checks, use double precision for these
  calculations.

ENH: support vector += and -= from compatible types

- eg, doubleVector += floatVector is now supported.
  This streamlines some coding for mixed precision.

- To avoid lots of boilerplate, do not yet attempt to support general
  operations such as `operator+(doubleVector, floatVector)`
  until they become necessary.
2025-08-12 09:24:47 +02:00
fe7006acd7 ENH: support mixed-precision reading for pointConstraintList (#3405)
- since pointConstraint is a tuple of (label, vector) not simply use
  readRawLabel, readRawScalar since the tuple will also include
  trailing padding and/or padding between its members

FIX: remove flawed handling of non-native precision for directionInfo

- packing of (label, vector) makes handling of non-native content
  non-trivial (#3412). Content is only streamed, not written to disk,
  so replace with a fatalCheck.
2025-08-12 09:24:47 +02:00
0483e4826a ENH: cleaner coding for low-level readRawLabel, readRawScalar (#1378)
- local templates and 'if constexpr' to simplify logic and reduce
  reliance on pre-processor defines.

FIX: readScalarOrDefault used scalarToken() not number() token

- will rarely (or never) be triggered, but was inconsistent
2025-08-12 09:24:46 +02:00
6a72b0e607 DEFEATURE: remove OStringStream::count() method (issue #3281)
- as seen in #3201, using count() based on the ostringstream tellp
  is not reliable since it is not updated with reset or copying.

STYLE: minor changes to string/char/span streams

- update docs to only mention string_view
- use auto return, without extra trailing 'decltype'

ENH: add IOstream size check helper methods

  * checkNativeSizes() : test only
  * fatalCheckNativeSizes() : an assert with FatalIOError
2025-08-12 09:24:46 +02:00
fcc8e62e47 ENH: add cfindPatch() method to boundary meshes
- find patch by name and return pointer to it. Similar to cfindZone()

ENH: robuster PatchFunction1 handling for uniformFixedValuePointPatchField

COMP: use 'if constexpr' with is_contiguous check

STYLE: consistent patch slicing parameters

- slice UList values, not List values
2025-08-12 09:24:46 +02:00
631b6e5111 ENH: add convenience fieldTypes tests for volume/area etc fields 2025-08-12 09:24:46 +02:00
83107a192c COMP: add forward declaration for UPstream::File
BUG: typo in UPstream::Window::put() code
2025-08-12 09:24:46 +02:00
233da9adaa TUT: bubbleColumnIATE: correct Crc-coefficient value (fixes #3362) 2025-08-11 21:32:49 +01:00
954a54ea73 BUG: heatTransferCoeff: correct the radiation-contribution sign (fixes #3325) 2025-08-08 15:35:00 +01:00
9cbf544ecd ENH: AMIInterpolation: make matching more robust 2025-08-06 11:11:37 +01:00
1bcad518c6 ENH: pointConstraint: work in binary mode 2025-07-31 14:53:21 +01:00
a32493778a ENH: surfaceSlip: allow use on stand-alone pointPatches. Fixes #3404 2025-07-31 11:39:06 +01:00
e4c1a252c6 Merge branch 'GeometricField-tweaks' into 'develop'
preliminary infrastructure for sliced/unified fields

See merge request Development/openfoam!751
2025-07-30 12:13:50 +01:00
c108153d06 ENH: DimensionedField/GeometricField provision for additional storage
- base DimensionedField on DynamicField instead of Field to allow
  convenient resizing

- initial infrastructure for unified GeometricField handling with
  the boundaryEvaluate() method

Co-authored-by: <Mark.Olesen@keysight.com>
2025-07-30 09:43:57 +02:00
53af711c6a ENH: simplify assign zero for Dimensioned and Geometric fields (#3402)
- regular or forced assignment from `zero` does not need dimension
  checking:

    Old:  U = dimensionedVector(U.dimensions(), Zero);
    New:  U = Zero;

  this eliminates a fair bit of clutter and simplifies new coding
  without losing general dimension checking capabilities.
2025-07-30 09:29:53 +02:00
a68ed1371f FIX: incorrect DynamicList resizing logic (memory pool)
- reserve() did not set the addressable size to the current capacity
  before resizing, which meant that the delete[] would not have the
  true allocated size. Only affects memory-pool usage (#3381), which
  is not yet integrated

ENH: remove unused DynamicList '*_unsafe()' methods

- can result in a mismatch between allocated and addressed sizes,
  which becomes important for memory-pool usage.
2025-07-28 14:58:08 +02:00
6ac50a3307 ENH: Added onStart option to timeControl for function object control
Triggers function object to execute on the first time step.

Example usage:

    minMax1
    {
        type            fieldMinMax;
        libs            (fieldFunctionObjects);
        writeControl    onStart;
        fields          (".*");
    }

Ref: EP2608
2025-07-24 15:09:58 +01:00
0a421c99ab ENH: checkMesh -writeChecks : support multi-region - see EP10:599 2025-07-24 15:09:58 +01:00
20e04a88f7 BUG: cylinderToCell: avoid large-number subtraction (fixes #3378) 2025-07-23 14:17:57 +01:00
9629ae8aa9 ENH: mapDistribute: add separate input and output
To avoid making initial copy of input to output field.
2025-07-17 09:59:46 +01:00
7a8089e076 ENH: extrudeMesh: excess code 2025-07-16 16:48:17 +01:00
4cd1912e4c BUG: AMIInterpolation: keep old geomComm. See #3372
Correcting bug introduced when trying to keep the old communicator.
We do not need local communicator if all ranks of comm have
some faces. Not all ranks of the already local communicator.
2025-07-14 14:43:50 +01:00
9eede215b0 BUG: argList: print excess. Fixes #3384 2025-07-14 14:43:50 +01:00
d37c685523 ENH: holeToFace: corrected documentation 2025-07-14 11:13:00 +01:00
bbef1bc289 ENH: report best dictionary context for failed foamDictionary search (#3379) 2025-07-03 14:35:54 +01:00
1147 changed files with 28162 additions and 13218 deletions

3
.gitignore vendored
View File

@ -11,6 +11,7 @@
# File-browser settings - anywhere
.directory
.DS_Store # OSX app store
# Backup/recovery versions - anywhere
.#*
@ -38,6 +39,8 @@ linux*Gcc*/
linux*Icc*/
solaris*Gcc*/
SunOS*Gcc*/
darwin*Clang*/
darwin*Gcc*/
platforms/
# Top-level build directories

View File

@ -1,6 +1,6 @@
#!/bin/sh
cd "${0%/*}" || exit # Run from this directory
set -- -no-recursion "$@" # Parse arguments only
set -- -all="${0##*/}" "$@" # Execute this instead of ./Allwmake
# Run from OPENFOAM top-level directory only
wmake -check-dir "$WM_PROJECT_DIR" 2>/dev/null || {
@ -33,7 +33,7 @@ case "$FOAM_MODULE_PREFIX" in
;;
(*)
# Use wmake -all instead of Allwmake to allow for overrides
( cd "$WM_PROJECT_DIR/modules" 2>/dev/null && wmake -all )
( cd "$WM_PROJECT_DIR/modules" 2>/dev/null && wmake -all $* )
esac
#------------------------------------------------------------------------------

View File

@ -1,6 +1,6 @@
#!/bin/sh
cd "${0%/*}" || exit # Run from this directory
set -- -no-recursion "$@" # Parse arguments only
set -- -all="${0##*/}" "$@" # Execute this instead of ./Allwmake
# Run from OPENFOAM top-level directory only
wmake -check-dir "$WM_PROJECT_DIR" 2>/dev/null || {
@ -33,7 +33,7 @@ case "$FOAM_MODULE_PREFIX" in
;;
(*)
# Use wmake -all instead of Allwmake to allow for overrides
( cd "$WM_PROJECT_DIR/plugins" 2>/dev/null && wmake -all )
( cd "$WM_PROJECT_DIR/plugins" 2>/dev/null && wmake -all $* )
esac
#------------------------------------------------------------------------------

View File

@ -1,2 +1,2 @@
api=2506
api=2507
patch=0

View File

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

View File

@ -6,7 +6,7 @@
+ MRF.DDt(U)
+ turbulence->divDevReff(U)
==
parcels.SU(U, true)
invRhoInf*parcels.SU(U)
+ fvOptions(U)
);

View File

@ -39,6 +39,11 @@ dimensionedScalar rhoInfValue
laminarTransport
);
const dimensionedScalar invRhoInf
(
dimless/dimDensity, scalar(1)/rhoInfValue.value()
);
volScalarField rhoInf
(
IOobject

View File

@ -1086,7 +1086,7 @@ void Foam::multiphaseMixtureThermo::solveAlphas
MULES::limitSum(alphaPhiCorrs);
rhoPhi_ = dimensionedScalar(dimensionSet(1, 0, -1, 0, 0), Zero);
rhoPhi_ = Zero;
volScalarField sumAlpha
(

View File

@ -63,23 +63,11 @@ Foam::DTRMParticle::DTRMParticle
{
is >> p0_ >> p1_ >> I0_ >> I_ >> dA_ >> transmissiveId_;
}
else if (!is.checkLabelSize<>() || !is.checkScalarSize<>())
{
// Non-native label or scalar size
is.beginRawRead();
readRawScalar(is, p0_.data(), vector::nComponents);
readRawScalar(is, p1_.data(), vector::nComponents);
readRawScalar(is, &I0_);
readRawScalar(is, &I_);
readRawScalar(is, &dA_);
readRawLabel(is, &transmissiveId_);
is.endRawRead();
}
else
{
// No non-native streaming
is.fatalCheckNativeSizes(FUNCTION_NAME);
is.read(reinterpret_cast<char*>(&p0_), sizeofFields_);
}
}

View File

@ -557,7 +557,7 @@ void Foam::radiation::laserDTRM::calculate()
// Reset the field
Q_ == dimensionedScalar(Q_.dimensions(), Zero);
Q_ == Zero;
a_ = absorptionEmission_->a();
e_ = absorptionEmission_->e();

View File

@ -232,7 +232,7 @@
surfaceScalarField mSfGradp("mSfGradp", pEqnIncomp.flux()/rAUf);
phasei = 0;
phi = dimensionedScalar("phi", phi.dimensions(), Zero);
phi = Zero;
for (phaseModel& phase : fluid.phases())
{
@ -261,7 +261,7 @@
mSfGradp = pEqnIncomp.flux()/rAUf;
U = dimensionedVector("U", dimVelocity, Zero);
U = Zero;
phasei = 0;
for (phaseModel& phase : fluid.phases())

View File

@ -626,7 +626,7 @@ void Foam::multiphaseMixture::solveAlphas
MULES::limitSum(alphaPhiCorrs);
rhoPhi_ = dimensionedScalar(dimMass/dimTime, Zero);
rhoPhi_ = Zero;
volScalarField sumAlpha
(

View File

@ -14,6 +14,6 @@ if (!(runTime.timeIndex() % 5))
if (smi < -SMALL)
{
Info<< "Resetting Dcorr to 0" << endl;
Dcorr == dimensionedVector(Dcorr.dimensions(), Zero);
Dcorr == Zero;
}
}

View File

@ -1,6 +1,6 @@
#!/bin/sh
cd "${0%/*}" || exit # Run from this directory
. ${WM_PROJECT_DIR:?}/wmake/scripts/wmakeFunctions # Require wmake functions
cd "${0%/*}" || exit # Run from this directory
. "${WM_PROJECT_DIR:?}"/wmake/scripts/wmakeFunctions # Need wmake functions
#------------------------------------------------------------------------------

View File

@ -1,8 +1,9 @@
#!/bin/sh
cd "${0%/*}" || exit # Run from this directory
set -- -no-recursion "$@" # Parse arguments only
. ${WM_PROJECT_DIR:?}/wmake/scripts/AllwmakeParseArguments
. ${WM_PROJECT_DIR:?}/wmake/scripts/wmakeFunctions # Require wmake functions
set -- -all="${0##*/}" "$@" # Execute this instead of ./Allwmake
. "${WM_PROJECT_DIR:?}"/wmake/scripts/AllwmakeParseArguments
. "${WM_PROJECT_DIR:?}"/wmake/scripts/wmakeFunctions # Need wmake functions
#------------------------------------------------------------------------------
# Environment

View File

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

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2020-2022 OpenCFD Ltd.
Copyright (C) 2020-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -25,7 +25,7 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application
testCompactIOList
Test-CompactIOList
Description
Simple demonstration and test application for the CompactIOList container
@ -46,13 +46,20 @@ using namespace Foam;
int main(int argc, char *argv[])
{
argList::addBoolOption("ascii", "use ascii format");
argList::addOption("count", "number of faces");
#include "setRootCase.H"
#include "createTime.H"
IOstreamOption streamOpt(IOstreamOption::BINARY);
// IOstreamOption streamOpt(IOstreamOption::ASCII);
const label size = 20000000;
if (args.found("ascii"))
{
streamOpt.format(IOstreamOption::ASCII);
}
const label size = args.getOrDefault<label>("count", 20000000);
// Old format
// ~~~~~~~~~~
@ -63,39 +70,50 @@ int main(int argc, char *argv[])
(
IOobject
(
"faces2",
"faces2-plain",
runTime.constant(),
polyMesh::meshSubDir,
runTime,
IOobject::NO_READ,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
),
size
)
);
const face f(identity(4));
faces2.resize(size, face(identity(4)));
forAll(faces2, i)
{
faces2[i] = f;
}
Info<< "Constructed faceList in = "
<< runTime.cpuTimeIncrement() << " s" << nl << endl;
Info<< "Plain format faceList " << faces2.objectRelPath() << nl;
Info<< " constructed in = " << runTime.cpuTimeIncrement()
<< " s" << endl;
faces2.writeObject(streamOpt, true);
Info<< "Written old format faceList in = "
<< runTime.cpuTimeIncrement() << " s" << nl << endl;
Info<< " wrote in = "
<< runTime.cpuTimeIncrement() << " s" << endl;
// Read
faceIOList faces3
// Read (size only)
label count = faceIOList::readContentsSize
(
IOobject
(
"faces2",
"faces2-plain",
runTime.constant(),
polyMesh::meshSubDir,
runTime,
IOobject::MUST_READ
)
);
Info<< " counted " << count << " faces on disk in = "
<< runTime.cpuTimeIncrement() << " s" << endl;
// Read
faceIOList faces2b
(
IOobject
(
"faces2-plain",
runTime.constant(),
polyMesh::meshSubDir,
runTime,
@ -105,7 +123,7 @@ int main(int argc, char *argv[])
)
);
Info<< "Read old format " << faces3.size() << " faceList in = "
Info<< " read " << faces2b.size() << " faces in = "
<< runTime.cpuTimeIncrement() << " s" << nl << endl;
}
@ -114,44 +132,54 @@ int main(int argc, char *argv[])
// ~~~~~~~~~~
{
// Construct big faceList in new format
// Construct big faceList in compact format
faceCompactIOList faces2
(
IOobject
(
"faces2",
"faces2-compact",
runTime.constant(),
polyMesh::meshSubDir,
runTime,
IOobject::NO_READ,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
),
size
)
);
const face f(identity(4));
faces2.resize(size, face(identity(4)));
forAll(faces2, i)
{
faces2[i] = f;
}
Info<< "Constructed new format faceList in = "
<< runTime.cpuTimeIncrement() << " s" << nl << endl;
Info<< "Compact format faceList" << faces2.objectRelPath() << nl;
Info<< " constructed in = "
<< runTime.cpuTimeIncrement() << " s" << endl;
faces2.writeObject(streamOpt, true);
Info<< "Written new format faceList in = "
<< runTime.cpuTimeIncrement() << " s" << nl << endl;
Info<< " wrote in = "
<< runTime.cpuTimeIncrement() << " s" << endl;
// Read
faceCompactIOList faces3
// Read (size only)
label count = faceCompactIOList::readContentsSize
(
IOobject
(
"faces2",
"faces2-compact",
runTime.constant(),
polyMesh::meshSubDir,
runTime,
IOobject::MUST_READ
)
);
Info<< " counted " << count << " faces on disk in = "
<< runTime.cpuTimeIncrement() << " s" << endl;
// Read
faceCompactIOList faces2b
(
IOobject
(
"faces2-compact",
runTime.constant(),
polyMesh::meshSubDir,
runTime,
@ -161,7 +189,7 @@ int main(int argc, char *argv[])
)
);
Info<< "Read new format " << faces3.size() << " faceList in = "
Info<< " read " << faces2b.size() << " faces in = "
<< runTime.cpuTimeIncrement() << " s" << nl << endl;
}

View File

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

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2017-2022 OpenCFD Ltd.
Copyright (C) 2017-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -42,33 +42,55 @@ Description
using namespace Foam;
class Scalar
bool verbosity = true;
// Gratuitous class inheritance
template<class T>
class BoxedType
{
scalar data_;
T data_;
public:
static bool verbose;
constexpr Scalar() noexcept : data_(0) {}
Scalar(scalar val) noexcept : data_(val) {}
constexpr BoxedType() noexcept : data_(0) {}
BoxedType(T val) noexcept : data_(val) {}
~BoxedType()
{
if (verbosity) Info<< " [delete BoxedType: " << value() << ']' << nl;
}
T value() const noexcept { return data_; }
T& value() noexcept { return data_; }
auto clone() const { return autoPtr<BoxedType<T>>::New(*this); }
};
template<class T> Ostream& operator<<(Ostream& os, const BoxedType<T>& item)
{
return (os << " -> " << item.value());
}
class Scalar : public BoxedType<scalar>
{
public:
using BoxedType<scalar>::BoxedType;
~Scalar()
{
if (verbose) Info<< "delete Scalar: " << data_ << endl;
}
const scalar& value() const noexcept { return data_; }
scalar& value() noexcept { return data_; }
friend Ostream& operator<<(Ostream& os, const Scalar& item)
{
os << item.value();
return os;
if (verbosity) Info<< "delete Scalar: " << value() << nl;
}
auto clone() const { return autoPtr<Scalar>::New(*this); }
};
bool Scalar::verbose = true;
Ostream& operator<<(Ostream& os, const Scalar& item)
{
return (os << item.value());
}
template<class T>

View File

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

View File

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

View File

@ -89,12 +89,6 @@ Ostream& printView(Ostream& os, std::string_view s)
}
Ostream& printView(Ostream& os, stdFoam::span<char> s)
{
return printView(os, s.begin(), s.end());
}
Ostream& printView(Ostream& os, const UList<char>& list)
{
return printView(os, list.begin(), list.end());

View File

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

View File

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

View File

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

View File

@ -106,7 +106,7 @@ void printMyString(const UList<string>& lst)
{
MyStrings slist2(lst);
Info<<slist2 << nl;
Info<< slist2 << nl;
}
@ -204,16 +204,6 @@ int main(int argc, char *argv[])
Info<<" " << *iter;
}
Info<< nl;
Info<< "data:" << Foam::name(ident.cdata())
<< " size:" << ident.size() << nl;
Info<< "resize_unsafe(10)" << nl;
ident.resize_unsafe(10);
Info<< "data:" << Foam::name(ident.cdata())
<< " size:" << ident.size() << nl;
}
if (false)
@ -370,7 +360,7 @@ int main(int argc, char *argv[])
auto shrtList = ListOps::create<short>
(
longLabelList,
[](const label& val){ return val; }
[](label val){ return val; }
);
printListOutputType<short>("short") << nl;
@ -567,7 +557,7 @@ int main(int argc, char *argv[])
auto scalars = ListOps::create<scalar>
(
labels,
[](const label& val){ return scalar(1.5*val); }
[](label val){ return scalar(1.5*val); }
);
Info<< "scalars: " << flatOutput(scalars) << endl;
}
@ -576,7 +566,7 @@ int main(int argc, char *argv[])
auto vectors = ListOps::create<vector>
(
labels,
[](const label& val){ return vector(1.2*val, -1.2*val, 0); }
[](label val){ return vector(1.2*val, -1.2*val, 0); }
);
Info<< "vectors: " << flatOutput(vectors) << endl;
}
@ -585,7 +575,7 @@ int main(int argc, char *argv[])
auto longs = ListOps::create<long>
(
labels,
[](const label& val){ return val; }
[](label val){ return val; }
);
Info<< "longs: " << flatOutput(longs) << endl;
}
@ -603,7 +593,7 @@ int main(int argc, char *argv[])
(
labelRange().cbegin(),
labelRange(15).cend(),
[](const label& val){ return scalar(-1.125*val); }
[](label val){ return scalar(-1.125*val); }
);
Info<< "scalars: " << flatOutput(scalars) << endl;
}

View File

@ -89,12 +89,6 @@ Ostream& printView(Ostream& os, std::string_view s)
}
Ostream& printView(Ostream& os, stdFoam::span<char> s)
{
return printView(os, s.begin(), s.end());
}
Ostream& printView(Ostream& os, const UList<char>& list)
{
return printView(os, list.begin(), list.end());
@ -189,12 +183,25 @@ int main(int argc, char *argv[])
printInfo(obuf);
// Overwrite at some position
obuf.stdStream().rdbuf()->pubseekpos(0.60 * obuf.size());
obuf << "<" << nl << "OVERWRITE" << nl;
if (auto i = obuf.view().find("item5"); i != std::string::npos)
{
// obuf.seek(0.60 * obuf.size());
obuf.seek(i);
obuf << "<OVERWRITE>" << nl;
}
Info<<"after overwrite" << nl;
printInfo(obuf);
// Truncate
{
constexpr float fraction = 0.90;
Info<<"truncated at " << (100*fraction) << "% ["
<< int(fraction*obuf.size()) << " chars]" << nl;
obuf.seek(fraction*obuf.size());
printInfo(obuf);
}
Info<< "transfer contents to a List or ICharStream" << nl;
// Reclaim data storage from OCharStream -> ICharStream

View File

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

View File

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

View File

@ -0,0 +1,473 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
Description
\*---------------------------------------------------------------------------*/
#include "SpanStream.H"
#include "wordList.H"
#include "IOstreams.H"
#include "argList.H"
#include <charconv>
#include <cctype>
#include <cstdio>
#include <limits>
#include <iomanip>
using namespace Foam;
Ostream& printString(Ostream& os, const char* first, const char* last)
{
os << '"';
for (; first != last; (void)++first)
{
os << *first;
}
os << '"';
return os;
}
Ostream& printView(Ostream& os, const char* first, const char* last)
{
char buf[4];
os << label(last-first) << '(';
for (; first != last; (void)++first)
{
const char c = *first;
if (isprint(c))
{
os << c;
}
else if (c == '\t')
{
os << "\\t";
}
else if (c == '\n')
{
os << "\\n";
}
else
{
::snprintf(buf, 4, "%02X", c);
os << "\\x" << buf;
}
}
os << ')';
return os;
}
Ostream& printView(Ostream& os, std::string_view s)
{
return printView(os, s.begin(), s.end());
}
Ostream& printView(Ostream& os, const UList<char>& list)
{
return printView(os, list.begin(), list.end());
}
Ostream& writeList(Ostream& os, const UList<char>& list)
{
return printView(os, list);
}
Ostream& toString(Ostream& os, const UList<char>& list)
{
return printString(os, list.begin(), list.end());
}
Ostream& toString(Ostream& os, std::string_view s)
{
return printString(os, s.begin(), s.end());
}
template<class BufType>
void printInfo(const BufType& buf)
{
Info<< nl << "=========================" << endl;
buf.print(Info);
Info<< "addr: " << Foam::name(buf.view().data()) << nl;
toString(Info, buf.view());
Info<< nl << "=========================" << endl;
}
// Return a left-padded integer as "word"
template<class IntType>
std::string leftpadded(IntType val, char fillch = ' ')
{
std::string buf;
buf.resize((std::numeric_limits<IntType>::digits10+1), fillch);
auto first = (buf.data());
auto last = (buf.data() + buf.size());
auto result = std::to_chars(first, last, val);
if (result.ec == std::errc{})
{
auto* iter = result.ptr;
int count = std::distance(iter, last);
std::cout << "did not fill: " << count << " chars\n";
// With two spaces before comments
if (count > 0) { *iter++ = ' '; --count; }
if (count > 0) { *iter++ = ' '; --count; }
for (char c = (count >= 2 ? '/' : ' '); count > 0; --count)
{
*iter++ = c;
}
}
return buf;
}
template<class IntType>
void leftpad(std::ostream& os, IntType val, char fillch = ' ')
{
// set fill char and width
os.setf(std::ios_base::left, std::ios_base::adjustfield);
fillch = os.fill(fillch);
os.width(std::numeric_limits<IntType>::digits10+1);
os << val;
// restore fill char
os.fill(fillch);
}
template<class IntType>
void rightpad(std::ostream& os, IntType val, char fillch = ' ')
{
// set fill char and width
os.setf(std::ios_base::right, std::ios_base::adjustfield);
fillch = os.fill(fillch);
os.width(std::numeric_limits<IntType>::digits10+1);
os << val;
// restore fill char
os.fill(fillch);
}
// Left-padded value with trailing comment slashes
template<class IntType>
void leftpad(ocharstream& os, IntType val)
{
const auto beg = os.tellp();
os << val;
int count = (std::numeric_limits<IntType>::digits10+1) - (os.tellp() - beg);
// With two spaces before comments
if (count > 0) { os << ' '; --count; }
if (count > 0) { os << ' '; --count; }
for (const char c = (count >= 2 ? '/' : ' '); count > 0; --count)
{
os << c;
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
argList::noBanner();
argList::noParallel();
argList::addBoolOption("fake-zerosize", "Fake overwriting with zero data");
argList::addBoolOption("dict-format", "Format as dictionary entry");
#include "setRootCase.H"
const bool optFakeZerosize = args.found("fake-zerosize");
const bool isDictFormat = args.found("dict-format");
// const constexpr int width = (std::numeric_limits<label>::digits10+1);
// experiment with to_chars instead of streaming
{
// Some value
label val(1234);
auto fixed = leftpadded(val);
Info<< "leftpadded " << val << " : " << fixed << nl;
}
ocharstream labelbuf;
labelbuf.reserve_exact(32);
// Some value
labelbuf.rewind();
rightpad(labelbuf, label(10));
printInfo(labelbuf);
OCharStream obuf;
obuf.reserve_exact(48);
printInfo(obuf);
obuf.push_back('>');
obuf.append(" string_view ");
obuf.push_back('<');
printInfo(obuf);
obuf.pop_back(8);
printInfo(obuf);
obuf.pop_back(100);
printInfo(obuf);
// Fill with some content
for (int i = 0; i < 26; ++i)
{
obuf<< char('A' + i);
}
// Change letter 'O' to '_'
if (auto i = obuf.view().find('O'); i != std::string::npos)
{
obuf.overwrite(i, '_');
}
// append and push_back some content
obuf.append(5, '<');
obuf.push_back('#');
obuf.append(5, '>');
printInfo(obuf);
obuf.pop_back(8);
printInfo(obuf);
// Slightly silly test
{
const auto list = obuf.list();
Info<< "list content:" << list << nl;
Info<< "view content:" << nl << list.view() << nl;
}
obuf.overwrite(4, labelbuf.view());
printInfo(obuf);
obuf.overwrite(20, "####");
printInfo(obuf);
Info<< "operation Ignored..." << nl;
obuf.overwrite(45, "????");
printInfo(obuf);
// Update with new value
{
labelbuf.rewind();
rightpad(labelbuf, label(200), '.');
obuf.overwrite(4, labelbuf.view());
printInfo(obuf);
}
// With yet another value (non-fixed width)
{
labelbuf.rewind();
labelbuf << label(15);
obuf.overwrite(4, labelbuf.view());
printInfo(obuf);
}
// Slightly harder test
{
std::string chars(26, '?');
for (int i = 0; i < 26; ++i)
{
chars[i] = char('A' + i);
}
auto& os = obuf;
os.rewind();
const word procName("processor0");
// Write as primitiveEntry or commented content
// // constexpr bool isDictFormat = true;
// if constexpr (isDictFormat)
if (isDictFormat)
{
// Like writeKeyword() with compoundToken
os << nl << procName << ' ' << word("List<char>") << nl;
}
else
{
// Human-readable comments
os << nl << "// " << procName << nl;
}
// This is the code we want to have, but assume we don't know
// the size or data beforehand.
//
// if (str && len > 0)
// {
// // Special treatment for char data (binary I/O only)
// const auto oldFmt = os.format(IOstreamOption::BINARY);
//
// os << label(len) << nl;
// os.write(str, len);
// os << nl;
//
// os.format(oldFmt);
// }
// else
// {
// os << label(0) << nl;
// }
// Position before writing the label
const auto labelBegin = os.tellp();
// Replace: os << label(len) << nl;
// with a fixed-length version
{
labelbuf.rewind();
rightpad(labelbuf, 0);
os.append(labelbuf.view());
os << nl;
}
constexpr bool testUnknown = true;
label dataCount = 0;
if constexpr (testUnknown)
{
// Pretend we don't know the number of characters a priori
const auto oldFmt = os.format(IOstreamOption::BINARY);
const auto lineNumber = os.lineNumber();
// count is unknown but irrelevant for serial
os.beginRawWrite(0);
// Position before raw binary data
const auto dataBegin = os.tellp();
// Some type of output, streaming etc
os.writeRaw(chars.data(), chars.size());
// How many chars of binary data written?
dataCount = (os.tellp() - dataBegin);
os.endRawWrite();
os.lineNumber() = lineNumber;
os << nl;
os.format(oldFmt);
}
else
{
// If we had all data collected a priori
dataCount = chars.size();
const auto oldFmt = os.format(IOstreamOption::BINARY);
if (dataCount > 0)
{
os.write(chars.data(), chars.size());
os << nl;
}
os.format(oldFmt);
}
if (optFakeZerosize)
{
dataCount = 0; // fake zero-size
}
printInfo(os);
// Update the data count with the correct value
if (dataCount > 0)
{
labelbuf.rewind();
leftpad(labelbuf, label(dataCount));
os.overwrite(labelBegin, labelbuf.view());
}
else
{
os.seek(int64_t(labelBegin)-1);
// if constexpr (isDictFormat)
if (isDictFormat)
{
os << ' ' << label(0);
}
else
{
os << nl << label(0) << nl;
}
}
// if constexpr (isDictFormat)
if (isDictFormat)
{
os.endEntry();
}
printInfo(os);
Info<< "view: " << os.view(4, 8) << nl;
Info<< "view: " << os.view(32) << nl;
// Ignores out-of-range
Info<< "view: " << os.view(1000) << nl;
}
Info<< "\nEnd\n" << endl;
return 0;
}
// ************************************************************************* //

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.
@ -65,7 +65,6 @@ int main(int argc, char *argv[])
OCountStream cnt;
OCharStream cstr;
OStringStream sstr;
ocountstream plain;
generateOutput(cstr);
@ -77,7 +76,6 @@ int main(int argc, char *argv[])
Info<< "counter state: " << (cnt.stdStream().rdstate()) << nl
<< "via char-stream: " << label(cstr.view().size()) << " chars" << nl
<< "via string-stream: " << label(sstr.count()) << " chars" << nl
<< "via ocountstream: " << plain.count() << " chars" << endl;
fileName outputName;

View File

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

View File

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

View File

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

View File

@ -42,6 +42,8 @@ Description
using namespace Foam;
bool verbosity = true;
class ent
:
public Dictionary<ent>::link
@ -73,14 +75,12 @@ class Scalar
public:
static bool verbose;
constexpr Scalar() noexcept : data_(0) {}
Scalar(scalar val) noexcept : data_(val) {}
~Scalar()
{
if (verbose) Info<< "delete Scalar: " << data_ << endl;
if (verbosity) Info<< "delete Scalar: " << data_ << endl;
}
scalar value() const noexcept { return data_; }
@ -93,8 +93,6 @@ public:
}
};
bool Scalar::verbose = true;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:

View File

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

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2018-2023 OpenCFD Ltd.
Copyright (C) 2018-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -41,35 +41,85 @@ Description
using namespace Foam;
class Scalar
bool verbosity = true;
// Gratuitous class inheritance
template<class T>
class BoxedType
{
scalar data_;
T data_;
public:
static bool verbose;
constexpr Scalar() noexcept : data_(0) {}
Scalar(scalar val) noexcept : data_(val) {}
constexpr BoxedType() noexcept : data_(0) {}
BoxedType(T val) noexcept : data_(val) {}
~BoxedType()
{
if (verbosity) Info<< " [delete BoxedType: " << value() << ']' << nl;
}
T value() const noexcept { return data_; }
T& value() noexcept { return data_; }
auto clone() const { return autoPtr<BoxedType<T>>::New(*this); }
};
template<class T> Ostream& operator<<(Ostream& os, const BoxedType<T>& item)
{
return (os << " -> " << item.value());
}
class Scalar : public BoxedType<scalar>
{
public:
using BoxedType<scalar>::BoxedType;
~Scalar()
{
if (verbose) Info<< "delete Scalar: " << data_ << endl;
}
scalar value() const noexcept { return data_; }
scalar& value() noexcept { return data_; }
autoPtr<Scalar> clone() const { return autoPtr<Scalar>::New(data_); }
friend Ostream& operator<<(Ostream& os, const Scalar& item)
{
os << item.value();
return os;
if (verbosity) Info<< "delete Scalar: " << value() << nl;
}
auto clone() const { return autoPtr<Scalar>::New(*this); }
};
bool Scalar::verbose = true;
Ostream& operator<<(Ostream& os, const Scalar& item)
{
return (os << item.value());
}
class Integer : public BoxedType<label>
{
public:
using BoxedType<label>::BoxedType;
~Integer()
{
if (verbosity) Info<< "delete Integer: " << value() << nl;
}
auto clone() const { return autoPtr<Integer>::New(*this); }
};
Ostream& operator<<(Ostream& os, const Integer& item)
{
return (os << item.value());
}
//- Permit up-casting to the base class (eg, fvMesh to polyMesh).
// Usually only for holding (const) references.
// Exercise caution with the
template<class Base, class Derived>
std::enable_if_t<std::is_base_of_v<Base, Derived>, const UPtrList<Base>&>
upcast(const UPtrList<Derived>& This)
{
return *reinterpret_cast<const UPtrList<Base>*>(&This);
}
// As per
@ -86,20 +136,7 @@ Ostream& printAddr
const UPtrList<T>& list
)
{
const label len = list.size();
// Size and start delimiter
os << nl << indent << len << nl
<< indent << token::BEGIN_LIST << incrIndent << nl;
for (label i=0; i < len; ++i)
{
os << "addr=" << Foam::name(list.get(i)) << nl;
}
// End delimiter
os << decrIndent << indent << token::END_LIST << nl;
return os;
return list.printAddresses(os);
}
@ -176,11 +213,11 @@ Ostream& print
{
const label cap = list.capacity();
for (label i=len; i < cap; ++i)
for (label i = len; i < cap; ++i)
{
const T* ptr = list.get(i);
os << "unused " << name(ptr) << nl;
os << "unused " << Foam::name(ptr) << nl;
}
}
@ -264,9 +301,9 @@ int main(int argc, char *argv[])
Info<< "DLPtrList: " << llist1 << endl;
Scalar::verbose = false;
verbosity = false;
llist1.clear();
Scalar::verbose = true;
verbosity = true;
}
#endif
@ -344,6 +381,44 @@ int main(int argc, char *argv[])
}
// Test upcasting - dangerous
{
const auto& base =
*reinterpret_cast<UPtrList<BoxedType<scalar>>*>(&list1);
Info<< "list :" << list1 << nl;
Info<< "base :" << base << nl;
}
// Expect bad things to happen!!
{
const auto& base =
*reinterpret_cast<UPtrList<BoxedType<label>>*>(&list1);
Info<< "list :" << list1 << nl;
Info<< "base :" << base << nl;
}
// Test upcasting - compile safer (make as member function?)
{
// const auto& base = list1.upcast<BoxedType<scalar>>();
const auto& base = upcast<BoxedType<scalar>>(list1);
Info<< "list :" << list1 << nl;
Info<< "base :" << base << nl;
}
// Refuse to compile (good!)
#if 0
{
// const auto& base = list1.upcast<BoxedType<label>>();
const auto& base = upcast<BoxedType<label>>(list1);
Info<< "list :" << list1 << nl;
Info<< "base :" << base << nl;
}
#endif
PtrList<Scalar> list2(15);
Info<< "Emplace set " << list2.size() << " values" << nl;
forAll(list2, i)
@ -518,6 +593,7 @@ int main(int argc, char *argv[])
print(Info, dynlist1d);
Info<< "addresses:" << nl;
dynlist1d.printAddresses(Info, true);
printAddr(Info, dynlist1d);
PtrList<Scalar> list1d;

View File

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

View File

@ -39,26 +39,26 @@ Description
using namespace Foam;
bool verbosity = true;
class Scalar
{
scalar data_;
public:
static bool verbose;
constexpr Scalar() noexcept : data_(0) {}
Scalar(scalar val) noexcept : data_(val) {}
~Scalar()
{
if (verbose) Info<< "delete Scalar: " << data_ << endl;
if (verbosity) Info<< "delete Scalar: " << value() << nl;
}
const scalar& value() const noexcept { return data_; }
scalar value() const noexcept { return data_; }
scalar& value() noexcept { return data_; }
autoPtr<Scalar> clone() const { return autoPtr<Scalar>::New(data_); }
auto clone() const { return autoPtr<Scalar>::New(*this); }
friend Ostream& operator<<(Ostream& os, const Scalar& item)
{
@ -67,8 +67,6 @@ public:
}
};
bool Scalar::verbose = true;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:

View File

@ -91,12 +91,6 @@ Ostream& printView(Ostream& os, std::string_view s)
}
Ostream& printView(Ostream& os, stdFoam::span<char> s)
{
return printView(os, s.begin(), s.end());
}
Ostream& printView(Ostream& os, const UList<char>& list)
{
return printView(os, list.begin(), list.end());

View File

@ -200,7 +200,7 @@ void printTypeName()
template<class Type, bool UseTypeName = true>
void printPstreamTraits(const std::string_view name = std::string_view())
void printPstreamTraits(std::string_view name = std::string_view())
{
Info<< "========" << nl;
Info<< "type: ";
@ -299,6 +299,9 @@ void printPstreamTraits(const std::string_view name = std::string_view())
// Use element or component type (or byte-wise) for data type
using base = typename UPstream_dataType<Type>::base;
// The sizing factor is constexpr
constexpr std::streamsize count = UPstream_dataType<Type>::size(1);
Info<< " : ";
if constexpr (UseTypeName)
{
@ -311,8 +314,7 @@ void printPstreamTraits(const std::string_view name = std::string_view())
Info<< " cmpt-type=";
printDataTypeId(UPstream_dataType<Type>::datatype_id);
Info<< " count=" << UPstream_dataType<Type>::size(1);
Info<< nl;
Info<< " count=" << count << nl;
}
}
@ -362,6 +364,24 @@ void print_data_opType(BinaryOp bop, std::string_view name)
}
template<class Type>
int check_simple(std::string_view name = std::string_view())
{
// The sizing factor is constexpr
constexpr std::streamsize count = UPstream_dataType<Type>::size(1);
static_assert
(
(count == 1),
"Code does not (yet) work with aggregate types"
);
Info<< "check_simple: " << name << ": " << count << nl;
return count;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
@ -389,6 +409,8 @@ int main()
printPstreamTraits<const float>();
printPstreamTraits<floatVector>();
check_simple<floatVector>("vector<float>");
printPstreamTraits<scalar>();
printPstreamTraits<double>();
printPstreamTraits<doubleVector>();

View File

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

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016 OpenCFD Ltd.
Copyright (C) 2016-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -35,25 +35,31 @@ Description
\*---------------------------------------------------------------------------*/
#include "base64Layer.H"
#include "SpanStream.H"
#include "List.H"
#include "Pair.H"
#include <sstream>
using namespace Foam;
bool test(const Pair<string>& unit)
{
const string& input = unit.first();
const string& expected = unit.second();
const auto& input = unit.first();
const auto& expected = unit.second();
std::ostringstream os;
Foam::ocharstream os;
base64Layer b64(os);
b64.write(input.data(), input.size());
b64.close();
{
base64Layer b64(os);
b64.write(input.data(), input.size());
const string encoded = os.str();
if (b64.close())
{
// Extra information
// std::cerr<< "closed with pending data" << nl;
}
}
const auto encoded = os.view();
Info<< input << nl;
@ -78,7 +84,7 @@ bool test(std::initializer_list<Pair<string>> list)
{
bool good = true;
for (const Pair<string>& t : list)
for (const auto& t : list)
{
good = test(t) && good;
}
@ -91,7 +97,7 @@ bool test(const UList<Pair<string>>& list)
{
bool good = true;
for (const Pair<string>& t : list)
for (const auto& t : list)
{
good = test(t) && good;
}
@ -107,7 +113,7 @@ void testMixed(std::ostream& os, const UList<Pair<string>>& list)
os << "<test-mixed>" << nl;
int i=0;
for (const Pair<string>& t : list)
for (const auto& t : list)
{
const string& input = t.first();

View File

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

View File

@ -142,6 +142,9 @@ int main(int argc, char *argv[])
Info<< "got: " << bset1 << nl
<< "and: " << bset2 << nl
<< "and: " << bset3 << nl;
Info<< "==";
bset3.writeList(Info, 10) << nl; // matrix-like output
}
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2021 OpenCFD Ltd.
Copyright (C) 2018-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -75,9 +75,9 @@ inline Ostream& info(const UList<bool>& bools)
Info<< "size=" << bools.size()
<< " count=" << BitOps::count(bools)
<< " !count=" << BitOps::count(bools, false)
<< " all:" << BitOps::all(bools)
<< " any:" << BitOps::any(bools)
<< " none:" << BitOps::none(bools) << nl;
<< " all:" << bools.all()
<< " any:" << bools.any()
<< " none:" << bools.none() << nl;
return Info;
}
@ -137,11 +137,11 @@ inline bool compare
const std::string& expected
)
{
const List<unsigned int>& store = bitset.storage();
const auto& store = bitset.storage();
std::string has;
for (label blocki=0; blocki < bitset.nBlocks(); ++blocki)
for (label blocki=0; blocki < bitset.num_blocks(); ++blocki)
{
has += toString(store[blocki]);
}
@ -194,8 +194,10 @@ int main(int argc, char *argv[])
{
boolList bools = list1.values();
Info<<"===============" << nl;
Info<<"bools: " << flatOutput(bools) << nl;
Info<< "===============" << nl;
Info<< "bools: " << flatOutput(bools) << nl;
Info<< " ";
info(bools);
for (int i : { -10, 0, 8, 15, 32})
{
@ -238,17 +240,18 @@ int main(int argc, char *argv[])
}
#ifdef TEST_SFINAE
// This should fail to compile:
{
labelList labels = list1.toc();
if (labels.test(0))
{
Info<<"no" << endl;
Info<< "no" << endl;
}
List<double*> ptrs(10, nullptr);
if (ptrs.get(0))
{
Info<<"no" << endl;
Info<< "no" << endl;
}
}
#endif

View File

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

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020-2022 OpenCFD Ltd.
Copyright (C) 2020-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -71,9 +71,9 @@ inline Ostream& info(const UList<bool>& bools)
Info<< "size=" << bools.size()
<< " count=" << BitOps::count(bools)
<< " !count=" << BitOps::count(bools, false)
<< " all:" << BitOps::all(bools)
<< " any:" << BitOps::any(bools)
<< " none:" << BitOps::none(bools) << nl;
<< " all:" << bools.all()
<< " any:" << bools.any()
<< " none:" << bools.none() << nl;
return Info;
}

View File

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

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2023 OpenCFD Ltd.
Copyright (C) 2023-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -158,7 +158,8 @@ void populateCompound(token::compound& ct, const dictionary& dict)
}
break;
case token::tokenType::LABEL :
case token::tokenType::INTEGER_32 :
case token::tokenType::INTEGER_64 :
{
fillComponents(label, cmpts, 123);
}

View File

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

View File

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

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.
@ -47,8 +47,18 @@ void entryInfo(entry* e)
{
if (e)
{
Info<<"added "
<< e->keyword() << ": " << typeid(e).name() << nl;
Info<< "added "
<< e->keyword() << ": " << typeid(e).name();
if (auto* stream = e->streamPtr())
{
Info<< " tokens: "; stream->tokens().writeList(Info);
}
if (auto* dict = e->dictPtr())
{
Info<< " dictionary:";
}
Info<< nl;
}
}
@ -200,12 +210,31 @@ int main(int argc, char *argv[])
{
dictionary tmpdict;
// Add an empty entry and populate afterwards
if (entry* e = dict1.set(word::printf("entry%d", i), nullptr))
{
entry* e = dict1.add
(
word::printf("entry%d", i),
string("entry" + Foam::name(i))
);
auto& toks = e->stream();
toks.resize(2);
toks[0] = word("value" + Foam::name(i));
toks[1] = 10*i;
entryInfo(e);
}
// Add an entry from given list of tokens
{
tokenList toks(2);
toks[0] = word("value" + Foam::name(i));
toks[1] = 10*i;
Info<< "set token0: " << Foam::name(&(toks[0])) << nl;
entry* e = dict1.set(word::printf("_entry%d", i), std::move(toks));
// verify that the address is identical (ie, move semantics worked)
auto& newToks = e->stream();
Info<< "get token0: " << Foam::name(&(newToks[0])) << nl;
entryInfo(e);
}

View File

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

View File

@ -49,8 +49,7 @@ int main(int argc, char *argv[])
Info<< "mesh 0: " << mesh.sortedNames() << nl;
faMeshesRegistry& reg =
const_cast<faMeshesRegistry&>(faMeshesRegistry::New(mesh));
auto& reg = const_cast<faMeshesRegistry&>(faMeshesRegistry::New(mesh));
// faMeshesRegistry faReg = faMeshesRegistry(mesh);

View File

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

View File

@ -27,7 +27,7 @@ Application
Test-fileOperation1
Description
Test string parsing and other bits for fileOperation
Test string parsing and other bits for fileOperation
\*---------------------------------------------------------------------------*/
@ -42,7 +42,8 @@ Description
using namespace Foam;
word toString(const fileOperation::procRangeType& group)
template<class IntType>
word toString(const IntRange<IntType>& group)
{
if (group.empty())
{

View File

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

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022-2023 OpenCFD Ltd.
Copyright (C) 2022-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -203,6 +203,7 @@ int main(int argc, char *argv[])
argList::addVerboseOption();
#include "addAllRegionOptions.H"
#include "addAllFaRegionOptions.H"
argList::addBoolOption
(
@ -251,6 +252,14 @@ int main(int argc, char *argv[])
// Handle -allRegions, -regions, -region
#include "getAllRegionOptions.H"
// Handle -all-area-regions, -area-regions, -area-region
#include "getAllFaRegionOptions.H"
if (!doFiniteArea)
{
areaRegionNames.clear(); // For consistency
}
// ------------------------------------------------------------------------
#include "createNamedMeshes.H"
@ -259,8 +268,8 @@ int main(int argc, char *argv[])
/// #include "createMeshAccounting.H"
PtrList<ensightMesh> ensightMeshes(regionNames.size());
PtrList<faMesh> meshesFa(regionNames.size());
PtrList<ensightFaMesh> ensightMeshesFa(regionNames.size());
List<PtrList<faMesh>> meshesFa(regionNames.size());
List<PtrList<ensightFaMesh>> ensightMeshesFa(regionNames.size());
forAll(regionNames, regioni)
{
@ -273,21 +282,32 @@ int main(int argc, char *argv[])
);
ensightMeshes[regioni].verbose(optVerbose);
if (doFiniteArea)
if (!doFiniteArea)
{
autoPtr<faMesh> faMeshPtr(faMesh::TryNew(mesh));
continue;
}
meshesFa[regioni].resize_null(areaRegionNames.size());
ensightMeshesFa[regioni].resize_null(areaRegionNames.size());
autoPtr<faMesh> faMeshPtr(faMesh::TryNew(mesh));
forAll(areaRegionNames, areai)
{
const word& areaName = areaRegionNames[areai];
autoPtr<faMesh> faMeshPtr(faMesh::TryNew(areaName, mesh));
if (faMeshPtr)
{
meshesFa.set(regioni, std::move(faMeshPtr));
meshesFa[regioni].set(areai, std::move(faMeshPtr));
ensightMeshesFa.set
ensightMeshesFa[regioni].set
(
regioni,
new ensightFaMesh(meshesFa[regioni])
areai,
new ensightFaMesh(meshesFa[regioni][areai])
);
ensightMeshesFa[regioni].verbose(optVerbose);
ensightMeshesFa[regioni][areai].verbose(optVerbose);
}
}
}
@ -295,7 +315,7 @@ int main(int argc, char *argv[])
// ------------------------------------------------------------------------
if (Pstream::master())
if (UPstream::master())
{
Info<< "Checking " << timeDirs.size() << " time steps" << nl;
}
@ -317,17 +337,20 @@ int main(int argc, char *argv[])
auto& ensMesh = ensightMeshes[regioni];
// Finite-area (can be missing)
auto* ensFaMeshPtr = ensightMeshesFa.get(regioni);
auto& ensFaMeshes = ensightMeshesFa[regioni];
if (moving)
{
ensMesh.expire();
ensMesh.correct();
if (ensFaMeshPtr)
forAll(areaRegionNames, areai)
{
ensFaMeshPtr->expire();
ensFaMeshPtr->correct();
if (auto* ensFaMeshPtr = ensFaMeshes.get(areai))
{
ensFaMeshPtr->expire();
ensFaMeshPtr->correct();
}
}
}
@ -340,9 +363,15 @@ int main(int argc, char *argv[])
printInfo(ensMesh, optVerbose);
if (ensFaMeshPtr)
// finite-area
forAll(areaRegionNames, areai)
{
printInfo(*ensFaMeshPtr, optVerbose);
auto* ensFaMeshPtr = ensFaMeshes.get(areai);
if (ensFaMeshPtr)
{
printInfo(*ensFaMeshPtr, optVerbose);
}
}
}
}

View File

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

View File

@ -79,8 +79,11 @@ int main(int argc, char *argv[])
}
Info<< nl << "times:" << times << nl;
sort(times);
labelList order(Foam::sortedOrder(times));
Foam::sort(times);
Info<< "Sorted:" << times << nl;
Info<< "order:" << flatOutput(order) << nl;
for (const scalar val : { -0.5, 5.0, 18.0, 25.0, 450.0, 480.0 })
{
@ -105,10 +108,29 @@ int main(int argc, char *argv[])
files.emplace_back(10, "ten");
Info<< nl << "files:" << files << nl;
sort(files);
Foam::sort(files);
Info<< "Sorted:" << files << nl;
{
const auto& a = times[3];
scalar b = 10;
Info<< "compare (" << a << ") <= (" << b << ") => "
<< a.less_equal(10) << nl;
Info<< "compare (" << a << ") >= (" << b << ") => "
<< a.greater_equal(10) << nl;
}
{
const auto& a = times[3];
const auto& b = files[4];
Info<< "compare (" << a << ") <= (" << b << ") => "
<< (a <= b) << nl;
Info<< "compare (" << a << ") >= (" << b << ") => "
<< (a >= b) << nl;
}
Info<< "\nEnd\n" << endl;
return 0;

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -24,8 +25,10 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application
Test-memInfo
Description
Very basic test for memInfo values
\*---------------------------------------------------------------------------*/
@ -33,6 +36,7 @@ Description
#include "IOstreams.H"
#include "List.H"
#include "vector.H"
#include "Switch.H"
using namespace Foam;
@ -41,9 +45,13 @@ using namespace Foam;
int main(int argc, char *argv[])
{
const int n = 10000000;
constexpr int n = 10000000;
const char* const memTags = "peak/size/rss/free mem: ";
Info<< nl
<< "memInfo::supported() = " << Switch(memInfo::supported()) << nl
<< nl;
memInfo mem;
Info<< memTags << mem << endl;

View File

@ -54,9 +54,12 @@ int main(int argc, char *argv[])
"int",
"Num of cores to simulate (default: 4)"
);
argList::addBoolOption("scatter", "Use scatter arrows");
#include "setRootCase.H"
const bool optScatterGraph = args.found("scatter");
label nProcs = UPstream::nProcs(UPstream::worldComm);
DynamicList<int> fake_interNode_offsets;
@ -128,25 +131,50 @@ int main(int argc, char *argv[])
auto& os = Info.stream();
os << "// node topology graph:" << nl;
os.beginBlock("graph");
std::string arrow;
if (optScatterGraph)
{
arrow = " -> ";
os.beginBlock("digraph");
}
else
{
arrow = " -- ";
os.beginBlock("graph");
}
// Prefer left-to-right layout for large graphs
os << indent << "rankdir=LR" << nl;
os << indent << "rankdir=LR" << nl << nl;
const label numNodes = interNodeOffsets.size()-1;
// The master
os << indent
<< "0 [label=\"master\", style=filled, fillcolor=lightgray];"
<< nl << nl;
// First level are the inter-node connections
{
os << indent << 0 << " -- " << token::LBRACE;
os << indent
<< "// inter-node: " << flatOutput(interNodeOffsets) << nl;
for (label nodei = 1; nodei < numNodes; ++nodei)
os << indent
<< 0 << arrow.data() << nl;
os.beginBlock();
os << indent << "rank=same; node [shape=box];" << nl << nl;
os << indent;
for (label nodei = 0; nodei < numNodes; ++nodei)
{
os << ' ' << interNodeOffsets[nodei];
if (nodei) os << ' ';
os << "node" << nodei;
}
os << token::SPACE << token::RBRACE
<< " // inter-node: " << flatOutput(interNodeOffsets)
<< nl;
os << nl;
os.endBlock() << nl;
}
// Next level are the local-node connections
@ -155,8 +183,9 @@ int main(int argc, char *argv[])
const auto firstProc = interNodeOffsets[nodei];
const auto lastProc = interNodeOffsets[nodei+1];
os << indent << firstProc << " -- " << token::DQUOTE
<< (firstProc+1) << ".." << (lastProc-1)
os << indent << "node" << nodei << arrow.data()
<< token::DQUOTE
<< firstProc << ".." << (lastProc-1)
<< token::DQUOTE << nl;
}

View File

@ -38,6 +38,7 @@ Description
#include "SubField.H"
#include "vector.H"
#include "IOstreams.H"
#include "UPstreamWindow.H"
using namespace Foam;

View File

@ -186,9 +186,9 @@ int main()
Info<< nl << "some interesting label limits:" << nl;
std::cout<< "sizeof = " << sizeof(label) << nl;
std::cout<< "min = " << pTraits<label>::min << nl;
std::cout<< "max = " << pTraits<label>::max << nl;
std::cout<< "umax = " << pTraits<uLabel>::max << nl;
std::cout<< "min = " << pTraits<label>::min_ << nl;
std::cout<< "max = " << pTraits<label>::max_ << nl;
std::cout<< "umax = " << pTraits<uLabel>::max_ << nl;
std::cout<< "max_2 = " << pTraits<label>::max/2 << " <=> "
<< (1L << (sizeof(label)*8-2)) << nl;

View File

@ -185,9 +185,9 @@ int main(int argc, char *argv[])
}
broadcast_chunks<labelList, label>(input1);
Pstream::maxCommsSize = 33;
UPstream::maxCommsSize = 33;
args.readIfPresent("comms-size", Pstream::maxCommsSize);
args.readIfPresent("comms-size", UPstream::maxCommsSize);
broadcast_chunks<labelList, label>(input1);
@ -197,11 +197,11 @@ int main(int argc, char *argv[])
PstreamBuffers pBufs;
labelList sendData;
if (Pstream::master())
if (UPstream::master())
{
sendData = identity(500);
for (const int proci : Pstream::subProcs())
for (const int proci : UPstream::subProcs())
{
UOPstream os(proci, pBufs);
os << sendData;
@ -211,7 +211,7 @@ int main(int argc, char *argv[])
Info<< "call finishedSends()" << endl;
pBufs.finishedScatters();
if (!Pstream::master())
if (UPstream::is_subrank())
{
UIPstream is(UPstream::masterNo(), pBufs);
is >> sendData;
@ -225,11 +225,11 @@ int main(int argc, char *argv[])
labelListList recvBufs(UPstream::nProcs());
labelList recvSizes;
if (Pstream::master())
if (UPstream::master())
{
for (const int proci : Pstream::allProcs())
for (const int proci : UPstream::allProcs())
{
if (proci != Pstream::myProcNo())
if (proci != UPstream::myProcNo())
{
sendBufs[proci] = identity(500);
}
@ -253,11 +253,11 @@ int main(int argc, char *argv[])
Map<labelList> recvBufs;
Map<label> recvSizes;
if (Pstream::master())
if (UPstream::master())
{
for (const int proci : Pstream::allProcs())
for (const int proci : UPstream::allProcs())
{
if (proci != Pstream::myProcNo())
if (proci != UPstream::myProcNo())
{
sendBufs(proci) = identity(500);
}

View File

@ -110,21 +110,25 @@ int main(int argc, char *argv[])
<< " (self) reduced " << selfVal << nl;
// Identical size on all procs
bitSet procUsed(nProcs);
if ((myRank % 4) == 0)
{
procUsed.set(myRank);
bitSet localUsed(nProcs);
localUsed.set(myRank, ((myRank % 4) == 0));
Pout<< "local procUsed " << localUsed << nl;
localUsed.reduceOr(UPstream::worldComm, false);
Pout<< "reduce procUsed " << localUsed << nl;
}
// With allGather
{
bitSet procUsed
(
bitSet::allGather((myRank % 4) == 0)
);
Pout<< "allGather: " << procUsed << nl;
}
Pout<< "local procUsed " << procUsed << nl;
reduce
(
procUsed.data(),
procUsed.size_data(),
bitOrOp<unsigned int>()
);
Pout<< "reduce procUsed " << procUsed << nl;
// Identical size on all procs
// encode as 0:empty, 1:uniform, 2:nonuniform, 3:mixed
@ -147,12 +151,26 @@ int main(int argc, char *argv[])
}
Pout<< "local uniform " << uniformity << nl;
reduce
// reduce with op<..>()
#if 1
Foam::reduce
(
uniformity.data(),
uniformity.size_data(),
bitOrOp<unsigned int>()
uniformity.num_blocks(),
bitOrOp<unsigned int>(),
UPstream::msgType(), // ignored
UPstream::worldComm
);
#else
// Direct call to MPI_Allreduce
UPstream::mpiAllReduce
(
uniformity.data(),
uniformity.num_blocks(),
UPstream::opCodes::op_bit_or,
UPstream::worldComm
);
#endif
Pout<< "reduce uniform " << uniformity << nl;
}
@ -160,8 +178,8 @@ int main(int argc, char *argv[])
{
Pair<label> val
(
Pstream::myProcNo(UPstream::commWorld()),
Pstream::myProcNo(UPstream::commWorld())
UPstream::myProcNo(UPstream::commWorld()),
UPstream::myProcNo(UPstream::commWorld())
);
Pair<label> worldVal = val;

View File

@ -79,7 +79,7 @@ int main(int argc, char *argv[])
#include "setRootCase.H"
if (!Pstream::parRun())
if (!UPstream::parRun())
{
Info<< "\nWarning: not parallel - skipping further tests\n" << endl;
return 0;
@ -97,7 +97,7 @@ int main(int argc, char *argv[])
DynamicList<MPI_Request> recvRequests(10);
if (!Pstream::master())
if (UPstream::is_subrank())
{
// Send some random length to master

View File

@ -76,7 +76,7 @@ int main(int argc, char *argv[])
#include "setRootCase.H"
if (!Pstream::parRun())
if (!UPstream::parRun())
{
Info<< "\nWarning: not parallel - skipping further tests\n" << endl;
return 0;
@ -96,7 +96,7 @@ int main(int argc, char *argv[])
// Map request indices to procs
Map<label> recvFromProc(20);
if (!Pstream::master())
if (UPstream::is_subrank())
{
// Send some random length to master

View File

@ -0,0 +1,3 @@
Test-parallel-file-write1.cxx
EXE = $(FOAM_USER_APPBIN)/Test-parallel-file-write1

View File

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

View File

@ -0,0 +1,260 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2025 Mark Olesen
-------------------------------------------------------------------------------
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-parallel-file-write1
Description
Simple test of writing with MPI/IO
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "Time.H"
#include "Switch.H"
#include "UPstreamFile.H"
#include "SpanStream.H"
using namespace Foam;
template<class IntType>
void zeropadded(std::ostream& os, IntType val, char fillch = '0')
{
// set fill char and width
os.setf(std::ios_base::right, std::ios_base::adjustfield);
fillch = os.fill(fillch);
os.width(std::numeric_limits<IntType>::digits10+1);
os << val;
// restore fill char
os.fill(fillch);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
argList::noCheckProcessorDirectories();
argList::addVerboseOption();
argList::addBoolOption("master-footer", "Write footer from master");
#include "setRootCase.H"
if (!UPstream::parRun())
{
Info<< "###############" << nl
<< "Not running in parallel. Stopping now" << nl
<< "###############" << endl;
return 1;
}
const bool optMasterFooter = args.found("master-footer");
Info<< nl << "Write master-footer: " << Switch::name(optMasterFooter)
<< nl << nl;
Info<< "Create time (without controlDict)\n" << endl;
auto runTimePtr = Time::New();
auto& runTime = runTimePtr();
const auto myProc = UPstream::myProcNo();
const auto nProcs = UPstream::nProcs();
// Some content
OCharStream charset;
for (int i = 0; i < 10; ++i)
{
charset<< char('A' + i);
}
// Header/footer buffers - these can be separate or bundled into
// the first/last blocks
OCharStream header;
OCharStream footer;
// Content buffer
OCharStream os(IOstream::BINARY);
{
const auto v = charset.view();
os << nl;
os.beginBlock(word("rank" + Foam::name(myProc)));
for (int repeat = 0; repeat <= myProc; ++repeat)
{
os << indent << word("entry" + Foam::name(repeat))
<< ' ' << word("List<char>");
// os << nl;
os << ' ';
os << label(v.size());
os.write(v.data(), v.size());
// os << nl;
os.endEntry();
}
os.endBlock();
}
// Bundle the footer into the last block
if (!optMasterFooter && (myProc == nProcs-1))
{
IOobject::writeEndDivider(os);
}
// All content now exists - commit to disk
const std::string_view blockData(os.view());
const int64_t blockSize(blockData.size());
// Collect sizes
const List<int64_t> sizes
(
UPstream::allGatherValues(blockSize, UPstream::worldComm)
);
// Format header with size information
if (UPstream::master())
{
header
<< "Simple MPI/IO test with " << nProcs << " ranks" << nl << nl;
ocharstream labelbuf;
labelbuf.reserve_exact(32);
// Position before writing a label
auto labelBegin = header.tellp();
header.beginBlock("meta");
{
header << indent << word("data.start") << ' ';
labelBegin = header.tellp();
// Add the start value (placeholder)
{
labelbuf.rewind();
zeropadded(labelbuf, label(0));
header.append(labelbuf.view());
}
header.endEntry();
header << indent << word("data.sizes") << nl;
sizes.writeList(header); // flatOutput
header.endEntry();
}
header.endBlock();
header << nl;
IOobject::writeDivider(header);
// Now update with the correct size
{
labelbuf.rewind();
zeropadded(labelbuf, label(header.view().size()));
header.overwrite(labelBegin, labelbuf.view());
}
// Bundled the footer into the last block or from master?
if (optMasterFooter)
{
IOobject::writeEndDivider(footer);
}
}
// With additional header/footer
int64_t headerSize(header.view().size());
int64_t footerSize(footer.view().size());
Pstream::broadcast(headerSize);
if (optMasterFooter)
{
Pstream::broadcast(footerSize);
}
int64_t totalSize(headerSize);
for (int i = 0; i < myProc; ++i)
{
totalSize += sizes[i];
}
const int64_t blockOffset(totalSize);
for (int i = myProc; i < nProcs; ++i)
{
totalSize += sizes[i];
}
const int64_t footerOffset(totalSize);
totalSize += footerSize;
Pout<< "write size=" << label(blockSize)
<< " at=" << label(blockOffset) << " total=" << label(totalSize) << nl;
{
UPstream::File file;
bool ok = file.open_write
(
UPstream::worldComm,
runTime.globalPath()/"mpiio-test1.txt",
IOstreamOption::ATOMIC
);
if (ok)
{
Info<< "writing: " << file.name() << nl;
if (UPstream::master())
{
// A no-op for empty buffer
ok = file.write_at(0, header.view());
}
ok = file.write_at_all(blockOffset, blockData);
if (UPstream::master())
{
// A no-op for empty buffer
ok = file.write_at(footerOffset, footer.view());
}
}
file.set_size(totalSize);
file.close();
}
Info<< "\nEnd\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -52,7 +52,7 @@ int main(int argc, char *argv[])
const bool optNonBlocking = args.found("non-blocking");
if (!Pstream::parRun())
if (!UPstream::parRun())
{
Info<< "\nWarning: not parallel - skipping further tests\n" << endl;
return 0;
@ -73,7 +73,7 @@ int main(int argc, char *argv[])
DynamicList<UPstream::Request> sendRequests(10);
DynamicList<UPstream::Request> recvRequests(10);
if (!Pstream::master())
if (UPstream::is_subrank())
{
// Send some random length to master

View File

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

View File

@ -64,6 +64,10 @@ int main(int argc, char * argv[])
osha<< str;
Info<< osha.digest() << " : output << to empty" << nl;
osha.reset();
osha<< std::string_view(str);
Info<< osha.digest() << " : << string_view [ not quite right !]" << nl;
sha.clear();
sha.append(str);
shaDig = sha;

View File

@ -296,7 +296,7 @@ int main(int argc, char *argv[])
(
strings,
order,
stringOps::natural_sort::less<string>(strings)
stringOps::natural_sort::list_less(strings)
);
Info<< "natural sortedOrder: " << flatOutput(order) << endl;
}
@ -321,7 +321,7 @@ int main(int argc, char *argv[])
/// sortable = hashed.toc();
/// sortable.sort
/// (
/// stringOps::natural_sort::less<string>(sortable)
/// stringOps::natural_sort::list_less(sortable)
/// );
/// Info<< nl << "natural:" << sortable << endl;
@ -329,7 +329,7 @@ int main(int argc, char *argv[])
/// sortable = hashed.toc();
/// sortable.sort
/// (
/// stringOps::natural_sort::greater<string>(sortable)
/// stringOps::natural_sort::list_greater(sortable)
/// );
/// Info<< nl << "natural:" << sortable << endl;
}

View File

@ -42,7 +42,7 @@ using namespace Foam;
int main(int argc, char *argv[])
{
stringList strings
{
({
"hello",
"heello",
"heeello",
@ -52,7 +52,7 @@ int main(int argc, char *argv[])
"okey",
"okkey",
"okkkey",
};
});
labelList matches;
wordRes matcher1(ICharStream("( okey \"[hy]e+.*\" )")());
@ -72,12 +72,14 @@ int main(int argc, char *argv[])
}
}
Info<< "Match found using ListOps = "
<< ListOps::found(strings, regExp(".*ee.*")) << nl;
Info<< "First index = "
<< ListOps::find(strings, regExp(".*ee.*")) << nl;
{
regExp matcher(".*ee.*");
Info<< "Match found using ListOps = "
<< ListOps::found_if(strings, matcher) << nl
<< "First index = "
<< ListOps::find_if(strings, matcher) << nl;
}
Info<< endl;
matches = findMatchingStrings(matcher1, strings);

View File

@ -59,11 +59,6 @@ int main(int argc, char *argv[])
<< " type: " << typeid(cstr).name() << " len:" << len << nl;
Info<< " view: " << std::string_view(cstr) << nl;
Info<< " span: "
<< stdFoam::span<const char>(cstr, len) << nl;
Info<< " span: "
<< stdFoam::span<char>(const_cast<char*>(cstr), len) << nl;
}
}

View File

@ -1,4 +1,4 @@
mydebugSurfaceWriter.C
Test-surface-sampling.C
mydebugSurfaceWriter.cxx
Test-surface-sampling.cxx
EXE = $(FOAM_USER_APPBIN)/Test-surface-sampling

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022-2023 OpenCFD Ltd.
Copyright (C) 2022-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -83,12 +83,10 @@ template<> struct narrowType<SymmTensor<double>>
typedef SymmTensor<float> type;
};
// FIXME: Not sure why this one seems to be broken...
//
// template<> struct narrowType<Tensor<double>>
// {
// typedef Tensor<float> type;
// };
template<> struct narrowType<Tensor<double>>
{
typedef Tensor<float> type;
};
} // End namespace Foam
@ -104,12 +102,18 @@ Foam::surfaceWriters::mydebugWriter::mergeField
{
addProfiling(merge, "debugWriter::merge-field");
// This is largely identical to surfaceWriter::mergeField()
// Identical to surfaceWriter::mergeField()
// but with narrowing for communication
if (narrowTransfer_ && parallel_ && UPstream::parRun())
if constexpr (std::is_same_v<Tensor<double>, Type>)
{
// Cannot narrow tensor. Does not compile since MatrixSpace
// does not (yet) allow assigments from different Cmpt types.
}
else if (narrowTransfer_ && parallel_ && UPstream::parRun())
{
// The narrowed type
typedef typename narrowType<Type>::type narrowedType;
using narrowedType = typename narrowType<Type>::type;
// Ensure geometry is also merged
merge();
@ -130,14 +134,29 @@ Foam::surfaceWriters::mydebugWriter::mergeField
ConstPrecisionAdaptor<narrowedType, Type> input(fld);
PrecisionAdaptor<narrowedType, Type> output(allFld);
globIndex.gather
(
input.cref(), // fld,
output.ref(), // allFld,
UPstream::msgType(),
commType_,
UPstream::worldComm
);
if (gatherv_)
{
globIndex.mpiGather
(
input.cref(), // fld
output.ref(), // allFld
UPstream::worldComm,
// For fallback:
commType_,
UPstream::msgType()
);
}
else
{
globIndex.gather
(
input.cref(), // fld
output.ref(), // allFld
UPstream::msgType(),
commType_,
UPstream::worldComm
);
}
// Commit adapted content changes
input.commit();
@ -193,8 +212,19 @@ Foam::surfaceWriters::mydebugWriter::mydebugWriter
{
Info<< "Using debug surface writer ("
<< (this->isPointData() ? "point" : "face") << " data):"
<< " commsType=" << UPstream::commsTypeNames[commType_]
<< " merge=" << Switch::name(enableMerge_)
<< " commsType=";
if (UPstream::parRun())
{
if (gatherv_) Info<< "gatherv+";
Info<< UPstream::commsTypeNames[commType_];
}
else
{
Info<< "serial";
}
Info<< " merge=" << Switch::name(enableMerge_)
<< " write=" << Switch::name(enableWrite_)
<< " narrow=" << Switch::name(narrowTransfer_)
<< endl;

View File

@ -43,6 +43,29 @@ Description
using namespace Foam;
const char yesno[2] = { 'n', 'y' };
void printIntegralTest(const token& tok)
{
Info<< "Test: " << tok.info() << nl
<< " is int32 = " << yesno[tok.is_int32()]
<< ", int64 = " << yesno[tok.is_int64()]
<< ", uint32 = " << yesno[tok.is_uint32()]
<< ", uint64 = " << yesno[tok.is_uint64()]
<< nl;
}
void printFloatTest(const token& tok)
{
Info<< "Test: " << tok.info() << nl
<< " is float = " << yesno[tok.isFloat()]
<< ", double = " << yesno[tok.isDouble()]
<< ", number = " << yesno[tok.isNumber()]
<< nl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
@ -56,6 +79,23 @@ int main(int argc, char *argv[])
token tok1;
Info<< "default construct: " << tok1.info() << endl;
tok1 = label(100);
Info<< "assign label: " << tok1.info() << endl;
tok1 = int64_t(100);
Info<< "assign int64: " << tok1.info() << endl;
tok1 = int32_t(100);
Info<< "assign int32: " << tok1.info() << endl;
{
tok1.int64Token(int64_t(INT32_MIN)-1);
Info<< "set int64Token: " << tok1.info() << endl;
printIntegralTest(tok1);
printFloatTest(tok1);
}
tok1 = double(3.14159);
Info<< "assign double: " << tok1.info() << endl;

View File

@ -33,6 +33,7 @@ Description
#include "vectorField.H"
#include "boolVector.H"
#include "complexVector.H"
#include "labelVector.H"
#include "IOstreams.H"
#include "FixedList.H"
@ -164,6 +165,30 @@ void testTranscribe(Type& input)
}
// Test of adding to vectors, possible of dissimilar types
template<class Target, class Source>
void testAdding(const Target& a, const Source& b)
{
typedef typename Target::cmptType cmptType1;
typedef typename Source::cmptType cmptType2;
Info<< " "
<< pTraits<Target>::typeName << " += "
<< pTraits<Source>::typeName << " : ";
if constexpr (std::is_convertible_v<cmptType2, cmptType1>)
{
Target res(a);
res += b;
Info<< a << " += " << b << " == " << res << nl;
}
else
{
Info<< "unsupported" << nl;
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
@ -173,6 +198,37 @@ int main(int argc, char *argv[])
Info<<"normalised: " << vector::uniform(VSMALL).normalise() << nl;
Info<<"normalised: " << vector::uniform(ROOTVSMALL).normalise() << nl;
{
complexVector cvec(complex(1), complex(0), complex(0));
doubleVector dvec(1, 0, 0);
floatVector fvec(1, 0, 0);
labelVector lvec(1, 0, 0);
Info<< nl << "additions:" << nl;
testAdding(cvec, cvec);
testAdding(cvec, dvec);
testAdding(cvec, fvec);
testAdding(cvec, lvec);
testAdding(dvec, cvec);
testAdding(dvec, dvec);
testAdding(dvec, fvec);
testAdding(dvec, lvec);
testAdding(fvec, cvec);
testAdding(fvec, dvec);
testAdding(fvec, fvec);
testAdding(fvec, lvec);
testAdding(lvec, cvec);
testAdding(lvec, dvec);
testAdding(lvec, fvec);
testAdding(lvec, lvec);
Info<< nl;
}
{
vector vec1(0.5, 0.5, 0.5);
vector vec2(0.5, 0.51, -0.5);

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2017 Wikki Ltd
Copyright (C) 2021-2023 OpenCFD Ltd.
Copyright (C) 2021-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -28,7 +28,7 @@ Application
makeFaMesh
Description
Check a finiteArea mesh
Check a finite-area mesh
Original Authors
Zeljko Tukovic, FAMENA
@ -39,6 +39,7 @@ Original Authors
#include "Time.H"
#include "argList.H"
#include "faMesh.H"
#include "faMeshTools.H"
#include "polyMesh.H"
#include "areaFaMesh.H"
#include "edgeFaMesh.H"
@ -47,7 +48,7 @@ Original Authors
#include "processorFaPatch.H"
#include "foamVtkIndPatchWriter.H"
#include "foamVtkLineWriter.H"
#include "faMeshTools.H"
#include "regionProperties.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -59,7 +60,7 @@ int main(int argc, char *argv[])
{
argList::addNote
(
"Check a finiteArea mesh"
"Check a finite-area mesh"
);
argList::addBoolOption
@ -77,9 +78,15 @@ int main(int argc, char *argv[])
);
#include "addRegionOption.H"
#include "addFaRegionOption.H"
#include "addAllFaRegionOptions.H"
#include "setRootCase.H"
#include "createTime.H"
// Handle -all-area-regions, -area-regions, -area-region
#include "getAllFaRegionOptions.H"
// ------------------------------------------------------------------------
#include "createNamedPolyMesh.H"
int geometryOrder(1);
@ -91,16 +98,41 @@ int main(int argc, char *argv[])
faMesh::geometryOrder(geometryOrder);
}
#include "createNamedFaMesh.H"
Info<< "Time = " << runTime.timeName() << nl << endl;
// Mesh information (verbose)
faMeshTools::printMeshChecks(aMesh);
if (args.found("write-vtk"))
for (const word& areaName : areaRegionNames)
{
#include "faMeshWriteVTK.H"
Info<< "Create faMesh";
if (!polyMesh::regionName(areaName).empty())
{
Info<< " [" << areaName << "]";
}
Info<< " for time = " << runTime.timeName() << nl;
autoPtr<faMesh> faMeshPtr(faMesh::TryNew(areaName, mesh));
if (!faMeshPtr)
{
Info<< " ...failed to create area-mesh";
if (!polyMesh::regionName(areaName).empty())
{
Info<< " [" << areaName << "]";
}
Info<< endl;
continue;
}
else
{
Info<< endl;
}
const auto& aMesh = faMeshPtr();
// Mesh information (verbose)
faMeshTools::printMeshChecks(aMesh);
if (args.found("write-vtk"))
{
#include "faMeshWriteVTK.H"
}
}
Info<< "\nEnd\n" << endl;

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021-2023 OpenCFD Ltd.
Copyright (C) 2021-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
@ -15,6 +15,16 @@ Description
\*---------------------------------------------------------------------------*/
// The base name for output files
word vtkBaseFileName(aMesh.regionName());
if (polyMesh::regionName(vtkBaseFileName).empty())
{
vtkBaseFileName = "finiteArea";
}
Info<< nl;
Info<< "Write faMesh in vtk format:" << nl;
{
// finiteArea - faces
vtk::uindirectPatchWriter writer
@ -23,7 +33,7 @@ Description
// vtk::formatType::INLINE_ASCII,
fileName
(
aMesh.time().globalPath() / "finiteArea"
aMesh.time().globalPath() / vtkBaseFileName
)
);
@ -32,7 +42,7 @@ Description
globalIndex procAddr(aMesh.nFaces());
labelList cellIDs;
if (Pstream::master())
if (UPstream::master())
{
cellIDs.resize(procAddr.totalSize());
for (const labelRange& range : procAddr.ranges())
@ -53,8 +63,7 @@ Description
writer.beginPointData(1);
writer.write("normal", aMesh.pointAreaNormals());
Info<< nl
<< "Wrote faMesh in vtk format: " << writer.output().name() << nl;
Info<< " " << writer.output().name() << nl;
}
{
@ -66,7 +75,7 @@ Description
// vtk::formatType::INLINE_ASCII,
fileName
(
aMesh.time().globalPath() / "finiteArea-edges"
aMesh.time().globalPath() / (vtkBaseFileName + "-edges")
)
);
@ -88,8 +97,7 @@ Description
writer.beginPointData(1);
writer.write("normal", aMesh.pointAreaNormals());
Info<< nl
<< "Wrote faMesh in vtk format: " << writer.output().name() << nl;
Info<< " " << writer.output().name() << nl;
}
{
@ -108,7 +116,7 @@ Description
// vtk::formatType::INLINE_ASCII,
fileName
(
aMesh.time().globalPath() / "finiteArea-edgesCentres"
aMesh.time().globalPath() / (vtkBaseFileName + "-edgesCentres")
)
);
@ -134,8 +142,7 @@ Description
writer.write("normal", fld);
}
Info<< nl
<< "Wrote faMesh in vtk format: " << writer.output().name() << nl;
Info<< " " << writer.output().name() << nl;
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2023 OpenCFD Ltd.
Copyright (C) 2023-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
@ -15,7 +15,7 @@ Description
Input
mesh (polyMesh)
meshDefDict (system/faMeshDefintion)
meshDefDict (system/finite-area/faMeshDefinition)
\*---------------------------------------------------------------------------*/
@ -25,13 +25,16 @@ Input
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
wordRes polyPatchNames;
meshDefDict.readIfPresent("polyMeshPatches", polyPatchNames);
labelList patchIDs;
const labelList patchIDs
if
(
pbm.indices(polyPatchNames, true) // useGroups
);
wordRes select;
meshDefDict.readIfPresent("polyMeshPatches", select)
)
{
patchIDs = pbm.indices(select, true); // useGroups
}
label nFaceLabels = 0;
for (const label patchi : patchIDs)

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021-2024 OpenCFD Ltd.
Copyright (C) 2021-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
@ -13,6 +13,18 @@ License
Description
Search for the appropriate faMeshDefinition dictionary...
Expects to find a faMeshDefinition file in a location specified
by the command-line option, or one of the standard locations.
For default area region (region0):
(1) system/finite-area/faMeshDefinition
(2) system/faMeshDefinition [legacy location - v2312 and earlier]
For a named area region:
(1) system/finite-area/<area-name>/faMeshDefinition
(2) system/finite-area/faMeshDefinition.<area-name>
[symmetric with faOptions]
Required Classes
- Foam::polyMesh
- Foam::IOdictionary
@ -24,81 +36,185 @@ Required Variables
- runTime [Time]
Provided Variables
- meshDefDict [IOdictionary]
- meshDictPtr [autoPtr<IOdictionary>]
- faMeshDefinitionPtr [autoPtr<IOdictionary>]
If the dictionary cannot be found, exits with an error message or
reports a warning (dry-run mode)
\*---------------------------------------------------------------------------*/
const word dictName("faMeshDefinition");
autoPtr<IOdictionary> meshDictPtr;
autoPtr<IOdictionary> faMeshDefinitionPtr;
{
fileName dictPath;
const word& regionDir = Foam::polyMesh::regionName(regionName);
const word& areaRegionDir = Foam::polyMesh::regionName(areaRegionName);
// Exit unless dry-run?
const bool exitOnFailure = (!args.dryRun());
if (args.readIfPresent("dict", dictPath))
const word& regionDir = polyMesh::regionName(regionName);
const word& areaRegionDir = polyMesh::regionName(areaRegionName);
// Canonical location
fileName dictPath
(
runTime.system()/regionDir
/ faMesh::prefix()/areaRegionDir/dictName
);
// Dictionary specified on the command-line ...
const bool specified = args.readIfPresent("dict", dictPath);
if (specified)
{
// Dictionary specified on the command-line ...
if (isDir(dictPath))
{
dictPath /= dictName;
}
}
else if
(
// Dictionary under system/faMeshDefinition ?
// (v2312 and earlier)
areaRegionDir.empty()
&& exists
(
runTime.path()/runTime.caseSystem()
/ regionDir/faMesh::meshSubDir/dictName
)
)
{
// Dictionary present directly in system/ (v2312 and earlier)
dictPath = runTime.system()/regionDir/dictName;
}
else
{
// Use system/finite-area/ directory, with region qualifications
dictPath =
(
runTime.system()/regionDir
/ faMesh::prefix()/areaRegionDir/dictName
);
}
IOobject meshDictIO
(
dictPath,
runTime,
IOobject::MUST_READ,
IOobject::NO_WRITE,
IOobject::NO_REGISTER,
IOobjectOption::MUST_READ,
IOobjectOption::NO_WRITE,
IOobjectOption::NO_REGISTER,
true // is globalObject
);
if (!meshDictIO.typeHeaderOk<IOdictionary>(true))
refPtr<IOobject> meshDictIOPtr;
bool foundIOobject = meshDictIO.typeHeaderOk<IOdictionary>(true);
// For reporting any alternative locations
dictPath.clear();
if (!foundIOobject && !specified)
{
FatalErrorInFunction
<< meshDictIO.objectPath() << nl
<< exit(FatalError);
if (!areaRegionDir.empty())
{
// Alternative location
// - system/finite-area/faMeshDefinition.<area-name>
dictPath =
(
runTime.system()/regionDir
/ faMesh::prefix()/IOobject::groupName(dictName, areaRegionDir)
);
}
else
{
// legacy location (v2312 and earlier)
// - system/faMeshDefinition
dictPath = runTime.system()/regionDir/dictName;
}
if (!dictPath.empty())
{
auto ioptr = autoPtr<IOobject>::New
(
dictPath,
runTime,
IOobjectOption::MUST_READ,
IOobjectOption::NO_WRITE,
IOobjectOption::NO_REGISTER,
true // is globalObject
);
foundIOobject =
(
ioptr && ioptr->typeHeaderOk<IOdictionary>(true)
);
if (foundIOobject)
{
// Use if found
meshDictIOPtr = std::move(ioptr);
}
// Generally retain dictPath for error messages,
// but don't mention the really old legacy location
if (areaRegionDir.empty())
{
dictPath.clear();
}
}
}
Info<< "Creating faMesh from definition: "
<< meshDictIO.objectRelPath() << endl;
// Alternative location or regular location?
if (!meshDictIOPtr)
{
meshDictIOPtr.cref(meshDictIO);
}
const auto& io = meshDictIOPtr();
meshDictPtr = autoPtr<IOdictionary>::New(meshDictIO);
// Handle final success or failure
if (foundIOobject)
{
Info<< "----------------" << nl
<< "Using area-mesh definition";
if (!areaRegionDir.empty())
{
Info<< " [" << areaRegionName << "]";
}
Info<< nl
<< " " << io.objectRelPath() << nl << endl;
faMeshDefinitionPtr = autoPtr<IOdictionary>::New(io);
}
else
{
// Failure
if (exitOnFailure)
{
auto& err =
FatalErrorInFunction
<< "Did not find area-mesh definition";
if (!areaRegionDir.empty())
{
err<< " [" << areaRegionName << "]";
}
err << nl
<< " " << io.objectRelPath() << nl;
if (!dictPath.empty())
{
err << " " << dictPath << nl;
}
FatalError<< exit(FatalError);
}
else
{
// dry-run: warning
auto& err =
Warning << nl
<< "----------------" << nl
<< "Did not find area-mesh definition";
if (!areaRegionDir.empty())
{
err << " [" << areaRegionName << "]";
}
err << nl
<< " " << io.objectRelPath() << nl;
if (!dictPath.empty())
{
err << " " << dictPath << nl;
}
}
}
}
IOdictionary& meshDefDict = *meshDictPtr;
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2017 Wikki Ltd
Copyright (C) 2021-2023 OpenCFD Ltd.
Copyright (C) 2021-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -40,7 +40,6 @@ Original Authors
#include "Time.H"
#include "argList.H"
#include "OSspecific.H"
#include "faMesh.H"
#include "faMeshTools.H"
#include "IOdictionary.H"
@ -53,6 +52,7 @@ Original Authors
#include "PtrListOps.H"
#include "foamVtkLineWriter.H"
#include "foamVtkIndPatchWriter.H"
#include "regionProperties.H"
#include "syncTools.H"
#include "OBJstream.H"
@ -104,12 +104,14 @@ int main(int argc, char *argv[])
);
#include "addRegionOption.H"
#include "addFaRegionOption.H"
#include "addAllFaRegionOptions.H"
#include "setRootCase.H"
#include "createTime.H"
#include "createNamedPolyMesh.H"
#include "getFaRegionOption.H"
// Handle -all-area-regions, -area-regions, -area-region
#include "getAllFaRegionOptions.H"
const bool doDecompose = !args.found("no-decompose");
const bool doDecompFields = !args.found("no-fields");
@ -123,56 +125,83 @@ int main(int argc, char *argv[])
Info<< "Skip decompose of finiteArea fields" << nl;
}
// Reading faMeshDefinition dictionary
#include "findMeshDefinitionDict.H"
// ------------------------------------------------------------------------
// Inject/overwrite name for optional 'empty' patch
word patchName;
if (args.readIfPresent("empty-patch", patchName))
for (const word& areaRegionName : areaRegionNames)
{
meshDefDict.add("emptyPatch", patchName, true);
}
// Reading faMeshDefinition dictionary
#include "findMeshDefinitionDict.H"
// Preliminary checks
#include "checkPatchTopology.H"
if (!faMeshDefinitionPtr)
{
if (args.dryRun())
{
break;
}
else
{
FatalErrorInFunction
<< "Did not find area-mesh definition"<< nl
<< exit(FatalError);
}
}
Info << "Create areaMesh";
if (!Foam::polyMesh::regionName(areaRegionName).empty())
{
Foam::Info << ' ' << areaRegionName;
}
Info << " for polyMesh at time = " << runTime.timeName() << nl;
auto& meshDefDict = (*faMeshDefinitionPtr);
// Create
faMesh aMesh(areaRegionName, mesh, meshDefDict);
// Mesh information (less verbose)
faMeshTools::printMeshChecks(aMesh, 0);
// Inject/overwrite name for optional 'empty' patch
if (word name; args.readIfPresent("empty-patch", name))
{
meshDefDict.add("emptyPatch", name, true);
}
if (args.found("write-edges-obj"))
{
#include "faMeshWriteEdgesOBJ.H"
}
// Preliminary checks
#include "checkPatchTopology.H"
if (args.found("write-vtk"))
{
#include "faMeshWriteVTK.H"
}
Info<< "Create area-mesh";
if (!polyMesh::regionName(areaRegionName).empty())
{
Info<< " [" << areaRegionName << "]";
}
Info<< " with polyMesh at time = " << runTime.timeName() << nl;
if (args.dryRun())
{
Info<< "\ndry-run: not writing mesh or decomposing fields\n" << nl;
}
else
{
// More precision (for points data)
IOstream::minPrecision(10);
// Create
faMesh aMesh(areaRegionName, mesh, meshDefDict);
Info<< nl << "Write finite area mesh." << nl;
aMesh.write();
// Mesh information (less verbose)
faMeshTools::printMeshChecks(aMesh, 0);
Info<< endl;
#include "decomposeFaFields.H"
if (args.found("write-edges-obj"))
{
#include "faMeshWriteEdgesOBJ.H"
}
if (args.found("write-vtk"))
{
#include "faMeshWriteVTK.H"
}
if (args.dryRun())
{
Info<< "\ndry-run: not writing mesh or decomposing fields\n" << nl;
}
else
{
// More precision (for points data)
IOstream::minPrecision(10);
Info<< nl << "Write finite area mesh";
if (const word& name = aMesh.regionName(); !name.empty())
{
Info<< " [" << name << "]";
}
Info<< nl;
aMesh.write();
Info<< endl;
#include "decomposeFaFields.H"
}
}
Info<< "\nEnd\n" << endl;

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2023 OpenCFD Ltd.
Copyright (C) 2016-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -857,16 +857,8 @@ int main(int argc, char *argv[])
if
(
obj.isHeaderClass<volScalarField>()
|| obj.isHeaderClass<volVectorField>()
|| obj.isHeaderClass<volSphericalTensorField>()
|| obj.isHeaderClass<volTensorField>()
|| obj.isHeaderClass<volSymmTensorField>()
|| obj.isHeaderClass<surfaceScalarField>()
|| obj.isHeaderClass<surfaceVectorField>()
|| obj.isHeaderClass<surfaceSphericalTensorField>()
|| obj.isHeaderClass<surfaceSymmTensorField>()
|| obj.isHeaderClass<surfaceTensorField>()
Foam::fieldTypes::is_volume(obj.headerClassName())
|| Foam::fieldTypes::is_surface(obj.headerClassName())
)
{
objects.add(objPtr);

View File

@ -86,7 +86,7 @@ void constructVolFields(fvMesh& mesh, const vtkUnstructuredReader& reader)
);
auto& fld = tfld.ref();
fld.instance() = mesh.time().timeName();
fld.writeOpt() = IOobject::AUTO_WRITE;
fld.writeOpt(IOobject::AUTO_WRITE);
// Fill cell values
fld.internalFieldRef().field() =

View File

@ -152,7 +152,7 @@ Description
if
(
!cleanupPatches.found(patchName)
!cleanupPatches.contains(patchName)
|| returnReduceOr(oldPatches[patchi].size())
)
{
@ -188,8 +188,9 @@ Description
// Cleanup empty merged point zones
{
PtrList<pointZone>& zones = mesh.pointZones();
mesh.pointZones().clearAddressing();
auto& zmesh = mesh.pointZones();
zmesh.clearAddressing();
PtrList<pointZone>& zones = zmesh;
wordHashSet removedZones(2*zones.size());
@ -198,12 +199,11 @@ Description
{
if
(
!cleanupPointZones.found(zones[zonei].name())
!cleanupPointZones.contains(zones[zonei].name())
|| returnReduceOr(zones[zonei].size())
)
{
zones.set(nZones, zones.release(zonei));
zones[nZones].index() = nZones; // re-index
++nZones;
}
else
@ -212,6 +212,7 @@ Description
}
}
zones.resize(nZones);
zmesh.reindex();
if (removedZones.size())
{
@ -223,8 +224,9 @@ Description
// Cleanup empty merged face zones
{
PtrList<faceZone>& zones = mesh.faceZones();
mesh.faceZones().clearAddressing();
auto& zmesh = mesh.faceZones();
zmesh.clearAddressing();
PtrList<faceZone>& zones = zmesh;
wordHashSet removedZones(2*zones.size());
@ -233,12 +235,11 @@ Description
{
if
(
!cleanupFaceZones.found(zones[zonei].name())
!cleanupFaceZones.contains(zones[zonei].name())
|| returnReduceOr(zones[zonei].size())
)
{
zones.set(nZones, zones.release(zonei));
zones[nZones].index() = nZones; // re-index
++nZones;
}
else
@ -247,6 +248,7 @@ Description
}
}
zones.resize(nZones);
zmesh.reindex();
if (removedZones.size())
{

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