diff --git a/README.md b/README.md index 09bb4d14..f66bdefb 100644 --- a/README.md +++ b/README.md @@ -41,8 +41,6 @@ Some animations created with GeophysicalFlows.jl are [online @ youtube]. ## Modules -All modules provide solvers on two-dimensional domains. We currently provide - * `TwoDNavierStokes`: the two-dimensional vorticity equation. * `SingleLayerQG`: the barotropic or equivalent-barotropic quasi-geostrophic equation, which generalizes `TwoDNavierStokes` to cases with topography, Coriolis parameters of the form `f = f₀ + βy`, and finite Rossby radius of deformation. * `MultiLayerQG`: a multi-layer quasi-geostrophic model over topography and with the ability to impose a zonal flow `U_n(y)` in each layer. diff --git a/docs/make.jl b/docs/make.jl index 74f2a65f..5bda3bec 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -95,9 +95,9 @@ sitename = "GeophysicalFlows.jl", "modules/surfaceqg.md" ], "Stochastic Forcing" => "stochastic_forcing.md", - "DocStrings" => Any[ - "man/types.md", - "man/functions.md" + "Library" => Any[ + "lib/types.md", + "lib/functions.md" ] ] ) diff --git a/docs/src/index.md b/docs/src/index.md index f9bea1b9..50e613da 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -6,6 +6,7 @@ [FourierFlows.jl](https://github.com/FourierFlows/FourierFlows.jl) framework to provide solvers for problems in Geophysical Fluid Dynamics, on periodic domains using Fourier-based pseudospectral methods. + ## Examples Examples aim to demonstrate the main functionalities of each module. Have a look at our Examples collection! @@ -53,6 +54,7 @@ The development of GeophysicalFlows.jl started by [Navid C. Constantinou](http:/ course of time various people have contributed to GeophysicalFlows.jl, including [Lia Siegelman](https://scholar.google.com/citations?user=BQJtj6sAAAAJ), [Brodie Pearson](https://brodiepearson.github.io), and [André Palóczy](https://scholar.google.com/citations?user=o4tYEH8AAAAJ) (see the [example in FourierFlows.jl](https://fourierflows.github.io/FourierFlowsDocumentation/stable/generated/OneDShallowWaterGeostrophicAdjustment/)). + ## Cite The code is citable via [zenodo](https://doi.org/10.5281/zenodo.1463809). diff --git a/docs/src/lib/functions.md b/docs/src/lib/functions.md new file mode 100644 index 00000000..48d13c8c --- /dev/null +++ b/docs/src/lib/functions.md @@ -0,0 +1,118 @@ +# Functions + +## `GeophysicalFlows` + +### Exported functions + +```@docs +GeophysicalFlows.lambdipole +GeophysicalFlows.peakedisotropicspectrum +``` + + +## `TwoDNavierStokes` + +### Exported functions + +```@docs +GeophysicalFlows.TwoDNavierStokes.Problem +GeophysicalFlows.TwoDNavierStokes.energy_dissipation_hyperviscosity +GeophysicalFlows.TwoDNavierStokes.energy_dissipation_hypoviscosity +GeophysicalFlows.TwoDNavierStokes.energy_work +GeophysicalFlows.TwoDNavierStokes.enstrophy_dissipation_hyperviscosity +GeophysicalFlows.TwoDNavierStokes.enstrophy_dissipation_hypoviscosity +GeophysicalFlows.TwoDNavierStokes.enstrophy_work +``` + +### Private functions + +```@docs +GeophysicalFlows.TwoDNavierStokes.calcN_advection! +GeophysicalFlows.TwoDNavierStokes.addforcing! +GeophysicalFlows.TwoDNavierStokes.energy_dissipation +GeophysicalFlows.TwoDNavierStokes.enstrophy_dissipation +``` + + +## `SingleLayerQG` + +### Exported functions + +```@docs +GeophysicalFlows.SingleLayerQG.Problem +GeophysicalFlows.SingleLayerQG.streamfunctionfrompv! +GeophysicalFlows.SingleLayerQG.energy_dissipation +GeophysicalFlows.SingleLayerQG.energy_work +GeophysicalFlows.SingleLayerQG.energy_drag +GeophysicalFlows.SingleLayerQG.enstrophy +GeophysicalFlows.SingleLayerQG.enstrophy_dissipation +GeophysicalFlows.SingleLayerQG.enstrophy_work +GeophysicalFlows.SingleLayerQG.enstrophy_drag +``` + +### Private functions + +```@docs +GeophysicalFlows.SingleLayerQG.calcN_advection! +GeophysicalFlows.SingleLayerQG.addforcing! +``` + + +## `MultiLayerQG` + +### Exported functions + +```@docs +GeophysicalFlows.MultiLayerQG.Problem +GeophysicalFlows.MultiLayerQG.fwdtransform! +GeophysicalFlows.MultiLayerQG.invtransform! +GeophysicalFlows.MultiLayerQG.streamfunctionfrompv! +GeophysicalFlows.MultiLayerQG.pvfromstreamfunction! +``` + +### Private functions + +```@docs +GeophysicalFlows.MultiLayerQG.LinearEquation +GeophysicalFlows.MultiLayerQG.calcNlinear! +GeophysicalFlows.MultiLayerQG.calcN_advection! +GeophysicalFlows.MultiLayerQG.calcN_linearadvection! +GeophysicalFlows.MultiLayerQG.addforcing! +``` + + +## `SurfaceQG` + +### Exported functions + +```@docs +GeophysicalFlows.SurfaceQG.Problem +GeophysicalFlows.SurfaceQG.buoyancy_dissipation +GeophysicalFlows.SurfaceQG.buoyancy_work +``` + +### Private functions + +```@docs +GeophysicalFlows.SurfaceQG.calcN_advection! +GeophysicalFlows.SurfaceQG.addforcing! +``` + + +## `BarotropicQGQL` + +### Exported functions + +```@docs +GeophysicalFlows.BarotropicQGQL.Problem +GeophysicalFlows.BarotropicQGQL.dissipation +GeophysicalFlows.BarotropicQGQL.work +GeophysicalFlows.BarotropicQGQL.drag +``` + +### Private functions + +```@docs +GeophysicalFlows.BarotropicQGQL.calcN_advection! +GeophysicalFlows.BarotropicQGQL.addforcing! +``` diff --git a/docs/src/man/types.md b/docs/src/lib/types.md similarity index 85% rename from docs/src/man/types.md rename to docs/src/lib/types.md index de171027..fdcbf1fd 100644 --- a/docs/src/man/types.md +++ b/docs/src/lib/types.md @@ -1,6 +1,6 @@ # Private types -## Private types in module `TwoDNavierStokes`: +## `TwoDNavierStokes` ```@docs GeophysicalFlows.TwoDNavierStokes.Params @@ -10,7 +10,8 @@ GeophysicalFlows.TwoDNavierStokes.ForcedVars GeophysicalFlows.TwoDNavierStokes.StochasticForcedVars ``` -## Private types in module `SingleLayerQG`: + +## `SingleLayerQG` ```@docs GeophysicalFlows.SingleLayerQG.Params @@ -22,17 +23,8 @@ GeophysicalFlows.SingleLayerQG.ForcedVars GeophysicalFlows.SingleLayerQG.StochasticForcedVars ``` -## Private types in module `BarotropicQGQL`: - -```@docs -GeophysicalFlows.BarotropicQGQL.Params -GeophysicalFlows.BarotropicQGQL.Vars -GeophysicalFlows.BarotropicQGQL.DecayingVars -GeophysicalFlows.BarotropicQGQL.ForcedVars -GeophysicalFlows.BarotropicQGQL.StochasticForcedVars -``` -## Private types in module `MultiLayerQG`: +## `MultiLayerQG` ```@docs GeophysicalFlows.MultiLayerQG.Params @@ -43,7 +35,8 @@ GeophysicalFlows.MultiLayerQG.ForcedVars GeophysicalFlows.MultiLayerQG.StochasticForcedVars ``` -## Private types in module `SurfaceQG`: + +## `SurfaceQG` ```@docs GeophysicalFlows.SurfaceQG.Params @@ -52,3 +45,14 @@ GeophysicalFlows.SurfaceQG.DecayingVars GeophysicalFlows.SurfaceQG.ForcedVars GeophysicalFlows.SurfaceQG.StochasticForcedVars ``` + + +## `BarotropicQGQL` + +```@docs +GeophysicalFlows.BarotropicQGQL.Params +GeophysicalFlows.BarotropicQGQL.Vars +GeophysicalFlows.BarotropicQGQL.DecayingVars +GeophysicalFlows.BarotropicQGQL.ForcedVars +GeophysicalFlows.BarotropicQGQL.StochasticForcedVars +``` diff --git a/docs/src/man/functions.md b/docs/src/man/functions.md deleted file mode 100644 index 1e6509fe..00000000 --- a/docs/src/man/functions.md +++ /dev/null @@ -1,50 +0,0 @@ -# Functions - - -## Functions exported from `TwoDNavierStokes`: - -```@autodocs -Modules = [GeophysicalFlows.TwoDNavierStokes] -Private = false -Order = [:function] -``` - -## Private functions from `TwoDNavierStokes`: - -```@autodocs -Modules = [GeophysicalFlows.TwoDNavierStokes] -Public = false -Order = [:function] -``` - -## Functions exported from `SingleLayerQG`: - -```@autodocs -Modules = [GeophysicalFlows.SingleLayerQG] -Private = false -Order = [:function] -``` - -## Functions exported from `BarotropicQGQL`: - -```@autodocs -Modules = [GeophysicalFlows.BarotropicQGQL] -Private = false -Order = [:function] -``` - -## Functions exported from `MultiLayerQG`: - -```@autodocs -Modules = [GeophysicalFlows.MultiLayerQG] -Private = false -Order = [:function] -``` - -## Functions exported from `SurfaceQG`: - -```@autodocs -Modules = [GeophysicalFlows.SurfaceQG] -Private = false -Order = [:function] -``` diff --git a/docs/src/modules/barotropicqgql.md b/docs/src/modules/barotropicqgql.md index 33ee4680..8c9e386d 100644 --- a/docs/src/modules/barotropicqgql.md +++ b/docs/src/modules/barotropicqgql.md @@ -48,6 +48,7 @@ denoted with ``q \equiv \zeta + \eta``. *Quasi-linear* dynamics **neglect the term eddy-eddy nonlinearity (EENL) term** above. + ### Implementation The equation is time-stepped forward in Fourier space: @@ -95,6 +96,24 @@ GeophysicalFlows.BarotropicQGQL.set_zeta! ``` +### Diagnostics + +The kinetic energy of the fluid is obtained via: + +```@docs +GeophysicalFlows.BarotropicQGQL.energy +``` + +while the enstrophy via: + +```@docs +GeophysicalFlows.BarotropicQGQL.enstrophy +``` + +Other diagnostic include: [`dissipation`](@ref GeophysicalFlows.BarotropicQGQL.dissipation), +[`drag`](@ref GeophysicalFlows.BarotropicQGQL.drag), and [`work`](@ref GeophysicalFlows.BarotropicQGQL.work). + + ## Examples - `examples/barotropicqgql_betaforced.jl`: A script that simulates forced-dissipative quasi-linear quasi-geostrophic flow on a beta-plane demonstrating zonation. The forcing is temporally delta-correlated and its spatial structure is isotropic with power in a narrow annulus of total radius ``k_f`` in wavenumber space. This example demonstrates that the anisotropic inverse energy cascade is not required for zonation. diff --git a/docs/src/modules/multilayerqg.md b/docs/src/modules/multilayerqg.md index 3c26c6c6..77803b13 100644 --- a/docs/src/modules/multilayerqg.md +++ b/docs/src/modules/multilayerqg.md @@ -103,6 +103,10 @@ GeophysicalFlows.MultiLayerQG.calcN! which in turn calls [`calcN_advection!`](@ref GeophysicalFlows.MultiLayerQG.calcN_advection!) and [`addforcing!`](@ref GeophysicalFlows.MultiLayerQG.addforcing!). +!!! tip + The `MultiLayerQG` module includes also a linearized version of the dynamics; see + [`LinearEquation`](@ref GeophysicalFlows.MultiLayerQG.LinearEquation, [`calcNlinear!`](@ref GeophysicalFlows.MultiLayerQG.calcNlinear!), and [`calcN_linearadvection!`](@ref GeophysicalFlows.MultiLayerQG.calcN_linearadvection!). + ### Parameters and Variables diff --git a/docs/src/modules/singlelayerqg.md b/docs/src/modules/singlelayerqg.md index a4b0521a..feed5ed6 100644 --- a/docs/src/modules/singlelayerqg.md +++ b/docs/src/modules/singlelayerqg.md @@ -102,10 +102,10 @@ The total energy is: GeophysicalFlows.SingleLayerQG.energy ``` -Other diagnostic include: [`energy_dissipation`](@ref GeophysicalFlows.SurfaceQG.energy_dissipation), -[`energy_drag`](@ref GeophysicalFlows.SurfaceQG.energy_drag), [`energy_work`](@ref GeophysicalFlows.SurfaceQG.energy_work), -[`enstrophy_dissipation`](@ref GeophysicalFlows.SurfaceQG.enstrophy_dissipation), and -[`enstrophy_drag`](@ref GeophysicalFlows.SurfaceQG.enstrophy_drag), [`enstrophy_work`](@ref GeophysicalFlows.SurfaceQG.enstrophy_work). +Other diagnostic include: [`energy_dissipation`](@ref GeophysicalFlows.SingleLayerQG.energy_dissipation), +[`energy_drag`](@ref GeophysicalFlows.SingleLayerQG.energy_drag), [`energy_work`](@ref GeophysicalFlows.SingleLayerQG.energy_work), +[`enstrophy_dissipation`](@ref GeophysicalFlows.SingleLayerQG.enstrophy_dissipation), and +[`enstrophy_drag`](@ref GeophysicalFlows.SingleLayerQG.enstrophy_drag), [`enstrophy_work`](@ref GeophysicalFlows.SingleLayerQG.enstrophy_work). ## Examples diff --git a/src/GeophysicalFlows.jl b/src/GeophysicalFlows.jl index ab9f183a..209f211b 100644 --- a/src/GeophysicalFlows.jl +++ b/src/GeophysicalFlows.jl @@ -17,8 +17,8 @@ using FFTW: irfft include("utils.jl") include("twodnavierstokes.jl") include("singlelayerqg.jl") -include("barotropicqgql.jl") include("multilayerqg.jl") include("surfaceqg.jl") +include("barotropicqgql.jl") end # module diff --git a/src/barotropicqgql.jl b/src/barotropicqgql.jl index 9ee88da5..1fe5b55e 100644 --- a/src/barotropicqgql.jl +++ b/src/barotropicqgql.jl @@ -28,7 +28,7 @@ abstract type BarotropicQGQLVars <: AbstractVars end nothingfunction(args...) = nothing """ - Problem(dev=CPU(); parameters...) + Problem(dev::Device; parameters...) Construct a BarotropicQGQL turbulence problem on device `dev`. """ @@ -409,9 +409,9 @@ enstrophy(prob) = enstrophy(prob.sol, prob.grid, prob.vars) """ dissipation(prob) - dissipation(sol, v, p, g) + dissipation(sol, vars, params, grid) -Return the domain-averaged dissipation rate. `nν` must be >= 1. +Return the domain-averaged energy dissipation rate. `nν` must be >= 1. """ @inline function dissipation(sol, vars, params, grid) @. vars.uh = grid.Krsq^(params.nν - 1) * abs2(sol) diff --git a/src/multilayerqg.jl b/src/multilayerqg.jl index 4cfae608..3e848c94 100644 --- a/src/multilayerqg.jl +++ b/src/multilayerqg.jl @@ -28,9 +28,9 @@ using FourierFlows: parsevalsum, parsevalsum2, superzeros, plan_flows_rfft nothingfunction(args...) = nothing """ - Problem(; parameters...) + Problem(nlayers, dev::Device; parameters...) -Construct a multi-layer QG problem. +Construct a multi-layer QG problem on device `dev`. """ function Problem(nlayers::Int, # number of fluid layers dev = CPU(); diff --git a/src/singlelayerqg.jl b/src/singlelayerqg.jl index 4dc23b65..0b9b4e13 100644 --- a/src/singlelayerqg.jl +++ b/src/singlelayerqg.jl @@ -30,11 +30,10 @@ using FourierFlows: parsevalsum, parsevalsum2 nothingfunction(args...) = nothing """ - Problem(; parameters...) + Problem(dev::Device; parameters...) -Construct a SingleLayerQG problem. +Construct a SingleLayerQG problem on device `dev`. """ - function Problem(dev::Device=CPU(); # Numerical parameters nx = 256, @@ -335,7 +334,7 @@ end """ streamfunctionfrompv!(ψh, qh, params, grid) -Invert the Fourier transform of PV to obtain the Fourier transform of the streamfunction `ψh`. +Invert the Fourier transform of PV `qh` to obtain the Fourier transform of the streamfunction `ψh`. """ function streamfunctionfrompv!(ψh, qh, params::BarotropicQGParams, grid) @. ψh = - grid.invKrsq * qh diff --git a/src/surfaceqg.jl b/src/surfaceqg.jl index 42ae6f26..39e13898 100644 --- a/src/surfaceqg.jl +++ b/src/surfaceqg.jl @@ -25,9 +25,9 @@ using FourierFlows: parsevalsum nothingfunction(args...) = nothing """ - Problem(; parameters...) + Problem(dev::Device; parameters...) -Construct a Surface QG problem. +Construct a Surface QG problem on device `dev`. """ function Problem(dev::Device=CPU(); # Numerical parameters diff --git a/src/twodnavierstokes.jl b/src/twodnavierstokes.jl index 013e5fe4..38d6e681 100644 --- a/src/twodnavierstokes.jl +++ b/src/twodnavierstokes.jl @@ -1,10 +1,3 @@ -""" -A module for simulating two-dimensional incompressible fluid with the Navier-Stokes equations. -The module uses the vorticity-streamfunction formulation. - -# Exports -$(EXPORTS) -""" module TwoDNavierStokes export @@ -36,7 +29,7 @@ nothingfunction(args...) = nothing """ Problem(dev::Device; parameters...) -Construct a two-dimensional Navier-Stokes `problem`. +Construct a two-dimensional Navier-Stokes `problem` on device `dev`. """ function Problem(dev::Device=CPU(); # Numerical parameters @@ -374,8 +367,18 @@ where ``ξ`` and ``nξ`` could be either the (hyper)-viscosity coefficient ``ν` return 1 / (grid.Lx * grid.Ly) * parsevalsum(energy_dissipationh, grid) end +""" + energy_dissipation_hyperviscosity(prob, ξ, νξ) + +Return the domain-averaged energy dissipation rate done by the ``ν`` (hyper)-viscosity. +""" energy_dissipation_hyperviscosity(prob) = energy_dissipation(prob, prob.params.ν, prob.params.nν) +""" + energy_dissipation_hypoviscosity(prob, ξ, νξ) + +Return the domain-averaged energy dissipation rate done by the ``μ`` (hypo)-viscosity. +""" energy_dissipation_hypoviscosity(prob) = energy_dissipation(prob, prob.params.μ, prob.params.nμ) """ @@ -399,8 +402,18 @@ where ``ξ`` and ``nξ`` could be either the (hyper)-viscosity coefficient ``ν` return 1 / (grid.Lx * grid.Ly) * parsevalsum(enstrophy_dissipationh, grid) end +""" + enstrophy_dissipation_hyperviscosity(prob, ξ, νξ) + +Return the domain-averaged enstrophy dissipation rate done by the ``ν`` (hyper)-viscosity. +""" enstrophy_dissipation_hyperviscosity(prob) = enstrophy_dissipation(prob, prob.params.ν, prob.params.nν) +""" + enstrophy_dissipation_hypoviscosity(prob, ξ, νξ) + +Return the domain-averaged enstrophy dissipation rate done by the ``μ`` (hypo)-viscosity. +""" enstrophy_dissipation_hypoviscosity(prob) = enstrophy_dissipation(prob, prob.params.μ, prob.params.nμ) """ diff --git a/src/utils.jl b/src/utils.jl index 09fef467..f217b0a6 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -20,7 +20,7 @@ function lambdipole(U, R, grid::TwoDGrid{T, A}; center=(mean(grid.x), mean(grid. end """ - peakedisotropicspectrum(g, kpeak, E₀; mask=mask, allones=false) + peakedisotropicspectrum(grid, kpeak, E₀; mask=mask, allones=false) Generate a random two-dimensional relative vorticity field ``q(x, y)`` with Fourier spectrum peaked around a central non-dimensional wavenumber `kpeak` and normalized so that its total