Forcing
VortexPasta.Forcing
— ModuleForcing
Defines methods for injecting energy onto a system of vortices.
Normal fluid forcing
VortexPasta.Forcing.NormalFluidForcing
— TypeNormalFluidForcing <: AbstractForcing
NormalFluidForcing(vn::Function; α, α′ = 0)
Forcing due to mutual friction with a normal fluid.
The normal fluid is represented by a function vn
which should take a position x⃗::SVector{N, T}
and return a velocity v⃗::SVector{N, T}
(N
is the number of dimensions, usually N = 3
).
In particular, the function could be a synthetic velocity field from the SyntheticFields
module (see below for examples).
This type of forcing defines an external velocity $\bm{v}_{\text{f}}$ affecting vortex motion, so that the actual vortex velocity $\bm{v}_{\text{L}}$ is
\[\frac{\mathrm{d}\bm{s}}{\mathrm{d}t} = \bm{v}_{\text{L}} = \bm{v}_{\text{s}} + \bm{v}_{\text{f}}.\]
Here $\bm{v}_{\text{s}}$ is the self-induced velocity obtained by applying Biot–Savart's law.
The forcing velocity is of the form:
\[\bm{v}_{\text{f}} = α \bm{s}' × \bm{v}_{\text{ns}} - α' \bm{s}' × \left( \bm{s}' × \bm{v}_{\text{ns}} \right)\]
where $\bm{s}'$ is the local unit tangent vector, $\bm{v}_{\text{ns}} = \bm{v}_{\text{n}} - \bm{v}_{\text{s}}$ is the local slip velocity, and $α$ and $α'$ are non-dimensional coefficients representing the intensity of Magnus and drag forces.
This "forcing" generally affects all lengthscales, even when $\bm{v}_{\text{n}}$ is a large-scale flow. This may be unwanted for turbulence simulations. In that case, the alternative FourierBandForcing
method can be more relevant.
Example
Define a mutual friction forcing based on a large-scale normal fluid velocity field (see SyntheticFields.FourierBandVectorField
):
julia> using VortexPasta.Forcing: NormalFluidForcing
julia> using VortexPasta.SyntheticFields: SyntheticFields, FourierBandVectorField
julia> using Random: Xoshiro
julia> rng = Xoshiro(42); # initialise random number generator (optional, but recommended)
julia> Ls = (2π, 2π, 2π); # domain dimensions
julia> vn_rms = 1.0; # typical magnitude (rms value) of normal fluid velocity components
julia> vn = FourierBandVectorField(undef, Ls; kmin = 0.1, kmax = 1.5) # create field with non-zero Fourier wavevectors kmin ≤ |k⃗| ≤ kmax
FourierBandVectorField{Float64, 3} with 9 independent Fourier coefficients in |k⃗| ∈ [1.0, 1.4142]
julia> SyntheticFields.init_coefficients!(rng, vn, vn_rms); # randomly set non-zero Fourier coefficients of the velocity field
julia> forcing = NormalFluidForcing(vn; α = 0.8, α′ = 0)
NormalFluidForcing{Float64} with:
├─ Normal velocity field: FourierBandVectorField{Float64, 3} with 9 independent Fourier coefficients in |k⃗| ∈ [1.0, 1.4142]
└─ Friction coefficients: α = 0.8 and α′ = 0.0
VortexPasta.Forcing.apply!
— FunctionForcing.apply!(forcing::AbstractForcing, vs::AbstractVector{<:Vec3}, f::AbstractFilament; [scheduler])
Apply forcing to a single filament f
with self-induced velocities vs
.
At output, the vs
vector is overwritten with the actual vortex line velocities.
The optional scheduler
keyword can be used to parallelise computations using one of the schedulers defined in OhMyThreads.jl.
Forcing.apply!(forcing::NormalFluidForcing, vs, vn, tangents; [scheduler])
This variant can be used in the case of a NormalFluidForcing
if one already has precomputed values of the normal fluid velocity and local unit tangents at filament points.
Fourier band forcing
VortexPasta.Forcing.FourierBandForcing
— TypeFourierBandForcing <: AbstractForcing
FourierBandForcing(vn::FourierBandVectorField; α, α′ = 0, filtered_vorticity = false)
Forcing due to mutual friction of a normal fluid with a Fourier-filtered superfluid velocity.
This forcing is similar to NormalFluidForcing
, but tries to only affect scales within a given band [kmin, kmax]
in Fourier space. This is achieved by a normal fluid velocity field represented by a FourierBandVectorField
, and by a modified Schwarz's equation in which only a coarse-grained superfluid flow is taken into account in the estimation of the mutual friction term.
Concretely, the vortex line velocity according to this forcing type is:
\[\frac{\mathrm{d}\bm{s}}{\mathrm{d}t} = \bm{v}_{\text{L}} = \bm{v}_{\text{s}} + \bm{v}_{\text{f}}\]
The forcing velocity is of the form:
\[\bm{v}_{\text{f}} = α \bm{s}' × \bm{v}_{\text{ns}}^{>} - α' \bm{s}' × \left( \bm{s}' × \bm{v}_{\text{ns}}^{>} \right)\]
where $\bm{v}_{\text{ns}}^{>} = \bm{v}_{\text{n}} - \bm{v}_{\text{s}}^{>}$ is a filtered slip velocity. In practice, the filtered velocity is active within the same wavenumber range [kmin, kmax]
where vn
is defined. See NormalFluidForcing
for other definitions.
Using a filtered vorticity field
To further ensure that this forcing only affects the chosen range of scales, one can pass filtered_vorticity = true
, which will replace the local unit tangent $\bm{s}'$ with a normalised coarse-grained vorticity. This corresponds to setting $\bm{s}' = \bm{ω}^{>} / |\bm{ω}^{>}|$ where $\bm{ω}^{>}$ is the Fourier-filtered vorticity field.
Abstract types
VortexPasta.Forcing.AbstractForcing
— TypeAbstractForcing
Abstract type representing a forcing method.