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.
Description
This fvModel applies forcing to the liquid phase-fraction field and all
components of the vector field to relax the fields towards those
calculated from the current wave distribution.
The force coefficient \f$\lambda\f$ should be set based on the desired level
of forcing and the residence time the waves through the forcing zone. For
example, if waves moving at 2 [m/s] are travelling through a forcing zone 8
[m] in length, then the residence time is 4 [s]. If it is deemed necessary
to force for 5 time-scales, then \f$\lambda\f$ should be set to equal 5/(4
[s]) = 1.2 [1/s]. If more aggressive forcing is required adjacent to the
boundaries, which is often the case if wave boundary conditions are
specified at outflow boundaries, the optional \f$\lambdaBoundary\f$
coefficient can be specified higher than the value of \f$\lambda\f$.
Alternatively the forcing force coefficient \f$\lambdaCoeff\f$ can be
specified in which case \f$\lambda\f$ is evaluated by multiplying the
maximum wave speed by \f$\lambdaCoeff\f$ and dividing by the forcing region
length. \f$\lambdaBoundary\f$ is similarly evaluated from
\f$\lambdaBoundaryCoeff\f$ if specified.
Usage
Example usage:
\verbatim
waveForcing1
{
type waveForcing;
libs ("libwaves.so");
liquidPhase water;
// Define the line along which to apply the graduation
origin (600 0 0);
direction (-1 0 0);
// // Or, define multiple lines
// origins ((600 0 0) (600 -300 0) (600 300 0));
// directions ((-1 0 0) (0 1 0) (0 -1 0));
scale
{
type halfCosineRamp;
start 0;
duration 300;
}
lambdaCoeff 2; // Forcing coefficient
// lambdaBoundaryCoeff 10; // Optional boundary forcing coefficient
// Useful when wave BCs are specified at outlets
// Write the forcing fields: forcing:scale, forcing:forceCoeff
writeForceFields true;
}
\endverbatim
e.g.
waveForcing1
{
type waveForcing;
libs ("libwaves.so");
liquidPhase water;
// Define the line along which to apply the graduation
origin (600 0 0);
direction (-1 0 0);
// // Or, define multiple lines
// origins ((600 0 0) (600 -300 0) (600 300 0));
// directions ((-1 0 0) (0 1 0) (0 -1 0));
scale
{
type halfCosineRamp;
start 0;
duration 300;
}
lambda 0.5; // Forcing coefficient
// lambdaBoundary 2; // Optional boundary forcing coefficient
// Useful when wave BCs are specified
// without mean flow
// Write the forcing fields: forcing:scale, forcing:forceCoeff
writeForceFields true;
}
will write the fields forcing:scale and forcing:forceCoeff at the start of the
run to visualise and check correctness.
In order to add convergence control to multi-region cases it is no longer
necessary to provide a residualControl entry in all region, convergence
specification can be provided for any sub-set of the region for which particular
residual levels should be met.
The tutorials/multiRegion/CHT/circuitBoardCooling case now has valid convergence
criteria to demonstrate this change.
Population balance size-group fraction 'f<index>.<phase>' fields are now
read from an 'fDefault.<phase>' field if they are not provided
explicitly. This is the same process as is applied to species fractions
or fvDOM rays. The sum-of-fs field 'f.<phase>' is no longer required.
The value of a fraction field and its boundary conditions must now be
specified in the corresponding field file. Value entries are no longer
given in the size group dictionaries in the constant/phaseProperties
file, and an error message will be generated if a value entry is found.
The fraction fields are now numbered programatically, rather than being
named. So, the size-group dictionaries do not require a name any more.
All of the above is also true for any 'kappa<index>.<phase>' fields that
are constructed and solved for as part of a fractal shape model.
The following is an example of a specification of a population balance
with two phases in it:
populationBalances (bubbles);
air1
{
type pureIsothermalPhaseModel;
diameterModel velocityGroup;
velocityGroupCoeffs
{
populationBalance bubbles;
shapeModel spherical;
sizeGroups
(
{ dSph 1e-3; } // Size-group #0: Fraction field f0.air1
{ dSph 2e-3; } // ...
{ dSph 3e-3; }
{ dSph 4e-3; }
{ dSph 5e-3; }
);
}
residualAlpha 1e-6;
}
air2
{
type pureIsothermalPhaseModel;
diameterModel velocityGroup;
velocityGroupCoeffs
{
populationBalance bubbles;
shapeModel spherical;
sizeGroups
(
{ dSph 6e-3; } // Size-group #5: Fraction field f5.air2
{ dSph 7e-3; } // ...
{ dSph 8e-3; }
{ dSph 9e-3; }
{ dSph 10e-3; }
{ dSph 11e-3; }
{ dSph 12e-3; }
);
}
residualAlpha 1e-6;
}
Previously a fraction field was constructed automatically using the
boundary condition types from the sum-of-fs field, and the value of both
the internal and boundary field was then overridden by the value setting
provided for the size-group. This procedure doesn't generalise to
boundary conditions other than basic types that store no additional
data, like zeroGradient and fixedValue. More complex boundary conditions
such as inletOutlet and uniformFixedValue are incompatible with this
approach.
This is arguably less convenient than the previous specification, where
the sizes and fractions appeared together in a table-like list in the
sizeGroups entry. In the event that a substantial proportion of the
size-groups have a non-zero initial fraction, writing out all the field
files manually is extremely tedious. To mitigate this somewhat, a
packaged function has been added to initialise the fields given a file
containing a size distribution (see the pipeBend tutorial for an example
of its usage). This function has the same limitations as the previous
code in that it requires all boundary conditions to be default
constructable.
Ultimately, the "correct" fix for the issue of how to set the boundary
conditions conveniently is to create customised inlet-outlet boundary
conditions that determine their field's position within the population
balance and evaluate a distribution to determine the appropriate inlet
value. This work is pending funding.
The momentum equation central coefficient and drag matrix is formulated,
inverted and used to eliminate the drag terms from each of the phase momentum
equations which are combined for formulate a drag-implicit pressure equation.
This eliminates the lagged drag terms from the previous formulation which
significantly improves convergence for small particle and Euler-VoF high-drag
cases.
It would also be possible to refactor the virtual-mass terms and include the
central coefficients of the phase acceleration terms in the drag matrix before
inversion to further improve the implicitness of the phase momentum-pressure
coupling for bubbly flows. This work is pending funding.
Mixture classes (e.g., pureMixtrure, coefficientMulticomponentMixture),
now have no fvMesh or volScalarField dependence. They operate on
primitive values only. All the fvMesh-dependent functionality has been
moved into the base thermodynamic classes. The 'composition()' access
function has been removed from multi-component thermo models. Functions
that were once provided by composition base classes such as
basicSpecieMixture and basicCombustionMixture are now implemented
directly in the relevant multi-component thermo base class.
Description
Calculates and applies the random OU (Ornstein-Uhlenbeck) process force to
the momentum equation for direct numerical simulation of boxes of isotropic
turbulence.
The energy spectrum is calculated and written at write-times which is
particularly useful to test and compare LES SGS models.
Note
This random OU process force uses a FFT to generate the force field which
is not currently parallelised. Also the mesh the FFT is applied to must
be isotropic and have a power of 2 cells in each direction.
Usage
Example usage:
\verbatim
OUForce
{
type OUForce;
libs ("librandomProcesses.so");
sigma 0.090295;
alpha 0.81532;
kUpper 10;
kLower 7;
}
\endverbatim
The tutorials/incompressibleFluid/boxTurb16 tutorial case is an updated version
of the original tutorials/legacy/incompressible/dnsFoam/boxTurb16 case,
demonstrating the use of the OUForce fvModel with the incompressibleFluid solver
module to replicate the behaviour of the legacy dnsFoam solver application.
for the multiphaseEuler solver module, replacing the more specific
uniformFixedMultiphaseHeatFluxFvPatchScalarField as it provide equivalent
functionality if the heat-flux q is specified.
multiphaseExternalTemperatureFvPatchScalarField is derived from the refactored
and generalised externalTemperatureFvPatchScalarField, overriding the
getKappa member function to provide the multiphase equivalents of kappa and
other heat transfer properties. All controls for
multiphaseExternalTemperatureFvPatchScalarField are the same as for
externalTemperatureFvPatchScalarField:
Class
Foam::externalTemperatureFvPatchScalarField
Description
This boundary condition applies a heat flux condition to temperature
on an external wall. Heat flux can be specified in the following ways:
- Fixed power: requires \c Q
- Fixed heat flux: requires \c q
- Fixed heat transfer coefficient: requires \c h and \c Ta
where:
\vartable
Q | Power Function1 of time [W]
q | Heat flux Function1 of time [W/m^2]
h | Heat transfer coefficient Function1 of time [W/m^2/K]
Ta | Ambient temperature Function1 of time [K]
\endvartable
Only one of \c Q or \c q may be specified, if \c h and \c Ta are also
specified the corresponding heat-flux is added.
If the heat transfer coefficient \c h is specified an optional thin thermal
layer resistances can also be specified through thicknessLayers and
kappaLayers entries.
The patch thermal conductivity \c kappa is obtained from the region
thermophysicalTransportModel so that this boundary condition can be applied
directly to either fluid or solid regions.
Usage
\table
Property | Description | Required | Default value
Q | Power [W] | no |
q | Heat flux [W/m^2] | no |
h | Heat transfer coefficient [W/m^2/K] | no |
Ta | Ambient temperature [K] | if h is given |
thicknessLayers | Layer thicknesses [m] | no |
kappaLayers | Layer thermal conductivities [W/m/K] | no |
relaxation | Relaxation for the wall temperature | no | 1
emissivity | Surface emissivity for radiative flux to ambient | no | 0
qr | Name of the radiative field | no | none
qrRelaxation | Relaxation factor for radiative field | no | 1
\endtable
Example of the boundary condition specification:
\verbatim
<patchName>
{
type externalTemperature;
Ta constant 300.0;
h uniform 10.0;
thicknessLayers (0.1 0.2 0.3 0.4);
kappaLayers (1 2 3 4);
value $internalField;
}
\endverbatim
See also
Foam::mixedFvPatchScalarField
Foam::Function1
This provides a smooth solution but it is not clear if this is more accurate
than running the cellMomentum p-U algorithm which generates complex transients
in the solution.
Lagrangian's dependency set is simpler than it used to be. There is no
longer a need to maintain a separate library for models that depend on
the momentum transport modelling.
Description
Specify an include file for #calc, expects a single string to follow.
For example if functions from transform.H are used in the #calc expression
\verbatim
angleOfAttack 5; // degs
angle #calc "-degToRad($angleOfAttack)";
#calcInclude "transform.H"
liftDir #calc "transform(Ry($angle), vector(0, 0, 1))";
dragDir #calc "transform(Ry($angle), vector(1, 0, 0))";
\endverbatim
The usual expansion of environment variables and other constructs
(eg, the \c ~OpenFOAM/ expansion) is retained.
See also:
Class
Foam::functionEntries::calcEntry
Description
Uses dynamic compilation to provide calculating functionality
for entering dictionary entries.
E.g.
\verbatim
a 1.0;
b 3;
c #calc "$a*$b";
\endverbatim
Note the explicit trailing 0 ('1.0') to force a to be read (and written)
as a floating point number.
Special care is required for calc entries that include a division since
"/" is also used as the scoping operator to identify keywords in
sub-dictionaries. For example, "$a/b" expects a keyword "b" within a
sub-dictionary named "a". A division can be correctly executed by using a
space between a variables and "/", e.g.
\verbatim
c #calc "$a / $b";
\endverbatim
or "()" scoping around the variable, e.g.
\verbatim
c #calc "($a)/$b";
\endverbatim
Additional include files for the #calc code compilation can be specified
using the #calcInclude entry, e.g. if functions from transform.H are used
\verbatim
angleOfAttack 5; // degs
angle #calc "-degToRad($angleOfAttack)";
#calcInclude "transform.H"
liftDir #calc "transform(Ry($angle), vector(0, 0, 1))";
dragDir #calc "transform(Ry($angle), vector(1, 0, 0))";
\endverbatim
Note:
Internally this is just a wrapper around codeStream functionality - the
#calc string is used to construct a dictionary for codeStream.
Simplifications have been made where possible, as permitted by the new
$<type>var syntax. Duplication has been reduced in similar blockMesh
files (e.g., sloshingTank cases). Settings that cannot practically be
changed have been hard-coded (e.g., angle in the mixerVessel2D
blockMeshDict). The rotor2D blockMeshDict has been centralised and
extended to work with an arbitrary number of rotor blades.
This makes the block/edge/face configuration much more similar between
the four different sections of this mesh. It is also useful as it
permits sections to be decativated by commenting them out without
this affecting all the subsequent numbering.
setFormat no longer defaults to the value of graphFormat optionally set in
controlDict and must be set in the functionObject dictionary.
boundaryFoam, financialFoam and pdfPlot still require a graphFormat entry in
controlDict but this is now read directly rather than by Time.
The parcelsPerSecond control can now be specified as a time-varying
function. This provides additional control over the temporal
distribution of injected parcels, which may be advantageous if, for
example, the mass flow rate varies significantly. It also enables
variable flow rates of particulates in cases which have a fixed number
of particles per parcel.
Description
fvMeshTopoChanger which maps the fields to a new mesh or sequence of meshes
which can optionally be mapped to repeatedly for example in multi-cycle
engine cases or cycled through for symmetric forward and reverse motion.
Usage
\table
Property | Description | Required | Default value
libs | Libraries to load | no |
times | List of times for the meshes | yes |
repeat | Repetition period | no |
cycle | Cycle period | no |
begin | Begin time for the meshes | no | Time::beginTime()
timeDelta | Time tolerance used for time -> index | yes |
\endtable
Examples of the mesh-to-mesh mapping for the multi-cycle
tutorials/incompressibleFluid/movingCone case:
\verbatim
topoChanger
{
type meshToMesh;
libs ("libmeshToMeshTopoChanger.so");
times (0.0015 0.003);
cycle #calc "1.0/300.0";
begin 0;
timeDelta 1e-6;
}
\endverbatim