Compare commits

...

11 Commits

Author SHA1 Message Date
460f1478be ENH: radiometerProbes: new function object to monitor radiative heat flux at internal points
The radiometer probes enable measurement of incident radiative heat flux
at arbitrary internal points within the domain, useful for radiation sensor
simulation and heat transfer analysis in participating media applications.
2025-10-23 10:15:09 +01:00
29813b0e96 ENH: probes: refactor probes framework with template-based design
- detach probe actions from data handling actions
- move common functionalities to base classes for code reuse
- add pointProberBase as abstract base for probe location handling
- implement internalPointProber for sampling at internal mesh locations
- implement patchPointProber for sampling at boundary patch locations
- introduce ProbesBase<Prober> template class for sampling framework
- refactor existing probes and patchProbes to use new template structure
- update thermoCoupleProbes to use new prober() interface
- maintain backward compatibility while enabling extensible probe types

ENH: probes: detach pointField inheritance from probes

STYLE: probes: rename lists as ids
2025-10-23 10:14:58 +01:00
6cadf3116f ENH: radiation: add access function for solverFreq variable 2025-10-15 20:45:06 +01:00
e9fcd75ec4 ENH: add default "constant" name for fileOperations::findTimes()
- makes fileHandler calling resemble Time more closely

ENH: provide natural_sort less/greater functions

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

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

- makes handling independent of aliasing order

STYLE: include <string_view> when including <string>

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

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

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

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

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

ENH: add -region support for cleanFaMesh and cleanPolyMesh

CONFIG: add bash completion help for -area-region

ENH: general improvements for regionProperties

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

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

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

BUG: gatherv/scatterv wrappers used the incorrect data type

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

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

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

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

See merge request Development/openfoam!761
2025-10-09 10:29:56 +00:00
165 changed files with 4202 additions and 2331 deletions

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

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

@ -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]
@ -72,6 +73,12 @@ int main(int argc, char *argv[])
"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"
@ -92,14 +99,20 @@ int main(int argc, char *argv[])
++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 || doFiniteArea)
if (dryRun || isOptional || doFiniteArea)
{
// Always treat finite-area regionProperties as optional
// The finite-area regionProperties are also considered optional
readOpt = IOobjectOption::READ_IF_PRESENT;
}
@ -116,58 +129,70 @@ int main(int argc, char *argv[])
if (doFiniteArea)
{
regionProps = regionProperties(runTime, faMeshPrefix, readOpt);
if (regionProps.empty())
{
InfoErr<< "No finite-area region types" << nl;
}
else if (optVerbose)
{
InfoErr
<< "Have " << regionProps.size()
<< " finite-area region types, "
<< regionProps.count() << " regions" << nl << nl;
}
}
else
{
regionProps = regionProperties(runTime, readOpt);
if (regionProps.empty())
{
// Probably only occurs with -dry-run option
InfoErr<< "No region types" << nl;
}
else if (optVerbose)
{
InfoErr
<< "Have " << regionProps.size() << " region types, "
<< regionProps.count() << " regions" << nl << nl;
}
}
// We now handle checking args and general sanity etc.
wordList regionTypes;
if (args.size() > 1)
// Some reporting...
if (regionProps.empty())
{
regionTypes.resize(args.size()-1);
if (doFiniteArea)
{
InfoErr<< "No finite-area region types" << nl;
}
else if (isOptional)
{
InfoErr<< "No region types" << nl;
}
}
else if (optVerbose)
{
InfoErr << "Have " << regionProps.size();
// No duplicates
if (doFiniteArea)
{
InfoErr<< " finite-area";
}
InfoErr
<< " region types, "
<< regionProps.count() << " regions" << nl << nl;
}
// We now handle checking args and general sanity etc.
DynamicList<word> regionTypes;
if (isOptional && regionProps.empty())
{
// Nothing to do...
}
else if (nFilters > 0)
{
// Apply region filters
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 (regionProps.contains(regType))
{
++nTypes;
if (!regionTypes.contains(regType))
{
regionTypes.push_back(std::move(regType));
}
}
else
{
@ -175,22 +200,22 @@ int main(int argc, char *argv[])
}
}
}
regionTypes.resize(nTypes);
}
else
{
// Take all regions
regionTypes = regionProps.sortedToc();
}
for (const word& regionType : regionTypes)
{
const wordList& regionNames = regionProps[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

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

@ -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");

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

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

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

@ -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));
}
}

View File

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

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>

View File

@ -113,6 +113,7 @@ SeeAlso
#include "label.H"
#include "scalar.H"
#include "regExpFwd.H"
#include "Switch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -55,6 +55,8 @@ SourceFiles
#include "label.H"
#include "word.H"
#include <string_view>
#include <string>
#include <iostream>

View File

@ -40,6 +40,7 @@ SourceFiles
#include "Dictionary.H"
#include "simpleRegIOobject.H"
#include <string_view>
#include <string>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -333,7 +333,7 @@ Foam::fileMonitor& Foam::fileOperation::monitor() const
void Foam::fileOperation::mergeTimes
(
const instantList& extraTimes,
const UList<instant>& extraTimes,
const word& constantName,
instantList& times
)

View File

@ -198,8 +198,10 @@ protected:
//- Merge two times
static void mergeTimes
(
const instantList& extraTimes,
const UList<instant>& extraTimes,
//! The "constant" name
const word& constantName,
//! [in,out] Updated with any extra times
instantList& times
);
@ -870,7 +872,13 @@ public:
) const;
//- Get sorted list of times
virtual instantList findTimes(const fileName&, const word&) const;
virtual instantList findTimes
(
//! The directory to search
const fileName& directory,
//! The "constant" name
const word& constantName = "constant"
) const;
//- Find time instance where IOobject is located.
//- The name of the IOobject can be empty, in which case only the

View File

@ -748,7 +748,13 @@ public:
// Other
//- Get sorted list of times
virtual instantList findTimes(const fileName&, const word&) const;
virtual instantList findTimes
(
//! The directory to search
const fileName& directory,
//! The "constant" name
const word& constantName = "constant"
) const;
//- Find time instance where IOobject is located.
//- The name of the IOobject can be empty, in which case only the

View File

@ -11,7 +11,10 @@ License
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
Description
Add multi-region command-line options: -allRegions, -regions, -region
Add multi-region command-line options:
-allRegions | -all-regions
-regions
-region
Required Classes
- Foam::argList
@ -24,10 +27,10 @@ See Also
{
Foam::argList::addBoolOption
(
"all-regions",
"allRegions",
"Use all regions in regionProperties"
);
Foam::argList::addOptionCompat("all-regions", { "allRegions", -2506 });
Foam::argList::addOptionCompat("allRegions", { "all-regions", 0 });
Foam::argList::addOption
(

View File

@ -45,12 +45,19 @@ See Also
wordList regionNames;
{
// Local alias
auto& names = regionNames;
// Exit or fallback if nothing matches
constexpr bool exitOnNoMatches = true;
if (args.found("all-regions"))
// Local aliases
auto& names = regionNames;
const auto& fallback = Foam::polyMesh::defaultRegion;
if
(
// Handle both here (independent of which is an alias)
args.found("all-regions")
|| args.found("allRegions")
)
{
names =
(
@ -81,11 +88,11 @@ wordList regionNames;
{
select.uniq(); // Normally a no-op
if (select.size() == 1 && select.front().isLiteral())
if (select.size() == 1 && select[0].isLiteral())
{
// Identical to -region NAME
names.resize(1);
names.front() = select.front();
names[0] = select[0];
}
else if (select.size())
{
@ -116,12 +123,12 @@ wordList regionNames;
}
else
{
InfoErr<< "... ignoring and using default region"
InfoErr
<< "... ignoring and using default region"
<< nl << endl;
// Arbitrary fallback, but can handle this further on
names.resize(1);
names.front() = Foam::polyMesh::defaultRegion;
names[0] = fallback;
}
}
else
@ -160,7 +167,7 @@ wordList regionNames;
else
{
names.resize(1);
names.front() = Foam::polyMesh::defaultRegion;
names[0] = fallback;
InfoErr
<< "Warning: No regionProperties, "
@ -169,17 +176,30 @@ wordList regionNames;
}
}
}
else if (args.found("region"))
else
{
// Single region option or fallback
names.resize(1);
names.front() = args.get<word>("region");
auto& name = names[0];
if
(
!args.readIfPresent("region", name)
)
{
name = fallback;
}
}
// Fallback to defaultRegion
// Final sanity checks and/or fallback
if (names.empty())
{
names.resize(1);
names.front() = Foam::polyMesh::defaultRegion;
names[0] = fallback;
}
else if (names.size() == 1 && names[0].empty())
{
names[0] = fallback;
}
}

View File

@ -221,9 +221,14 @@ Foam::tmp<Foam::labelField> Foam::pairGAMGAgglomeration::agglomerate
auto tcoarseCellMap = tmp<labelField>::New(nFineCells, -1);
auto& coarseCellMap = tcoarseCellMap.ref();
// Small tolerance to account for faces potentially having slightly
// different truncation error in their weights from run to run
// (e.g. due to offloading). If all the largest faces per cell are
// within this tolerance use the first one. This guarantees repeatability.
const scalar tol = 1E-10;
nCoarseCells = 0;
label celli;
for (label cellfi=0; cellfi<nFineCells; cellfi++)
{
// Change cell ordering depending on direction for this level
@ -250,7 +255,7 @@ Foam::tmp<Foam::labelField> Foam::pairGAMGAgglomeration::agglomerate
(
coarseCellMap[upperAddr[facei]] < 0
&& coarseCellMap[lowerAddr[facei]] < 0
&& faceWeights[facei] > maxFaceWeight
&& faceWeights[facei] > maxFaceWeight*(1.0 + tol)
)
{
// Match found. Pick up all the necessary data
@ -282,7 +287,7 @@ Foam::tmp<Foam::labelField> Foam::pairGAMGAgglomeration::agglomerate
{
label facei = cellFaces[faceOs];
if (faceWeights[facei] > clusterMaxFaceCoeff)
if (faceWeights[facei] > clusterMaxFaceCoeff*(1.0 + tol))
{
clusterMatchFaceNo = facei;
clusterMaxFaceCoeff = faceWeights[facei];

View File

@ -27,6 +27,7 @@ License
\*---------------------------------------------------------------------------*/
#include "globalIndex.H"
#include <functional>
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
@ -696,159 +697,94 @@ void Foam::globalIndex::mpiGather
const UList<Type>& sendData,
OutputContainer& allData,
const label comm,
UPstream::commsTypes commsType,
const int tag
[[maybe_unused]] UPstream::commsTypes commsType,
[[maybe_unused]] const int tag
) const
{
if (!UPstream::parRun())
if (!UPstream::is_parallel(comm))
{
// Serial: direct copy
allData = sendData;
return;
}
// MPI_Gatherv requires contiguous data, but a byte-wise transfer can
// quickly exceed the 'int' limits used for MPI sizes/offsets.
// Thus gather label/scalar components when possible to increase the
// effective size limit.
//
// Note: cannot rely on pTraits (cmptType, nComponents) since this method
// needs to compile (and work) even with things like strings etc.
// Single char ad hoc "enum":
// - b(yte): gather bytes
// - f(loat): gather scalars components
// - i(nt): gather label components
// - 0: gather with Pstream read/write etc.
List<int> recvCounts;
List<int> recvOffsets;
char dataMode(0);
int nCmpts(0);
if constexpr (is_contiguous_v<Type>)
if (UPstream::master(comm))
{
if constexpr (is_contiguous_scalar<Type>::value)
{
dataMode = 'f';
nCmpts = static_cast<int>(sizeof(Type)/sizeof(scalar));
}
else if constexpr (is_contiguous_label<Type>::value)
{
dataMode = 'i';
nCmpts = static_cast<int>(sizeof(Type)/sizeof(label));
}
else
{
dataMode = 'b';
nCmpts = static_cast<int>(sizeof(Type));
}
allData.resize_nocopy(offsets_.back()); // == totalSize()
}
else
{
allData.clear(); // zero-size on non-master
}
if constexpr (UPstream_dataType<Type>::value)
{
// Restrict to basic (or aliased) MPI types
// - simplifies calculating counts/offsets
// and can call UPstream::mpiGatherv directly
// 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"
);
List<int> recvCounts;
List<int> recvOffsets;
// Offsets must fit into int
if (UPstream::master(comm))
{
const globalIndex& globalAddr = *this;
// Must be same as Pstream::nProcs(comm), at least on master!
// if (UPstream::nProcs(comm) != this->nProcs()) ...
if (globalAddr.totalSize() > (INT_MAX/nCmpts))
{
// Offsets do not fit into int - revert to manual.
dataMode = 0;
}
else
{
// Must be same as Pstream::nProcs(comm), at least on master!
const label nproc = globalAddr.nProcs();
recvCounts.resize(offsets_.size()-1);
recvOffsets.resize(offsets_.size());
allData.resize_nocopy(globalAddr.totalSize());
// Copy offsets
std::copy(offsets_.begin(), offsets_.end(), recvOffsets.begin());
recvCounts.resize(nproc);
recvOffsets.resize(nproc+1);
// Calculate sizes. Currently without std::minus <functional>
std::transform
(
offsets_.begin()+1, offsets_.end(),
offsets_.begin(), recvCounts.begin(),
std::minus<>{}
);
for (label proci = 0; proci < nproc; ++proci)
{
recvCounts[proci] = globalAddr.localSize(proci)*nCmpts;
recvOffsets[proci] = globalAddr.localStart(proci)*nCmpts;
}
recvOffsets[nproc] = globalAddr.totalSize()*nCmpts;
// Assign local data directly
recvCounts[0] = 0; // ie, ignore for MPI_Gatherv
SubList<Type>(allData, globalAddr.range(0)) =
SubList<Type>(sendData, globalAddr.range(0));
}
// FUTURE .. fix sizes and offsets by the element factor...
// if constexpr (UPstream_basic_dataType<Type>::size(1) > 1)
}
// Consistent information for everyone
UPstream::broadcast(&dataMode, 1, comm);
int sendSize = static_cast<int>(sendData.size());
// Note we let MPI_Gatherv copy back the local data as well...
UPstream::mpiGatherv
(
sendData.cdata(),
sendSize,
allData.data(),
recvCounts,
recvOffsets,
comm
);
}
// Dispatch
switch (dataMode)
else
{
case 'b': // Byte-wise
{
UPstream::mpiGatherv
(
sendData.cdata_bytes(),
sendData.size_bytes(),
allData.data_bytes(),
recvCounts,
recvOffsets,
comm
);
break;
}
case 'f': // Float (scalar) components
{
typedef scalar cmptType;
UPstream::mpiGatherv
(
reinterpret_cast<const cmptType*>(sendData.cdata()),
(sendData.size()*nCmpts),
reinterpret_cast<cmptType*>(allData.data()),
recvCounts,
recvOffsets,
comm
);
break;
}
case 'i': // Int (label) components
{
typedef label cmptType;
UPstream::mpiGatherv
(
reinterpret_cast<const cmptType*>(sendData.cdata()),
(sendData.size()*nCmpts),
reinterpret_cast<cmptType*>(allData.data()),
recvCounts,
recvOffsets,
comm
);
break;
}
default: // Regular (manual) gathering
{
globalIndex::gather
(
offsets_, // needed on master only
comm,
UPstream::allProcs(comm), // All communicator ranks
sendData,
allData,
tag,
commsType
);
break;
}
}
if (!UPstream::master(comm))
{
allData.clear(); // safety: zero-size on non-master
// Regular (manual) gathering
globalIndex::gather
(
offsets_, // needed on master only
comm,
UPstream::allProcs(comm), // All communicator ranks
sendData,
allData,
tag,
commsType
);
}
}

View File

@ -43,6 +43,9 @@ SourceFiles
#include "bool.H"
#include "stdFoam.H"
#include <string_view>
#include <string>
// Avoid any pre-processor conflicts with enum names
#undef FALSE
#undef TRUE

View File

@ -58,6 +58,9 @@ Description
#include <algorithm> // std::copy
#include <utility> // std::initializer_list
#include <vector>
#include <string_view>
#include <string>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -93,6 +96,11 @@ class CStringList
// \return location one-past end of dest (ie, the next destination)
static inline char* stringCopy(char* dest, const char* src);
//- Copy string characters into dest as NUL-terminated string.
//
// \return location one-past end of dest (ie, the next destination)
static inline char* stringCopy(char *dest, std::string_view src);
//- Copy string characters into dest as NUL-terminated string.
// Forces conversion of std::sub_match to string form
//
@ -133,9 +141,17 @@ public:
template<class StringType>
inline explicit CStringList(const UList<StringType>& input);
//- Copy construct from a list of string_views
// Copies the input characters.
inline explicit CStringList(const UList<std::string_view>& input);
//- Copy construct from a list of string_views
// Copies the input characters.
inline explicit CStringList(const std::vector<std::string_view>& input);
//- Copy construct from a list of sub-string references
// Copies the input characters.
explicit CStringList(const SubStrings& input);
inline explicit CStringList(const SubStrings& input);
//- Destructor. Invokes clear() to free memory.
@ -157,6 +173,9 @@ public:
//- Return the number of C-strings (ie, argc)
int size() const noexcept { return argc_; }
//- The flattened character content, with interspersed nul-chars
inline std::string_view view() const;
//- The flattened character content, with interspersed nul-chars
const char* cdata_bytes() const noexcept { return data_; }

View File

@ -28,16 +28,6 @@ License
#include "CStringList.H"
#include "Ostream.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::CStringList::CStringList(const SubStrings& input)
:
CStringList()
{
resetContent(input);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// Largely identical to resetContent() except with 'c-string'

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2024 OpenCFD Ltd.
Copyright (C) 2016-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -35,6 +35,14 @@ inline char* Foam::CStringList::stringCopy(char* dest, const char* src)
}
inline char* Foam::CStringList::stringCopy(char *dest, std::string_view src)
{
dest = std::copy_n(src.data(), src.size(), dest);
*(dest++) = '\0';
return dest;
}
inline char* Foam::CStringList::stringCopy(char *dest, const std::string& src)
{
dest = std::copy_n(src.data(), src.size(), dest);
@ -90,6 +98,33 @@ inline Foam::CStringList::CStringList(const UList<StringType>& input)
}
inline Foam::CStringList::CStringList(const UList<std::string_view>& input)
:
CStringList()
{
resetContent(input);
}
inline Foam::CStringList::CStringList
(
const std::vector<std::string_view>& input
)
:
CStringList()
{
resetContent(input);
}
inline Foam::CStringList::CStringList(const SubStrings& input)
:
CStringList()
{
resetContent(input);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
inline Foam::CStringList::~CStringList()
@ -100,6 +135,12 @@ inline Foam::CStringList::~CStringList()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline std::string_view Foam::CStringList::view() const
{
return std::string_view(data_, nbytes_);
}
inline void Foam::CStringList::clear()
{
argc_ = 0;

View File

@ -37,6 +37,7 @@ Description
#include <regex> // For std::ssub_match
#include <memory>
#include <string_view>
#include <string>
#include <vector>

View File

@ -69,6 +69,7 @@ SourceFiles
#define Foam_regExpCxx_H
#include <regex>
#include <string_view>
#include <string>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -54,6 +54,7 @@ SourceFiles
#include "Hasher.H"
#include <cstdlib>
#include <cstring>
#include <string_view>
#include <string>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017 OpenCFD Ltd.
Copyright (C) 2017-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -46,85 +46,106 @@ namespace Foam
namespace stringOps
{
//- 'Natural' compare for C-strings
// Uses algorithm and code from Jan-Marten Spit <jmspit@euronet.nl>
//
// In the 'natural' comparison, strings are compared alphabetically
// and numerically. Thus 'file010.txt' sorts after 'file2.txt'
//
// \param s1 left string
// \param s2 right string
//- 'Natural' compare for C-strings
// Uses algorithm and code from Jan-Marten Spit <jmspit@euronet.nl>
//
// In the 'natural' comparison, strings are compared alphabetically
// and numerically. Thus 'file010.txt' sorts after 'file2.txt'
//
// \param s1 left string
// \param s2 right string
// \return -1 when s1 < s2, 0 when s1 == s2, 1 when s1 > s2
int natstrcmp(const char* s1, const char* s2);
//- Encapsulation of natural order sorting for algorithms
struct natural_sort
{
//- Natural compare for std::string
// \return -1 when s1 < s2, 0 when s1 == s2, 1 when s1 > s2
int natstrcmp(const char* s1, const char* s2);
//- Encapsulation of natural order sorting for algorithms
struct natural_sort
static inline int compare
(
const std::string& s1,
const std::string& s2
)
{
//- Natural compare for std::string
// \return -1 when s1 < s2, 0 when s1 == s2, 1 when s1 > s2
static inline int compare
(
const std::string& s1,
const std::string& s2
)
{
return natstrcmp(s1.data(), s2.data());
}
return stringOps::natstrcmp(s1.data(), s2.data());
}
//- Default (forward) natural sorting
//- Natural compare two strings for a less-than relationship
static inline bool less
(
const std::string& s1,
const std::string& s2
)
{
return (natural_sort::compare(s1, s2) < 0);
}
//- Natural compare two strings for a greater-than relationship
static inline bool greater
(
const std::string& s1,
const std::string& s2
)
{
return (natural_sort::compare(s1, s2) > 0);
}
//- Default (forward) natural sorting
bool operator()(const std::string& s1, const std::string& s2) const
{
return (natural_sort::compare(s1, s2) < 0);
}
//- Reverse natural sorting
struct reverse
{
//- Reverse natural sorting
bool operator()(const std::string& s1, const std::string& s2) const
{
return natural_sort::compare(s1, s2) < 0;
return (natural_sort::compare(s1, s2) > 0);
}
//- Reverse natural sorting
struct reverse
{
//- Reverse natural sorting
bool operator()(const std::string& s1, const std::string& s2) const
{
return natural_sort::compare(s1, s2) > 0;
}
};
//- A list compare binary predicate for natural sort
template<class T>
struct less
{
const UList<T>& values;
less(const UList<T>& list)
:
values(list)
{}
bool operator()(const label a, const label b) const
{
return natural_sort::compare(values[a], values[b]) < 0;
}
};
//- A list compare binary predicate for reverse natural sort
template<class T>
struct greater
{
const UList<T>& values;
greater(const UList<T>& list)
:
values(list)
{}
bool operator()(const label a, const label b) const
{
return natural_sort::compare(values[a], values[b]) > 0;
}
};
};
//- A UList compare binary predicate for natural sort
template<class T>
struct list_less
{
const UList<T>& values;
list_less(const UList<T>& list) noexcept
:
values(list)
{}
bool operator()(label a, label b) const
{
return (natural_sort::compare(values[a], values[b]) < 0);
}
};
//- A Ulist compare binary predicate for reverse natural sort
template<class T>
struct list_greater
{
const UList<T>& values;
list_greater(const UList<T>& list) noexcept
:
values(list)
{}
bool operator()(label a, label b) const
{
return (natural_sort::compare(values[a], values[b]) > 0);
}
};
};
} // End namespace stringOps
} // End namespace Foam

View File

@ -28,33 +28,45 @@ License
#include "Pstream.H"
#include "PstreamGlobals.H"
#include "UPstreamWrapping.H"
#include "vector.H" // for debugging
#undef STRINGIFY
#undef STRING_QUOTE
#define STRINGIFY(content) #content
#define STRING_QUOTE(input) STRINGIFY(input)
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
static inline bool is_basic_dataType(Foam::UPstream::dataTypes id) noexcept
namespace
{
inline bool is_nonAggregate(Foam::UPstream::dataTypes id) noexcept
{
return
(
int(id) >= int(Foam::UPstream::dataTypes::Basic_begin)
&& int(id) < int(Foam::UPstream::dataTypes::Basic_end)
)
||
(
int(id) >= int(Foam::UPstream::dataTypes::User_begin)
&& int(id) < int(Foam::UPstream::dataTypes::User_end)
);
}
namespace
{
using namespace Foam;
// Local function to print some error information
inline void printErrorNonIntrinsic
(
const char* context,
UPstream::dataTypes dataTypeId
Foam::UPstream::dataTypes dataTypeId
)
{
using namespace Foam;
FatalError
<< "Bad input for " << context << ": likely a programming problem\n"
<< " Non-intrinsic data (" << int(dataTypeId) << ")\n"
<< " Non-intrinsic/non-user data (type:" << int(dataTypeId) << ")\n"
<< Foam::endl;
}
@ -214,19 +226,37 @@ void Foam::UPstream::mpi_gatherv
{
MPI_Datatype datatype = PstreamGlobals::getDataType(dataTypeId);
if
(
FOAM_UNLIKELY
(
!is_basic_dataType(dataTypeId)
)
)
// Runtime assert that we are not using aggregated data types
if (FOAM_UNLIKELY(!is_nonAggregate(dataTypeId)))
{
FatalErrorInFunction;
printErrorNonIntrinsic("MPI_Gatherv()", dataTypeId);
FatalError << Foam::abort(FatalError);
}
const label np = UPstream::nProcs(communicator);
// For total-size calculation,
// don't rely on recvOffsets being (np+1)
const int totalSize =
(
(UPstream::master(communicator) && np > 1)
? (recvOffsets[np-1] + recvCounts[np-1])
: 0
);
if (FOAM_UNLIKELY(UPstream::debug))
{
Perr<< "[mpi_gatherv] :"
<< " type:" << int(dataTypeId)
<< " count:" << sendCount
<< " total:" << totalSize
<< " comm:" << communicator
<< " recvCounts:" << flatOutput(recvCounts)
<< " recvOffsets:" << flatOutput(recvOffsets)
<< Foam::endl;
}
{
PstreamDetail::gatherv
(
@ -235,6 +265,48 @@ void Foam::UPstream::mpi_gatherv
datatype, communicator
);
}
// Extended debugging. Limit to master:
#if 0
if (FOAM_UNLIKELY(UPstream::debug))
{
if (UPstream::master(communicator))
{
switch (dataTypeId)
{
#undef dataPrinter
#define dataPrinter(enumType, nativeType) \
case UPstream::dataTypes::enumType : \
{ \
UList<nativeType> combined \
( \
static_cast<nativeType*>(recvData), \
totalSize \
); \
\
Info<< "[mpi_gatherv] => " \
"List<" STRING_QUOTE(nativeType) "> "; \
combined.writeList(Info) << Foam::endl; \
\
break; \
}
// Some common types
dataPrinter(type_int32, int32_t);
dataPrinter(type_int64, int64_t);
dataPrinter(type_float, float);
dataPrinter(type_double, double);
dataPrinter(type_3float, floatVector);
dataPrinter(type_3double, doubleVector);
// Some other type
default: break;
#undef dataPrinter
}
}
}
#endif
}
@ -255,13 +327,8 @@ void Foam::UPstream::mpi_scatterv
{
MPI_Datatype datatype = PstreamGlobals::getDataType(dataTypeId);
if
(
FOAM_UNLIKELY
(
!is_basic_dataType(dataTypeId)
)
)
// Runtime assert that we are not using aggregated data types
if (FOAM_UNLIKELY(!is_nonAggregate(dataTypeId)))
{
FatalErrorInFunction;
printErrorNonIntrinsic("MPI_Scatterv()", dataTypeId);

View File

@ -16,6 +16,6 @@ starcd/STARCDMeshWriter.C
polyDualMesh/polyDualMesh.C
vtk/output/foamVtkSurfaceFieldWriter.C
vtk/output/foamVtkSurfaceFieldWriter.cxx
LIB = $(FOAM_LIBBIN)/libconversion

View File

@ -98,7 +98,7 @@ bool writeAreaField
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "ensightOutputAreaFieldTemplates.C"
#include "ensightOutputAreaField.txx"
#endif
#endif

View File

@ -177,7 +177,7 @@ bool writePointField
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "ensightOutputVolFieldTemplates.C"
#include "ensightOutputVolField.txx"
#endif
#endif

View File

@ -39,7 +39,7 @@ Note
SourceFiles
foamVtkToolsI.H
foamVtkToolsTemplates.C
foamVtkTools.txx
\*---------------------------------------------------------------------------*/
@ -358,7 +358,7 @@ void Foam::vtk::Tools::remapTuple<Foam::symmTensor>(double data[])
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "foamVtkToolsTemplates.C"
#include "foamVtkTools.txx"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -39,7 +39,7 @@ Note
SourceFiles
foamVtkVtuAdaptorI.H
foamVtkVtuAdaptorTemplates.C
foamVtkVtuAdaptor.txx
\*---------------------------------------------------------------------------*/
@ -156,7 +156,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "foamVtkVtuAdaptorTemplates.C"
#include "foamVtkVtuAdaptor.txx"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -32,7 +32,7 @@ Description
Caution, currently only works properly for indirect patches.
SourceFiles
foamVtkGenericPatchGeoFieldsWriter.C
foamVtkGenericPatchGeoFieldsWriter.txx
\*---------------------------------------------------------------------------*/
@ -117,7 +117,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "foamVtkGenericPatchGeoFieldsWriter.C"
#include "foamVtkGenericPatchGeoFieldsWriter.txx"
#endif

View File

@ -44,7 +44,7 @@ See Also
Foam::vtk::internalMeshWriter
SourceFiles
foamVtkInternalWriterTemplates.C
foamVtkInternalWriter.txx
\*---------------------------------------------------------------------------*/
@ -183,7 +183,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "foamVtkInternalWriterTemplates.C"
#include "foamVtkInternalWriter.txx"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -43,7 +43,7 @@ See Also
Foam::vtk::patchMeshWriter
SourceFiles
foamVtkPatchWriterTemplates.C
foamVtkPatchWriter.txx
\*---------------------------------------------------------------------------*/
@ -202,7 +202,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "foamVtkPatchWriterTemplates.C"
#include "foamVtkPatchWriter.txx"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -47,7 +47,7 @@ Note
may be addressed using ghost points.
SourceFiles
surfaceFieldWriter.C
foamVtkSurfaceFieldWriter.cxx
\*---------------------------------------------------------------------------*/

View File

@ -34,7 +34,7 @@ SourceFiles
ensightCase.C
ensightCaseI.H
ensightCaseOptions.C
ensightCaseTemplates.C
ensightCase.txx
\*---------------------------------------------------------------------------*/
@ -548,7 +548,7 @@ public:
#include "ensightCaseI.H"
#ifdef NoRepository
#include "ensightCaseTemplates.C"
#include "ensightCase.txx"
#endif
#endif

View File

@ -394,7 +394,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "ensightFileTemplates.C"
#include "ensightFile.txx"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -31,7 +31,7 @@ Description
SourceFiles
ensightOutput.C
ensightOutputTemplates.C
ensightOutput.txx
\*---------------------------------------------------------------------------*/
@ -557,7 +557,7 @@ bool writeFaceLocalField
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "ensightOutputTemplates.C"
#include "ensightOutput.txx"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -38,7 +38,7 @@ Note
SourceFiles
ensightOutputSurface.C
ensightOutputSurfaceTemplates.C
ensightOutputSurface.txx
\*---------------------------------------------------------------------------*/
@ -136,7 +136,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "ensightOutputSurfaceTemplates.C"
#include "ensightOutputSurface.txx"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -42,8 +42,8 @@ Description
SourceFiles
foamVtkFileWriter.C
foamVtkFileWriter.txx
foamVtkFileWriterI.H
foamVtkFileWriterTemplates.C
\*---------------------------------------------------------------------------*/
@ -350,7 +350,7 @@ public:
#include "foamVtkFileWriterI.H"
#ifdef NoRepository
#include "foamVtkFileWriterTemplates.C"
#include "foamVtkFileWriter.txx"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2023 OpenCFD Ltd.
Copyright (C) 2018-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -64,13 +64,17 @@ namespace Foam
// 2. natural sort (name)
struct seriesLess
{
bool operator()(const fileNameInstant a, const fileNameInstant b) const
template<class StringType>
bool operator()
(
const Instant<StringType>& a,
const Instant<StringType>& b
) const
{
scalar val = compareOp<scalar>()(a.value(), b.value());
if (val == 0)
{
return
stringOps::natural_sort::compare(a.name(), b.name()) < 0;
return stringOps::natural_sort::less(a.name(), b.name());
}
return val < 0;
}
@ -78,7 +82,7 @@ namespace Foam
// Check if value is less than upper, with some tolerance.
static inline bool lessThan(const scalar& val, const scalar& upper)
static inline bool lessThan(scalar val, scalar upper)
{
return (val < upper && Foam::mag(val - upper) > ROOTVSMALL);
}

View File

@ -34,7 +34,8 @@ Description
SourceFiles
foamVtkFormatter.C
foamVtkFormatterTemplates.C
foamVtkFormatter.txx
foamVtkFormatterI.H
\*---------------------------------------------------------------------------*/
@ -560,7 +561,7 @@ inline uint64_t sizeofData(label count)
#include "foamVtkFormatterI.H"
#ifdef NoRepository
#include "foamVtkFormatterTemplates.C"
#include "foamVtkFormatter.txx"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -38,7 +38,8 @@ Description
SourceFiles
foamVtkOutput.C
foamVtkOutputTemplates.C
foamVtkOutput.txx
foamVtkOutputI.H
\*---------------------------------------------------------------------------*/
@ -352,7 +353,7 @@ namespace legacy
#include "foamVtkOutputI.H"
#ifdef NoRepository
#include "foamVtkOutputTemplates.C"
#include "foamVtkOutput.txx"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -358,7 +358,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "vtkUnstructuredReaderTemplates.C"
#include "vtkUnstructuredReader.txx"
#endif

View File

@ -42,7 +42,7 @@ Note
SourceFiles
foamVtkPolyWriter.C
foamVtkPolyWriterTemplates.C
foamVtkPolyWriter.txx
\*---------------------------------------------------------------------------*/
@ -253,7 +253,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "foamVtkPolyWriterTemplates.C"
#include "foamVtkPolyWriter.txx"
#endif

View File

@ -12,7 +12,9 @@ License
Description
Add multi-region command-line options:
-all-area-regions, -area-regions, -area-region
-allAreas | -all-area-regions
-area-regions
-area-region
Required Classes
- Foam::argList
@ -25,9 +27,10 @@ See Also
{
Foam::argList::addBoolOption
(
"all-area-regions",
"allAreas",
"Use all regions in finite-area regionProperties"
);
Foam::argList::addOptionCompat("allAreas", { "all-area-regions", 0 });
Foam::argList::addOption
(
@ -41,8 +44,11 @@ See Also
(
"area-region",
"name",
"Specify area-mesh region. Eg, -region shell"
"Specify area-mesh region. Eg, -area-region shell"
);
// TBD:
//? Foam::argList::addOptionCompat("area-region", { "areaRegion", 0 });
}

View File

@ -15,7 +15,7 @@ Description
(-all-area-regions | -area-regions | -area-region)
Priority
1. -all-area-regions
1. -all-area-regions (-allAreas)
2. -area-regions = specify multiple area regions to select,
or a single area region
3. -area-region = specify a single area region
@ -46,12 +46,19 @@ See Also
wordList areaRegionNames;
{
// Local alias
auto& names = areaRegionNames;
// Exit or fallback if nothing matches
constexpr bool exitOnNoMatches = false;
if (args.found("all-area-regions"))
// Local aliases
auto& names = areaRegionNames;
const auto& fallback = Foam::polyMesh::defaultRegion;
if
(
// Handle both here (independent of which is an alias)
args.found("all-area-regions")
|| args.found("allAreas")
)
{
names =
(
@ -78,16 +85,20 @@ wordList areaRegionNames;
else if
(
wordRes select;
args.readListIfPresent<wordRe>("area-regions", select)
(
// Handle both here (independent of which is an alias)
args.readListIfPresent<wordRe>("area-regions", select)
|| args.readListIfPresent<wordRe>("areaRegions", select)
)
)
{
select.uniq(); // Normally a no-op
if (select.size() == 1 && select.front().isLiteral())
if (select.size() == 1 && select[0].isLiteral())
{
// Identical to -area-region NAME
names.resize(1);
names.front() = select.front();
names[0] = select[0];
}
else if (select.size())
{
@ -119,12 +130,12 @@ wordList areaRegionNames;
}
else
{
InfoErr<< "... ignoring and using default region"
InfoErr
<< "... ignoring and using default region"
<< nl << endl;
// Arbitrary fallback, but can handle this further on
names.resize(1);
names.front() = Foam::polyMesh::defaultRegion;
names[0] = fallback;
}
}
else
@ -162,7 +173,7 @@ wordList areaRegionNames;
else
{
names.resize(1);
names.front() = Foam::polyMesh::defaultRegion;
names[0] = fallback;
InfoErr
<< "Warning: No finite-area regionProperties, "
@ -171,17 +182,32 @@ wordList areaRegionNames;
}
}
}
else if (args.found("area-region"))
else
{
// Single region option or fallback
names.resize(1);
names.front() = args.get<word>("area-region");
auto& name = names[0];
if
(
// Handle both here (independent of which is an alias)
!args.readIfPresent("area-region", name)
&& !args.readIfPresent("areaRegion", name)
)
{
name = fallback;
}
}
// Fallback to defaultRegion
// Final sanity checks and/or fallback
if (names.empty())
{
names.resize(1);
names.front() = Foam::polyMesh::defaultRegion;
names[0] = fallback;
}
else if (names.size() == 1 && names[0].empty())
{
names[0] = fallback;
}
}

View File

@ -4,7 +4,7 @@ cloudInfo/cloudInfo.C
icoUncoupledKinematicCloud/icoUncoupledKinematicCloud.C
dsmcFields/dsmcFields.C
vtkCloud/vtkCloud.C
vtkCloud/vtkCloud.cxx
ensightCloud/ensightCloudWriteObject.cxx
LIB = $(FOAM_LIBBIN)/liblagrangianFunctionObjects

View File

@ -129,8 +129,8 @@ See also
Foam::functionObjects::timeControl
SourceFiles
vtkCloud.C
vtkCloudTemplates.C
vtkCloud.cxx
vtkCloudImpl.cxx
\*---------------------------------------------------------------------------*/
@ -262,12 +262,6 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "vtkCloudTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -47,6 +47,12 @@ namespace functionObjects
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Implementation
#include "vtkCloudImpl.cxx"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::functionObjects::vtkCloud::writeVerts

View File

@ -4,10 +4,10 @@ caseInfo/caseInfo.C
codedFunctionObject/codedFunctionObject.C
areaWrite/areaWrite.C
areaWrite/areaWrite.cxx
ensightWrite/ensightWrite.C
ensightWrite/ensightWriteUpdate.C
ensightWrite/ensightWrite.cxx
ensightWrite/ensightWriteUpdate.cxx
foamReport/foamReport.C
foamReport/substitutionModels/substitutionModel/substitutionModel.C
@ -20,8 +20,8 @@ foamReport/substitutionModels/userValue/userValue.C
graphFunctionObject/graphFunctionObject.C
vtkWrite/vtkWrite.C
vtkWrite/vtkWriteUpdate.C
vtkWrite/vtkWrite.cxx
vtkWrite/vtkWriteUpdate.cxx
multiRegion/multiRegion.C
@ -57,6 +57,7 @@ writeDictionary/writeDictionary.C
writeObjects/writeObjects.C
thermoCoupleProbes/thermoCoupleProbes.C
radiometerProbes/radiometerProbes.C
syncObjects/syncObjects.C

View File

@ -9,7 +9,9 @@ EXE_INC = \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/ODE/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/transportModels/compressible/lnInclude
-I$(LIB_SRC)/transportModels/compressible/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \
-I$(LIB_SRC)/parallel/distributed/lnInclude
LIB_LIBS = \
-lfiniteVolume \
@ -22,4 +24,6 @@ LIB_LIBS = \
-lsampling \
-lODE \
-lfluidThermophysicalModels \
-lcompressibleTransportModels
-lcompressibleTransportModels \
-lradiationModels \
-ldistributed

View File

@ -72,8 +72,8 @@ Usage
libs | Library name: utilityFunctionObjects | word | yes | -
fields | Name of operand fields | wordRes | yes | -
surfaceFormat | Output surface format | word | yes | -
areas | Names of multiple areas | wordRes | no | -
area | Name of the selected area | word | no | -
areas | Names of finite-area regions | wordRes | no | -
area | Name of finite-area region | word | no | -
formatOptions | Dictionary of format options | dict | no | -
\endtable
@ -82,8 +82,8 @@ Usage
- \link surfaceWriter.H \endlink
SourceFiles
areaWrite.C
areaWriteTemplates.C
areaWrite.cxx
areaWriteImpl.cxx
\*---------------------------------------------------------------------------*/
@ -95,7 +95,6 @@ SourceFiles
#include "areaFieldsFwd.H"
#include "surfaceWriter.H"
#include "HashPtrTable.H"
#include "IOobjectList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -105,6 +104,7 @@ namespace Foam
// Forward Declarations
class faMesh;
class polySurface;
class IOobjectList;
/*---------------------------------------------------------------------------*\
Class areaWrite Declaration
@ -145,7 +145,7 @@ class areaWrite
//- Hold intermediate surfaces.
// The faMesh has an indirect face list but we require real ones.
autoPtr<objectRegistry> surfaces_;
std::unique_ptr<objectRegistry> surfaces_;
// Output control
@ -156,6 +156,9 @@ class areaWrite
// Private Member Functions
//- Mark intermediate surfaces and writers as needing an update.
void expire();
//- Write fieldName on surface and on outputDir path.
// Can have a field nullptr for partially missing fields,
// but the caller should generally filter out completely
@ -177,8 +180,13 @@ class areaWrite
const IOobjectList& objects
);
//- Mark intermediate surfaces and writers as needing an update.
void expire();
public:
//- Runtime type information
TypeName("areaWrite");
// Generated Methods
//- No copy construct
areaWrite(const areaWrite&) = delete;
@ -187,12 +195,6 @@ class areaWrite
void operator=(const areaWrite&) = delete;
public:
//- Runtime type information
TypeName("areaWrite");
// Constructors
//- Construct from name, Time and dictionary
@ -215,14 +217,14 @@ public:
//- Destructor
virtual ~areaWrite() = default;
virtual ~areaWrite();
// Member Functions
//- Enable/disable verbose output
// \return old value
bool verbose(const bool on) noexcept;
bool verbose(bool on) noexcept;
//- Read the function-object dictionary
virtual bool read(const dictionary& dict);
@ -246,7 +248,7 @@ public:
static scalar mergeTol() noexcept;
//- Set merge tolerance and return old value
static scalar mergeTol(const scalar tol) noexcept;
static scalar mergeTol(scalar tol) noexcept;
};

View File

@ -28,11 +28,13 @@ License
#include "areaWrite.H"
#include "polySurface.H"
#include "faMesh.H"
#include "fvMesh.H"
#include "mapPolyMesh.H"
#include "areaFields.H"
#include "HashOps.H"
#include "ListOps.H"
#include "IOobjectList.H"
#include "Time.H"
#include "IndirectList.H"
#include "addToRunTimeSelectionTable.H"
@ -55,7 +57,7 @@ Foam::scalar Foam::areaWrite::mergeTol_ = 1e-10;
// Implementation
#include "areaWriteImpl.C"
#include "areaWriteImpl.cxx"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -72,12 +74,7 @@ Foam::areaWrite::areaWrite
outputPath_
(
time_.globalPath()/functionObject::outputPrefix/name
),
selectAreas_(),
fieldSelection_(),
meshes_(),
surfaces_(nullptr),
writers_()
)
{
outputPath_.clean(); // Remove unneeded ".."
@ -99,12 +96,7 @@ Foam::areaWrite::areaWrite
outputPath_
(
time_.globalPath()/functionObject::outputPrefix/name
),
selectAreas_(),
fieldSelection_(),
meshes_(),
surfaces_(nullptr),
writers_()
)
{
outputPath_.clean(); // Remove unneeded ".."
@ -112,9 +104,15 @@ Foam::areaWrite::areaWrite
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::areaWrite::~areaWrite()
{} // Define here: header had forward declared classes
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::areaWrite::verbose(const bool on) noexcept
bool Foam::areaWrite::verbose(bool on) noexcept
{
bool old(verbose_);
verbose_ = on;
@ -393,6 +391,7 @@ bool Foam::areaWrite::write()
void Foam::areaWrite::expire()
{
// Clear the registry contents
surfaces_->clear();
// Dimension as fraction of mesh bounding box
@ -434,13 +433,15 @@ void Foam::areaWrite::readUpdate(const polyMesh::readUpdateState state)
}
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::scalar Foam::areaWrite::mergeTol() noexcept
{
return mergeTol_;
}
Foam::scalar Foam::areaWrite::mergeTol(const scalar tol) noexcept
Foam::scalar Foam::areaWrite::mergeTol(scalar tol) noexcept
{
scalar old(mergeTol_);
mergeTol_ = tol;

View File

@ -25,10 +25,6 @@ License
\*---------------------------------------------------------------------------*/
#include "areaWrite.H"
#include "areaFields.H"
#include "faMesh.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>

View File

@ -135,8 +135,8 @@ See also
SourceFiles
ensightWrite.C
ensightWriteImpl.C
ensightWriteUpdate.C
ensightWriteImpl.cxx
ensightWriteUpdate.cxx
\*---------------------------------------------------------------------------*/
@ -158,10 +158,6 @@ SourceFiles
namespace Foam
{
// Forward Declarations
class dictionary;
namespace functionObjects
{
@ -173,7 +169,7 @@ class ensightWrite
:
public fvMeshFunctionObject
{
// Private data
// Private Data
//- Ensight writer options
ensightMesh::options writeOpts_;
@ -188,7 +184,7 @@ class ensightWrite
bool consecutive_;
//- Track changes in mesh geometry
enum polyMesh::readUpdateState meshState_;
polyMesh::readUpdateState meshState_;
//- Requested selection of fields to process
wordRes selectFields_;
@ -212,16 +208,10 @@ class ensightWrite
// Private Member Functions
//- Ensight case handler
ensightCase& ensCase()
{
return *ensCase_;
}
ensightCase& ensCase() { return *ensCase_; }
//- Ensight mesh handler
ensightMesh& ensMesh()
{
return *ensMesh_;
}
ensightMesh& ensMesh() { return *ensMesh_; }
//- Update mesh subset according to zones, geometry, bounds
@ -252,13 +242,6 @@ class ensightWrite
const wordHashSet& candidateNames
);
//- No copy construct
ensightWrite(const ensightWrite&) = delete;
//- No copy assignment
void operator=(const ensightWrite&) = delete;
public:
//- Runtime type information
@ -275,6 +258,12 @@ public:
const dictionary& dict
);
//- No copy construct
ensightWrite(const ensightWrite&) = delete;
//- No copy assignment
void operator=(const ensightWrite&) = delete;
//- Destructor
virtual ~ensightWrite() = default;

View File

@ -49,7 +49,7 @@ namespace functionObjects
}
// Implementation
#include "ensightWriteImpl.C"
#include "ensightWriteImpl.cxx"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -96,17 +96,10 @@ Foam::functionObjects::ensightWrite::ensightWrite
)
:
fvMeshFunctionObject(name, runTime, dict),
writeOpts_(),
caseOpts_("format", dict, IOstreamOption::BINARY),
outputDir_(),
consecutive_(false),
meshState_(polyMesh::TOPO_CHANGE),
selectFields_(),
blockFields_(),
selection_(),
meshSubset_(mesh_),
ensCase_(nullptr),
ensMesh_(nullptr)
meshSubset_(mesh_)
{
// May still want this? (OCT-2018)
// if (postProcess)

View File

@ -0,0 +1,260 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "radiometerProbes.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace functionObjects
{
defineTypeNameAndDebug(radiometerProbes, 0);
addToRunTimeSelectionTable(functionObject, radiometerProbes, dictionary);
}
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::functionObjects::radiometerProbes::writeFileHeader(Ostream& os)
{
const pointField& locs = probeLocations();
writeCommented(os, "Probe,Location,Normal");
os << nl;
for (label i = 0; i < szProbes_; ++i)
{
const vector& loc = locs[i];
const vector& n = n_[i];
os << '#' << ' ' << i
<< ',' << loc.x() << ',' << loc.y() << ',' << loc.z()
<< ',' << n.x() << ',' << n.y() << ',' << n.z()
<< nl;
}
os << "# Time";
for (int i = 0; i < szProbes_; ++i)
{
os << ',' << i;
}
os << endl;
writtenHeader_ = true;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::functionObjects::radiometerProbes::radiometerProbes
(
const word& name,
const Time& runTime,
const dictionary& dict
)
:
regionFunctionObject(name, runTime, dict),
internalProber(mesh_, dict),
writeFile(mesh_, name, typeName, dict),
dom_(mesh_.lookupObject<radiation::fvDOM>("radiationProperties")),
firstIter_(true)
{
read(dict);
}
// * * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * //
bool Foam::functionObjects::radiometerProbes::read(const dictionary& dict)
{
if
(
!(
regionFunctionObject::read(dict)
&& internalProber::read(dict)
&& writeFile::read(dict)
)
)
{
return false;
}
// Skip if the radiation model is inactive
if (!dom_.radiation())
{
WarningInFunction
<< "The radiation model is inactive."
<< "Skipping the function object " << type() << ' ' << name()
<< endl;
return false;
}
Log << type() << ':' << name() << ": read" << nl << nl;
// Probe locations are read by 'internalProber'
szProbes_ = this->size();
// If/when fvDOM is updated, the 'read' func is assumed to be executed to
// update the fvDOM properties
nRay_ = dom_.nRay();
if (!szProbes_ || !nRay_)
{
FatalIOErrorInFunction(dict)
<< "size(probe locations): " << szProbes_ << nl
<< "size(rays): " << nRay_ << nl
<< "The input size of probe locations and rays cannot be zero."
<< exit(FatalIOError);
}
// Read and check size consistency of probe normals with probe locations
dict.readEntry("probeNormals", n_);
if (n_.size() != szProbes_)
{
FatalIOErrorInFunction(dict)
<< "size(probe locations): " << szProbes_ << nl
<< "size(probe normals): " << n_.size() << nl
<< "The input size of probe locations and normals must match."
<< exit(FatalIOError);
}
n_.normalise();
// Pre-compute and cache inner product of 'n_' and 'dAve_', and 'C_'
// This simplification of calculation is valid only if I is non-negative
n_dAve_.resize(nRay_);
C_.resize(nRay_);
for (label rayi = 0; rayi < nRay_; ++rayi)
{
const vector& dAvei = dom_.IRay(rayi).dAve();
scalarList& n_dAveRay = n_dAve_[rayi];
boolList& Cray = C_[rayi];
n_dAveRay.resize(szProbes_, Zero);
Cray.resize(szProbes_, false);
for (label pi = 0; pi < szProbes_; ++pi)
{
n_dAveRay[pi] = n_[pi] & dAvei;
if (n_dAveRay[pi] < 0) // ray entering the probe
{
Cray[pi] = true;
}
}
}
qin_.resize(szProbes_);
if (writeFile::canResetFile())
{
writeFile::resetFile(typeName);
}
if (writeFile::canWriteHeader())
{
writeFileHeader(file());
}
return true;
}
bool Foam::functionObjects::radiometerProbes::execute()
{
// Skip if there is no probe to sample, or the radiation model is inactive
if (!szProbes_ || !dom_.radiation() || !shouldCalcThisStep())
{
return false;
}
Log << type() << ' ' << name() << ": execute" << nl << nl;
qin_ = Zero; // resized in 'read'
for (label rayi = 0; rayi < nRay_; ++rayi)
{
// Radiative intensity field for this ray
const volScalarField& I = dom_.IRay(rayi).I();
// Sample radiative intensity ray at probe locations
tmp<scalarField> tIp = internalProber::sample(I);
const scalarField& Ip = tIp.cref();
const scalarList& n_dAveRay = n_dAve_[rayi];
const boolList& Cray = C_[rayi];
// Add incident radiative heat flux per probe location for each ray
for (label pi = 0; pi < szProbes_; ++pi)
{
if (Cray[pi])
{
qin_[pi] += Ip[pi]*n_dAveRay[pi];
}
}
}
return true;
}
bool Foam::functionObjects::radiometerProbes::write()
{
// Skip if there is no probe to sample, or the radiation model is inactive
if (!szProbes_ || !dom_.radiation() || !shouldCalcThisStep())
{
return false;
}
Log << type() << ' ' << name() << ": write" << nl << nl;
if (UPstream::master())
{
Ostream& os = file();
os << mesh_.time().timeOutputValue();
for (label pi = 0; pi < szProbes_; ++pi)
{
os << ',' << qin_[pi];
}
os << endl;
}
firstIter_ = false;
return true;
}
// ************************************************************************* //

View File

@ -0,0 +1,200 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::functionObjects::radiometerProbes
Group
grpUtilitiesFunctionObjects
Description
Probes the incident radiative heat flux, qin, at arbitrary points within a
domain.
Usage
Minimal example by using \c system/controlDict.functions:
\verbatim
radiometer
{
// Mandatory entries
type radiometerProbes;
libs (utilityFunctionObjects);
probeLocations (<vectorList>);
probeNormals (<vectorList>);
// Inherited entries
...
}
\endverbatim
where the entries mean:
\table
Property | Description | Type | Reqd | Deflt
type | Type name: radiometerProbes | word | yes | -
libs | Library name: utilityFunctionObjects | word | yes | -
probeLocations | Locations of probes | vectorList | yes | -
probeNormals | Normals of specified probes | vectorList | yes | -
\endtable
The inherited entries are elaborated in:
- \link regionFunctionObject.H \endlink
- \link internalProber.H \endlink
- \link writeFile.H \endlink
- \link fvDOM.H \endlink
Note
- The function object can only be used with the \c fvDOM radiation model.
- The \c solverFreq input of the \c fvDOM model has superiority over
\c executeControl and \c writeControl entries.
SourceFiles
radiometerProbes.C
\*---------------------------------------------------------------------------*/
#ifndef Foam_functionObjects_radiometerProbes_H
#define Foam_functionObjects_radiometerProbes_H
#include "regionFunctionObject.H"
#include "internalProber.H"
#include "writeFile.H"
#include "fvDOM.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace functionObjects
{
/*---------------------------------------------------------------------------*\
Class radiometerProbes Declaration
\*---------------------------------------------------------------------------*/
class radiometerProbes
:
public regionFunctionObject,
public internalProber,
public writeFile
{
// Private Data
//- Const reference to the underlying radiation model
const radiation::fvDOM& dom_;
//- Normal vectors of the specified probes
vectorField n_;
//- Pre-computed inner product of probe normals (n_) and average
//- solid-angle direction (dAve) per radiative intensity ray
List<scalarList> n_dAve_;
//- Directional selection coefficient for radiative intensity rays
// false: ray entering the probe
// true: ray leaving the probe
List<boolList> C_;
//- Incident radiative heat flux per probe location
scalarField qin_;
//- Number of radiative intensity rays
label nRay_;
//- Number of probe locations/normals
label szProbes_;
//- Flag to identify whether the iteration is the first iteration
// Resets with a restarted simulation
bool firstIter_;
// Private Member Functions
//- Write file-header information into the output file
virtual void writeFileHeader(Ostream& os);
//- Return the flag to decide if radiation-model calculations are
//- performed, so that function object calculations can proceed
bool shouldCalcThisStep() const
{
return
firstIter_
|| (mesh_.time().timeIndex() % dom_.solverFreq() == 0);
}
public:
//- Runtime type information
TypeName("radiometerProbes");
// Generated Methods
//- No copy construct
radiometerProbes(const radiometerProbes&) = delete;
//- No copy assignment
void operator=(const radiometerProbes&) = delete;
// Constructors
//- Construct from name, Time and dictionary
radiometerProbes
(
const word& name,
const Time& runTime,
const dictionary& dict
);
//- Destructor
virtual ~radiometerProbes() = default;
// Public Member Functions
//- Read the function object settings
virtual bool read(const dictionary&);
//- Execute the function object
virtual bool execute();
//- Write to data files/fields and to streams
virtual bool write();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace functionObjects
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -76,7 +76,7 @@ Foam::functionObjects::thermoCoupleProbes::thermoCoupleProbes
}
else
{
Ttc_ = probes::sample(thermo_.T());
Ttc_ = prober().sample(thermo_.T());
}
// Note: can only create the solver once all samples have been found
@ -89,7 +89,7 @@ Foam::functionObjects::thermoCoupleProbes::thermoCoupleProbes
Foam::label Foam::functionObjects::thermoCoupleProbes::nEqns() const
{
return this->size();
return prober().size();
}
@ -108,19 +108,21 @@ void Foam::functionObjects::thermoCoupleProbes::derivatives
scalarField Cpc(y.size(), Zero);
scalarField kappac(y.size(), Zero);
const auto& p = prober();
if (radiationFieldName_ != "none")
{
G = sample(mesh_.lookupObject<volScalarField>(radiationFieldName_));
G = p.sample(mesh_.lookupObject<volScalarField>(radiationFieldName_));
}
Tc = probes::sample(thermo_.T());
Tc = p.sample(thermo_.T());
Uc = mag(this->sample(mesh_.lookupObject<volVectorField>(UName_)));
Uc = mag(p.sample(mesh_.lookupObject<volVectorField>(UName_)));
rhoc = this->sample(thermo_.rho()());
kappac = this->sample(thermo_.kappa()());
muc = this->sample(thermo_.mu()());
Cpc = this->sample(thermo_.Cp()());
rhoc = p.sample(thermo_.rho()());
kappac = p.sample(thermo_.kappa()());
muc = p.sample(thermo_.mu()());
Cpc = p.sample(thermo_.Cp()());
scalarField Re(rhoc*Uc*d_/muc);
scalarField Pr(Cpc*muc/kappac);
@ -163,7 +165,7 @@ void Foam::functionObjects::thermoCoupleProbes::jacobian
bool Foam::functionObjects::thermoCoupleProbes::write()
{
if (!pointField::empty())
if (!prober().empty())
{
(void) prepare(ACTION_WRITE);
@ -182,7 +184,7 @@ bool Foam::functionObjects::thermoCoupleProbes::write()
bool Foam::functionObjects::thermoCoupleProbes::execute()
{
if (!pointField::empty())
if (!prober().empty())
{
scalar dt = mesh_.time().deltaTValue();
scalar t = mesh_.time().value();

View File

@ -42,7 +42,8 @@ void Foam::functionObjects::thermoCoupleProbes::writeValues
os << setw(w) << timeValue;
forAll(*this, probei)
const pointField& probes = prober().probeLocations();
forAll(probes, probei)
{
// if (includeOutOfBounds_ || processor_[probei] != -1)
{

View File

@ -130,8 +130,9 @@ See also
Foam::cellBitSet::select
SourceFiles
vtkWrite.C
vtkWriteImpl.C
vtkWrite.cxx
vtkWriteImpl.cxx
vtkWriteUpdate.cxx
\*---------------------------------------------------------------------------*/
@ -193,7 +194,7 @@ class vtkWrite
bool writeIds_;
//- Track changes in mesh geometry
enum polyMesh::readUpdateState meshState_;
polyMesh::readUpdateState meshState_;
//- Requested names of regions to process
wordRes selectRegions_;
@ -294,13 +295,6 @@ class vtkWrite
) const;
//- No copy construct
vtkWrite(const vtkWrite&) = delete;
//- No copy assignment
void operator=(const vtkWrite&) = delete;
public:
//- Runtime type information
@ -317,6 +311,12 @@ public:
const dictionary& dict
);
//- No copy construct
vtkWrite(const vtkWrite&) = delete;
//- No copy assignment
void operator=(const vtkWrite&) = delete;
//- Destructor
virtual ~vtkWrite() = default;

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