The thermodynamic density field is now named "rho" by default and only renamed
"thermo:rho" by solvers that create and maintain a separate continuity density
field which is named "rho". This change significantly simplifies and
standardises the specification of schemes and boundary conditions requiring
density as it is now always named "rho" or "rho.<phase>" unless under some very
unusual circumstances the thermodynamic rather than continuity density is
required for a solver maintaining both.
The advantage of this change is particularly noticeable for multiphase
simulations in which each phase has its own density now named "rho.<phase>"
rather than "thermo:rho.<phase>" as separate phase continuity density fields are
not required so for multiphaseEulerFoam the scheme specification:
"div\(alphaRhoPhi.*,\(p\|thermo:rho.*\)\)" Gauss limitedLinear 1;
is now written:
"div\(alphaRhoPhi.*,\(p\|rho.*\)\)" Gauss limitedLinear 1;
The basic thermophysical properties are now considered fundamental and complex
models like kineticTheoryModel using these names for some other purpose must
disambiguate using typedName to prepend the model name to the field name.
This change standardises, rationalises and simplifies the specification of
fvSchemes and boundary conditions.
thermo:rho will also be renamed rho in a subsequent commit to complete this
rationalisation.
to enable writing of the isotropicDamping:forceCoeff isotropicDamping:scale
waveForcing:forceCoeff waveForcing:scale diagnostic fields to check the damping
and forcing distributions.
so that it can now be used with either the isothermalFluid or fluid solver
modules, thus supporting non-uniform fluid properties, compressibility and
thermal effect. This development makes the special potentialFreeSurfaceFoam
solver redundant as both the isothermalFluid and fluid solver modules are more
general and has been removed and replaced with a user redirection script.
The tutorials/multiphase/potentialFreeSurfaceFoam cases have been updated to run
with the isothermalFluid solver module:
tutorials/multiphase/potentialFreeSurfaceFoam/oscillatingBox
tutorials/multiphase/potentialFreeSurfaceFoam/movingOscillatingBox
which demonstrate how to upgrade potentialFreeSurfaceFoam cases to
isothermalFluid.
and demonstrates the wave being generated in a region adjacent to the outlet and
propagating upstream towards the inlet where it is damped by a damping region
and mesh expansion.
With waveForcing waves can be generated with a domain by applying forcing to
both the phase-fraction and velocity fields rather than requiring that the waves
are introduced at an inlet. This provides much greater flexibility as waves can
be generated in any direction relative to the mean flow, obliquely or even
against the flow. isotropicDamping or verticalDamping can be used in
conjunction with waveForcing to damp the waves before they reach an outlet,
alternatively waveForcing can be used in regions surrounding a hull for example
to maintain far-field waves everywhere.
The tutorials/multiphase/interFoam/laminar/forcedWave tutorial case is provided
to demonstrate the waveForcing fvModel as an alternative to the wave inlet
boundary conditions used in the tutorials/multiphase/interFoam/laminar/wave
case.
Class
Foam::fv::waveForcing
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 forcing 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].
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;
}
lambda 0.5; // Forcing coefficient
}
\endverbatim
Replacing the specific twoPhaseChangeModel with a consistent and general fvModel
interface will support not just cavitation using the new VoFCavitation fvModel
but also other phase-change and interface manipulation models in the future and
is easier to use for case-specific and other user customisation.
The mappedPatchBase has been separated into a type which maps from
another patch (still called mappedPatchBase) and one that maps from
internal cell values (mappedInternalPatchBase). This prevents the user
needing to specify settings for mapping procedures that are not being
used, and potentially don't even make sense given the context in which
they are being applied. It also removes a lot of fragile logic and error
states in the mapping engine and its derivatives regarding the mode of
operation. Mapping from any face in the boundary is no longer supported.
Most region-coupling mapping patches are generated automatically by
utilities like splitMeshRegions and extrudeToRegionMesh. Cases which
create region-coupling mapped patches in this way will likely require no
modification.
Explicitly user-specified mapping will need modifying, however. For
example, where an inlet boundary is mapped to a downstream position in
order to evolve a developed profile. Or if a multi-region simulation is
constructed manually, without using one of the region-generating
utilities.
The available mapped patch types are now as follows:
- mapped: Maps values from one patch to another. Typically used for
inlets and outlets; to map values from an outlet patch to an inlet
patch in order to evolve a developed inlet profile, or to permit
flow between regions. Example specification in blockMesh:
inlet
{
type mapped;
neighbourRegion region0; // Optional. Defaults to the same
// region as the patch.
neighbourPatch outlet;
faces ( ... );
}
Note that any transformation between the patches is now determined
automatically. Alternatively, it can be explicitly specified using
the same syntax as for cyclic patches. The "offset" and "distance"
keywords are no longer used.
- mappedWall: As mapped, but treated as a wall for the purposes of
modelling (wall distance). No transformation. Typically used for
thermally coupling different regions. Usually created automatically
by meshing utilities. Example:
fluid_to_solid
{
type mappedWall;
neighbourRegion solid;
neighbourPatch solid_to_fluid;
method intersection; // The patchToPatch method. See
// below.
faces ( ... );
}
- mappedExtrudedWall: As mapped wall, but with corrections to account
for the thickness of an extruded mesh. Used for region coupling
involving film and thermal baffle models. Almost always generated
automatically by extrudeToRegionMesh (so no example given).
- mappedInternal: Map values from internal cells to a patch. Typically
used for inlets; to map values from internal cells to the inlet in
order to evolve a developed inlet profile. Example:
inlet
{
type mappedInternal;
distance 0.05; // Normal distance from the patch
// from which to map cell values
//offset (0.05 0 0); // Offset from the patch from
// which to map cell values
faces ( ... );
}
Note that an "offsetMode" entry is no longer necessary. The mode
will be inferred from the presence of the distance or offset
entries. If both are provided, then offsetMode will also be required
to choose which setting applies.
The mapped, mappedWall and mappedExtrudedWall patches now permit
specification of a "method". This selects a patchToPatch object and
therefore determines how values are transferred or interpolated between
the patches. Valid options are:
- nearest: Copy the value from the nearest face in the neighbouring
patch.
- matching: As nearest, but with checking to make sure that the
mapping is one-to-one. This is appropriate for patches that are
identically meshed.
- inverseDistance: Inverse distance weighting from a small stencil of
nearby faces in the neighbouring patch.
- intersection: Weighting based on the overlapping areas with faces in
the neighbouring patch. Equivalent to the previous AMI-based mapping
mode.
If a method is not specfied, then the pre-existing approach will apply.
This should be equivalent to the "nearest" method (though in most such
cases, "matching" is probably more appropriate). This fallback may be
removed in the future once the patchToPatch methods have been proven
robust.
The important mapped boundary conditions are now as follows:
- mappedValue: Maps values from one patch to another, and optionally
modify the mapped values to recover a specified average. Example:
inlet
{
type mappedValue;
field U; // Optional. Defaults to the same
// as this field.
average (10 0 0); // The presence of this entry now
// enables setting of the average,
// so "setAverage" is not needed
value uniform 0.1;
}
- mappedInternalValue: Map values from cells to a patch, and
optionally specify the average as in mappedValue. Example:
inlet
{
type mappedValue;
field k; // Optional. Defaults to the same
// as this field.
interpolationScheme cell;
value uniform 0.1;
}
- mappedFlowRateVelocity: Maps the flow rate from one patch to
another, and use this to set a patch-normal velocity. Example:
inlet
{
type mappedFlowRate;
value uniform (0 0 0);
}
Of these, mappedValue and mappedInternalValue can override the
underlying mapped patch's settings by additionally specifying mapping
information (i.e., the neighbourPatch, offset, etc... settings usually
supplied for the patch). This also means these boundary condtions can be
applied to non-mapped patches. This functionality used to be provided
with a separate "mappedField" boundary condition, which has been removed
as it is no longer necessary.
Other mapped boundary conditions are either extremely niche (e.g.,
mappedVelocityFlux), are always automatically generated (e.g.,
mappedValueAndPatchInternalValue), or their usage has not changed (e.g.,
compressible::turbulentTemperatureCoupledBaffleMixed and
compressible::turbulentTemperatureRadCoupledMixed). Use foamInfo to
obtain further details about these conditions.
executed with foamRun for single region simulations of foamMultiRun for
multi-region simulations. Replaces compressibleInterFoam and all the
corresponding tutorials have been updated and moved to
tutorials/modules/compressibleVoF.
Class
Foam::solvers::compressibleVoF
Description
Solver module for for 2 compressible, non-isothermal immiscible fluids
using a VOF (volume of fluid) phase-fraction based interface capturing
approach, with optional mesh motion and mesh topology changes including
adaptive re-meshing.
The momentum and other fluid properties are of the "mixture" and a single
momentum equation is solved.
Either mixture or two-phase transport modelling may be selected. In the
mixture approach a single laminar, RAS or LES model is selected to model the
momentum stress. In the Euler-Euler two-phase approach separate laminar,
RAS or LES selected models are selected for each of the phases.
Uses the flexible PIMPLE (PISO-SIMPLE) solution for time-resolved and
pseudo-transient and steady simulations.
Optional fvModels and fvConstraints are provided to enhance the simulation
in many ways including adding various sources, Lagrangian
particles, surface film etc. and constraining or limiting the solution.
SourceFiles
compressibleVoF.C
See also
Foam::solvers::fluidSolver
This greatly simplifies most setups in which it is a patch (or patches)
of the original mesh which are extruded. It prevents the need for a
topoSet configuration to convert the patch into a zone or set.
An extruded region is now contiguous even when specified with multiple
face zones. Edges that border faces in different zones now extrude into
internal faces, rather than a pair of boundary faces. Different zones
now result only in different mapped patches in the extruded and primary
meshes. This means a mesh can be created for a single contiguous
extruded region spanning multiple patches. This might be necessary if,
for example, a film region is needed across multiple walls with
differing thermal boundary conditions.
Disconnected extruded regions can still be constructed by running the
extrudeToRegionMesh utility muiliple times.
The mapped patches created to couple the extruded regions now have
symmetric names similar to those created by splitMeshRegions. For
example, if the mapped patch in the primary region is called
"region0_to_extrudedRegion_f0", then the corresponding patch in the
extruded region is called "extrudedRegion_to_region0_f0" (f0, in this
example is the face zone from which the region was extruded).
Offsetting of the top patch is now handled automatically by a new
mappedExtrudedWallPolyPatch. This refers to the bottom patch and
automatically calculates the sampling offsets by doing a wave across the
extruded mesh layers. This prevents the need to store the offsets in the
patch itself, and makes it possible for the patch to undergo mesh
changes without adding additional functions to the polyPatch (mapping
constructors, autoMap and rmap methods, etc ...).
Description
General cell set selection class for models that apply to sub-sets
of the mesh.
Currently supports cell selection from a set of points, a specified cellSet
or cellZone or all of the cells. The selection method can either be
specified explicitly using the \c selectionMode entry or inferred from the
presence of either a \c cellSet, \c cellZone or \c points entry. The \c
selectionMode entry is required to select \c all cells.
Usage
Examples:
\verbatim
// Apply everywhere
selectionMode all;
// Apply within a given cellSet
selectionMode cellSet; // Optional
cellSet rotor;
// Apply within a given cellZone
selectionMode cellZone; // Optional
cellSet rotor;
// Apply in cells containing a list of points
selectionMode points; // Optional
points
(
(2.25 0.5 0)
(2.75 0.5 0)
);
\endverbatim
Also used as the base-class for fvCellSet which additionally provides and
maintains the volume of the cell set.
Description
General cell set selection class for models that apply to sub-sets
of the mesh.
Currently supports cell selection from a set of points, a specified cellSet
or cellZone or all of the cells. The selection method can either be
specified explicitly using the \c selectionMode entry or inferred from the
presence of either a \c cellSet, \c cellZone or \c points entry. The \c
selectionMode entry is required to select \c all cells.
Usage
Examples:
\verbatim
// Apply everywhere
selectionMode all;
// Apply within a given cellSet
selectionMode cellSet; // Optional
cellSet rotor;
// Apply within a given cellZone
selectionMode cellZone; // Optional
cellSet rotor;
// Apply in cells containing a list of points
selectionMode points; // Optional
points
(
(2.25 0.5 0)
(2.75 0.5 0)
);
\endverbatim
All tutorials updated and simplified.
Description
User convenience class to handle the input of time-varying rotational speed
in rad/s if \c omega is specified or rpm if \c rpm is specified.
Usage
For specifying the rotational speed in rpm of an MRF zone:
\verbatim
MRF
{
cellZone rotor;
origin (0 0 0);
axis (0 0 1);
rpm 60;
}
\endverbatim
or the equivalent specified in rad/s:
\verbatim
MRF
{
cellZone rotor;
origin (0 0 0);
axis (0 0 1);
rpm 6.28319;
}
\endverbatim
or for a tabulated ramped rotational speed of a solid body:
\verbatim
mover
{
type motionSolver;
libs ("libfvMeshMovers.so" "libfvMotionSolvers.so");
motionSolver solidBody;
cellZone innerCylinder;
solidBodyMotionFunction rotatingMotion;
origin (0 0 0);
axis (0 1 0);
rpm table
(
(0 0)
(0.01 6000)
(0.022 6000)
(0.03 4000)
(100 4000)
);
}
\endverbatim
The following classes have been updated to use the new Function1s::omega class:
solidBodyMotionFunctions::rotatingMotion
MRFZone
rotatingPressureInletOutletVelocityFvPatchVectorField
rotatingTotalPressureFvPatchScalarField
rotatingWallVelocityFvPatchVectorField
and all tutorials using these models and BCs updated to use rpm where appropriate.
MRF (multiple reference frames) can now be used to simulate SRF (single
reference frame) cases by defining the MRF zone to include all the cells is the
mesh and applying appropriate boundary conditions. The huge advantage of this
is that MRF can easily be added to any solver by the addition of forcing terms
in the momentum equation and absolute velocity to relative flux conversions in
the formulation of the pressure equation rather than having to reformulate the
momentum and pressure system based on the relative velocity as in traditional
SRF. Also most of the OpenFOAM solver applications and all the solver modules
already support MRF.
To enable this generalisation of MRF the transformations necessary on the
velocity boundary conditions in the MRF zone can no longer be handled by the
MRFZone class itself but special adapted fvPatchFields are required. Although
this adds to the case setup it provides much greater flexibility and now complex
inlet/outlet conditions can be applied within the MRF zone, necessary for some
SRF case and which was not possible in the original MRF implementation. Now for
walls rotating within the MRF zone the new 'MRFnoSlip' velocity boundary
conditions must be applied, e.g. in the
tutorials/modules/incompressibleFluid/mixerVessel2DMRF/constant/MRFProperties
case:
boundaryField
{
rotor
{
type MRFnoSlip;
}
stator
{
type noSlip;
}
front
{
type empty;
}
back
{
type empty;
}
}
similarly for SRF cases, e.g. in the
tutorials/modules/incompressibleFluid/mixerSRF case:
boundaryField
{
inlet
{
type fixedValue;
value uniform (0 0 -10);
}
outlet
{
type pressureInletOutletVelocity;
value $internalField;
}
rotor
{
type MRFnoSlip;
}
outerWall
{
type noSlip;
}
cyclic_half0
{
type cyclic;
}
cyclic_half1
{
type cyclic;
}
}
For SRF case all the cells should be selected in the MRFproperties dictionary
which is achieved by simply setting the optional 'selectionMode' entry to all,
e.g.:
SRF
{
selectionMode all;
origin (0 0 0);
axis (0 0 1);
rpm 1000;
}
In the above the rotational speed is set in RPM rather than rad/s simply by
setting the 'rpm' entry rather than 'omega'.
The tutorials/modules/incompressibleFluid/rotor2DSRF case is more complex and
demonstrates a transient SRF simulation of a rotor requiring the free-stream
velocity to rotate around the apparently stationary rotor which is achieved
using the new 'MRFFreestreamVelocity' velocity boundary condition. The
equivalent simulation can be achieved by simply rotating the entire mesh and
keeping the free-stream flow stationary and this is demonstrated in the
tutorials/modules/incompressibleFluid/rotor2DRotating case for comparison.
The special SRFSimpleFoam and SRFPimpleFoam solvers are now redundant and have
been replaced by redirection scripts providing details of the case migration
process.
Full backward-compatibility is provided which support for both multiComponentMixture and
multiComponentPhaseModel provided but all tutorials have been updated.
The cellProc field is the field of cell-processor labels.
The names "distribution" and "dist" have been removed as these are
ambiguous in relation to other forms of distribution and to distance.
This utility now always creates two patches, and only creates duplicate
faces when they connect to different cells and point in opposite
directions. Now that ACMI has been removed, there is no need to create
duplicate faces on the same cell and with similar orientations. This is
unituitive and is now considered an invalid mesh topology.
The preferred syntax for createBaffles is now as follows:
internalFacesOnly true;
baffles
{
cyclics
{
type faceZone;
zoneName cyclicFaces;
owner
{
name cyclicLeft;
type cyclic;
neighbourPatch cyclicRight;
}
neighbour
{
name cyclicRight;
type cyclic;
neighbourPatch cyclicLeft;
}
}
}
Note that the 'patches' sub-dictionary is not needed any more; the
'owner' and 'neighbour' sub-dictionaries can be in the same dictionary
as the parameters with which faces are selected. For backwards
compatibility, however, a 'patches' sub-dictionary is still permitted,
as are keywords 'master' and 'slave' (in place of 'owner' and
'neighbour', respectively).
The 'patchPairs' syntax has been removed. Whilst consise, this syntax
made a number of assumptions and decisions regarding naming conventions
that were not sufficiently intuitive for the user to understand without
extensive reference to the code. If identical boundaries are desired on
both sides of the patch, dictionary substitution provides a more
intuitive way of minimising the amount of specifiection required. For
example, to create two back-to-back walls, the following specification
could be used:
internalFacesOnly true;
fields true;
baffles
{
walls
{
type faceZone;
zoneName wallFaces;
owner
{
name baffleWallLeft;
type wall;
patchFields
{
p
{
type zeroGradient;
}
U
{
type noSlip;
}
}
}
neighbour
{
name baffleWallRight;
$owner; // <-- Use the same settings as for the owner
}
}
}
to ensure complex BCs are selected and initialised correctly.
All mixture fields are now constructed and read as required in the construction
of the liquid (phase 1) mixtureKEpsilon model to ensure they are read before
time-increment and possible mesh topology change.
The 'pointSync' setting in createPatchDict is now optional and defaults
to false. This setting is very rarely used. A number of unused
'createPatchDict' files have also been removed and obsolete information
has been removed from the annotated example dictionaries.
The following examples in the tutorials ($FOAM_TUTORIALS) directory have
been converted from using AMI to the new NCC system:
+ compressible/rhoPimpleFoam/RAS/annularThermalMixer
+ incompressible/pimpleFoam/RAS/propeller
+ lagrangian/particleFoam/mixerVessel2D (formerly mixerVesselAMI2D)
+ multiphase/interFoam/RAS/mixerVessel
+ multiphase/interFoam/RAS/propeller
+ multiphase/multiphaseEulerFoam/laminar/mixerVessel2D (formerly mixerVesselAMI2D)
The following tutorial has been converted from using ACMI:
+ incompressible/pimpleFoam/RAS/oscillatingInlet
The following tutorial has been converted from using Repeat AMI:
+ incompressible/pimpleFoam/RAS/impeller
The following tutorial has been added to demonstrate NCC's ability to
create a sufficiently conservative solution in a closed domain to
maintain phase fraction boundedness:
+ multiphase/interFoam/laminar/mixerVessel2D
The following tutorials have been added to demonstrate NCC's ability to
simulate partially overlapping couples on curved surfaces:
+ incompressible/pimpleFoam/RAS/ballValve
+ multiphase/compressibleInterFoam/RAS/ballValve
The following tutorial has been added to provide a simple comparison of
the conservation behaviour of AMI and NCC:
+ incompressible/pimpleFoam/laminar/nonConformalChannel
The following tutorial has been removed, as there were sufficiently many
examples involving this geometry:
+ incompressible/pimpleFoam/laminar/mixerVesselAMI2D
This tutorial simulates solid particle coalescence and breakage through
a 90 degree pipe bend.
Patch contributed by Kasper Gram Bilde and Institute of Fluid Dynamics,
Helmholtz-Zentrum Dresden - Rossendorf (HZDR)
On unstructured collocated meshes the Reynolds stress tends to decouple from the
velocity creating pronounced staggering patterns in the solution. This effect
is reduced or eliminated by a special coupling algorithm which replaces the
gradient diffusion component of the Reynolds stress with the equivalent compact
representation on the mesh, i.e. div-grad with Laplacian in the DivDevRhoReff function:
template<class BasicMomentumTransportModel>
template<class RhoFieldType>
Foam::tmp<Foam::fvVectorMatrix>
Foam::ReynoldsStress<BasicMomentumTransportModel>::DivDevRhoReff
(
const RhoFieldType& rho,
volVectorField& U
) const
{
tmp<volTensorField> tgradU = fvc::grad(U);
const volTensorField& gradU = tgradU();
const surfaceTensorField gradUf(fvc::interpolate(gradU));
// Interpolate Reynolds stress to the faces
// with either a stress or velocity coupling correction
const surfaceVectorField Refff
(
(this->mesh().Sf() & fvc::interpolate(R_))
// Stress coupling
+ couplingFactor_
*(this->mesh().Sf() & fvc::interpolate(this->nut()*gradU))
// or velocity gradient coupling
// + couplingFactor_
// *fvc::interpolate(this->nut())*(this->mesh().Sf() & gradUf)
- fvc::interpolate(couplingFactor_*this->nut() + this->nu())
*this->mesh().magSf()*fvc::snGrad(U)
- fvc::interpolate(this->nu())*(this->mesh().Sf() & dev2(gradUf.T()))
);
return
(
fvc::div(fvc::interpolate(this->alpha_*rho)*Refff)
- correction(fvm::laplacian(this->alpha_*rho*this->nuEff(), U))
);
}
In the above two options for the coupling term are provided, one based on the
stress correction (un-commented) and an alternative based an the velocity
gradient correction (commented). Tests run so far indicate that the stress
correction provides better coupling while minimising the error introduced.
A new tutorial case ductSecondaryFlow is provided which demonstrates the updated
coupling algorithm on the simulation of the classic secondary flow generated in
rectangular ducts.
The population balance model considers dilatation originating from density
change and mass transfer via source terms describing nucleation as well as
"drift" of the size distribution to smaller or larger sizes. Numerically, the
treatment does not necessarily equal the total dilatation, hence a correction is
introduced to ensure boundedness of the size group fractions.
Patch contributed by Institute of Fluid Dynamics,
Helmholtz-Zentrum Dresden - Rossendorf (HZDR)
and VTT Technical Research Centre of Finland Ltd.
epsilonm is obtained by combining epsilon.gas and epsilon.liquid in a two-phase
system, each of which will apply the epsilonWallFunction at walls; the
epsilonmWallFunction propagates the resulting wall epsilonm into the near-wall
cells.
If the 0/epsilonm file is provided the epsilonmWallFunction should be specified
for walls, if the 0/epsilonm file is not provided it will be generated
automatically and the epsilonmWallFunction applied to walls for which the
epsilonWallFunction is specified in the epsilon.liquid file.
fvMesh::update() now executes at the beginning of the time-step, before time is
incremented and handles topology change, mesh to mesh mapping and redistribution
without point motion. Following each of these mesh changes fields are mapped
from the previous mesh state to new mesh state in a conservative manner. These
mesh changes not occur at most once per time-step.
fvMesh::move() is executed after time is incremented and handles point motion
mesh morphing during the time-step in an Arbitrary Lagrangian Eulerian approach
requiring the mesh motion flux to match the cell volume change. fvMesh::move()
can be called any number of times during the time-step to allow iterative update
of the coupling between the mesh motion and field solution.
This required changing the formulation of the relative velocity in terms of a
scalar velocity coefficient Vc rather than the velocity V0 such that
V0 = Vc*g
where g is the acceleration due to gravity. With MRF rotation
V0 = Vc*(g + <MRF centrifugal acceleration>)