Public Documentation
Documentation for FourierFlows.jl's public interface.
See the Internals section of the manual for internal package docs covering all submodules.
FourierFlows
FourierFlows.FourierFlows — Module
Main module for FourierFlows.jl – an ecosystem for solving partial differential equations on periodic domains using Fourier-based pseudospectral methods."
Exports
AB3TimeStepperAbstractGridAbstractParamsAbstractTimeStepperAbstractVarsCPUDeviceDiagnosticETDRK4TimeStepperFilteredAB3TimeStepperFilteredETDRK4TimeStepperFilteredForwardEulerTimeStepperFilteredLSRK54TimeStepperFilteredRK4TimeStepperForwardEulerTimeStepperGPULSRK54TimeStepperOneDGridOutputRK4TimeStepperThreeDGridTimeStepperTwoDGrid@createarrayscxtypedealias!device_array@devzerosfftfltypegridpointsgroupsizeifftincrement!innereltypeirfftresize!rfftsavediagnosticsaveoutputsaveproblemstep_until!stepforward!supersize@superzerossuperzerosupdate!@zeros
FourierFlows.AbstractGrid — Type
Abstract supertype for grids.
FourierFlows.AbstractParams — Type
Abstract supertype for parameters.
FourierFlows.AbstractTimeStepper — Type
Abstract supertype for timesteppers.
FourierFlows.AbstractVars — Type
Abstract supertype for variables.
FourierFlows.CPU — Type
CPU device.
FourierFlows.Device — Type
Abstract supertype for supported devices.
FourierFlows.GPU — Type
GPU device.
Problem
Domain
FourierFlows.OneDGrid — Type
OneDGrid(dev::Device = CPU();
nx, Lx,
x0 = -Lx/2, nthreads = Sys.CPU_THREADS, effort = FFTW.MEASURE,
T = Float64, aliased_fraction = 1/3)Construct a OneDGrid on device; by default on CPU(). Grid size is Lx, resolution is nx, and leftmost position is x0. FFT plans are generated for nthreads CPUs using FFTW flag effort. The float type is T. The aliased_fraction keyword determines the highest wavenubers that are being zero-ed out by dealias! function; 1/3 is the nominal value for quadratic nonlinearities.
FourierFlows.OneDGrid — Type
struct OneDGrid{T<:AbstractFloat, A, Tx, Tfft, Trfft, Talias} <: AbstractGrid{T, A, Talias, D}A one-dimensional grid.
device::Any: device which the grid lives onnx::Int64: number of points in $x$nk::Int64: number of wavenumbers in $x$nkr::Int64: number of positive wavenumbers in $x$ (real Fourier transforms)dx::AbstractFloat: grid spacing in $x$Lx::AbstractFloat: domain extent in $x$x::Any: range with $x$-grid-pointsk::Any: array with $x$-wavenumberskr::Any: array with positive $x$-wavenumbers (real Fourier transforms)invksq::Any: array with inverse squared $k$-wavenumbers, $1 / k²$invkrsq::Any: array with inverse squared $kᵣ$-wavenumbers, $1 / kᵣ²$fftplan::Any: the FFT plan for complex-valued fieldsrfftplan::Any: the FFT plan for real-valued fieldsaliased_fraction::AbstractFloat: the fraction of wavenumbers that are aliased (e.g., 1/3 for quadradic nonlinearities)kalias::Any: range of the indices of aliased $x$-wavenumberskralias::Any: range of the indices of aliased positive $x$-wavenumbers (real Fourier transforms)
FourierFlows.ThreeDGrid — Type
ThreeDGrid(dev::Device=CPU(); nx, Lx, ny=nx, Ly=Lx, nz=nx, Lz=Lx,
x0=-Lx/2, y0=-Ly/2, z0=-Lz/2,
nthreads=Sys.CPU_THREADS, effort=FFTW.MEASURE, T=Float64,
aliased_fraction=1/3)Construct a ThreeDGrid on device; by default on CPU(). Grid size is Lx, Ly, Lz, resolution is nx, ny, nz and leftmost positions are x0, y0, z0. FFT plans are generated for nthreads CPUs using FFTW flag effort. The float type is T. The aliased_fraction keyword determines the highest wavenubers that are being zero-ed out by dealias! function; 1/3 is the nominal value for quadratic nonlinearities.
FourierFlows.ThreeDGrid — Type
struct ThreeDGrid{T<:AbstractFloat, Tk, Tx, Tfft, Trfft, Talias} <: AbstractGrid{T, Tk, Talias}A three-dimensional grid.
device::Any: device which the grid lives onnx::Int64: number of points in $x$ny::Int64: number of points in $y$nz::Int64: number of points in $z$nk::Int64: number of wavenumbers in $x$nl::Int64: number of wavenumbers in $y$nm::Int64: number of wavenumbers in $z$nkr::Int64: number of positive wavenumers in $x$ (real Fourier transforms)dx::AbstractFloat: grid spacing in $x$dy::AbstractFloat: grid spacing in $y$dz::AbstractFloat: grid spacing in $z$Lx::AbstractFloat: domain extent in $x$Ly::AbstractFloat: domain extent in $y$Lz::AbstractFloat: domain extent in $z$x::Any: range with $x$-grid-pointsy::Any: range with $y$-grid-pointsz::Any: range with $z$-grid-pointsk::Any: array with $x$-wavenumbersl::Any: array with $y$-wavenumbersm::Any: array with $z$-wavenumberskr::Any: array with positive $x$-wavenumbers (real Fourier transforms)Ksq::Any: array with squared total wavenumbers, $k² + l² + m²$invKsq::Any: array with inverse squared total wavenumbers, $1 / (k² + l² + m²)$Krsq::Any: array with squared total wavenumbers for real Fourier transforms, $kᵣ² + l² + m²$invKrsq::Any: array with inverse squared total wavenumbers for real Fourier transforms, $1 / (kᵣ² + l² + m²)$fftplan::Any: the FFT plan for complex-valued fieldsrfftplan::Any: the FFT plan for real-valued fieldsaliased_fraction::AbstractFloat: the fraction of wavenumbers that are aliased (e.g., 1/3 for quadradic nonlinearities)kalias::Any: range of the indices of aliased $x$-wavenumberskralias::Any: range of the indices of aliased positive $x$-wavenumbers (real Fourier transforms)lalias::Any: range of the indices of aliased $y$-wavenumbersmalias::Any: range of the indices of aliased $m$-wavenumbers
FourierFlows.TwoDGrid — Type
TwoDGrid(dev::Device=CPU(); nx, Lx, ny=nx, Ly=Lx,
x0=-Lx/2, y0=-Ly/2, nthreads=Sys.CPU_THREADS, effort=FFTW.MEASURE,
T=Float64, aliased_fraction=1/3)Construct a TwoDGrid on device; by default on CPU(). Grid size is Lx, Ly, resolution is nx, ny, and leftmost positions are x0, y0. FFT plans are generated for nthreads CPUs using FFTW flag effort. The float type is T. The aliased_fraction keyword determines the highest wavenubers that are being zero-ed out by dealias! function; 1/3 is the nominal value for quadratic nonlinearities.
FourierFlows.TwoDGrid — Type
struct TwoDGrid{T<:AbstractFloat, A, Tx, Tfft, Trfft, Talias, D} <: AbstractGrid{T, Tk, Talias, D}A two-dimensional grid.
device::Any: device which the grid lives onnx::Int64: number of points in $x$ny::Int64: number of points in $y$nk::Int64: number of wavenumbers in $x$nl::Int64: number of wavenumbers in $y$nkr::Int64: number of positive wavenumers in $x$ (real Fourier transforms)dx::AbstractFloat: grid spacing in $x$dy::AbstractFloat: grid spacing in $y$Lx::AbstractFloat: domain extent in $x$Ly::AbstractFloat: domain extent in $y$x::Any: range with $x$-grid-pointsy::Any: range with $y$-grid-pointsk::Any: array with $x$-wavenumbersl::Any: array with $y$-wavenumberskr::Any: array with positive $x$-wavenumbers (real Fourier transforms)Ksq::Any: array with squared total wavenumbers, $k² + l²$invKsq::Any: array with inverse squared total wavenumbers, $1 / (k² + l²)$Krsq::Any: array with squared total wavenumbers for real Fourier transforms, $kᵣ² + l²$invKrsq::Any: array with inverse squared total wavenumbers for real Fourier transforms, $1 / (kᵣ² + l²)$fftplan::Any: the FFT plan for complex-valued fieldsrfftplan::Any: the FFT plan for real-valued fieldsaliased_fraction::AbstractFloat: the fraction of wavenumbers that are aliased (e.g., 1/3 for quadradic nonlinearities)kalias::Any: range of the indices of aliased $x$-wavenumberskralias::Any: range of the indices of aliased positive $x$-wavenumbers (real Fourier transforms)lalias::Any: range of the indices of aliased $y$-wavenumbers
FourierFlows.dealias! — Method
dealias!(fh, grid)Dealias array fh on the grid based on the grids's aliased_fraction.
FourierFlows.gridpoints — Method
gridpoints(grid::OneDDGrid)
gridpoints(grid::TwoDGrid)
gridpoints(grid::ThreeDGrid)Return the collocation points of the grid in 1D (X), 2D (X, Y) or 3D arrays (X, Y, Z).
Utilities
FourierFlows.cxtype — Method
cxtype(T)Returns T when T is Complex, or Complex{T} when T is Real.
FourierFlows.device_array — Method
device_array(grid::AbstractGrid)Return the proper array type according to the grid's device, i.e., Array for CPU and CuArray for GPU.
FourierFlows.device_array — Method
device_array(device::Device)
device_array(device::Device, T, dim)Return the proper array type according to the device, i.e., Array for CPU and CuArray for GPU.
FourierFlows.fltype — Method
fltype(T)Returns T when T<:AbstractFloat or Tf when T<:Complex{Tf}.
FourierFlows.innereltype — Method
innereltype(x)Recursively determine the 'innermost' type in by the collection x (which may be, for example, a collection of a collection).
FourierFlows.superzeros — Method
superzeros(T, A)Returns an array like A, but full of zeros. If innereltype(A) can be promoted to T, then the innermost elements of the array will have type T.
FourierFlows.@devzeros — Macro
@devzeros dev T dims a b c...Create arrays of all zeros with element type T, size dims, and global names a, b, c (for example) on device dev.
FourierFlows.@superzeros — Macro
@superzeros T a b c d...
@superzeros T dims b c d...Generate arrays b, c, d... with the super-dimensions of a and innereltype T.
FourierFlows.@zeros — Macro
@zeros T dims a b c...Create arrays of all zeros with element type T, size dims, and global names a, b, c (for example). An arbitrary number of arrays may be created.
Diagnostics
FourierFlows.Diagnostic — Type
mutable struct Diagnostic{T, N} <: AbstractDiagnosticA diagnostic that includes N elements of type T.
calc::Function: function that returns the diagnostic viacalc(prob)prob::FourierFlows.Problem: the relevant problem for this diagnosticdata::Vector: vector where the diagnostic time-series is savedt::Vector{Float64}: vector with the times for which the diagnostic was savedsteps::Vector{Int64}: vector with the problem'sstepfor which the diagnostic was savedfreq::Int64: integer denoting how often (every how manyproblem.steps) to save the diagnostici::Int64: integer denoting how many times thediagnostic.datawas updated
FourierFlows.Diagnostic — Method
Diagnostic(calc, prob; freq=1, nsteps=100, ndata=ceil(Int, (nsteps+1)/freq))Construct a diagnostic that stores the result of calc(prob) with frequency freq.
Keywords
freq: Diagnostic is saved everyfreqsteps.nsteps: The total number of steps in problem.ndata: The number of diagnostics to be saved.
FourierFlows.increment! — Method
increment!(diag)Increment the Diagnostic diag, or an array of Diagnostics diags.
FourierFlows.update! — Method
update!(diag)Update diag.
Output
FourierFlows.Output — Type
struct OutputThe composite type for output.
prob::FourierFlows.Problem: the relevant problem for the outputpath::String: the path for the output filefields::Dict{Symbol, Function}: the fields to be saved; the relevant problem for this diagnostic
FourierFlows.Output — Method
Output(prob, filename, fieldtuples...)Define output for prob with fields and functions that calculate the output in the list of tuples fieldtuples = (fldname, func)....
FourierFlows.savediagnostic — Method
savediagnostic(diagnostic, diagname, filename)Save diagnostic to filename under name diagname. Only the computed diagnostic is saved, that is, everything up to diagnostic's iteration diagnostic.i.
FourierFlows.saveoutput — Method
saveoutput(out)Save the fields in out.fields to out.path.
FourierFlows.saveproblem — Method
saveproblem(prob, filename)Save certain aspects of a problem prob to filename.
Timesteppers
FourierFlows.AB3TimeStepper — Type
AB3TimeStepper(equation::Equation, dev::Device=CPU())Construct a 3rd order Adams-Bashforth timestepper for equation on device dev.
FourierFlows.AB3TimeStepper — Type
struct AB3TimeStepper{T} <: AbstractTimeStepper{T}A 3rd-order Adams-Bashforth timestepper for time-stepping ∂u/∂t = RHS(u, t) via:
uⁿ⁺¹ = uⁿ + dt/12 * (23 * RHS(uⁿ, tⁿ) - 16 * RHS(uⁿ⁻¹, tⁿ⁻¹) + 5 * RHS(uⁿ⁻², tⁿ⁻²))Adams-Bashforth is a multistep method, i.e., it not only requires information from the n-th time-step (uⁿ) but also from the previous two timesteps (uⁿ⁻¹ and uⁿ⁻²). For the first two timesteps, it falls back to a forward Euler timestepping scheme:
uⁿ⁺¹ = uⁿ + dt * RHS(uⁿ, tⁿ)FourierFlows.ETDRK4TimeStepper — Type
ETDRK4TimeStepper(equation::Equation, dt, dev::Device=CPU())Construct a 4th-order exponential-time-differencing Runge-Kutta timestepper with timestep dt for equation on device dev.
FourierFlows.ETDRK4TimeStepper — Type
struct ETDRK4TimeStepper{T,TL} <: AbstractTimeStepper{T}A 4th-order exponential-time-differencing Runge-Kutta timestepper for time-stepping ∂u/∂t = L * u + N(u). The scheme treats the linear term L exactly while for the nonlinear terms N(u) it uses a 4th-order Runge-Kutta scheme (RK4TimeStepper). That is,
uⁿ⁺¹ = exp(L * dt) * uⁿ + RK4(N(uⁿ))For more info refer to Kassam and Trefethen (2005).
FourierFlows.FilteredAB3TimeStepper — Type
FilteredAB3TimeStepper(equation::Equation, dev::Device=CPU(); filterkwargs...)Construct a 3rd order Adams-Bashforth timestepper with spectral filtering for equation on device dev.
FourierFlows.FilteredAB3TimeStepper — Type
struct FilteredAB3TimeStepper{T} <: AbstractTimeStepper{T}A 3rd order Adams-Bashforth timestepper with spectral filtering. See AB3TimeStepper.
FourierFlows.FilteredETDRK4TimeStepper — Type
FilteredETDRK4TimeStepper(equation, dt; filterkwargs...)Construct a 4th-order exponential-time-differencing Runge-Kutta timestepper with timestep dt and spectral filtering for equation on device dev.
FourierFlows.FilteredETDRK4TimeStepper — Type
FilteredETDRK4TimeStepper{T,TL,Tf} <: AbstractTimeStepper{T}A 4th-order exponential-time-differencing Runge-Kutta timestepper with spectral filtering. See ETDRK4TimeStepper.
FourierFlows.FilteredForwardEulerTimeStepper — Type
FilteredForwardEulerTimeStepper(equation, dev; filterkwargs...)Construct a Forward Euler timestepper with spectral filtering for equation on device dev.
FourierFlows.FilteredForwardEulerTimeStepper — Type
struct FilteredForwardEulerTimeStepper{T,Tf} <: AbstractTimeStepper{T}A forward Euler timestepper with spectral filtering. See ForwardEulerTimeStepper.
FourierFlows.FilteredLSRK54TimeStepper — Type
FilteredRK4TimeStepper(equation::Equation, dev::Device=CPU(); filterkwargs...)Construct a 4th-order 5-stages 2-storage Runge-Kutta timestepper with spectral filtering for equation on device dev.
FourierFlows.FilteredLSRK54TimeStepper — Type
struct FilteredLSRK54TimeStepper{T,V,Tf} <: AbstractTimeStepper{T}A 4th-order 5-stages low-storage Runge-Kutta timestepper with spectral filtering. See LSRK54TimeStepper.
FourierFlows.FilteredRK4TimeStepper — Type
FilteredRK4TimeStepper(equation::Equation, dev::Device=CPU(); filterkwargs...)Construct a 4th-order Runge-Kutta timestepper with spectral filtering for equation on device dev.
FourierFlows.FilteredRK4TimeStepper — Type
struct FilteredRK4TimeStepper{T,Tf} <: AbstractTimeStepper{T}A 4th-order Runge-Kutta timestepper with spectral filtering. See RK4TimeStepper.
FourierFlows.ForwardEulerTimeStepper — Type
ForwardEulerTimeStepper(equation::Equation, dev::Device=CPU())Construct a forward Euler timestepper for equation on device dev.
FourierFlows.ForwardEulerTimeStepper — Type
struct ForwardEulerTimeStepper{T} <: AbstractTimeStepper{T}A forward Euler timestepper for time-stepping ∂u/∂t = RHS(u, t) via:
uⁿ⁺¹ = uⁿ + dt * RHS(uⁿ, tⁿ)FourierFlows.LSRK54TimeStepper — Type
LSRK54TimeStepper(equation::Equation, dev::Device=CPU())Construct a 4th-order 5-stages low-storage Runge-Kutta timestepper for equation on device dev.
FourierFlows.LSRK54TimeStepper — Type
struct LSRK54TimeStepper{T} <: AbstractTimeStepper{T}A 4th-order 5-stages 2-storage Runge-Kutta timestepper for time-stepping ∂u/∂t = RHS(u, t) via:
S² = 0
for i = 1:5
S² = Aᵢ * S² + dt * RHS(uⁿ, t₀ + Cᵢ * dt)
uⁿ += Bᵢ * S²
end
uⁿ⁺¹ = uⁿwhere Aᵢ, Bᵢ, and Cᵢ are the $A$, $B$, and $C$ coefficients from the LSRK table at the $i$-th stage. For details, refer to Carpenter and Kennedy (1994).
The LSRK54TimeStepper is slower than the RK4TimeStepper but has less memory footprint; half compared to RK4TimeStepper.
If your simulation is bound by performance then use RK4TimeStepper; if your simulation is bound by memory then consider using LSRK54TimeStepper.
FourierFlows.RK4TimeStepper — Type
RK4TimeStepper(equation::Equation, dev::Device=CPU())Construct a 4th-order Runge-Kutta timestepper for equation on device dev.
FourierFlows.RK4TimeStepper — Type
struct RK4TimeStepper{T} <: AbstractTimeStepper{T}A 4th-order Runge-Kutta timestepper for time-stepping ∂u/∂t = RHS(u, t) via:
uⁿ⁺¹ = uⁿ + dt/6 * (k₁ + 2 * k₂ + 2 * k₃ + k₄)where
k₁ = RHS(uⁿ, tⁿ)
k₂ = RHS(uⁿ + k₁ * dt/2, tⁿ + dt/2)
k₃ = RHS(uⁿ + k₂ * dt/2, tⁿ + dt/2)
k₄ = RHS(uⁿ + k₃ * dt, tⁿ + dt)If your simulation is limited by memory then consider switching to LSRK54TimeStepper. The LSRK54TimeStepper timestepper has about half the memory footprint compared to the RK4TimeStepper with a about 25%-30% performance trade off.
FourierFlows.TimeStepper — Function
TimeStepper(stepper, equation, dt=nothing, dev=CPU(); kw...)Instantiate the Timestepper for equation with timestep dt and on the device. The keyword arguments, kw, are passed to the timestepper constructor.
FourierFlows.step_until! — Method
step_until!(prob, stop_time)Step forward prob until stop_time.
We cannot use step_until! with ETDRK4TimeStepper nor FilteredETDRK4TimeStepper.
See also: stepforward!
FourierFlows.stepforward! — Method
stepforward!(prob::Problem, diags, nsteps::Int)Step forward prob for nsteps, incrementing diags along the way. diags may be a single Diagnostic or a Vector of Diagnostics.
FourierFlows.stepforward! — Method
stepforward!(prob::Problem, nsteps::Int)Step forward prob for nsteps.
FourierFlows.stepforward! — Method
stepforward!(prob::Problem)Step forward prob one time step.
Diffusion Testbed Module
FourierFlows.Diffusion — Module
FourierFlows.Diffusion.Problem — Function
Problem(dev::Device = CPU();
nx = 128,
Lx = 2π,
κ = 0,
dt = 0.01,
stepper = "RK4",
aliased_fraction = 0,
T = Float64)Construct a constant diffusivity problem.
Keyword arguments
dev: (required)CPU()orGPU(); computer architecture used to time-stepproblem.nx: Number of grid points in $x$-domain.Lx: Extent of the $x$-domain.κ: Diffusivity coefficient.dt: Time-step.stepper: The extent of the $y$-domain.aliased_fraction: the fraction of high-wavenubers that are zero-ed out bydealias!().T:Float64orFloat32; floating point type used forproblemdata.
FourierFlows.Diffusion.set_c! — Method
set_c!(prob, c)Set the solution sol as the transform of c and update vars.
FourierFlows.Diffusion.updatevars! — Method
updatevars!(vars, grid, sol)Update the variables in vars on the grid with the solution in sol.