Commit Graph

1324 Commits

Author SHA1 Message Date
a4a03db574 DiagTensor: Added SymmTensor combination operations 2022-04-14 09:25:07 +01:00
9297b3c679 regIOobject: Added a move constructor
to resolve an issue with the unexpected registration of DimensionedFields
constructed from an unregistered temporary field.
2022-04-08 18:57:37 +01:00
47b0cd54dd fvMeshTopoChangers::meshToMesh: New fvMesh topoChanger which maps to a sequence of meshes at run-time
With fvMeshTopoChangers::meshToMesh it is now possible to map the solution to a
specified sequence of pre-generated meshes at run-time to support arbitrary mesh
changes, refinements, un-refinements, changes in region topology, geometry,
etc.  Additionally mesh-motion between the sequence of meshes is supported to
allow for e.g. piston and valve motion in engines.

The tutorials/incompressible/pimpleFoam/laminar/movingCone case has been updated
to provide a demonstration of the advantages of this run-time mesh-mapping by
mapping to meshes that are finer behind the cone and coarser in front of the
cone as the cone approaches the end of the domain, thus maintaining good
resolution while avoiding excessive cell aspect ratio as the mesh is squeezed.
The dynamicMeshDict for the movingCone case is;

mover
{
    type            motionSolver;

    libs            ("libfvMeshMovers.so" "libfvMotionSolvers.so");

    motionSolver    velocityComponentLaplacian;

    component       x;
    diffusivity     directional (1 200 0);
}

topoChanger
{
    type    meshToMesh;

    libs    ("libmeshToMeshTopoChanger.so");

    times   (0.0015 0.003);

    timeDelta 1e-6;
}

which lists the mesh mapping times 0.0015s 0.003s and meshes for these times in
directories constant/meshToMesh_0.0015 and constant/meshToMesh_0.003 are
generated in the Allrun script before the pimpleFoam run:

runApplication -a blockMesh -dict blockMeshDict.2
rm -rf constant/meshToMesh_0.0015
mkdir constant/meshToMesh_0.0015
mv constant/polyMesh constant/meshToMesh_0.0015

runApplication -a blockMesh -dict blockMeshDict.3
rm -rf constant/meshToMesh_0.003
mkdir constant/meshToMesh_0.003
mv constant/polyMesh constant/meshToMesh_0.003

runApplication -a blockMesh -dict blockMeshDict.1

runApplication $application

Note: This functionality is experimental and has only undergone basic testing.
It is likely that it does not yet work with all functionObject, fvModels
etc. which will need updating to support this form of mesh topology change.
2022-04-06 16:37:22 +01:00
1c8f92f52a cyclicPolyPatch: Option to pass transformation to component constructor 2022-04-06 14:52:25 +01:00
796e1cb2e0 cyclicTransform: Added null constructor to permit storage in a list 2022-04-06 12:26:47 +01:00
98fa8df9a1 motionSolvers::motionSolverList: Updated as a PtrDictionary
so that the input is now dictionary rather than list of dictionaries which
provides support for dictionary substitutions within the motionSolver
sub-dictionaries and also simplifies lookup of specific motionSolvers within the
list.  For example the dynamicMeshDict for the floatingObject case with a second
floating object would be:

mover
{
    type            motionSolver;

    libs            ("libfvMeshMovers.so" "librigidBodyMeshMotion.so");

    motionSolver       motionSolverList;

    solvers
    {
        floatingObject
        {
            motionSolver rigidBodyMotion;

            report          on;

            solver
            {
                type Newmark;
            }

            accelerationRelaxation 0.7;

            bodies
            {
                floatingObject
                {
                    type            cuboid;
                    parent          root;

                    // Cuboid dimensions
                    Lx              0.3;
                    Ly              0.2;
                    Lz              0.5;

                    // Density of the cuboid
                    rho             500;

                    // Cuboid mass
                    mass            #calc "$rho*$Lx*$Ly*$Lz";
                    L               ($Lx $Ly $Lz);
                    centreOfMass    (0 0 0.25);
                    transform       (1 0 0 0 1 0 0 0 1) (0.5 0.45 0.1);

                    joint
                    {
                        type            composite;
                        joints
                        (
                            {
                                type Py;
                            }
                            {
                                type Ry;
                            }
                        );
                    }

                    patches         (floatingObject);
                    innerDistance   0.05;
                    outerDistance   0.35;
                }
            }
        }

        anotherFloatingObject
        {
        .
        .
        .
        }
    }
}
2022-04-04 16:38:20 +01:00
4fe853fa87 Updated to support compilation with 64bit label
Resolves bug-report https://bugs.openfoam.org/view.php?id=3821
2022-04-04 11:22:01 +01:00
7592a81c6e polyMeshMap: New mesh to mesh map for the new mapping update function mapMesh(const polyMeshMap&)
This new mapping structure is designed to support run-time mesh-to-mesh mapping
to allow arbitrary changes to the mesh structure, for example during extreme
motion requiring significant topology change including region disconnection etc.
2022-04-04 11:15:41 +01:00
1aa194e18b Updated documentation for the distribute(const polyDistributionMap&) function 2022-04-01 09:11:09 +01:00
cd2f614a48 Added new polyTopoChangeMap and polyDistributionMap directories 2022-03-31 23:46:50 +01:00
6047f27aac polyDistributionMap: renamed from polyMeshDistributionMap for consistency with polyTopoChangeMap 2022-03-31 23:44:47 +01:00
3ace8f434b polyTopoChangeMap: Renamed from mapPolyMesh to clarify purpose and scope
The polyTopoChangeMap is the map specifically relating to polyMesh topological
changes generated by polyTopoChange and used to update and map mesh related
types and fields following the topo-change.
2022-03-31 22:05:37 +01:00
2e6eb5f2ce polyMeshDistributionMap: renamed mapDistributePolyMesh -> polyMeshDistributionMap
This is a map data structure rather than a class or function which performs the
mapping operation so polyMeshDistributionMap is more logical and comprehensible
than mapDistributePolyMesh.
2022-03-31 18:01:44 +01:00
97eee844ad fvMeshDistribute: Added support to map V0 for moving mesh cases with 2nd-order ddt
Moving mesh cases running with 2nd-order ddt schemes can now run with
re-distribution.  This does not include support for topology change including
mesh refinement which will require special complex handling for 2nd-order time
schemes.
2022-03-30 16:21:26 +01:00
14c9057a34 regIOobject: Added registered() member function 2022-03-30 13:39:40 +01:00
93b106cdfd PackedList: Make iteratorBase copy constructor public
This allows an iterator to be stored and used in the same way as a
non-const reference to an element of a non-packed list
2022-03-30 11:49:28 +01:00
4c2c4bb43d fvMesh, pointMesh: Simplified field mapping using FOR_ALL_FIELD_TYPES macro 2022-03-23 19:33:47 +00:00
ddbf2d7853 fvMesh: fvSchemes and fvSolution are now demand-driven
fvMesh is no longer derived from fvSchemes and fvSolution, these are now
demand-driven and accessed by the member functions schemes() and solution()
respectively.  This means that the system/fvSchemes and system/fvSolution files
are no longer required during fvMesh constructions simplifying the mesh
generation and manipulation phase; theses files are read on the first call of
their access functions.

The fvSchemes member function names have also been simplified taking advantage
of the context in which they are called, for example

    mesh.ddtScheme(fieldName) -> mesh.schemes().ddt(fieldName)
2022-03-23 16:23:55 +00:00
a578586c2c processorTopology: Un-templated
The template parameters were only ever polyBoundaryMesh and
processorPolyPatch. Un-templating makes mainteance and bug-fixing
quicker as it means minor modifications no longer cause a full rebuild
of OpenFOAM.
2022-03-17 11:58:06 +00:00
dc052dd20c functionObjectList: Added access to the PtrList<functionObject>::append function
to allow addition of case specific functionObjects during the run.
2022-03-10 08:58:43 +00:00
58dce31c79 cyclicPolyPatch: Added default-transform-is-none flag to constructor
This allows the patch to be derived into patches that have different
ideas about whether or not a default no-transformation is appropriate.
2022-03-08 12:04:04 +00:00
a576b72356 processorCyclicPolyPatch: Fix to message tagging
The tagging is now correct for the case when there are two processor
interfaces connected in different directions across the same cyclic.
2022-03-08 10:19:51 +00:00
b37141932a functionObjects::timeControl: Corrected initialisation of executionIndex_
needed by the adjustableRunTime option for restarted cases.
2022-03-03 15:54:32 +00:00
bb172b77ef FixedList: Correction to comparison operators 2022-02-25 17:23:21 +00:00
93be3fc011 Merge branch 'master' of github.com-OpenFOAM:OpenFOAM/OpenFOAM-dev 2022-02-24 22:41:28 +00:00
99cfbd818f blockMesh: Added warning to set defaultPatch appropriately for snappyHexMesh and 2D cases
The defaultPatch type currently defaults to empty which is appropriate for 1D
and 2D cases but not when creating the initial blockMesh for snappyHexMesh as
the presence of empty patches triggers the inappropriate application of 2D point
constraint corrections following snapping and morphing.  To avoid this hidden
problem a warning is now generated from blockMesh when the defaultPatch is not
explicitly set for cases which generate a default patch, i.e. for which the
boundary is not entirely defined.  e.g.

.
.
.
Creating block mesh topology

--> FOAM FATAL IO ERROR:
The 'defaultPatch' type must be specified for the 'defaultFaces' patch, e.g. for snappyHexMesh

    defaultPatch
    {
        name default; // optional
        type patch;
    }

or for 2D meshes

    defaultPatch
    {
        name frontAndBack; // optional
        type empty;
    }
.
.
.

All the tutorials have been update to include the defaultPatch specification as
appropriate.
2022-02-24 21:35:09 +00:00
518024dbad boundBox: Improved function documentation 2022-02-24 16:52:19 +00:00
92eaa31793 processorCyclicPolyPatch: Removed unused constructors 2022-02-24 16:16:25 +00:00
842a6021f7 functionObjects::timeControl: Converted writeInterval and executeInterval to user-time
Resolves bug-report https://bugs.openfoam.org/view.php?id=3807
2022-02-18 16:34:53 +00:00
a6cee0edbc dimensionSets: Reformatted so the .C and .H files match 2022-02-15 18:33:52 +00:00
a82f5a6fe2 GeometricField: Move sub-classes outside of the field
This permits forward declaration of the boundary and internal fields.
References and pointers to boundary fields and sliced internal fields
can now be used in situations where full instantiation of the geometric
field is not possible due to cyclic dependencies.

It has been possible as a result of this change to type the pointer to
the cell volumes field in fvMesh. Previously this was done with a void
pointer and explicit casting.
2022-02-10 09:45:41 +00:00
a7030ee97e CompactListList: Removed unnecessary templating and create unallocated base 2022-02-04 15:17:27 +00:00
96de80cf4a fvModels::actuationDiskSource: Added phase support
actuationDiskSource can now be applied to a phase in multiphaseEulerFoam, this
is most likely to be useful in regions where a single phase is present.
2022-02-02 18:58:09 +00:00
1f461cd53b fieldMapper: Use FOR_ALL_FIELD_TYPES to reduce duplication/boilerplate 2022-02-01 13:26:52 +00:00
4c2ccffacf UPtrList: Added convert method to return a UPtrList of a different type
This is useful for creating a UPtrList<BaseType> from a
UPtrList<DerivedType>, or creating a UPtrList<const Type> from a
UPtrList<Type>.

The new pointers are constructed by implicit conversion of the old ones,
so the new type must be a base class of the old type and it must not
remove const-ness.
2022-01-27 10:07:48 +00:00
8cb90dab4f functionObjectList: Improved error message if a functionObject configuration file is not foundation
e.g. if streamlinesLines is specified rather than the correct streamlinesLine in
the controlDict::functions list:

functions
{
    #includeFunc streamlinesLines
    (
        funcName=streamlines,
        start=(-0.0205 0.001 0.00001),
        end=(-0.0205 0.0251 0.00001),
        nPoints=10,
        fields=(p k U)
    )
}

the following error message is generated providing a list of all the
functionObject configuration files available and the run stops rather than
continuing regardless of the error:

--> FOAM FATAL IO ERROR:
Cannot find functionObject configuration file streamlinesLines

Available configured functionObjects:
88
(
CourantNo
Lambda2
MachNo
PecletNo
Q
Qdot
XiReactionRate
add
age
boundaryProbes
cellMax
cellMaxMag
cellMin
cellMinMag
components
cutPlaneSurface
ddt
div
divide
dsmcFields
enstrophy
faceZoneAverage
faceZoneFlowRate
fieldAverage
flowType
forceCoeffsCompressible
forceCoeffsIncompressible
forcesCompressible
forcesIncompressible
grad
graphCell
graphCellFace
graphFace
graphLayerAverage
graphUniform
interfaceHeight
internalProbes
isoSurface
log
mag
magSqr
moments
multiply
particles
patchAverage
patchDifference
patchFlowRate
patchIntegrate
patchSurface
phaseForces
phaseMap
phaseScalarTransport
probes
randomise
residuals
scalarTransport
scale
shearStress
sizeDistribution
staticPressureIncompressible
stopAtClockTime
stopAtFile
streamFunction
streamlinesLine
streamlinesPatch
streamlinesPoints
streamlinesSphere
subtract
surfaceInterpolate
time
timeStep
totalEnthalpy
totalPressureCompressible
totalPressureIncompressible
triSurfaceDifference
triSurfaceVolumetricFlowRate
turbulenceFields
turbulenceIntensity
uniform
vorticity
wallHeatFlux
wallHeatTransferCoeff
wallShearStress
writeCellCentres
writeCellVolumes
writeObjects
writeVTK
yPlus
)

file: /home/dm2/henry/OpenFOAM/OpenFOAM-dev/tutorials/incompressible/simpleFoam/pitzDaily/system/controlDict/functions

    From function static bool Foam::functionObjectList::readFunctionObject(const Foam::string&, Foam::dictionary&, const Foam::Pair<Foam::string>&, const Foam::word&)
    in file db/functionObjects/functionObjectList/functionObjectList.C at line 250.

FOAM exiting
2022-01-26 12:02:07 +00:00
8bb48df87f flowRateInletVelocityFvPatchVectorField: Added optional profile entry to specify the velocity profile
The unreliable extrapolateProfile option has been replaced by the more flexible
and reliable profile option which allows the velocity profile to be specified as
a Function1 of the normalised distance to the wall.  To simplify the
specification of the most common velocity profiles the new laminarBL (quadratic
profile) and turbulentBL (1/7th power law) Function1s are provided.

In addition to the new profile option the flow rate can now be specified as a
meanVelocity, volumetricFlowRate or massFlowRate, all of which are Function1s of
time.

The following tutorials have been updated to use the laminarBL profile:
    multiphase/multiphaseEulerFoam/laminar/titaniaSynthesis
    multiphase/multiphaseEulerFoam/laminar/titaniaSynthesisSurface

The following tutorials have been updated to use the turbulentBL profile:
    combustion/reactingFoam/Lagrangian/verticalChannel
    combustion/reactingFoam/Lagrangian/verticalChannelLTS
    combustion/reactingFoam/Lagrangian/verticalChannelSteady
    compressible/rhoPimpleFoam/RAS/angledDuct
    compressible/rhoPimpleFoam/RAS/angledDuctLTS
    compressible/rhoPimpleFoam/RAS/squareBendLiq
    compressible/rhoPorousSimpleFoam/angledDuctImplicit
    compressible/rhoSimpleFoam/angledDuctExplicitFixedCoeff
    compressible/rhoSimpleFoam/squareBend
    compressible/rhoSimpleFoam/squareBendLiq
    heatTransfer/chtMultiRegionFoam/shellAndTubeHeatExchanger
    heatTransfer/chtMultiRegionFoam/shellAndTubeHeatExchanger
    incompressible/porousSimpleFoam/angledDuctImplicit
    incompressible/porousSimpleFoam/straightDuctImplicit
    multiphase/interFoam/RAS/angledDuct

Class
    Foam::flowRateInletVelocityFvPatchVectorField

Description
    Velocity inlet boundary condition creating a velocity field with
    optionally specified profile normal to the patch adjusted to match the
    specified mass flow rate, volumetric flow rate or mean velocity.

    For a mass-based flux:
    - the flow rate should be provided in kg/s
    - if \c rho is "none" the flow rate is in m3/s
    - otherwise \c rho should correspond to the name of the density field
    - if the density field cannot be found in the database, the user must
      specify the inlet density using the \c rhoInlet entry

    For a volumetric-based flux:
    - the flow rate is in m3/s

Usage
    \table
        Property     | Description             | Required    | Default value
        massFlowRate | Mass flow rate [kg/s]   | no          |
        volumetricFlowRate | Volumetric flow rate [m^3/s]| no |
        meanVelocity | Mean velocity [m/s]| no |
        profile      | Velocity profile        | no          |
        rho          | Density field name      | no          | rho
        rhoInlet     | Inlet density           | no          |
        alpha        | Volume fraction field name | no       |
    \endtable

    Example of the boundary condition specification for a volumetric flow rate:
    \verbatim
    <patchName>
    {
        type                flowRateInletVelocity;
        volumetricFlowRate  0.2;
        profile             laminarBL;
    }
    \endverbatim

    Example of the boundary condition specification for a mass flow rate:
     \verbatim
    <patchName>
    {
        type                flowRateInletVelocity;
        massFlowRate        0.2;
        profile             turbulentBL;
        rho                 rho;
        rhoInlet            1.0;
    }
    \endverbatim

    Example of the boundary condition specification for a volumetric flow rate:
    \verbatim
    <patchName>
    {
        type                flowRateInletVelocity;
        meanVelocity        5;
        profile             turbulentBL;
    }
    \endverbatim

    The \c volumetricFlowRate, \c massFlowRate or \c meanVelocity entries are
    \c Function1 of time, see Foam::Function1s.

    The \c profile entry is a \c Function1 of the normalised distance to the
    wall.  Any suitable Foam::Function1s can be used including
    Foam::Function1s::codedFunction1 but Foam::Function1s::laminarBL and
    Foam::Function1s::turbulentBL have been created specifically for this
    purpose and are likely to be appropriate for most cases.

Note
    - \c rhoInlet is required for the case of a mass flow rate, where the
      density field is not available at start-up
    - The value is positive into the domain (as an inlet)
    - May not work correctly for transonic inlets
    - Strange behaviour with potentialFoam since the U equation is not solved

See also
    Foam::fixedValueFvPatchField
    Foam::Function1s::laminarBL
    Foam::Function1s::turbulentBL
    Foam::Function1s
    Foam::flowRateOutletVelocityFvPatchVectorField
2022-01-24 19:10:39 +00:00
ded017b762 mapFields: Corrected handling of userTime
Resolves bug-report https://bugs.openfoam.org/view.php?id=3786
2022-01-18 10:52:06 +00:00
aab660450a fileOperation, timeSelector: Correct handling of negative time directories
Resolves bug-report https://bugs.openfoam.org/view.php?id=3784
2022-01-15 21:15:41 +00:00
76d8280c96 Time: Improved the time directory precision changes for variable time-step cases
Resolves bug-report https://bugs.openfoam.org/view.php?id=3781
2022-01-14 17:58:14 +00:00
fca30da1fd Time: Corrected the handling of user-time in the write time precision update
Resolves bug-report https://bugs.openfoam.org/view.php?id=3781
2022-01-13 17:38:11 +00:00
b58e1f5d5a className: Added define with name for non-template classes 2022-01-12 16:47:46 +00:00
b56f6d9109 cyclicFvPatchField: Corrected handling of rotated cyclic transformation for tensors
This correction applies to the handling of the implicit part of the matrix for
the segregates solution of the tensor components, e.g. when solving for the
Reynolds stress in cases with rotated cyclic patches.
2022-01-06 15:26:05 +00:00
a4e02fb247 MeshObject: Added DistributeableMeshObject for mesh distribution and load-balancing
The new DistributeableMeshObject MeshObject provides the interface for the
distribute(const mapDistributePolyMesh&) function used to distribute mesh
related objects following redistribution.
2021-12-24 10:05:23 +00:00
ebfe26b2b3 TimeState: Removed temporary protected status of the private member data
This temporary change is no longer needed now that integration of user-time into
Time is complete.
2021-12-24 00:11:31 +00:00
029db2748b Time: Changed all the entries in <time>/uniform/time to user-time 2021-12-09 15:53:57 +00:00
bf5f056296 fvMeshDistributors: New library for mesh redistribution and load-balancing
Basic support is now provided for dynamic mesh redistribution, particularly for
load-balancing.  The mesh distributor is selected in the optional 'distributor'
entry in dynamicMeshDict, for example in the
multiphase/interFoam/RAS/floatingObject tutorial case when run in parallel using
the new Allrun-parallel script

distributor
{
    type            decomposer;

    libs            ("libfvMeshDistributors.so");

    redistributionInterval  10;
}

in which the 'decomposer' form of redistribution is selected to call the mesh
decomposition method specified in decomposeParDict to re-decompose the mesh for
redistribution.  The redistributionInterval entry specifies how frequently mesh
redistribution takes place, in the above every 10th time-step.  An optional
maxImbalance entry is also provided to control redistribution based on the cell
distribution imbalance:

Class
    Foam::fvMeshDistributor::decomposer

Description
    Dynamic mesh redistribution using the decomposer

Usage
    Example of single field based refinement in all cells:
    \verbatim
    distributor
    {
        type            decomposer;

        libs            ("libfvMeshDistributors.so");

        // How often to redistribute
        redistributionInterval  10;

        // Maximum fractional cell distribution imbalance
        // before rebalancing
        maxImbalance    0.1;
    }
    \endverbatim

Currently mesh refinement/unrefinement and motion with redistribution is
supported but many aspects of OpenFOAM are not yet and will require further
development, in particular fvModels and Lagrangian.

Also only the geometry-based simple and hierarchical decomposition method are
well behaved for redistribution, scotch and ptScotch cause dramatic changes in
mesh distribution with a corresponding heavy communications overhead limiting
their usefulness or at least the frequency with which they should be called to
redistribute the mesh.
2021-12-09 14:06:45 +00:00
25a6d068f0 sampledSets, streamlines: Various improvements
Sampled sets and streamlines now write all their fields to the same
file. This prevents excessive duplication of the geometry and makes
post-processing tasks more convenient.

"axis" entries are now optional in sampled sets and streamlines. When
omitted, a default entry will be used, which is chosen appropriately for
the coordinate set and the write format. Some combinations are not
supported. For example, a scalar ("x", "y", "z" or "distance") axis
cannot be used to write in the vtk format, as vtk requires 3D locations
with which to associate data. Similarly, a point ("xyz") axis cannot be
used with the gnuplot format, as gnuplot needs a single scalar to
associate with the x-axis.

Streamlines can now write out fields of any type, not just scalars and
vectors, and there is no longer a strict requirement for velocity to be
one of the fields.

Streamlines now output to postProcessing/<functionName>/time/<file> in
the same way as other functions. The additional "sets" subdirectory has
been removed.

The raw set writer now aligns columns correctly.

The handling of segments in coordSet and sampledSet has been
fixed/completed. Segments mean that a coordinate set can represent a
number of contiguous lines, disconnected points, or some combination
thereof. This works in parallel; segments remain contiguous across
processor boundaries. Set writers now only need one write method, as the
previous "writeTracks" functionality is now handled by streamlines
providing the writer with the appropriate segment structure.

Coordinate sets and set writers now have a convenient programmatic
interface. To write a graph of A and B against some coordinate X, in
gnuplot format, we can call the following:

    setWriter::New("gnuplot")->write
    (
        directoryName,
        graphName,
        coordSet(true, "X", X), // <-- "true" indicates a contiguous
        "A",                    //     line, "false" would mean
        A,                      //     disconnected points
        "B",
        B
    );

This write function is variadic. It supports any number of
field-name-field pairs, and they can be of any primitive type.

Support for Jplot and Xmgrace formats has been removed. Raw, CSV,
Gnuplot, VTK and Ensight formats are all still available.

The old "graph" functionality has been removed from the code, with the
exception of the randomProcesses library and associated applications
(noise, DNSFoam and boxTurb). The intention is that these should also
eventually be converted to use the setWriters. For now, so that it is
clear that the "graph" functionality is not to be used elsewhere, it has
been moved into a subdirectory of the randomProcesses library.
2021-12-07 11:18:27 +00:00
a0ac78c129 MeshObject: Added distribute(const mapDistributePolyMesh&) for mesh-motion
To support mesh redistribution for load-balancing etc. all MeshObjects requiring
a special updateMesh(const mapPolyMesh&) function will also require a
distribute(const mapDistributePolyMesh&) to handle the redistribution of
no-field and unregistered mesh-related state data.

Fortunately there are not many MeshObjects requiring a special distribute(const
mapDistributePolyMesh&) implementation but it will take some time to implement
and test all those that do; this patch provides those for displacement-based
mesh-movers.
2021-12-06 12:27:59 +00:00
506d2891b7 transformerIOList: Centralised instantiation 2021-11-25 09:45:04 +00:00