Corrected according to the original reference:
Marschall, H. (2011).
Towards the numerical simulation of multi-scale two-phase flows.
PhD Thesis, TU München.
The syntax of this model has changed to permit transfers of species in
either direction. A list of transferring species is now given for each
phase, rather than identifying a single reacting phase. For example:
phaseTransfer
(
vapour_particles
{
type reactionDriven;
// TiO2 and TiO2_s are created by reactions in the vapour
// and are then transferred to the particles
species.vapour (TiO2 TiO2_s);
// H2O is created by reactions in the particles and is then
// transferred to the vapour
species.particles (H2O);
}
);
These models represent a phase nucleating directly out of a
multi-component mixture into isolated particles (i.e., homogeneous),
rather than onto an existing surface or impurity (heterogeneous).
The homogeneousCondensation model can represent the initial stages of a
gas condensing into a liquid. Example usage, in constant/fvModels:
homogeneousCondensation
{
type homogeneousCondensation;
libs ("libmultiphaseEulerFvModels.so");
// Phases between which the transfer occurs. The first phase is the
// gas, and the second is the condensed liquid.
phases (gas water);
// The specie that is condensing
specie H2O;
// Linearise the latent heat contribution into the energy equation?
energySemiImplicit no;
// Saturation curve for the specie in the gaseous phase
pSat ArdenBuck;
}
The homogeneousLiquidPhaseSeparation model can represent the initial
stages of a liquid solution precipitating out a solid or separating into
two immiscible liquid phases: Example usage, in constant/fvModels:
homogeneousLiquidPhaseSeparation
{
type homogeneousLiquidPhaseSeparation;
libs ("libmultiphaseEulerFvModels.so");
// Phases between which the transfer occurs. The first phase is the
// solution, and the second is the precipitate.
phases (liquid sugar);
// The specie that is condensing
specie C2H12O6;
// Linearise the latent heat contribution into the energy equation?
energySemiImplicit no;
// Solubility given in mass of solute per mass of solvent
solubility constant 0.9;
}
If population balance is being used, then both of these models require a
source term to be applied to the size-group equations. This is achieved
by means of a new nucleationSizeGroup field source. Example usage, in
0/fDefault.water:
sources
{
homogeneousCondensation
{
type nucleationSizeGroup;
libs ("libmultiphaseEulerFvModels.so");
}
}
Functions have been added to populationBalance to generate the
volumetric allocation coefficient etaV. This is needed if a volume or
mass source is to be conveniently distributed into the size groups. The
number-based allocation coefficient, eta, is still available and is
still used in all cases within populationBalance.
The allocation bounds handling has been removed. This, as it turns out,
was just an incomplete subset of having both number- and volume-based
allocation coefficients implemented.
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.
Now that BasicThermo::Cp returns a volScalarField reference because Cp is cached
in BasicThermo code calling Cp can hold a reference rather than a copy for
efficiency.
The Clang compiler does not use std::move to transfer the result of the ternary
operator into the phase-fraction field resulting in it not being registered to
the database. To work around this limitation/bug the ternary operator is now
provided with tmp fields the result of which is passed with an IOobject to the
final field constructor to ensure it is registered and the IO options set
correctly.
An enumeration has been added to the arguments of the allocation
coefficient function, eta, to allow specification of how to allocate out
of bounds of the population balance size-groups. There are two options:
- "Clamp" will create an out-of-bounds allocation coefficient of exactly
one. This partitions unity across all size-space.
- "Extrapolate" will create an out-of-bounds allocation coefficient in
proportion to the ratio between the given size and the nearest
size-group size. This does not partition unity outside the range of
the size-groups.
The previous operation is equivalent to "Extrapolate".
It is not yet clear which method is preferable and under what
circumstances. More testing is required. The enumeration has been
created to facilitate this testing.
The specie molecular mass (Wi) and formation enthalpy (hfi) methods now
return dimensioned scalars. This permits their direct inclusion into
dimensioned field expressions. Non-dimensioned methods have been
retained with a "Value" suffix (i.e., WiValue and hfiValue).
All property functions in the low-level templated thermo property
implementations and the high-level virtual interfaces have been made
consistent. All energies and enthalpies are lower case to denote that
they are specific quantities. Molar functions have been removed as these
are no longer used anywhere.
The nearWallDist MeshObject is now deleted on mesh-change rather than updated
which is more efficient for cases with multiple mesh changes, e.g. motion,
stitching and mapping by avoiding unnecessary updates.
As a consequence of this change the wallDist::y() volScalarField reference
should not be cached across mesh changes so the turbulence models now obtain the
y field as required from the new momentumTransportModel::y() function, the
original near-wall distance function is now named momentumTransportModel::yb()
to clarify that it is the wall distance of the boundary cells.
This is consistent with the fluid solvers, and prevents failures
associated with using fields that haven't yet been updated or corrected
following mesh changes
This simple model creates a heat transfer coefficient in proportion with
the corresponding drag model's momentum transfer coefficient. A
user-defined Prandtl number and a harmonic average of the phases'
specific heats are used to specify the constant of proportionality.
This model has no physical basis. It exists primarily for testing
purposes. It has the advantage of being applicable to any interface,
including those representing segregated configurations.
Example usage:
heatTransfer
{
gas_segregatedWith_liquid
{
type Prandtl;
Pr 0.7;
}
}
The patch-specific mapper interfaces, fvPatchFieldMapper and
pointPatchFieldMapper, have been removed as they did not do anything.
Patch mapping constructors and functions now take a basic fieldMapper
reference.
An fvPatchFieldMapper.H header has been provided to aid backwards
compatability so that existing custom boundary conditions continue to
compile.
Currently in compressibleVoF vDot contains only the compressibility dilatation
effect whereas in multiphaseEuler the effect of sources are also included but
this will be refactored shortly so that the handling of mass sources and
compressibility is consistent between VoF and Euler-Euler solvers.
The previously hard-coded 1e-4 division stabilisation used when linearising vDot
for bounded semi-implicit solution of the phase-fractions is now an optional
user-input with keyword vDotResidualAlpha, e.g. in multiphaseEuler:
solvers
{
"alpha.*"
{
nAlphaCorr 1;
nAlphaSubCycles 2;
vDotResidualAlpha 1e-6;
}
.
.
.
The fact that these names create sources in their associated transport
equations is clear in context, so the name does not need to contain
'Source'.
Having 'Source' in the name is a historic convention that dates back to
when fvModels and fvConstraints were combined in a single fvOptions
interface. In this interface, disambiguation between sources and
constraints was necessary.
The full set of name changes is as follows:
accelerationSource -> acceleration
actuationDiskSource -> actuationDisk
effectivenessHeatExchangerSource -> effectivenessHeatExchanger
explicitPorositySource -> porosityForce
radialActuationDiskSource -> radialActuationDisk
rotorDiskSource -> rotorDisk
sixDoFAccelerationSource -> sixDoFAcceleration
solidEquilibriumEnergySource -> solidThermalEquilibrium
solidificationMeltingSource -> solidificationMelting
volumeFractionSource -> volumeBlockage
interRegionExplicitPorositySource -> interRegionPorosityForce
VoFSolidificationMeltingSource -> VoFSolidificationMelting
The old names are still available for backwards compatibility.
IsothermalSolidPhaseModel does not update energy and density from pressure
whereas IsothermalPhaseModel does to allow compressible fluid phases to change
volume due to pressure changes.
for thermophysical transport within stationary solid phases. This provides a
consistent interface to heat transport within solids for single and now
multiphase solvers so that for example the wallHeatFlux functionObject can now
be used with multiphaseEuler, see tutorials/multiphaseEuler/boilingBed.
Also this development supports anisotropic thermal conductivity within the
stationary solid regions which was not possible previously.
The tutorials/multiphaseEuler/bed and tutorials/multiphaseEuler/boilingBed
tutorial cases have been updated for phaseSolidThermophysicalTransportModel by
changing the thermo type in physicalProperties.solid to heSolidThermo. This
change will need to be made to all multiphaseEuler cases involving stationary
phases.
The interface for fvModels has been modified to improve its application
to "proxy" equations. That is, equations that are not straightforward
statements of conservation laws in OpenFOAM's usual convention.
A standard conservation law typically takes the following form:
fvMatrix<scalar> psiEqn
(
fvm::ddt(alpha, rho, psi)
+ <fluxes>
==
<sources>
);
A proxy equation, on the other hand, may be a derivation or
rearrangement of a law like this, and may be linearised in terms of a
different variable.
The pressure equation is the most common example of a proxy equation. It
represents a statement of the conservation of volume or mass, but it is
a rearrangement of the original continuity equation, and it has been
linearised in terms of a different variable; the pressure. Another
example is that in the pre-predictor of a VoF solver the
phase-continuity equation is constructed, but it is linearised in terms
of volume fraction rather than density.
In these situations, fvModels sources are now applied by calling:
fvModels().sourceProxy(<conserved-fields ...>, <equation-field>)
Where <conserved-fields ...> are (alpha, rho, psi), (rho, psi), just
(psi), or are omitted entirely (for volume continuity), and the
<equation-field> is the field associated with the proxy equation. This
produces a source term identical in value to the following call:
fvModels().source(<conserved-fields ...>)
It is only the linearisation in terms of <equation-field> that differs
between these two calls.
This change permits much greater flexibility in the handling of mass and
volume sources than the previous name-based system did. All the relevant
fields are available, dimensions can be used in the logic to determine
what sources are being constructed, and sources relating to a given
conservation law all share the same function.
This commit adds the functionality for injection-type sources in the
compressibleVoF solver. A following commit will add a volume source
model for use in incompressible solvers.
This change makes multiphaseEuler more consistent with other modules and
makes its sub-libraries less inter-dependent. Some left-over references
to multiphaseEulerFoam have also been removed.
The previous implementation was dimensionally inconsistent and was
missing a factor of the VbyA field. This change will, in most cases,
reduce the total impingement pressure contribution.