Simple diffusion example

This script provides our simplest example of Oceananigans.jl functionality: the diffusion of a one-dimensional Gaussian. This example demonstrates

  • how to load Oceananigans.jl;
  • how to instantiate an Oceananigans.jl Model;
  • how to set an initial condition with a function;
  • how to time-step a model forward, and finally
  • how to look at results.

Using Oceananigans.jl

To use Oceananigans.jl after it has been installed, we bring Oceananigans.jl functions and names into our 'namespace' by writing

using Oceananigans

We also use PyPlot.jl for plotting and Printf to format plot legends:

using PyPlot, Printf

Instantiating and configuring a Model

To begin using Oceananigans, we instantiate a Model by calling the Model constructor:

model = Model(
    grid = RegularCartesianGrid(N = (1, 1, 128), L = (1, 1, 1)),
    closure = ConstantIsotropicDiffusivity(κ = 1.0)
)
Model{Oceananigans.AdamsBashforthTimestepper{Float64,NamedTuple{(:u, :v, :w, :T, :S),Tuple{Field{Oceananigans.Face,Oceananigans.Cell,Oceananigans.Cell,OffsetArrays.OffsetArray{Float64,3,Array{Float64,3}},RegularCartesianGrid{Float64,StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}}},Field{Oceananigans.Cell,Oceananigans.Face,Oceananigans.Cell,OffsetArrays.OffsetArray{Float64,3,Array{Float64,3}},RegularCartesianGrid{Float64,StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}}},Field{Oceananigans.Cell,Oceananigans.Cell,Oceananigans.Face,OffsetArrays.OffsetArray{Float64,3,Array{Float64,3}},RegularCartesianGrid{Float64,StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}}},Field{Oceananigans.Cell,Oceananigans.Cell,Oceananigans.Cell,OffsetArrays.OffsetArray{Float64,3,Array{Float64,3}},RegularCartesianGrid{Float64,StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}}},Field{Oceananigans.Cell,Oceananigans.Cell,Oceananigans.Cell,OffsetArrays.OffsetArray{Float64,3,Array{Float64,3}},RegularCartesianGrid{Float64,StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}}}}}},ConstantIsotropicDiffusivity{Float64,NamedTuple{(:T, :S),Tuple{Float64,Float64}}},CPU,RegularCartesianGrid{Float64,StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}},Float64,SeawaterBuoyancy{Float64,LinearEquationOfState{Float64}},Nothing,NamedTuple{(:u, :v, :w),Tuple{Field{Oceananigans.Face,Oceananigans.Cell,Oceananigans.Cell,OffsetArrays.OffsetArray{Float64,3,Array{Float64,3}},RegularCartesianGrid{Float64,StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}}},Field{Oceananigans.Cell,Oceananigans.Face,Oceananigans.Cell,OffsetArrays.OffsetArray{Float64,3,Array{Float64,3}},RegularCartesianGrid{Float64,StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}}},Field{Oceananigans.Cell,Oceananigans.Cell,Oceananigans.Face,OffsetArrays.OffsetArray{Float64,3,Array{Float64,3}},RegularCartesianGrid{Float64,StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}}}}},NamedTuple{(:T, :S),Tuple{Field{Oceananigans.Cell,Oceananigans.Cell,Oceananigans.Cell,OffsetArrays.OffsetArray{Float64,3,Array{Float64,3}},RegularCartesianGrid{Float64,StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}}},Field{Oceananigans.Cell,Oceananigans.Cell,Oceananigans.Cell,OffsetArrays.OffsetArray{Float64,3,Array{Float64,3}},RegularCartesianGrid{Float64,StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}}}}},NamedTuple{(:pHY′, :pNHS),Tuple{Field{Oceananigans.Cell,Oceananigans.Cell,Oceananigans.Cell,OffsetArrays.OffsetArray{Float64,3,Array{Float64,3}},RegularCartesianGrid{Float64,StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}}},Field{Oceananigans.Cell,Oceananigans.Cell,Oceananigans.Cell,OffsetArrays.OffsetArray{Float64,3,Array{Float64,3}},RegularCartesianGrid{Float64,StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}}}}},NamedTuple{(:u, :v, :w, :T, :S),NTuple{5,typeof(Oceananigans.zeroforcing)}},NamedTuple{(:solution, :tendency, :pressure),Tuple{NamedTuple{(:u, :v, :w, :T, :S),Tuple{NamedTuple{(:x, :y, :z),Tuple{CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}},CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}},CoordinateBoundaryConditions{BoundaryCondition{Flux,Nothing},BoundaryCondition{Flux,Nothing}}}},NamedTuple{(:x, :y, :z),Tuple{CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}},CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}},CoordinateBoundaryConditions{BoundaryCondition{Flux,Nothing},BoundaryCondition{Flux,Nothing}}}},NamedTuple{(:x, :y, :z),Tuple{CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}},CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}},CoordinateBoundaryConditions{BoundaryCondition{Oceananigans.NoPenetration,Nothing},BoundaryCondition{Oceananigans.NoPenetration,Nothing}}}},NamedTuple{(:x, :y, :z),Tuple{CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}},CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}},CoordinateBoundaryConditions{BoundaryCondition{Flux,Nothing},BoundaryCondition{Flux,Nothing}}}},NamedTuple{(:x, :y, :z),Tuple{CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}},CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}},CoordinateBoundaryConditions{BoundaryCondition{Flux,Nothing},BoundaryCondition{Flux,Nothing}}}}}},NamedTuple{(:u, :v, :w, :T, :S),Tuple{NamedTuple{(:x, :y, :z),Tuple{CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}},CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}},CoordinateBoundaryConditions{BoundaryCondition{Flux,Nothing},BoundaryCondition{Flux,Nothing}}}},NamedTuple{(:x, :y, :z),Tuple{CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}},CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}},CoordinateBoundaryConditions{BoundaryCondition{Flux,Nothing},BoundaryCondition{Flux,Nothing}}}},NamedTuple{(:x, :y, :z),Tuple{CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}},CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}},CoordinateBoundaryConditions{BoundaryCondition{Oceananigans.NoPenetration,Nothing},BoundaryCondition{Oceananigans.NoPenetration,Nothing}}}},NamedTuple{(:x, :y, :z),Tuple{CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}},CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}},CoordinateBoundaryConditions{BoundaryCondition{Flux,Nothing},BoundaryCondition{Flux,Nothing}}}},NamedTuple{(:x, :y, :z),Tuple{CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}},CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}},CoordinateBoundaryConditions{BoundaryCondition{Flux,Nothing},BoundaryCondition{Flux,Nothing}}}}}},NamedTuple{(:x, :y, :z),Tuple{CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}},CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}},CoordinateBoundaryConditions{BoundaryCondition{Flux,Nothing},BoundaryCondition{Flux,Nothing}}}}}},Oceananigans.PoissonSolverCPU{Oceananigans.PPN,Array{Float64,3},Array{Complex{Float64},3},FFTW.cFFTWPlan{Complex{Float64},-1,true,3},FFTW.r2rFFTWPlan{Complex{Float64},(5,),true,3},AbstractFFTs.ScaledPlan{Complex{Float64},FFTW.cFFTWPlan{Complex{Float64},1,true,3},Float64},FFTW.r2rFFTWPlan{Complex{Float64},(4,),true,3}},Nothing,OrderedCollections.OrderedDict{Symbol,Oceananigans.AbstractOutputWriter},OrderedCollections.OrderedDict{Symbol,Oceananigans.AbstractDiagnostic},Nothing}(CPU(), RegularCartesianGrid{Float64}
  resolution (Nx, Ny, Nz) = (1, 1, 128)
   halo size (Hx, Hy, Hz) = (1, 1, 1)
      domain (Lx, Ly, Lz) = (1.0, 1.0, 1.0)
grid spacing (Δx, Δy, Δz) = (1.0, 1.0, 0.0078125), Clock{Float64}(0.0, 0), SeawaterBuoyancy{Float64,LinearEquationOfState{Float64}}(9.80665, LinearEquationOfState{Float64}(0.000167, 0.00078)), nothing, (u = [0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

...

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0], v = [0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

...

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0], w = [0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

...

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]), (T = [0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

...

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0], S = [0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

...

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]), (pHY′ = [0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

...

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0], pNHS = [0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

...

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]), (u = Oceananigans.zeroforcing, v = Oceananigans.zeroforcing, w = Oceananigans.zeroforcing, T = Oceananigans.zeroforcing, S = Oceananigans.zeroforcing), ConstantIsotropicDiffusivity{Float64,NamedTuple{(:T, :S),Tuple{Float64,Float64}}}(1.05e-6, (T = 1.0, S = 1.0)), (solution = (u = (x = CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}}(BoundaryCondition{Periodic,Nothing}(nothing), BoundaryCondition{Periodic,Nothing}(nothing)), y = CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}}(BoundaryCondition{Periodic,Nothing}(nothing), BoundaryCondition{Periodic,Nothing}(nothing)), z = CoordinateBoundaryConditions{BoundaryCondition{Flux,Nothing},BoundaryCondition{Flux,Nothing}}(BoundaryCondition{Flux,Nothing}(nothing), BoundaryCondition{Flux,Nothing}(nothing))), v = (x = CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}}(BoundaryCondition{Periodic,Nothing}(nothing), BoundaryCondition{Periodic,Nothing}(nothing)), y = CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}}(BoundaryCondition{Periodic,Nothing}(nothing), BoundaryCondition{Periodic,Nothing}(nothing)), z = CoordinateBoundaryConditions{BoundaryCondition{Flux,Nothing},BoundaryCondition{Flux,Nothing}}(BoundaryCondition{Flux,Nothing}(nothing), BoundaryCondition{Flux,Nothing}(nothing))), w = (x = CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}}(BoundaryCondition{Periodic,Nothing}(nothing), BoundaryCondition{Periodic,Nothing}(nothing)), y = CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}}(BoundaryCondition{Periodic,Nothing}(nothing), BoundaryCondition{Periodic,Nothing}(nothing)), z = CoordinateBoundaryConditions{BoundaryCondition{Oceananigans.NoPenetration,Nothing},BoundaryCondition{Oceananigans.NoPenetration,Nothing}}(BoundaryCondition{Oceananigans.NoPenetration,Nothing}(nothing), BoundaryCondition{Oceananigans.NoPenetration,Nothing}(nothing))), T = (x = CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}}(BoundaryCondition{Periodic,Nothing}(nothing), BoundaryCondition{Periodic,Nothing}(nothing)), y = CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}}(BoundaryCondition{Periodic,Nothing}(nothing), BoundaryCondition{Periodic,Nothing}(nothing)), z = CoordinateBoundaryConditions{BoundaryCondition{Flux,Nothing},BoundaryCondition{Flux,Nothing}}(BoundaryCondition{Flux,Nothing}(nothing), BoundaryCondition{Flux,Nothing}(nothing))), S = (x = CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}}(BoundaryCondition{Periodic,Nothing}(nothing), BoundaryCondition{Periodic,Nothing}(nothing)), y = CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}}(BoundaryCondition{Periodic,Nothing}(nothing), BoundaryCondition{Periodic,Nothing}(nothing)), z = CoordinateBoundaryConditions{BoundaryCondition{Flux,Nothing},BoundaryCondition{Flux,Nothing}}(BoundaryCondition{Flux,Nothing}(nothing), BoundaryCondition{Flux,Nothing}(nothing)))), tendency = (u = (x = CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}}(BoundaryCondition{Periodic,Nothing}(nothing), BoundaryCondition{Periodic,Nothing}(nothing)), y = CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}}(BoundaryCondition{Periodic,Nothing}(nothing), BoundaryCondition{Periodic,Nothing}(nothing)), z = CoordinateBoundaryConditions{BoundaryCondition{Flux,Nothing},BoundaryCondition{Flux,Nothing}}(BoundaryCondition{Flux,Nothing}(nothing), BoundaryCondition{Flux,Nothing}(nothing))), v = (x = CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}}(BoundaryCondition{Periodic,Nothing}(nothing), BoundaryCondition{Periodic,Nothing}(nothing)), y = CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}}(BoundaryCondition{Periodic,Nothing}(nothing), BoundaryCondition{Periodic,Nothing}(nothing)), z = CoordinateBoundaryConditions{BoundaryCondition{Flux,Nothing},BoundaryCondition{Flux,Nothing}}(BoundaryCondition{Flux,Nothing}(nothing), BoundaryCondition{Flux,Nothing}(nothing))), w = (x = CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}}(BoundaryCondition{Periodic,Nothing}(nothing), BoundaryCondition{Periodic,Nothing}(nothing)), y = CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}}(BoundaryCondition{Periodic,Nothing}(nothing), BoundaryCondition{Periodic,Nothing}(nothing)), z = CoordinateBoundaryConditions{BoundaryCondition{Oceananigans.NoPenetration,Nothing},BoundaryCondition{Oceananigans.NoPenetration,Nothing}}(BoundaryCondition{Oceananigans.NoPenetration,Nothing}(nothing), BoundaryCondition{Oceananigans.NoPenetration,Nothing}(nothing))), T = (x = CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}}(BoundaryCondition{Periodic,Nothing}(nothing), BoundaryCondition{Periodic,Nothing}(nothing)), y = CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}}(BoundaryCondition{Periodic,Nothing}(nothing), BoundaryCondition{Periodic,Nothing}(nothing)), z = CoordinateBoundaryConditions{BoundaryCondition{Flux,Nothing},BoundaryCondition{Flux,Nothing}}(BoundaryCondition{Flux,Nothing}(nothing), BoundaryCondition{Flux,Nothing}(nothing))), S = (x = CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}}(BoundaryCondition{Periodic,Nothing}(nothing), BoundaryCondition{Periodic,Nothing}(nothing)), y = CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}}(BoundaryCondition{Periodic,Nothing}(nothing), BoundaryCondition{Periodic,Nothing}(nothing)), z = CoordinateBoundaryConditions{BoundaryCondition{Flux,Nothing},BoundaryCondition{Flux,Nothing}}(BoundaryCondition{Flux,Nothing}(nothing), BoundaryCondition{Flux,Nothing}(nothing)))), pressure = (x = CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}}(BoundaryCondition{Periodic,Nothing}(nothing), BoundaryCondition{Periodic,Nothing}(nothing)), y = CoordinateBoundaryConditions{BoundaryCondition{Periodic,Nothing},BoundaryCondition{Periodic,Nothing}}(BoundaryCondition{Periodic,Nothing}(nothing), BoundaryCondition{Periodic,Nothing}(nothing)), z = CoordinateBoundaryConditions{BoundaryCondition{Flux,Nothing},BoundaryCondition{Flux,Nothing}}(BoundaryCondition{Flux,Nothing}(nothing), BoundaryCondition{Flux,Nothing}(nothing)))), Oceananigans.AdamsBashforthTimestepper{Float64,NamedTuple{(:u, :v, :w, :T, :S),Tuple{Field{Oceananigans.Face,Oceananigans.Cell,Oceananigans.Cell,OffsetArrays.OffsetArray{Float64,3,Array{Float64,3}},RegularCartesianGrid{Float64,StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}}},Field{Oceananigans.Cell,Oceananigans.Face,Oceananigans.Cell,OffsetArrays.OffsetArray{Float64,3,Array{Float64,3}},RegularCartesianGrid{Float64,StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}}},Field{Oceananigans.Cell,Oceananigans.Cell,Oceananigans.Face,OffsetArrays.OffsetArray{Float64,3,Array{Float64,3}},RegularCartesianGrid{Float64,StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}}},Field{Oceananigans.Cell,Oceananigans.Cell,Oceananigans.Cell,OffsetArrays.OffsetArray{Float64,3,Array{Float64,3}},RegularCartesianGrid{Float64,StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}}},Field{Oceananigans.Cell,Oceananigans.Cell,Oceananigans.Cell,OffsetArrays.OffsetArray{Float64,3,Array{Float64,3}},RegularCartesianGrid{Float64,StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}}}}}}((u = [0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

...

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0], v = [0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

...

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0], w = [0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

...

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0], T = [0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

...

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0], S = [0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

...

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]), (u = [0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

...

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0], v = [0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

...

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0], w = [0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

...

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0], T = [0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

...

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0], S = [0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

...

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]

[0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0]), 0.125), Oceananigans.PoissonSolverCPU{Oceananigans.PPN,Array{Float64,3},Array{Complex{Float64},3},FFTW.cFFTWPlan{Complex{Float64},-1,true,3},FFTW.r2rFFTWPlan{Complex{Float64},(5,),true,3},AbstractFFTs.ScaledPlan{Complex{Float64},FFTW.cFFTWPlan{Complex{Float64},1,true,3},Float64},FFTW.r2rFFTWPlan{Complex{Float64},(4,),true,3}}(Oceananigans.PPN(), [0.0], [0.0], [0.0]

[9.869108962780114]

[39.47049106891104]

...

[65447.21368444733]

[65496.52950893109]

[65526.13089103722], Complex{Float64}[0.0 + 0.0im]

Complex{Float64}[0.0 + 0.0im]

Complex{Float64}[0.0 + 0.0im]

...

Complex{Float64}[0.0 + 0.0im]

Complex{Float64}[0.0 + 0.0im]

Complex{Float64}[0.0 + 0.0im], FFTW in-place forward plan for 1×1×128 array of Complex{Float64}
(dft-nop), FFTW in-place r2r REDFT10 plan for 1×1×128 array of Complex{Float64}
(redft10e-r2hc-128-x2
  (rdft-r2hc-direct-r2c-128 "r2cf_128")), 1.0 * FFTW in-place backward plan for 1×1×128 array of Complex{Float64}
(dft-nop), FFTW in-place r2r REDFT01 plan for 1×1×128 array of Complex{Float64}
(redft01e-r2hc-128-x2
  (rdft-r2hc-direct-r2c-128 "r2cf_128"))), nothing, OrderedCollections.OrderedDict{Symbol,Oceananigans.AbstractOutputWriter}(), OrderedCollections.OrderedDict{Symbol,Oceananigans.AbstractDiagnostic}(), nothing)

The keyword arguments grid and closure indicate that our model grid is Cartesian with uniform grid spacing, that our diffusive stress and tracer fluxes are determined by diffusion with a constant diffusivity κ (note that we do not use viscosity in this example).

Note that by default, a Model has no-flux boundary condition on all variables. Next, we set an initial condition on our "passive tracer", temperature. Our objective is to observe the diffusion of a Gaussian.

# Build a Gaussian initial condition function with width `δ`:
δ = 0.1
Tᵢ(x, y, z) = exp( -(z + 0.5)^2 / (2δ^2) )

# Set `model.tracers.T` to the function `Tᵢ`:
set!(model, T=Tᵢ)

Running your first Model

Finally, we time-step the model forward using the function time_step!, with a time-step size that ensures numerical stability.

# Time-scale for diffusion across a grid cell
cell_diffusion_time_scale = model.grid.Δz^2 / model.closure.κ.T

# The function `time_step!` executes `Nt` time steps with step size `Δt`
# using a second-order Adams-Bashforth method
time_step!(model, Nt = 1000, Δt = 0.1 * cell_diffusion_time_scale)

Visualizing the results

We use PyPlot.jl to look at the results.

# A convenient function for generating a label with the Current model time
tracer_label(model) = @sprintf("\$ t=%.3f \$", model.clock.time)

# Create a figure with `PyPlot.jl`
close("all")
fig, ax = subplots()
title("Diffusion of a Gaussian")
xlabel("Tracer concentration")
ylabel(L"z")

# Plot initial condition
plot(Tᵢ.(0, 0, model.grid.zC), model.grid.zC, "--", label=L"t=0")

# Plot current solution
plot(data(model.tracers.T)[1, 1, :], model.grid.zC, label=tracer_label(model))
legend()
gcf()

Interesting! Running the model even longer makes even more interesting results.

for i = 1:3
    time_step!(model, Nt = 1000, Δt = 0.1 * cell_diffusion_time_scale)
    plot(data(model.tracers.T)[1, 1, :], model.grid.zC, label=tracer_label(model))
end

legend()
gcf()

This page was generated using Literate.jl.