Compare commits

..

34 Commits

Author SHA1 Message Date
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
536 changed files with 10349 additions and 8257 deletions

View File

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

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

@ -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-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-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

@ -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

@ -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

@ -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

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2020 OpenCFD Ltd.
Copyright (C) 2017-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -30,7 +30,8 @@ Group
grpPostProcessingUtilities
Description
List regions from constant/regionProperties.
List volume regions from constant/regionProperties
or area regions from constant/finite-area/regionProperties
Usage
\b foamListRegions [OPTION]
@ -45,6 +46,9 @@ Note
#include "Time.H"
#include "regionProperties.H"
// Same as faMesh::prefix() but without additional linkage
constexpr const char* const faMeshPrefix = "finite-area";
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -53,7 +57,8 @@ int main(int argc, char *argv[])
{
argList::addNote
(
"List regions from constant/regionProperties"
"List volume regions from constant/regionProperties,\n"
"or area regions from constant/finite-area/regionProperties"
);
argList::noBanner();
@ -62,12 +67,55 @@ int main(int argc, char *argv[])
argList::noFunctionObjects(); // Never use function objects
// No profiling since there is no time loop
argList::addBoolOption
(
"finite-area",
"List constant/finite-area/regionProperties (if available)"
);
argList::addBoolOption
(
"optional",
"A missing regionProperties is not treated as an error"
);
argList::addDryRunOption
(
"Make reading optional and add verbosity"
);
argList::addVerboseOption("Additional verbosity");
// Arguments are optional (non-mandatory)
argList::noMandatoryArgs();
argList::addArgument("regionType ... regionType");
#include "setRootCase.H"
const bool dryRun = args.dryRun();
int optVerbose = args.verbose();
if (dryRun && !optVerbose)
{
++optVerbose;
}
// File is optional, not an error
const bool isOptional = args.found("optional");
// Use finite-area regions
const bool doFiniteArea = args.found("finite-area");
// The number of optional region filters to apply
const label nFilters = (args.size()-1);
IOobjectOption::readOption readOpt(IOobjectOption::MUST_READ);
if (dryRun || isOptional || doFiniteArea)
{
// The finite-area regionProperties are also considered optional
readOpt = IOobjectOption::READ_IF_PRESENT;
}
// Silent version of "createTime.H", without libraries
Time runTime
(
@ -77,30 +125,74 @@ int main(int argc, char *argv[])
false // no enableLibs
);
regionProperties rp(runTime);
regionProperties regionProps;
if (doFiniteArea)
{
regionProps = regionProperties(runTime, faMeshPrefix, readOpt);
}
else
{
regionProps = regionProperties(runTime, readOpt);
}
// Some reporting...
if (regionProps.empty())
{
if (doFiniteArea)
{
InfoErr<< "No finite-area region types" << nl;
}
else if (isOptional)
{
InfoErr<< "No region types" << nl;
}
}
else if (optVerbose)
{
InfoErr << "Have " << regionProps.size();
if (doFiniteArea)
{
InfoErr<< " finite-area";
}
InfoErr
<< " region types, "
<< regionProps.count() << " regions" << nl << nl;
}
// We now handle checking args and general sanity etc.
wordList regionTypes;
if (args.size() > 1)
DynamicList<word> regionTypes;
if (isOptional && regionProps.empty())
{
regionTypes.resize(args.size()-1);
// Nothing to do...
}
else if (nFilters > 0)
{
// Apply region filters
// No duplicates
regionTypes.reserve_exact
(
Foam::min(nFilters, regionProps.size())
);
// No duplicates, and no duplicate warnings
wordHashSet uniq;
label nTypes = 0;
for (label argi = 1; argi < args.size(); ++argi)
{
regionTypes[nTypes] = args[argi];
const word& regType = regionTypes[nTypes];
word regType(args[argi]);
if (uniq.insert(regType))
{
if (rp.found(regType))
if (regionProps.contains(regType))
{
++nTypes;
if (!regionTypes.contains(regType))
{
regionTypes.push_back(std::move(regType));
}
}
else
{
@ -108,22 +200,22 @@ int main(int argc, char *argv[])
}
}
}
regionTypes.resize(nTypes);
}
else
{
regionTypes = rp.sortedToc();
// Take all regions
regionTypes = regionProps.sortedToc();
}
for (const word& regionType : regionTypes)
{
const wordList& regionNames = rp[regionType];
for (const word& regionName : regionNames)
if (const auto iter = regionProps.cfind(regionType); iter.good())
{
Info<< regionName << nl;
for (const word& regionName : iter.val())
{
Info<< regionName << nl;
}
}
}

View File

@ -418,8 +418,14 @@ int main(int argc, char *argv[])
// Allow explicit -constant, have zero from time range
timeSelector::addOptions(true, false); // constant(true), zero(false)
// Prevent volume BCs from triggering finite-area
regionModels::allowFaModels(false);
#include "setRootCase.H"
// ------------------------------------------------------------------------
// Configuration
const bool writeCellDist = args.found("cellDist");
// Most of these are ignored for dry-run (not triggered anywhere)

View File

@ -135,9 +135,14 @@ int main(int argc, char *argv[])
"Only reconstruct new times (i.e. that do not exist already)"
);
// Prevent volume BCs from triggering finite-area
regionModels::allowFaModels(false);
#include "setRootCase.H"
#include "createTime.H"
// ------------------------------------------------------------------------
// Configuration
const bool doFields = !args.found("no-fields");
wordRes selectedFields;

View File

@ -780,11 +780,17 @@ int main(int argc, char *argv[])
#include "addAllRegionOptions.H"
// Prevent volume BCs from triggering finite-area
regionModels::allowFaModels(false);
#include "setRootCase.H"
#include "createTime.H"
printWarning();
// ------------------------------------------------------------------------
// Configuration
const bool fullMatch = args.found("fullMatch");
const bool procMatch = args.found("procMatch");
const bool writeCellDist = args.found("cellDist");

View File

@ -1,12 +1,12 @@
passivePositionParticleCloud.C
passivePositionParticleCloud.cxx
parLagrangianDistributor.C
parLagrangianDistributorFields.C
parLagrangianDistributor.cxx
parLagrangianDistributorFields.cxx
parPointFieldDistributor.C
parFaFieldDistributorCache.C
parFvFieldDistributor.C
parFvFieldDistributorFields.C
parPointFieldDistributor.cxx
parFaFieldDistributorCache.cxx
parFvFieldDistributor.cxx
parFvFieldDistributorFields.cxx
loadOrCreateMesh.C
redistributePar.C

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022 OpenCFD Ltd.
Copyright (C) 2022-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -30,7 +30,7 @@ Description
Simple container to manage read/write, redistribute finiteArea fields.
SourceFiles
parFaFieldDistributorCache.C
parFaFieldDistributorCache.cxx
\*---------------------------------------------------------------------------*/
@ -71,6 +71,20 @@ class parFaFieldDistributorCache
// Private Member Functions
//- Read distributed fields
template<class BoolListType>
void readImpl
(
const Time& baseRunTime,
const fileName& proc0CaseName,
const bool decompose, // i.e. read from undecomposed case
const BoolListType& areaMeshOnProc,
refPtr<fileOperation>& readHandler,
const fileName& areaMeshInstance,
faMesh& mesh
);
//- Redistribute and write fields of given type (file-scope use)
template<class GeoField>
static void redistributeAndWrite
@ -102,9 +116,24 @@ public:
(
const Time& baseRunTime,
const fileName& proc0CaseName,
const bool decompose, // i.e. read from undecomposed case
//! read from undecomposed case?
const bool decompose,
//! Existence of the processor-local mesh (bitset)
const bitSet& areaMeshOnProc,
refPtr<fileOperation>& readHandler,
const fileName& areaMeshInstance,
faMesh& mesh
);
const boolList& areaMeshOnProc,
//- Read distributed fields
void read
(
const Time& baseRunTime,
const fileName& proc0CaseName,
//! read from undecomposed case?
const bool decompose,
//! Existence of the processor-local mesh (bool list)
const boolUList& areaMeshOnProc,
refPtr<fileOperation>& readHandler,
const fileName& areaMeshInstance,
faMesh& mesh

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022 OpenCFD Ltd.
Copyright (C) 2022-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -55,15 +55,14 @@ void Foam::parFaFieldDistributorCache::redistributeAndWrite
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::parFaFieldDistributorCache::read
template<class BoolListType>
void Foam::parFaFieldDistributorCache::readImpl
(
const Time& baseRunTime,
const fileName& proc0CaseName,
const bool decompose, // i.e. read from undecomposed case
const boolList& areaMeshOnProc,
const BoolListType& areaMeshOnProc,
refPtr<fileOperation>& readHandler,
const fileName& areaMeshInstance,
faMesh& mesh
@ -75,14 +74,14 @@ void Foam::parFaFieldDistributorCache::read
autoPtr<faMeshSubset> subsetterPtr;
// Missing an area mesh somewhere?
if (areaMeshOnProc.found(false))
if (!areaMeshOnProc.all())
{
const bool oldParRun = UPstream::parRun(false);
const int oldCache = fileOperation::cacheLevel(0);
// A zero-sized mesh with boundaries.
// This is used to create zero-sized fields.
subsetterPtr.reset(new faMeshSubset(mesh, zero{}));
subsetterPtr.reset(new faMeshSubset(mesh, Foam::zero{}));
fileOperation::cacheLevel(oldCache);
UPstream::parRun(oldParRun); // Restore parallel state
@ -162,6 +161,60 @@ void Foam::parFaFieldDistributorCache::read
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::parFaFieldDistributorCache::read
(
const Time& baseRunTime,
const fileName& proc0CaseName,
const bool decompose, // i.e. read from undecomposed case
const bitSet& areaMeshOnProc,
refPtr<fileOperation>& readHandler,
const fileName& areaMeshInstance,
faMesh& mesh
)
{
readImpl
(
baseRunTime,
proc0CaseName,
decompose,
areaMeshOnProc,
readHandler,
areaMeshInstance,
mesh
);
}
void Foam::parFaFieldDistributorCache::read
(
const Time& baseRunTime,
const fileName& proc0CaseName,
const bool decompose, // i.e. read from undecomposed case
const boolUList& areaMeshOnProc,
refPtr<fileOperation>& readHandler,
const fileName& areaMeshInstance,
faMesh& mesh
)
{
readImpl
(
baseRunTime,
proc0CaseName,
decompose,
areaMeshOnProc,
readHandler,
areaMeshInstance,
mesh
);
}
void Foam::parFaFieldDistributorCache::redistributeAndWrite
(
const faMeshDistributor& distributor,

View File

@ -35,9 +35,9 @@ Description
baseMesh is non-zero cells on processor0 only.
SourceFiles
parFvFieldDistributor.C
parFvFieldDistributorFields.C
parFvFieldDistributorTemplates.C
parFvFieldDistributor.cxx
parFvFieldDistributor.txx
parFvFieldDistributorFields.cxx
\*---------------------------------------------------------------------------*/
@ -228,7 +228,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "parFvFieldDistributorTemplates.C"
# include "parFvFieldDistributor.txx"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -33,9 +33,9 @@ Description
Runs in parallel. Redistributes from fromMesh to toMesh.
SourceFiles
parLagrangianDistributor.C
parLagrangianDistributorFields.C
parLagrangianDistributorTemplates.C
parLagrangianDistributor.cxx
parLagrangianDistributor.txx
parLagrangianDistributorFields.cxx
\*---------------------------------------------------------------------------*/
@ -226,7 +226,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "parLagrangianDistributorTemplates.C"
# include "parLagrangianDistributor.txx"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -46,8 +46,8 @@ Description
Runs in parallel. Redistributes from srcMesh to tgtMesh.
SourceFiles
parPointFieldDistributor.C
parPointFieldDistributorTemplates.C
parPointFieldDistributor.cxx
parPointFieldDistributor.txx
\*---------------------------------------------------------------------------*/
@ -266,7 +266,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "parPointFieldDistributorTemplates.C"
# include "parPointFieldDistributor.txx"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -30,7 +30,7 @@ Description
A Cloud of passive position particles
SourceFiles
passivePositionParticleCloud.C
passivePositionParticleCloud.cxx
\*---------------------------------------------------------------------------*/
@ -79,7 +79,7 @@ public:
passivePositionParticleCloud
(
const polyMesh& mesh,
const Foam::zero,
Foam::zero,
const word& cloudName = cloud::defaultName
)
:

View File

@ -48,13 +48,11 @@ PtrList<unmappedPassivePositionParticleCloud>
readLagrangian
(
const fvMesh& mesh,
const wordList& cloudNames,
const UList<word>& cloudNames,
const boolUList& haveClouds,
const wordRes& selectedFields
)
{
PtrList<unmappedPassivePositionParticleCloud> clouds(cloudNames.size());
if (!cloudNames.empty())
{
(void)mesh.tetBasePtIs();
@ -72,16 +70,16 @@ readLagrangian
// Setup clouds
PtrList<unmappedPassivePositionParticleCloud> clouds(cloudNames.size());
forAll(cloudNames, i)
{
//Pout<< "Loading cloud " << cloudNames[i] << endl;
clouds.set
(
i,
new unmappedPassivePositionParticleCloud(mesh, cloudNames[i], false)
);
const auto& cloudName = cloudNames[i];
//Pout<< "Loading cloud " << cloudName << endl;
//for (passivePositionParticle& p : clouds[i]))
auto& cloud = clouds.emplace_set(i, mesh, cloudName, false);
//for (passivePositionParticle& p : cloud)
//{
// Pout<< "Particle position:" << p.position()
// << " cell:" << p.cell()
@ -89,12 +87,12 @@ readLagrangian
// << endl;
//}
IOobjectList cloudObjs(clouds[i], clouds[i].time().timeName());
IOobjectList cloudObjs(cloud, cloud.time().timeName());
parLagrangianDistributor::readAllFields
(
clouds[i],
haveClouds[i],
cloud,
haveClouds.test(i),
cloudObjs,
selectedFields
);

View File

@ -1257,6 +1257,8 @@ int main(int argc, char *argv[])
true // Advanced option
);
// Prevent volume BCs from triggering finite-area
regionModels::allowFaModels(false);
//- Disable caching of times/processor dirs etc. Cause massive parallel
// problems when e.g decomposing.
@ -1269,6 +1271,7 @@ int main(int argc, char *argv[])
argList args(argc, argv);
// ------------------------------------------------------------------------
// As much as possible avoid synchronised operation. To be looked at more
// closely for the three scenarios:

View File

@ -31,9 +31,6 @@ Description
passivePositionParticleCloud but with autoMap and writing disabled.
Only used for its objectRegistry to store lagrangian fields
SourceFiles
unmappedPassivePositionParticleCloud.C
\*---------------------------------------------------------------------------*/
#ifndef Foam_unmappedPassivePositionParticleCloud_H
@ -73,7 +70,7 @@ public:
unmappedPassivePositionParticleCloud
(
const polyMesh& mesh,
const Foam::zero,
Foam::zero,
const word& cloudName = cloud::defaultName
)
:

View File

@ -323,6 +323,9 @@ int main(int argc, char *argv[])
);
argList::addOptionCompat("cellZones", {"cellZone", 1912});
// Prevent volume BCs from triggering finite-area
regionModels::allowFaModels(false);
#include "setRootCase.H"
// ------------------------------------------------------------------------

View File

@ -479,8 +479,14 @@ int main(int argc, char *argv[])
"Directory name for VTK output (default: 'VTK')"
);
// Prevent volume BCs from triggering finite-area
regionModels::allowFaModels(false);
#include "setRootCase.H"
// ------------------------------------------------------------------------
// Configuration
/// const int optVerbose = args.verbose();
const bool decomposePoly = args.found("poly-decomp");
const bool doBoundary = !args.found("no-boundary");

View File

@ -79,6 +79,7 @@ scalar calcVertexNormalWeight
{
FatalErrorInFunction
<< "Point not in face" << abort(FatalError);
return 0;
}
const vector e1 = points[f[index]] - points[f[f.fcIndex(index)]];

138
bin/foamCleanFaMesh Executable file
View File

@ -0,0 +1,138 @@
#!/bin/sh
#------------------------------------------------------------------------------
# ========= |
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \\ / O peration |
# \\ / A nd | www.openfoam.com
# \\/ M anipulation |
#-------------------------------------------------------------------------------
# Copyright (C) 2011 OpenFOAM Foundation
# Copyright (C) 2025 OpenCFD Ltd.
#------------------------------------------------------------------------------
# License
# This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
#
# Script
# foamCleanFaMesh
#
# Description
# Remove the contents of the constant/finite-area/faMesh directory
# as per the Foam::faMesh::removeFiles() method.
#
#------------------------------------------------------------------------------
usage() {
exec 1>&2
while [ "$#" -ge 1 ]; do echo "$1"; shift; done
cat <<USAGE
Usage: ${0##*/} [OPTION]
options:
-case <dir> case directory, default is the cwd
-area-region <name> area-mesh region
-dry-run | -n report actions but do not remove
-help print the usage
Remove the contents of the constant/finite-area/faMesh directory as per the
Foam::faMesh::removeFiles() method.
USAGE
exit 1
}
#------------------------------------------------------------------------------
# Parse options
unset caseDir areaRegion optDryRun
while [ "$#" -gt 0 ]
do
case "$1" in
-h | -help*)
usage
;;
-dry-run | -n)
optDryRun="(dry-run) "
;;
-case=*)
caseDir="${1#*=}"
;;
-case)
[ "$#" -ge 2 ] || usage "'$1' option requires an argument"
cd "$2" 2>/dev/null || usage "directory does not exist: '$2'"
caseDir=$2
shift
;;
-area-region)
[ "$#" -ge 2 ] || usage "'$1' option requires an argument"
areaRegion=$2
shift
;;
(*)
usage "unknown option/argument: '$*'"
;;
esac
shift
done
#------------------------------------------------------------------------------
# Remove files (mesh etc)
# also remove .gz versions of the same files
removeFiles()
{
local directory="$1"
for i in \
faceLabels \
faBoundary \
;
do
if [ -n "$optDryRun" ]
then
echo "${optDryRun} rm -rf $directory/{$i,$i.gz}"
else
rm -rf -- "$directory/$i" "$directory/$i.gz"
fi
done
}
#------------------------------------------------------------------------------
meshDir="constant/finite-area/${areaRegion}${areaRegion:+/}faMesh"
if [ -d "$meshDir" ]
then
# [OK] has constant/finite-areaRegion/<region>/faMesh
:
elif [ -n "$caseDir" ]
then
# Specified -case, so no extra magic...
echo "Error: no <$meshDir> in $caseDir" 1>&2
exit 1
else
# Try some other combinations
other="${meshDir#constant/}"
if [ -d "$other" ]
then
# Probably already within constant/
meshDir="$other}"
elif [ "${PWD##*/}" = faMesh ] && [ -z "$areaRegion" ]
then
# Apparently already within faMesh/
meshDir=.
fi
fi
echo "Cleaning ${caseDir:-.}/$meshDir" 1>&2
removeFiles "$meshDir"
#------------------------------------------------------------------------------

View File

@ -7,7 +7,7 @@
# \\/ M anipulation |
#-------------------------------------------------------------------------------
# Copyright (C) 2011-2016 OpenFOAM Foundation
# Copyright (C) 2022 OpenCFD Ltd.
# Copyright (C) 2022,2025 OpenCFD Ltd.
#------------------------------------------------------------------------------
# License
# This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
@ -27,9 +27,10 @@ usage() {
Usage: ${0##*/} [OPTION]
options:
-case <dir> specify alternative case directory, default is the cwd
-region <name> specify alternative mesh region
-help print the usage
-case <dir> case directory, default is the cwd
-region <name> mesh region
-dry-run | -n report actions but do not remove
-help print the usage
Remove the contents of the constant/polyMesh directory as per the
Foam::polyMesh::removeFiles() method.
@ -38,58 +39,101 @@ USAGE
exit 1
}
unset caseDir regionName
#------------------------------------------------------------------------------
# Parse options
unset caseDir regionName optDryRun
# Parse a single option
while [ "$#" -gt 0 ]
do
case "$1" in
-h | -help*)
usage
;;
-dry-run | -n)
optDryRun="(dry-run) "
;;
-case=*)
caseDir="${1#*=}"
;;
-case)
caseDir="$2"
[ "$#" -ge 2 ] || usage "'$1' option requires an argument"
cd "$2" 2>/dev/null || usage "directory does not exist: '$2'"
caseDir=$2
shift 2
shift
;;
-region)
[ "$#" -ge 2 ] || usage "'$1' option requires an argument"
regionName=$2
shift 2
regionName="$2"
shift
;;
*)
(*)
usage "unknown option/argument: '$*'"
;;
esac
shift
done
meshDir=polyMesh
if [ -n "$regionName" ]
then
meshDir="$regionName/$meshDir"
fi
#------------------------------------------------------------------------------
# If -case was specified: insist upon 'constant/polyMesh'
if [ -n "$caseDir" ]
# Remove files (mesh itself, modifiers, snappyHexMesh ones) and subdirectories
# also remove .gz versions of the same files
removeFiles()
{
local directory="$1"
for i in \
points faces \
owner neighbour \
boundary \
cells \
cellZones faceZones pointZones \
meshModifiers \
parallelData \
sets \
cellLevel pointLevel \
level0Edge \
refinementHistory \
surfaceIndex \
;
do
if [ -n "$optDryRun" ]
then
echo "${optDryRun} rm -rf $directory/{$i,$i.gz}"
else
rm -rf -- "$directory/$i" "$directory/$i.gz"
fi
done
}
#------------------------------------------------------------------------------
meshDir="constant/${regionName}${regionName:+/}polyMesh"
if [ -d "$meshDir" ]
then
if [ -d constant/"$meshDir" ]
then
# Use constant/polyMesh
meshDir=constant/"$meshDir"
else
echo "Error: no 'constant/$meshDir' in $caseDir" 1>&2
exit 1
fi
# [OK] has constant/<region>/polyMesh
:
elif [ -n "$caseDir" ]
then
# Specified -case, so no extra magic...
echo "Error: no <$meshDir> in $caseDir" 1>&2
exit 1
else
if [ -d constant/"$meshDir" ]
# Try some other combinations
other="${meshDir#constant/}"
if [ -d "$other" ]
then
# Use constant/polyMesh
meshDir=constant/"$meshDir"
elif [ -d "$meshDir" ]
then
# Likely already in constant/ - do not adjust anything
:
# Probably already within constant/
meshDir="$other}"
elif [ "${PWD##*/}" = polyMesh ] && [ -z "$regionName" ]
then
# Apparently already within polyMesh/
@ -98,31 +142,8 @@ else
fi
# Remove files (mesh itself, modifiers, snappyHexMesh ones) and subdirectories
# also remove .gz versions of the same files
echo "Cleaning ${caseDir:-.}/$meshDir" 1>&2
for i in \
points \
faces \
owner \
neighbour \
cells \
boundary \
pointZones \
faceZones \
cellZones \
meshModifiers \
parallelData \
sets \
cellLevel \
pointLevel \
level0Edge \
refinementHistory \
surfaceIndex \
;
do
rm -rf "$meshDir/$i" "$meshDir/$i.gz"
done
removeFiles "$meshDir"
#------------------------------------------------------------------------------

View File

@ -108,54 +108,116 @@ cleanPostProcessing()
}
# ---------------
# Remove constant/finite-area/faMesh or constant/finite-area/{region}/faMesh
#
# Accepts following options:
# -region <name> The region name
# -- End of options
# ---------------
cleanFaMesh()
{
if [ -e constant/finite-area/faMesh ]
local region
# Parse options
while [ "$#" -gt 0 ]
do
case "$1" in
('') ;; # Ignore empty option
(--) shift; break ;; # Stop option parsing
(-region) region="$2"; shift ;;
(*) break ;;
esac
shift
done
# safety
if [ "$region" = "--" ]; then unset region; fi
local meshDir="constant/finite-area/${region}${region:+/}faMesh"
if [ -e "$meshDir" ]
then
rm -rf constant/finite-area/faMesh
[ -n "$region" ] && echo "Clearing $meshDir" 1>&2
rm -rf -- "$meshDir"
fi
if [ -e constant/faMesh ]
# Legacy location <constant/faMesh>
# - may still have remnant <constant/faMesh/faMeshDefinition>
meshDir="constant/faMesh"
if [ -e "$meshDir" ] && [ -z "$region" ]
then
if [ -e constant/faMesh/faMeshDefinition ]
if [ -e "$meshDir"/faMeshDefinition ]
then
# Old constant/faMesh location for faMeshDefinition still in use:
# - warn but don't remove anything
# VERY OLD LOCATION
echo
echo "Warning: not removing constant/faMesh/"
echo "WARNING: not removing $meshDir/"
echo " It contains a 'faMeshDefinition' file"
echo " Please relocate file(s) to system/ !!"
echo " Please relocate file(s) to system/finite-area/ !!"
echo
else
# Can remove constant/faMesh/ entirely (no faMeshDefinition)
rm -rf constant/faMesh
echo "Clearing $meshDir" 1>&2
rm -rf -- "$meshDir"
fi
fi
}
# ---------------
# Remove constant/polyMesh or constant/<region>/polyMesh
#
# Accepts following options:
# -region <name> The region name
# -- End of options
# ---------------
cleanPolyMesh()
{
if [ -e constant/polyMesh ]
local region
# Parse options
while [ "$#" -gt 0 ]
do
case "$1" in
('') ;; # Ignore empty option
(--) shift; break ;; # Stop option parsing
(-region) region="$2"; shift ;;
(*) break ;;
esac
shift
done
# safety
if [ "$region" = "--" ]; then unset region; fi
local meshDir="constant/${region}${region:+/}polyMesh"
if [ -e "$meshDir" ]
then
if [ -e constant/polyMesh/blockMeshDict ] \
|| [ -e constant/polyMesh/blockMeshDict.m4 ]
[ -n "$region" ] && echo "Clearing $meshDir" 1>&2
if [ -e "$meshDir"/blockMeshDict ] \
|| [ -e "$meshDir"/blockMeshDict.m4 ]
then
# Old constant/polyMesh location for blockMeshDict still in use:
# - warn but don't remove anything
# VERY OLD LOCATION
echo
echo "Warning: not removing constant/polyMesh/"
echo "WARNING: not removing $meshDir/"
echo " It contains a 'blockMeshDict' or 'blockMeshDict.m4' file"
echo " Please relocate file(s) to system/ !!"
echo
else
# Can remove constant/polyMesh/ entirely (no blockMeshDict)
rm -rf constant/polyMesh
rm -rf -- "$meshDir"
fi
fi
if [ -e system/blockMeshDict.m4 ]
meshDir="system${region:+/}${region}"
if [ -e "$meshDir"/blockMeshDict.m4 ]
then
rm -f system/blockMeshDict
rm -f -- "$meshDir"/blockMeshDict
fi
}
@ -212,7 +274,7 @@ cleanCase0()
removeCase()
{
echo "Removing case ${1:-unknown}"
[ "$#" -ge 1 ] && rm -rf "$1"
[ "$#" -ge 1 ] && rm -rf -- "$1"
}

View File

@ -517,9 +517,11 @@ cloneParallelCase()
}
# ---------------
# If 0.orig/ exists, copy (overwrite) into 0/ [ie, serial case]
# * -processor : copy into processor directories instead
# * -all : copy into serial and processor directories
# ---------------
restore0Dir()
{
if [ ! -d 0.orig ]
@ -553,4 +555,61 @@ restore0Dir()
}
# ---------------
# Helper routine to remove specified fields from the 0/ directory.
# Often used in combination with foamListRegions.
#
# Accepts following options:
# -region <name> The region name
# -- End of options
#
# any remaining parameters are taken to be fields names
# ---------------
remove0DirFields()
{
local region
# Parse options
while [ "$#" -gt 0 ]
do
case "$1" in
('') ;; # Ignore empty option
(--) shift; break ;; # Stop option parsing
(-region) region="$2"; shift ;;
(*) break ;;
esac
shift
done
# safety
if [ "$region" = "--" ]; then unset region; fi
if [ "$#" -eq 0 ]
then
echo "No fields specified for ${region:+region=$region }" 1>&2
return 0
fi
echo "Remove 0/ fields${region:+ [$region]} : $@" 1>&2
local subdir
for subdir in 0/"$region" processor*/0/"$region"
do
if [ -d "$subdir" ]
then
for field in $@ ## unquoted for IFS splitting [SIC]
do
# Cautious with removal
if [ -f "$subdir/$field" ]
then
rm -f -- "$subdir/$field"
fi
done
fi
done
return 0
}
#------------------------------------------------------------------------------

View File

@ -140,6 +140,11 @@ _of_complete_()
# Could use "foamListTimes -withZero", but still doesn't address ranges
COMPREPLY=($(compgen -d -X '![-0-9]*' -- ${cur}))
;;
-area-region)
# Or: $(find system/finite-area -mindepth 1 -maxdepth 1 -type d 2>/dev/null | sed -e 's%.*/%%')
choices=$(\ls -d system/finite-area/*/ 2>/dev/null | sed -e 's%/$%%; s%^.*/%%')
COMPREPLY=($(compgen -W "$choices" -- ${cur}))
;;
-region)
# Or: $(find system -mindepth 1 -maxdepth 1 -type d 2>/dev/null | sed -e 's%.*/%%')
choices=$(\ls -d system/*/ 2>/dev/null | sed -e 's%/$%%; s%^.*/%%')

View File

@ -1,7 +1,7 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2512 |
| \\ / O peration | Version: v2506 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
@ -108,11 +108,6 @@ OptimisationSwitches
// uncollated (default), collated, masterUncollated etc.
fileHandler uncollated;
//- Preferred backend for collated format. Default: 0
// 0: legacy writer
// 1: MPI/IO writer
collated.backend 0;
//- collated: thread buffer size for queued file writes.
// If set to 0 or not sufficient for the file size, threading is not used.
// A special setting is a negative value which assumes the buffer

View File

@ -1 +0,0 @@
#warning File removed - left for old dependency check only

View File

@ -1 +0,0 @@
#warning File removed - left for old dependency check only

View File

@ -116,7 +116,7 @@ public:
inline explicit DynamicList(const label initialCapacity);
//- Construct with given size and capacity
inline explicit DynamicList(const std::pair<label,label>& sizing);
inline explicit DynamicList(std::pair<label,label> sizing);
//- Construct with given size and value for all elements.
inline DynamicList(const label len, const T& val);

View File

@ -66,13 +66,10 @@ inline void Foam::DynamicList<T, SizeMin>::doCapacity_copy
}
// Addressable length, possibly truncated by new capacity
const label currLen = Foam::min(List<T>::size(), newCapacity);
const label currLen = std::min(List<T>::size(), newCapacity);
// The count truncated by the new addressable range
if (count > currLen)
{
count = currLen;
}
count = std::min(count, currLen);
// Consistent allocated sizing
List<T>::setAddressableSize(capacity_);
@ -104,10 +101,7 @@ inline void Foam::DynamicList<T, SizeMin>::doReserve_copy
const label currLen = List<T>::size();
// The count truncated by the addressable range
if (count > currLen)
{
count = currLen;
}
count = std::min(count, currLen);
// Consistent allocated sizing
List<T>::setAddressableSize(capacity_);
@ -155,7 +149,7 @@ inline Foam::DynamicList<T, SizeMin>::DynamicList(const label initialCapacity)
template<class T, int SizeMin>
inline Foam::DynamicList<T, SizeMin>::DynamicList
(
const std::pair<label,label>& sizing
std::pair<label,label> sizing
)
:
List<T>(std::max(sizing.first, sizing.second)),

View File

@ -200,27 +200,7 @@ Foam::Istream& Foam::DynamicList<T, SizeMin>::readList(Istream& is)
// Resize to length required
list.resize_nocopy(len);
if (is.format() == IOstreamOption::BINARY && is_contiguous_v<T>)
{
// Binary and contiguous
if (len)
{
Detail::readContiguous<T>
(
is,
list.data_bytes(),
list.size_bytes()
);
is.fatalCheck
(
"DynamicList<T>::readList(Istream&) : "
"reading binary block"
);
}
}
else if constexpr (std::is_same_v<char, std::remove_cv_t<T>>)
if constexpr (std::is_same_v<char, std::remove_cv_t<T>>)
{
// Special treatment for char data (binary I/O only)
const auto oldFmt = is.format(IOstreamOption::BINARY);
@ -232,8 +212,7 @@ Foam::Istream& Foam::DynamicList<T, SizeMin>::readList(Istream& is)
is.fatalCheck
(
"DynamicList<char>::readList(Istream&) : "
"reading binary block"
"DynamicList<char>::readList(Istream&) : [binary block]"
);
}
@ -241,48 +220,70 @@ Foam::Istream& Foam::DynamicList<T, SizeMin>::readList(Istream& is)
}
else
{
// Begin of contents marker
const char delimiter = is.readBeginList("List");
if (len)
if (is.format() == IOstreamOption::BINARY && is_contiguous_v<T>)
{
if (delimiter == token::BEGIN_LIST)
{
auto iter = list.begin();
const auto last = list.end();
// Binary and contiguous
// Contents
for (/*nil*/; (iter != last); (void)++iter)
if (len)
{
Detail::readContiguous<T>
(
is,
list.data_bytes(),
list.size_bytes()
);
is.fatalCheck
(
"DynamicList<T>::readList(Istream&) : [binary block]"
);
}
}
else
{
// Begin of contents marker
const char delimiter = is.readBeginList("List");
if (len)
{
if (delimiter == token::BEGIN_LIST)
{
is >> *iter;
auto iter = list.begin();
const auto last = list.end();
// Contents
for (/*nil*/; (iter != last); (void)++iter)
{
is >> *iter;
is.fatalCheck
(
"DynamicList<T>::readList(Istream&) : "
"reading entry"
);
}
}
else
{
// Uniform content (delimiter == token::BEGIN_BLOCK)
T elem;
is >> elem;
is.fatalCheck
(
"DynamicList<T>::readList(Istream&) : "
"reading entry"
"reading the single entry"
);
// Fill with the value
UList<T>::operator=(elem);
}
}
else
{
// Uniform content (delimiter == token::BEGIN_BLOCK)
T elem;
is >> elem;
is.fatalCheck
(
"DynamicList<T>::readList(Istream&) : "
"reading the single entry"
);
// Fill with the value
UList<T>::operator=(elem);
}
// End of contents marker
is.readEndList("List");
}
// End of contents marker
is.readEndList("List");
}
}
else if (tok.isPunctuation(token::BEGIN_LIST))

View File

@ -48,16 +48,12 @@ void Foam::List<T>::resize_copy(label count, const label len)
T* old = this->v_;
const label oldLen = this->size_;
if (count > len)
{
count = len; // The count truncated by the new length
}
// The count truncated by the new length?
count = std::min(count, len);
// Extra safety, probably not necessary:
// if (count > oldLen)
// {
// count = oldLen; // The count truncated by the old length
// }
// The count truncated by the old length?
// // count = std::min(count, oldLen);
if (count > 0)
{
@ -102,6 +98,8 @@ void Foam::List<T>::resize_copy(label count, const label len)
template<class T>
Foam::List<T>::List(const label len)
:
UList<T>()
{
if (FOAM_UNLIKELY(len < 0))
{
@ -120,6 +118,8 @@ Foam::List<T>::List(const label len)
template<class T>
Foam::List<T>::List(const label len, const T& val)
:
UList<T>()
{
if (FOAM_UNLIKELY(len < 0))
{
@ -139,6 +139,8 @@ Foam::List<T>::List(const label len, const T& val)
template<class T>
Foam::List<T>::List(const label len, Foam::zero)
:
UList<T>()
{
if (FOAM_UNLIKELY(len < 0))
{
@ -185,6 +187,8 @@ Foam::List<T>::List(Foam::one, Foam::zero)
template<class T>
Foam::List<T>::List(const UList<T>& list)
:
UList<T>()
{
if (!list.empty())
{
@ -196,6 +200,8 @@ Foam::List<T>::List(const UList<T>& list)
template<class T>
Foam::List<T>::List(const List<T>& list)
:
UList<T>()
{
if (!list.empty())
{
@ -207,6 +213,8 @@ Foam::List<T>::List(const List<T>& list)
template<class T>
Foam::List<T>::List(List<T>& list, bool reuse)
:
UList<T>()
{
if (reuse)
{
@ -226,6 +234,8 @@ Foam::List<T>::List(List<T>& list, bool reuse)
template<class T>
Foam::List<T>::List(const UList<T>& list, const labelUList& indices)
:
UList<T>()
{
if (!indices.empty())
{
@ -242,6 +252,8 @@ Foam::List<T>::List
const UList<T>& list,
const FixedList<label,N>& indices
)
:
UList<T>()
{
// if (!FixedList::empty()) is always true
{
@ -261,6 +273,8 @@ Foam::List<T>::List(const FixedList<T, N>& list)
template<class T>
Foam::List<T>::List(const UPtrList<T>& list)
:
UList<T>()
{
if (!list.empty())
{
@ -273,6 +287,8 @@ Foam::List<T>::List(const UPtrList<T>& list)
template<class T>
template<class Addr>
Foam::List<T>::List(const IndirectListBase<T, Addr>& list)
:
UList<T>()
{
if (!list.empty())
{
@ -292,6 +308,8 @@ Foam::List<T>::List(std::initializer_list<T> list)
template<class T>
template<int SizeMin>
Foam::List<T>::List(DynamicList<T, SizeMin>&& list)
:
UList<T>()
{
transfer(list);
}

View File

@ -88,6 +88,8 @@ inline Foam::List<T>::List
InputIterator inputEnd, // (unused)
const label len
)
:
UList<T>()
{
if (len > 0)
{

View File

@ -200,27 +200,7 @@ Foam::Istream& Foam::List<T>::readList(Istream& is)
// Resize to length required
list.resize_nocopy(len);
if (is.format() == IOstreamOption::BINARY && is_contiguous_v<T>)
{
// Binary and contiguous
if (len)
{
Detail::readContiguous<T>
(
is,
list.data_bytes(),
list.size_bytes()
);
is.fatalCheck
(
"List<T>::readList(Istream&) : "
"reading binary block"
);
}
}
else if constexpr (std::is_same_v<char, std::remove_cv_t<T>>)
if constexpr (std::is_same_v<char, std::remove_cv_t<T>>)
{
// Special treatment for char data (binary I/O only)
const auto oldFmt = is.format(IOstreamOption::BINARY);
@ -232,8 +212,7 @@ Foam::Istream& Foam::List<T>::readList(Istream& is)
is.fatalCheck
(
"List<char>::readList(Istream&) : "
"reading binary block"
"List<char>::readList(Istream&) : [binary block]"
);
}
@ -241,48 +220,70 @@ Foam::Istream& Foam::List<T>::readList(Istream& is)
}
else
{
// Begin of contents marker
const char delimiter = is.readBeginList("List");
if (len)
if (is.format() == IOstreamOption::BINARY && is_contiguous_v<T>)
{
if (delimiter == token::BEGIN_LIST)
{
auto iter = list.begin();
const auto last = list.end();
// Binary and contiguous
// Contents
for (/*nil*/; (iter != last); (void)++iter)
if (len)
{
Detail::readContiguous<T>
(
is,
list.data_bytes(),
list.size_bytes()
);
is.fatalCheck
(
"List<T>::readList(Istream&) : [binary block]"
);
}
}
else
{
// Begin of contents marker
const char delimiter = is.readBeginList("List");
if (len)
{
if (delimiter == token::BEGIN_LIST)
{
is >> *iter;
auto iter = list.begin();
const auto last = list.end();
// Contents
for (/*nil*/; (iter != last); (void)++iter)
{
is >> *iter;
is.fatalCheck
(
"List<T>::readList(Istream&) : "
"reading entry"
);
}
}
else
{
// Uniform content (delimiter == token::BEGIN_BLOCK)
T elem;
is >> elem;
is.fatalCheck
(
"List<T>::readList(Istream&) : "
"reading entry"
"reading the single entry"
);
// Fill with the value
UList<T>::operator=(elem);
}
}
else
{
// Uniform content (delimiter == token::BEGIN_BLOCK)
T elem;
is >> elem;
is.fatalCheck
(
"List<T>::readList(Istream&) : "
"reading the single entry"
);
// Fill with the value
UList<T>::operator=(elem);
}
// End of contents marker
is.readEndList("List");
}
// End of contents marker
is.readEndList("List");
}
}
else if (tok.isPunctuation(token::BEGIN_LIST))

View File

@ -103,19 +103,7 @@ Foam::Ostream& Foam::UList<T>::writeList
const label len = list.size();
if (os.format() == IOstreamOption::BINARY && is_contiguous_v<T>)
{
// Binary and contiguous
os << nl << len << nl;
if (len)
{
// write(...) includes surrounding start/end delimiters
os.write(list.cdata_bytes(), list.size_bytes());
}
}
else if constexpr (std::is_same_v<char, std::remove_cv_t<T>>)
if constexpr (std::is_same_v<char, std::remove_cv_t<T>>)
{
// Special treatment for char data (binary I/O only)
@ -130,61 +118,76 @@ Foam::Ostream& Foam::UList<T>::writeList
os.format(oldFmt);
}
else if (is_contiguous_v<T> && len > 1 && list.uniform())
{
// Two or more entries, and all entries have identical values.
os << len << token::BEGIN_BLOCK << list[0] << token::END_BLOCK;
}
else if
(
(len <= 1 || !shortLen)
||
(
(len <= shortLen)
&& (is_contiguous_v<T> || Foam::ListPolicy::no_linebreak<T>::value)
)
)
{
// Single-line output
// Size and start delimiter
os << len << token::BEGIN_LIST;
auto iter = list.cbegin();
const auto last = list.cend();
// Contents
if (iter != last)
{
os << *iter;
for (++iter; (iter != last); (void)++iter)
{
os << token::SPACE << *iter;
}
}
// End delimiter
os << token::END_LIST;
}
else
{
// Multi-line output
// Size and start delimiter
os << nl << len << nl << token::BEGIN_LIST;
auto iter = list.cbegin();
const auto last = list.cend();
// Contents
for (/*nil*/; (iter != last); (void)++iter)
if (os.format() == IOstreamOption::BINARY && is_contiguous_v<T>)
{
os << nl << *iter;
}
// Binary and contiguous
// End delimiter
os << nl << token::END_LIST << nl;
os << nl << len << nl;
if (len)
{
// write(...) includes surrounding start/end delimiters
os.write(list.cdata_bytes(), list.size_bytes());
}
}
else if (is_contiguous_v<T> && len > 1 && list.uniform())
{
// Two or more entries, and all entries have identical values.
os << len << token::BEGIN_BLOCK << list[0] << token::END_BLOCK;
}
else if
(
(len <= 1 || !shortLen)
||
(
(len <= shortLen)
&& (is_contiguous_v<T> || Foam::ListPolicy::no_linebreak<T>::value)
)
)
{
// Single-line output
// Size and start delimiter
os << len << token::BEGIN_LIST;
auto iter = list.cbegin();
const auto last = list.cend();
// Contents
if (iter != last)
{
os << *iter;
for (++iter; (iter != last); (void)++iter)
{
os << token::SPACE << *iter;
}
}
// End delimiter
os << token::END_LIST;
}
else
{
// Multi-line output
// Size and start delimiter
os << nl << len << nl << token::BEGIN_LIST;
auto iter = list.cbegin();
const auto last = list.cend();
// Contents
for (/*nil*/; (iter != last); (void)++iter)
{
os << nl << *iter;
}
// End delimiter
os << nl << token::END_LIST << nl;
}
}
os.check(FUNCTION_NAME);
@ -244,26 +247,6 @@ Foam::Istream& Foam::UList<T>::readList(Istream& is)
<< exit(FatalIOError);
}
if (is.format() == IOstreamOption::BINARY && is_contiguous_v<T>)
{
// Binary and contiguous
if (len)
{
Detail::readContiguous<T>
(
is,
list.data_bytes(),
list.size_bytes()
);
is.fatalCheck
(
"UList<T>::readList(Istream&) : "
"reading binary block"
);
}
}
else if constexpr (std::is_same_v<char, std::remove_cv_t<T>>)
{
// Special treatment for char data (binary I/O only)
@ -276,8 +259,7 @@ Foam::Istream& Foam::UList<T>::readList(Istream& is)
is.fatalCheck
(
"UList<char>::readList(Istream&) : "
"reading binary block"
"UList<char>::readList(Istream&) : [binary block]"
);
}
@ -285,44 +267,66 @@ Foam::Istream& Foam::UList<T>::readList(Istream& is)
}
else
{
// Begin of contents marker
const char delimiter = is.readBeginList("List");
if (len)
if (is.format() == IOstreamOption::BINARY && is_contiguous_v<T>)
{
if (delimiter == token::BEGIN_LIST)
// Binary and contiguous
if (len)
{
for (label i=0; i<len; ++i)
Detail::readContiguous<T>
(
is,
list.data_bytes(),
list.size_bytes()
);
is.fatalCheck
(
"UList<T>::readList(Istream&) : [binary block]"
);
}
}
else
{
// Begin of contents marker
const char delimiter = is.readBeginList("List");
if (len)
{
if (delimiter == token::BEGIN_LIST)
{
is >> list[i];
for (label i=0; i<len; ++i)
{
is >> list[i];
is.fatalCheck
(
"UList<T>::readList(Istream&) : "
"reading entry"
);
}
}
else
{
// Uniform content (delimiter == token::BEGIN_BLOCK)
T elem;
is >> elem;
is.fatalCheck
(
"UList<T>::readList(Istream&) : "
"reading entry"
"reading the single entry"
);
// Fill with the value
this->fill_uniform(elem);
}
}
else
{
// Uniform content (delimiter == token::BEGIN_BLOCK)
T elem;
is >> elem;
is.fatalCheck
(
"UList<T>::readList(Istream&) : "
"reading the single entry"
);
// Fill with the value
this->fill_uniform(elem);
}
// End of contents marker
is.readEndList("List");
}
// End of contents marker
is.readEndList("List");
}
}
else if (tok.isPunctuation(token::BEGIN_LIST))

View File

@ -80,7 +80,7 @@ public:
inline explicit PtrDynList(const label len);
//- Construct with given size and capacity
inline explicit PtrDynList(const std::pair<label,label>& sizing);
inline explicit PtrDynList(std::pair<label,label> sizing);
//- Copy construct using 'clone()' method on each element
inline PtrDynList(const PtrDynList<T, SizeMin>& list);

View File

@ -52,7 +52,7 @@ inline Foam::PtrDynList<T, SizeMin>::PtrDynList(const label len)
template<class T, int SizeMin>
inline Foam::PtrDynList<T, SizeMin>::PtrDynList
(
const std::pair<label,label>& sizing
std::pair<label,label> sizing
)
:
PtrList<T>(std::max(sizing.first, sizing.second)),

View File

@ -484,6 +484,13 @@ const Foam::fileName& Foam::IOobject::globalCaseName() const noexcept
}
const Foam::fileName&
Foam::IOobject::caseName(IOobjectOption::Layout layout) const noexcept
{
return time().caseName(layout);
}
Foam::scalar Foam::IOobject::instanceValue() const
{
scalar val(0);
@ -504,6 +511,7 @@ Foam::fileName Foam::IOobject::path() const
return instance();
}
// == time().path()/instance()/db_.dbDir()/local();
return rootPath()/caseName()/instance()/db_.dbDir()/local();
}
@ -515,10 +523,23 @@ Foam::fileName Foam::IOobject::globalPath() const
return instance();
}
// == time().globalPath()/instance()/db_.dbDir()/local();
return rootPath()/globalCaseName()/instance()/db_.dbDir()/local();
}
Foam::fileName Foam::IOobject::path(IOobjectOption::Layout layout) const
{
if (file_isOutsideCase(instance()))
{
return instance();
}
// == time().path(layout)/instance()/db_.dbDir()/local();
return rootPath()/caseName(layout)/instance()/db_.dbDir()/local();
}
Foam::fileName Foam::IOobject::path
(
const word& instance,
@ -541,6 +562,18 @@ Foam::fileName Foam::IOobject::globalPath
}
Foam::fileName Foam::IOobject::path
(
IOobjectOption::Layout layout,
const word& instance,
const fileName& local
) const
{
// Note: can only be called with relative instance since is word type
return rootPath()/caseName(layout)/instance/db_.dbDir()/local;
}
Foam::fileName Foam::IOobject::objectRelPath() const
{
if (file_isOutsideCase(instance()))

View File

@ -578,6 +578,9 @@ public:
//- Return the Time::globalCaseName()
const fileName& globalCaseName() const noexcept;
//- Return the Time::caseName() - normal or global
const fileName& caseName(IOobjectOption::Layout) const noexcept;
//- Read access to instance path component
inline const fileName& instance() const noexcept;
@ -600,6 +603,9 @@ public:
//- The complete global path for the object (with instance, local,...)
fileName globalPath() const;
//- The complete path (normal or global) for the object
fileName path(IOobjectOption::Layout) const;
//- The complete path with alternative instance and local
fileName path
(
@ -614,12 +620,24 @@ public:
const fileName& local = fileName::null
) const;
//- The complete path (normal or global)
//- with alternative instance and local
fileName path
(
IOobjectOption::Layout,
const word& instance,
const fileName& local = fileName::null
) const;
//- The complete path + object name
inline fileName objectPath() const;
//- The complete global path + object name
inline fileName globalObjectPath() const;
//- The complete path (normal or global) + object name
inline fileName objectPath(IOobjectOption::Layout) const;
//- The object path relative to the root
fileName objectRelPath() const;

View File

@ -329,6 +329,15 @@ inline Foam::fileName Foam::IOobject::globalObjectPath() const
}
inline Foam::fileName Foam::IOobject::objectPath
(
IOobjectOption::Layout layout
) const
{
return path(layout)/name();
}
// Error Handling
inline bool Foam::IOobject::good() const noexcept

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2018 OpenFOAM Foundation
Copyright (C) 2020-2025 OpenCFD Ltd.
Copyright (C) 2020-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -51,8 +51,6 @@ FoamFile
class decomposedBlockData;
location "constant/polyMesh";
object points;
data.format ascii; // optional
data.class vectorField; // optional
}
// processor0
@ -137,15 +135,23 @@ protected:
// Protected Member Functions
//- Read data (on master) and transmit.
//- Helper: determine number of processors whose recvSizes fits
//- into maxBufferSize
static label calcNumProcs
(
const label comm,
const off_t maxBufferSize,
const labelUList& recvSizes,
const label startProci
);
//- Read data into *this. ISstream is only valid on master.
static bool readBlocks
(
const label comm,
// [in] The input stream (only valid on master)
autoPtr<ISstream>& isPtr,
// [out] The processor local data
List<char>& localData,
const UPstream::commsTypes commsType /* unused */
List<char>& contentChars,
const UPstream::commsTypes commsType
);
//- Helper: skip a block of (binary) character data
@ -271,15 +277,14 @@ public:
}
//- Helper: write block of (binary) character content
// Housekeeping
static std::streamoff writeBlockEntry
(
OSstream& os,
const label blocki,
std::string_view sv
const std::string& s
)
{
return writeBlockEntry(os, blocki, sv.data(), sv.size());
return writeBlockEntry(os, blocki, s.data(), s.size());
}
//- Helper: write block of (binary) character data
@ -302,134 +307,61 @@ public:
);
//- Read master header information (into headerIO) and return
//- data in stream.
//- data in stream. Note: isPtr is only valid on master.
static autoPtr<ISstream> readBlocks
(
const label comm,
const fileName& fName,
//! [in] The input stream (only valid on master)
autoPtr<ISstream>& isPtr,
//! [out] header information
IOobject& headerIO,
const UPstream::commsTypes commsType /* unused */
);
//- Helper: gather data from (subset of) sub-ranks.
// In non-blocking mode it sets up send/recv for non-empty content.
// In blocking/scheduled mode it uses MPI_Gatherv to collect data.
//
// Returns:
// - recvData : the received data
// - recvOffsets : offset in data. recvOffsets is nProcs+1
static void gatherProcData
(
const label comm,
const UList<char>& localData, //!< [in] required on all procs
const labelUList& recvSizes, //!< [in] only required on master
const labelRange& whichProcs, //!< [in] required on all procs
List<int>& recvOffsets, //!< [out] only relevant on master
DynamicList<char>& recvData, //!< [out] only relevant on master
const UPstream::commsTypes commsType
);
//- Helper: gather single label. Note: using native Pstream.
// datas sized with num procs but undefined contents on
// slaves
static void gather
(
const label comm,
const label data,
labelList& datas
);
//- Helper: gather data from (subset of) slaves.
//
// Returns:
// - recvData : received data
// - recvOffsets : offset in data. recvOffsets is nProcs+1
static void gatherSlaveData
(
const label comm,
const UList<char>& data,
const labelUList& recvSizes,
const labelRange& fromProcs,
List<int>& recvOffsets,
DynamicList<char>& recvData
);
//- Write *this. Ostream only valid on master.
// Returns offsets of processor blocks in blockOffset
static bool writeBlocks
(
const label comm,
//! [in] output stream (relevant on master)
autoPtr<OSstream>& osPtr,
//! [out] start offsets to each block (relevant on master),
//! ignored if List::null() type
List<std::streamoff>& blockOffset,
const UList<char>& localData, //!< [in] required on all procs
const labelUList& recvSizes, //!< [in] only required on master
const UList<char>& masterData,
//! Optional proc data (only written on master)
//! but \b must also be symmetrically defined (empty/non-empty)
//! on all ranks
const UList<std::string_view>& procData,
const labelUList& recvSizes,
// Optional slave data (on master)
const UPtrList<SubList<char>>& slaveData,
const UPstream::commsTypes commsType,
const bool syncReturnState = true
);
// Housekeeping
//- Write *this. Ostream only valid on master.
// Returns offsets of processor blocks in blockOffset
FOAM_DEPRECATED_FOR(2023-09, "write with std::string_view instead")
static bool writeBlocks
(
const label comm,
autoPtr<OSstream>& osPtr,
List<std::streamoff>& blockOffset,
const UList<char>& localData, // [in] required on all procs
const labelUList& recvSizes, // [in] only required on master
// Optional proc data (only written on master)
// but \b must also be symmetrically defined (empty/non-empty)
// on all ranks
const UPtrList<SubList<char>>& procData,
const UPstream::commsTypes commsType,
const bool syncReturnState = true
)
{
// Transcribe to string_view
List<std::string_view> spans(procData.size());
forAll(procData, proci)
{
const auto* ptr = procData.get(proci);
if (ptr && !ptr->empty())
{
spans[proci] = std::string_view(ptr->cdata(), ptr->size());
}
}
bool ok = decomposedBlockData::writeBlocks
(
comm,
osPtr,
blockOffset,
localData,
recvSizes,
spans,
commsType,
syncReturnState
);
return ok;
}
//- Deprecated(2023-09) - consider UPstream::listGatherValue
// The only difference is that this gather also resizes the output
// on the non-master procs
// \deprecated(2023-09) - consider UPstream::listGatherValue
FOAM_DEPRECATED_FOR(2023-09, "consider UPstream::listGatherValue()")
static void gather
(
const label comm,
const label localValue,
labelList& allValues
)
{
allValues.resize_nocopy(UPstream::nProcs(comm));
UPstream::mpiGather
(
reinterpret_cast<const char*>(&localValue),
allValues.data_bytes(),
sizeof(label), // The send/recv size per rank
comm
);
}
};

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021-2023 OpenCFD Ltd.
Copyright (C) 2021-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -189,9 +189,10 @@ void Foam::decomposedBlockData::writeExtraHeaderContent
dict.set("data.class", io.type());
// Deep-copy of meta-data (if any)
if (const auto* meta = io.findMetaData(); meta && !meta->empty())
const dictionary* metaDataDict = io.findMetaData();
if (metaDataDict && !metaDataDict->empty())
{
dict.add("meta", *meta);
dict.add("meta", *metaDataDict);
}
}
@ -220,16 +221,16 @@ void Foam::decomposedBlockData::writeHeader
io.name()
);
// Same as writeExtraHeaderContent
{
writeHeaderEntry(os, "data.format", streamOptData.format());
writeHeaderEntry(os, "data.class", io.type());
}
// Meta-data (if any)
if (const auto* meta = io.findMetaData(); meta && !meta->empty())
const dictionary* metaDataDict = io.findMetaData();
if (metaDataDict && !metaDataDict->empty())
{
meta->writeEntry("meta", os);
metaDataDict->writeEntry("meta", os);
}
os.endBlock();

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017 OpenFOAM Foundation
Copyright (C) 2020-2025 OpenCFD Ltd.
Copyright (C) 2020-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -29,7 +29,7 @@ License
#include "masterOFstream.H"
#include "OFstream.H"
#include "OSspecific.H"
#include "Pstream.H"
#include "PstreamBuffers.H"
#include "masterUncollatedFileOperation.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -41,9 +41,9 @@ void Foam::masterOFstream::checkWrite
std::streamsize len
)
{
if (!str || !(len > 0))
if (!len)
{
// Can skip everything if there is nothing to write
// Can probably skip all of this if there is nothing to write
return;
}
@ -63,7 +63,9 @@ void Foam::masterOFstream::checkWrite
<< exit(FatalIOError);
}
// Write characters directly to std::ostream
// Use writeRaw() instead of writeQuoted(string,false) to output
// characters directly.
os.writeRaw(str, len);
if (!os.good())
@ -75,29 +77,24 @@ void Foam::masterOFstream::checkWrite
}
void Foam::masterOFstream::checkWrite
(
const fileName& fName,
const std::string& s
)
{
checkWrite(fName, s.data(), s.length());
}
void Foam::masterOFstream::commit()
{
// Take ownership of serialized content
DynamicList<char> charData(OCharStream::release());
if (!UPstream::parRun())
if (UPstream::parRun())
{
// Write (non-empty) data
checkWrite(pathName_, charData);
}
else
{
// Ignore content if not writing
if (!writeOnProc_)
{
charData.clear();
}
List<fileName> filePaths(UPstream::nProcs(comm_));
filePaths[UPstream::myProcNo(comm_)] = pathName_;
Pstream::gatherList(filePaths, UPstream::msgType(), comm_);
// Test for identical output paths
bool uniform =
(
UPstream::master(comm_)
@ -108,136 +105,69 @@ void Foam::masterOFstream::commit()
if (uniform)
{
// Identical file paths - write on master
if (UPstream::master(comm_) && writeOnProc_)
{
checkWrite(pathName_, charData);
checkWrite(pathName_, this->str());
}
this->reset();
return;
}
// Different files
// ---------------
//
// Non-sparse (most ranks have writeOnProc_ == true),
// so gather sizes first and use PEX-like handling,
// with polling for when data becomes available.
//
// Could also consider double buffering + write to reduce
// memory overhead.
PstreamBuffers pBufs(comm_);
// Or int64_t
const label dataSize =
(
(UPstream::is_subrank(comm_) && writeOnProc_)
? charData.size()
: 0
);
if (!UPstream::master(comm_))
{
if (writeOnProc_)
{
// Send buffer to master
string s(this->str());
const labelList recvSizes
(
UPstream::listGatherValues<label>(dataSize, comm_)
);
UOPstream os(UPstream::masterNo(), pBufs);
os.write(s.data(), s.length());
}
this->reset(); // Done with contents
}
pBufs.finishedGathers();
// Receive from these procs
DynamicList<int> recvProcs;
if (UPstream::master(comm_))
{
// Sorted by message size
labelList order(Foam::sortedOrder(recvSizes));
recvProcs.reserve_exact(order.size());
// Want to receive large messages first. Ignore empty slots
forAllReverse(order, i)
{
const label proci = order[i];
// Ignore empty slots
if (recvSizes[proci] > 0)
{
recvProcs.push_back(proci);
}
}
}
// Non-blocking communication
const label startOfRequests = UPstream::nRequests();
// Some unique tag for this read/write grouping (extra precaution)
const int messageTag = (UPstream::msgType() + 256);
if (UPstream::is_subrank(comm_) && dataSize > 0)
{
// Send to content to master
UOPstream::write
(
UPstream::commsTypes::nonBlocking,
UPstream::masterNo(),
charData.cdata_bytes(),
charData.size_bytes(),
messageTag,
comm_
);
}
else if (UPstream::master(comm_))
{
// The receive slots
List<List<char>> recvBuffers(UPstream::nProcs(comm_));
// Receive from these procs (non-empty slots)
for (const int proci : recvProcs)
{
auto& slot = recvBuffers[proci];
slot.resize_nocopy(recvSizes[proci]);
// Receive content
UIPstream::read
(
UPstream::commsTypes::nonBlocking,
proci,
slot.data_bytes(),
slot.size_bytes(),
messageTag,
comm_
);
}
if (writeOnProc_)
{
// Write non-empty master data
checkWrite(pathName_, charData);
charData.clear();
// Write master data
checkWrite(filePaths[UPstream::masterNo()], this->str());
}
this->reset(); // Done with contents
// Poll for completed receive requests and dispatch
DynamicList<int> indices(recvProcs.size());
while
(
UPstream::waitSomeRequests
(
startOfRequests,
recvProcs.size(),
&indices
)
)
// Allocate large enough to read without resizing
List<char> buf(pBufs.maxRecvCount());
for (const int proci : UPstream::subProcs(comm_))
{
for (const int i : indices)
const std::streamsize count(pBufs.recvDataCount(proci));
if (count)
{
const int proci = recvProcs[i];
auto& slot = recvBuffers[proci];
UIPstream is(proci, pBufs);
// Write non-empty sub-proc data
checkWrite(filePaths[proci], slot);
// Eager cleanup
slot.clear();
is.read(buf.data(), count);
checkWrite(filePaths[proci], buf.cdata(), count);
}
}
}
UPstream::waitRequests(startOfRequests);
}
else
{
checkWrite(pathName_, this->str());
this->reset();
}
// This method is only called once (internally)
// so no need to clear/flush old buffered data
}
@ -246,24 +176,21 @@ void Foam::masterOFstream::commit()
Foam::masterOFstream::masterOFstream
(
IOstreamOption::atomicType atomic,
const int communicator,
const label comm,
const fileName& pathName,
IOstreamOption streamOpt,
IOstreamOption::appendType append,
const bool writeOnProc
)
:
OCharStream(streamOpt),
OStringStream(streamOpt),
pathName_(pathName),
atomic_(atomic),
compression_(streamOpt.compression()),
append_(append),
writeOnProc_(writeOnProc),
comm_(communicator < 0 ? UPstream::worldComm : communicator)
{
// Start with a slightly larger buffer
OCharStream::reserve(4*1024);
}
comm_(comm)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017 OpenFOAM Foundation
Copyright (C) 2020-2025 OpenCFD Ltd.
Copyright (C) 2020-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -41,7 +41,7 @@ SourceFiles
#ifndef Foam_masterOFstream_H
#define Foam_masterOFstream_H
#include "SpanStream.H"
#include "StringStream.H"
#include "UPstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -55,7 +55,7 @@ namespace Foam
class masterOFstream
:
public OCharStream
public OStringStream
{
// Private Data
@ -80,8 +80,7 @@ class masterOFstream
// Private Member Functions
//- Open file with checking and write append contents.
// A no-op if str is null or len is zero
//- Open file with checking and write append contents
void checkWrite
(
const fileName& fName,
@ -90,16 +89,9 @@ class masterOFstream
);
//- Open file with checking and write append contents
void checkWrite
(
const fileName& fName,
const UList<char>& charData
)
{
checkWrite(fName, charData.cdata(), charData.size_bytes());
}
void checkWrite(const fileName& fName, const std::string& s);
//- Commit buffered information, including communication as required
//- Commit buffered information, including parallel gather as required
void commit();
@ -112,8 +104,7 @@ public:
masterOFstream
(
IOstreamOption::atomicType atomic,
//! The communicator number (-1 == worldComm)
const int communicator,
const label comm,
const fileName& pathname,
IOstreamOption streamOpt = IOstreamOption(),
IOstreamOption::appendType append = IOstreamOption::NO_APPEND,
@ -124,8 +115,7 @@ public:
//- from pathname, stream option, optional append
masterOFstream
(
//! The communicator number (-1 == worldComm)
const int communicator,
const label comm,
const fileName& pathname,
IOstreamOption streamOpt = IOstreamOption(),
IOstreamOption::appendType append = IOstreamOption::NO_APPEND,
@ -135,7 +125,7 @@ public:
masterOFstream
(
IOstreamOption::NON_ATOMIC,
communicator,
comm,
pathname,
streamOpt,
append,

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2011-2016,2024 OpenFOAM Foundation
Copyright (C) 2017-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
@ -150,8 +150,17 @@ public:
//- Read a string (including enclosing double-quotes)
virtual Istream& read(string&) = 0;
//- Read a label
virtual Istream& read(label&) = 0;
//- Read int32_t
virtual Istream& read(int32_t&) = 0;
//- Read int64_t
virtual Istream& read(int64_t&) = 0;
//- Read uint32_t
virtual Istream& read(uint32_t&) = 0;
//- Read uint64_t
virtual Istream& read(uint64_t&) = 0;
//- Read a float
virtual Istream& read(float&) = 0;

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2011-2016,2024 OpenFOAM Foundation
Copyright (C) 2016-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
@ -154,6 +154,12 @@ public:
//- Write int64_t
virtual Ostream& write(const int64_t val) = 0;
//- Write uint32_t
virtual Ostream& write(const uint32_t val) = 0;
//- Write uint64_t
virtual Ostream& write(const uint64_t val) = 0;
//- Write float
virtual Ostream& write(const float val) = 0;
@ -335,22 +341,6 @@ inline Ostream& operator<<(Ostream& os, std::string_view s)
return os;
}
//- Write operator for character span. Output like string data
inline Ostream& operator<<(Ostream& os, stdFoam::span<char> s)
{
os.writeQuoted(s.data(), s.size(), true); // quoted
os.check("Foam::operator<<(Ostream&, stdFoam::span<char>)");
return os;
}
//- Write operator for const character span. Output like string data
inline Ostream& operator<<(Ostream& os, stdFoam::span<const char> s)
{
os.writeQuoted(s.data(), s.size(), true); // quoted
os.check("Foam::operator<<(Ostream&, stdFoam::span<const char>)");
return os;
}
/*---------------------------------------------------------------------------*\
Manipulators (without arguments)

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2013 OpenFOAM Foundation
Copyright (C) 2011-2013,2024 OpenFOAM Foundation
Copyright (C) 2017-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
@ -184,8 +184,17 @@ public:
// Read a string
virtual Istream& read(string& str) override;
//- Read a label
virtual Istream& read(label& val) override;
//- Read int32_t
virtual Istream& read(int32_t& val) override;
//- Read int64_t
virtual Istream& read(int64_t& val) override;
//- Read uint32_t
virtual Istream& read(uint32_t& val) override;
//- Read uint64_t
virtual Istream& read(uint64_t& val) override;
//- Read a float
virtual Istream& read(float& val) override;

View File

@ -5,8 +5,8 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2017-2023 OpenCFD Ltd.
Copyright (C) 2011-2015,2024 OpenFOAM Foundation
Copyright (C) 2017-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -306,9 +306,7 @@ Foam::Istream& Foam::UIPstreamBase::read(token& t)
if (c == token::FLAG)
{
char flagVal;
if (read(flagVal))
if (char flagVal; read(flagVal))
{
processFlags(*this, flagVal);
}
@ -349,8 +347,7 @@ Foam::Istream& Foam::UIPstreamBase::read(token& t)
case token::tokenType::WORD :
case token::tokenType::DIRECTIVE :
{
word val;
if (readString(val))
if (word val; readString(val))
{
if
(
@ -376,8 +373,7 @@ Foam::Istream& Foam::UIPstreamBase::read(token& t)
case token::tokenType::VERBATIM :
case token::tokenType::CHAR_DATA :
{
string val;
if (readString(val))
if (string val; readString(val))
{
t = std::move(val);
t.setType(token::tokenType(c));
@ -389,13 +385,54 @@ Foam::Istream& Foam::UIPstreamBase::read(token& t)
return *this;
}
// Label
case token::tokenType::LABEL :
// (signed) int32
case token::tokenType::INTEGER_32 :
{
label val;
if (read(val))
if (int32_t val; read(val))
{
t = val;
t.int32Token(val);
}
else
{
t.setBad();
}
return *this;
}
// (signed) int64
case token::tokenType::INTEGER_64 :
{
if (int64_t val; read(val))
{
t.int64Token(val);
}
else
{
t.setBad();
}
return *this;
}
// (unsigned) int32
case token::tokenType::UNSIGNED_INTEGER_32 :
{
if (uint32_t val; read(val))
{
t.uint32Token(val);
}
else
{
t.setBad();
}
return *this;
}
// (unsigned) int64
case token::tokenType::UNSIGNED_INTEGER_64 :
{
if (uint64_t val; read(val))
{
t.uint64Token(val);
}
else
{
@ -407,8 +444,7 @@ Foam::Istream& Foam::UIPstreamBase::read(token& t)
// Float
case token::tokenType::FLOAT :
{
float val;
if (read(val))
if (float val; read(val))
{
t = val;
}
@ -422,8 +458,7 @@ Foam::Istream& Foam::UIPstreamBase::read(token& t)
// Double
case token::tokenType::DOUBLE :
{
double val;
if (read(val))
if (double val; read(val))
{
t = val;
}
@ -473,7 +508,28 @@ Foam::Istream& Foam::UIPstreamBase::read(string& str)
}
Foam::Istream& Foam::UIPstreamBase::read(label& val)
Foam::Istream& Foam::UIPstreamBase::read(int32_t& val)
{
readFromBuffer(val);
return *this;
}
Foam::Istream& Foam::UIPstreamBase::read(int64_t& val)
{
readFromBuffer(val);
return *this;
}
Foam::Istream& Foam::UIPstreamBase::read(uint32_t& val)
{
readFromBuffer(val);
return *this;
}
Foam::Istream& Foam::UIPstreamBase::read(uint64_t& val)
{
readFromBuffer(val);
return *this;

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2014 OpenFOAM Foundation
Copyright (C) 2011-2014,2024 OpenFOAM Foundation
Copyright (C) 2017-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
@ -192,12 +192,18 @@ public:
//- Write string
virtual Ostream& write(const std::string& str) override;
//- Write int32_t as a label
//- Write int32_t
virtual Ostream& write(const int32_t val) override;
//- Write int64_t as a label
//- Write int64_t
virtual Ostream& write(const int64_t val) override;
//- Write uint32_t
virtual Ostream& write(const uint32_t val) override;
//- Write uint64_t
virtual Ostream& write(const uint64_t val) override;
//- Write float
virtual Ostream& write(const float val) override;

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2011-2017,2024 OpenFOAM Foundation
Copyright (C) 2016-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
@ -321,7 +321,7 @@ Foam::Ostream& Foam::UOPstreamBase::write(const std::string& str)
Foam::Ostream& Foam::UOPstreamBase::write(const int32_t val)
{
putChar(token::tokenType::LABEL);
putChar(token::tokenType::INTEGER_32);
writeToBuffer(val);
return *this;
}
@ -329,7 +329,23 @@ Foam::Ostream& Foam::UOPstreamBase::write(const int32_t val)
Foam::Ostream& Foam::UOPstreamBase::write(const int64_t val)
{
putChar(token::tokenType::LABEL);
putChar(token::tokenType::INTEGER_64);
writeToBuffer(val);
return *this;
}
Foam::Ostream& Foam::UOPstreamBase::write(const uint32_t val)
{
putChar(token::tokenType::UNSIGNED_INTEGER_32);
writeToBuffer(val);
return *this;
}
Foam::Ostream& Foam::UOPstreamBase::write(const uint64_t val)
{
putChar(token::tokenType::UNSIGNED_INTEGER_64);
writeToBuffer(val);
return *this;
}

View File

@ -533,6 +533,52 @@ private:
static void freeCommunicatorComponents(const label index);
// Private implementation helpers
//- Test for communicator equality.
// True if they have the same index or address the same ranks
static bool sameProcs_impl(int comm1, int comm2)
{
return
(
(comm1 == comm2) ||
(
// With guard against bad index
(comm1 >= 0 && comm1 <= procIDs_.size())
&& (comm2 >= 0 && comm2 <= procIDs_.size())
&& (procIDs_[comm1] == procIDs_[comm2])
)
);
}
//- Test equality of communicator procs with the given list of ranks
template<typename IntType>
static bool sameProcs_impl
(
int communicator,
const UList<IntType>& procs
)
{
return
(
// With guard against bad index
(communicator >= 0 && communicator <= procIDs_.size())
&& ListOps::equal(procIDs_[communicator], procs)
);
}
//- Test the equality of two lists of ranks
template<typename Type1, typename Type2>
static bool sameProcs_impl
(
const UList<Type1>& procs1,
const UList<Type2>& procs2
)
{
return ListOps::equal(procs1, procs2);
}
protected:
// Protected Member Functions
@ -1061,7 +1107,7 @@ public:
//
// \param pos starting position within the internal list of requests
// \param len length of slice to remove (negative = until the end)
static void removeRequests(const label pos, label len = -1);
static void removeRequests(label pos, label len = -1);
//- Non-blocking comms: free outstanding request.
//- Corresponds to MPI_Request_free()
@ -1085,7 +1131,7 @@ public:
//
// \param pos starting position within the internal list of requests
// \param len length of slice to check (negative = until the end)
static void waitRequests(const label pos, label len = -1);
static void waitRequests(label pos, label len = -1);
//- Wait until all requests have finished.
//- Corresponds to MPI_Waitall()
@ -1103,7 +1149,7 @@ public:
//
// \param pos starting position within the internal list of requests
// \param len length of slice to check (negative = until the end)
static bool waitAnyRequest(const label pos, label len = -1);
static bool waitAnyRequest(label pos, label len = -1);
//- Wait until some requests (from position onwards) have finished.
//- Corresponds to MPI_Waitsome()
@ -1122,7 +1168,7 @@ public:
// when calling within a loop.
static bool waitSomeRequests
(
const label pos,
label pos,
label len = -1,
DynamicList<int>* indices = nullptr
);
@ -1148,7 +1194,7 @@ public:
//- Corresponds to MPI_Waitany()
// Returns -1 if parRun() == false, or the list is empty,
// or if all the requests have already been handled
static label waitAnyRequest(UList<UPstream::Request>& requests);
static int waitAnyRequest(UList<UPstream::Request>& requests);
//- Wait until request i has finished.
//- Corresponds to MPI_Wait()
@ -1162,6 +1208,14 @@ public:
// A no-op if parRun() == false or for a null-request
static void waitRequest(UPstream::Request& req);
//- Is request \p i active (!= MPI_REQUEST_NULL)?
// False if there are no pending requests,
// or if the index is out-of-range (0 to nRequests)
static bool activeRequest(const label i);
//- Is request active (!= MPI_REQUEST_NULL)?
static bool activeRequest(const UPstream::Request& req);
//- Non-blocking comms: has request i finished?
//- Corresponds to MPI_Test()
// A no-op and returns true if parRun() == false,
@ -1185,7 +1239,7 @@ public:
//
// \param pos starting position within the internal list of requests
// \param len length of slice to check (negative = until the end)
static bool finishedRequests(const label pos, label len = -1);
static bool finishedRequests(label pos, label len = -1);
//- Non-blocking comms: have all requests finished?
//- Corresponds to MPI_Testall()
@ -1291,6 +1345,43 @@ public:
}
//- Test for communicator equality.
// True if they have the same index or address the same ranks
static bool sameProcs(int communicator1, int communicator2)
{
return sameProcs_impl(communicator1, communicator2);
}
//- Test equality of communicator procs with the given list of ranks.
//- Includes a guard for the communicator index.
template
<
typename T1,
typename = std::void_t
<std::enable_if_t<std::is_integral_v<T1>>>
>
static bool sameProcs(int communicator, const UList<T1>& procs)
{
return sameProcs_impl(communicator, procs);
}
//- Test the equality of two lists of ranks
template
<
typename T1,
typename T2,
typename = std::void_t
<
std::enable_if_t<std::is_integral_v<T1>>,
std::enable_if_t<std::is_integral_v<T2>>
>
>
static bool sameProcs(const UList<T1>& procs1, const UList<T2>& procs2)
{
return sameProcs_impl(procs1, procs2);
}
// Worlds
//- All worlds
@ -1997,6 +2088,8 @@ public:
// Member Functions
// Access
//- Return raw value
value_type value() const noexcept { return value_; }
@ -2006,6 +2099,9 @@ public:
return reinterpret_cast<const void*>(value_);
}
// Query
//- True if not equal to MPI_COMM_NULL
bool good() const noexcept;
@ -2094,6 +2190,8 @@ public:
// Member Functions
// Access
//- Return raw value
value_type value() const noexcept { return value_; }
@ -2103,23 +2201,37 @@ public:
return reinterpret_cast<const void*>(value_);
}
// Basics
//- True if not equal to MPI_REQUEST_NULL
bool good() const noexcept;
//- Reset to default constructed value (MPI_REQUEST_NULL)
void reset() noexcept;
//- Same as calling UPstream::cancelRequest()
void cancel() { UPstream::cancelRequest(*this); }
//- Same as calling UPstream::freeRequest()
void free() { UPstream::freeRequest(*this); }
//- True if request is active (!= MPI_REQUEST_NULL)
//- Same as good(). Same as calling UPstream::activeRequest()
bool active() const noexcept { return good(); }
//- Same as calling UPstream::finishedRequest()
// Uses MPI_Test()
bool finished() { return UPstream::finishedRequest(*this); }
//- Same as calling UPstream::waitRequest()
//- Same as calling UPstream::waitRequest().
// Uses MPI_Wait()
void wait() { UPstream::waitRequest(*this); }
// Other
//- Same as calling UPstream::cancelRequest().
// Uses MPI_Cancel(), MPI_Request_free()
void cancel() { UPstream::cancelRequest(*this); }
//- Same as calling UPstream::freeRequest().
// Uses MPI_Request_free()
void free() { UPstream::freeRequest(*this); }
};
@ -2138,6 +2250,9 @@ Ostream& operator<<(Ostream&, const UPstream::commsStruct&);
#include "UPstreamTraits.H"
#include "UPstreamWindow.H"
// Locally include the following where required:
// - UPstreamFile.H
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository

View File

@ -343,11 +343,22 @@ void Foam::UPstream::mpiGatherv
}
// Nothing further to do
}
else if constexpr (UPstream_basic_dataType<Type>::value)
else if constexpr (UPstream_dataType<Type>::value)
{
// Restrict to basic (or aliased) MPI types to avoid recalculating
// the list of counts/offsets.
// The sizing factor (constexpr) must be 1 otherwise
// [recvCounts,recvOffsets] are likely incorrect
constexpr std::streamsize count = UPstream_dataType<Type>::size(1);
static_assert
(
(count == 1),
"Code does not (yet) work with aggregate types"
);
UPstream::mpi_gatherv
(
sendData,
@ -356,7 +367,7 @@ void Foam::UPstream::mpiGatherv
recvCounts,
recvOffsets,
UPstream_basic_dataType<Type>::datatype_id,
UPstream_dataType<Type>::datatype_id,
communicator
);
}
@ -364,7 +375,8 @@ void Foam::UPstream::mpiGatherv
{
static_assert
(
stdFoam::dependent_false_v<Type>, "Only basic MPI data types"
stdFoam::dependent_false_v<Type>,
"Only basic and user data types"
);
}
}
@ -392,11 +404,22 @@ void Foam::UPstream::mpiScatterv
}
// Nothing further to do
}
else if constexpr (UPstream_basic_dataType<Type>::value)
else if constexpr (UPstream_dataType<Type>::value)
{
// Restrict to basic (or aliased) MPI types to avoid recalculating
// the list of counts/offsets.
// The sizing factor (constexpr) must be 1 otherwise
// [sendCounts,sendOffsets] are likely incorrect
constexpr std::streamsize count = UPstream_dataType<Type>::size(1);
static_assert
(
(count == 1),
"Code does not (yet) work with aggregate types"
);
UPstream::mpi_scatterv
(
sendData,
@ -405,7 +428,7 @@ void Foam::UPstream::mpiScatterv
recvData,
recvCount,
UPstream_basic_dataType<Type>::datatype_id,
UPstream_dataType<Type>::datatype_id,
communicator
);
}
@ -413,7 +436,8 @@ void Foam::UPstream::mpiScatterv
{
static_assert
(
stdFoam::dependent_false_v<Type>, "Only basic MPI data types"
stdFoam::dependent_false_v<Type>,
"Only basic and user data types"
);
}
}

View File

@ -354,7 +354,7 @@ struct UPstream_basic_dataType
UPstream_alias_dataType<base>::datatype_id;
//- The size in terms of the number of underlying data elements
static std::streamsize size(std::streamsize n) noexcept
static constexpr std::streamsize size(std::streamsize n) noexcept
{
if constexpr (UPstream_alias_dataType<T>::value)
{
@ -373,7 +373,10 @@ struct UPstream_basic_dataType
template<> struct UPstream_basic_dataType<void> : UPstream_mpi_dataType<void>
{
using base = void;
static std::streamsize size(std::streamsize n) noexcept { return n; }
static constexpr std::streamsize size(std::streamsize n) noexcept
{
return n;
}
};
@ -410,7 +413,7 @@ struct UPstream_dataType
UPstream_any_dataType<base>::datatype_id;
//- The size in terms of the number of base data elements
static std::streamsize size(std::streamsize n) noexcept
static constexpr std::streamsize size(std::streamsize n) noexcept
{
if constexpr (UPstream_any_dataType<T>::value)
{

View File

@ -1 +0,0 @@
#warning File removed - left for old dependency check only

View File

@ -1 +0,0 @@
#warning File removed - left for old dependency check only

View File

@ -1 +0,0 @@
#warning File removed - left for old dependency check only

View File

@ -1 +0,0 @@
#warning File removed - left for old dependency check only

View File

@ -1 +0,0 @@
#warning File removed - left for old dependency check only

View File

@ -1 +0,0 @@
#warning File removed - left for old dependency check only

View File

@ -1 +0,0 @@
#warning File removed - left for old dependency check only

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2023 OpenCFD Ltd.
Copyright (C) 2017-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -714,7 +714,7 @@ Foam::Istream& Foam::ISstream::read(token& t)
case '0' : case '1' : case '2' : case '3' : case '4' :
case '5' : case '6' : case '7' : case '8' : case '9' :
{
label labelVal = (c != '.'); // used as bool here
bool isIntegral = (c != '.'); // possible integral value?
unsigned nChar = 0;
buf[nChar++] = c;
@ -725,7 +725,7 @@ Foam::Istream& Foam::ISstream::read(token& t)
(
is_.get(c)
&& (
isdigit(c)
std::isdigit(c)
|| c == '+'
|| c == '-'
|| c == '.'
@ -734,10 +734,10 @@ Foam::Istream& Foam::ISstream::read(token& t)
)
)
{
if (labelVal)
{
labelVal = isdigit(c);
}
// Silently skip "'" digit separators in numeric literals?
// Still possible as integral?
isIntegral = isIntegral && std::isdigit(c);
buf[nChar++] = c;
if (nChar == bufLen)
@ -766,23 +766,91 @@ Foam::Istream& Foam::ISstream::read(token& t)
{
is_.putback(c);
if (nChar == 1 && buf[0] == '-')
if (nChar == 1)
{
// A single '-' is punctuation
t = token::punctuationToken(token::MINUS);
}
else if (labelVal && Foam::read(buf, labelVal))
{
t = labelVal;
}
else
{
scalar scalarVal;
if (readScalar(buf, scalarVal))
// Special single char handling
switch (buf[0])
{
// A scalar or too big to fit as a label
t = scalarVal;
case '-' : // A single '-' is punctuation
{
t.pToken(token::MINUS);
break;
}
case '.' : // A single '.' is currently bad
{
t.setBad();
break;
}
default :
{
if (isIntegral)
{
// Single digit : conversion is trivial
t.int32Token(buf[0] - '0');
}
else
{
// At the moment nothing to handle here
t.setBad();
}
break;
}
}
return *this;
}
if (isIntegral)
{
// Parse as an integral?
// - read with largest resolution and narrow when possible.
// - retain (signed|unsigned) int32/int64 ...
if (int64_t val; Foam::readInt64(buf, val))
{
// Use smaller representations when possible
if (val >= INT32_MIN && val <= INT32_MAX)
{
t.int32Token(static_cast<int32_t>(val));
}
else if (val >= 0 && val <= int64_t(UINT32_MAX))
{
t.uint32Token(static_cast<uint32_t>(val));
}
else
{
t.int64Token(val);
}
}
else if (uint64_t val; Foam::readUint64(buf, val))
{
// Use smaller representations when possible
if (val <= UINT32_MAX)
{
t.uint32Token(static_cast<uint32_t>(val));
}
else
{
t.uint64Token(val);
}
}
else
{
// Fallthrough to scalar parsing
isIntegral = false;
}
}
// Floating point format or a series of digits that are too
// big to fit an integral representation
//
// - read as 'scalar' (float|double) since this is what the
// rest of the code expects to handle anyhow
if (!isIntegral)
{
if (scalar val; Foam::readScalar(buf, val))
{
t = val;
}
else
{
@ -1007,7 +1075,31 @@ Foam::Istream& Foam::ISstream::read(string& str)
}
Foam::Istream& Foam::ISstream::read(label& val)
Foam::Istream& Foam::ISstream::read(int32_t& val)
{
is_ >> val;
syncState();
return *this;
}
Foam::Istream& Foam::ISstream::read(int64_t& val)
{
is_ >> val;
syncState();
return *this;
}
Foam::Istream& Foam::ISstream::read(uint32_t& val)
{
is_ >> val;
syncState();
return *this;
}
Foam::Istream& Foam::ISstream::read(uint64_t& val)
{
is_ >> val;
syncState();

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2012 OpenFOAM Foundation
Copyright (C) 2011-2012,2024 OpenFOAM Foundation
Copyright (C) 2017-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
@ -226,8 +226,17 @@ public:
// and an embedded newline character.
virtual Istream& read(string& str) override;
//- Read a label
virtual Istream& read(label& val) override;
//- Read int32_t
virtual Istream& read(int32_t& val) override;
//- Read int64_t
virtual Istream& read(int64_t& val) override;
//- Read uint32_t
virtual Istream& read(uint32_t& val) override;
//- Read uint64_t
virtual Istream& read(uint64_t& val) override;
//- Read a float
virtual Istream& read(float& val) override;

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2011-2016,2024 OpenFOAM Foundation
Copyright (C) 2017-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
@ -218,6 +218,22 @@ Foam::Ostream& Foam::OSstream::write(const int64_t val)
}
Foam::Ostream& Foam::OSstream::write(const uint32_t val)
{
os_ << val;
syncState();
return *this;
}
Foam::Ostream& Foam::OSstream::write(const uint64_t val)
{
os_ << val;
syncState();
return *this;
}
Foam::Ostream& Foam::OSstream::write(const float val)
{
os_ << val;

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2014 OpenFOAM Foundation
Copyright (C) 2011-2014,2024 OpenFOAM Foundation
Copyright (C) 2017-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
@ -198,6 +198,12 @@ public:
//- Write int64_t
virtual Ostream& write(const int64_t val) override;
//- Write uint32_t
virtual Ostream& write(const uint32_t val) override;
//- Write uint64_t
virtual Ostream& write(const uint64_t val) override;
//- Write float
virtual Ostream& write(const float val) override;

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2014 OpenFOAM Foundation
Copyright (C) 2011-2014,2024 OpenFOAM Foundation
Copyright (C) 2020-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
@ -140,6 +140,20 @@ Foam::Ostream& Foam::prefixOSstream::write(const int64_t val)
}
Foam::Ostream& Foam::prefixOSstream::write(const uint32_t val)
{
checkWritePrefix();
return OSstream::write(val);
}
Foam::Ostream& Foam::prefixOSstream::write(const uint64_t val)
{
checkWritePrefix();
return OSstream::write(val);
}
Foam::Ostream& Foam::prefixOSstream::write(const float val)
{
checkWritePrefix();

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2014 OpenFOAM Foundation
Copyright (C) 2011-2014,2024 OpenFOAM Foundation
Copyright (C) 2020-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
@ -130,6 +130,12 @@ public:
//- Write int64_t
virtual Ostream& write(const int64_t val) override;
//- Write uint32_t
virtual Ostream& write(const uint32_t val) override;
//- Write uint64_t
virtual Ostream& write(const uint64_t val) override;
//- Write float
virtual Ostream& write(const float val) override;

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2011-2015,2024 OpenFOAM Foundation
Copyright (C) 2017-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
@ -95,10 +95,12 @@ Foam::tokenList Foam::ITstream::parse_chars
IOstreamOption streamOpt
)
{
ISpanStream is(s, nbytes, streamOpt);
tokenList tokens;
parseStream(is, tokens);
if (s && nbytes > 0) // extra safety
{
ISpanStream is(s, nbytes, streamOpt);
parseStream(is, tokens);
}
return tokens;
}
@ -107,10 +109,19 @@ Foam::tokenList Foam::ITstream::parse_chars
void Foam::ITstream::reset(const char* input, size_t nbytes)
{
ISpanStream is(input, nbytes, static_cast<IOstreamOption>(*this));
tokenList tokens;
if (input && nbytes > 0) // extra safety
{
ISpanStream is(input, nbytes, static_cast<IOstreamOption>(*this));
parseStream(is, static_cast<tokenList&>(*this));
ITstream::seek(0); // rewind() bypassing virtual
parseStream(is, static_cast<tokenList&>(*this));
ITstream::seek(0); // rewind() bypassing virtual
}
else
{
ITstream::seek(0); // rewind() bypassing virtual
tokenList::clear();
}
}
@ -248,7 +259,10 @@ Foam::ITstream::ITstream
:
ITstream(streamOpt, name)
{
reset(input, strlen(input));
if (input)
{
reset(input, strlen(input));
}
}
@ -643,7 +657,28 @@ Foam::Istream& Foam::ITstream::read(string&)
}
Foam::Istream& Foam::ITstream::read(label&)
Foam::Istream& Foam::ITstream::read(int32_t&)
{
NotImplemented;
return *this;
}
Foam::Istream& Foam::ITstream::read(int64_t&)
{
NotImplemented;
return *this;
}
Foam::Istream& Foam::ITstream::read(uint32_t&)
{
NotImplemented;
return *this;
}
Foam::Istream& Foam::ITstream::read(uint64_t&)
{
NotImplemented;
return *this;

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2011-2016,2024 OpenFOAM Foundation
Copyright (C) 2017-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
@ -77,7 +77,8 @@ class ITstream
// but leave any excess capacity (ie, like reserve).
void reserveCapacity(const label newCapacity);
//- Convert input sequence into a list of tokens,
//- Convert input sequence into a list of tokens.
// Includes nullptr guard
static tokenList parse_chars
(
const char* s,
@ -87,6 +88,7 @@ class ITstream
//- Convert input sequence into a list of tokens,
//- using the existing stream format. Rewinds the stream
// Includes nullptr guard
void reset(const char* input, size_t nbytes);
//- Failsafe read-access to token at specified location
@ -175,32 +177,6 @@ public:
reset(s.data(), s.size());
}
//- Construct token list by parsing the input character sequence
// Uses static parse function internally.
explicit ITstream
(
stdFoam::span<char> s,
IOstreamOption streamOpt = IOstreamOption()
)
:
ITstream(streamOpt)
{
reset(s.data(), s.size());
}
//- Construct token list by parsing the input character sequence
// Uses static parse function internally.
explicit ITstream
(
stdFoam::span<const char> s,
IOstreamOption streamOpt = IOstreamOption()
)
:
ITstream(streamOpt)
{
reset(s.data(), s.size());
}
// Additional constructors
@ -255,17 +231,6 @@ public:
return parse_chars(input.cdata(), input.size(), streamOpt);
}
//- Create token list by parsing the input string
//- until no good tokens remain.
static tokenList parse
(
const std::string& input,
IOstreamOption streamOpt = IOstreamOption()
)
{
return parse_chars(input.data(), input.size(), streamOpt);
}
//- Create token list by parsing the input character sequence
//- until no good tokens remain.
static tokenList parse
@ -274,7 +239,14 @@ public:
IOstreamOption streamOpt = IOstreamOption()
)
{
return parse_chars(input, strlen(input), streamOpt);
if (input)
{
return parse_chars(input, strlen(input), streamOpt);
}
else
{
return tokenList();
}
}
//- Create token list by parsing the input character sequence
@ -288,28 +260,6 @@ public:
return parse_chars(s.data(), s.size(), streamOpt);
}
//- Create token list by parsing the input character sequence
//- until no good tokens remain.
static tokenList parse
(
stdFoam::span<char> s,
IOstreamOption streamOpt = IOstreamOption()
)
{
return parse_chars(s.data(), s.size(), streamOpt);
}
//- Create token list by parsing the input character sequence
//- until no good tokens remain.
static tokenList parse
(
stdFoam::span<const char> s,
IOstreamOption streamOpt = IOstreamOption()
)
{
return parse_chars(s.data(), s.size(), streamOpt);
}
// Member Functions
@ -387,7 +337,7 @@ public:
label& tokenIndex() noexcept { return tokenIndex_; }
//- Set the token index (no checks). \return the previous value
label tokenIndex(const label num) noexcept
label tokenIndex(label num) noexcept
{
label old(tokenIndex_);
tokenIndex_ = num;
@ -509,8 +459,17 @@ public:
//- triggers not implemented error
virtual Istream& read(string&) override;
//- Read a label : triggers not implemented error
virtual Istream& read(label&) override;
//- Read int32_t : triggers not implemented error
virtual Istream& read(int32_t&) override;
//- Read int64_t : triggers not implemented error
virtual Istream& read(int64_t&) override;
//- Read uint32_t : triggers not implemented error
virtual Istream& read(uint32_t&) override;
//- Read uint64_t : triggers not implemented error
virtual Istream& read(uint64_t&) override;
//- Read a float : triggers not implemented error
virtual Istream& read(float&) override;

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2023 OpenCFD Ltd.
Copyright (C) 2019-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -65,7 +65,7 @@ Foam::Ostream& Foam::OTstream::writeQuoted
if (quoted)
{
// tokenType::STRING
tokens().emplace_back() = string(str, len);
tokens().emplace_back() = Foam::string(str, len);
}
else if (len > 0)
{
@ -120,7 +120,7 @@ Foam::Ostream& Foam::OTstream::write(const std::string& str)
Foam::Ostream& Foam::OTstream::write(const int32_t val)
{
tokens().push_back(token(label(val))); // tokenType::LABEL
tokens().emplace_back().int32Token(val);
return *this;
}
@ -128,24 +128,36 @@ Foam::Ostream& Foam::OTstream::write(const int32_t val)
Foam::Ostream& Foam::OTstream::write(const int64_t val)
{
tokens().push_back(token(label(val))); // tokenType::LABEL
tokens().emplace_back().int64Token(val);
return *this;
}
Foam::Ostream& Foam::OTstream::write(const uint32_t val)
{
tokens().emplace_back().uint32Token(val);
return *this;
}
Foam::Ostream& Foam::OTstream::write(const uint64_t val)
{
tokens().emplace_back().uint64Token(val);
return *this;
}
Foam::Ostream& Foam::OTstream::write(const float val)
{
tokens().push_back(token(val)); // tokenType::FLOAT
tokens().emplace_back().floatToken(val);
return *this;
}
Foam::Ostream& Foam::OTstream::write(const double val)
{
tokens().push_back(token(val)); // tokenType::DOUBLE
tokens().emplace_back().doubleToken(val);
return *this;
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2024 OpenCFD Ltd.
Copyright (C) 2019-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -137,12 +137,18 @@ public:
//- Write string
virtual Ostream& write(const std::string& str) override;
//- Write int32_t as a label
//- Write int32_t
virtual Ostream& write(const int32_t val) override;
//- Write int64_t as a label
//- Write int64_t
virtual Ostream& write(const int64_t val) override;
//- Write uint32_t
virtual Ostream& write(const uint32_t val) override;
//- Write uint64_t
virtual Ostream& write(const uint64_t val) override;
//- Write float
virtual Ostream& write(const float val) override;

View File

@ -128,8 +128,29 @@ public:
return *this;
}
//- Read a label
virtual Istream& read(label&) override
//- Read int32_t
virtual Istream& read(int32_t&) override
{
NotImplemented;
return *this;
}
//- Read int64_t
virtual Istream& read(int64_t&) override
{
NotImplemented;
return *this;
}
//- Read uint32_t
virtual Istream& read(uint32_t&) override
{
NotImplemented;
return *this;
}
//- Read uint64_t
virtual Istream& read(uint64_t&) override
{
NotImplemented;
return *this;

View File

@ -123,20 +123,6 @@ public:
stream_type(static_cast<buffer_type*>(this))
{}
//- Construct (shallow copy) from span character content
explicit ispanstream(stdFoam::span<char> s)
:
buffer_type(const_cast<char*>(s.data()), s.size()),
stream_type(static_cast<buffer_type*>(this))
{}
//- Construct (shallow copy) from span character content
explicit ispanstream(stdFoam::span<const char> s)
:
buffer_type(const_cast<char*>(s.data()), s.size()),
stream_type(static_cast<buffer_type*>(this))
{}
// Member Functions
@ -325,26 +311,6 @@ public:
ISpanStream(buffer.cdata(), buffer.size(), streamOpt)
{}
//- Construct (shallow copy) from span character content
explicit ISpanStream
(
stdFoam::span<const char> s,
IOstreamOption streamOpt = IOstreamOption()
)
:
ISpanStream(s.data(), s.size(), streamOpt)
{}
//- Construct (shallow copy) from span character content
explicit ISpanStream
(
stdFoam::span<char> s,
IOstreamOption streamOpt = IOstreamOption()
)
:
ISpanStream(s.data(), s.size(), streamOpt)
{}
// Member Functions
@ -402,20 +368,6 @@ public:
syncState();
}
//- Reset input area to use data from span character content
void reset(stdFoam::span<char> s)
{
stream_.reset(s.data(), s.size());
syncState();
}
//- Reset input area to use data from span character content
void reset(stdFoam::span<const char> s)
{
stream_.reset(s.data(), s.size());
syncState();
}
//- Rewind the stream, clearing any old errors
virtual void rewind() override
{

View File

@ -38,6 +38,7 @@ Description
#include "DynamicList.H"
#include <memory>
#include <string_view>
#include <string>
#include <type_traits>
@ -488,7 +489,7 @@ public:
if (data && (count > 0) && in_range(pos))
{
// Restrict to intersection with current content
if (span_tellp() <= std::streampos(pos+count))
if (span_tellp() <= pos+std::streampos(count))
{
count = (span_tellp() - pos);
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2011-2016,2024 OpenFOAM Foundation
Copyright (C) 2017-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
@ -30,6 +30,10 @@ Class
Description
A token holds an item read from Istream.
Note
Use boolean() static method for creating a \b bool token
since \c bool and \c int are otherwise indistinguishable
SourceFiles
tokenI.H
token.C
@ -84,7 +88,10 @@ public:
FLAG, //!< stream flag (1-byte bitmask)
PUNCTUATION, //!< single character punctuation
BOOL, //!< boolean type
LABEL, //!< label (integer) type
INTEGER_32, //!< int32 type
INTEGER_64, //!< int64 type
UNSIGNED_INTEGER_32, //!< uint32 type
UNSIGNED_INTEGER_64, //!< uint64 type
FLOAT, //!< float (single-precision) type
DOUBLE, //!< double (double-precision) type
@ -107,7 +114,13 @@ public:
// Aliases
FLOAT_SCALAR = FLOAT, //!< compatibility name for FLOAT
DOUBLE_SCALAR = DOUBLE, //!< compatibility name for DOUBLE
VERBATIMSTRING = VERBATIM //!< compatibility name for VERBATIM
VERBATIMSTRING = VERBATIM, //!< compatibility name for VERBATIM
#if (WM_LABEL_SIZE == 64)
LABEL = INTEGER_64, //!< compatibility name
#else
LABEL = INTEGER_32, //!< compatibility name
#endif
};
@ -463,10 +476,11 @@ private:
// Fundamental values. Largest first for any {} initialization.
int64_t int64Val;
int32_t int32Val;
uint64_t uint64Val;
uint32_t uint32Val;
int flagVal; // bitmask - stored as int, not enum
punctuationToken punctuationVal;
label labelVal;
float floatVal;
double doubleVal;
@ -495,12 +509,23 @@ private:
//- Set as UNDEFINED and zero the union content without any checking
inline void setUndefined() noexcept;
//- True if token type corresponds to WORD or WORD-variant.
//- Token type corresponds to (int32, uint32, ...)
inline static bool is_integerToken(tokenType tokType) noexcept;
//- Token type corresponds to WORD or WORD-variant.
inline static bool is_wordToken(tokenType tokType) noexcept;
//- True if token type corresponds to STRING or STRING-variant
//- Token type corresponds to STRING or STRING-variant
inline static bool is_stringToken(tokenType tokType) noexcept;
//- Return integral type or emit parseError
template<class Type>
inline Type getIntegral(const char* expected) const;
//- Return integral/floating-point type or emit parseError
template<class Type>
inline Type getArithmetic(const char* expected) const;
// Parse error, expected 'expected', found ...
void parseError(const char* expected) const;
@ -527,16 +552,23 @@ public:
//- Construct punctuation character token
inline explicit token(punctuationToken p, label lineNum=0) noexcept;
//- Construct label token
//- \note Use boolean() static method for creating a \b bool token
//- since \c bool and \c int are otherwise indistinguishable
inline explicit token(const label val, label lineNum=0) noexcept;
//- Construct 32-bit integer token
inline explicit token(int32_t val, label lineNum=0) noexcept;
//- Construct 64-bit integer token
inline explicit token(int64_t val, label lineNum=0) noexcept;
//- Construct unsigned 32-bit integer token
inline explicit token(uint32_t val, label lineNum=0) noexcept;
//- Construct unsigned 64-bit integer token
inline explicit token(uint64_t val, label lineNum=0) noexcept;
//- Construct float token
inline explicit token(const float val, label lineNum=0) noexcept;
inline explicit token(float val, label lineNum=0) noexcept;
//- Construct double token
inline explicit token(const double val, label lineNum=0) noexcept;
inline explicit token(double val, label lineNum=0) noexcept;
//- Copy construct word token
inline explicit token(const word& w, label lineNum=0);
@ -640,15 +672,33 @@ public:
inline bool isPunctuation() const noexcept;
//- True if token is PUNCTUATION and equal to parameter
inline bool isPunctuation(const punctuationToken p) const noexcept;
inline bool isPunctuation(punctuationToken p) const noexcept;
//- Token is PUNCTUATION and isseparator
inline bool isSeparator() const noexcept;
//- Token is LABEL
//- Token is (int32 | int64 | uint32 | uint64)
inline bool isIntType() const noexcept;
//- Token is INTEGER_32 or is convertible to one
inline bool is_int32() const noexcept;
//- Token is INTEGER_64 or is convertible to one
inline bool is_int64() const noexcept;
//- Token is UNSIGNED_INTEGER_32 or is convertible to one
inline bool is_uint32() const noexcept;
//- Token is UNSIGNED_INTEGER_64 or is convertible to one
inline bool is_uint64() const noexcept;
//- Integral token is convertible to Foam::label
inline bool isLabel() const noexcept;
//- True if token is LABEL and equal to parameter
//- Integral token is convertible to Foam::uLabel
inline bool isULabel() const noexcept;
//- True if token is integer type and equal to parameter
inline bool isLabel(const label value) const noexcept;
//- Token is FLOAT
@ -660,7 +710,7 @@ public:
//- Token is FLOAT or DOUBLE
inline bool isScalar() const noexcept;
//- Token is LABEL, FLOAT or DOUBLE
//- Token is (signed/unsigned) integer type, FLOAT or DOUBLE
inline bool isNumber() const noexcept;
//- Token is word-variant (WORD, DIRECTIVE)
@ -729,23 +779,55 @@ public:
inline punctuationToken pToken() const;
//- Assign to a punctuation token
inline void pToken(const punctuationToken p);
inline void pToken(punctuationToken p);
//- Return label value.
// Report FatalIOError and return \b 0 if token is not LABEL
//- Return int32 value, convert from other integer type or Error
inline int32_t int32Token() const;
//- Assign a int32 value token
inline void int32Token(int32_t val);
//- Return int64 value, convert from other integer type or Error
inline int64_t int64Token() const;
//- Assign a int64 value token
inline void int64Token(int64_t val);
//- Return int32 value, convert from other integer type or Error
inline uint32_t uint32Token() const;
//- Assign a uint32 value token
inline void uint32Token(uint32_t val);
//- Return int64 value, convert from other integer type or Error
inline uint64_t uint64Token() const;
//- Assign a uint64 value token
inline void uint64Token(uint64_t val);
//- Return integer type as label value or Error
inline label labelToken() const;
//- Assign to a label token
//- Return integer type as uLabel value or Error
inline uLabel uLabelToken() const;
//- Assign to a label (int32 or int64) token
inline void labelToken(const label val);
//- Return float value.
// Report FatalIOError and return \b 0 if token is not FLOAT
inline float floatToken() const;
//- Assign to a float token
inline void floatToken(const float val);
//- Return double value.
// Report FatalIOError and return \b 0 if token is not DOUBLE
inline double doubleToken() const;
//- Assign to a double token
inline void doubleToken(const double val);
//- Return float or double value.
// Report FatalIOError and return \b 0 if token is not a
// FLOAT or DOUBLE
@ -753,7 +835,7 @@ public:
//- Return label, float or double value.
// Report FatalIOError and return \b 0 if token is not a
// LABEL, FLOAT or DOUBLE
// an integer type, FLOAT or DOUBLE
inline scalar number() const;
//- Return const reference to the word contents.
@ -841,14 +923,23 @@ public:
//- Copy assign from punctuation
inline void operator=(const punctuationToken p);
//- Copy assign from label
inline void operator=(const label val);
//- Copy assign from int32_t
inline void operator=(int32_t val);
//- Copy assign from int64_t
inline void operator=(int64_t val);
//- Copy assign from uint32_t
inline void operator=(uint32_t val);
//- Copy assign from uint64_t
inline void operator=(uint64_t val);
//- Copy assign from float
inline void operator=(const float val);
inline void operator=(float val);
//- Copy assign from double
inline void operator=(const double val);
inline void operator=(double val);
//- Copy assign from word content
inline void operator=(const word& w);
@ -873,20 +964,29 @@ public:
inline bool operator==(const token& tok) const;
inline bool operator==(const punctuationToken p) const noexcept;
inline bool operator==(const label val) const noexcept;
inline bool operator==(const int32_t val) const noexcept;
inline bool operator==(const int64_t val) const noexcept;
inline bool operator==(const uint32_t val) const noexcept;
inline bool operator==(const uint64_t val) const noexcept;
inline bool operator==(const float val) const noexcept;
inline bool operator==(const double val) const noexcept;
inline bool operator==(const std::string& s) const;
inline bool operator==(const std::string&) const;
// Inequality
inline bool operator!=(const token& tok) const;
inline bool operator!=(const punctuationToken p) const noexcept;
inline bool operator!=(const label val) const noexcept;
inline bool operator!=(const float val) const noexcept;
inline bool operator!=(const double val) const noexcept;
inline bool operator!=(const std::string& s) const;
bool operator!=(const token& t) const { return !operator==(t); }
bool operator!=(punctuationToken p) const noexcept
{
return !operator==(p);
}
bool operator!=(int32_t b) const noexcept { return !operator==(b); }
bool operator!=(int64_t b) const noexcept { return !operator==(b); }
bool operator!=(uint32_t b) const noexcept { return !operator==(b); }
bool operator!=(uint64_t b) const noexcept { return !operator==(b); }
bool operator!=(float b) const noexcept { return !operator==(b); }
bool operator!=(double b) const noexcept { return !operator==(b); }
bool operator!=(const std::string& s) const { return !operator==(s); }
// IOstream Operators
@ -907,11 +1007,11 @@ public:
//- Token is FLOAT
// \deprecated(2020-01) - isFloat()
bool isFloatScalar() const { return isFloat(); };
bool isFloatScalar() const noexcept { return isFloat(); };
//- Token is DOUBLE
// \deprecated(2020-01) - isDouble()
bool isDoubleScalar() const { return isDouble(); }
bool isDoubleScalar() const noexcept { return isDouble(); }
//- Return float value.
// \deprecated(2020-01) - floatToken()

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2011-2016,2024 OpenFOAM Foundation
Copyright (C) 2017-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
@ -34,7 +34,7 @@ inline Foam::token Foam::token::boolean(bool on) noexcept
{
token tok;
tok.type_ = tokenType::BOOL;
tok.data_.labelVal = on;
tok.data_.flagVal = on;
return tok;
}
@ -50,6 +50,18 @@ inline Foam::token Foam::token::flag(int bitmask) noexcept
}
inline bool Foam::token::is_integerToken(tokenType tokType) noexcept
{
return
(
tokType == tokenType::INTEGER_32
|| tokType == tokenType::INTEGER_64
|| tokType == tokenType::UNSIGNED_INTEGER_32
|| tokType == tokenType::UNSIGNED_INTEGER_64
);
}
inline bool Foam::token::is_wordToken(tokenType tokType) noexcept
{
return
@ -115,6 +127,41 @@ inline void Foam::token::setUndefined() noexcept
}
// inline bool Foam::token:is_pointer() const noexcept
// {
// return (isWord() || isString() || isCompound());
// }
template<class Type>
inline Type Foam::token::getIntegral(const char* expected) const
{
switch (type_)
{
case tokenType::INTEGER_32 : return data_.int32Val;
case tokenType::INTEGER_64 : return data_.int64Val;
case tokenType::UNSIGNED_INTEGER_32 : return data_.uint32Val;
case tokenType::UNSIGNED_INTEGER_64 : return data_.uint64Val;
default: parseError(expected); return 0;
}
}
template<class Type>
inline Type Foam::token::getArithmetic(const char* expected) const
{
switch (type_)
{
case tokenType::INTEGER_32 : return data_.int32Val;
case tokenType::INTEGER_64 : return data_.int64Val;
case tokenType::UNSIGNED_INTEGER_32 : return data_.uint32Val;
case tokenType::UNSIGNED_INTEGER_64 : return data_.uint64Val;
case tokenType::FLOAT : return data_.floatVal;
case tokenType::DOUBLE : return data_.doubleVal;
default: parseError(expected); return 0;
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
inline constexpr Foam::token::token() noexcept
@ -190,17 +237,47 @@ inline Foam::token::token(punctuationToken p, label lineNum) noexcept
}
inline Foam::token::token(const label val, label lineNum) noexcept
inline Foam::token::token(int32_t val, label lineNum) noexcept
:
data_(),
type_(tokenType::LABEL),
type_(tokenType::INTEGER_32),
line_(lineNum)
{
data_.labelVal = val;
data_.int32Val = val;
}
inline Foam::token::token(const float val, label lineNum) noexcept
inline Foam::token::token(int64_t val, label lineNum) noexcept
:
data_(),
type_(tokenType::INTEGER_64),
line_(lineNum)
{
data_.int64Val = val;
}
inline Foam::token::token(uint32_t val, label lineNum) noexcept
:
data_(),
type_(tokenType::UNSIGNED_INTEGER_32),
line_(lineNum)
{
data_.uint32Val = val;
}
inline Foam::token::token(uint64_t val, label lineNum) noexcept
:
data_(),
type_(tokenType::UNSIGNED_INTEGER_64),
line_(lineNum)
{
data_.uint64Val = val;
}
inline Foam::token::token(float val, label lineNum) noexcept
:
data_(),
type_(tokenType::FLOAT),
@ -210,7 +287,7 @@ inline Foam::token::token(const float val, label lineNum) noexcept
}
inline Foam::token::token(const double val, label lineNum) noexcept
inline Foam::token::token(double val, label lineNum) noexcept
:
data_(),
type_(tokenType::DOUBLE),
@ -425,13 +502,13 @@ inline bool Foam::token::setType(token::tokenType tokType) noexcept
switch (tokType)
{
case tokenType::FLAG:
case tokenType::BOOL:
case tokenType::LABEL:
{
switch (type_)
{
case tokenType::FLAG:
case tokenType::BOOL:
case tokenType::LABEL:
type_ = tokType;
return true;
break;
@ -537,9 +614,13 @@ inline bool Foam::token::isBool() const noexcept
inline bool Foam::token::boolToken() const
{
if (type_ == tokenType::BOOL || type_ == tokenType::LABEL)
if (type_ == tokenType::BOOL)
{
return data_.labelVal;
return data_.flagVal;
}
else if (type_ == tokenType::INTEGER_32)
{
return data_.int32Val;
}
parseError("bool");
@ -551,7 +632,7 @@ inline void Foam::token::boolToken(bool on)
{
reset();
type_ = tokenType::BOOL;
data_.labelVal = on;
data_.flagVal = on;
}
@ -579,7 +660,7 @@ inline bool Foam::token::isPunctuation() const noexcept
}
inline bool Foam::token::isPunctuation(const punctuationToken p) const noexcept
inline bool Foam::token::isPunctuation(punctuationToken p) const noexcept
{
return
(
@ -606,12 +687,12 @@ inline Foam::token::punctuationToken Foam::token::pToken() const
return data_.punctuationVal;
}
parseError("punctuation character");
parseError("punctuation");
return punctuationToken::NULL_TOKEN;
}
inline void Foam::token::pToken(const punctuationToken p)
inline void Foam::token::pToken(punctuationToken p)
{
reset();
type_ = tokenType::PUNCTUATION;
@ -619,57 +700,224 @@ inline void Foam::token::pToken(const punctuationToken p)
}
inline bool Foam::token::isLabel() const noexcept
inline bool Foam::token::isIntType() const noexcept
{
return
return is_integerToken(type_);
}
// inline bool Foam::token::isSignedIntType() const noexcept
// {
// return
// (
// (type_ == tokenType::INTEGER_32)
// || (type_ == tokenType::INTEGER_64)
// );
// }
//
//
// inline bool Foam::token::isUnsignedIntType() const noexcept
// {
// return
// (
// (type_ == tokenType::UNSIGNED_INTEGER_32)
// || (type_ == tokenType::UNSIGNED_INTEGER_64)
// );
// }
inline bool Foam::token::is_int32() const noexcept
{
return (type_ == tokenType::INTEGER_32) ||
(
type_ == tokenType::LABEL
// FUTURE?
// || type_ == tokenType::INT32
// || type_ == tokenType::INT64
(type_ == tokenType::INTEGER_64)
? (data_.int64Val >= INT32_MIN && data_.int64Val <= INT32_MAX)
: (type_ == tokenType::UNSIGNED_INTEGER_32)
? (data_.uint32Val <= INT32_MAX)
:
(
type_ == tokenType::UNSIGNED_INTEGER_64
&& data_.uint64Val <= INT32_MAX
)
);
}
inline bool Foam::token::isLabel(const label value) const noexcept
inline int32_t Foam::token::int32Token() const
{
// FUTURE?
// return
// (
// type_ == tokenType::LABEL
// ? value == data_.labelVal
// : type_ == tokenType::INT32
// ? value == data_.int32Val
// : type_ == tokenType::INT64
// ? value == data_.int64Val
// : false
// );
return getIntegral<int32_t>("int32");
}
inline void Foam::token::int32Token(int32_t val)
{
reset();
type_ = tokenType::INTEGER_32;
data_.int32Val = val;
}
inline bool Foam::token::is_int64() const noexcept
{
return (type_ == tokenType::INTEGER_64) ||
(
(type_ == tokenType::INTEGER_32)
|| (type_ == tokenType::UNSIGNED_INTEGER_32)
|| (
type_ == tokenType::UNSIGNED_INTEGER_64
&& data_.uint64Val <= INT64_MAX
)
);
}
inline int64_t Foam::token::int64Token() const
{
return getIntegral<int64_t>("int64");
}
inline void Foam::token::int64Token(int64_t val)
{
reset();
type_ = tokenType::INTEGER_64;
data_.int64Val = val;
}
inline bool Foam::token::is_uint32() const noexcept
{
return (type_ == tokenType::UNSIGNED_INTEGER_32) ||
(
(type_ == tokenType::INTEGER_32)
? (data_.int32Val >= 0)
: (type_ == tokenType::INTEGER_64)
? (data_.int64Val >= 0 && data_.int64Val <= UINT32_MAX)
:
(
type_ == tokenType::UNSIGNED_INTEGER_64
&& data_.uint64Val <= UINT32_MAX
)
);
}
inline uint32_t Foam::token::uint32Token() const
{
return getIntegral<uint32_t>("uint32");
}
inline void Foam::token::uint32Token(uint32_t val)
{
reset();
type_ = tokenType::UNSIGNED_INTEGER_32;
data_.uint32Val = val;
}
inline bool Foam::token::is_uint64() const noexcept
{
return
(
type_ == tokenType::LABEL
&& value == data_.labelVal
(
type_ == tokenType::UNSIGNED_INTEGER_32
|| type_ == tokenType::UNSIGNED_INTEGER_64
)
||
(
(type_ == tokenType::INTEGER_32) ? (data_.int32Val >= 0)
: (type_ == tokenType::INTEGER_64 && data_.int64Val >= 0)
)
);
}
inline uint64_t Foam::token::uint64Token() const
{
return getIntegral<uint64_t>("uint64");
}
inline void Foam::token::uint64Token(uint64_t val)
{
reset();
type_ = tokenType::UNSIGNED_INTEGER_64;
data_.uint64Val = val;
}
inline bool Foam::token::isLabel() const noexcept
{
if constexpr (sizeof(Foam::label) == sizeof(int32_t))
{
return is_int32();
}
else
{
return is_int64();
}
}
inline bool Foam::token::isULabel() const noexcept
{
if constexpr (sizeof(Foam::label) == sizeof(int32_t))
{
return is_uint32();
}
else
{
return is_uint64();
}
}
inline Foam::label Foam::token::labelToken() const
{
if (type_ == tokenType::LABEL)
{
return data_.labelVal;
}
return getIntegral<label>("label");
}
parseError("label");
return 0;
inline Foam::uLabel Foam::token::uLabelToken() const
{
return getIntegral<uLabel>("uLabel");
}
inline bool Foam::token::isLabel(const label value) const noexcept
{
return
(
(type_ == tokenType::INTEGER_32)
? (value == data_.int32Val)
: (type_ == tokenType::INTEGER_64)
? (value == data_.int64Val)
: (type_ == tokenType::UNSIGNED_INTEGER_32)
? (value >= 0 && uint32_t(value) == data_.uint32Val)
:
(
(type_ == tokenType::UNSIGNED_INTEGER_64)
&& (value >= 0 && uint64_t(value) == data_.uint64Val)
)
);
}
inline void Foam::token::labelToken(const label val)
{
reset();
type_ = tokenType::LABEL;
data_.labelVal = val;
if constexpr (sizeof(Foam::label) == sizeof(int32_t))
{
reset();
type_ = tokenType::INTEGER_32;
data_.int32Val = val;
}
else
{
reset();
type_ = tokenType::INTEGER_64;
data_.int64Val = val;
}
}
@ -685,9 +933,18 @@ inline float Foam::token::floatToken() const
{
return data_.floatVal;
}
else
{
parseError("float"); return 0;
}
}
parseError("float");
return 0;
inline void Foam::token::floatToken(const float val)
{
reset();
type_ = tokenType::FLOAT;
data_.floatVal = val;
}
@ -703,9 +960,18 @@ inline double Foam::token::doubleToken() const
{
return data_.doubleVal;
}
else
{
parseError("double"); return 0;
}
}
parseError("double");
return 0;
inline void Foam::token::doubleToken(const double val)
{
reset();
type_ = tokenType::DOUBLE;
data_.doubleVal = val;
}
@ -721,39 +987,24 @@ inline bool Foam::token::isScalar() const noexcept
inline Foam::scalar Foam::token::scalarToken() const
{
if (type_ == tokenType::FLOAT)
switch (type_)
{
return data_.floatVal;
case tokenType::FLOAT : return data_.floatVal;
case tokenType::DOUBLE : return data_.doubleVal;
default: parseError("scalar"); return 0;
}
else if (type_ == tokenType::DOUBLE)
{
return data_.doubleVal;
}
parseError("scalar");
return 0;
}
inline bool Foam::token::isNumber() const noexcept
{
return (isLabel() || isScalar());
return (is_integerToken(type_) || isScalar());
}
inline Foam::scalar Foam::token::number() const
{
if (isLabel())
{
return labelToken();
}
if (isScalar())
{
return scalarToken();
}
parseError("number (label or scalar)");
return 0;
return getArithmetic<scalar>("number (label or scalar)");
}
@ -934,15 +1185,15 @@ inline Type& Foam::token::transferCompoundToken(const Istream& is)
}
template<class T>
Foam::token::tokenType Foam::token::Compound<T>::typeCode() const
template<class Type>
Foam::token::tokenType Foam::token::Compound<Type>::typeCode() const
{
// Does not cover all possibilities perfectly, but should handle
// most of the common ones (bool, label, scalar, vector lists).
// Something like List<edge> will not be quite correct if we rely
// on nComponents
typedef typename T::value_type valueType;
typedef typename Type::value_type valueType;
if constexpr (std::is_same_v<bool, valueType>)
{
@ -952,26 +1203,26 @@ Foam::token::tokenType Foam::token::Compound<T>::typeCode() const
else if constexpr (is_contiguous_label<valueType>::value)
{
// List<label>, List<labelVector> etc
return token::tokenType::LABEL;
// FUTURE?
// return
// (
// sizeof(int32_t) == sizeof(Foam::label)
// ? token::tokenType::INT32
// : token::tokenType::INT64
// );
if constexpr (sizeof(Foam::label) == sizeof(int32_t))
{
return token::tokenType::INTEGER_32;
}
else
{
return token::tokenType::INTEGER_64;
}
}
else if constexpr (is_contiguous_scalar<valueType>::value)
{
// List<scalar>, List<vector>, List<tensor> etc
return
(
sizeof(float) == sizeof(Foam::scalar)
? token::tokenType::FLOAT
: token::tokenType::DOUBLE
);
if constexpr (sizeof(Foam::scalar) == sizeof(float))
{
return token::tokenType::FLOAT;
}
else
{
return token::tokenType::DOUBLE;
}
}
else if constexpr (std::is_same_v<char, valueType>)
{
@ -1059,9 +1310,35 @@ inline void Foam::token::operator=(const punctuationToken p)
}
inline void Foam::token::operator=(const label val)
inline void Foam::token::operator=(const int32_t val)
{
token::labelToken(val);
reset();
type_ = tokenType::INTEGER_32;
data_.int32Val = val;
}
inline void Foam::token::operator=(const int64_t val)
{
reset();
type_ = tokenType::INTEGER_64;
data_.int64Val = val;
}
inline void Foam::token::operator=(const uint32_t val)
{
reset();
type_ = tokenType::UNSIGNED_INTEGER_32;
data_.uint32Val = val;
}
inline void Foam::token::operator=(const uint64_t val)
{
reset();
type_ = tokenType::UNSIGNED_INTEGER_64;
data_.uint64Val = val;
}
@ -1142,7 +1419,7 @@ inline bool Foam::token::operator==(const token& tok) const
return true;
case tokenType::BOOL:
return data_.labelVal == tok.data_.labelVal;
return data_.flagVal == tok.data_.flagVal;
case tokenType::FLAG:
return data_.flagVal == tok.data_.flagVal;
@ -1150,8 +1427,17 @@ inline bool Foam::token::operator==(const token& tok) const
case tokenType::PUNCTUATION:
return data_.punctuationVal == tok.data_.punctuationVal;
case tokenType::LABEL:
return data_.labelVal == tok.data_.labelVal;
case tokenType::INTEGER_32 :
return data_.int32Val == tok.data_.int32Val;
case tokenType::INTEGER_64 :
return data_.int64Val == tok.data_.int64Val;
case tokenType::UNSIGNED_INTEGER_32 :
return data_.uint64Val == tok.data_.uint64Val;
case tokenType::UNSIGNED_INTEGER_64 :
return data_.uint64Val == tok.data_.uint64Val;
case tokenType::FLOAT:
return equal(data_.floatVal, tok.data_.floatVal);
@ -1200,9 +1486,43 @@ inline bool Foam::token::operator==(const std::string& s) const
}
inline bool Foam::token::operator==(const label val) const noexcept
inline bool Foam::token::operator==(const int32_t val) const noexcept
{
return isLabel(val);
return
(
type_ == tokenType::INTEGER_32
&& data_.int32Val == val
);
}
inline bool Foam::token::operator==(const int64_t val) const noexcept
{
return
(
type_ == tokenType::INTEGER_64
&& data_.int64Val == val
);
}
inline bool Foam::token::operator==(const uint32_t val) const noexcept
{
return
(
type_ == tokenType::UNSIGNED_INTEGER_32
&& data_.uint32Val == val
);
}
inline bool Foam::token::operator==(const uint64_t val) const noexcept
{
return
(
type_ == tokenType::UNSIGNED_INTEGER_64
&& data_.uint64Val == val
);
}
@ -1226,40 +1546,4 @@ inline bool Foam::token::operator==(const double val) const noexcept
}
inline bool Foam::token::operator!=(const token& tok) const
{
return !operator==(tok);
}
inline bool Foam::token::operator!=(const punctuationToken p) const noexcept
{
return !isPunctuation(p);
}
inline bool Foam::token::operator!=(const label val) const noexcept
{
return !operator==(val);
}
inline bool Foam::token::operator!=(const float val) const noexcept
{
return !operator==(val);
}
inline bool Foam::token::operator!=(const double val) const noexcept
{
return !operator==(val);
}
inline bool Foam::token::operator!=(const std::string& s) const
{
return !operator==(s);
}
// ************************************************************************* //

View File

@ -57,16 +57,20 @@ static OS& printTokenInfo(OS& os, const token& tok)
os << "punctuation '" << tok.pToken() << '\'';
break;
// case token::tokenType::INT32:
// os << "int32 " << tok.int32Token();
// break;
//
// case token::tokenType::INT64:
// os << "int64 " << tok.int64Token();
// break;
case token::tokenType::INTEGER_32:
os << "int32 " << tok.int32Token();
break;
case token::tokenType::LABEL:
os << "label " << tok.labelToken();
case token::tokenType::INTEGER_64:
os << "int64 " << tok.int64Token();
break;
case token::tokenType::UNSIGNED_INTEGER_32:
os << "uint32 " << tok.uint32Token();
break;
case token::tokenType::UNSIGNED_INTEGER_64:
os << "uint64 " << tok.uint64Token();
break;
case token::tokenType::FLOAT:
@ -168,9 +172,10 @@ Foam::word Foam::token::name(const token::tokenType tokType)
case token::tokenType::FLAG: return "flag";
case token::tokenType::PUNCTUATION: return "punctuation";
// case token::tokenType::INT32: return "int32";
// case token::tokenType::INT64: return "int64";
case token::tokenType::LABEL: return "label";
case token::tokenType::INTEGER_32: return "int32";
case token::tokenType::INTEGER_64: return "int64";
case token::tokenType::UNSIGNED_INTEGER_32: return "uint32";
case token::tokenType::UNSIGNED_INTEGER_64: return "uint64";
case token::tokenType::FLOAT: return "float";
case token::tokenType::DOUBLE: return "double";
case token::tokenType::WORD: return "word";
@ -219,8 +224,23 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const token& tok)
break;
case token::tokenType::BOOL:
case token::tokenType::LABEL:
os << tok.data_.labelVal;
os << tok.data_.flagVal; // An int value
break;
case token::tokenType::INTEGER_32:
os << tok.data_.int32Val;
break;
case token::tokenType::INTEGER_64:
os << tok.data_.int64Val;
break;
case token::tokenType::UNSIGNED_INTEGER_32:
os << tok.data_.uint32Val;
break;
case token::tokenType::UNSIGNED_INTEGER_64:
os << tok.data_.uint64Val;
break;
case token::tokenType::FLOAT:

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