Commit Graph

16 Commits

Author SHA1 Message Date
a3e38977c6 nonConformalMappedWall: New patch type for connecting regions
A new nonConformalMappedWall patch type has been added which can couple
between different regions of a multi-region simulation. This patch type
uses the same intersection algorithm as the nonConformalCyclic patch,
which is used for coupling sections of a mesh within the same region.

The nonConformalMappedWall provides some advantages over the existing
mappedWall patches:

  - The connection it creates is not interpolative. It creates a pair of
    coupled finite-volume faces wherever two opposing faces overlap.
    There is therefore no interpolation error associated with mapping
    values across the coupling.

  - Faces (or parts of faces) which do not overlap are not normalised
    away by an interpolation or averaging process. Instead, they are
    assigned an alternative boundary condition; e.g., an external
    constraint, or even another non-conformal cyclic or mapped wall.
    This makes the system able to construct partially-overlapping
    couplings.

  - The direct non-interpolative transfer of values between the patches
    makes the method equivalent to a conformal coupling. Properties of
    the solution algorithm, such as conservation and boundedness, are
    retained regardless of the non-conformance of the boundary meshes.

  - All constructed finite volume faces have accurate centre points.
    This makes the method second order accurate in space.

Usage:

Non-conformal mapped wall couplings are constructed as the last stage of
a multi-region meshing process. First, a multi-region mesh is
constructed in one of the usual ways, but with the boundaries specified
as standard non-coupled walls instead of a special mapped type. Then,
createNonConformalCouples is called to construct non-conformal mapped
patches that couple overlapping parts of these non-coupled walls. This
process is very similar to the construction of non-conformal cyclics.

createNonConformalCouples requires a
system/createNonConformalCouplesDict in order to construct non-conformal
mapped walls. Each coupling is specified in its own sub-dictionary, and
a "regions" entry is used to specify the pair of regions that the
non-conformal mapped wall will couple. Non-conformal cyclics can also be
created using the same dictionary, and will be assumed if the two
specified regions are the same, or if a single "region" entry is
specified. For example:

    // Do not modify the fields
    fields  no;

    // List of non-conformal couplings
    nonConformalCouples
    {
        // Non-conformal cyclic interface. Only one region is specified.
        fluidFluid
        {
            region      fluid;
            originalPatches (nonCoupleRotating nonCoupleStationary);
        }

        // Non-conformal mapped wall interface. Two different regions
        // have been specified.
        fluidSolid
        {
            regions     (fluid solid);
            originalPatches (nonCoupleRotating nonCoupleStationary);
        }
    }

After this step, a case should execute with foamMultiRun and decompose
and reconstruct and post-process normally.

One additional restriction for parallelised workflows is that
decomposition and reconstruction must be done with the -allRegions
option, so that the both sides of the coupling are available to the
decomposition/reconstruction algorithm.

Tutorials:

Two tutorials have been added to demonstrate use of this new
functionality:

  - The multiRegion/CHT/misalignedDuct case provides a simple visual
    confirmation that the patches are working (the exposed corners of
    the solid will be hot if the non-conformal mapped walls are active),
    and it demonstrates createNonConformalCouples's ability to add
    boundary conditions to existing fields.

  - The multiRegion/CHT/notchedRoller case demonstrates use of
    non-conformal mapped walls with a moving mesh, and also provides an
    example of parallelised usage.

Notes for Developers:

A coupled boundary condition now uses a new class,
mappedFvPatchBaseBase, in order to perform a transfer of values to or
from the neighbouring patch. For example:

    // Cast the patch type to it's underlying mapping engine
    const mappedFvPatchBaseBase& mapper =
        mappedFvPatchBaseBase::getMap(patch());

    // Lookup a field on the neighbouring patch
    const fvPatchScalarField& nbrTn =
        mapper.nbrFvPatch().lookupPatchField<volScalarField, scalar>("T");

    // Map the values to this patch
    const scalarField Tn(mapper.fromNeighbour(nbrTn));

For this to work, the fvPatch should be of an appropriate mapped type
which derives from mappedFvPatchBaseBase. This mappedFvPatchBaseBase
class provides an interface to to both conformal/interpolative and
non-conformal mapping procedures. This means that a coupled boundary
condition implemented in the manner above will work with either
conformal/interpolative or non-conformal mapped patch types.

Previously, coupled boundary conditions would access a mappedPatchBase
base class of the associated polyPatch, and use that to transfer values
between the patches. This direct dependence on the polyPatch's mapping
engine meant that only conformal/interpolative fvPatch fields that
corresponded to the polyPatch's geometry could be mapped.
2024-01-30 11:21:58 +00:00
716cab7618 fvMesh: Split construction
This provides finer control as to when the changes get constructed and
initial stitching is performed. These is needed by certain processes,
notably decomposition and reconstruction.

By default, the mesh still performs all these operations on a "normal"
read-construction. A flag has to be passed explicitly to the constructor
in order to prevent the post-construction steps.
2024-01-30 09:10:58 +00:00
f1ab9882c7 solvers: Split moveMesh from motionCorrector
This is so that stitching is complete across all regions before any FV
operations are attempted.
2024-01-30 09:10:58 +00:00
77eec2cda3 MultiRegionRefs, MultiRegionUList, MultiRegionList: Centralised region prefixing
These classes permit any PtrList of region-associated objects (meshes,
solvers, domainDecompositions, ...) to prefix the region name to the log.

At present these classes are used by decomposePar and reconstructPar
only. The foamMultiRun solver still handles its own prefixing.
2023-11-23 10:35:18 +00:00
2779442d2a functionObjects::fluidMaxDeltaT: New functionObject to set the maximum Courant number and time-step
at Function1s of time.

Underlying this new functionObject is a generalisation of the handling of the
maximum time-step in the modular solvers to allow complex user-specification of
the maximum time-step used in a simulation, not just the time-dependency
provided by fluidMaxDeltaT but functions of anything in the simulation by
creating a specialised functionObject in which the maxDeltaT function is
defined.

The chemical and combustion time-scale functionObjects adjustTimeStepToChemistry
and adjustTimeStepToCombustion have been updated and simplified using the above
mechanism.
2023-07-20 14:37:18 +01:00
00cb37652f foamRun,foamMultiRun: fvModels are now corrected directly
This ensures that all fvModels in all regions are updated before continuity is
predicted in any region so that inter-region mass transfers are included in the
region continuity equations.
2023-05-17 14:31:11 +01:00
05ffb6a6ff Info: Use nl rather than "\n..." to ensure region-prefixed printing 2023-04-05 17:14:24 +01:00
4d63b39e3e foamMultiRun: Added automatic region prefixing to the Info statements in the log
e.g. for the rivuletBox case the output for a time-step now looks like:

film  Courant Number mean: 0.0003701330848 max: 0.1862204919
panel Diffusion Number mean: 0.007352456305 max: 0.1276468109
box   Courant Number mean: 0.006324172752 max: 0.09030825997
      deltaT = 0.001550908752
      Time = 0.08294s

film  diagonal:  Solving for alpha, Initial residual = 0, Final residual = 0, No Iterations 0
film  diagonal:  Solving for alpha, Initial residual = 0, Final residual = 0, No Iterations 0
box   diagonal:  Solving for rho, Initial residual = 0, Final residual = 0, No Iterations 0
film  DILUPBiCGStab:  Solving for Ux, Initial residual = 0.009869417958, Final residual = 2.132619614e-11, No Iterations 2
film  DILUPBiCGStab:  Solving for Uy, Initial residual = 0.0002799662756, Final residual = 6.101011285e-12, No Iterations 1
film  DILUPBiCGStab:  Solving for Uz, Initial residual = 1, Final residual = 1.854120599e-12, No Iterations 2
box   DILUPBiCGStab:  Solving for Ux, Initial residual = 0.004071057403, Final residual = 4.79249226e-07, No Iterations 1
box   DILUPBiCGStab:  Solving for Uy, Initial residual = 0.006370817152, Final residual = 9.606673696e-07, No Iterations 1
box   DILUPBiCGStab:  Solving for Uz, Initial residual = 0.0158299327, Final residual = 2.104129791e-06, No Iterations 1
film  DILUPBiCGStab:  Solving for e, Initial residual = 0.0002888908396, Final residual = 2.301587523e-11, No Iterations 1
panel GAMG:  Solving for e, Initial residual = 0.00878508958, Final residual = 7.807579738e-12, No Iterations 1
box   DILUPBiCGStab:  Solving for h, Initial residual = 0.004403989559, Final residual = 1.334113552e-06, No Iterations 1
film  DILUPBiCGStab:  Solving for alpha, Initial residual = 0.0002760406755, Final residual = 2.267583256e-14, No Iterations 1
film  time step continuity errors : sum local = 9.01334987e-12, global = 2.296671859e-13, cumulative = 1.907846466e-08
box   GAMG:  Solving for p_rgh, Initial residual = 0.002842335602, Final residual = 1.036572819e-05, No Iterations 4
box   diagonal:  Solving for rho, Initial residual = 0, Final residual = 0, No Iterations 0
box   time step continuity errors : sum local = 4.538744531e-07, global = 1.922637799e-08, cumulative = -6.612579497e-09
box   GAMG:  Solving for p_rgh, Initial residual = 1.283128787e-05, Final residual = 7.063185653e-07, No Iterations 2
box   diagonal:  Solving for rho, Initial residual = 0, Final residual = 0, No Iterations 0
box   time step continuity errors : sum local = 3.069629869e-08, global = 3.780547824e-10, cumulative = -6.234524715e-09
      ExecutionTime = 19.382601 s  ClockTime = 20 s

film  Courant Number mean: 0.0003684434169 max: 0.1840342756
panel Diffusion Number mean: 0.007352456305 max: 0.1276468109
box   Courant Number mean: 0.006292704463 max: 0.09016861809
      deltaT = 0.001550908752
      Time = 0.0844909s

where each line printed by each region solver is prefixed by the region name.
Global messages for the time-step and time are just prefixed with spaces to
align them with the region output.
2023-03-08 10:59:13 +00:00
9621cbf704 regionSolvers: Added #include "solver.H" 2023-03-07 15:37:55 +00:00
67e692b5a8 foamRun, foamMultiRun: Pre-load the solver libraries before the mesh/meshes are constructed
to ensure that any solver-specific patch types are available before mesh construction.
2023-03-07 13:18:33 +00:00
189c52389f solver::deltaTFactor: renamed from maxIncreaseDeltaT to clarify that it is a multiplying factor 2023-02-01 11:54:17 +00:00
0543521992 solver: Make time-step fractional increase available externally 2023-01-31 15:01:01 +00:00
fcab778f57 solvers: Adjust time step even if Courant number is zero
This change means that even if the Courant number is zero, the time step
is adjusted based on maximum time step settings and/or constraints
specified by active fvModels. If none of these additional constraints
are present then adjustment is deactivated.
2023-01-26 08:34:07 +00:00
ce42ebc5d7 thermophysicalTransportModel: added predict() function
None of the current thermophysicalTransportModels solve transport equations in
order to evaluate the thermophysical transport properties so it makes more sense
that the evaluation occurs at the beginning of the time-step rather than at the
end where conservative fluxes are available for transport solution.  To enable
this the correct() functions have been renamed predict() and called in the
prePredictor() step of foamRun and foamMultiRun and at the beginning of the
time-step in the legacy solvers.  A particular advantage of this approach is
that complex data cached in the thermophysicalTransportModels can now be deleted
following mesh topology changes and recreated in the predict() call which is
more efficient than attempting to register and map the data.

An empty correct() function is included in addition to the new predict()
function in thermophysicalTransportModel to support scalar flux transport
closure in the future if needed.

Additionally the two transport model corrector function calls in foamRun and
foamMultiRun have been combined into a single postCorrector() call to allow
greater flexibility in transport property prediction and correction in the
modular solvers.
2022-12-15 14:59:44 +00:00
ed7e703040 Time::timeName(): no longer needed, calls replaced by name()
The timeName() function simply returns the dimensionedScalar::name() which holds
the user-time name of the current time and now that timeName() is no longer
virtual the dimensionedScalar::name() can be called directly.  The timeName()
function implementation is maintained for backward-compatibility.
2022-11-30 15:53:51 +00:00
29b82422d7 applications/solvers/modules: Reorganised to match the structure of tutorials/modules
Given that the number of solid solver modules is currently 1 and unlikely to
exceed 3 it is not very useful to maintain solid and fluid sub-directories and
easier to see the correspondence between the solver modules and tutorial cases
without.
2022-11-16 23:28:59 +00:00