diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index 8e11f2d2..9471a814 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.6.7","generation_timestamp":"2024-02-12T14:17:00","documenter_version":"1.2.1"}} \ No newline at end of file +{"documenter":{"julia_version":"1.6.7","generation_timestamp":"2024-02-15T00:05:07","documenter_version":"1.2.1"}} \ No newline at end of file diff --git a/dev/api/diagnostics/index.html b/dev/api/diagnostics/index.html index dfb77222..ed4ac1df 100644 --- a/dev/api/diagnostics/index.html +++ b/dev/api/diagnostics/index.html @@ -1,2 +1,2 @@ -Diagnostics · CryoGrid.jl

Diagnostics

CryoGrid.Diagnostics.active_layer_thicknessMethod
active_layer_thickness(T::AbstractDimArray{<:TempQuantity})

Computes active layer thickness annually. The active layer thickness is defined here as the maximum thaw depth throughout the calendar year. Assumes T to have dimensions Ti (time) and Z (depth) in any order.

source
CryoGrid.Diagnostics.integrateMethod
integrate(X::AbstractDimArray, grid::Grid{Edges}; upper_limit=0u"m", lower_limit=10u"m")

Integrates the quantity X over the given grid, which is assumed to be spatially alligned, i.e. length(grid) == length(dims(X,Z)) + 1 and cells(grid) .≈ dims(X,Z) are necessary preconditions.

source
CryoGrid.Diagnostics.mean_annual_ground_temperatureMethod
mean_annual_ground_temperature(T::AbstractDimArray; upper_limit=0u"m", lower_limit=10u"m")

Computes mean annual ground temperature between upper_limit and lower_limit. Assumes T to have dimensions Ti (time) and Z (depth) in any order.

source
CryoGrid.Diagnostics.permafrostbaseMethod
permafrostbase(T::AbstractDimArray{<:TempQuantity})

Computes depth of permafrost base for all years, i.e. the closest depth to the "bottom" at which the maximum annual temperature is strictly < 0°C. Assumes T to have dimensions Ti (time) and Z (depth) in any order.

source
CryoGrid.Diagnostics.permafrosttableMethod
permafrosttable(T::AbstractDimArray{<:TempQuantity})

Computes depth of permafrost table for all years, i.e. the closest depth to the surface at which the maximum annual temperature is strictly less than Tmelt. Assumes T to have dimensions Ti (time) and Z (depth) in any order.

source
CryoGrid.Diagnostics.spinupMethod
spinup(setup::Tile, tspan::NTuple{2,DateTime}, p, tol, layername; kwargs...)

Implements a simple, iterative spin-up procedure. Runs the model specified by setup over tspan until the profile mean up to maxdepth over the whole time span changes only within the given tolerance tol. Returns the ODESolution generated by the final iteration.

source
CryoGrid.Diagnostics.thawdepthMethod
thawdepth(T::AbstractDimArray{<:TempQuantity}; Tmelt=0.0u"°C")

Computes sub-grid thaw depth (a.k.a freezing front) from temperature at all time steps. The sub-grid depth of the zero degree isotherm is determined by linearly interpolating between grid cell temperatures in T. Note that T is assumed to have units °C and dimensions Ti (time) and Z (depth) in any order.

source
CryoGrid.Diagnostics.zero_annual_amplitudeMethod
zero_annual_amplitude(T::AbstractDimArray{<:TempQuantity}; threshold=0.5u"K")

Computes annual depth of zero amplitude (where |max - min| < threshold) and returns the result for each year. Assumes T to have dimensions Ti (time) and Z (depth) in any order.

source
+Diagnostics · CryoGrid.jl

Diagnostics

CryoGrid.Diagnostics.active_layer_thicknessMethod
active_layer_thickness(T::AbstractDimArray{<:TempQuantity})

Computes active layer thickness annually. The active layer thickness is defined here as the maximum thaw depth throughout the calendar year. Assumes T to have dimensions Ti (time) and Z (depth) in any order.

source
CryoGrid.Diagnostics.integrateMethod
integrate(X::AbstractDimArray, grid::Grid{Edges}; upper_limit=0u"m", lower_limit=10u"m")

Integrates the quantity X over the given grid, which is assumed to be spatially alligned, i.e. length(grid) == length(dims(X,Z)) + 1 and cells(grid) .≈ dims(X,Z) are necessary preconditions.

source
CryoGrid.Diagnostics.mean_annual_ground_temperatureMethod
mean_annual_ground_temperature(T::AbstractDimArray; upper_limit=0u"m", lower_limit=10u"m")

Computes mean annual ground temperature between upper_limit and lower_limit. Assumes T to have dimensions Ti (time) and Z (depth) in any order.

source
CryoGrid.Diagnostics.permafrostbaseMethod
permafrostbase(T::AbstractDimArray{<:TempQuantity})

Computes depth of permafrost base for all years, i.e. the closest depth to the "bottom" at which the maximum annual temperature is strictly < 0°C. Assumes T to have dimensions Ti (time) and Z (depth) in any order.

source
CryoGrid.Diagnostics.permafrosttableMethod
permafrosttable(T::AbstractDimArray{<:TempQuantity})

Computes depth of permafrost table for all years, i.e. the closest depth to the surface at which the maximum annual temperature is strictly less than Tmelt. Assumes T to have dimensions Ti (time) and Z (depth) in any order.

source
CryoGrid.Diagnostics.spinupMethod
spinup(setup::Tile, tspan::NTuple{2,DateTime}, p, tol, layername; kwargs...)

Implements a simple, iterative spin-up procedure. Runs the model specified by setup over tspan until the profile mean up to maxdepth over the whole time span changes only within the given tolerance tol. Returns the ODESolution generated by the final iteration.

source
CryoGrid.Diagnostics.thawdepthMethod
thawdepth(T::AbstractDimArray{<:TempQuantity}; Tmelt=0.0u"°C")

Computes sub-grid thaw depth (a.k.a freezing front) from temperature at all time steps. The sub-grid depth of the zero degree isotherm is determined by linearly interpolating between grid cell temperatures in T. Note that T is assumed to have units °C and dimensions Ti (time) and Z (depth) in any order.

source
CryoGrid.Diagnostics.zero_annual_amplitudeMethod
zero_annual_amplitude(T::AbstractDimArray{<:TempQuantity}; threshold=0.5u"K")

Computes annual depth of zero amplitude (where |max - min| < threshold) and returns the result for each year. Assumes T to have dimensions Ti (time) and Z (depth) in any order.

source
diff --git a/dev/api/index.html b/dev/api/index.html index bd5ee52a..09710f36 100644 --- a/dev/api/index.html +++ b/dev/api/index.html @@ -1,2 +1,2 @@ -Index · CryoGrid.jl

Index of public API

+Index · CryoGrid.jl

Index of public API

diff --git a/dev/api/io/index.html b/dev/api/io/index.html index 01f46a0e..47143783 100644 --- a/dev/api/io/index.html +++ b/dev/api/io/index.html @@ -1,8 +1,8 @@ -InputOutput · CryoGrid.jl

InputOutput

This module provides types and utilities for reading input files (i.e. parameters and forcings) as well as saving model outputs.

CryoGrid.InputOutput.ConstantForcingType
  ConstantForcing{unit,T} <: Forcing{unit,T}

Simple Forcing type that just returns a constant value. This type is primarily intended for writing tests but could still be used in applications if necessary.

source
CryoGrid.InputOutput.CryoGridOutputType
CryoGridOutput{TSol}

Helper type that stores the raw output from a CryoGrid run along with DimArray views of all logged variables. CryoGridOutput overrides Base.getproperty to allow for direct dot-syntax access of state variables. For example, if your model has a grid variable named T, out.T returns a DimArray with indexed time and depth axes. For OrdinaryDiffEq.jl outputs, the ODESolution can be accessed via out.sol, or for convenience, the continuous solution at time t can be computed via out(t) which is equivalent to withaxes(out.sol(t)).

source
CryoGrid.InputOutput.CryoGridOutputMethod
CryoGridOutput(sol::TSol, tspan::NTuple{2,Float64}=(-Inf,Inf)) where {TSol<:SciMLBase.AbstractODESolution}

Constructs a CryoGridOutput from the given ODESolution. Optional argument tspan restricts the time span of the output.

source
CryoGrid.InputOutput.CryoGridParamsType
CryoGridParams{T,TM} <: DenseArray{T,1}

Wraps a ModelParameters.Model parameter handler for CryoGrid types. It is recommended not to use this type directly in math or linear algebra operations but rather to use Base.values to obtain a normal array of parameter values.

source
CryoGrid.InputOutput.CryoGridParamsMethod
CryoGridParams(obj)

Constructs a modelParameters.Model wrapped with CryoGridParams from obj. If full_metadata is true, additonal fields for nested Parameterization types will be added.

source
CryoGrid.InputOutput.TransformedForcingType
  TransformedForcing(transformed_unit,orig_unit,TF,T,TO<:Forcing{orig_unit,T}) <: Forcing{transformed_unit,T}

Wraps another Forcing and applies an arbitrary transformation f when evaluated. The transformed unit can either be automatically determined on construction or specified directly.

source
CryoGrid.InputOutput.loadforcingsMethod
loadforcings(filename::String)::Forcings
+InputOutput · CryoGrid.jl

InputOutput

This module provides types and utilities for reading input files (i.e. parameters and forcings) as well as saving model outputs.

CryoGrid.InputOutput.ConstantForcingType
  ConstantForcing{unit,T} <: Forcing{unit,T}

Simple Forcing type that just returns a constant value. This type is primarily intended for writing tests but could still be used in applications if necessary.

source
CryoGrid.InputOutput.CryoGridOutputType
CryoGridOutput{TSol}

Helper type that stores the raw output from a CryoGrid run along with DimArray views of all logged variables. CryoGridOutput overrides Base.getproperty to allow for direct dot-syntax access of state variables. For example, if your model has a grid variable named T, out.T returns a DimArray with indexed time and depth axes. For OrdinaryDiffEq.jl outputs, the ODESolution can be accessed via out.sol, or for convenience, the continuous solution at time t can be computed via out(t) which is equivalent to withaxes(out.sol(t)).

source
CryoGrid.InputOutput.CryoGridOutputMethod
CryoGridOutput(sol::TSol, tspan::NTuple{2,Float64}=(-Inf,Inf)) where {TSol<:SciMLBase.AbstractODESolution}

Constructs a CryoGridOutput from the given ODESolution. Optional argument tspan restricts the time span of the output.

source
CryoGrid.InputOutput.CryoGridParamsType
CryoGridParams{T,TM} <: DenseArray{T,1}

Wraps a ModelParameters.Model parameter handler for CryoGrid types. It is recommended not to use this type directly in math or linear algebra operations but rather to use Base.values to obtain a normal array of parameter values.

source
CryoGrid.InputOutput.CryoGridParamsMethod
CryoGridParams(obj)

Constructs a modelParameters.Model wrapped with CryoGridParams from obj. If full_metadata is true, additonal fields for nested Parameterization types will be added.

source
CryoGrid.InputOutput.TransformedForcingType
  TransformedForcing(transformed_unit,orig_unit,TF,T,TO<:Forcing{orig_unit,T}) <: Forcing{transformed_unit,T}

Wraps another Forcing and applies an arbitrary transformation f when evaluated. The transformed unit can either be automatically determined on construction or specified directly.

source
CryoGrid.InputOutput.loadforcingsMethod
loadforcings(filename::String)::Forcings
 loadforcings(resource::Resource; outdir=DEFAULT_FORCINGS_DIR)::Forcings
-loadforcings([format::ForcingFormat], filename::String; outdir=DEFAULT_FORCINGS_DIR)::Forcings

Loads forcing data from the given file according to the format specified by format. By default, the forcing format is automatically detected via detectformat. Returns a Forcings struct containing all forcing data and metadata

source
CryoGrid.InputOutput.time_derivative_forcingMethod
time_derivative_forcing(
+loadforcings([format::ForcingFormat], filename::String; outdir=DEFAULT_FORCINGS_DIR)::Forcings

Loads forcing data from the given file according to the format specified by format. By default, the forcing format is automatically detected via detectformat. Returns a Forcings struct containing all forcing data and metadata

source
CryoGrid.InputOutput.time_derivative_forcingMethod
time_derivative_forcing(
     f::InterpolatedForcing{unit},
     new_name::Symbol;
     interp=Numerics.Linear()
-) where {unit}

Computes the finite difference time derivative of the given InterpolatedForcing time series and returns a new forcing with units [unit].s⁻¹

source
+) where {unit}

Computes the finite difference time derivative of the given InterpolatedForcing time series and returns a new forcing with units [unit].s⁻¹

source
diff --git a/dev/api/numerics/index.html b/dev/api/numerics/index.html index c2d297ec..97189eff 100644 --- a/dev/api/numerics/index.html +++ b/dev/api/numerics/index.html @@ -1,4 +1,4 @@ -Numerics · CryoGrid.jl

Numerics

This module contains a wide range of numerical utilities including math and discretization routines, state variable array caches, and helper types for supporting automatic differentiation.

CryoGrid.Numerics.DiffCacheType
DiffCache{T,TCache}

Wrapper around PreallocationTools.DiffCache that stores state variables in forward-diff compatible cache arrays.

source
CryoGrid.Numerics.GridType
struct Grid{S,G,Q,A} <: AbstractDiscretization{Q,1}

Represents the 1D spatial discretization on which time integration is performed. S is a GridOffset, either Edges or Cells (always edges upon initial construction). The grid representation can be converted (allocation free) between grid edges and cells via the cells and edges methods. G represents the geometry/volume on which the vertical 1D discretization is applied. A is the underlying array type, and Q is the numerical type (e.g. Float64 or a Unitful.Quantity).

source
CryoGrid.Numerics.ProfileType
Profile{N,idxTypes,valTypes}

Represents a "profile" of values indexed typically over depth, i.e:

x₁: value 1 x₂: value 2 ...

where xᵢ are the indices.

source
CryoGrid.Numerics.StateVarsType
StateVars{names,griddvars,TU,TV,DF,DG}

Generic container for holding discretized state arrays from symbolic variables (Var types). The uproto field represetns a "prototype" of the prognostic state array which should fully define the state of the system at any given point.

source
CryoGrid.Numerics.StateVarsMethod
StateVars(vars::NamedTuple, D::Numerics.AbstractDiscretization, cachector::Function, arrayproto::Type{A}=Vector) where {A<:AbstractVector}

Constructs a StateVars container from vars and the given discretization D. The function cachector must accept argments f(name::Symbol, x::AbstractVector) where name is the name of the state variable and x is the array generated by the discretization.

source
CryoGrid.Numerics.divergence!Method
divergence!(dx::AbstractVector, j::AbstractVector, Δj::AbstractVector)

Calculates the first-order divergence over a 1D flux vector field j and grid cell lengths Δj. Divergences are added to existing values in dx.

source
CryoGrid.Numerics.flux!Method
flux!(j::AbstractVector, x::AbstractVector, Δx::AbstractVector, k::AbstractVector)

Calculates the first-order, non-linear spatial flux over a discretized variable x with conductivity k. x is assumed to have shape (N,), Δx shape (N-1,), and j and k shape (N+1,) such that j[2:end-1] represents the fluxes over the inner grid cell faces. Fluxes are added to existing values in j.

source
CryoGrid.Numerics.harmonicmean!Method
harmonicmean!(h::AbstractVector, x::AbstractVector, w::AbstractVector)

Vectorized harmonic mean of elements in x with weights w. Output is stored in h, which should have size length(x)-1.

source
CryoGrid.Numerics.makegridMethod
makegrid(strategy::DiscretizationStrategy, bounds::NTuple{2,<:DistQuantity})
-makegrid(layer::Layer, strategy::DiscretizationStrategy, bounds::NTuple{2,<:DistQuantity})

Constructs a Grid spanning bounds using the given strategy. makegrid can also be specified for specific Layer types when layers have specific discretization requirements.

source
CryoGrid.Numerics.nonlineardiffusion!Method
nonlineardiffusion!(dx::AbstractVector, j::AbstractVector, x::AbstractVector, Δx::AbstractVector, k::AbstractVector, Δk::AbstractVector)

Fast alternative to flux! and divergence! which computes fluxes and divergences (via _flux_kernel and _div_kernel) in a single pass. Note, however, that loop vectorization with @turbo is not possible because of necessary loop-carried dependencies. Fluxes and divergences are added to the existing values stored in j and dx.

source
CryoGrid.Numerics.updategrid!Method
updategrid!(grid::Grid{Edges}, edges)
-updategrid!(grid::Grid{Edges}, z0, thick::AbstractVector)

Updates all grid values based on new grid edges or an initial z0 + cell thick.

source
CryoGrid.Numerics.∇Method
∇(f::F, x::AbstractArray) where {F}

Takes a function y = f(x) and vector-valued argument x and returns a tuple: (y, ∇ₓy). The gradient is calculated using forward-mode automatic differentiation.

source
CryoGrid.Numerics.∇Method
∇(f::F, x::Number) where {F}

Takes a function y = f(x) and argument x and returns a tuple: (y, ∂y∂x). The derivative is calculated using forward-mode automatic differentiation.

source
+Numerics · CryoGrid.jl

Numerics

This module contains a wide range of numerical utilities including math and discretization routines, state variable array caches, and helper types for supporting automatic differentiation.

CryoGrid.Numerics.DiffCacheType
DiffCache{T,TCache}

Wrapper around PreallocationTools.DiffCache that stores state variables in forward-diff compatible cache arrays.

source
CryoGrid.Numerics.GridType
struct Grid{S,G,Q,A} <: AbstractDiscretization{Q,1}

Represents the 1D spatial discretization on which time integration is performed. S is a GridOffset, either Edges or Cells (always edges upon initial construction). The grid representation can be converted (allocation free) between grid edges and cells via the cells and edges methods. G represents the geometry/volume on which the vertical 1D discretization is applied. A is the underlying array type, and Q is the numerical type (e.g. Float64 or a Unitful.Quantity).

source
CryoGrid.Numerics.ProfileType
Profile{N,idxTypes,valTypes}

Represents a "profile" of values indexed typically over depth, i.e:

x₁: value 1 x₂: value 2 ...

where xᵢ are the indices.

source
CryoGrid.Numerics.StateVarsType
StateVars{names,griddvars,TU,TV,DF,DG}

Generic container for holding discretized state arrays from symbolic variables (Var types). The uproto field represetns a "prototype" of the prognostic state array which should fully define the state of the system at any given point.

source
CryoGrid.Numerics.StateVarsMethod
StateVars(vars::NamedTuple, D::Numerics.AbstractDiscretization, cachector::Function, arrayproto::Type{A}=Vector) where {A<:AbstractVector}

Constructs a StateVars container from vars and the given discretization D. The function cachector must accept argments f(name::Symbol, x::AbstractVector) where name is the name of the state variable and x is the array generated by the discretization.

source
CryoGrid.Numerics.divergence!Method
divergence!(dx::AbstractVector, j::AbstractVector, Δj::AbstractVector)

Calculates the first-order divergence over a 1D flux vector field j and grid cell lengths Δj. Divergences are added to existing values in dx.

source
CryoGrid.Numerics.flux!Method
flux!(j::AbstractVector, x::AbstractVector, Δx::AbstractVector, k::AbstractVector)

Calculates the first-order, non-linear spatial flux over a discretized variable x with conductivity k. x is assumed to have shape (N,), Δx shape (N-1,), and j and k shape (N+1,) such that j[2:end-1] represents the fluxes over the inner grid cell faces. Fluxes are added to existing values in j.

source
CryoGrid.Numerics.harmonicmean!Method
harmonicmean!(h::AbstractVector, x::AbstractVector, w::AbstractVector)

Vectorized harmonic mean of elements in x with weights w. Output is stored in h, which should have size length(x)-1.

source
CryoGrid.Numerics.makegridMethod
makegrid(strategy::DiscretizationStrategy, bounds::NTuple{2,<:DistQuantity})
+makegrid(layer::Layer, strategy::DiscretizationStrategy, bounds::NTuple{2,<:DistQuantity})

Constructs a Grid spanning bounds using the given strategy. makegrid can also be specified for specific Layer types when layers have specific discretization requirements.

source
CryoGrid.Numerics.nonlineardiffusion!Method
nonlineardiffusion!(dx::AbstractVector, j::AbstractVector, x::AbstractVector, Δx::AbstractVector, k::AbstractVector, Δk::AbstractVector)

Fast alternative to flux! and divergence! which computes fluxes and divergences (via _flux_kernel and _div_kernel) in a single pass. Note, however, that loop vectorization with @turbo is not possible because of necessary loop-carried dependencies. Fluxes and divergences are added to the existing values stored in j and dx.

source
CryoGrid.Numerics.updategrid!Method
updategrid!(grid::Grid{Edges}, edges)
+updategrid!(grid::Grid{Edges}, z0, thick::AbstractVector)

Updates all grid values based on new grid edges or an initial z0 + cell thick.

source
CryoGrid.Numerics.∇Method
∇(f::F, x::AbstractArray) where {F}

Takes a function y = f(x) and vector-valued argument x and returns a tuple: (y, ∇ₓy). The gradient is calculated using forward-mode automatic differentiation.

source
CryoGrid.Numerics.∇Method
∇(f::F, x::Number) where {F}

Takes a function y = f(x) and argument x and returns a tuple: (y, ∂y∂x). The derivative is calculated using forward-mode automatic differentiation.

source
diff --git a/dev/api/physics/heat_conduction/index.html b/dev/api/physics/heat_conduction/index.html index 831f69cb..b4af7b3b 100644 --- a/dev/api/physics/heat_conduction/index.html +++ b/dev/api/physics/heat_conduction/index.html @@ -1,2 +1,2 @@ -Heat Conduction · CryoGrid.jl

Heat conduction

CryoGrid.Heat.GeothermalHeatFluxType
GeothermalHeatFlux{TQ} <: BoundaryProcess{HeatBalance}

Represents a simple, forced Neumann heat flux boundary condition for HeatBalance processes.

source
CryoGrid.Heat.GroundHeatFluxType
GroundHeatFlux{TE,TQ} <: BoundaryProcess{HeatBalance}

Represents a simple, forced Neumann heat flux boundary condition for HeatBalance processes.

source
CryoGrid.Heat.HeatBalanceType
HeatBalance{Tfc<:FreezeCurve,THeatOp<:HeatOperator,Tdt,Tprop} <: SubSurfaceProcess

Represents subsurface heat transfer processes. The formulation of heat transfer is governed by the HeatOperator, op.

source
CryoGrid.Heat.StefanProblemType
StefanProblem{Tp<:StefanParameters,Tx,Tt}

Represents the simple two-phase Stefan problem defined on a semi-infinite slab. The one-phase Stefan problem can be computed by setting the parameters T_s = T_m.

source
CryoGrid.Heat.TemperatureBCType
TemperatureBC{E,F} <: BoundaryProcess{HeatBalance}

Represents a simple, forced Dirichlet temperature boundary condition for HeatBalance processes.

source
CryoGrid.Heat.ThermalPropertiesType
ThermalProperties

Material thermal properties, e.g. conductivity and heat capacity. By default, this includes the thermal properties of water, ice, and air. This can be extended by passing additional properties into the constructor.

source
CryoGrid.Heat.TemperatureProfileMethod
TemperatureProfile(pairs::Pair{<:Union{DistQuantity,Param},<:Union{TempQuantity,Param}}...)

Convenience constructor for Numerics.Profile which automatically converts temperature quantities.

source
CryoGrid.Heat.enthalpyMethod
enthalpy(T, C, L, θ) = T*C + L*θ

Discrete enthalpy function on temperature, heat capacity, specific latent heat of fusion, and liquid water content.

source
CryoGrid.Heat.freezethaw!Method
freezethaw!(sub::SubSurface, heat::HeatBalance{FreeWater,<:EnthalpyBased}, state)

Implementation of "free water" freezing characteristic for any subsurface layer. Assumes that state contains at least temperature (T), enthalpy (H), heat capacity (C), total water content (θwi), and liquid water content (θw).

source
CryoGrid.Heat.freezethaw!Method
freezethaw!(sub::SubSurface, heat::HeatBalance, state)

Calculates freezing and thawing effects, including evaluation of the freeze curve. In general, this function should compute at least the liquid/frozen water contents and the corresponding heat capacity. Other variables such as temperature or enthalpy may also need to be computed depending on the thermal scheme being implemented.

source
CryoGrid.Heat.heatcapacity!Method
heatcapacity!(sub::SubSurface, heat::HeatBalance, state)

Computes the heat capacity for the given layer from the current state and stores the result in-place in the state variable C.

source
CryoGrid.Heat.heatcapacityMethod
heatcapacity(sub::SubSurface, heat::HeatBalance, state, i)

Computes the heat capacity as a weighted average over constituent capacities with volumetric fractions θfracs.

source
CryoGrid.Heat.thermalconductivity!Method
thermalconductivity!(sub::SubSurface, heat::HeatBalance, state)

Computes the thermal conductivity for the given layer from the current state and stores the result in-place in the state variable k.

source
CryoGrid.Heat.thermalconductivityMethod
thermalconductivity(sub::SubSurface, heat::HeatBalance, state, i)

Computes the thermal conductivity as a squared weighted sum over constituent conductivities with volumetric fractions θfracs.

source
+Heat Conduction · CryoGrid.jl

Heat conduction

CryoGrid.Heat.GeothermalHeatFluxType
GeothermalHeatFlux{TQ} <: BoundaryProcess{HeatBalance}

Represents a simple, forced Neumann heat flux boundary condition for HeatBalance processes.

source
CryoGrid.Heat.GroundHeatFluxType
GroundHeatFlux{TE,TQ} <: BoundaryProcess{HeatBalance}

Represents a simple, forced Neumann heat flux boundary condition for HeatBalance processes.

source
CryoGrid.Heat.HeatBalanceType
HeatBalance{Tfc<:FreezeCurve,THeatOp<:HeatOperator,Tdt,Tprop} <: SubSurfaceProcess

Represents subsurface heat transfer processes. The formulation of heat transfer is governed by the HeatOperator, op.

source
CryoGrid.Heat.StefanProblemType
StefanProblem{Tp<:StefanParameters,Tx,Tt}

Represents the simple two-phase Stefan problem defined on a semi-infinite slab. The one-phase Stefan problem can be computed by setting the parameters T_s = T_m.

source
CryoGrid.Heat.TemperatureBCType
TemperatureBC{E,F} <: BoundaryProcess{HeatBalance}

Represents a simple, forced Dirichlet temperature boundary condition for HeatBalance processes.

source
CryoGrid.Heat.ThermalPropertiesType
ThermalProperties

Material thermal properties, e.g. conductivity and heat capacity. By default, this includes the thermal properties of water, ice, and air. This can be extended by passing additional properties into the constructor.

source
CryoGrid.Heat.TemperatureProfileMethod
TemperatureProfile(pairs::Pair{<:Union{DistQuantity,Param},<:Union{TempQuantity,Param}}...)

Convenience constructor for Numerics.Profile which automatically converts temperature quantities.

source
CryoGrid.Heat.enthalpyMethod
enthalpy(T, C, L, θ) = T*C + L*θ

Discrete enthalpy function on temperature, heat capacity, specific latent heat of fusion, and liquid water content.

source
CryoGrid.Heat.freezethaw!Method
freezethaw!(sub::SubSurface, heat::HeatBalance{FreeWater,<:EnthalpyBased}, state)

Implementation of "free water" freezing characteristic for any subsurface layer. Assumes that state contains at least temperature (T), enthalpy (H), heat capacity (C), total water content (θwi), and liquid water content (θw).

source
CryoGrid.Heat.freezethaw!Method
freezethaw!(sub::SubSurface, heat::HeatBalance, state)

Calculates freezing and thawing effects, including evaluation of the freeze curve. In general, this function should compute at least the liquid/frozen water contents and the corresponding heat capacity. Other variables such as temperature or enthalpy may also need to be computed depending on the thermal scheme being implemented.

source
CryoGrid.Heat.heatcapacity!Method
heatcapacity!(sub::SubSurface, heat::HeatBalance, state)

Computes the heat capacity for the given layer from the current state and stores the result in-place in the state variable C.

source
CryoGrid.Heat.heatcapacityMethod
heatcapacity(sub::SubSurface, heat::HeatBalance, state, i)

Computes the heat capacity as a weighted average over constituent capacities with volumetric fractions θfracs.

source
CryoGrid.Heat.thermalconductivity!Method
thermalconductivity!(sub::SubSurface, heat::HeatBalance, state)

Computes the thermal conductivity for the given layer from the current state and stores the result in-place in the state variable k.

source
CryoGrid.Heat.thermalconductivityMethod
thermalconductivity(sub::SubSurface, heat::HeatBalance, state, i)

Computes the thermal conductivity as a squared weighted sum over constituent conductivities with volumetric fractions θfracs.

source
diff --git a/dev/api/physics/hydrology/index.html b/dev/api/physics/hydrology/index.html index dc6cd0a3..187cf944 100644 --- a/dev/api/physics/hydrology/index.html +++ b/dev/api/physics/hydrology/index.html @@ -1,6 +1,6 @@ -Hydrology · CryoGrid.jl

Hydrology

CryoGrid.Hydrology.DampedETType
DampedET{Tftr,Tfev,Tdtr,Tdev}

Corresponds to evapotranspiration scheme 2 described in section 2.2.4 of Westermann et al. (2022).

source
CryoGrid.Hydrology.WaterBalanceType
WaterBalance{TFlow<:WaterFlow,TET<:Union{Nothing,Evapotranspiration},Tdt,Taux,TProp} <: CryoGrid.SubSurfaceProcess

Represents subsurface water transport processes.

source
CryoGrid.Hydrology.WaterTableInitializerType
WaterTableInitializer <: VarInitializer{:sat}

Simple, piecewise constant initializer for saturation state that takes a surface-level saturation sat0 and water table depth z_tab and produces a two-segment, piecewise constant profile with the saturation level set to (sat0 + 1.0) / 2 from the halfway point down to the water table.

source
CryoGrid.Hydrology.maxwaterMethod
maxwater(sub::SubSurface, ::WaterBalance) 
+Hydrology · CryoGrid.jl

Hydrology

CryoGrid.Hydrology.DampedETType
DampedET{Tftr,Tfev,Tdtr,Tdev}

Corresponds to evapotranspiration scheme 2 described in section 2.2.4 of Westermann et al. (2022).

source
CryoGrid.Hydrology.WaterBalanceType
WaterBalance{TFlow<:WaterFlow,TET<:Union{Nothing,Evapotranspiration},Tdt,Taux,TProp} <: CryoGrid.SubSurfaceProcess

Represents subsurface water transport processes.

source
CryoGrid.Hydrology.WaterTableInitializerType
WaterTableInitializer <: VarInitializer{:sat}

Simple, piecewise constant initializer for saturation state that takes a surface-level saturation sat0 and water table depth z_tab and produces a two-segment, piecewise constant profile with the saturation level set to (sat0 + 1.0) / 2 from the halfway point down to the water table.

source
CryoGrid.Hydrology.maxwaterMethod
maxwater(sub::SubSurface, ::WaterBalance) 
 maxwater(sub::SubSurface, water::WaterBalance, state)
-maxwater(::SubSurface, ::WaterBalance, state, i)

Returns the maximum volumetric water content (saturation point) for grid cell i.

source
CryoGrid.Hydrology.minwaterMethod
minwater(::SubSurface, water::WaterBalance)
-minwater(::SubSurface, water::WaterBalance, state, i)

Returns the minimum volumetric water content (typically field capacity for simplified schemes) for grid cell i. Defaults to zero.

source
CryoGrid.Hydrology.watercontentMethod
watercontent(::SubSurface, state)
-watercontent(::SubSurface, state, i)

Returns the total water content θwi from the given subsurface layer and/or current state.

source
CryoGrid.Hydrology.waterdensityMethod
waterdensity(sub::SubSurface)

Retrieves the density of water ρw from the given SubSurface layer. Default implementation assumes that WaterBalance is provided as a field water on sub; this can of course, however, be overridden.

source
+maxwater(::SubSurface, ::WaterBalance, state, i)

Returns the maximum volumetric water content (saturation point) for grid cell i.

source
CryoGrid.Hydrology.minwaterMethod
minwater(::SubSurface, water::WaterBalance)
+minwater(::SubSurface, water::WaterBalance, state, i)

Returns the minimum volumetric water content (typically field capacity for simplified schemes) for grid cell i. Defaults to zero.

source
CryoGrid.Hydrology.watercontentMethod
watercontent(::SubSurface, state)
+watercontent(::SubSurface, state, i)

Returns the total water content θwi from the given subsurface layer and/or current state.

source
CryoGrid.Hydrology.waterdensityMethod
waterdensity(sub::SubSurface)

Retrieves the density of water ρw from the given SubSurface layer. Default implementation assumes that WaterBalance is provided as a field water on sub; this can of course, however, be overridden.

source
diff --git a/dev/api/physics/salt/index.html b/dev/api/physics/salt/index.html index 87f11377..b8dddabe 100644 --- a/dev/api/physics/salt/index.html +++ b/dev/api/physics/salt/index.html @@ -1,2 +1,2 @@ -Salt · CryoGrid.jl
+Salt · CryoGrid.jl
diff --git a/dev/api/physics/seb/index.html b/dev/api/physics/seb/index.html index 8e5447ba..5d31e4c7 100644 --- a/dev/api/physics/seb/index.html +++ b/dev/api/physics/seb/index.html @@ -1,2 +1,2 @@ -Surface Energy Balance · CryoGrid.jl

Surface Energy Balance

CryoGrid.Surface.SurfaceWaterBalanceType
SurfaceWaterBalance{TR,TS} <: BoundaryProcess{Union{WaterBalance, SnowMassBalance}}

The SurfaceWaterBalance represents the closure of the water balance at the surface and acts as both a Neumann-type upper boundary condition for snow and water fluxes as well as an accountant for the water mass balance at the surface.

source
+Surface Energy Balance · CryoGrid.jl

Surface Energy Balance

CryoGrid.Surface.SurfaceWaterBalanceType
SurfaceWaterBalance{TR,TS} <: BoundaryProcess{Union{WaterBalance, SnowMassBalance}}

The SurfaceWaterBalance represents the closure of the water balance at the surface and acts as both a Neumann-type upper boundary condition for snow and water fluxes as well as an accountant for the water mass balance at the surface.

source
diff --git a/dev/api/physics/snow/index.html b/dev/api/physics/snow/index.html index 8c9b0b37..f36c2fc5 100644 --- a/dev/api/physics/snow/index.html +++ b/dev/api/physics/snow/index.html @@ -1,2 +1,2 @@ -Snow · CryoGrid.jl

Snow

CryoGrid.Snow.SnowMassBalanceType
SnowMassBalance{TAcc,TAbl} <: CryoGrid.SubSurfaceProcess

Subsurface process for snow layers governing how snow is accumulated and ablated.

source
CryoGrid.Snow.SnowpackType
Snowpack{Tpara<:SnowpackParameterization,Tmass<:SnowMassBalance,Theat<:HeatBalance,Twater<:WaterBalance,Taux} <: CryoGrid.SubSurface

Generic representation of a snowpack "subsurface" layer.

source
CryoGrid.Snow.SnowpackMethod
Snowpack(para::SnowpackParameterization; kwargs...)

Convenience constructor that accepts the parameterization as a positional argument.

source
CryoGrid.Snow.ablation!Method
ablation!(::Top, ::SnowBC, ::Snowpack, ::SnowMassBalance, stop, ssnow)

Computes snow mass balance fluxes due to ablation (e.g. snow melt).

source
CryoGrid.Snow.accumulation!Method
accumulation!(::Top, ::SnowBC, ::Snowpack, ::SnowMassBalance, stop, ssnow)

Computes snow mass balance fluxes due to accumulation (e.g. snowfall).

source
CryoGrid.Snow.snowfallMethod
snowfall(::SnowBC, state)

Retrieves the current snowfall flux for the given SnowBC. Defaults to state.jw_snow.

source
+Snow · CryoGrid.jl

Snow

CryoGrid.Snow.SnowMassBalanceType
SnowMassBalance{TAcc,TAbl} <: CryoGrid.SubSurfaceProcess

Subsurface process for snow layers governing how snow is accumulated and ablated.

source
CryoGrid.Snow.SnowpackType
Snowpack{Tpara<:SnowpackParameterization,Tmass<:SnowMassBalance,Theat<:HeatBalance,Twater<:WaterBalance,Taux} <: CryoGrid.SubSurface

Generic representation of a snowpack "subsurface" layer.

source
CryoGrid.Snow.SnowpackMethod
Snowpack(para::SnowpackParameterization; kwargs...)

Convenience constructor that accepts the parameterization as a positional argument.

source
CryoGrid.Snow.ablation!Method
ablation!(::Top, ::SnowBC, ::Snowpack, ::SnowMassBalance, stop, ssnow)

Computes snow mass balance fluxes due to ablation (e.g. snow melt).

source
CryoGrid.Snow.accumulation!Method
accumulation!(::Top, ::SnowBC, ::Snowpack, ::SnowMassBalance, stop, ssnow)

Computes snow mass balance fluxes due to accumulation (e.g. snowfall).

source
CryoGrid.Snow.snowfallMethod
snowfall(::SnowBC, state)

Retrieves the current snowfall flux for the given SnowBC. Defaults to state.jw_snow.

source
diff --git a/dev/api/physics/soils/index.html b/dev/api/physics/soils/index.html index a9f0fa1d..56e114e4 100644 --- a/dev/api/physics/soils/index.html +++ b/dev/api/physics/soils/index.html @@ -1,8 +1,8 @@ -Soils · CryoGrid.jl

Soils

CryoGrid.Soils.AbstractGroundType
AbstractGround{Tpara<:GroundParameterization,Theat<:Optional{HeatBalance},Twater<:Optional{WaterBalance}} <: SubSurface

Base type for all ground layers defining heat and water balance schemes.

source
CryoGrid.Soils.GroundType
Ground{Tpara,Theat<:Optional{HeatBalance},Twater<:Optional{WaterBalance},Taux} <: Soil{Tpara,Theat,Twater}

Generic representation of a Ground layer with material parameterization para.

source
CryoGrid.Soils.HeterogeneousType
Heterogeneous{V,N,D,Taux} <: SoilParameterization

Special SoilParameterization which wraps a Profile of another soil parameterization type to indicate that it should be heterogeneous with over depth.

source
CryoGrid.Soils.MineralOrganicType
MineralOrganic{Tpor,Tsat,Torg} <: SoilParameterization

Represents a simple organic/mineral soil mixutre in terms of its characteristic fractions: i.e. natural porosity, saturation, and organic solid fraction. This is the standard CryoGrid representation of a discrete soil volume.

source
CryoGrid.Soils.RichardsEqType
RichardsEq{Tform<:RichardsEqFormulation,Tswrc<:SWRC,Taux,TΩ} <: Hydrology.WaterFlow

The Richardson-Richards equation describes the flow of water in porous media under unsaturated condition.

source
CryoGrid.Soils.SoilType
Soil{Tpara,Theat,Twater}

Type alias for any AbstractGround layer with parameterization of type SoilParameterization.

source
CryoGrid.Soils.SoilProfileType
SoilProfile{N,IT,VT} = Profile{N,IT,VT} where {N,IT<:NTuple{N},VT<:NTuple{N,SoilParameterization}}

Alias for depthwise Profile where the values are SoilParameterization types.

source
CryoGrid.Soils.SoilProfileMethod
SoilProfile(pairs::Pair{<:DistQuantity,<:SoilParameterization}...)

Alias for Profile(pairs...) specific for SoilProfiles.

source
CryoGrid.Soils.mineralMethod
mineral(soil::Soil, state, i)
+Soils · CryoGrid.jl

Soils

CryoGrid.Soils.AbstractGroundType
AbstractGround{Tpara<:GroundParameterization,Theat<:Optional{HeatBalance},Twater<:Optional{WaterBalance}} <: SubSurface

Base type for all ground layers defining heat and water balance schemes.

source
CryoGrid.Soils.GroundType
Ground{Tpara,Theat<:Optional{HeatBalance},Twater<:Optional{WaterBalance},Taux} <: Soil{Tpara,Theat,Twater}

Generic representation of a Ground layer with material parameterization para.

source
CryoGrid.Soils.HeterogeneousType
Heterogeneous{V,N,D,Taux} <: SoilParameterization

Special SoilParameterization which wraps a Profile of another soil parameterization type to indicate that it should be heterogeneous with over depth.

source
CryoGrid.Soils.MineralOrganicType
MineralOrganic{Tpor,Tsat,Torg} <: SoilParameterization

Represents a simple organic/mineral soil mixutre in terms of its characteristic fractions: i.e. natural porosity, saturation, and organic solid fraction. This is the standard CryoGrid representation of a discrete soil volume.

source
CryoGrid.Soils.RichardsEqType
RichardsEq{Tform<:RichardsEqFormulation,Tswrc<:SWRC,Taux,TΩ} <: Hydrology.WaterFlow

The Richardson-Richards equation describes the flow of water in porous media under unsaturated condition.

source
CryoGrid.Soils.SoilType
Soil{Tpara,Theat,Twater}

Type alias for any AbstractGround layer with parameterization of type SoilParameterization.

source
CryoGrid.Soils.SoilProfileType
SoilProfile{N,IT,VT} = Profile{N,IT,VT} where {N,IT<:NTuple{N},VT<:NTuple{N,SoilParameterization}}

Alias for depthwise Profile where the values are SoilParameterization types.

source
CryoGrid.Soils.SoilProfileMethod
SoilProfile(pairs::Pair{<:DistQuantity,<:SoilParameterization}...)

Alias for Profile(pairs...) specific for SoilProfiles.

source
CryoGrid.Soils.mineralMethod
mineral(soil::Soil, state, i)
 mineral(soil::Soil, state)
-mineral(soil::Soil)

Retrieves the volumetric mineral content for the given layer at grid cell i, if provided.

source
CryoGrid.Soils.organicMethod
organic(soil::Soil, state, i)
+mineral(soil::Soil)

Retrieves the volumetric mineral content for the given layer at grid cell i, if provided.

source
CryoGrid.Soils.organicMethod
organic(soil::Soil, state, i)
 organic(soil::Soil, state)
-organic(soil::Soil)

Retrieves the volumetric organic content for the given layer at grid cell i, if provided.

source
CryoGrid.Soils.porosityMethod
porosity(soil::Soil, state, i)
+organic(soil::Soil)

Retrieves the volumetric organic content for the given layer at grid cell i, if provided.

source
CryoGrid.Soils.porosityMethod
porosity(soil::Soil, state, i)
 porosity(soil::Soil, state)
-porosity(soil::Soil)

Retrieves the porosity for the given layer at grid cell i, if provided.

source
+porosity(soil::Soil)

Retrieves the porosity for the given layer at grid cell i, if provided.

source
diff --git a/dev/api/presets/index.html b/dev/api/presets/index.html index dc7a3bc8..1da9f100 100644 --- a/dev/api/presets/index.html +++ b/dev/api/presets/index.html @@ -1,2 +1,2 @@ -Presets · CryoGrid.jl

Presets (@)

CryoGrid.Presets.SoilHeatTileMethod
SoilHeatTile([heatop=:H], upperbc::BoundaryProcess, soilprofile::Profile, init::CryoGrid.Initializer...; grid::Grid=DefaultGrid_10cm, freezecurve::F=FreeWater(), tile_kwargs...) where {F<:FreezeCurve}

Builds a simple one-layer soil/heat-conduction model with the given grid and configuration. Uses the "free water" freeze curve by default, but this can be changed via the freezecurve parameter. For example, to use the Dall'Amico freeze curve, set freezecurve=SFCC(DallAmico()).

source
+Presets · CryoGrid.jl

Presets (@)

CryoGrid.Presets.SoilHeatTileMethod
SoilHeatTile([heatop=:H], upperbc::BoundaryProcess, soilprofile::Profile, init::CryoGrid.Initializer...; grid::Grid=DefaultGrid_10cm, freezecurve::F=FreeWater(), tile_kwargs...) where {F<:FreezeCurve}

Builds a simple one-layer soil/heat-conduction model with the given grid and configuration. Uses the "free water" freeze curve by default, but this can be changed via the freezecurve parameter. For example, to use the Dall'Amico freeze curve, set freezecurve=SFCC(DallAmico()).

source
diff --git a/dev/api/solvers/basic_solvers/index.html b/dev/api/solvers/basic_solvers/index.html index a9b8964b..6fdc3063 100644 --- a/dev/api/solvers/basic_solvers/index.html +++ b/dev/api/solvers/basic_solvers/index.html @@ -1,2 +1,2 @@ -Built-in · CryoGrid.jl
+Built-in · CryoGrid.jl
diff --git a/dev/api/solvers/diffeq/index.html b/dev/api/solvers/diffeq/index.html index 8d1e350a..99259308 100644 --- a/dev/api/solvers/diffeq/index.html +++ b/dev/api/solvers/diffeq/index.html @@ -6,4 +6,4 @@ output_func=(sol, i) -> CryoGridOutput(sol), reduction=(u,data,i) -> (append!(u,data),false), ensprob_kwargs... -)

Constructs an EnsembleProblem for a m x N parameter matrix Θ, where N is the size of the ensemble and m is the dimensionality of the ensmeble parameter space (e.g. the number of parameters). transform should be a transform function that accepts an m-dimensional vector and produces a parameter vector (or CryoGridParams instance) which matches the output of CryoGrid.parameters. By default, param_map is the identity function; however, it may be customized to permit the construction of reduced-rank or reparameterized ensembles for which the parameter space differs from the full CryoGrid model parameter space.

Keyword arguments:

output_func: a function (sol,i)::Any which processes the ODESolution for ensemble member i and returns the result. It is recommended to save output to disk for non-trivial time spans to avoid slowdowns from serialization time when running the ensemble using parallel workers.

reduction: a function (u,data,i) which accumulates the result of output_func in u. Defaults to just appending data to u.

output_dir: Only used to specify the output directory for the default implementation of output_func. If a custom output_func is provided, this arugment is ignored.

All additional keyword arguments will be passed to EnsembleProblem.

See also SciMLBase.EnsembleProblem

source +)

Constructs an EnsembleProblem for a m x N parameter matrix Θ, where N is the size of the ensemble and m is the dimensionality of the ensmeble parameter space (e.g. the number of parameters). transform should be a transform function that accepts an m-dimensional vector and produces a parameter vector (or CryoGridParams instance) which matches the output of CryoGrid.parameters. By default, param_map is the identity function; however, it may be customized to permit the construction of reduced-rank or reparameterized ensembles for which the parameter space differs from the full CryoGrid model parameter space.

Keyword arguments:

output_func: a function (sol,i)::Any which processes the ODESolution for ensemble member i and returns the result. It is recommended to save output to disk for non-trivial time spans to avoid slowdowns from serialization time when running the ensemble using parallel workers.

reduction: a function (u,data,i) which accumulates the result of output_func in u. Defaults to just appending data to u.

output_dir: Only used to specify the output directory for the default implementation of output_func. If a custom output_func is provided, this arugment is ignored.

All additional keyword arguments will be passed to EnsembleProblem.

See also SciMLBase.EnsembleProblem

source diff --git a/dev/api/solvers/lite_implicit/index.html b/dev/api/solvers/lite_implicit/index.html index 0b5d3b07..34077ae4 100644 --- a/dev/api/solvers/lite_implicit/index.html +++ b/dev/api/solvers/lite_implicit/index.html @@ -1,2 +1,2 @@ -CryoGridLite · CryoGrid.jl
+CryoGridLite · CryoGrid.jl
diff --git a/dev/api/tiles/index.html b/dev/api/tiles/index.html index c00cb352..8008933f 100644 --- a/dev/api/tiles/index.html +++ b/dev/api/tiles/index.html @@ -1,5 +1,5 @@ -Tiles · CryoGrid.jl

Tiles

This module contains Tile, Stratigraphy, and all related methods and types necessary for constructing a 1-D CryoGrid process model.

CryoGrid.Tiles.StratigraphyType
Stratigraphy{N,TLayers<:NamedTuple,TBoundaries}

Defines a 1-dimensional stratigraphy by connecting a top and bottom layer to one or more subsurface layers.

source
CryoGrid.Tiles.TileType
Tile{TStrat,TGrid,TStates,TInits,TEvents,iip} <: AbstractTile{iip}

Defines the full specification of a single CryoGrid tile; i.e. stratigraphy, grid, and state variables.

source
CryoGrid.Tiles.TileMethod
Tile(
+Tiles · CryoGrid.jl

Tiles

This module contains Tile, Stratigraphy, and all related methods and types necessary for constructing a 1-D CryoGrid process model.

CryoGrid.Tiles.StratigraphyType
Stratigraphy{N,TLayers<:NamedTuple,TBoundaries}

Defines a 1-dimensional stratigraphy by connecting a top and bottom layer to one or more subsurface layers.

source
CryoGrid.Tiles.TileType
Tile{TStrat,TGrid,TStates,TInits,TEvents,iip} <: AbstractTile{iip}

Defines the full specification of a single CryoGrid tile; i.e. stratigraphy, grid, and state variables.

source
CryoGrid.Tiles.TileMethod
Tile(
     @nospecialize(strat::Stratigraphy),
     @nospecialize(discretization_strategy::DiscretizationStrategy),
     @nospecialize(inits::CryoGrid.Initializer...);
@@ -7,4 +7,4 @@
     arraytype::Type{A}=Vector,
     iip::Bool=true,
     chunk_size=nothing,
-)

Constructs a Tile from the given stratigraphy and discretization strategy. arraytype keyword arg should be an array instance (of any arbitrary length, including zero, contents are ignored) that will determine the array type used for all state vectors.

source
CryoGrid.Tiles.getstateFunction
getstate(tile::Tile, u, du, t, dt=1.0)

Constructs a LayerState representing the full state of layername given tile, state vectors u and du, and the time step t.

source
CryoGrid.Tiles.withaxesMethod
withaxes(u::AbstractArray, ::Tile)

Constructs a ComponentArray with labeled axes from the given state vector u. Assumes u to be of the same type/shape as setup.uproto.

source
+)

Constructs a Tile from the given stratigraphy and discretization strategy. arraytype keyword arg should be an array instance (of any arbitrary length, including zero, contents are ignored) that will determine the array type used for all state vectors.

source
CryoGrid.Tiles.getstateFunction
getstate(tile::Tile, u, du, t, dt=1.0)

Constructs a LayerState representing the full state of layername given tile, state vectors u and du, and the time step t.

source
CryoGrid.Tiles.withaxesMethod
withaxes(u::AbstractArray, ::Tile)

Constructs a ComponentArray with labeled axes from the given state vector u. Assumes u to be of the same type/shape as setup.uproto.

source
diff --git a/dev/api/toplevel/index.html b/dev/api/toplevel/index.html index 11ed8d2a..ef96e1ca 100644 --- a/dev/api/toplevel/index.html +++ b/dev/api/toplevel/index.html @@ -1,5 +1,5 @@ -CryoGrid · CryoGrid.jl

Top level methods and types

CryoGrid.AlgebraicType
Algebraic{name,S,T,units,domain} <: Var{name,S,T,units,domain}

Defines an algebraic (implicit) state variable.

source
CryoGrid.BCKindType
BCKind

Trait that specifies the kind of boundary condition. This can be used to write generic implementations of interact! that are (relatively) agnostic to specific implementations of BoundaryProcess. A good example of this can be found in the boundaryflux method interface.

source
CryoGrid.BCKindMethod
BCKind(::Type{T})

Can be overriden by BoundaryProcess types to indicate the type of boundary condition, e.g:

BCKind(::Type{BP}) = Dirichlet()

where BP is a BoundaryProcess that provides the boundary conditions.

source
CryoGrid.BottomType
Bottom{TProc} <: Layer

Generic "bottom" layer that marks the lower boundary of the subsurface grid.

source
CryoGrid.BoundaryProcessType
BoundaryProcess{T<:SubSurfaceProcess}

Abstract base type for boundary processes, i.e. processes that operate at the boundaries of the subsurface. A BoundaryProcess represents the boundary conditions of one or more SubSurfaceProcesses but may include its own diagnostic (or even prognostic) variables, if necessary.

source
CryoGrid.CGEulerType
CGEuler <: SciMLBase.AbstractODEAlgorithm

Simple, lightweight implementation of the forward Euler integration algorithm. Does not include support for fancier features such as interpolation, adaptive timestepping, or event handling. In order to get these features, you must install the OrdinaryDiffEq package.

source
CryoGrid.ConstantBCType
ConstantBC{P,S,T} <: BoundaryProcess{P}

Constant boundary condition (of any type/unit) specified by value.

source
CryoGrid.Coupled2Type
Coupled2{P1,P2} = CoupledProcesses{Tuple{T1,T2}} where {T1,T2}

Type alias for coupled processes, i.e. CoupledProcesses{Tuple{P1,P2}}. Coupled provides a simple mechanism for defining new behaviors on multi-processes systems.

source
CryoGrid.CoupledProcessesType
CoupledProcesses{TProcs} <: Process

Represents an explicitly or implicitly coupled system of processes. TProcs is always a Tuple of other processes.

source
CryoGrid.CryoGridProblemType
CryoGridProblem{iip,Tu,Tt,Tp,TT,Tsv,Tsf,Tcb,Tdf,Tkw} <: SciMLBase.AbstractODEProblem{Tu,Tt,iip}

Represents a CryoGrid discretized PDE forward model configuration using the SciMLBase/DiffEqBase problem interface.

source
CryoGrid.CryoGridProblemType
CryoGridProblem(
+CryoGrid · CryoGrid.jl

Top level methods and types

CryoGrid.AlgebraicType
Algebraic{name,S,T,units,domain} <: Var{name,S,T,units,domain}

Defines an algebraic (implicit) state variable.

source
CryoGrid.BCKindType
BCKind

Trait that specifies the kind of boundary condition. This can be used to write generic implementations of interact! that are (relatively) agnostic to specific implementations of BoundaryProcess. A good example of this can be found in the boundaryflux method interface.

source
CryoGrid.BCKindMethod
BCKind(::Type{T})

Can be overriden by BoundaryProcess types to indicate the type of boundary condition, e.g:

BCKind(::Type{BP}) = Dirichlet()

where BP is a BoundaryProcess that provides the boundary conditions.

source
CryoGrid.BottomType
Bottom{TProc} <: Layer

Generic "bottom" layer that marks the lower boundary of the subsurface grid.

source
CryoGrid.BoundaryProcessType
BoundaryProcess{T<:SubSurfaceProcess}

Abstract base type for boundary processes, i.e. processes that operate at the boundaries of the subsurface. A BoundaryProcess represents the boundary conditions of one or more SubSurfaceProcesses but may include its own diagnostic (or even prognostic) variables, if necessary.

source
CryoGrid.CGEulerType
CGEuler <: SciMLBase.AbstractODEAlgorithm

Simple, lightweight implementation of the forward Euler integration algorithm. Does not include support for fancier features such as interpolation, adaptive timestepping, or event handling. In order to get these features, you must install the OrdinaryDiffEq package.

source
CryoGrid.ConstantBCType
ConstantBC{P,S,T} <: BoundaryProcess{P}

Constant boundary condition (of any type/unit) specified by value.

source
CryoGrid.Coupled2Type
Coupled2{P1,P2} = CoupledProcesses{Tuple{T1,T2}} where {T1,T2}

Type alias for coupled processes, i.e. CoupledProcesses{Tuple{P1,P2}}. Coupled provides a simple mechanism for defining new behaviors on multi-processes systems.

source
CryoGrid.CoupledProcessesType
CoupledProcesses{TProcs} <: Process

Represents an explicitly or implicitly coupled system of processes. TProcs is always a Tuple of other processes.

source
CryoGrid.CryoGridProblemType
CryoGridProblem{iip,Tu,Tt,Tp,TT,Tsv,Tsf,Tcb,Tdf,Tkw} <: SciMLBase.AbstractODEProblem{Tu,Tt,iip}

Represents a CryoGrid discretized PDE forward model configuration using the SciMLBase/DiffEqBase problem interface.

source
CryoGrid.CryoGridProblemType
CryoGridProblem(
     tile::Tile,
     u0::ComponentVector,
     tspan::NTuple{2,Float64},
@@ -17,21 +17,21 @@
     specialization=SciMLBase.AutoSpecialize,
     function_kwargs=(),
     prob_kwargs...
-)

Constructor for CryoGridProblem that automatically generates all necessary callbacks.

source
CryoGrid.DiagnosticType
Diagnostic{name,S,T,units,domain} <: Var{name,S,T,units,domain}

Defines a diagnostic variable which is allocated and cached per timestep but not integrated over time.

source
CryoGrid.DiagnosticVolumeType
DiagnosticVolume

Volume trait instance for layers with time varying volume where the volume should be treated as a diagnostic state variable.

source
CryoGrid.PeriodicBCType
PeriodicBC{P,S,T1,T2,T3,T4} <: BoundaryProcess{P}

Periodic boundary condition (of any type/unit) specified by period, amplitude, and phaseshift.

source
CryoGrid.PrognosticType
Prognostic{name,S,T,units,domain} <: Var{name,S,T,units,domain}

Defines a prognostic (time-integrated) state variable.

source
CryoGrid.PrognosticVolumeType
PrognosticVolume

Volume trait instance for layers with time varying volume where the volume should be treated as a prognostic state variable.

source
CryoGrid.SubSurfaceType
SubSurface <: Layer

Abstract base type for layers in the stratigraphy, e.g. soil, snow, pond, etc.

source
CryoGrid.SubSurfaceProcessType
SubSurfaceProcess <: Process

Abstract base type for subsurface processes, i.e. processes that operate at or below the surface, such as heat conduction, water infiltration, etc.

source
CryoGrid.TopType
Top{TProc} <: Layer

Generic "top" layer that marks the upper boundary of the subsurface grid.

source
CryoGrid.VarType
Var{name,S<:VarDim,T,units,domain}

Base type for symbolic state variables in the model.

source
CryoGrid.VarInitializerType
VarInitializer{varname}

Base type for state variable initializers. Initializers of this type are dedicated to a specific state variable with name varname and are run before all other initializers.

source
CryoGrid.VolumeMethod
Volume(::Type{<:Layer})

Trait for layer types that determines whether its spatial volume is temporally invariant, FixedVolume, or varying with time, DiagnosticVolume or PrognosticVolume.

source
CryoGrid.CoupledMethod
Coupled(ps::SubSurfaceProcess...)

Constructs a composite/coupled process from one or more subsurface processes. Alias for CoupledProcesses(ps...).

source
CryoGrid.CoupledMethod
Coupled(types::Type{<:Process}...)

Convenince method which constructs a CoupledProcesses type corresponding to each type in types, e.g:

Coupled(SnowMassBalance, HeatBalance) = CoupledProcesses{Tuple{T1,T2}} where {T1<:SnowMassBalance, T2<:HeatBalance}

also equivalent to Coupled2{<:SnowMassBalance,<:HeatBalance}.

source
CryoGrid.boundaryfluxMethod
boundaryflux(bc::BoundaryProcess, b::Union{Top,Bottom}, p::SubSurfaceProcess, sub::SubSurface, sbc, ssub)
-boundaryflux(s::BCKind, bc::BoundaryProcess, b::Union{Top,Bottom}, p::SubSurfaceProcess, sub::SubSurface, sbc, ssub)

Computes the flux dH/dt at the boundary layer. Calls boundaryflux(BCKind(B),...) to allow for generic implementations by boundary condition type. Note that this method uses a different argument order convention than interact!. This is intended to faciliate stratigraphy independent implementations of certain boundary conditions (e.g. a simple Dirichlet boundary could be applied in the same manner to both the upper and lower boundary).

source
CryoGrid.boundaryvalueMethod
boundaryvalue(bc::BoundaryProcess, state)

Computes the value of the boundary condition specified by bc for the given layer/process combinations. Note that this method uses a different argument order convention than interact!. This is intended to faciliate stratigraphy independent implementations of certain boundary conditions (e.g. a simple Dirichlet boundary could be applied in the same manner to both the upper and lower boundary).

source
CryoGrid.caninteractMethod
caninteract(layer1::Layer, layer2::Layer, state1, state2)
-caninteract(l1::Layer, ::Process, l2::Layer, ::Process, state1, state2)

Returns true if and only if the given layer/process types are able to interact based on the current state. Defaults to checking whether both layers are currently active. This behavior should be overridden by subtypes where necessary.

source
CryoGrid.computediagnostic!Method
computediagnostic!(l::Layer, state)
-computediagnostic!(l::Layer, p::Process, state)

Updates all diagnostic/non-flux state variables for the given Layer based on the current prognostic state.

source
CryoGrid.computefluxes!Method
computefluxes!(l::Layer, p::Process, state)

Calculates all internal fluxes for a given layer. Note that an instance of computefluxes! must be provided for all non-boundary (subsurface) processes/layers.

source
CryoGrid.criterion!Method
criterion!(out::AbstractArray, ev::GridContinuousEvent, ::Layer, ::Process, state)

Event criterion for on-grid (i.e. multi-valued) continuous events. The condition for each grid cell should be stored in out.

source
CryoGrid.criterionMethod
criterion(::Event, ::Layer, ::Process, state)

Event criterion/condition. Should return a Bool for discrete events. For continuous events, this should be a real-valued function where the event is fired at the zeros/roots.

source
CryoGrid.diagnosticstep!Method
diagnosticstep!(layer::Layer, state)

Optionally performs discontinuous/discrete-time updates to the layer state. Should return true if the prognostic state was modified and false otherwise. Defaults to returning false.

source
CryoGrid.initialcondition!Method
initialcondition!(::Layer, state)
+)

Constructor for CryoGridProblem that automatically generates all necessary callbacks.

source
CryoGrid.DiagnosticType
Diagnostic{name,S,T,units,domain} <: Var{name,S,T,units,domain}

Defines a diagnostic variable which is allocated and cached per timestep but not integrated over time.

source
CryoGrid.DiagnosticVolumeType
DiagnosticVolume

Volume trait instance for layers with time varying volume where the volume should be treated as a diagnostic state variable.

source
CryoGrid.PeriodicBCType
PeriodicBC{P,S,T1,T2,T3,T4} <: BoundaryProcess{P}

Periodic boundary condition (of any type/unit) specified by period, amplitude, and phaseshift.

source
CryoGrid.PrognosticType
Prognostic{name,S,T,units,domain} <: Var{name,S,T,units,domain}

Defines a prognostic (time-integrated) state variable.

source
CryoGrid.PrognosticVolumeType
PrognosticVolume

Volume trait instance for layers with time varying volume where the volume should be treated as a prognostic state variable.

source
CryoGrid.SubSurfaceType
SubSurface <: Layer

Abstract base type for layers in the stratigraphy, e.g. soil, snow, pond, etc.

source
CryoGrid.SubSurfaceProcessType
SubSurfaceProcess <: Process

Abstract base type for subsurface processes, i.e. processes that operate at or below the surface, such as heat conduction, water infiltration, etc.

source
CryoGrid.TopType
Top{TProc} <: Layer

Generic "top" layer that marks the upper boundary of the subsurface grid.

source
CryoGrid.VarType
Var{name,S<:VarDim,T,units,domain}

Base type for symbolic state variables in the model.

source
CryoGrid.VarInitializerType
VarInitializer{varname}

Base type for state variable initializers. Initializers of this type are dedicated to a specific state variable with name varname and are run before all other initializers.

source
CryoGrid.VolumeMethod
Volume(::Type{<:Layer})

Trait for layer types that determines whether its spatial volume is temporally invariant, FixedVolume, or varying with time, DiagnosticVolume or PrognosticVolume.

source
CryoGrid.CoupledMethod
Coupled(ps::SubSurfaceProcess...)

Constructs a composite/coupled process from one or more subsurface processes. Alias for CoupledProcesses(ps...).

source
CryoGrid.CoupledMethod
Coupled(types::Type{<:Process}...)

Convenince method which constructs a CoupledProcesses type corresponding to each type in types, e.g:

Coupled(SnowMassBalance, HeatBalance) = CoupledProcesses{Tuple{T1,T2}} where {T1<:SnowMassBalance, T2<:HeatBalance}

also equivalent to Coupled2{<:SnowMassBalance,<:HeatBalance}.

source
CryoGrid.boundaryfluxMethod
boundaryflux(bc::BoundaryProcess, b::Union{Top,Bottom}, p::SubSurfaceProcess, sub::SubSurface, sbc, ssub)
+boundaryflux(s::BCKind, bc::BoundaryProcess, b::Union{Top,Bottom}, p::SubSurfaceProcess, sub::SubSurface, sbc, ssub)

Computes the flux dH/dt at the boundary layer. Calls boundaryflux(BCKind(B),...) to allow for generic implementations by boundary condition type. Note that this method uses a different argument order convention than interact!. This is intended to faciliate stratigraphy independent implementations of certain boundary conditions (e.g. a simple Dirichlet boundary could be applied in the same manner to both the upper and lower boundary).

source
CryoGrid.boundaryvalueMethod
boundaryvalue(bc::BoundaryProcess, state)

Computes the value of the boundary condition specified by bc for the given layer/process combinations. Note that this method uses a different argument order convention than interact!. This is intended to faciliate stratigraphy independent implementations of certain boundary conditions (e.g. a simple Dirichlet boundary could be applied in the same manner to both the upper and lower boundary).

source
CryoGrid.caninteractMethod
caninteract(layer1::Layer, layer2::Layer, state1, state2)
+caninteract(l1::Layer, ::Process, l2::Layer, ::Process, state1, state2)

Returns true if and only if the given layer/process types are able to interact based on the current state. Defaults to checking whether both layers are currently active. This behavior should be overridden by subtypes where necessary.

source
CryoGrid.computediagnostic!Method
computediagnostic!(l::Layer, state)
+computediagnostic!(l::Layer, p::Process, state)

Updates all diagnostic/non-flux state variables for the given Layer based on the current prognostic state.

source
CryoGrid.computefluxes!Method
computefluxes!(l::Layer, p::Process, state)

Calculates all internal fluxes for a given layer. Note that an instance of computefluxes! must be provided for all non-boundary (subsurface) processes/layers.

source
CryoGrid.criterion!Method
criterion!(out::AbstractArray, ev::GridContinuousEvent, ::Layer, ::Process, state)

Event criterion for on-grid (i.e. multi-valued) continuous events. The condition for each grid cell should be stored in out.

source
CryoGrid.criterionMethod
criterion(::Event, ::Layer, ::Process, state)

Event criterion/condition. Should return a Bool for discrete events. For continuous events, this should be a real-valued function where the event is fired at the zeros/roots.

source
CryoGrid.diagnosticstep!Method
diagnosticstep!(layer::Layer, state)

Optionally performs discontinuous/discrete-time updates to the layer state. Should return true if the prognostic state was modified and false otherwise. Defaults to returning false.

source
CryoGrid.initialcondition!Method
initialcondition!(::Layer, state)
 initialcondition!(::Layer, ::Process, state)
-initialcondition!(::VarInitializer, ::Layer, state)

Defines the initial condition for a given Layer and possibly an initializer. initialcondition! should compute initial values into all relevant state variables in state.

source
CryoGrid.initialcondition!Method
initialcondition!(layer1::Layer, layer2::Layer, state1, state2)
-initialcondition!(::Layer, ::Process, ::Layer, ::Process, state1, state2)

Defines the initial condition for two processes on adjacent layers. initialcondition! should write initial values into all relevant state variables in state.

source
CryoGrid.initializerMethod
initializer(varname::Symbol, args...) = initializer(Val{varname}(), args...)
+initialcondition!(::VarInitializer, ::Layer, state)

Defines the initial condition for a given Layer and possibly an initializer. initialcondition! should compute initial values into all relevant state variables in state.

source
CryoGrid.initialcondition!Method
initialcondition!(layer1::Layer, layer2::Layer, state1, state2)
+initialcondition!(::Layer, ::Process, ::Layer, ::Process, state1, state2)

Defines the initial condition for two processes on adjacent layers. initialcondition! should write initial values into all relevant state variables in state.

source
CryoGrid.initializerMethod
initializer(varname::Symbol, args...) = initializer(Val{varname}(), args...)
 initializer(::Val{varname}, x::Number) => FunctionInitializer w/ constant
 initializer(::Val{varname}, f::Function) => FunctionInitializer
-initializer(::Val{varname}, profile::Profile, interp=Linear(), extrap=Flat()) => InterpInitializer

Convenience constructor for VarInitializer that selects the appropriate initializer type based on the arguments.

source
CryoGrid.initializersMethod
initializers(::Layer)
-initializers(::Layer, ::Process)

Optional method that can be used to provide default initializers for state variables that will be run before user provided ones.

source
CryoGrid.interact!Method
interact!(::Layer, ::Process, ::Layer, ::Process, state1, state2)

Defines a boundary interaction between two processes on adjacent layers. For any interaction, the order of the arguments follows decreasing depth, i.e. the first layer/process is always on top of the second layer/process. This ordering matters and separate dispatches must be provided for interactions in reverse order.

source
CryoGrid.interactmaybe!Method
interactmaybe!(layer1::Layer, layer2::Layer, state1, state2)
-interactmaybe!(layer1::Layer, p1::Process, layer2::Layer, p2::Process, state1, state2)

Conditionally invokes interact! if and only if caninteract is true.

source
CryoGrid.isactiveMethod
isactive(::Layer, state)

Returns a boolean whether or not this layer is currently active in the stratigraphy and should interact with other layers. Note that computediagnostic! and computefluxes! are always invoked regardless of the current state of isactive. The default implementation of isactive always returns true.

source
CryoGrid.processesMethod
processes(l::Layer)

Fetches the process(es) attached to this layer, if any. Returned value must be of type Process. If the layer has more than one process, they should be combined together with Coupled(procs...).

source
CryoGrid.resetfluxes!Method
resetfluxes!(layer::Layer, state)
-resetfluxes!(layer::Layer, ::Process, state)

Resets all flux variables for the given layer/process to zero.

source
CryoGrid.timestepMethod
timestep(::Layer, ::Process, state)

Retrieves the recommended timestep for the given Process defined on the given Layer. The default implementation returns Inf which indicates no timestep restriction. The actual chosen timestep will depend on the integrator being used and other user configuration options.

source
CryoGrid.timestepMethod
timestep(l::Layer, ps::CoupledProcesses{P}, state) where {P}

Default implementation of timestep for coupled process types. Calls each process in sequence.

source
CryoGrid.trigger!Method
trigger!(::Event, ::Layer, ::Process, state)
+initializer(::Val{varname}, profile::Profile, interp=Linear(), extrap=Flat()) => InterpInitializer

Convenience constructor for VarInitializer that selects the appropriate initializer type based on the arguments.

source
CryoGrid.initializersMethod
initializers(::Layer)
+initializers(::Layer, ::Process)

Optional method that can be used to provide default initializers for state variables that will be run before user provided ones.

source
CryoGrid.interact!Method
interact!(::Layer, ::Process, ::Layer, ::Process, state1, state2)

Defines a boundary interaction between two processes on adjacent layers. For any interaction, the order of the arguments follows decreasing depth, i.e. the first layer/process is always on top of the second layer/process. This ordering matters and separate dispatches must be provided for interactions in reverse order.

source
CryoGrid.interactmaybe!Method
interactmaybe!(layer1::Layer, layer2::Layer, state1, state2)
+interactmaybe!(layer1::Layer, p1::Process, layer2::Layer, p2::Process, state1, state2)

Conditionally invokes interact! if and only if caninteract is true.

source
CryoGrid.isactiveMethod
isactive(::Layer, state)

Returns a boolean whether or not this layer is currently active in the stratigraphy and should interact with other layers. Note that computediagnostic! and computefluxes! are always invoked regardless of the current state of isactive. The default implementation of isactive always returns true.

source
CryoGrid.processesMethod
processes(l::Layer)

Fetches the process(es) attached to this layer, if any. Returned value must be of type Process. If the layer has more than one process, they should be combined together with Coupled(procs...).

source
CryoGrid.resetfluxes!Method
resetfluxes!(layer::Layer, state)
+resetfluxes!(layer::Layer, ::Process, state)

Resets all flux variables for the given layer/process to zero.

source
CryoGrid.timestepMethod
timestep(::Layer, ::Process, state)

Retrieves the recommended timestep for the given Process defined on the given Layer. The default implementation returns Inf which indicates no timestep restriction. The actual chosen timestep will depend on the integrator being used and other user configuration options.

source
CryoGrid.timestepMethod
timestep(l::Layer, ps::CoupledProcesses{P}, state) where {P}

Default implementation of timestep for coupled process types. Calls each process in sequence.

source
CryoGrid.trigger!Method
trigger!(::Event, ::Layer, ::Process, state)
 trigger!(ev::ContinuousEvent, ::ContinuousTrigger, ::Layer, ::Process, state)
-trigger!(ev::GridContinuousEvent, ::ContinuousTrigger, ::Layer, ::Process, state)

Event action executed when criterion is met.

source
CryoGrid.variablesMethod
variables(layer::Layer, process::Process)
+trigger!(ev::GridContinuousEvent, ::ContinuousTrigger, ::Layer, ::Process, state)

Event action executed when criterion is met.

source
CryoGrid.variablesMethod
variables(layer::Layer, process::Process)
 variables(::Layer)
-variables(::Any)

Defines variables for a given Layer, Process, or arbitrary user-defined type. Implementations should return a Tuple of Vars.

source
CryoGrid.volumetricfractionsMethod
volumetricfractions(::SubSurface, state)
-volumetricfractions(::SubSurface, state, i)

Get the volumetric fractions of each constituent in the volume (at grid cell i, if specificed). All implementations of volumetricfractions are expected to obey a semi-consistent order in the returned Tuple of fractions; the first three consituents should always be θw,θi,θa, i.e. water, ice, and air, followed by any number of additional constituents which may be defined by the specific layer. There is no feasible way to verify that client code actually obeys this ordering, so be sure to double check your implementation, otherwise this can cause very subtle bugs!

source
+variables(::Any)

Defines variables for a given Layer, Process, or arbitrary user-defined type. Implementations should return a Tuple of Vars.

source
CryoGrid.volumetricfractionsMethod
volumetricfractions(::SubSurface, state)
+volumetricfractions(::SubSurface, state, i)

Get the volumetric fractions of each constituent in the volume (at grid cell i, if specificed). All implementations of volumetricfractions are expected to obey a semi-consistent order in the returned Tuple of fractions; the first three consituents should always be θw,θi,θa, i.e. water, ice, and air, followed by any number of additional constituents which may be defined by the specific layer. There is no feasible way to verify that client code actually obeys this ordering, so be sure to double check your implementation, otherwise this can cause very subtle bugs!

source
diff --git a/dev/api/utils/index.html b/dev/api/utils/index.html index c9c5fe65..24a053cf 100644 --- a/dev/api/utils/index.html +++ b/dev/api/utils/index.html @@ -1,5 +1,5 @@ -Utilities · CryoGrid.jl

Utility methods and types

This module provides miscellaneous utility methods and types that are used throughout the CryoGrid.jl codebase. Note that the Utils module is not exported by the top-level CryoGrid module. It may, however, be explicitly imported by the user via using CryoGrid.Utils or import CryoGrid.Utils when needed.

CryoGrid.Utils.NamedTupleWrapperType
NamedTupleWrapper

Base type for container types that hold a NamedTuple of arbitrary field values. NamedTupleWrapper provides dispatches for getproperty and propertynames that forward property name queries to the NamedTuple container. Subtypes are by default assumed to have a field named values that corresponds to the NamedTuple container, but this can be overriden by providing a dispatch for Base.values.

source
CryoGrid.Utils.applyunitsMethod
applyunits(u::Unitful.Units, x::Number)

Conditionally applies unit u to x if and only if x is a unit-free quantity. If x is a unitful quantity, asserts that the unit matches u.

source
CryoGrid.Utils.convert_tMethod
convert_t(t::DateTime)
-convert_t(t::Float64)

Convenience method for converting between Dates.DateTime and solver time.

source
CryoGrid.Utils.convert_tspanMethod
convert_tspan(tspan::Tuple{DateTime,DateTime})
-convert_tspan(tspan::Tuple{Float64,Float64})

Convenience method for converting between Dates.DateTime and solver time.

source
CryoGrid.Utils.fastiterateMethod
fastiterate(f!::F, iters::NTuple{N,Any}...) where {F,N}

Same as fastmap but simply invokes f! on each argument set without constructing a tuple.

source
CryoGrid.Utils.fastmapMethod
fastmap(f::F, iter::NTuple{N,Any}...) where {F,N}

Same as map for NTuples but with guaranteed type stability. fastmap is a @generated function which unrolls calls to f into a loop-free tuple construction expression.

source
CryoGrid.Utils.getscalarMethod
getscalar(x)
-getscalar(x, i)

Helper method for generalizing between arrays and scalars. Without an index, retrieves the first element of x if x is an array, otherwise simply returning x. If an index i, is specified, returns the ith value of x if x is an array, or x otherwise. Note that this method is not strictly necessary since Julia allows for scalar quantities to be accessed at the first index like an array; however, the point is to make it expliclty clear in scalar-typed code that a state variable is treated as such and is not a vector valued quantity.

source
CryoGrid.Utils.pstripMethod
pstrip(obj; keep_units=false)

Strips Param types and units from obj. If keep_units=true, then Param types will be stripped but units preserved.

source
CryoGrid.Utils.@UFloat_strMacro

Similar to Unitful.@u_str (i.e. u"kg") but produces the type of the quantity rather than the instance. NOT conditional on debug mode.

source
CryoGrid.Utils.@UT_strMacro

Similar to Unitful.@u_str (i.e. u"kg") but produces the type of the unit rather than the instance. NOT conditional on debug mode.

source
CryoGrid.Utils.@setscalarMacro

Convenience macro for setting scalar (single-element) arrays/vectors. It turns an expression of the form: a.b = ... into a.b[1] = ...

This is primarily intended for code clarity, i.e to clearly discern scalar and non-scalar values.

source
CryoGrid.Utils.@sym_strMacro
sym_str(val)

Convenience macro, sym"val", for creating a Symbol from val. Equivalent to Symbol(val). Use in situations where normal Julia :val syntax is not possible, e.g. sym"1" instead of Symbol(1) or sym"my.var" instead of Symbol("my.var").

source
CryoGrid.Utils.@threadedMacro

Prepends expr with Threads.@threads if and only if Threads.nthreads() > 1, thus avoiding the overhead of @threads when running in single-threaded mode.

Credit to @ranocha (Hendrik Ranocha) https://discourse.julialang.org/t/overhead-of-threads-threads/53964/22

source
+Utilities · CryoGrid.jl

Utility methods and types

This module provides miscellaneous utility methods and types that are used throughout the CryoGrid.jl codebase. Note that the Utils module is not exported by the top-level CryoGrid module. It may, however, be explicitly imported by the user via using CryoGrid.Utils or import CryoGrid.Utils when needed.

CryoGrid.Utils.NamedTupleWrapperType
NamedTupleWrapper

Base type for container types that hold a NamedTuple of arbitrary field values. NamedTupleWrapper provides dispatches for getproperty and propertynames that forward property name queries to the NamedTuple container. Subtypes are by default assumed to have a field named values that corresponds to the NamedTuple container, but this can be overriden by providing a dispatch for Base.values.

source
CryoGrid.Utils.applyunitsMethod
applyunits(u::Unitful.Units, x::Number)

Conditionally applies unit u to x if and only if x is a unit-free quantity. If x is a unitful quantity, asserts that the unit matches u.

source
CryoGrid.Utils.convert_tMethod
convert_t(t::DateTime)
+convert_t(t::Float64)

Convenience method for converting between Dates.DateTime and solver time.

source
CryoGrid.Utils.convert_tspanMethod
convert_tspan(tspan::Tuple{DateTime,DateTime})
+convert_tspan(tspan::Tuple{Float64,Float64})

Convenience method for converting between Dates.DateTime and solver time.

source
CryoGrid.Utils.fastiterateMethod
fastiterate(f!::F, iters::NTuple{N,Any}...) where {F,N}

Same as fastmap but simply invokes f! on each argument set without constructing a tuple.

source
CryoGrid.Utils.fastmapMethod
fastmap(f::F, iter::NTuple{N,Any}...) where {F,N}

Same as map for NTuples but with guaranteed type stability. fastmap is a @generated function which unrolls calls to f into a loop-free tuple construction expression.

source
CryoGrid.Utils.getscalarMethod
getscalar(x)
+getscalar(x, i)

Helper method for generalizing between arrays and scalars. Without an index, retrieves the first element of x if x is an array, otherwise simply returning x. If an index i, is specified, returns the ith value of x if x is an array, or x otherwise. Note that this method is not strictly necessary since Julia allows for scalar quantities to be accessed at the first index like an array; however, the point is to make it expliclty clear in scalar-typed code that a state variable is treated as such and is not a vector valued quantity.

source
CryoGrid.Utils.pstripMethod
pstrip(obj; keep_units=false)

Strips Param types and units from obj. If keep_units=true, then Param types will be stripped but units preserved.

source
CryoGrid.Utils.@UFloat_strMacro

Similar to Unitful.@u_str (i.e. u"kg") but produces the type of the quantity rather than the instance. NOT conditional on debug mode.

source
CryoGrid.Utils.@UT_strMacro

Similar to Unitful.@u_str (i.e. u"kg") but produces the type of the unit rather than the instance. NOT conditional on debug mode.

source
CryoGrid.Utils.@setscalarMacro

Convenience macro for setting scalar (single-element) arrays/vectors. It turns an expression of the form: a.b = ... into a.b[1] = ...

This is primarily intended for code clarity, i.e to clearly discern scalar and non-scalar values.

source
CryoGrid.Utils.@sym_strMacro
sym_str(val)

Convenience macro, sym"val", for creating a Symbol from val. Equivalent to Symbol(val). Use in situations where normal Julia :val syntax is not possible, e.g. sym"1" instead of Symbol(1) or sym"my.var" instead of Symbol("my.var").

source
CryoGrid.Utils.@threadedMacro

Prepends expr with Threads.@threads if and only if Threads.nthreads() > 1, thus avoiding the overhead of @threads when running in single-threaded mode.

Credit to @ranocha (Hendrik Ranocha) https://discourse.julialang.org/t/overhead-of-threads-threads/53964/22

source
diff --git a/dev/dev/concepts/index.html b/dev/dev/concepts/index.html index 2e4d98d8..5cb408e2 100644 --- a/dev/dev/concepts/index.html +++ b/dev/dev/concepts/index.html @@ -19,4 +19,4 @@ computediagnostic!(Layer1(), MyProcess() state) computediagnostic!(Layer2(), MyProcess(), state)

Output:

hello MyProcess on any SubSurface
-hello MyProcess on Bar

Thus, multiple dispatch allows us to write generic code in computediagnostic! that implements MyProcess for any SubSurface layer (i.e. the parent type of both Foo and Bar) in addition to adding specialized code for more specific layer types.

+hello MyProcess on Bar

Thus, multiple dispatch allows us to write generic code in computediagnostic! that implements MyProcess for any SubSurface layer (i.e. the parent type of both Foo and Bar) in addition to adding specialized code for more specific layer types.

diff --git a/dev/dev/contributing/index.html b/dev/dev/contributing/index.html index 97f5a5de..941b1800 100644 --- a/dev/dev/contributing/index.html +++ b/dev/dev/contributing/index.html @@ -1,2 +1,2 @@ -Contributing · CryoGrid.jl
+Contributing · CryoGrid.jl
diff --git a/dev/dev/debugging/index.html b/dev/dev/debugging/index.html index 0f95ab1f..d0b4fd1c 100644 --- a/dev/dev/debugging/index.html +++ b/dev/dev/debugging/index.html @@ -1,2 +1,2 @@ -Debugging · CryoGrid.jl
+Debugging · CryoGrid.jl
diff --git a/dev/examples/heat_freeW_bucketW_samoylov/bb2f829b.svg b/dev/examples/heat_freeW_bucketW_samoylov/6917f78e.svg similarity index 99% rename from dev/examples/heat_freeW_bucketW_samoylov/bb2f829b.svg rename to dev/examples/heat_freeW_bucketW_samoylov/6917f78e.svg index d8a9d282..8bce7883 100644 --- a/dev/examples/heat_freeW_bucketW_samoylov/bb2f829b.svg +++ b/dev/examples/heat_freeW_bucketW_samoylov/6917f78e.svg @@ -1,47 +1,47 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/examples/heat_freeW_bucketW_samoylov/06285a09.svg b/dev/examples/heat_freeW_bucketW_samoylov/7fd16456.svg similarity index 99% rename from dev/examples/heat_freeW_bucketW_samoylov/06285a09.svg rename to dev/examples/heat_freeW_bucketW_samoylov/7fd16456.svg index ad812150..f7f279ba 100644 --- a/dev/examples/heat_freeW_bucketW_samoylov/06285a09.svg +++ b/dev/examples/heat_freeW_bucketW_samoylov/7fd16456.svg @@ -1,47 +1,47 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/examples/heat_freeW_bucketW_samoylov/fae75a76.svg b/dev/examples/heat_freeW_bucketW_samoylov/bf219679.svg similarity index 99% rename from dev/examples/heat_freeW_bucketW_samoylov/fae75a76.svg rename to dev/examples/heat_freeW_bucketW_samoylov/bf219679.svg index 545f774d..17271d69 100644 --- a/dev/examples/heat_freeW_bucketW_samoylov/fae75a76.svg +++ b/dev/examples/heat_freeW_bucketW_samoylov/bf219679.svg @@ -1,47 +1,47 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/examples/heat_freeW_bucketW_samoylov/db989f7b.svg b/dev/examples/heat_freeW_bucketW_samoylov/bfb3591c.svg similarity index 96% rename from dev/examples/heat_freeW_bucketW_samoylov/db989f7b.svg rename to dev/examples/heat_freeW_bucketW_samoylov/bfb3591c.svg index a9d5c9e4..50e22ce3 100644 --- a/dev/examples/heat_freeW_bucketW_samoylov/db989f7b.svg +++ b/dev/examples/heat_freeW_bucketW_samoylov/bfb3591c.svg @@ -1,37 +1,37 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + diff --git a/dev/examples/heat_freeW_bucketW_samoylov/index.html b/dev/examples/heat_freeW_bucketW_samoylov/index.html index 8af39da9..6ca0d181 100644 --- a/dev/examples/heat_freeW_bucketW_samoylov/index.html +++ b/dev/examples/heat_freeW_bucketW_samoylov/index.html @@ -35,4 +35,4 @@ water_mass = Diagnostics.integrate(out.θwi, tile.grid) Δwater = water_mass[end] - water_mass[1]

Plot the results:

import Plots
 zs = [1,5,9,15,21,25,33,55,65,75,100]u"cm"
-cg = Plots.cgrad(:copper,rev=true);

Temperature:

Plots.plot(out.T[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Temperature", leg=false, size=(800,500), dpi=150)
Example block output

Liquid water:

Plots.plot(out.θw[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Unfrozen water content", leg=false, size=(800,500), dpi=150)
Example block output

Saturation:

Plots.plot(out.sat[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Saturation", leg=false, size=(800,500), dpi=150)
Example block output

Runoff:

Plots.plot(out.top.runoff[1,:], ylabel="Runoff")
Example block output

This page was generated using Literate.jl.

+cg = Plots.cgrad(:copper,rev=true);

Temperature:

Plots.plot(out.T[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Temperature", leg=false, size=(800,500), dpi=150)
Example block output

Liquid water:

Plots.plot(out.θw[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Unfrozen water content", leg=false, size=(800,500), dpi=150)
Example block output

Saturation:

Plots.plot(out.sat[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Saturation", leg=false, size=(800,500), dpi=150)
Example block output

Runoff:

Plots.plot(out.top.runoff[1,:], ylabel="Runoff")
Example block output

This page was generated using Literate.jl.

diff --git a/dev/examples/heat_freeW_lite_implicit/95c53d3c.svg b/dev/examples/heat_freeW_lite_implicit/8ec38367.svg similarity index 99% rename from dev/examples/heat_freeW_lite_implicit/95c53d3c.svg rename to dev/examples/heat_freeW_lite_implicit/8ec38367.svg index 03246545..b979f4a4 100644 --- a/dev/examples/heat_freeW_lite_implicit/95c53d3c.svg +++ b/dev/examples/heat_freeW_lite_implicit/8ec38367.svg @@ -1,52 +1,52 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/examples/heat_freeW_lite_implicit/index.html b/dev/examples/heat_freeW_lite_implicit/index.html index 40afcdda..900e6a6e 100644 --- a/dev/examples/heat_freeW_lite_implicit/index.html +++ b/dev/examples/heat_freeW_lite_implicit/index.html @@ -32,5 +32,5 @@

Plot the results!

import Plots
 zs = [5,10,15,20,25,30,40,50,100,500,1000,5000]u"cm"
 cg = Plots.cgrad(:copper,rev=true);
-Plots.plot(out.T[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Temperature", title="", leg=false, dpi=150)
Example block output

CryoGridLite can also be embedded into integrators from OrdinaryDiffEq.jl via the NLCGLite nonlinear solver interface. Note that these sovers generally will not be faster (in execution time) but may be more stable in some cases. Adaptive timestepping can be employed by removing the adaptive=false argument.

using OrdinaryDiffEq
-sol2 = @time solve(prob, ImplicitEuler(nlsolve=NLCGLite()), adaptive=false, dt=24*3600.0, saveat=24*3600);
781.402326 seconds (1.31 G allocations: 1.366 TiB, 7.14% gc time)

This page was generated using Literate.jl.

+Plots.plot(out.T[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Temperature", title="", leg=false, dpi=150)Example block output

CryoGridLite can also be embedded into integrators from OrdinaryDiffEq.jl via the NLCGLite nonlinear solver interface. Note that these sovers generally will not be faster (in execution time) but may be more stable in some cases. Adaptive timestepping can be employed by removing the adaptive=false argument.

using OrdinaryDiffEq
+sol2 = @time solve(prob, ImplicitEuler(nlsolve=NLCGLite()), adaptive=false, dt=24*3600.0, saveat=24*3600);
792.219430 seconds (1.31 G allocations: 1.366 TiB, 6.97% gc time)

This page was generated using Literate.jl.

diff --git a/dev/examples/heat_freeW_samoylov/1a1605c1.svg b/dev/examples/heat_freeW_samoylov/37c102a7.svg similarity index 98% rename from dev/examples/heat_freeW_samoylov/1a1605c1.svg rename to dev/examples/heat_freeW_samoylov/37c102a7.svg index e02670e4..548b84d3 100644 --- a/dev/examples/heat_freeW_samoylov/1a1605c1.svg +++ b/dev/examples/heat_freeW_samoylov/37c102a7.svg @@ -1,51 +1,51 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/examples/heat_freeW_samoylov/index.html b/dev/examples/heat_freeW_samoylov/index.html index e5492330..f3600b0c 100644 --- a/dev/examples/heat_freeW_samoylov/index.html +++ b/dev/examples/heat_freeW_samoylov/index.html @@ -15,4 +15,4 @@

Now we plot the reuslts!

import Plots
 zs = [1,10,20,30,50,100,200,500,1000]u"cm"
 cg = Plots.cgrad(:copper,rev=true);
-Plots.plot(out.T[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Temperature", leg=false, size=(800,500), dpi=150)
Example block output

This page was generated using Literate.jl.

+Plots.plot(out.T[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Temperature", leg=false, size=(800,500), dpi=150)Example block output

This page was generated using Literate.jl.

diff --git a/dev/examples/heat_freeW_seb_snow_bucketW_samoylov/index.html b/dev/examples/heat_freeW_seb_snow_bucketW_samoylov/index.html index 77b9213d..a777ad05 100644 --- a/dev/examples/heat_freeW_seb_snow_bucketW_samoylov/index.html +++ b/dev/examples/heat_freeW_seb_snow_bucketW_samoylov/index.html @@ -54,4 +54,4 @@ out = CryoGridOutput(integrator.sol)

Plot it!

import Plots
 zs = [1,3,5,7,10,15,20,25,30,40,50,100,150,200,500,1000]u"cm"
 cg = Plots.cgrad(:copper,rev=true);
-Plots.plot(ustrip.(out.T[Z(Near(zs))]), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Temperature", leg=false, size=(800,500), dpi=150)

Saturation:

Plots.plot(ustrip.(out.sat[Z(Near(zs))]), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Soil saturation", leg=false, size=(800,500), dpi=150)

Runoff

Plots.plot(ustrip.(out.top.runoff), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Total runoff", leg=false, size=(800,500), dpi=150)

Evapotranspiration

Plots.plot(ustrip.(out.top.ET), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Total ET", leg=false, size=(800,500), dpi=150)

Snow depth:

Plots.plot(ustrip.(out.snowpack.dsn), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Snow depth", leg=false, size=(800,500), dpi=150)

Integrated ground heat flux:

Plots.plot(ustrip.(cumsum(out.top.Qg, dims=2)), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Integrated ground heat flux", leg=false, size=(800,500), dpi=150)

Integratoed ground latent heat flux:

Plots.plot(ustrip.(cumsum(out.top.Qe, dims=2)), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Integrated ground heat flux", leg=false, size=(800,500), dpi=150)

This page was generated using Literate.jl.

+Plots.plot(ustrip.(out.T[Z(Near(zs))]), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Temperature", leg=false, size=(800,500), dpi=150)

Saturation:

Plots.plot(ustrip.(out.sat[Z(Near(zs))]), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Soil saturation", leg=false, size=(800,500), dpi=150)

Runoff

Plots.plot(ustrip.(out.top.runoff), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Total runoff", leg=false, size=(800,500), dpi=150)

Evapotranspiration

Plots.plot(ustrip.(out.top.ET), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Total ET", leg=false, size=(800,500), dpi=150)

Snow depth:

Plots.plot(ustrip.(out.snowpack.dsn), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Snow depth", leg=false, size=(800,500), dpi=150)

Integrated ground heat flux:

Plots.plot(ustrip.(cumsum(out.top.Qg, dims=2)), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Integrated ground heat flux", leg=false, size=(800,500), dpi=150)

Integratoed ground latent heat flux:

Plots.plot(ustrip.(cumsum(out.top.Qe, dims=2)), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Integrated ground heat flux", leg=false, size=(800,500), dpi=150)

This page was generated using Literate.jl.

diff --git a/dev/examples/heat_freeW_snow_samoylov/017d7dd2.svg b/dev/examples/heat_freeW_snow_samoylov/017d7dd2.svg new file mode 100644 index 00000000..a4381ba6 --- /dev/null +++ b/dev/examples/heat_freeW_snow_samoylov/017d7dd2.svg @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/examples/heat_freeW_snow_samoylov/3cd414b0.svg b/dev/examples/heat_freeW_snow_samoylov/3cd414b0.svg deleted file mode 100644 index d42a8daf..00000000 --- a/dev/examples/heat_freeW_snow_samoylov/3cd414b0.svg +++ /dev/null @@ -1,2715 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/examples/heat_freeW_snow_samoylov/a6dd858f.svg b/dev/examples/heat_freeW_snow_samoylov/a6dd858f.svg new file mode 100644 index 00000000..cfa4d6cc --- /dev/null +++ b/dev/examples/heat_freeW_snow_samoylov/a6dd858f.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/examples/heat_freeW_snow_samoylov/b270c5dd.svg b/dev/examples/heat_freeW_snow_samoylov/b270c5dd.svg deleted file mode 100644 index a61ae2a0..00000000 --- a/dev/examples/heat_freeW_snow_samoylov/b270c5dd.svg +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/examples/heat_freeW_snow_samoylov/c7389209.svg b/dev/examples/heat_freeW_snow_samoylov/c7389209.svg new file mode 100644 index 00000000..3eae46f6 --- /dev/null +++ b/dev/examples/heat_freeW_snow_samoylov/c7389209.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/examples/heat_freeW_snow_samoylov/db387a0e.svg b/dev/examples/heat_freeW_snow_samoylov/db387a0e.svg deleted file mode 100644 index f6d66eac..00000000 --- a/dev/examples/heat_freeW_snow_samoylov/db387a0e.svg +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/examples/heat_freeW_snow_samoylov/f02f2964.svg b/dev/examples/heat_freeW_snow_samoylov/f02f2964.svg deleted file mode 100644 index a9c05bba..00000000 --- a/dev/examples/heat_freeW_snow_samoylov/f02f2964.svg +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/examples/heat_freeW_snow_samoylov/fdbddfcb.svg b/dev/examples/heat_freeW_snow_samoylov/fdbddfcb.svg new file mode 100644 index 00000000..8a1973d5 --- /dev/null +++ b/dev/examples/heat_freeW_snow_samoylov/fdbddfcb.svg @@ -0,0 +1,2634 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/examples/heat_freeW_snow_samoylov/index.html b/dev/examples/heat_freeW_snow_samoylov/index.html index a784df57..6010f0e6 100644 --- a/dev/examples/heat_freeW_snow_samoylov/index.html +++ b/dev/examples/heat_freeW_snow_samoylov/index.html @@ -35,25 +35,25 @@ prob = CryoGridProblem(tile, u0, tspan, saveat=3*3600.0, savevars=(:T, :top => (:T_ub), :snowpack => (:dsn,)))
CryoGridProblem with uType ComponentArrays.ComponentVector{Float64, Vector{Float64}, Tuple{ComponentArrays.Axis{(top = ViewAxis(1:1, Axis(runoff = 1:1,)), snowpack = ViewAxis(2:3, Axis(swe = 1:1, Δz = 2:2)), sat = 4:2:440, H = 5:2:441)}}} and tType Float64. In-place: true
 timespan: (6.3453024e10, 6.35161824e10)
 u0: ComponentVector{Float64}(top = (runoff = [0.0]), snowpack = (swe = [0.0], Δz = [0.0]), sat = [0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0  …  1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0], H = [0.0, -1.995e6, -1.995e6, -1.945e6, -1.945e6, -1.945e6, -1.945e6, -1.945e6, -1.945e6, -2.00125e6  …  -1.773e7, -1.5628666666666668e7, -1.1426000000000002e7, -7.223333333333333e6, -3.0206666666666674e6, 1.01796e8, 1.0747066666666667e8, 1.1314533333333333e8, 1.1882e8, 1.2449466666666666e8])

solve full tspan with forward Euler and initial timestep of 5 minutes

@info "Running model ..."
-sol = @time solve(prob, CGEuler(), dt=300.0);
-out = CryoGridOutput(sol)
CryoGridOutput with 5541 time steps (2010-09-30T00:00:00 to 2012-09-30T00:00:00) and 8 variables:
-    sat => DimArray of Float64 with dimensions (219, 5541)
-    H => DimArray of Quantity{Float64, 𝐌 𝐋^-1 𝐓^-2, Unitful.FreeUnits{(J, m^-3), 𝐌 𝐋^-1 𝐓^-2, nothing}} with dimensions (219, 5541)
-    T => DimArray of Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}} with dimensions (219, 5541)
+sol = @time solve(prob, Euler(), dt=300.0);
+out = CryoGridOutput(sol)
CryoGridOutput with 5849 time steps (2010-09-30T00:00:00 to 2012-09-30T00:00:00) and 8 variables:
+    sat => DimArray of Float64 with dimensions (219, 5849)
+    H => DimArray of Quantity{Float64, 𝐌 𝐋^-1 𝐓^-2, Unitful.FreeUnits{(J, m^-3), 𝐌 𝐋^-1 𝐓^-2, nothing}} with dimensions (219, 5849)
+    T => DimArray of Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}} with dimensions (219, 5849)
     top => 
-        runoff => DimArray of Quantity{Float64, 𝐋^3, Unitful.FreeUnits{(m^3,), 𝐋^3, nothing}} with dimensions (1, 5541)
-        T_ub => DimArray of Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, nothing}} with dimensions (1, 5541)
+        runoff => DimArray of Quantity{Float64, 𝐋^3, Unitful.FreeUnits{(m^3,), 𝐋^3, nothing}} with dimensions (1, 5849)
+        T_ub => DimArray of Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, nothing}} with dimensions (1, 5849)
     snowpack => 
-        swe => DimArray of Quantity{Float64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}} with dimensions (1, 5541)
-        Δz => DimArray of Quantity{Float64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}} with dimensions (1, 5541)
-        dsn => DimArray of Quantity{Float64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}} with dimensions (1, 5541)
+        swe => DimArray of Quantity{Float64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}} with dimensions (1, 5849)
+        Δz => DimArray of Quantity{Float64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}} with dimensions (1, 5849)
+        dsn => DimArray of Quantity{Float64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}} with dimensions (1, 5849)
 

Plot it!

using Plots: plot, plot!, heatmap, cgrad, Measures
 zs = [1,10,20,30,50,100,200,500]u"cm"
 cg = cgrad(:copper,rev=true);
 plot(ustrip(out.T[Z(Near(zs))]), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Temperature (°C)", leg=false, dpi=150)
 plot!(ustrip(out.T[1,:]), color=:darkgray, ylabel="Temperature (°C)", leg=false, dpi=150)
-plt1 = plot!(ustrip.(out.top.T_ub), color=:skyblue, linestyle=:dash, alpha=0.5, leg=false, dpi=150)
Example block output

Plot snow water equivalent and depth:

plot(ustrip(out.snowpack.swe), ylabel="Depth (m)", label="Snow water equivalent", dpi=150)
+plt1 = plot!(ustrip.(out.top.T_ub), color=:skyblue, linestyle=:dash, alpha=0.5, leg=false, dpi=150)
Example block output

Plot snow water equivalent and depth:

plot(ustrip(out.snowpack.swe), ylabel="Depth (m)", label="Snow water equivalent", dpi=150)
 plt2 = plot!(ustrip.(out.snowpack.dsn), label="Snow depth", ylabel="Depth (m)", legendtitle=nothing, dpi=150)
-plot(plt1, plt2, size=(1600,700), margins=5*Measures.mm)
Example block output

Temperature heatmap:

T_sub = out.T[Z(Between(0.0u"m",10.0u"m"))]
-heatmap(T_sub, yflip=true, size=(1200,600), dpi=150)
Example block output

Thaw depth:

td = Diagnostics.thawdepth(out.T[Z(Where(>=(0.0u"m")))])
-plot(td, yflip=true, ylabel="Thaw depth (m)", size=(1200,600))
Example block output

This page was generated using Literate.jl.

+plot(plt1, plt2, size=(1600,700), margins=5*Measures.mm)Example block output

Temperature heatmap:

T_sub = out.T[Z(Between(0.0u"m",10.0u"m"))]
+heatmap(T_sub, yflip=true, size=(1200,600), dpi=150)
Example block output

Thaw depth:

td = Diagnostics.thawdepth(out.T[Z(Where(>=(0.0u"m")))])
+plot(td, yflip=true, ylabel="Thaw depth (m)", size=(1200,600))
Example block output

This page was generated using Literate.jl.

diff --git a/dev/examples/heat_sfcc_constantbc/a3fd0515.svg b/dev/examples/heat_sfcc_constantbc/43a6e40c.svg similarity index 85% rename from dev/examples/heat_sfcc_constantbc/a3fd0515.svg rename to dev/examples/heat_sfcc_constantbc/43a6e40c.svg index c4479859..2ff6d1e3 100644 --- a/dev/examples/heat_sfcc_constantbc/a3fd0515.svg +++ b/dev/examples/heat_sfcc_constantbc/43a6e40c.svg @@ -1,48 +1,48 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/examples/heat_sfcc_constantbc/f1e41f59.svg b/dev/examples/heat_sfcc_constantbc/877e20f0.svg similarity index 98% rename from dev/examples/heat_sfcc_constantbc/f1e41f59.svg rename to dev/examples/heat_sfcc_constantbc/877e20f0.svg index 8c617779..e78ed174 100644 --- a/dev/examples/heat_sfcc_constantbc/f1e41f59.svg +++ b/dev/examples/heat_sfcc_constantbc/877e20f0.svg @@ -1,49 +1,49 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/examples/heat_sfcc_constantbc/f6ec6778.svg b/dev/examples/heat_sfcc_constantbc/8ae9ed22.svg similarity index 91% rename from dev/examples/heat_sfcc_constantbc/f6ec6778.svg rename to dev/examples/heat_sfcc_constantbc/8ae9ed22.svg index a41174ae..77de611e 100644 --- a/dev/examples/heat_sfcc_constantbc/f6ec6778.svg +++ b/dev/examples/heat_sfcc_constantbc/8ae9ed22.svg @@ -1,41 +1,41 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/examples/heat_sfcc_constantbc/index.html b/dev/examples/heat_sfcc_constantbc/index.html index 3095eed5..857cad26 100644 --- a/dev/examples/heat_sfcc_constantbc/index.html +++ b/dev/examples/heat_sfcc_constantbc/index.html @@ -8,7 +8,7 @@ );

Here we specify the soil freezing characteristic curve (SFCC) formulation of Painter and Karra (2014). The van Genuchten parameters α=0.1 and n=1.8 correspond to a silty soil.

sfcc = PainterKarra(swrc=VanGenuchten(α=1.0, n=2.0));
 
 import Plots
-Plots.plot(-2.0u"°C":0.01u"K":0.0u"°C", sfcc)
Example block output

Enthalpy form of the heat transfer operator (i.e. prognostic :H). In this case, this is equivalent to the shorthand SoilHeatTile(:H, ...). However, it's worth demonstrating how the operator can be explicitly specified.

heatop = Heat.Diffusion1D(:H)
+Plots.plot(-2.0u"°C":0.01u"K":0.0u"°C", sfcc)
Example block output

Enthalpy form of the heat transfer operator (i.e. prognostic :H). In this case, this is equivalent to the shorthand SoilHeatTile(:H, ...). However, it's worth demonstrating how the operator can be explicitly specified.

heatop = Heat.Diffusion1D(:H)
 initT = initializer(:T, tempprofile)
 tile = CryoGrid.Presets.SoilHeatTile(
     heatop,
@@ -28,4 +28,4 @@
 

Compute total energy balance error.

Htot = Diagnostics.integrate(out.H, grid)
 mass_balance_error = Htot[end] - Htot[1]
0.0006561279296875 J

Plot it!

import Plots
 zs = [1,45,95,195,495,795,995]u"cm"
-Diagnostics.plot_at_depths(:T, out, zs, ylabel="Temperature", leg=false, size=(800,500), dpi=150)
Example block output

Plot the energy balance error over time.

Plots.plot(uconvert.(u"MJ", Htot .- Htot[1]), title="", ylabel="Energy balance error")
Example block output

This page was generated using Literate.jl.

+Diagnostics.plot_at_depths(:T, out, zs, ylabel="Temperature", leg=false, size=(800,500), dpi=150)Example block output

Plot the energy balance error over time.

Plots.plot(uconvert.(u"MJ", Htot .- Htot[1]), title="", ylabel="Energy balance error")
Example block output

This page was generated using Literate.jl.

diff --git a/dev/examples/heat_sfcc_salt_constantbc/index.html b/dev/examples/heat_sfcc_salt_constantbc/index.html index bfe11773..93c43de5 100644 --- a/dev/examples/heat_sfcc_salt_constantbc/index.html +++ b/dev/examples/heat_sfcc_salt_constantbc/index.html @@ -35,4 +35,4 @@ p2 = Plots.plot(out.T[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Temperature", leg=false, size=(800,500), dpi=150) p3 = Plots.plot(out.c[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Salt concentration", leg=false, size=(800,500), dpi=150) p4 = Plots.plot(out.θw[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Liquid water content", leg=false, size=(800,500), dpi=150) -Plots.plot([p1,p2,p3,p4], layout=Plots.@layout([p1 p2; p3 p4]))

This page was generated using Literate.jl.

+Plots.plot([p1,p2,p3,p4], layout=Plots.@layout([p1 p2; p3 p4]))

This page was generated using Literate.jl.

diff --git a/dev/examples/heat_sfcc_samoylov/474a0118.svg b/dev/examples/heat_sfcc_samoylov/119587d3.svg similarity index 98% rename from dev/examples/heat_sfcc_samoylov/474a0118.svg rename to dev/examples/heat_sfcc_samoylov/119587d3.svg index 57507f9f..58cc6a9c 100644 --- a/dev/examples/heat_sfcc_samoylov/474a0118.svg +++ b/dev/examples/heat_sfcc_samoylov/119587d3.svg @@ -1,50 +1,50 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/examples/heat_sfcc_samoylov/index.html b/dev/examples/heat_sfcc_samoylov/index.html index bb3bfee5..931a884e 100644 --- a/dev/examples/heat_sfcc_samoylov/index.html +++ b/dev/examples/heat_sfcc_samoylov/index.html @@ -15,4 +15,4 @@ T => DimArray of Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, Unitful.Affine{-5463//20}}} with dimensions (218, 2920)

Finally, plot the resulting temperatures.

import Plots
 zs = [5,10,15,20,25,30,40,50,100,500]u"cm"
-Diagnostics.plot_at_depths(:T, out, zs, ylabel="Temperature (°C)")
Example block output

This page was generated using Literate.jl.

+Diagnostics.plot_at_depths(:T, out, zs, ylabel="Temperature (°C)")Example block output

This page was generated using Literate.jl.

diff --git a/dev/examples/heat_simple_autodiff_grad/index.html b/dev/examples/heat_simple_autodiff_grad/index.html index e3810faa..2e9f85a6 100644 --- a/dev/examples/heat_simple_autodiff_grad/index.html +++ b/dev/examples/heat_simple_autodiff_grad/index.html @@ -14,7 +14,7 @@ grid=grid ) tspan = (DateTime(2010,10,30),DateTime(2011,10,30)) -u0, du0 = @time initialcondition!(tile, tspan);
 16.715084 seconds (19.12 M allocations: 1.449 GiB, 1.30% gc time, 99.98% compilation time)

Collect model parameters

p = CryoGrid.parameters(tile)
CryoGridParams{Float64} with 2 parameters
+u0, du0 = @time initialcondition!(tile, tspan);
 17.453621 seconds (19.70 M allocations: 1.467 GiB, 0.90% gc time, 99.97% compilation time)

Collect model parameters

p = CryoGrid.parameters(tile)
CryoGridParams{Float64} with 2 parameters
 Parameters:
 ┌───────────┬───────────┬─────────┬────────┬───────┬────────┐
 │ component │ fieldname │     val │  layer │   idx │   name │
@@ -34,4 +34,4 @@
     local out = CryoGridOutput(sol)
     return mean(ustrip.(out.T[:,end]))
 end
loss (generic function with 1 method)

ForwardDiff provides tools for forward-mode automatic differentiation.

using ForwardDiff
-pvec = vec(p)

Compute gradient with forward diff:

grad = @time ForwardDiff.gradient(loss, pvec)

This page was generated using Literate.jl.

+pvec = vec(p)

Compute gradient with forward diff:

grad = @time ForwardDiff.gradient(loss, pvec)

This page was generated using Literate.jl.

diff --git a/dev/index.html b/dev/index.html index c2b595cc..80e53aab 100644 --- a/dev/index.html +++ b/dev/index.html @@ -1,2 +1,2 @@ -Home · CryoGrid.jl

CryoGrid.jl

CryoGrid.jl is a Julia implementation of the CryoGrid land surface model using DifferentialEquations.jl and the SciML package ecosystem. Its primary goal is to provide a fast, flexible, and feature rich framework for modeling permafrost in Julia while simultaneously laying the groundwork for rapid prototyping of data-driven parameter estimation, uncertainty quantification, and causal analysis of complex Arctic land surface processes.

This package is part of the broader research project: Quantifying and explaining uncertainty in permafrost modeling under a warming climate

+Home · CryoGrid.jl

CryoGrid.jl

CryoGrid.jl is a Julia implementation of the CryoGrid land surface model using DifferentialEquations.jl and the SciML package ecosystem. Its primary goal is to provide a fast, flexible, and feature rich framework for modeling permafrost in Julia while simultaneously laying the groundwork for rapid prototyping of data-driven parameter estimation, uncertainty quantification, and causal analysis of complex Arctic land surface processes.

This package is part of the broader research project: Quantifying and explaining uncertainty in permafrost modeling under a warming climate

diff --git a/dev/installation/index.html b/dev/installation/index.html index 480a0c7d..0e619b8d 100644 --- a/dev/installation/index.html +++ b/dev/installation/index.html @@ -1,3 +1,3 @@ Installation · CryoGrid.jl

Installation

CryoGrid.jl can be installed via the Julia package manager:

add https://gitlab.awi.de/sparcs/cryogrid/cryogridjulia

or equivalently in code/REPL:

import Pkg
-Pkg.add(["https://gitlab.awi.de/sparcs/cryogrid/cryogridjulia"])

Be aware that CryoGrid.jl is a relatively large package with quite a few dependencies, so installation into a blank Julia environment could take several minutes.

It is recommended that you work with CryoGrid.jl as a Julia package rather than cloning the repository and hacking on it directly. This will allow for more rapid development and minimize latency from precompile time. It is also recommended to create a dedicated Julia environment in your workspace to better manage package dependencies. This can be accomplished by running:

activate .

in your working directory, or by starting Julia with the --project=. option. Then, you can proceed to install CryoGrid.jl into the environment via the commands above.

You can load CryoGrid.jl in your Julia REPL or editor by running:

using CryoGrid

or similarly:

import CryoGrid

The latter option will bring only the CryoGrid module name into scope rather than all of its exported components.

+Pkg.add(["https://gitlab.awi.de/sparcs/cryogrid/cryogridjulia"])

Be aware that CryoGrid.jl is a relatively large package with quite a few dependencies, so installation into a blank Julia environment could take several minutes.

It is recommended that you work with CryoGrid.jl as a Julia package rather than cloning the repository and hacking on it directly. This will allow for more rapid development and minimize latency from precompile time. It is also recommended to create a dedicated Julia environment in your workspace to better manage package dependencies. This can be accomplished by running:

activate .

in your working directory, or by starting Julia with the --project=. option. Then, you can proceed to install CryoGrid.jl into the environment via the commands above.

You can load CryoGrid.jl in your Julia REPL or editor by running:

using CryoGrid

or similarly:

import CryoGrid

The latter option will bring only the CryoGrid module name into scope rather than all of its exported components.

diff --git a/dev/manual/architecture/index.html b/dev/manual/architecture/index.html index 96f05691..ddc7a023 100644 --- a/dev/manual/architecture/index.html +++ b/dev/manual/architecture/index.html @@ -7,4 +7,4 @@ state = Diagnostics.build_dummy_state(grid, soil) @which CryoGrid.computediagnostic!(soil, state)

Output:

computediagnostic!(layer::Layer, state)
-     @ CryoGrid ~/workspace/sparc-local/repos/CryoGrid/CryoGrid.jl/src/methods.jl:55

State variables

In order to facilitate modularity and ease-of-use, CryoGrid.jl provides an automated system for initializing and configuring state variables for any given model configuration. Note that there is an important distinction between two types of model state: prognostic and diagnostic.

Prognostic(@ref) state variables fully define the state of the system at any given time t. They form what is typically called the "phase space" or "state space" in the mathematics and engineering literature. In order to be compatible with standard ODE solvers (e.g. like those in OrdinaryDiffEq), CryoGrid.jl automatically assembles prognostic state variables into a single array u (and its corresponding time derivative du) which is returned when initializing a Tile with the initialcondition! method. Note again that this array should always fully define the state of the system.

Diagnostic(@ref) state variables act as caches for intermediate and derived quantities defined by the model. They also may, in some cases, provide a means of coupling between different processes (e.g. the heat and water flux variables jH and jw might be updated by more than one Process). For any model configuration, all diagnostic variables should be fully updated (and thus consistent) with the given prognostic state after invoking computediagnostic!, interact!, and computefluxes!.

When a Tile is constructed, all variables defined by each layer in the Stratigraphy are collected and then intiailized in StateVars according to the given DiscretizationStrategy.

References

[1] Bass L, Clements P, Kazman R. Software architecture in practice. Addison-Wesley Professional; 2003.

[2] Westermann S, Ingeman-Nielsen T, Scheer J, Aalstad K, Aga J, Chaudhary N, Etzelmüller B, Filhol S, Kääb A, Renette C, Schmidt LS. The CryoGrid community model (version 1.0)–a multi-physics toolbox for climate-driven simulations in the terrestrial cryosphere. Geoscientific Model Development. 2023 May 15;16(9):2607-47.

+ @ CryoGrid ~/workspace/sparc-local/repos/CryoGrid/CryoGrid.jl/src/methods.jl:55

State variables

In order to facilitate modularity and ease-of-use, CryoGrid.jl provides an automated system for initializing and configuring state variables for any given model configuration. Note that there is an important distinction between two types of model state: prognostic and diagnostic.

Prognostic(@ref) state variables fully define the state of the system at any given time t. They form what is typically called the "phase space" or "state space" in the mathematics and engineering literature. In order to be compatible with standard ODE solvers (e.g. like those in OrdinaryDiffEq), CryoGrid.jl automatically assembles prognostic state variables into a single array u (and its corresponding time derivative du) which is returned when initializing a Tile with the initialcondition! method. Note again that this array should always fully define the state of the system.

Diagnostic(@ref) state variables act as caches for intermediate and derived quantities defined by the model. They also may, in some cases, provide a means of coupling between different processes (e.g. the heat and water flux variables jH and jw might be updated by more than one Process). For any model configuration, all diagnostic variables should be fully updated (and thus consistent) with the given prognostic state after invoking computediagnostic!, interact!, and computefluxes!.

When a Tile is constructed, all variables defined by each layer in the Stratigraphy are collected and then intiailized in StateVars according to the given DiscretizationStrategy.

References

[1] Bass L, Clements P, Kazman R. Software architecture in practice. Addison-Wesley Professional; 2003.

[2] Westermann S, Ingeman-Nielsen T, Scheer J, Aalstad K, Aga J, Chaudhary N, Etzelmüller B, Filhol S, Kääb A, Renette C, Schmidt LS. The CryoGrid community model (version 1.0)–a multi-physics toolbox for climate-driven simulations in the terrestrial cryosphere. Geoscientific Model Development. 2023 May 15;16(9):2607-47.

diff --git a/dev/manual/coupling/index.html b/dev/manual/coupling/index.html index f5719360..9614320d 100644 --- a/dev/manual/coupling/index.html +++ b/dev/manual/coupling/index.html @@ -1,2 +1,2 @@ -Coupling layers and processes · CryoGrid.jl +Coupling layers and processes · CryoGrid.jl diff --git a/dev/manual/overview/index.html b/dev/manual/overview/index.html index 4d2a3a0e..763912e2 100644 --- a/dev/manual/overview/index.html +++ b/dev/manual/overview/index.html @@ -31,4 +31,4 @@ # compute internal fluxes and non-linear diffusion assuming boundary fluxes have been set nonlineardiffusion!(state.dH, state.jH, state.T, ΔT, state.k, Δk) return nothing -end
Warning

Prognostic state variables like H in the example above should not be directly modified in the model code. They should only be modified by the calling solver/integrator. This is especially important when using higher order or implicit integrators as unexpected changes to prognostic state may destroy the accuracy of their internal interpolant. For modeling discontinuities, use Events instead.

Note that state is (typically) of type LayerState with properties corresponding to the state variables declared by the variables function for Soil and HeatBalance. Additionally, output arrays for the time derivatives are provided (here dH), as well as the current timestep, layer boundary depths, and variable grids (accessible via state.t, and state.grid respectively). Note that state will also contain other variables declared on this Soil layer by other SubSurfaceProcesses, allowing for implicit coupling between processes where appropriate.

+end
Warning

Prognostic state variables like H in the example above should not be directly modified in the model code. They should only be modified by the calling solver/integrator. This is especially important when using higher order or implicit integrators as unexpected changes to prognostic state may destroy the accuracy of their internal interpolant. For modeling discontinuities, use Events instead.

Note that state is (typically) of type LayerState with properties corresponding to the state variables declared by the variables function for Soil and HeatBalance. Additionally, output arrays for the time derivatives are provided (here dH), as well as the current timestep, layer boundary depths, and variable grids (accessible via state.t, and state.grid respectively). Note that state will also contain other variables declared on this Soil layer by other SubSurfaceProcesses, allowing for implicit coupling between processes where appropriate.

diff --git a/dev/quickstart/index.html b/dev/quickstart/index.html index 76ea910f..1afddca4 100644 --- a/dev/quickstart/index.html +++ b/dev/quickstart/index.html @@ -30,4 +30,4 @@ plot(out2.T[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel="Temperature", leg=false)

Note that SoilHeatTile uses energy as the state variable by default. To use temperature as the state variable instead:

# :T is the variable name for temperature, :H represents enthalpy/energy.
 # This is used in the specification of the HeatBalance process type.
 # While this will work with any freeze curve, here we use Westermann (2011) as an example.
-model = CryoGrid.Presets.SoilHeatTile(:T, TemperatureBC(forcings.Tair), soilprofile, freezecurve=SFCC(Westermann()))
+model = CryoGrid.Presets.SoilHeatTile(:T, TemperatureBC(forcings.Tair), soilprofile, freezecurve=SFCC(Westermann())) diff --git a/dev/search_index.js b/dev/search_index.js index 97f059cd..79ccd137 100644 --- a/dev/search_index.js +++ b/dev/search_index.js @@ -1,3 +1,3 @@ var documenterSearchIndex = {"docs": -[{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"EditURL = \"../../../examples/heat_sfcc_constantbc.jl\"","category":"page"},{"location":"examples/heat_sfcc_constantbc/#example2","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"","category":"section"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"In this example, we use the preset SoilHeatTile to construct a Tile consisting of a soil column with heat conduction and zero-flux boundary conditions. This is a useful test case for checking energy conservation since we can guarantee that no energy is being added or removed at the boundaries.","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"using CryoGrid","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"Select default grid and initial temperature profile.","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"grid = CryoGrid.Presets.DefaultGrid_10cm\ntempprofile = TemperatureProfile(\n 0.0u\"m\" => -20.0u\"°C\",\n 1000.0u\"m\" => 10.0u\"°C\",\n);\nnothing #hide","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"Here we use a simple single layer model with default soil parameters (50% porosity, no organic).","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"soilprofile = SoilProfile(\n 0.0u\"m\" => MineralOrganic()\n);\nnothing #hide","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"Here we specify the soil freezing characteristic curve (SFCC) formulation of Painter and Karra (2014). The van Genuchten parameters α=0.1 and n=1.8 correspond to a silty soil.","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"sfcc = PainterKarra(swrc=VanGenuchten(α=1.0, n=2.0));\n\nimport Plots\nPlots.plot(-2.0u\"°C\":0.01u\"K\":0.0u\"°C\", sfcc)","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"Enthalpy form of the heat transfer operator (i.e. prognostic :H). In this case, this is equivalent to the shorthand SoilHeatTile(:H, ...). However, it's worth demonstrating how the operator can be explicitly specified.","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"heatop = Heat.Diffusion1D(:H)\ninitT = initializer(:T, tempprofile)\ntile = CryoGrid.Presets.SoilHeatTile(\n heatop,\n # 10 W/m^2 in and out, i.e. net zero flux\n ConstantBC(HeatBalance, CryoGrid.Neumann, 10.0u\"W/m^2\"),\n ConstantBC(HeatBalance, CryoGrid.Neumann, 10.0u\"W/m^2\"),\n soilprofile,\n initT;\n grid,\n freezecurve=sfcc,\n);\nnothing #hide","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"Define the simulation time span.","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"tspan = (DateTime(2010,1,1),DateTime(2010,12,31))\nu0, du0 = initialcondition!(tile, tspan);\nnothing #hide","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"Construct and solve the CryoGridProblem using the built-in forward Euler integrator.","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"prob = CryoGridProblem(tile, u0, tspan, saveat=3600.0, savevars=(:T,:H))\nsol = @time solve(prob, dtmax=900.0);\nout = CryoGridOutput(sol)","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"Compute total energy balance error.","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"Htot = Diagnostics.integrate(out.H, grid)\nmass_balance_error = Htot[end] - Htot[1]","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"Plot it!","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"import Plots\nzs = [1,45,95,195,495,795,995]u\"cm\"\nDiagnostics.plot_at_depths(:T, out, zs, ylabel=\"Temperature\", leg=false, size=(800,500), dpi=150)","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"Plot the energy balance error over time.","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"Plots.plot(uconvert.(u\"MJ\", Htot .- Htot[1]), title=\"\", ylabel=\"Energy balance error\")","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"This page was generated using Literate.jl.","category":"page"},{"location":"examples/heat_sfcc_salt_constantbc/","page":"Coupled heat and salt diffusion on salty soil column","title":"Coupled heat and salt diffusion on salty soil column","text":"EditURL = \"../../../examples/heat_sfcc_salt_constantbc.jl\"","category":"page"},{"location":"examples/heat_sfcc_salt_constantbc/#example9","page":"Coupled heat and salt diffusion on salty soil column","title":"Coupled heat and salt diffusion on salty soil column","text":"","category":"section"},{"location":"examples/heat_sfcc_salt_constantbc/","page":"Coupled heat and salt diffusion on salty soil column","title":"Coupled heat and salt diffusion on salty soil column","text":"In this example, we construct a Tile from a Stratigraphy of three \"salty soil\" layers which include coupled salt/heat diffusion. Note that this is currently only supported for the temperature-based form of the heat equation.","category":"page"},{"location":"examples/heat_sfcc_salt_constantbc/","page":"Coupled heat and salt diffusion on salty soil column","title":"Coupled heat and salt diffusion on salty soil column","text":"using CryoGrid\ninitT = initializer(:T, -2.0)\ninitsalt = initializer(:c, 0.0)\ninitpor = SedimentCompactionInitializer(porosityZero=0.4)\nsfcc = DallAmicoSalt(swrc=VanGenuchten(α=4.06, n=2.03))\nupperbc = SaltHeatBC(SaltGradient(benthicSalt=900.0, surfaceState=0), ConstantTemperature(0.0))\nstrat = @Stratigraphy(\n 0.0u\"m\" => Top(upperbc),\n 0.0u\"m\" => SalineGround(heat=HeatBalance(:T, freezecurve=sfcc), salt=SaltMassBalance()),\n 1000.0u\"m\" => Bottom(GeothermalHeatFlux(0.053u\"W/m^2\"))\n);\nmodelgrid = CryoGrid.Presets.DefaultGrid_10cm\ntile = Tile(strat, modelgrid, initT, initsalt, initpor)\ntspan = (DateTime(1990,1,1),DateTime(2000,12,31))\nu0, du0 = initialcondition!(tile, tspan)\nprob = CryoGridProblem(tile, u0, tspan, saveat=24*3600.0, savevars=(:T,:θw,:k,:dₛ))\n@info \"Running model\"\nintegrator = init(prob, CGEuler(), dt=60.0);\n@time step!(integrator, 24*3600)\n# Run to end of time span.\n@time for i in integrator end\nout = CryoGridOutput(integrator.sol)","category":"page"},{"location":"examples/heat_sfcc_salt_constantbc/","page":"Coupled heat and salt diffusion on salty soil column","title":"Coupled heat and salt diffusion on salty soil column","text":"Plot it!","category":"page"},{"location":"examples/heat_sfcc_salt_constantbc/","page":"Coupled heat and salt diffusion on salty soil column","title":"Coupled heat and salt diffusion on salty soil column","text":"import Plots\nzs = [5,15,25,35,45,55,65,75]u\"cm\"\ncg = Plots.cgrad(:copper,rev=true);\ntotal_salt = out.c.*out.θw\np1 = Plots.plot(total_salt[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Salt concentration\", leg=false, size=(800,500), dpi=150)\np2 = Plots.plot(out.T[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Temperature\", leg=false, size=(800,500), dpi=150)\np3 = Plots.plot(out.c[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Salt concentration\", leg=false, size=(800,500), dpi=150)\np4 = Plots.plot(out.θw[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Liquid water content\", leg=false, size=(800,500), dpi=150)\nPlots.plot([p1,p2,p3,p4], layout=Plots.@layout([p1 p2; p3 p4]))","category":"page"},{"location":"examples/heat_sfcc_salt_constantbc/","page":"Coupled heat and salt diffusion on salty soil column","title":"Coupled heat and salt diffusion on salty soil column","text":"","category":"page"},{"location":"examples/heat_sfcc_salt_constantbc/","page":"Coupled heat and salt diffusion on salty soil column","title":"Coupled heat and salt diffusion on salty soil column","text":"This page was generated using Literate.jl.","category":"page"},{"location":"api/presets/#Presets-(@)","page":"Presets","title":"Presets (@)","text":"","category":"section"},{"location":"api/presets/","page":"Presets","title":"Presets","text":"Modules = [CryoGrid.Presets]\nPrivate = false\nOrder = [:type, :function, :macro]","category":"page"},{"location":"api/presets/#CryoGrid.Presets.SoilHeatTile-Union{Tuple{F}, Tuple{Any, BoundaryProcess, BoundaryProcess, CryoGrid.Numerics.Profile, Vararg{CryoGrid.Initializer, N} where N}} where F<:FreezeCurve","page":"Presets","title":"CryoGrid.Presets.SoilHeatTile","text":"SoilHeatTile([heatop=:H], upperbc::BoundaryProcess, soilprofile::Profile, init::CryoGrid.Initializer...; grid::Grid=DefaultGrid_10cm, freezecurve::F=FreeWater(), tile_kwargs...) where {F<:FreezeCurve}\n\nBuilds a simple one-layer soil/heat-conduction model with the given grid and configuration. Uses the \"free water\" freeze curve by default, but this can be changed via the freezecurve parameter. For example, to use the Dall'Amico freeze curve, set freezecurve=SFCC(DallAmico()).\n\n\n\n\n\n","category":"method"},{"location":"dev/debugging/#debugging","page":"Debugging","title":"Debugging","text":"","category":"section"},{"location":"dev/debugging/","page":"Debugging","title":"Debugging","text":"TODO","category":"page"},{"location":"api/physics/heat_conduction/#Heat-conduction","page":"Heat Conduction","title":"Heat conduction","text":"","category":"section"},{"location":"api/physics/heat_conduction/","page":"Heat Conduction","title":"Heat Conduction","text":"Modules = [Heat]\nPrivate = false\nOrder = [:type, :function, :macro]","category":"page"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.GeothermalHeatFlux","page":"Heat Conduction","title":"CryoGrid.Heat.GeothermalHeatFlux","text":"GeothermalHeatFlux{TQ} <: BoundaryProcess{HeatBalance}\n\nRepresents a simple, forced Neumann heat flux boundary condition for HeatBalance processes.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.GroundHeatFlux","page":"Heat Conduction","title":"CryoGrid.Heat.GroundHeatFlux","text":"GroundHeatFlux{TE,TQ} <: BoundaryProcess{HeatBalance}\n\nRepresents a simple, forced Neumann heat flux boundary condition for HeatBalance processes.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.HeatBalance","page":"Heat Conduction","title":"CryoGrid.Heat.HeatBalance","text":"HeatBalance{Tfc<:FreezeCurve,THeatOp<:HeatOperator,Tdt,Tprop} <: SubSurfaceProcess\n\nRepresents subsurface heat transfer processes. The formulation of heat transfer is governed by the HeatOperator, op. \n\n\n\n\n\n","category":"type"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.HeatBalanceImplicit","page":"Heat Conduction","title":"CryoGrid.Heat.HeatBalanceImplicit","text":"Type alias for the implicit enthalpy formulation of HeatBalance.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.StefanProblem","page":"Heat Conduction","title":"CryoGrid.Heat.StefanProblem","text":"StefanProblem{Tp<:StefanParameters,Tx,Tt}\n\nRepresents the simple two-phase Stefan problem defined on a semi-infinite slab. The one-phase Stefan problem can be computed by setting the parameters T_s = T_m.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.TemperatureBC","page":"Heat Conduction","title":"CryoGrid.Heat.TemperatureBC","text":"TemperatureBC{E,F} <: BoundaryProcess{HeatBalance}\n\nRepresents a simple, forced Dirichlet temperature boundary condition for HeatBalance processes.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.ThermalProperties","page":"Heat Conduction","title":"CryoGrid.Heat.ThermalProperties","text":"ThermalProperties\n\nMaterial thermal properties, e.g. conductivity and heat capacity. By default, this includes the thermal properties of water, ice, and air. This can be extended by passing additional properties into the constructor.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.TemperatureProfile-Tuple{Vararg{Pair{var\"#s207\", var\"#s206\"} where {var\"#s207\"<:Union{Param, Quantity{T, 𝐋, U} where {T, U<:(Unitful.FreeUnits{N, 𝐋, nothing} where N)}}, var\"#s206\"<:Union{Param, Quantity{T, 𝚯, U} where {T, U<:(Unitful.FreeUnits{N, 𝚯, A} where {N, A})}}}, N} where N}","page":"Heat Conduction","title":"CryoGrid.Heat.TemperatureProfile","text":"TemperatureProfile(pairs::Pair{<:Union{DistQuantity,Param},<:Union{TempQuantity,Param}}...)\n\nConvenience constructor for Numerics.Profile which automatically converts temperature quantities.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.enthalpy-NTuple{4, Any}","page":"Heat Conduction","title":"CryoGrid.Heat.enthalpy","text":"enthalpy(T, C, L, θ) = T*C + L*θ\n\nDiscrete enthalpy function on temperature, heat capacity, specific latent heat of fusion, and liquid water content.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.enthalpyinv-NTuple{4, Any}","page":"Heat Conduction","title":"CryoGrid.Heat.enthalpyinv","text":"enthalpyinv(H, C, L, θ) = (H - L*θ) / C\n\nDiscrete inverse enthalpy function given H, C, L, and θ.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.freezethaw!-Tuple{Any, Any}","page":"Heat Conduction","title":"CryoGrid.Heat.freezethaw!","text":"freezethaw!(sub::SubSurface, heat::HeatBalance{FreeWater,<:EnthalpyBased}, state)\n\nImplementation of \"free water\" freezing characteristic for any subsurface layer. Assumes that state contains at least temperature (T), enthalpy (H), heat capacity (C), total water content (θwi), and liquid water content (θw).\n\n\n\n\n\n","category":"method"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.freezethaw!-Tuple{SubSurface, HeatBalance, Any}","page":"Heat Conduction","title":"CryoGrid.Heat.freezethaw!","text":"freezethaw!(sub::SubSurface, heat::HeatBalance, state)\n\nCalculates freezing and thawing effects, including evaluation of the freeze curve. In general, this function should compute at least the liquid/frozen water contents and the corresponding heat capacity. Other variables such as temperature or enthalpy may also need to be computed depending on the thermal scheme being implemented.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.heat_conduction_linear_periodic_ub-NTuple{4, Any}","page":"Heat Conduction","title":"CryoGrid.Heat.heat_conduction_linear_periodic_ub","text":"Analytical solution to linear form of the heat equation on a semi-infinite rod with periodic fluctuations at the upper boundary. Solution taken from Riseborough et al. 2008.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.heatcapacity!-Tuple{SubSurface, HeatBalance, Any}","page":"Heat Conduction","title":"CryoGrid.Heat.heatcapacity!","text":"heatcapacity!(sub::SubSurface, heat::HeatBalance, state)\n\nComputes the heat capacity for the given layer from the current state and stores the result in-place in the state variable C.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.heatcapacity-Tuple{SubSurface, Any, Any}","page":"Heat Conduction","title":"CryoGrid.Heat.heatcapacity","text":"heatcapacity(::SubSurface, state, i)\n\nComputes the heat capacity for the given SubSurface layer at grid cell i.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.heatcapacity-Tuple{SubSurface, HeatBalance, Any, Any}","page":"Heat Conduction","title":"CryoGrid.Heat.heatcapacity","text":"heatcapacity(sub::SubSurface, heat::HeatBalance, state, i)\n\nComputes the heat capacity as a weighted average over constituent capacities with volumetric fractions θfracs.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.thermalconductivity!-Tuple{SubSurface, HeatBalance, Any}","page":"Heat Conduction","title":"CryoGrid.Heat.thermalconductivity!","text":"thermalconductivity!(sub::SubSurface, heat::HeatBalance, state)\n\nComputes the thermal conductivity for the given layer from the current state and stores the result in-place in the state variable k.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.thermalconductivity-Tuple{SubSurface, Any, Any}","page":"Heat Conduction","title":"CryoGrid.Heat.thermalconductivity","text":"thermalconductivity(::SubSurface, state, i)\n\nComputes the thermal conductivity for the given SubSurface layer at grid cell i.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.thermalconductivity-Tuple{SubSurface, HeatBalance, Any, Any}","page":"Heat Conduction","title":"CryoGrid.Heat.thermalconductivity","text":"thermalconductivity(sub::SubSurface, heat::HeatBalance, state, i)\n\nComputes the thermal conductivity as a squared weighted sum over constituent conductivities with volumetric fractions θfracs.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.thermalproperties-Tuple{SubSurface}","page":"Heat Conduction","title":"CryoGrid.Heat.thermalproperties","text":"thermalproperties(::SubSurface)\n\nReturns the thermal properties for the given subsurface layer.\n\n\n\n\n\n","category":"method"},{"location":"installation/#Installation","page":"Installation","title":"Installation","text":"","category":"section"},{"location":"installation/","page":"Installation","title":"Installation","text":"CryoGrid.jl can be installed via the Julia package manager:","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"add https://gitlab.awi.de/sparcs/cryogrid/cryogridjulia","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"or equivalently in code/REPL:","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"import Pkg\nPkg.add([\"https://gitlab.awi.de/sparcs/cryogrid/cryogridjulia\"])","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"Be aware that CryoGrid.jl is a relatively large package with quite a few dependencies, so installation into a blank Julia environment could take several minutes.","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"It is recommended that you work with CryoGrid.jl as a Julia package rather than cloning the repository and hacking on it directly. This will allow for more rapid development and minimize latency from precompile time. It is also recommended to create a dedicated Julia environment in your workspace to better manage package dependencies. This can be accomplished by running:","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"activate .","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"in your working directory, or by starting Julia with the --project=. option. Then, you can proceed to install CryoGrid.jl into the environment via the commands above.","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"You can load CryoGrid.jl in your Julia REPL or editor by running:","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"using CryoGrid","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"or similarly:","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"import CryoGrid","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"The latter option will bring only the CryoGrid module name into scope rather than all of its exported components.","category":"page"},{"location":"api/utils/#utils","page":"Utilities","title":"Utility methods and types","text":"","category":"section"},{"location":"api/utils/","page":"Utilities","title":"Utilities","text":"This module provides miscellaneous utility methods and types that are used throughout the CryoGrid.jl codebase. Note that the Utils module is not exported by the top-level CryoGrid module. It may, however, be explicitly imported by the user via using CryoGrid.Utils or import CryoGrid.Utils when needed.","category":"page"},{"location":"api/utils/","page":"Utilities","title":"Utilities","text":"Modules = [CryoGrid.Utils]\nPrivate = false\nOrder = [:type, :function, :macro]","category":"page"},{"location":"api/utils/#CryoGrid.Utils.Named","page":"Utilities","title":"CryoGrid.Utils.Named","text":"Named{name,T}\n\nWraps a value of type T with a name type parameter.\n\n\n\n\n\n","category":"type"},{"location":"api/utils/#CryoGrid.Utils.NamedTupleWrapper","page":"Utilities","title":"CryoGrid.Utils.NamedTupleWrapper","text":"NamedTupleWrapper\n\nBase type for container types that hold a NamedTuple of arbitrary field values. NamedTupleWrapper provides dispatches for getproperty and propertynames that forward property name queries to the NamedTuple container. Subtypes are by default assumed to have a field named values that corresponds to the NamedTuple container, but this can be overriden by providing a dispatch for Base.values.\n\n\n\n\n\n","category":"type"},{"location":"api/utils/#CryoGrid.Utils.applyunits-Tuple{Unitful.Units, Number}","page":"Utilities","title":"CryoGrid.Utils.applyunits","text":"applyunits(u::Unitful.Units, x::Number)\n\nConditionally applies unit u to x if and only if x is a unit-free quantity. If x is a unitful quantity, asserts that the unit matches u.\n\n\n\n\n\n","category":"method"},{"location":"api/utils/#CryoGrid.Utils.convert_t-Tuple{DateTime}","page":"Utilities","title":"CryoGrid.Utils.convert_t","text":"convert_t(t::DateTime)\nconvert_t(t::Float64)\n\nConvenience method for converting between Dates.DateTime and solver time.\n\n\n\n\n\n","category":"method"},{"location":"api/utils/#CryoGrid.Utils.convert_tspan-Tuple{Tuple{DateTime, DateTime}}","page":"Utilities","title":"CryoGrid.Utils.convert_tspan","text":"convert_tspan(tspan::Tuple{DateTime,DateTime})\nconvert_tspan(tspan::Tuple{Float64,Float64})\n\nConvenience method for converting between Dates.DateTime and solver time.\n\n\n\n\n\n","category":"method"},{"location":"api/utils/#CryoGrid.Utils.fastiterate-Union{Tuple{N}, Tuple{F}, Tuple{F, Vararg{Tuple{Vararg{Any, N}}, N1} where N1}} where {F, N}","page":"Utilities","title":"CryoGrid.Utils.fastiterate","text":"fastiterate(f!::F, iters::NTuple{N,Any}...) where {F,N}\n\nSame as fastmap but simply invokes f! on each argument set without constructing a tuple.\n\n\n\n\n\n","category":"method"},{"location":"api/utils/#CryoGrid.Utils.fastmap-Union{Tuple{N}, Tuple{F}, Tuple{F, Vararg{Tuple{Vararg{Any, N}}, N1} where N1}} where {F, N}","page":"Utilities","title":"CryoGrid.Utils.fastmap","text":"fastmap(f::F, iter::NTuple{N,Any}...) where {F,N}\n\nSame as map for NTuples but with guaranteed type stability. fastmap is a @generated function which unrolls calls to f into a loop-free tuple construction expression.\n\n\n\n\n\n","category":"method"},{"location":"api/utils/#CryoGrid.Utils.getscalar-Tuple{Number}","page":"Utilities","title":"CryoGrid.Utils.getscalar","text":"getscalar(x)\ngetscalar(x, i)\n\nHelper method for generalizing between arrays and scalars. Without an index, retrieves the first element of x if x is an array, otherwise simply returning x. If an index i, is specified, returns the ith value of x if x is an array, or x otherwise. Note that this method is not strictly necessary since Julia allows for scalar quantities to be accessed at the first index like an array; however, the point is to make it expliclty clear in scalar-typed code that a state variable is treated as such and is not a vector valued quantity.\n\n\n\n\n\n","category":"method"},{"location":"api/utils/#CryoGrid.Utils.pstrip-Tuple{Any}","page":"Utilities","title":"CryoGrid.Utils.pstrip","text":"pstrip(obj; keep_units=false)\n\nStrips Param types and units from obj. If keep_units=true, then Param types will be stripped but units preserved.\n\n\n\n\n\n","category":"method"},{"location":"api/utils/#CryoGrid.Utils.tuplejoin-Tuple{}","page":"Utilities","title":"CryoGrid.Utils.tuplejoin","text":"tuplejoin([x, y], z...)\n\nConcatenates one or more tuples together; should generally be type stable.\n\n\n\n\n\n","category":"method"},{"location":"api/utils/#CryoGrid.Utils.@UFloat_str-Tuple{Any}","page":"Utilities","title":"CryoGrid.Utils.@UFloat_str","text":"Similar to Unitful.@u_str (i.e. u\"kg\") but produces the type of the quantity rather than the instance. NOT conditional on debug mode.\n\n\n\n\n\n","category":"macro"},{"location":"api/utils/#CryoGrid.Utils.@UT_str-Tuple{Any}","page":"Utilities","title":"CryoGrid.Utils.@UT_str","text":"Similar to Unitful.@u_str (i.e. u\"kg\") but produces the type of the unit rather than the instance. NOT conditional on debug mode.\n\n\n\n\n\n","category":"macro"},{"location":"api/utils/#CryoGrid.Utils.@pstrip-Tuple{Any, Vararg{Any, N} where N}","page":"Utilities","title":"CryoGrid.Utils.@pstrip","text":"@pstrip(expr, kwargs...)\n\nConvenience macro for Utils.pstrip; equivalent to pstrip(expr, kwargs...).\n\n\n\n\n\n","category":"macro"},{"location":"api/utils/#CryoGrid.Utils.@setscalar-Tuple{Any}","page":"Utilities","title":"CryoGrid.Utils.@setscalar","text":"Convenience macro for setting scalar (single-element) arrays/vectors. It turns an expression of the form: a.b = ... into a.b[1] = ...\n\nThis is primarily intended for code clarity, i.e to clearly discern scalar and non-scalar values.\n\n\n\n\n\n","category":"macro"},{"location":"api/utils/#CryoGrid.Utils.@sym_str-Tuple{Any}","page":"Utilities","title":"CryoGrid.Utils.@sym_str","text":"sym_str(val)\n\nConvenience macro, sym\"val\", for creating a Symbol from val. Equivalent to Symbol(val). Use in situations where normal Julia :val syntax is not possible, e.g. sym\"1\" instead of Symbol(1) or sym\"my.var\" instead of Symbol(\"my.var\").\n\n\n\n\n\n","category":"macro"},{"location":"api/utils/#CryoGrid.Utils.@threaded-Tuple{Any}","page":"Utilities","title":"CryoGrid.Utils.@threaded","text":"Prepends expr with Threads.@threads if and only if Threads.nthreads() > 1, thus avoiding the overhead of @threads when running in single-threaded mode.\n\nCredit to @ranocha (Hendrik Ranocha) https://discourse.julialang.org/t/overhead-of-threads-threads/53964/22\n\n\n\n\n\n","category":"macro"},{"location":"api/#Index-of-public-API","page":"Index","title":"Index of public API","text":"","category":"section"},{"location":"api/","page":"Index","title":"Index","text":"","category":"page"},{"location":"api/toplevel/#toplevel","page":"CryoGrid","title":"Top level methods and types","text":"","category":"section"},{"location":"api/toplevel/","page":"CryoGrid","title":"CryoGrid","text":"Modules = [CryoGrid]\nPrivate = false\nOrder = [:type, :constant, :function, :macro]","category":"page"},{"location":"api/toplevel/#CryoGrid.Algebraic","page":"CryoGrid","title":"CryoGrid.Algebraic","text":"Algebraic{name,S,T,units,domain} <: Var{name,S,T,units,domain}\n\nDefines an algebraic (implicit) state variable.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.BCKind","page":"CryoGrid","title":"CryoGrid.BCKind","text":"BCKind\n\nTrait that specifies the kind of boundary condition. This can be used to write generic implementations of interact! that are (relatively) agnostic to specific implementations of BoundaryProcess. A good example of this can be found in the boundaryflux method interface.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.BCKind-Union{Tuple{Type{BP}}, Tuple{BP}} where BP<:BoundaryProcess","page":"CryoGrid","title":"CryoGrid.BCKind","text":"BCKind(::Type{T})\n\nCan be overriden by BoundaryProcess types to indicate the type of boundary condition, e.g:\n\nBCKind(::Type{BP}) = Dirichlet()\n\nwhere BP is a BoundaryProcess that provides the boundary conditions.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.Bottom","page":"CryoGrid","title":"CryoGrid.Bottom","text":"Bottom{TProc} <: Layer\n\nGeneric \"bottom\" layer that marks the lower boundary of the subsurface grid.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.BoundaryProcess","page":"CryoGrid","title":"CryoGrid.BoundaryProcess","text":"BoundaryProcess{T<:SubSurfaceProcess}\n\nAbstract base type for boundary processes, i.e. processes that operate at the boundaries of the subsurface. A BoundaryProcess represents the boundary conditions of one or more SubSurfaceProcesses but may include its own diagnostic (or even prognostic) variables, if necessary.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.CGEuler","page":"CryoGrid","title":"CryoGrid.CGEuler","text":"CGEuler <: SciMLBase.AbstractODEAlgorithm\n\nSimple, lightweight implementation of the forward Euler integration algorithm. Does not include support for fancier features such as interpolation, adaptive timestepping, or event handling. In order to get these features, you must install the OrdinaryDiffEq package.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.ConstantBC","page":"CryoGrid","title":"CryoGrid.ConstantBC","text":"ConstantBC{P,S,T} <: BoundaryProcess{P}\n\nConstant boundary condition (of any type/unit) specified by value.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.Coupled2","page":"CryoGrid","title":"CryoGrid.Coupled2","text":"Coupled2{P1,P2} = CoupledProcesses{Tuple{T1,T2}} where {T1,T2}\n\nType alias for coupled processes, i.e. CoupledProcesses{Tuple{P1,P2}}. Coupled provides a simple mechanism for defining new behaviors on multi-processes systems.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.CoupledProcesses","page":"CryoGrid","title":"CryoGrid.CoupledProcesses","text":"CoupledProcesses{TProcs} <: Process\n\nRepresents an explicitly or implicitly coupled system of processes. TProcs is always a Tuple of other processes.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.CryoGridProblem","page":"CryoGrid","title":"CryoGrid.CryoGridProblem","text":"CryoGridProblem{iip,Tu,Tt,Tp,TT,Tsv,Tsf,Tcb,Tdf,Tkw} <: SciMLBase.AbstractODEProblem{Tu,Tt,iip}\n\nRepresents a CryoGrid discretized PDE forward model configuration using the SciMLBase/DiffEqBase problem interface.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.CryoGridProblem-2","page":"CryoGrid","title":"CryoGrid.CryoGridProblem","text":"CryoGridProblem(\n tile::Tile,\n u0::ComponentVector,\n tspan::NTuple{2,Float64},\n p=nothing;\n saveat=3600.0,\n savevars=(),\n save_everystep=false,\n save_start=true,\n save_end=true,\n step_limiter=timestep,\n safety_factor=1,\n max_step=true,\n callback=nothing,\n isoutofdomain=Tiles.domain(tile),\n specialization=SciMLBase.AutoSpecialize,\n function_kwargs=(),\n prob_kwargs...\n)\n\nConstructor for CryoGridProblem that automatically generates all necessary callbacks.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.CryoGridProblem-Tuple{Tile, ComponentArrays.ComponentVector{T, A, Axes} where {T, A, Axes}, Tuple{DateTime, DateTime}, Vararg{Any, N} where N}","page":"CryoGrid","title":"CryoGrid.CryoGridProblem","text":"CryoGridProblem(tile::Tile, u0::ComponentVector, tspan::NTuple{2,DateTime}, args...;kwargs...)\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.Diagnostic","page":"CryoGrid","title":"CryoGrid.Diagnostic","text":"Diagnostic{name,S,T,units,domain} <: Var{name,S,T,units,domain}\n\nDefines a diagnostic variable which is allocated and cached per timestep but not integrated over time.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.DiagnosticVolume","page":"CryoGrid","title":"CryoGrid.DiagnosticVolume","text":"DiagnosticVolume\n\nVolume trait instance for layers with time varying volume where the volume should be treated as a diagnostic state variable.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.FixedVolume","page":"CryoGrid","title":"CryoGrid.FixedVolume","text":"FixedVolume\n\nVolume trait instance for fixed volume layers. Default for all Layer types.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.GridOffset","page":"CryoGrid","title":"CryoGrid.GridOffset","text":"Base type for grid alignment, i.e. either \"edges\" or \"cells\".\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.Layer","page":"CryoGrid","title":"CryoGrid.Layer","text":"Layer\n\nAbstract base type for all layers.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.PeriodicBC","page":"CryoGrid","title":"CryoGrid.PeriodicBC","text":"PeriodicBC{P,S,T1,T2,T3,T4} <: BoundaryProcess{P}\n\nPeriodic boundary condition (of any type/unit) specified by period, amplitude, and phaseshift.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.Process","page":"CryoGrid","title":"CryoGrid.Process","text":"Abstract base type for all dynamical processes.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.Prognostic","page":"CryoGrid","title":"CryoGrid.Prognostic","text":"Prognostic{name,S,T,units,domain} <: Var{name,S,T,units,domain}\n\nDefines a prognostic (time-integrated) state variable.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.PrognosticVolume","page":"CryoGrid","title":"CryoGrid.PrognosticVolume","text":"PrognosticVolume\n\nVolume trait instance for layers with time varying volume where the volume should be treated as a prognostic state variable.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.SubSurface","page":"CryoGrid","title":"CryoGrid.SubSurface","text":"SubSurface <: Layer\n\nAbstract base type for layers in the stratigraphy, e.g. soil, snow, pond, etc.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.SubSurfaceProcess","page":"CryoGrid","title":"CryoGrid.SubSurfaceProcess","text":"SubSurfaceProcess <: Process\n\nAbstract base type for subsurface processes, i.e. processes that operate at or below the surface, such as heat conduction, water infiltration, etc.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.Top","page":"CryoGrid","title":"CryoGrid.Top","text":"Top{TProc} <: Layer\n\nGeneric \"top\" layer that marks the upper boundary of the subsurface grid.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.Var","page":"CryoGrid","title":"CryoGrid.Var","text":"Var{name,S<:VarDim,T,units,domain}\n\nBase type for symbolic state variables in the model.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.VarInitializer","page":"CryoGrid","title":"CryoGrid.VarInitializer","text":"VarInitializer{varname}\n\nBase type for state variable initializers. Initializers of this type are dedicated to a specific state variable with name varname and are run before all other initializers.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.Volume-Tuple{Type{var\"#s59\"} where var\"#s59\"<:Layer}","page":"CryoGrid","title":"CryoGrid.Volume","text":"Volume(::Type{<:Layer})\n\nTrait for layer types that determines whether its spatial volume is temporally invariant, FixedVolume, or varying with time, DiagnosticVolume or PrognosticVolume.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.Coupled-Tuple{Vararg{Process, N} where N}","page":"CryoGrid","title":"CryoGrid.Coupled","text":"Coupled(ps::SubSurfaceProcess...)\n\nConstructs a composite/coupled process from one or more subsurface processes. Alias for CoupledProcesses(ps...).\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.Coupled-Tuple{Vararg{Type{var\"#s28\"} where var\"#s28\"<:Process, N} where N}","page":"CryoGrid","title":"CryoGrid.Coupled","text":"Coupled(types::Type{<:Process}...)\n\nConvenince method which constructs a CoupledProcesses type corresponding to each type in types, e.g:\n\nCoupled(SnowMassBalance, HeatBalance) = CoupledProcesses{Tuple{T1,T2}} where {T1<:SnowMassBalance, T2<:HeatBalance}\n\nalso equivalent to Coupled2{<:SnowMassBalance,<:HeatBalance}.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.boundaryflux-Tuple{BoundaryProcess, Union{Bottom, Top}, SubSurfaceProcess, SubSurface, Any, Any}","page":"CryoGrid","title":"CryoGrid.boundaryflux","text":"boundaryflux(bc::BoundaryProcess, b::Union{Top,Bottom}, p::SubSurfaceProcess, sub::SubSurface, sbc, ssub)\nboundaryflux(s::BCKind, bc::BoundaryProcess, b::Union{Top,Bottom}, p::SubSurfaceProcess, sub::SubSurface, sbc, ssub)\n\nComputes the flux dH/dt at the boundary layer. Calls boundaryflux(BCKind(B),...) to allow for generic implementations by boundary condition type. Note that this method uses a different argument order convention than interact!. This is intended to faciliate stratigraphy independent implementations of certain boundary conditions (e.g. a simple Dirichlet boundary could be applied in the same manner to both the upper and lower boundary).\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.boundaryvalue-Tuple{BoundaryProcess, Any}","page":"CryoGrid","title":"CryoGrid.boundaryvalue","text":"boundaryvalue(bc::BoundaryProcess, state)\n\nComputes the value of the boundary condition specified by bc for the given layer/process combinations. Note that this method uses a different argument order convention than interact!. This is intended to faciliate stratigraphy independent implementations of certain boundary conditions (e.g. a simple Dirichlet boundary could be applied in the same manner to both the upper and lower boundary).\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.caninteract-Tuple{Layer, Layer, Any, Any}","page":"CryoGrid","title":"CryoGrid.caninteract","text":"caninteract(layer1::Layer, layer2::Layer, state1, state2)\ncaninteract(l1::Layer, ::Process, l2::Layer, ::Process, state1, state2)\n\nReturns true if and only if the given layer/process types are able to interact based on the current state. Defaults to checking whether both layers are currently active. This behavior should be overridden by subtypes where necessary.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.computediagnostic!-Tuple{Layer, Any}","page":"CryoGrid","title":"CryoGrid.computediagnostic!","text":"computediagnostic!(l::Layer, state)\ncomputediagnostic!(l::Layer, p::Process, state)\n\nUpdates all diagnostic/non-flux state variables for the given Layer based on the current prognostic state.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.computefluxes!-Tuple{Layer, Any}","page":"CryoGrid","title":"CryoGrid.computefluxes!","text":"computefluxes!(l::Layer, p::Process, state)\n\nCalculates all internal fluxes for a given layer. Note that an instance of computefluxes! must be provided for all non-boundary (subsurface) processes/layers.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.criterion!-Tuple{AbstractArray, GridContinuousEvent, Layer, Any}","page":"CryoGrid","title":"CryoGrid.criterion!","text":"criterion!(out::AbstractArray, ev::GridContinuousEvent, ::Layer, ::Process, state)\n\nEvent criterion for on-grid (i.e. multi-valued) continuous events. The condition for each grid cell should be stored in out.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.criterion-Tuple{Union{ContinuousEvent, DiscreteEvent}, Layer, Any}","page":"CryoGrid","title":"CryoGrid.criterion","text":"criterion(::Event, ::Layer, ::Process, state)\n\nEvent criterion/condition. Should return a Bool for discrete events. For continuous events, this should be a real-valued function where the event is fired at the zeros/roots.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.diagnosticstep!-Tuple{Layer, Any}","page":"CryoGrid","title":"CryoGrid.diagnosticstep!","text":"diagnosticstep!(layer::Layer, state)\n\nOptionally performs discontinuous/discrete-time updates to the layer state. Should return true if the prognostic state was modified and false otherwise. Defaults to returning false.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.initialcondition!-Tuple{Layer, Any}","page":"CryoGrid","title":"CryoGrid.initialcondition!","text":"initialcondition!(::Layer, state)\ninitialcondition!(::Layer, ::Process, state)\ninitialcondition!(::VarInitializer, ::Layer, state)\n\nDefines the initial condition for a given Layer and possibly an initializer. initialcondition! should compute initial values into all relevant state variables in state.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.initialcondition!-Tuple{Layer, Layer, Any, Any}","page":"CryoGrid","title":"CryoGrid.initialcondition!","text":"initialcondition!(layer1::Layer, layer2::Layer, state1, state2)\ninitialcondition!(::Layer, ::Process, ::Layer, ::Process, state1, state2)\n\nDefines the initial condition for two processes on adjacent layers. initialcondition! should write initial values into all relevant state variables in state.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.initializer-Tuple{Symbol, Vararg{Any, N} where N}","page":"CryoGrid","title":"CryoGrid.initializer","text":"initializer(varname::Symbol, args...) = initializer(Val{varname}(), args...)\ninitializer(::Val{varname}, x::Number) => FunctionInitializer w/ constant\ninitializer(::Val{varname}, f::Function) => FunctionInitializer\ninitializer(::Val{varname}, profile::Profile, interp=Linear(), extrap=Flat()) => InterpInitializer\n\nConvenience constructor for VarInitializer that selects the appropriate initializer type based on the arguments.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.initializers-Tuple{Layer}","page":"CryoGrid","title":"CryoGrid.initializers","text":"initializers(::Layer)\ninitializers(::Layer, ::Process)\n\nOptional method that can be used to provide default initializers for state variables that will be run before user provided ones.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.interact!-Tuple{Layer, Layer, Any, Any}","page":"CryoGrid","title":"CryoGrid.interact!","text":"interact!(::Layer, ::Process, ::Layer, ::Process, state1, state2)\n\nDefines a boundary interaction between two processes on adjacent layers. For any interaction, the order of the arguments follows decreasing depth, i.e. the first layer/process is always on top of the second layer/process. This ordering matters and separate dispatches must be provided for interactions in reverse order.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.interactmaybe!-Tuple{Layer, Layer, Any, Any}","page":"CryoGrid","title":"CryoGrid.interactmaybe!","text":"interactmaybe!(layer1::Layer, layer2::Layer, state1, state2)\ninteractmaybe!(layer1::Layer, p1::Process, layer2::Layer, p2::Process, state1, state2)\n\nConditionally invokes interact! if and only if caninteract is true.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.isactive-Tuple{Layer, Any}","page":"CryoGrid","title":"CryoGrid.isactive","text":"isactive(::Layer, state)\n\nReturns a boolean whether or not this layer is currently active in the stratigraphy and should interact with other layers. Note that computediagnostic! and computefluxes! are always invoked regardless of the current state of isactive. The default implementation of isactive always returns true.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.processes-Tuple{Layer}","page":"CryoGrid","title":"CryoGrid.processes","text":"processes(l::Layer)\n\nFetches the process(es) attached to this layer, if any. Returned value must be of type Process. If the layer has more than one process, they should be combined together with Coupled(procs...).\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.resetfluxes!-Tuple{Layer, Any}","page":"CryoGrid","title":"CryoGrid.resetfluxes!","text":"resetfluxes!(layer::Layer, state)\nresetfluxes!(layer::Layer, ::Process, state)\n\nResets all flux variables for the given layer/process to zero.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.timestep-Tuple{Layer, Any}","page":"CryoGrid","title":"CryoGrid.timestep","text":"timestep(::Layer, ::Process, state)\n\nRetrieves the recommended timestep for the given Process defined on the given Layer. The default implementation returns Inf which indicates no timestep restriction. The actual chosen timestep will depend on the integrator being used and other user configuration options.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.timestep-Union{Tuple{P}, Tuple{Layer, CoupledProcesses{P}, Any}} where P","page":"CryoGrid","title":"CryoGrid.timestep","text":"timestep(l::Layer, ps::CoupledProcesses{P}, state) where {P}\n\nDefault implementation of timestep for coupled process types. Calls each process in sequence.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.trigger!-Tuple{CryoGrid.Event, Layer, Any}","page":"CryoGrid","title":"CryoGrid.trigger!","text":"trigger!(::Event, ::Layer, ::Process, state)\ntrigger!(ev::ContinuousEvent, ::ContinuousTrigger, ::Layer, ::Process, state)\ntrigger!(ev::GridContinuousEvent, ::ContinuousTrigger, ::Layer, ::Process, state)\n\nEvent action executed when criterion is met.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.variables-Tuple{Layer, Process}","page":"CryoGrid","title":"CryoGrid.variables","text":"variables(layer::Layer, process::Process)\nvariables(::Layer)\nvariables(::Any)\n\nDefines variables for a given Layer, Process, or arbitrary user-defined type. Implementations should return a Tuple of Vars.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.volumetricfractions-Tuple{SubSurface, Any}","page":"CryoGrid","title":"CryoGrid.volumetricfractions","text":"volumetricfractions(::SubSurface, state)\nvolumetricfractions(::SubSurface, state, i)\n\nGet the volumetric fractions of each constituent in the volume (at grid cell i, if specificed). All implementations of volumetricfractions are expected to obey a semi-consistent order in the returned Tuple of fractions; the first three consituents should always be θw,θi,θa, i.e. water, ice, and air, followed by any number of additional constituents which may be defined by the specific layer. There is no feasible way to verify that client code actually obeys this ordering, so be sure to double check your implementation, otherwise this can cause very subtle bugs!\n\n\n\n\n\n","category":"method"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"EditURL = \"../../../examples/heat_freeW_samoylov.jl\"","category":"page"},{"location":"examples/heat_freeW_samoylov/#example1","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"","category":"section"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"In this example, we use the preset SoilHeatTile to construct a Tile consisting of a soil column with heat conduction forced using air temperatures from Samoylov Island. The enthalpy-based HeatBalance process defaults to the so-called \"free water\" freezing characteristic which assumes that water only freezes and thaws at a melting temperature of 0°C.","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"First we load the built-in forcing file from Nitzbon et al. 2020 (CryoGrid 3). Note that this will download the forcing files from the AWI NextCloud if they are not already present in the input/ folder.","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"using CryoGrid\nforcings = loadforcings(CryoGrid.Presets.Forcings.Samoylov_ERA_obs_fitted_1979_2014_spinup_extended_2044);\nnothing #hide","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"We use the provided default soil and temperature profiles for Samoylov.","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"soilprofile, tempprofile = CryoGrid.Presets.SamoylovDefault;\nnothing #hide","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"We choose the default grid discretization with 5 cm spacing at the surface.","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"grid = CryoGrid.Presets.DefaultGrid_5cm;\nnothing #hide","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"We construct a state variable initializer for temperature T from the temperature profile.","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"initT = initializer(:T, tempprofile)\ntile = CryoGrid.Presets.SoilHeatTile(\n :H,\n TemperatureBC(forcings.Tair, NFactor(nf=0.6)),\n GeothermalHeatFlux(0.053u\"W/m^2\"),\n soilprofile,\n initT;\n grid=grid\n);\nnothing #hide","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"Here we define the time span:","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"tspan = (DateTime(2010,10,30),DateTime(2011,10,30));\nnothing #hide","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"Evaluate the initial condition","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"u0, du0 = initialcondition!(tile, tspan);\nnothing #hide","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"Here we construct a CryoGridProblem with tile, initial condition, and timespan.","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"prob = CryoGridProblem(tile, u0, tspan, saveat=24*3600.0, savevars=(:T,));\nnothing #hide","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"Solve the configured problem with the built-in forward Euler method. note that, due to compile time, this may take 1-2 minutes when executed in a fresh Julia session. Subsequent solves will be much faster.","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"sol = @time solve(prob);\nout = CryoGridOutput(sol)","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"Now we plot the reuslts!","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"import Plots\nzs = [1,10,20,30,50,100,200,500,1000]u\"cm\"\ncg = Plots.cgrad(:copper,rev=true);\nPlots.plot(out.T[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Temperature\", leg=false, size=(800,500), dpi=150)","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"This page was generated using Literate.jl.","category":"page"},{"location":"api/numerics/#Numerics","page":"Numerics","title":"Numerics","text":"","category":"section"},{"location":"api/numerics/","page":"Numerics","title":"Numerics","text":"This module contains a wide range of numerical utilities including math and discretization routines, state variable array caches, and helper types for supporting automatic differentiation.","category":"page"},{"location":"api/numerics/","page":"Numerics","title":"Numerics","text":"DocTestSetup = quote\n using CryoGrid\nend","category":"page"},{"location":"api/numerics/","page":"Numerics","title":"Numerics","text":"Modules = [CryoGrid.Numerics]\nPrivate = false\nOrder = [:type, :function, :macro]","category":"page"},{"location":"api/numerics/#CryoGrid.Numerics.ArrayCache","page":"Numerics","title":"CryoGrid.Numerics.ArrayCache","text":"ArrayCache{T,TA} <: StateVarCache\n\nSimple state variable cache that writes directly into the given array.\n\n\n\n\n\n","category":"type"},{"location":"api/numerics/#CryoGrid.Numerics.AutoGrid","page":"Numerics","title":"CryoGrid.Numerics.AutoGrid","text":"AutoGrid <: DiscretizationStrategy\n\n\n\n\n\n","category":"type"},{"location":"api/numerics/#CryoGrid.Numerics.DiffCache","page":"Numerics","title":"CryoGrid.Numerics.DiffCache","text":"DiffCache{T,TCache}\n\nWrapper around PreallocationTools.DiffCache that stores state variables in forward-diff compatible cache arrays.\n\n\n\n\n\n","category":"type"},{"location":"api/numerics/#CryoGrid.Numerics.DiscretizationStrategy","page":"Numerics","title":"CryoGrid.Numerics.DiscretizationStrategy","text":"Base type for discretization \"strategies\" that generate a spatial discretization (typically a grid).\n\n\n\n\n\n","category":"type"},{"location":"api/numerics/#CryoGrid.Numerics.Grid","page":"Numerics","title":"CryoGrid.Numerics.Grid","text":"struct Grid{S,G,Q,A} <: AbstractDiscretization{Q,1}\n\nRepresents the 1D spatial discretization on which time integration is performed. S is a GridOffset, either Edges or Cells (always edges upon initial construction). The grid representation can be converted (allocation free) between grid edges and cells via the cells and edges methods. G represents the geometry/volume on which the vertical 1D discretization is applied. A is the underlying array type, and Q is the numerical type (e.g. Float64 or a Unitful.Quantity).\n\n\n\n\n\n","category":"type"},{"location":"api/numerics/#CryoGrid.Numerics.PresetGrid","page":"Numerics","title":"CryoGrid.Numerics.PresetGrid","text":"Simple discretization strategy that just supplies a pre-specified grid.\n\n\n\n\n\n","category":"type"},{"location":"api/numerics/#CryoGrid.Numerics.Profile","page":"Numerics","title":"CryoGrid.Numerics.Profile","text":"Profile{N,idxTypes,valTypes}\n\nRepresents a \"profile\" of values indexed typically over depth, i.e:\n\nx₁: value 1 x₂: value 2 ...\n\nwhere xᵢ are the indices.\n\n\n\n\n\n","category":"type"},{"location":"api/numerics/#CryoGrid.Numerics.StateVars","page":"Numerics","title":"CryoGrid.Numerics.StateVars","text":"StateVars{names,griddvars,TU,TV,DF,DG}\n\nGeneric container for holding discretized state arrays from symbolic variables (Var types). The uproto field represetns a \"prototype\" of the prognostic state array which should fully define the state of the system at any given point.\n\n\n\n\n\n","category":"type"},{"location":"api/numerics/#CryoGrid.Numerics.StateVars-Union{Tuple{TArray}, Tuple{TCache}, Tuple{NamedTuple, CryoGrid.Numerics.AbstractDiscretization, Type{TCache}}, Tuple{NamedTuple, CryoGrid.Numerics.AbstractDiscretization, Type{TCache}, Type{TArray}}} where {TCache, TArray<:(AbstractVector{T} where T)}","page":"Numerics","title":"CryoGrid.Numerics.StateVars","text":"StateVars(vars::NamedTuple, D::Numerics.AbstractDiscretization, cachector::Function, arrayproto::Type{A}=Vector) where {A<:AbstractVector}\n\nConstructs a StateVars container from vars and the given discretization D. The function cachector must accept argments f(name::Symbol, x::AbstractVector) where name is the name of the state variable and x is the array generated by the discretization.\n\n\n\n\n\n","category":"method"},{"location":"api/numerics/#CryoGrid.Numerics.divergence!-Tuple{AbstractVector{T} where T, AbstractVector{T} where T, AbstractVector{T} where T}","page":"Numerics","title":"CryoGrid.Numerics.divergence!","text":"divergence!(dx::AbstractVector, j::AbstractVector, Δj::AbstractVector)\n\nCalculates the first-order divergence over a 1D flux vector field j and grid cell lengths Δj. Divergences are added to existing values in dx.\n\n\n\n\n\n","category":"method"},{"location":"api/numerics/#CryoGrid.Numerics.flux!-NTuple{4, AbstractVector{T} where T}","page":"Numerics","title":"CryoGrid.Numerics.flux!","text":"flux!(j::AbstractVector, x::AbstractVector, Δx::AbstractVector, k::AbstractVector)\n\nCalculates the first-order, non-linear spatial flux over a discretized variable x with conductivity k. x is assumed to have shape (N,), Δx shape (N-1,), and j and k shape (N+1,) such that j[2:end-1] represents the fluxes over the inner grid cell faces. Fluxes are added to existing values in j.\n\n\n\n\n\n","category":"method"},{"location":"api/numerics/#CryoGrid.Numerics.harmonicmean!-Tuple{AbstractVector{T} where T, AbstractVector{T} where T, AbstractVector{T} where T}","page":"Numerics","title":"CryoGrid.Numerics.harmonicmean!","text":"harmonicmean!(h::AbstractVector, x::AbstractVector, w::AbstractVector)\n\nVectorized harmonic mean of elements in x with weights w. Output is stored in h, which should have size length(x)-1.\n\n\n\n\n\n","category":"method"},{"location":"api/numerics/#CryoGrid.Numerics.harmonicmean-NTuple{4, Any}","page":"Numerics","title":"CryoGrid.Numerics.harmonicmean","text":"harmonicmean(x₁, x₂, w₁, w₂)\n\nSimple weighted harmonic mean of two values, x₁ and x₂.\n\n\n\n\n\n","category":"method"},{"location":"api/numerics/#CryoGrid.Numerics.makegrid-Tuple{PresetGrid, Tuple{var\"#s59\", var\"#s59\"} where var\"#s59\"<:(Quantity{T, 𝐋, U} where {T, U<:(Unitful.FreeUnits{N, 𝐋, nothing} where N)})}","page":"Numerics","title":"CryoGrid.Numerics.makegrid","text":"makegrid(strategy::DiscretizationStrategy, bounds::NTuple{2,<:DistQuantity})\nmakegrid(layer::Layer, strategy::DiscretizationStrategy, bounds::NTuple{2,<:DistQuantity})\n\nConstructs a Grid spanning bounds using the given strategy. makegrid can also be specified for specific Layer types when layers have specific discretization requirements.\n\n\n\n\n\n","category":"method"},{"location":"api/numerics/#CryoGrid.Numerics.nonlineardiffusion!-NTuple{6, AbstractVector{T} where T}","page":"Numerics","title":"CryoGrid.Numerics.nonlineardiffusion!","text":"nonlineardiffusion!(dx::AbstractVector, j::AbstractVector, x::AbstractVector, Δx::AbstractVector, k::AbstractVector, Δk::AbstractVector)\n\nFast alternative to flux! and divergence! which computes fluxes and divergences (via _flux_kernel and _div_kernel) in a single pass. Note, however, that loop vectorization with @turbo is not possible because of necessary loop-carried dependencies. Fluxes and divergences are added to the existing values stored in j and dx.\n\n\n\n\n\n","category":"method"},{"location":"api/numerics/#CryoGrid.Numerics.updategrid!-Tuple{Grid{Edges, G, Q, A} where {G, Q, A}, AbstractVector{T} where T}","page":"Numerics","title":"CryoGrid.Numerics.updategrid!","text":"updategrid!(grid::Grid{Edges}, edges)\nupdategrid!(grid::Grid{Edges}, z0, thick::AbstractVector)\n\nUpdates all grid values based on new grid edges or an initial z0 + cell thick.\n\n\n\n\n\n","category":"method"},{"location":"api/numerics/#CryoGrid.Numerics.∇-Union{Tuple{F}, Tuple{F, AbstractArray}} where F","page":"Numerics","title":"CryoGrid.Numerics.∇","text":"∇(f::F, x::AbstractArray) where {F}\n\nTakes a function y = f(x) and vector-valued argument x and returns a tuple: (y, ∇ₓy). The gradient is calculated using forward-mode automatic differentiation.\n\n\n\n\n\n","category":"method"},{"location":"api/numerics/#CryoGrid.Numerics.∇-Union{Tuple{F}, Tuple{F, Number}} where F","page":"Numerics","title":"CryoGrid.Numerics.∇","text":"∇(f::F, x::Number) where {F}\n\nTakes a function y = f(x) and argument x and returns a tuple: (y, ∂y∂x). The derivative is calculated using forward-mode automatic differentiation.\n\n\n\n\n\n","category":"method"},{"location":"dev/concepts/#concepts","page":"Concepts","title":"Concepts","text":"","category":"section"},{"location":"dev/concepts/","page":"Concepts","title":"Concepts","text":"This page provides a brief(-ish) overview of the basic programming and Julia-language concepts needed in order to develop and extend CryoGrid.jl.","category":"page"},{"location":"dev/concepts/#Multiple-dispatch","page":"Concepts","title":"Multiple dispatch","text":"","category":"section"},{"location":"dev/concepts/","page":"Concepts","title":"Concepts","text":"The CryoGrid community model in MATLAB reuses code through object-oriented programming (OOP), namely by separating process implementations into standalone classes. These classes are then subtyped by layer classes (e.g. GROUND_freeW_ubT) which then inherit their state variables, parameters, and functions.","category":"page"},{"location":"dev/concepts/","page":"Concepts","title":"Concepts","text":"Unlike MATLAB, Julia is not object-oriented and has no concept of a class (the closest equivalent is a struct). Furthermore, while Julia allows for inheritance from abstract types, it does not allow structs to inherit from other structs, as explained by the Julia documentation:","category":"page"},{"location":"dev/concepts/","page":"Concepts","title":"Concepts","text":"One particularly distinctive feature of Julia's type system is that concrete types may not subtype each other: all concrete types are final and may only have abstract types as their supertypes. While this might at first seem unduly restrictive, it has many beneficial consequences with surprisingly few drawbacks. It turns out that being able to inherit behavior is much more important than being able to inherit structure, and inheriting both causes significant difficulties in traditional object-oriented languages.","category":"page"},{"location":"dev/concepts/","page":"Concepts","title":"Concepts","text":"In light of this, CryoGrid.jl takes a different approach to effectively reuse code between model components. Rather than having layers \"inherit\" processes, subtypes of Layer are composed of one or more processes as well as parameter types which then determine which methods are invoked at runtime. This is facilitated by one of Julia's key features, multiple dispatch. Multiple dispatch means that methods are dynamically invoked based on the (runtime) types of all their arguments. This is in constrast to most OOP languages (also MATLAB) where dynamic dispatch occurs based on only one (implicit) argument, i.e. the type of the \"object\" or class itself. As an example, consider the CryoGrid method computediagnostic!:","category":"page"},{"location":"dev/concepts/","page":"Concepts","title":"Concepts","text":"using CryoGrid\n\n# Declare two new SubSurface layer types;\n# note that <: basically means \"is a subtype of\"\nstruct Foo <: SubSurface end\nstruct Bar <: SubSurface end\n\nCryoGrid.computediagnostic!(layer::Foo, state) = println(\"hello Foo\")\nCryoGrid.computediagnostic!(layer::Bar, state) = println(\"hello Bar\")\n\nstate = nothing # we can ignore the state for the sake of the example\ncomputediagnostic!(Foo(), state)\ncomputediagnostic!(Bar(), state)","category":"page"},{"location":"dev/concepts/","page":"Concepts","title":"Concepts","text":"Output:","category":"page"},{"location":"dev/concepts/","page":"Concepts","title":"Concepts","text":"hello Foo\nhello Bar","category":"page"},{"location":"dev/concepts/","page":"Concepts","title":"Concepts","text":"In this example, we can see that which computediagnostic! implementation gets invoked is determined by which type is supplied by the caller.","category":"page"},{"location":"dev/concepts/","page":"Concepts","title":"Concepts","text":"Multiple dispatch allows us to extend this naturally to cases where more than one method argument has a declared type:","category":"page"},{"location":"dev/concepts/","page":"Concepts","title":"Concepts","text":"struct MyProcess <: SubSurfaceProcess end\n\nCryoGrid.computediagnostic!(::SubSurface, ::MyProcess, state) = println(\"hello MyProcess on any SubSurface\")\nCryoGrid.computediagnostic!(::Bar, ::MyProcess, state) = println(\"hello MyProcess on Bar\")\n\ncomputediagnostic!(Layer1(), MyProcess() state)\ncomputediagnostic!(Layer2(), MyProcess(), state)","category":"page"},{"location":"dev/concepts/","page":"Concepts","title":"Concepts","text":"Output:","category":"page"},{"location":"dev/concepts/","page":"Concepts","title":"Concepts","text":"hello MyProcess on any SubSurface\nhello MyProcess on Bar","category":"page"},{"location":"dev/concepts/","page":"Concepts","title":"Concepts","text":"Thus, multiple dispatch allows us to write generic code in computediagnostic! that implements MyProcess for any SubSurface layer (i.e. the parent type of both Foo and Bar) in addition to adding specialized code for more specific layer types.","category":"page"},{"location":"api/tiles/#tiles","page":"Tiles","title":"Tiles","text":"","category":"section"},{"location":"api/tiles/","page":"Tiles","title":"Tiles","text":"This module contains Tile, Stratigraphy, and all related methods and types necessary for constructing a 1-D CryoGrid process model.","category":"page"},{"location":"api/tiles/","page":"Tiles","title":"Tiles","text":"Modules = [Tiles]\nPrivate = false\nOrder = [:type, :function, :macro]","category":"page"},{"location":"api/tiles/#CryoGrid.Tiles.JacobianStyle","page":"Tiles","title":"CryoGrid.Tiles.JacobianStyle","text":"JacobianStyle\n\nTrait for indicating Jacobian sparsity of a CryoGrid ODEProblem.\n\n\n\n\n\n","category":"type"},{"location":"api/tiles/#CryoGrid.Tiles.JacobianStyle-Tuple{CryoGrid.Tiles.AbstractTile}","page":"Tiles","title":"CryoGrid.Tiles.JacobianStyle","text":"JacobianStyle(::AbstractTile)\n\nCan be overriden/extended to specify Jacobian structure for specific Tiles.\n\n\n\n\n\n","category":"method"},{"location":"api/tiles/#CryoGrid.Tiles.Stratigraphy","page":"Tiles","title":"CryoGrid.Tiles.Stratigraphy","text":"Stratigraphy{N,TLayers<:NamedTuple,TBoundaries}\n\nDefines a 1-dimensional stratigraphy by connecting a top and bottom layer to one or more subsurface layers.\n\n\n\n\n\n","category":"type"},{"location":"api/tiles/#CryoGrid.Tiles.Tile","page":"Tiles","title":"CryoGrid.Tiles.Tile","text":"Tile{TStrat,TGrid,TStates,TInits,TEvents,iip} <: AbstractTile{iip}\n\nDefines the full specification of a single CryoGrid tile; i.e. stratigraphy, grid, and state variables.\n\n\n\n\n\n","category":"type"},{"location":"api/tiles/#CryoGrid.Tiles.Tile-Tuple{SciMLBase.DEIntegrator}","page":"Tiles","title":"CryoGrid.Tiles.Tile","text":"Tile(integrator::SciMLBase.DEIntegrator)\n\nConstructs a Tile from a SciMLBase DEIntegrator.\n\n\n\n\n\n","category":"method"},{"location":"api/tiles/#CryoGrid.Tiles.Tile-Union{Tuple{A}, Tuple{T}, Tuple{Stratigraphy, DiscretizationStrategy, Vararg{CryoGrid.Initializer, N} where N}} where {T<:CryoGrid.Numerics.StateVarCache, A<:AbstractArray}","page":"Tiles","title":"CryoGrid.Tiles.Tile","text":"Tile(\n @nospecialize(strat::Stratigraphy),\n @nospecialize(discretization_strategy::DiscretizationStrategy),\n @nospecialize(inits::CryoGrid.Initializer...);\n metadata::Dict=Dict(),\n arraytype::Type{A}=Vector,\n iip::Bool=true,\n chunk_size=nothing,\n)\n\nConstructs a Tile from the given stratigraphy and discretization strategy. arraytype keyword arg should be an array instance (of any arbitrary length, including zero, contents are ignored) that will determine the array type used for all state vectors.\n\n\n\n\n\n","category":"method"},{"location":"api/tiles/#CryoGrid.Tiles.TileState","page":"Tiles","title":"CryoGrid.Tiles.TileState","text":"TileState{TGrid,TStates,Tu,Tt,Tdt}\n\nRepresents the state of a CryoGrid Tile.\n\n\n\n\n\n","category":"type"},{"location":"api/tiles/#CryoGrid.Tiles.getstate","page":"Tiles","title":"CryoGrid.Tiles.getstate","text":"getstate(tile::Tile, u, du, t, dt=1.0)\n\nConstructs a LayerState representing the full state of layername given tile, state vectors u and du, and the time step t.\n\n\n\n\n\n","category":"function"},{"location":"api/tiles/#CryoGrid.Tiles.getstate-Tuple{SciMLBase.DEIntegrator}","page":"Tiles","title":"CryoGrid.Tiles.getstate","text":"getstate(integrator::SciMLBase.DEIntegrator)\n\nBuilds the TileState given an initialized integrator.\n\n\n\n\n\n","category":"method"},{"location":"api/tiles/#CryoGrid.Tiles.withaxes-Tuple{AbstractArray, Tile}","page":"Tiles","title":"CryoGrid.Tiles.withaxes","text":"withaxes(u::AbstractArray, ::Tile)\n\nConstructs a ComponentArray with labeled axes from the given state vector u. Assumes u to be of the same type/shape as setup.uproto.\n\n\n\n\n\n","category":"method"},{"location":"api/tiles/#CryoGrid.Tiles.@Stratigraphy-Tuple","page":"Tiles","title":"CryoGrid.Tiles.@Stratigraphy","text":"Convenience macro for defining stratigraphies with multiple subsurface layers.\n\n\n\n\n\n","category":"macro"},{"location":"dev/contributing/#contrib","page":"Contributing","title":"Contributing","text":"","category":"section"},{"location":"dev/contributing/","page":"Contributing","title":"Contributing","text":"TODO","category":"page"},{"location":"api/solvers/basic_solvers/#Basic-built-in-solvers","page":"Built-in","title":"Basic built-in solvers","text":"","category":"section"},{"location":"api/physics/hydrology/#Hydrology","page":"Hydrology","title":"Hydrology","text":"","category":"section"},{"location":"api/physics/hydrology/","page":"Hydrology","title":"Hydrology","text":"Modules = [Hydrology]\nPrivate = false\nOrder = [:type, :function, :macro]","category":"page"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.BucketScheme","page":"Hydrology","title":"CryoGrid.Hydrology.BucketScheme","text":"BucketScheme <: WaterFlow\n\n\"Bucket\" water scheme for downward advective flow due to gravity.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.DampedET","page":"Hydrology","title":"CryoGrid.Hydrology.DampedET","text":"DampedET{Tftr,Tfev,Tdtr,Tdev}\n\nCorresponds to evapotranspiration scheme 2 described in section 2.2.4 of Westermann et al. (2022).\n\n\n\n\n\n","category":"type"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.Evapotranspiration","page":"Hydrology","title":"CryoGrid.Hydrology.Evapotranspiration","text":"Evapotranspiration\n\nBase type for parameterizations of evapotranspiration (ET).\n\n\n\n\n\n","category":"type"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.HydraulicProperties","page":"Hydrology","title":"CryoGrid.Hydrology.HydraulicProperties","text":"HydraulicProperties\n\nDefault material hydraulic properties.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.NoFlow","page":"Hydrology","title":"CryoGrid.Hydrology.NoFlow","text":"NoFlow <: WaterFlow\n\nRepresents a zero flow scheme \n\n\n\n\n\n","category":"type"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.WaterBalance","page":"Hydrology","title":"CryoGrid.Hydrology.WaterBalance","text":"WaterBalance{TFlow<:WaterFlow,TET<:Union{Nothing,Evapotranspiration},Tdt,Taux,TProp} <: CryoGrid.SubSurfaceProcess\n\nRepresents subsurface water transport processes.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.WaterBalanceProperties","page":"Hydrology","title":"CryoGrid.Hydrology.WaterBalanceProperties","text":"WaterBalanceProperties\n\nNumerical constants shared across water balance implementations.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.WaterFlow","page":"Hydrology","title":"CryoGrid.Hydrology.WaterFlow","text":"WaterFlow\n\nBase type for different formulations of water flow in WaterBalance.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.WaterTableInitializer","page":"Hydrology","title":"CryoGrid.Hydrology.WaterTableInitializer","text":"WaterTableInitializer <: VarInitializer{:sat}\n\nSimple, piecewise constant initializer for saturation state that takes a surface-level saturation sat0 and water table depth z_tab and produces a two-segment, piecewise constant profile with the saturation level set to (sat0 + 1.0) / 2 from the halfway point down to the water table.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.hydraulicconductivity!-Tuple{SubSurface, WaterBalance, Any}","page":"Hydrology","title":"CryoGrid.Hydrology.hydraulicconductivity!","text":"hydraulicconductivity!(sub::SubSurface, water::WaterBalance, state)\n\nComputes hydraulic conductivities for the given subsurface layer and water balance scheme.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.hydraulicproperties-Tuple{SubSurface}","page":"Hydrology","title":"CryoGrid.Hydrology.hydraulicproperties","text":"hydraulicproperties(::SubSurface)\n\nRetrieves the hydraulic properties from the given subsurface layer.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.maxwater-Tuple{SubSurface, WaterBalance}","page":"Hydrology","title":"CryoGrid.Hydrology.maxwater","text":"maxwater(sub::SubSurface, ::WaterBalance) \nmaxwater(sub::SubSurface, water::WaterBalance, state)\nmaxwater(::SubSurface, ::WaterBalance, state, i)\n\nReturns the maximum volumetric water content (saturation point) for grid cell i.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.minwater-Tuple{SubSurface, WaterBalance}","page":"Hydrology","title":"CryoGrid.Hydrology.minwater","text":"minwater(::SubSurface, water::WaterBalance)\nminwater(::SubSurface, water::WaterBalance, state, i)\n\nReturns the minimum volumetric water content (typically field capacity for simplified schemes) for grid cell i. Defaults to zero.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.watercontent!-Tuple{SubSurface, WaterBalance, Any}","page":"Hydrology","title":"CryoGrid.Hydrology.watercontent!","text":"watercontent!(::SubSurface, ::WaterBalance, state)\n\nComputes the volumetric water content from current saturation or pressure state.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.watercontent-Tuple{SubSurface, Any}","page":"Hydrology","title":"CryoGrid.Hydrology.watercontent","text":"watercontent(::SubSurface, state)\nwatercontent(::SubSurface, state, i)\n\nReturns the total water content θwi from the given subsurface layer and/or current state.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.waterdensity-Tuple{SubSurface}","page":"Hydrology","title":"CryoGrid.Hydrology.waterdensity","text":"waterdensity(sub::SubSurface)\n\nRetrieves the density of water ρw from the given SubSurface layer. Default implementation assumes that WaterBalance is provided as a field water on sub; this can of course, however, be overridden.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/salt/#Salt","page":"Salt","title":"Salt","text":"","category":"section"},{"location":"api/physics/salt/","page":"Salt","title":"Salt","text":"Modules = [CryoGrid.Salt]\nPrivate = false\nOrder = [:type, :function, :macro]","category":"page"},{"location":"api/physics/snow/#Snow","page":"Snow","title":"Snow","text":"","category":"section"},{"location":"api/physics/snow/","page":"Snow","title":"Snow","text":"Modules = [Snow]\nPrivate = false\nOrder = [:type, :function, :macro]","category":"page"},{"location":"api/physics/snow/#CryoGrid.Snow.SnowBC","page":"Snow","title":"CryoGrid.Snow.SnowBC","text":"SnowBC\n\nType alias for any BoundaryProcess compatible with SnowMassBalance.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/snow/#CryoGrid.Snow.SnowMassBalance","page":"Snow","title":"CryoGrid.Snow.SnowMassBalance","text":"SnowMassBalance{TAcc,TAbl} <: CryoGrid.SubSurfaceProcess\n\nSubsurface process for snow layers governing how snow is accumulated and ablated.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/snow/#CryoGrid.Snow.Snowpack","page":"Snow","title":"CryoGrid.Snow.Snowpack","text":"Snowpack{Tpara<:SnowpackParameterization,Tmass<:SnowMassBalance,Theat<:HeatBalance,Twater<:WaterBalance,Taux} <: CryoGrid.SubSurface\n\nGeneric representation of a snowpack \"subsurface\" layer.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/snow/#CryoGrid.Snow.Snowpack-Tuple{CryoGrid.Snow.SnowpackParameterization}","page":"Snow","title":"CryoGrid.Snow.Snowpack","text":"Snowpack(para::SnowpackParameterization; kwargs...)\n\nConvenience constructor that accepts the parameterization as a positional argument.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/snow/#CryoGrid.Snow.ablation!-Tuple{Top, SnowBC{T} where SnowMassBalance<:T<:SubSurfaceProcess, Snowpack, SnowMassBalance, Any, Any}","page":"Snow","title":"CryoGrid.Snow.ablation!","text":"ablation!(::Top, ::SnowBC, ::Snowpack, ::SnowMassBalance, stop, ssnow)\n\nComputes snow mass balance fluxes due to ablation (e.g. snow melt).\n\n\n\n\n\n","category":"method"},{"location":"api/physics/snow/#CryoGrid.Snow.accumulation!-Tuple{Top, SnowBC{T} where SnowMassBalance<:T<:SubSurfaceProcess, Snowpack, SnowMassBalance, Any, Any}","page":"Snow","title":"CryoGrid.Snow.accumulation!","text":"accumulation!(::Top, ::SnowBC, ::Snowpack, ::SnowMassBalance, stop, ssnow)\n\nComputes snow mass balance fluxes due to accumulation (e.g. snowfall).\n\n\n\n\n\n","category":"method"},{"location":"api/physics/snow/#CryoGrid.Snow.snowdensity-Tuple{Snowpack, Any}","page":"Snow","title":"CryoGrid.Snow.snowdensity","text":"snowdensity(::Snowpack, state)\n\nRetrieve the current snow density.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/snow/#CryoGrid.Snow.snowdepth-Tuple{Snowpack, SnowMassBalance, Any}","page":"Snow","title":"CryoGrid.Snow.snowdepth","text":"snowdepth(::Snowpack, ::SnowMassBalance, state)\n\nRetrieve the current snow depth.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/snow/#CryoGrid.Snow.snowfall-Tuple{SnowBC{T} where SnowMassBalance<:T<:SubSurfaceProcess, Any}","page":"Snow","title":"CryoGrid.Snow.snowfall","text":"snowfall(::SnowBC, state)\n\nRetrieves the current snowfall flux for the given SnowBC. Defaults to state.jw_snow.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/soils/#Soils","page":"Soils","title":"Soils","text":"","category":"section"},{"location":"api/physics/soils/","page":"Soils","title":"Soils","text":"Modules = [Soils]\nPrivate = false\nOrder = [:type, :function, :macro]","category":"page"},{"location":"api/physics/soils/#CryoGrid.Soils.AbstractGround","page":"Soils","title":"CryoGrid.Soils.AbstractGround","text":"AbstractGround{Tpara<:GroundParameterization,Theat<:Optional{HeatBalance},Twater<:Optional{WaterBalance}} <: SubSurface\n\nBase type for all ground layers defining heat and water balance schemes.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/soils/#CryoGrid.Soils.Ground","page":"Soils","title":"CryoGrid.Soils.Ground","text":"Ground{Tpara,Theat<:Optional{HeatBalance},Twater<:Optional{WaterBalance},Taux} <: Soil{Tpara,Theat,Twater}\n\nGeneric representation of a Ground layer with material parameterization para.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/soils/#CryoGrid.Soils.Ground-Tuple{CryoGrid.Numerics.Profile{N, IT, VT} where {N, IT<:(Tuple{Vararg{T, N}} where T), VT<:Tuple{Vararg{SoilParameterization, N}}}}","page":"Soils","title":"CryoGrid.Soils.Ground","text":"Ground(soilprofile::SoilProfile; kwargs...)\n\n\n\n\n\n","category":"method"},{"location":"api/physics/soils/#CryoGrid.Soils.Heterogeneous","page":"Soils","title":"CryoGrid.Soils.Heterogeneous","text":"Heterogeneous{V,N,D,Taux} <: SoilParameterization\n\nSpecial SoilParameterization which wraps a Profile of another soil parameterization type to indicate that it should be heterogeneous with over depth.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/soils/#CryoGrid.Soils.MineralOrganic","page":"Soils","title":"CryoGrid.Soils.MineralOrganic","text":"MineralOrganic{Tpor,Tsat,Torg} <: SoilParameterization\n\nRepresents a simple organic/mineral soil mixutre in terms of its characteristic fractions: i.e. natural porosity, saturation, and organic solid fraction. This is the standard CryoGrid representation of a discrete soil volume.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/soils/#CryoGrid.Soils.RichardsEq","page":"Soils","title":"CryoGrid.Soils.RichardsEq","text":"RichardsEq{Tform<:RichardsEqFormulation,Tswrc<:SWRC,Taux,TΩ} <: Hydrology.WaterFlow\n\nThe Richardson-Richards equation describes the flow of water in porous media under unsaturated condition.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/soils/#CryoGrid.Soils.Soil","page":"Soils","title":"CryoGrid.Soils.Soil","text":"Soil{Tpara,Theat,Twater}\n\nType alias for any AbstractGround layer with parameterization of type SoilParameterization.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/soils/#CryoGrid.Soils.SoilParameterization","page":"Soils","title":"CryoGrid.Soils.SoilParameterization","text":"SoilParameterization\n\nBase type for parameterizations of soil consituents.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/soils/#CryoGrid.Soils.SoilProfile","page":"Soils","title":"CryoGrid.Soils.SoilProfile","text":"SoilProfile{N,IT,VT} = Profile{N,IT,VT} where {N,IT<:NTuple{N},VT<:NTuple{N,SoilParameterization}}\n\nAlias for depthwise Profile where the values are SoilParameterization types.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/soils/#CryoGrid.Soils.SoilProfile-Tuple{Vararg{Pair{var\"#s207\", var\"#s206\"} where {var\"#s207\"<:(Quantity{T, 𝐋, U} where {T, U<:(Unitful.FreeUnits{N, 𝐋, nothing} where N)}), var\"#s206\"<:SoilParameterization}, N} where N}","page":"Soils","title":"CryoGrid.Soils.SoilProfile","text":"SoilProfile(pairs::Pair{<:DistQuantity,<:SoilParameterization}...)\n\nAlias for Profile(pairs...) specific for SoilProfiles.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/soils/#CryoGrid.Soils.SoilTexture","page":"Soils","title":"CryoGrid.Soils.SoilTexture","text":"SoilTexture{Tsand,Tsilt,Tclay}\n\nRepresents soil \"texture\" as a simple mixture of sand, silt, and clay.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/soils/#CryoGrid.Soils.mineral-Tuple{Soil{Tpara, Theat, Twater} where {Tpara<:SoilParameterization, Theat<:Union{Nothing, HeatBalance}, Twater<:Union{Nothing, WaterBalance}}, Any, Any}","page":"Soils","title":"CryoGrid.Soils.mineral","text":"mineral(soil::Soil, state, i)\nmineral(soil::Soil, state)\nmineral(soil::Soil)\n\nRetrieves the volumetric mineral content for the given layer at grid cell i, if provided.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/soils/#CryoGrid.Soils.organic-Tuple{Soil{Tpara, Theat, Twater} where {Tpara<:SoilParameterization, Theat<:Union{Nothing, HeatBalance}, Twater<:Union{Nothing, WaterBalance}}, Any, Any}","page":"Soils","title":"CryoGrid.Soils.organic","text":"organic(soil::Soil, state, i)\norganic(soil::Soil, state)\norganic(soil::Soil)\n\nRetrieves the volumetric organic content for the given layer at grid cell i, if provided.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/soils/#CryoGrid.Soils.porosity-Tuple{Soil{Tpara, Theat, Twater} where {Tpara<:SoilParameterization, Theat<:Union{Nothing, HeatBalance}, Twater<:Union{Nothing, WaterBalance}}, Any, Any}","page":"Soils","title":"CryoGrid.Soils.porosity","text":"porosity(soil::Soil, state, i)\nporosity(soil::Soil, state)\nporosity(soil::Soil)\n\nRetrieves the porosity for the given layer at grid cell i, if provided.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/seb/#Surface-Energy-Balance","page":"Surface Energy Balance","title":"Surface Energy Balance","text":"","category":"section"},{"location":"api/physics/seb/","page":"Surface Energy Balance","title":"Surface Energy Balance","text":"Modules = [CryoGrid.Surface]\nPrivate = false\nOrder = [:type, :function, :macro]","category":"page"},{"location":"api/physics/seb/#CryoGrid.Surface.SurfaceEnergyBalance","page":"Surface Energy Balance","title":"CryoGrid.Surface.SurfaceEnergyBalance","text":"SurfaceEnergyBalance{TSolution,TStabFun,TPara,F} <: BoundaryProcess{HeatBalance}\n\nSurface energy balance upper boundary condition.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/seb/#CryoGrid.Surface.SurfaceWaterBalance","page":"Surface Energy Balance","title":"CryoGrid.Surface.SurfaceWaterBalance","text":"SurfaceWaterBalance{TR,TS} <: BoundaryProcess{Union{WaterBalance, SnowMassBalance}}\n\nThe SurfaceWaterBalance represents the closure of the water balance at the surface and acts as both a Neumann-type upper boundary condition for snow and water fluxes as well as an accountant for the water mass balance at the surface.\n\n\n\n\n\n","category":"type"},{"location":"examples/heat_freeW_lite_implicit/","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"EditURL = \"../../../examples/heat_freeW_lite_implicit.jl\"","category":"page"},{"location":"examples/heat_freeW_lite_implicit/#example7","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"","category":"section"},{"location":"examples/heat_freeW_lite_implicit/","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"This example is very similar to Example 1 but uses the fast implicit CryoGridLite solver of Langer et al. 2023.","category":"page"},{"location":"examples/heat_freeW_lite_implicit/","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"Make sure to explicitly import the LiteImplicit submodule which has the relevant solver types.","category":"page"},{"location":"examples/heat_freeW_lite_implicit/","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"using CryoGrid\nusing CryoGrid.LiteImplicit","category":"page"},{"location":"examples/heat_freeW_lite_implicit/","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"Load forcings and build stratigraphy like before.","category":"page"},{"location":"examples/heat_freeW_lite_implicit/","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"forcings = loadforcings(CryoGrid.Presets.Forcings.Samoylov_ERA_MkL3_CCSM4_long_term);\nsoilprofile = SoilProfile(\n 0.0u\"m\" => MineralOrganic(por=0.80,sat=1.0,org=0.75),\n 0.1u\"m\" => MineralOrganic(por=0.80,sat=1.0,org=0.25),\n 0.4u\"m\" => MineralOrganic(por=0.55,sat=1.0,org=0.25),\n 3.0u\"m\" => MineralOrganic(por=0.50,sat=1.0,org=0.0),\n 10.0u\"m\" => MineralOrganic(por=0.30,sat=1.0,org=0.0),\n)\nz_top = -2.0u\"m\"\nz_bot = 1000.0u\"m\"\nupperbc = TemperatureBC(forcings.Tair, NFactor())\nssinit = ThermalSteadyStateInit(T0=-15.0u\"°C\")\nheatop = Heat.EnthalpyImplicit()\nfreezecurve = FreeWater()\nheat = HeatBalance(heatop; freezecurve)\nsoil_layers = map(para -> Ground(para; heat), soilprofile)\nstrat = Stratigraphy(\n z_top => Top(upperbc),\n soil_layers,\n z_bot => Bottom(GeothermalHeatFlux(0.053u\"W/m^2\"))\n);\nmodelgrid = CryoGrid.Presets.DefaultGrid_2cm\ntile = Tile(strat, modelgrid, ssinit);\nnothing #hide","category":"page"},{"location":"examples/heat_freeW_lite_implicit/","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"Since the solver can take daily timesteps, we can easily specify longer simulation time spans at minimal cost. Here we specify a time span of 20 years.","category":"page"},{"location":"examples/heat_freeW_lite_implicit/","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"tspan = (DateTime(2000,1,1), DateTime(2020,1,1))\nu0, du0 = initialcondition!(tile, tspan);\nprob = CryoGridProblem(tile, u0, tspan, saveat=24*3600.0, savevars=(:T,))\nsol = @time solve(prob, LiteImplicitEuler(), dt=24*3600.0)\nout = CryoGridOutput(sol)","category":"page"},{"location":"examples/heat_freeW_lite_implicit/","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"Plot the results!","category":"page"},{"location":"examples/heat_freeW_lite_implicit/","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"import Plots\nzs = [5,10,15,20,25,30,40,50,100,500,1000,5000]u\"cm\"\ncg = Plots.cgrad(:copper,rev=true);\nPlots.plot(out.T[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Temperature\", title=\"\", leg=false, dpi=150)","category":"page"},{"location":"examples/heat_freeW_lite_implicit/","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"CryoGridLite can also be embedded into integrators from OrdinaryDiffEq.jl via the NLCGLite nonlinear solver interface. Note that these sovers generally will not be faster (in execution time) but may be more stable in some cases. Adaptive timestepping can be employed by removing the adaptive=false argument.","category":"page"},{"location":"examples/heat_freeW_lite_implicit/","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"using OrdinaryDiffEq\nsol2 = @time solve(prob, ImplicitEuler(nlsolve=NLCGLite()), adaptive=false, dt=24*3600.0, saveat=24*3600);\nnothing #hide","category":"page"},{"location":"examples/heat_freeW_lite_implicit/","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"","category":"page"},{"location":"examples/heat_freeW_lite_implicit/","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"This page was generated using Literate.jl.","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"EditURL = \"../../../examples/heat_simple_autodiff_grad.jl\"","category":"page"},{"location":"examples/heat_simple_autodiff_grad/#example10","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"","category":"section"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"This example demonstrates how to parameterize and differentiate a simulation with two parameters (summer and winter n-factors) using forward-mode automatic simulation.","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"TODO: add more detail/background","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"Set up forcings and boundary conditions similarly to other examples:","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"using CryoGrid\nforcings = loadforcings(CryoGrid.Presets.Forcings.Samoylov_ERA_obs_fitted_1979_2014_spinup_extended_2044);\nsoilprofile, tempprofile = CryoGrid.Presets.SamoylovDefault\ngrid = CryoGrid.Presets.DefaultGrid_5cm\ninitT = initializer(:T, tempprofile)\ntile = CryoGrid.Presets.SoilHeatTile(\n :T,\n TemperatureBC(forcings.Tair, NFactor(nf=Param(0.5), nt=Param(0.9))),\n GeothermalHeatFlux(0.053u\"W/m^2\"),\n soilprofile,\n initT;\n freezecurve=PainterKarra(),\n grid=grid\n)\ntspan = (DateTime(2010,10,30),DateTime(2011,10,30))\nu0, du0 = @time initialcondition!(tile, tspan);\nnothing #hide","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"Collect model parameters","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"p = CryoGrid.parameters(tile)","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"Create the CryoGridProblem.","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"prob = CryoGridProblem(tile, u0, tspan, p, saveat=24*3600.0);\nnothing #hide","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"Solve the forward problem with default parameter settings:","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"sol = @time solve(prob)\nout = CryoGridOutput(sol)","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"Define a \"loss\" function; here we'll just take the mean over the final temperature field.","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"using Statistics\nfunction loss(p)\n local u0, _ = initialcondition!(tile, tspan, p)\n local prob = CryoGridProblem(tile, u0, tspan, p, saveat=24*3600.0)\n local sol = solve(prob, CGEuler());\n local out = CryoGridOutput(sol)\n return mean(ustrip.(out.T[:,end]))\nend","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"ForwardDiff provides tools for forward-mode automatic differentiation.","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"using ForwardDiff\npvec = vec(p)","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"Compute gradient with forward diff:","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"grad = @time ForwardDiff.gradient(loss, pvec)","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"This page was generated using Literate.jl.","category":"page"},{"location":"examples/heat_sfcc_samoylov/","page":"Soil heat with SFCC","title":"Soil heat with SFCC","text":"EditURL = \"../../../examples/heat_sfcc_samoylov.jl\"","category":"page"},{"location":"examples/heat_sfcc_samoylov/#example3","page":"Soil heat with SFCC","title":"Soil heat with SFCC","text":"","category":"section"},{"location":"examples/heat_sfcc_samoylov/","page":"Soil heat with SFCC","title":"Soil heat with SFCC","text":"In this example, we use the preset SoilHeatTile to construct a Tile consisting of a soil column with heat conduction forced using air temperatures from Samoylov Island. We use the SFCC formulation of Painter and Karra (2014). For the purpose of demonstration, we use the apparent heat capacity form of the heat equation in this example (i.e. Heat.Diffusion1D(:T)).","category":"page"},{"location":"examples/heat_sfcc_samoylov/","page":"Soil heat with SFCC","title":"Soil heat with SFCC","text":"using CryoGrid","category":"page"},{"location":"examples/heat_sfcc_samoylov/","page":"Soil heat with SFCC","title":"Soil heat with SFCC","text":"First we set up the model:","category":"page"},{"location":"examples/heat_sfcc_samoylov/","page":"Soil heat with SFCC","title":"Soil heat with SFCC","text":"forcings = loadforcings(CryoGrid.Presets.Forcings.Samoylov_ERA5_fitted_daily_1979_2020);\ngrid = CryoGrid.Presets.DefaultGrid_5cm\nsoilprofile, tempprofile = CryoGrid.Presets.SamoylovDefault\ninitT = initializer(:T, tempprofile)\nsfcc = PainterKarra(swrc=VanGenuchten(α=0.1, n=2.0))\nupperbc = TemperatureBC(forcings.Tair, NFactor(nf=0.6))\nlowerbc = GeothermalHeatFlux(0.053u\"W/m^2\")\ntile = CryoGrid.Presets.SoilHeatTile(upperbc, lowerbc, soilprofile, initT; grid=grid, freezecurve=sfcc)\ntspan = (DateTime(2010,10,30),DateTime(2011,10,30))\nu0, du0 = initialcondition!(tile, tspan)\nprob = CryoGridProblem(tile, u0, tspan, saveat=3*3600.0, savevars=(:T,));\nnothing #hide","category":"page"},{"location":"examples/heat_sfcc_samoylov/","page":"Soil heat with SFCC","title":"Soil heat with SFCC","text":"... then solve it with the built-in forward Euler integrator.","category":"page"},{"location":"examples/heat_sfcc_samoylov/","page":"Soil heat with SFCC","title":"Soil heat with SFCC","text":"sol = @time solve(prob);\nout = CryoGridOutput(sol)","category":"page"},{"location":"examples/heat_sfcc_samoylov/","page":"Soil heat with SFCC","title":"Soil heat with SFCC","text":"Finally, plot the resulting temperatures.","category":"page"},{"location":"examples/heat_sfcc_samoylov/","page":"Soil heat with SFCC","title":"Soil heat with SFCC","text":"import Plots\nzs = [5,10,15,20,25,30,40,50,100,500]u\"cm\"\nDiagnostics.plot_at_depths(:T, out, zs, ylabel=\"Temperature (°C)\")","category":"page"},{"location":"examples/heat_sfcc_samoylov/","page":"Soil heat with SFCC","title":"Soil heat with SFCC","text":"","category":"page"},{"location":"examples/heat_sfcc_samoylov/","page":"Soil heat with SFCC","title":"Soil heat with SFCC","text":"This page was generated using Literate.jl.","category":"page"},{"location":"api/io/#InputOutput","page":"InputOutput","title":"InputOutput","text":"","category":"section"},{"location":"api/io/","page":"InputOutput","title":"InputOutput","text":"This module provides types and utilities for reading input files (i.e. parameters and forcings) as well as saving model outputs.","category":"page"},{"location":"api/io/","page":"InputOutput","title":"InputOutput","text":"Modules = [CryoGrid.InputOutput]\nPrivate = false\nOrder = [:type, :function, :macro]","category":"page"},{"location":"api/io/#CryoGrid.InputOutput.ConstantForcing","page":"InputOutput","title":"CryoGrid.InputOutput.ConstantForcing","text":" ConstantForcing{unit,T} <: Forcing{unit,T}\n\nSimple Forcing type that just returns a constant value. This type is primarily intended for writing tests but could still be used in applications if necessary.\n\n\n\n\n\n","category":"type"},{"location":"api/io/#CryoGrid.InputOutput.CryoGridOutput","page":"InputOutput","title":"CryoGrid.InputOutput.CryoGridOutput","text":"CryoGridOutput{TSol}\n\nHelper type that stores the raw output from a CryoGrid run along with DimArray views of all logged variables. CryoGridOutput overrides Base.getproperty to allow for direct dot-syntax access of state variables. For example, if your model has a grid variable named T, out.T returns a DimArray with indexed time and depth axes. For OrdinaryDiffEq.jl outputs, the ODESolution can be accessed via out.sol, or for convenience, the continuous solution at time t can be computed via out(t) which is equivalent to withaxes(out.sol(t)).\n\n\n\n\n\n","category":"type"},{"location":"api/io/#CryoGrid.InputOutput.CryoGridOutput-Tuple{Real}","page":"InputOutput","title":"CryoGrid.InputOutput.CryoGridOutput","text":"Evaluates the continuous solution at time t.\n\n\n\n\n\n","category":"method"},{"location":"api/io/#CryoGrid.InputOutput.CryoGridOutput-Tuple{SciMLBase.AbstractODESolution, Tuple{DateTime, DateTime}}","page":"InputOutput","title":"CryoGrid.InputOutput.CryoGridOutput","text":"CryoGridOutput(sol::TSol, tspan::NTuple{2,Float64}=(-Inf,Inf)) where {TSol<:SciMLBase.AbstractODESolution}\n\nConstructs a CryoGridOutput from the given ODESolution. Optional argument tspan restricts the time span of the output.\n\n\n\n\n\n","category":"method"},{"location":"api/io/#CryoGrid.InputOutput.CryoGridParams","page":"InputOutput","title":"CryoGrid.InputOutput.CryoGridParams","text":"CryoGridParams{T,TM} <: DenseArray{T,1}\n\nWraps a ModelParameters.Model parameter handler for CryoGrid types. It is recommended not to use this type directly in math or linear algebra operations but rather to use Base.values to obtain a normal array of parameter values.\n\n\n\n\n\n","category":"type"},{"location":"api/io/#CryoGrid.InputOutput.CryoGridParams-Tuple{Any}","page":"InputOutput","title":"CryoGrid.InputOutput.CryoGridParams","text":"CryoGridParams(obj)\n\nConstructs a modelParameters.Model wrapped with CryoGridParams from obj. If full_metadata is true, additonal fields for nested Parameterization types will be added.\n\n\n\n\n\n","category":"method"},{"location":"api/io/#CryoGrid.InputOutput.Forcing","page":"InputOutput","title":"CryoGrid.InputOutput.Forcing","text":" Forcing{unit,T}\n\nAbstract type representing a generic external forcing term.\n\n\n\n\n\n","category":"type"},{"location":"api/io/#CryoGrid.InputOutput.ForcingFormat","page":"InputOutput","title":"CryoGrid.InputOutput.ForcingFormat","text":"Represents an externally specified format for forcing inputs. IO functions should dispatch on specific types T<:ForcingFormat that they implement.\n\n\n\n\n\n","category":"type"},{"location":"api/io/#CryoGrid.InputOutput.ForcingFormatJSON","page":"InputOutput","title":"CryoGrid.InputOutput.ForcingFormatJSON","text":"JSON forcing input format (from CryoGridLite) with specified version indicator.\n\n\n\n\n\n","category":"type"},{"location":"api/io/#CryoGrid.InputOutput.ForcingFormatNCD","page":"InputOutput","title":"CryoGrid.InputOutput.ForcingFormatNCD","text":"NetCDF forcing input format.\n\n\n\n\n\n","category":"type"},{"location":"api/io/#CryoGrid.InputOutput.Forcings","page":"InputOutput","title":"CryoGrid.InputOutput.Forcings","text":" Forcings{names,TF,TMeta}\n\nGeneric container for forcing types with optional metadata.\n\n\n\n\n\n","category":"type"},{"location":"api/io/#CryoGrid.InputOutput.InterpolatedForcing","page":"InputOutput","title":"CryoGrid.InputOutput.InterpolatedForcing","text":" InterpolatedForcing{unit,T,TI}\n\nForcing data provided by a discrete time series of data.\n\n\n\n\n\n","category":"type"},{"location":"api/io/#CryoGrid.InputOutput.InterpolatedForcing-Tuple{Number}","page":"InputOutput","title":"CryoGrid.InputOutput.InterpolatedForcing","text":"Get interpolated forcing value at t seconds from t0.\n\n\n\n\n\n","category":"method"},{"location":"api/io/#CryoGrid.InputOutput.ParamsJSON","page":"InputOutput","title":"CryoGrid.InputOutput.ParamsJSON","text":"JSON parameter input format (from CryoGridLite). Not yet implemented.\n\n\n\n\n\n","category":"type"},{"location":"api/io/#CryoGrid.InputOutput.ParamsYAML","page":"InputOutput","title":"CryoGrid.InputOutput.ParamsYAML","text":"YAML parameter input format matching that of the CryoGrid community model. Not yet implemented.\n\n\n\n\n\n","category":"type"},{"location":"api/io/#CryoGrid.InputOutput.TimeVaryingForcing","page":"InputOutput","title":"CryoGrid.InputOutput.TimeVaryingForcing","text":" TimeVaryingForcing{unit,T} <: Forcing{unit,T}\n\nSimple Forcing type that evaluates a given function f(t) of where t is the current time.\n\n\n\n\n\n","category":"type"},{"location":"api/io/#CryoGrid.InputOutput.TransformedForcing","page":"InputOutput","title":"CryoGrid.InputOutput.TransformedForcing","text":" TransformedForcing(transformed_unit,orig_unit,TF,T,TO<:Forcing{orig_unit,T}) <: Forcing{transformed_unit,T}\n\nWraps another Forcing and applies an arbitrary transformation f when evaluated. The transformed unit can either be automatically determined on construction or specified directly.\n\n\n\n\n\n","category":"type"},{"location":"api/io/#CryoGrid.InputOutput.loadforcings-Tuple{String}","page":"InputOutput","title":"CryoGrid.InputOutput.loadforcings","text":"loadforcings(filename::String)::Forcings\nloadforcings(resource::Resource; outdir=DEFAULT_FORCINGS_DIR)::Forcings\nloadforcings([format::ForcingFormat], filename::String; outdir=DEFAULT_FORCINGS_DIR)::Forcings\n\nLoads forcing data from the given file according to the format specified by format. By default, the forcing format is automatically detected via detectformat. Returns a Forcings struct containing all forcing data and metadata \n\n\n\n\n\n","category":"method"},{"location":"api/io/#CryoGrid.InputOutput.time_derivative_forcing-Union{Tuple{InterpolatedForcing{unit, T, TI} where {T, TI<:(Interpolations.AbstractInterpolation{T, N, IT} where {N, IT<:Union{Tuple{Vararg{Interpolations.InterpolationType, N} where N}, Interpolations.InterpolationType}})}}, Tuple{unit}, Tuple{InterpolatedForcing{unit, T, TI} where {T, TI<:(Interpolations.AbstractInterpolation{T, N, IT} where {N, IT<:Union{Tuple{Vararg{Interpolations.InterpolationType, N} where N}, Interpolations.InterpolationType}})}, Symbol}} where unit","page":"InputOutput","title":"CryoGrid.InputOutput.time_derivative_forcing","text":"time_derivative_forcing(\n f::InterpolatedForcing{unit},\n new_name::Symbol;\n interp=Numerics.Linear()\n) where {unit}\n\nComputes the finite difference time derivative of the given InterpolatedForcing time series and returns a new forcing with units [unit].s⁻¹\n\n\n\n\n\n","category":"method"},{"location":"manual/coupling/#coupling","page":"Coupling layers and processes","title":"Coupling","text":"","category":"section"},{"location":"manual/coupling/","page":"Coupling layers and processes","title":"Coupling layers and processes","text":"TODO","category":"page"},{"location":"manual/overview/#overview","page":"Overview","title":"Overview","text":"","category":"section"},{"location":"manual/overview/#Setting-up-a-model","page":"Overview","title":"Setting up a model","text":"","category":"section"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"DocTestSetup = quote\n using CryoGrid\nend","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"At the highest level, a model in CryoGrid.jl is defined by one or more Tiles each consisting of a Grid and a Stratigraphy, constructed top-down from individual Layers, each of which has one or more Processes. Each layer in the Stratigraphy is assigned a depth, which then aligns it with the Grid. All models must consist of at least three layers/nodes: Top and Bottom layers with corresponding boundary conditions, as well as one or more SubSurface layers. Here we define a simple three-layer model (or one-layer, exlcuding the boundaries) with a single sub-surface process, i.e. HeatBalance (heat conduction):","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"# ... load forcings, set up profiles, etc.\n# see examples/heat_vgfc_seb_saoylov_custom.jl for more details\nstrat = Stratigraphy(\n -2.0u\"m\" => Top(SurfaceEnergyBalance(Tair,pr,q,wind,Lin,Sin,z)),\n 0.0u\"m\" => Ground(soilprofile, HeatBalance(:H; freezecurve=DallAmico())),\n 1000.0u\"m\" => Bottom(GeothermalHeatFlux(0.053u\"J/s/m^2\"))\n);\ngrid = CryoGrid.Presets.DefaultGrid_5cm\n# define initial conditions for temperature using a given profile;\n# The default initializer linearly interpolates between profile points.\ninitT = initializer(:T, tempprofile)\ntile = Tile(strat, grid, initT);","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"This model can then be used to construct a CryoGridProblem:","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"tspan = (DateTime(2010,10,30),DateTime(2011,10,30))\np = parameters(tile)\nu0 = initialcondition!(tile, tspan, p, initT)\nprob = CryoGridProblem(tile, u0, tspan, p, saveat=24*3600.0, savevars=(:T,)) # produces an ODEProblem with problem type CryoGridODEProblem","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"It can then be solved/integrated using the solve function (from DiffEqBase and OrdinaryDiffEq):","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"# solve and construct CryoGridOutput from solution\nsol = @time solve(prob, saveat=24*3600.0, progress=true);\nout = CryoGridOutput(sol)","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"The resulting CryoGridOutput type provides DimArrays containing the model outputs over time and space:","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"julia> out.T\n278×366 DimArray{Float64,2} with dimensions: \n Z: Quantity{Float64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}[0.01 m, 0.03 m, …, 850.0 m, 950.0 m] Sampled: Ordered Irregular Points,\n Ti (Time): DateTime[2010-10-30T00:00:00, …, 2011-10-30T00:00:00] Sampled: Ordered Irregular Points","category":"page"},{"location":"manual/overview/#Defining-model-behavior","page":"Overview","title":"Defining model behavior","text":"","category":"section"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"Notice that, in the example above, it is types such as Ground, HeatBalance, DallAmico, etc. that specify which components the model should use. These components are defined by adding method dispatches to the CryoGrid interface methods. State variables are declared via the variables method, e.g:","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"variables(soil::Soil, heat::HeatBalance{<:EnthalpyBased}) = (\n Prognostic(:H, OnGrid(Cells), u\"J/m^3\"),\n Diagnostic(:T, OnGrid(Cells), u\"°C\"),\n Diagnostic(:C, OnGrid(Cells), u\"J//K*/m^3\"),\n Diagnostic(:∂H∂T, OnGrid(Cells), u\"J/K/m^3\"),\n Diagnostic(:k, OnGrid(Edges), u\"W/m/K\"),\n Diagnostic(:kc, OnGrid(Cells), u\"W//m/K\"),\n)","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"When the HeatBalance process is assigned to a Soil layer, Tile will invoke this method and create state variables corresponding to each Var. Prognostic variables are assigned derivatives (in this case, dH, since H is the prognostic state variable) and integrated over time. Diagnostic variables provide in-place caches for derived/intermediary state variables.","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"Each variable definition consists of a name (a Julia Symbol), a type, and a shape. For variables discretized on the grid, the shape is specified by OnGrid, which will generate an array of the appropriate size when the model is compiled. The arguments Cells and Edges specify whether the variable should be defined on the grid cells or edges respecitvely.","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"The real work finally happens in computediagnostic! and computefluxes!, the latter of which should be used to compute the time derivatives (here dH). interact! defines the behavior at the boundaries and should be used to compute the derivatives (and any other necessary values) at the interface between layers.","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"We can take as an example the implementation of computefluxes! for enthalpy-based heat conduction (note that jH is a diagnostic variable representing the energy flux over each cell edge):","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"function CryoGrid.computefluxes!(::SubSurface, ::HeatBalance{<:FreezeCurve,<:EnthalpyBased}, state)\n Δk = Δ(state.grid) # cell sizes\n ΔT = Δ(cells(state.grid)) # midpoint distances\n # compute internal fluxes and non-linear diffusion assuming boundary fluxes have been set\n nonlineardiffusion!(state.dH, state.jH, state.T, ΔT, state.k, Δk)\n return nothing\nend","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"warning: Warning\nPrognostic state variables like H in the example above should not be directly modified in the model code. They should only be modified by the calling solver/integrator. This is especially important when using higher order or implicit integrators as unexpected changes to prognostic state may destroy the accuracy of their internal interpolant. For modeling discontinuities, use Events instead.","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"Note that state is (typically) of type LayerState with properties corresponding to the state variables declared by the variables function for Soil and HeatBalance. Additionally, output arrays for the time derivatives are provided (here dH), as well as the current timestep, layer boundary depths, and variable grids (accessible via state.t, and state.grid respectively). Note that state will also contain other variables declared on this Soil layer by other SubSurfaceProcesses, allowing for implicit coupling between processes where appropriate.","category":"page"},{"location":"manual/architecture/#arch","page":"Architecture","title":"Architecture","text":"","category":"section"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"This page provides a general overview of the code organization and architecture of CryoGrid.jl.","category":"page"},{"location":"manual/architecture/#Modular-design","page":"Architecture","title":"Modular design","text":"","category":"section"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"Modular programming in software design revolves around the separation of computer programs into \"modules\" that can be independently constructed, tested, and coupled together into a larger system. The benefits of modular programming are well documented and have been common practice in software engineering for decades [1]. In the context of physical modeling, modular programming has the potential to facilitate rapid prototyping and comparison of different model configurations, parameterizations, and process interactions [2].","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"The term \"modular programming\" is fairly abstract and encompasses a wide range of patterns and techniques centered around the central aim of building robust and reusable software components. Namespaces are a commonly employed tool for organizing code into standalone modules or packages that share functionality and naming patterns. Namespaces help avoid name collisions by localizing variable and function names to their enclosing namespace, therefore resolving possible ambiguities.","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"In Julia, namespaces are declared via modules. Modules are more-or-less self-contained namespaces which can be used to organize and isolate code. Modules can \"export\" methods or variables which are intended for external use via export statements. Other modules can then import these methods or variables into their namespace via using and import statements; e.g. using Dates brings all exported names from the Dates module into the current namespace. Note that the top-level module (i.e. in a script or in the REPL) is always called Main.","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"The CryoGrid module provided by CryoGrid.jl is organized into a series of submodules:","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"Name Description Depends on\nUtils Miscellaneous utility methods and types. \nNumerics Utilities for math, array caches, and spatial discretization. Utils\nInputOutput Methods and types related to reading and writing input and output data. Utils,Numerics\nDiagnostics Tools for model diagnostics. Utils,Numerics\nHydrology Methods and types for computing water related quanities. Utils,Numerics\nHeat Methods and types for computing heat and energy related quanities. Utils,Numerics,Hydrology\nSoils Defines Soil layers and provides dispatches for soil-specific physical processes. Utils,Numerics,Hydrology,Heat\nSnow Defines Snowpack layer and provides dispatches for snow processes. Utils,Numerics,Hydrology,Heat\nSalt Provides types and dispatches for coupled heat/salt diffusion in saline soils. Utils,Numerics,Hydrology,Heat,Soils\nSurface Defines boundary processes for the surface such as the surface energy and water balance equations. Utils,Numerics,Hydrology,Heat,Soils,Snow\nTiles Defines the Tile and Stratigraphy types for constructing 1D land models. Utils,Numerics,InputOutput\nDiffEq Provides dispatches and utilities for integrating with solvers from the SciML OrdinaryDiffEq package. Utils,Numerics,InputOutput\nLiteImplicit Provides an implementation of the CryoGridLite solver scheme from Langer et al. 2023. Utils,Numerics\nPresets Provides pre-defined stratigraphies, forcings, and layer configurations to facilitate rapid prototyping. Utils,Numerics,InputOutput,Heat,Hydrology,Soils","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"Note that all submodules depend on the top-level CryoGrid module which declares all of the \"core\" types and method interfaces for defining model behavior. Each submodule may additionally define its own method interfaces related to its own specific process(es) or layer(s).","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"The @reexport macro from the Reexport package is used extensively to propagate exported methods and types to the top-level CryoGrid namespace. This is intended to alleviate the user of the burden to keep track of which types/methods are exported by which submodules. In most cases, it is sufficient to simply import or using the CryoGrid module in order to bring all CryoGrid-related methods and types into scope.","category":"page"},{"location":"manual/architecture/#Model-structure","page":"Architecture","title":"Model structure","text":"","category":"section"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"In the context of CryoGrid, a \"model\" typically refers to one or more Tiles [2] which may or may not be laterally coupled together. A Tile typically corresponds to a rectangular volume discretized along the vertical z-axis, i.e. corresponding physically to depth/elevation. CryoGrid.jl implements this concept by defining a single Tile as a composition of the following:","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"A Stratigraphy with three or more Layers, including a Top layer and a Bottom layer.\nA StateVars cache which stores all non-prognostic state and grid data.\nZero or more VarInitializers that define the intial condition of the prognostic state.\nZero or more layer Events that may or may not be invoked when their trigger conditions are met.","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"The Stratigraphy is simply a Tuple of layers in ascending order of depth (i.e. top to bottom) paired with (initial) upper boundary depths. The thickness of each stratigraphy layer is therefore determined by the distance between the upper boundary of the layer and the upper boundary of the following layer. Depending on the configuration of the layer, this thickness may be either static or dynamic over time. In the latter case, the layer thickness Δz is automatically included as a prognostic state variable.","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"Each SubSurface layer in the stratigraphy will typically consist of one or more Processes as fields on the layer struct which should then be explicitly declared via a dispatch of the processes method. The variables and events methods similarly declare state variables and events respectively that should be defined for any given configuration of the layer.","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"The Tile constructor collects all of the relevant state variables declared by variables and discretizes them according to the given DiscretizationStrategy. The resulting state vectors are initialized in the forward-diff compatible StateVars cache. On each invocation of Tile, the current TileState is constructed from the current prognostic state variable u, parameter vector p, and time step t. The TileState consists of named LayerStates which provide layer-local views of each state variable array, i.e. only grid cells within the layer boundaries are included.","category":"page"},{"location":"manual/architecture/#Control-flow","page":"Architecture","title":"Control flow","text":"","category":"section"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"The CryoGrid module defines three primary methods that can be used to implement the behavior of each Layer/Process in any given model configuration. When updating the model at a particular timestep, these methods are typically invoked in the following order:","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"computediagnostic! updates all (non-flux) state variables and/or derived quantities based on the current (prognostic) state.\ninteract! defines interactions between adjacent layers in the stratigraphy, including fluxes over the layer boundary.\ncomputefluxes! computes all internal fluxes (and the divergence thereof) within each layer, after boundary fluxes are taken into account by interact!.","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"Layer and/or process specific implementations of each of these methods can generally assume that the previous methods have already been invoked by the caller (it is the responsibility of the calling code to ensure that this is the case). This is, for example, the order in which these methods will be invoked by tile(du, u, p t).","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"Note that, due to the nature of multiple dispatch, the execution path (i.e. with respect to the actual source code) of any given model configuration will typically be quite nonlinear and may span multiple source files depending on where the matching method dispatches are defined. Users may find the which provided by Julia (and correspondingly the @which macro from InteractiveUtils) useful in figuring out where executing code is located. For example:","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"using CryoGrid\nusing CryoGrid.Diagnostics\n\nsoil = Ground()\ngrid = CryoGrid.Presets.DefaultGrid_5cm\nstate = Diagnostics.build_dummy_state(grid, soil)\n\n@which CryoGrid.computediagnostic!(soil, state)","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"Output:","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"computediagnostic!(layer::Layer, state)\n @ CryoGrid ~/workspace/sparc-local/repos/CryoGrid/CryoGrid.jl/src/methods.jl:55","category":"page"},{"location":"manual/architecture/#State-variables","page":"Architecture","title":"State variables","text":"","category":"section"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"In order to facilitate modularity and ease-of-use, CryoGrid.jl provides an automated system for initializing and configuring state variables for any given model configuration. Note that there is an important distinction between two types of model state: prognostic and diagnostic.","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"Prognostic(@ref) state variables fully define the state of the system at any given time t. They form what is typically called the \"phase space\" or \"state space\" in the mathematics and engineering literature. In order to be compatible with standard ODE solvers (e.g. like those in OrdinaryDiffEq), CryoGrid.jl automatically assembles prognostic state variables into a single array u (and its corresponding time derivative du) which is returned when initializing a Tile with the initialcondition! method. Note again that this array should always fully define the state of the system.","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"Diagnostic(@ref) state variables act as caches for intermediate and derived quantities defined by the model. They also may, in some cases, provide a means of coupling between different processes (e.g. the heat and water flux variables jH and jw might be updated by more than one Process). For any model configuration, all diagnostic variables should be fully updated (and thus consistent) with the given prognostic state after invoking computediagnostic!, interact!, and computefluxes!.","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"When a Tile is constructed, all variables defined by each layer in the Stratigraphy are collected and then intiailized in StateVars according to the given DiscretizationStrategy.","category":"page"},{"location":"manual/architecture/#References","page":"Architecture","title":"References","text":"","category":"section"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"[1] Bass L, Clements P, Kazman R. Software architecture in practice. Addison-Wesley Professional; 2003.","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"[2] Westermann S, Ingeman-Nielsen T, Scheer J, Aalstad K, Aga J, Chaudhary N, Etzelmüller B, Filhol S, Kääb A, Renette C, Schmidt LS. The CryoGrid community model (version 1.0)–a multi-physics toolbox for climate-driven simulations in the terrestrial cryosphere. Geoscientific Model Development. 2023 May 15;16(9):2607-47.","category":"page"},{"location":"quickstart/#Quick-start","page":"Getting Started","title":"Quick start","text":"","category":"section"},{"location":"quickstart/","page":"Getting Started","title":"Getting Started","text":"After installing CryoGrid.jl, you can get started right away with a simple soil heat model. The Presets module (aliased CryoGrid.Presets) provides pre-specified model configurations that can be obtained with a single function call. It is also possible to modify the soil and initial temperature profiles via SoilLayerConfig; here SamoylovDefault is used.","category":"page"},{"location":"quickstart/","page":"Getting Started","title":"Getting Started","text":"Single layer heat conduction model with free water freeze curve and air temperature upper boundary condition:","category":"page"},{"location":"quickstart/","page":"Getting Started","title":"Getting Started","text":"using CryoGrid\nusing Plots\n\n# load provided forcing data from Samoylov;\n# The forcing file will be automatically downloaded to the input/ folder if not already present.\nforcings = loadforcings(CryoGrid.Presets.Forcings.Samoylov_ERA_obs_fitted_1979_2014_spinup_extended_2044, :Tair => u\"°C\");\n# get preset soil and initial temperature profile for Samoylov\nsoilprofile, tempprofile = CryoGrid.Presets.SamoylovDefault\ninitT = initializer(:T, tempprofile)\n# choose grid with 5cm spacing\ngrid = CryoGrid.Presets.DefaultGrid_5cm\n# basic 1-layer heat conduction model (defaults to free water freezing scheme)\ntile = CryoGrid.Presets.SoilHeatTile(TemperatureBC(forcings.Tair), GeothermalHeatFlux(0.053u\"W/m^2\"), soilprofile, initT, grid=grid)\n# define time span (1 year)\ntspan = (DateTime(2010,11,30),DateTime(2011,11,30))\nu0, du0 = initialcondition!(tile, tspan)\n# CryoGrid front-end for ODEProblem\nprob = CryoGridProblem(tile, u0, tspan, savevars=(:T,))\n# solve discretized system, saving every 3 hours;\nout = @time solve(prob, saveat=3*3600.0, progress=true) |> CryoGridOutput;\nzs = [2,7,12,22,32,42,50,100,500]u\"cm\"\ncg = Plots.cgrad(:copper,rev=true)\nplot(out.T[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Temperature\", leg=false)","category":"page"},{"location":"quickstart/","page":"Getting Started","title":"Getting Started","text":"(Image: Ts_output_freew)","category":"page"},{"location":"quickstart/","page":"Getting Started","title":"Getting Started","text":"Alternatively, we can use a Dall'Amico freeze curve:","category":"page"},{"location":"quickstart/","page":"Getting Started","title":"Getting Started","text":"sfcc = SFCC(DallAmico(swrc=VanGenuchten(α=0.02, n=1.8))) # silt/clay-like freeze curve\ntile2 = CryoGrid.Presets.SoilHeatTile(TemperatureBC(forcings.Tair), GeothermalHeatFlux(0.053u\"W/m^2\"), soilprofile, initT, grid=grid, freezecurve=sfcc)\nu0, du0 = initialcondition!(tile2, tspan)\n# CryoGrid front-end for ODEProblem\nprob2 = CryoGridProblem(tile2, u0, tspan, savevars=(:T,))\nout2 = @time solve(prob2, saveat=3*3600.0, progress=true) |> CryoGridOutput;\nplot(out2.T[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Temperature\", leg=false)","category":"page"},{"location":"quickstart/","page":"Getting Started","title":"Getting Started","text":"Note that SoilHeatTile uses energy as the state variable by default. To use temperature as the state variable instead:","category":"page"},{"location":"quickstart/","page":"Getting Started","title":"Getting Started","text":"# :T is the variable name for temperature, :H represents enthalpy/energy.\n# This is used in the specification of the HeatBalance process type.\n# While this will work with any freeze curve, here we use Westermann (2011) as an example.\nmodel = CryoGrid.Presets.SoilHeatTile(:T, TemperatureBC(forcings.Tair), soilprofile, freezecurve=SFCC(Westermann()))","category":"page"},{"location":"api/solvers/diffeq/#SciML/DiffEq-solvers","page":"SciML/DiffEq","title":"SciML/DiffEq solvers","text":"","category":"section"},{"location":"api/solvers/diffeq/","page":"SciML/DiffEq","title":"SciML/DiffEq","text":"Modules = [CryoGrid.DiffEq]\nPrivate = false\nOrder = [:type, :function, :macro]","category":"page"},{"location":"api/solvers/diffeq/#CryoGrid.DiffEq.CryoGridParameterEnsemble-Tuple{CryoGridProblem, AbstractMatrix{T} where T}","page":"SciML/DiffEq","title":"CryoGrid.DiffEq.CryoGridParameterEnsemble","text":"CryoGridParameterEnsemble(\n prob::CryoGridProblem,\n Θ::AbstractMatrix;\n transform=identity,\n output_func=(sol, i) -> CryoGridOutput(sol),\n reduction=(u,data,i) -> (append!(u,data),false),\n ensprob_kwargs...\n)\n\nConstructs an EnsembleProblem for a m x N parameter matrix Θ, where N is the size of the ensemble and m is the dimensionality of the ensmeble parameter space (e.g. the number of parameters). transform should be a transform function that accepts an m-dimensional vector and produces a parameter vector (or CryoGridParams instance) which matches the output of CryoGrid.parameters. By default, param_map is the identity function; however, it may be customized to permit the construction of reduced-rank or reparameterized ensembles for which the parameter space differs from the full CryoGrid model parameter space.\n\nKeyword arguments:\n\noutput_func: a function (sol,i)::Any which processes the ODESolution for ensemble member i and returns the result. It is recommended to save output to disk for non-trivial time spans to avoid slowdowns from serialization time when running the ensemble using parallel workers.\n\nreduction: a function (u,data,i) which accumulates the result of output_func in u. Defaults to just appending data to u.\n\noutput_dir: Only used to specify the output directory for the default implementation of output_func. If a custom output_func is provided, this arugment is ignored.\n\nAll additional keyword arguments will be passed to EnsembleProblem.\n\nSee also SciMLBase.EnsembleProblem\n\n\n\n\n\n","category":"method"},{"location":"api/diagnostics/#Diagnostics","page":"Diagnostics","title":"Diagnostics","text":"","category":"section"},{"location":"api/diagnostics/","page":"Diagnostics","title":"Diagnostics","text":"Modules = [Diagnostics]\nPrivate = false\nOrder = [:type, :function, :macro]","category":"page"},{"location":"api/diagnostics/#CryoGrid.Diagnostics.active_layer_thickness-Tuple{AbstractDimArray{var\"#s205\", N, D, A} where {var\"#s205\"<:(Quantity{T, 𝚯, U} where {T, U<:(Unitful.FreeUnits{N, 𝚯, A} where {N, A})}), N, D<:Tuple, A}}","page":"Diagnostics","title":"CryoGrid.Diagnostics.active_layer_thickness","text":"active_layer_thickness(T::AbstractDimArray{<:TempQuantity})\n\nComputes active layer thickness annually. The active layer thickness is defined here as the maximum thaw depth throughout the calendar year. Assumes T to have dimensions Ti (time) and Z (depth) in any order.\n\n\n\n\n\n","category":"method"},{"location":"api/diagnostics/#CryoGrid.Diagnostics.computejac-Tuple{Tile, Any, Any, Any}","page":"Diagnostics","title":"CryoGrid.Diagnostics.computejac","text":"computejac(tile::Tile, u, p, t)\n\nHelper function that computes the Jacobian of the given tile at u with parameters p and time t.\n\n\n\n\n\n","category":"method"},{"location":"api/diagnostics/#CryoGrid.Diagnostics.integrate-Union{Tuple{G}, Tuple{AbstractDimArray, Grid{Edges, G, var\"#s205\", A} where {var\"#s205\"<:(Quantity{T, 𝐋, U} where {T, U<:(Unitful.FreeUnits{N, 𝐋, nothing} where N)}), A}}} where G","page":"Diagnostics","title":"CryoGrid.Diagnostics.integrate","text":"integrate(X::AbstractDimArray, grid::Grid{Edges}; upper_limit=0u\"m\", lower_limit=10u\"m\")\n\nIntegrates the quantity X over the given grid, which is assumed to be spatially alligned, i.e. length(grid) == length(dims(X,Z)) + 1 and cells(grid) .≈ dims(X,Z) are necessary preconditions.\n\n\n\n\n\n","category":"method"},{"location":"api/diagnostics/#CryoGrid.Diagnostics.mean_annual_ground_temperature-Tuple{AbstractDimArray{var\"#s205\", N, D, A} where {var\"#s205\"<:(Quantity{T, 𝚯, U} where {T, U<:(Unitful.FreeUnits{N, 𝚯, A} where {N, A})}), N, D<:Tuple, A}}","page":"Diagnostics","title":"CryoGrid.Diagnostics.mean_annual_ground_temperature","text":"mean_annual_ground_temperature(T::AbstractDimArray; upper_limit=0u\"m\", lower_limit=10u\"m\")\n\nComputes mean annual ground temperature between upper_limit and lower_limit. Assumes T to have dimensions Ti (time) and Z (depth) in any order.\n\n\n\n\n\n","category":"method"},{"location":"api/diagnostics/#CryoGrid.Diagnostics.permafrostbase-Tuple{AbstractDimArray{var\"#s205\", N, D, A} where {var\"#s205\"<:(Quantity{T, 𝚯, U} where {T, U<:(Unitful.FreeUnits{N, 𝚯, A} where {N, A})}), N, D<:Tuple, A}}","page":"Diagnostics","title":"CryoGrid.Diagnostics.permafrostbase","text":"permafrostbase(T::AbstractDimArray{<:TempQuantity})\n\nComputes depth of permafrost base for all years, i.e. the closest depth to the \"bottom\" at which the maximum annual temperature is strictly < 0°C. Assumes T to have dimensions Ti (time) and Z (depth) in any order.\n\n\n\n\n\n","category":"method"},{"location":"api/diagnostics/#CryoGrid.Diagnostics.permafrosttable-Tuple{AbstractDimArray{var\"#s205\", N, D, A} where {var\"#s205\"<:(Quantity{T, 𝚯, U} where {T, U<:(Unitful.FreeUnits{N, 𝚯, A} where {N, A})}), N, D<:Tuple, A}}","page":"Diagnostics","title":"CryoGrid.Diagnostics.permafrosttable","text":"permafrosttable(T::AbstractDimArray{<:TempQuantity})\n\nComputes depth of permafrost table for all years, i.e. the closest depth to the surface at which the maximum annual temperature is strictly less than Tmelt. Assumes T to have dimensions Ti (time) and Z (depth) in any order.\n\n\n\n\n\n","category":"method"},{"location":"api/diagnostics/#CryoGrid.Diagnostics.spinup-Tuple{Tile, Tuple{DateTime, DateTime}, Any, Any, Any}","page":"Diagnostics","title":"CryoGrid.Diagnostics.spinup","text":"spinup(setup::Tile, tspan::NTuple{2,DateTime}, p, tol, layername; kwargs...)\n\nImplements a simple, iterative spin-up procedure. Runs the model specified by setup over tspan until the profile mean up to maxdepth over the whole time span changes only within the given tolerance tol. Returns the ODESolution generated by the final iteration.\n\n\n\n\n\n","category":"method"},{"location":"api/diagnostics/#CryoGrid.Diagnostics.thawdepth-Tuple{AbstractDimArray{var\"#s205\", N, D, A} where {var\"#s205\"<:(Quantity{T, 𝚯, U} where {T, U<:(Unitful.FreeUnits{N, 𝚯, A} where {N, A})}), N, D<:Tuple, A}}","page":"Diagnostics","title":"CryoGrid.Diagnostics.thawdepth","text":"thawdepth(T::AbstractDimArray{<:TempQuantity}; Tmelt=0.0u\"°C\")\n\nComputes sub-grid thaw depth (a.k.a freezing front) from temperature at all time steps. The sub-grid depth of the zero degree isotherm is determined by linearly interpolating between grid cell temperatures in T. Note that T is assumed to have units °C and dimensions Ti (time) and Z (depth) in any order.\n\n\n\n\n\n","category":"method"},{"location":"api/diagnostics/#CryoGrid.Diagnostics.zero_annual_amplitude-Tuple{AbstractDimArray{var\"#s205\", N, D, A} where {var\"#s205\"<:(Quantity{T, 𝚯, U} where {T, U<:(Unitful.FreeUnits{N, 𝚯, A} where {N, A})}), N, D<:Tuple, A}}","page":"Diagnostics","title":"CryoGrid.Diagnostics.zero_annual_amplitude","text":"zero_annual_amplitude(T::AbstractDimArray{<:TempQuantity}; threshold=0.5u\"K\")\n\nComputes annual depth of zero amplitude (where |max - min| < threshold) and returns the result for each year. Assumes T to have dimensions Ti (time) and Z (depth) in any order.\n\n\n\n\n\n","category":"method"},{"location":"api/solvers/lite_implicit/#CryoGridLite","page":"CryoGridLite","title":"CryoGridLite","text":"","category":"section"},{"location":"api/solvers/lite_implicit/","page":"CryoGridLite","title":"CryoGridLite","text":"Modules = [CryoGrid.LiteImplicit]\nPrivate = false\nOrder = [:type, :function, :macro]","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"EditURL = \"../../../examples/heat_freeW_bucketW_samoylov.jl\"","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/#example5","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"","category":"section"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"In this example, we construct a Tile consisting of a soil column with (i) heat conduction and (ii) a bucket hydrology scheme. The rainfall data comes from the ERA5-Interim reanalysis product.","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"Frist, load forcings and define boundary conditions.","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"using CryoGrid\nforcings = loadforcings(CryoGrid.Presets.Forcings.Samoylov_ERA_obs_fitted_1979_2014_spinup_extended_2044);\n_, tempprofile = CryoGrid.Presets.SamoylovDefault;\ninitT = initializer(:T, tempprofile)\ninitsat = initializer(:sat, (l,state) -> state.sat .= l.para.sat);\nupperbc = WaterHeatBC(SurfaceWaterBalance(forcings), TemperatureBC(forcings.Tair, NFactor(0.5,0.9)));\nnothing #hide","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"The @Stratigraphy macro is just a small convenience that automatically wraps the three subsurface layers in a tuple. It would be equivalent to use the Stratigraphy constructor directly and wrap these layers in a tuple or list.","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"strat = @Stratigraphy(\n 0.0u\"m\" => Top(upperbc),\n 0.0u\"m\" => Ground(MineralOrganic(por=0.80,sat=0.5,org=0.75), heat=HeatBalance(), water=WaterBalance(BucketScheme())),\n 0.2u\"m\" => Ground(MineralOrganic(por=0.40,sat=0.75,org=0.10), heat=HeatBalance(), water=WaterBalance(BucketScheme())),\n 2.0u\"m\" => Ground(MineralOrganic(por=0.10,sat=1.0,org=0.0), heat=HeatBalance(), water=WaterBalance(BucketScheme())),\n 1000.0u\"m\" => Bottom(GeothermalHeatFlux(0.053u\"W/m^2\")),\n);\nmodelgrid = CryoGrid.Presets.DefaultGrid_2cm\ntile = Tile(strat, modelgrid, initT, initsat);\nnothing #hide","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"Now we set up the problem and solve using the integrator interface.","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"tspan = (DateTime(2010,5,30),DateTime(2012,8,30))\nu0, du0 = initialcondition!(tile, tspan)\nprob = CryoGridProblem(tile, u0, tspan, savevars=(:T,:jw,:θw,:θwi), saveat=3*3600.0)\nintegrator = init(prob, CGEuler())\n# Take a single step:\nstep!(integrator)\n# ...then iterate over the remaining steps.\n@time for i in integrator\n # can add code here if necessary\nend\nout = CryoGridOutput(integrator.sol)","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"Now let's check mass conservation for water.","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"water_added = values(sum(forcings.rainfall.(tspan[1]:Hour(3):tspan[2]).*u\"m/s\".*(3*3600.0u\"s\")))[1]\nwater_mass = Diagnostics.integrate(out.θwi, tile.grid)\nΔwater = water_mass[end] - water_mass[1]","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"Plot the results:","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"import Plots\nzs = [1,5,9,15,21,25,33,55,65,75,100]u\"cm\"\ncg = Plots.cgrad(:copper,rev=true);\nnothing #hide","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"Temperature:","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"Plots.plot(out.T[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Temperature\", leg=false, size=(800,500), dpi=150)","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"Liquid water:","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"Plots.plot(out.θw[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Unfrozen water content\", leg=false, size=(800,500), dpi=150)","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"Saturation:","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"Plots.plot(out.sat[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Saturation\", leg=false, size=(800,500), dpi=150)","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"Runoff:","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"Plots.plot(out.top.runoff[1,:], ylabel=\"Runoff\")","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"This page was generated using Literate.jl.","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"EditURL = \"../../../examples/heat_freeW_seb_snow_bucketW_samoylov.jl\"","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/#example6","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"","category":"section"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"In this example, we construct a Tile consisting of a soil column with (i) heat conduction forced by the surface energy balance (SEB), (ii) a bulk snow scheme, and (iii) a bucket hydrology scheme.","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"For this example, we need to use an OrdinaryDiffEq integrator.","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"using CryoGrid\nusing OrdinaryDiffEq","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"First, load the forcings and construct the Tile.","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"modelgrid = CryoGrid.Presets.DefaultGrid_2cm;\nsoilprofile = SoilProfile(\n 0.0u\"m\" => MineralOrganic(por=0.80,sat=1.0,org=0.75),\n 0.1u\"m\" => MineralOrganic(por=0.80,sat=1.0,org=0.25),\n 0.4u\"m\" => MineralOrganic(por=0.55,sat=1.0,org=0.25),\n 3.0u\"m\" => MineralOrganic(por=0.50,sat=1.0,org=0.0),\n 10.0u\"m\" => MineralOrganic(por=0.30,sat=1.0,org=0.0),\n);\n# mid-winter temperature profile\ntempprofile = CryoGrid.Presets.SamoylovDefault.tempprofile\nforcings = loadforcings(CryoGrid.Presets.Forcings.Samoylov_ERA_obs_fitted_1979_2014_spinup_extended_2044);\ntempprofile = CryoGrid.Presets.SamoylovDefault.tempprofile\ninitT = initializer(:T, tempprofile)\nz = 2.0u\"m\"; # height [m] for which the forcing variables (Temp, humidity, wind, pressure) are provided\nseb = SurfaceEnergyBalance(forcings, z)\nswb = SurfaceWaterBalance(forcings)\nupperbc = WaterHeatBC(swb, seb)\nheat = HeatBalance()\nwater = WaterBalance(BucketScheme(), DampedET())\n# build stratigraphy\nstrat = @Stratigraphy(\n -z => Top(upperbc),\n -z => Snowpack(heat=HeatBalance(), water=water),\n 0.0u\"m\" => Ground(soilprofile; heat, water),\n 1000.0u\"m\" => Bottom(GeothermalHeatFlux(0.053u\"J/s/m^2\")),\n);\n# create Tile\ntile = Tile(strat, modelgrid, initT);\nnothing #hide","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"Set up the problem and solve it!","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"tspan = (DateTime(2010,10,30), DateTime(2011,10,30))\n# generate initial condition and set up CryoGridProblem\nu0, du0 = @time initialcondition!(tile, tspan)\n\nprob = CryoGridProblem(\n tile,\n u0,\n tspan,\n savevars=(:T,:jH,:top => (:Qh,:Qe,:Qg,),:snowpack => (:dsn,)),\n saveat=3*3600.0\n)\nintegrator = init(prob, Euler(), dt=60.0)\n# step forwards 24 hours and check for NaN/Inf values\n@time step!(integrator); integrator.dt\n@assert all(isfinite.(integrator.u))\n# iterate over remaining timespan at fixed points using `TimeChoiceIterator`\n@time for (u,t) in TimeChoiceIterator(integrator, convert_t.(tspan[1]:Day(1):tspan[end]))\n state = getstate(integrator)\n @assert isfinite(state.top.Qg[1])\n @info \"Current t=$(Date(convert_t(t))), dt=$(integrator.dt), Tsurf=$(state.ground.T[1]), infil=$(state.top.jw_infil[1])\"\n if integrator.sol.retcode != ReturnCode.Default\n break\n end\nend\nout = CryoGridOutput(integrator.sol)","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"Plot it!","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"import Plots\nzs = [1,3,5,7,10,15,20,25,30,40,50,100,150,200,500,1000]u\"cm\"\ncg = Plots.cgrad(:copper,rev=true);\nPlots.plot(ustrip.(out.T[Z(Near(zs))]), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Temperature\", leg=false, size=(800,500), dpi=150)","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"Saturation:","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"Plots.plot(ustrip.(out.sat[Z(Near(zs))]), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Soil saturation\", leg=false, size=(800,500), dpi=150)","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"Runoff","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"Plots.plot(ustrip.(out.top.runoff), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Total runoff\", leg=false, size=(800,500), dpi=150)","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"Evapotranspiration","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"Plots.plot(ustrip.(out.top.ET), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Total ET\", leg=false, size=(800,500), dpi=150)","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"Snow depth:","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"Plots.plot(ustrip.(out.snowpack.dsn), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Snow depth\", leg=false, size=(800,500), dpi=150)","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"Integrated ground heat flux:","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"Plots.plot(ustrip.(cumsum(out.top.Qg, dims=2)), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Integrated ground heat flux\", leg=false, size=(800,500), dpi=150)","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"Integratoed ground latent heat flux:","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"Plots.plot(ustrip.(cumsum(out.top.Qe, dims=2)), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Integrated ground heat flux\", leg=false, size=(800,500), dpi=150)","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"This page was generated using Literate.jl.","category":"page"},{"location":"#CryoGrid.jl","page":"Home","title":"CryoGrid.jl","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"CryoGrid.jl is a Julia implementation of the CryoGrid land surface model using DifferentialEquations.jl and the SciML package ecosystem. Its primary goal is to provide a fast, flexible, and feature rich framework for modeling permafrost in Julia while simultaneously laying the groundwork for rapid prototyping of data-driven parameter estimation, uncertainty quantification, and causal analysis of complex Arctic land surface processes.","category":"page"},{"location":"","page":"Home","title":"Home","text":"This package is part of the broader research project: Quantifying and explaining uncertainty in permafrost modeling under a warming climate","category":"page"},{"location":"","page":"Home","title":"Home","text":"Pages = [\"index.md\",\"installation.md\",\"quickstart.md\",\"manual/overview.md\",\"api/index.md\"]","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"EditURL = \"../../../examples/heat_freeW_snow_samoylov.jl\"","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/#example4","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"","category":"section"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"In this example, we construct a Tile consisting of a soil column with (i) heat conduction and (ii) a bulk (single-layer) snow scheme. The snowfall data comes from the ERA-Interim reanalysis product.","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"using CryoGrid\nusing OrdinaryDiffEq","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"First we set up the model:","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"forcings = loadforcings(CryoGrid.Presets.Forcings.Samoylov_ERA_obs_fitted_1979_2014_spinup_extended_2044);\nsoilprofile, tempprofile = CryoGrid.Presets.SamoylovDefault\ninitT = initializer(:T, tempprofile)\ninitsat = initializer(:sat, 1.0)\nz_top = -2.0u\"m\"\nz_sub = keys(soilprofile)\nz_bot = 1000.0u\"m\"\nupperbc = WaterHeatBC(\n SurfaceWaterBalance(forcings),\n TemperatureBC(forcings.Tair)\n)\nsnowmass = SnowMassBalance(\n ablation = Snow.DegreeDayMelt(factor=5.0u\"mm/K/d\")\n)\nsnowpack = Snowpack(\n para=Snow.Bulk(),\n mass=snowmass,\n heat=HeatBalance(),\n water=WaterBalance(),\n)\nground_layers = map(soilprofile) do para\n Ground(para, heat=HeatBalance(), water=WaterBalance())\nend\nstrat = @Stratigraphy(\n z_top => Top(upperbc),\n z_top => snowpack,\n ground_layers...,\n z_bot => Bottom(GeothermalHeatFlux(0.053u\"J/s/m^2\"))\n);\nmodelgrid = CryoGrid.Presets.DefaultGrid_5cm\ntile = Tile(strat, modelgrid, initT, initsat)","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"define time span, 2 years + 3 months","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"tspan = (DateTime(2010,9,30), DateTime(2012,9,30))\nu0, du0 = @time initialcondition!(tile, tspan)\nprob = CryoGridProblem(tile, u0, tspan, saveat=3*3600.0, savevars=(:T, :top => (:T_ub), :snowpack => (:dsn,)))","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"solve full tspan with forward Euler and initial timestep of 5 minutes","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"@info \"Running model ...\"\nsol = @time solve(prob, CGEuler(), dt=300.0);\nout = CryoGridOutput(sol)","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"Plot it!","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"using Plots: plot, plot!, heatmap, cgrad, Measures\nzs = [1,10,20,30,50,100,200,500]u\"cm\"\ncg = cgrad(:copper,rev=true);\nplot(ustrip(out.T[Z(Near(zs))]), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Temperature (°C)\", leg=false, dpi=150)\nplot!(ustrip(out.T[1,:]), color=:darkgray, ylabel=\"Temperature (°C)\", leg=false, dpi=150)\nplt1 = plot!(ustrip.(out.top.T_ub), color=:skyblue, linestyle=:dash, alpha=0.5, leg=false, dpi=150)","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"Plot snow water equivalent and depth:","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"plot(ustrip(out.snowpack.swe), ylabel=\"Depth (m)\", label=\"Snow water equivalent\", dpi=150)\nplt2 = plot!(ustrip.(out.snowpack.dsn), label=\"Snow depth\", ylabel=\"Depth (m)\", legendtitle=nothing, dpi=150)\nplot(plt1, plt2, size=(1600,700), margins=5*Measures.mm)","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"Temperature heatmap:","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"T_sub = out.T[Z(Between(0.0u\"m\",10.0u\"m\"))]\nheatmap(T_sub, yflip=true, size=(1200,600), dpi=150)","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"Thaw depth:","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"td = Diagnostics.thawdepth(out.T[Z(Where(>=(0.0u\"m\")))])\nplot(td, yflip=true, ylabel=\"Thaw depth (m)\", size=(1200,600))","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"This page was generated using Literate.jl.","category":"page"}] +[{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"EditURL = \"../../../examples/heat_sfcc_constantbc.jl\"","category":"page"},{"location":"examples/heat_sfcc_constantbc/#example2","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"","category":"section"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"In this example, we use the preset SoilHeatTile to construct a Tile consisting of a soil column with heat conduction and zero-flux boundary conditions. This is a useful test case for checking energy conservation since we can guarantee that no energy is being added or removed at the boundaries.","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"using CryoGrid","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"Select default grid and initial temperature profile.","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"grid = CryoGrid.Presets.DefaultGrid_10cm\ntempprofile = TemperatureProfile(\n 0.0u\"m\" => -20.0u\"°C\",\n 1000.0u\"m\" => 10.0u\"°C\",\n);\nnothing #hide","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"Here we use a simple single layer model with default soil parameters (50% porosity, no organic).","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"soilprofile = SoilProfile(\n 0.0u\"m\" => MineralOrganic()\n);\nnothing #hide","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"Here we specify the soil freezing characteristic curve (SFCC) formulation of Painter and Karra (2014). The van Genuchten parameters α=0.1 and n=1.8 correspond to a silty soil.","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"sfcc = PainterKarra(swrc=VanGenuchten(α=1.0, n=2.0));\n\nimport Plots\nPlots.plot(-2.0u\"°C\":0.01u\"K\":0.0u\"°C\", sfcc)","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"Enthalpy form of the heat transfer operator (i.e. prognostic :H). In this case, this is equivalent to the shorthand SoilHeatTile(:H, ...). However, it's worth demonstrating how the operator can be explicitly specified.","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"heatop = Heat.Diffusion1D(:H)\ninitT = initializer(:T, tempprofile)\ntile = CryoGrid.Presets.SoilHeatTile(\n heatop,\n # 10 W/m^2 in and out, i.e. net zero flux\n ConstantBC(HeatBalance, CryoGrid.Neumann, 10.0u\"W/m^2\"),\n ConstantBC(HeatBalance, CryoGrid.Neumann, 10.0u\"W/m^2\"),\n soilprofile,\n initT;\n grid,\n freezecurve=sfcc,\n);\nnothing #hide","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"Define the simulation time span.","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"tspan = (DateTime(2010,1,1),DateTime(2010,12,31))\nu0, du0 = initialcondition!(tile, tspan);\nnothing #hide","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"Construct and solve the CryoGridProblem using the built-in forward Euler integrator.","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"prob = CryoGridProblem(tile, u0, tspan, saveat=3600.0, savevars=(:T,:H))\nsol = @time solve(prob, dtmax=900.0);\nout = CryoGridOutput(sol)","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"Compute total energy balance error.","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"Htot = Diagnostics.integrate(out.H, grid)\nmass_balance_error = Htot[end] - Htot[1]","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"Plot it!","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"import Plots\nzs = [1,45,95,195,495,795,995]u\"cm\"\nDiagnostics.plot_at_depths(:T, out, zs, ylabel=\"Temperature\", leg=false, size=(800,500), dpi=150)","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"Plot the energy balance error over time.","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"Plots.plot(uconvert.(u\"MJ\", Htot .- Htot[1]), title=\"\", ylabel=\"Energy balance error\")","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"","category":"page"},{"location":"examples/heat_sfcc_constantbc/","page":"Soil heat with SFCC and constant BCs","title":"Soil heat with SFCC and constant BCs","text":"This page was generated using Literate.jl.","category":"page"},{"location":"examples/heat_sfcc_salt_constantbc/","page":"Coupled heat and salt diffusion on salty soil column","title":"Coupled heat and salt diffusion on salty soil column","text":"EditURL = \"../../../examples/heat_sfcc_salt_constantbc.jl\"","category":"page"},{"location":"examples/heat_sfcc_salt_constantbc/#example9","page":"Coupled heat and salt diffusion on salty soil column","title":"Coupled heat and salt diffusion on salty soil column","text":"","category":"section"},{"location":"examples/heat_sfcc_salt_constantbc/","page":"Coupled heat and salt diffusion on salty soil column","title":"Coupled heat and salt diffusion on salty soil column","text":"In this example, we construct a Tile from a Stratigraphy of three \"salty soil\" layers which include coupled salt/heat diffusion. Note that this is currently only supported for the temperature-based form of the heat equation.","category":"page"},{"location":"examples/heat_sfcc_salt_constantbc/","page":"Coupled heat and salt diffusion on salty soil column","title":"Coupled heat and salt diffusion on salty soil column","text":"using CryoGrid\ninitT = initializer(:T, -2.0)\ninitsalt = initializer(:c, 0.0)\ninitpor = SedimentCompactionInitializer(porosityZero=0.4)\nsfcc = DallAmicoSalt(swrc=VanGenuchten(α=4.06, n=2.03))\nupperbc = SaltHeatBC(SaltGradient(benthicSalt=900.0, surfaceState=0), ConstantTemperature(0.0))\nstrat = @Stratigraphy(\n 0.0u\"m\" => Top(upperbc),\n 0.0u\"m\" => SalineGround(heat=HeatBalance(:T, freezecurve=sfcc), salt=SaltMassBalance()),\n 1000.0u\"m\" => Bottom(GeothermalHeatFlux(0.053u\"W/m^2\"))\n);\nmodelgrid = CryoGrid.Presets.DefaultGrid_10cm\ntile = Tile(strat, modelgrid, initT, initsalt, initpor)\ntspan = (DateTime(1990,1,1),DateTime(2000,12,31))\nu0, du0 = initialcondition!(tile, tspan)\nprob = CryoGridProblem(tile, u0, tspan, saveat=24*3600.0, savevars=(:T,:θw,:k,:dₛ))\n@info \"Running model\"\nintegrator = init(prob, CGEuler(), dt=60.0);\n@time step!(integrator, 24*3600)\n# Run to end of time span.\n@time for i in integrator end\nout = CryoGridOutput(integrator.sol)","category":"page"},{"location":"examples/heat_sfcc_salt_constantbc/","page":"Coupled heat and salt diffusion on salty soil column","title":"Coupled heat and salt diffusion on salty soil column","text":"Plot it!","category":"page"},{"location":"examples/heat_sfcc_salt_constantbc/","page":"Coupled heat and salt diffusion on salty soil column","title":"Coupled heat and salt diffusion on salty soil column","text":"import Plots\nzs = [5,15,25,35,45,55,65,75]u\"cm\"\ncg = Plots.cgrad(:copper,rev=true);\ntotal_salt = out.c.*out.θw\np1 = Plots.plot(total_salt[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Salt concentration\", leg=false, size=(800,500), dpi=150)\np2 = Plots.plot(out.T[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Temperature\", leg=false, size=(800,500), dpi=150)\np3 = Plots.plot(out.c[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Salt concentration\", leg=false, size=(800,500), dpi=150)\np4 = Plots.plot(out.θw[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Liquid water content\", leg=false, size=(800,500), dpi=150)\nPlots.plot([p1,p2,p3,p4], layout=Plots.@layout([p1 p2; p3 p4]))","category":"page"},{"location":"examples/heat_sfcc_salt_constantbc/","page":"Coupled heat and salt diffusion on salty soil column","title":"Coupled heat and salt diffusion on salty soil column","text":"","category":"page"},{"location":"examples/heat_sfcc_salt_constantbc/","page":"Coupled heat and salt diffusion on salty soil column","title":"Coupled heat and salt diffusion on salty soil column","text":"This page was generated using Literate.jl.","category":"page"},{"location":"api/presets/#Presets-(@)","page":"Presets","title":"Presets (@)","text":"","category":"section"},{"location":"api/presets/","page":"Presets","title":"Presets","text":"Modules = [CryoGrid.Presets]\nPrivate = false\nOrder = [:type, :function, :macro]","category":"page"},{"location":"api/presets/#CryoGrid.Presets.SoilHeatTile-Union{Tuple{F}, Tuple{Any, BoundaryProcess, BoundaryProcess, CryoGrid.Numerics.Profile, Vararg{CryoGrid.Initializer, N} where N}} where F<:FreezeCurve","page":"Presets","title":"CryoGrid.Presets.SoilHeatTile","text":"SoilHeatTile([heatop=:H], upperbc::BoundaryProcess, soilprofile::Profile, init::CryoGrid.Initializer...; grid::Grid=DefaultGrid_10cm, freezecurve::F=FreeWater(), tile_kwargs...) where {F<:FreezeCurve}\n\nBuilds a simple one-layer soil/heat-conduction model with the given grid and configuration. Uses the \"free water\" freeze curve by default, but this can be changed via the freezecurve parameter. For example, to use the Dall'Amico freeze curve, set freezecurve=SFCC(DallAmico()).\n\n\n\n\n\n","category":"method"},{"location":"dev/debugging/#debugging","page":"Debugging","title":"Debugging","text":"","category":"section"},{"location":"dev/debugging/","page":"Debugging","title":"Debugging","text":"TODO","category":"page"},{"location":"api/physics/heat_conduction/#Heat-conduction","page":"Heat Conduction","title":"Heat conduction","text":"","category":"section"},{"location":"api/physics/heat_conduction/","page":"Heat Conduction","title":"Heat Conduction","text":"Modules = [Heat]\nPrivate = false\nOrder = [:type, :function, :macro]","category":"page"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.GeothermalHeatFlux","page":"Heat Conduction","title":"CryoGrid.Heat.GeothermalHeatFlux","text":"GeothermalHeatFlux{TQ} <: BoundaryProcess{HeatBalance}\n\nRepresents a simple, forced Neumann heat flux boundary condition for HeatBalance processes.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.GroundHeatFlux","page":"Heat Conduction","title":"CryoGrid.Heat.GroundHeatFlux","text":"GroundHeatFlux{TE,TQ} <: BoundaryProcess{HeatBalance}\n\nRepresents a simple, forced Neumann heat flux boundary condition for HeatBalance processes.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.HeatBalance","page":"Heat Conduction","title":"CryoGrid.Heat.HeatBalance","text":"HeatBalance{Tfc<:FreezeCurve,THeatOp<:HeatOperator,Tdt,Tprop} <: SubSurfaceProcess\n\nRepresents subsurface heat transfer processes. The formulation of heat transfer is governed by the HeatOperator, op. \n\n\n\n\n\n","category":"type"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.HeatBalanceImplicit","page":"Heat Conduction","title":"CryoGrid.Heat.HeatBalanceImplicit","text":"Type alias for the implicit enthalpy formulation of HeatBalance.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.StefanProblem","page":"Heat Conduction","title":"CryoGrid.Heat.StefanProblem","text":"StefanProblem{Tp<:StefanParameters,Tx,Tt}\n\nRepresents the simple two-phase Stefan problem defined on a semi-infinite slab. The one-phase Stefan problem can be computed by setting the parameters T_s = T_m.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.TemperatureBC","page":"Heat Conduction","title":"CryoGrid.Heat.TemperatureBC","text":"TemperatureBC{E,F} <: BoundaryProcess{HeatBalance}\n\nRepresents a simple, forced Dirichlet temperature boundary condition for HeatBalance processes.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.ThermalProperties","page":"Heat Conduction","title":"CryoGrid.Heat.ThermalProperties","text":"ThermalProperties\n\nMaterial thermal properties, e.g. conductivity and heat capacity. By default, this includes the thermal properties of water, ice, and air. This can be extended by passing additional properties into the constructor.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.TemperatureProfile-Tuple{Vararg{Pair{var\"#s208\", var\"#s207\"} where {var\"#s208\"<:Union{Param, Quantity{T, 𝐋, U} where {T, U<:(Unitful.FreeUnits{N, 𝐋, nothing} where N)}}, var\"#s207\"<:Union{Param, Quantity{T, 𝚯, U} where {T, U<:(Unitful.FreeUnits{N, 𝚯, A} where {N, A})}}}, N} where N}","page":"Heat Conduction","title":"CryoGrid.Heat.TemperatureProfile","text":"TemperatureProfile(pairs::Pair{<:Union{DistQuantity,Param},<:Union{TempQuantity,Param}}...)\n\nConvenience constructor for Numerics.Profile which automatically converts temperature quantities.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.enthalpy-NTuple{4, Any}","page":"Heat Conduction","title":"CryoGrid.Heat.enthalpy","text":"enthalpy(T, C, L, θ) = T*C + L*θ\n\nDiscrete enthalpy function on temperature, heat capacity, specific latent heat of fusion, and liquid water content.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.enthalpyinv-NTuple{4, Any}","page":"Heat Conduction","title":"CryoGrid.Heat.enthalpyinv","text":"enthalpyinv(H, C, L, θ) = (H - L*θ) / C\n\nDiscrete inverse enthalpy function given H, C, L, and θ.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.freezethaw!-Tuple{Any, Any}","page":"Heat Conduction","title":"CryoGrid.Heat.freezethaw!","text":"freezethaw!(sub::SubSurface, heat::HeatBalance{FreeWater,<:EnthalpyBased}, state)\n\nImplementation of \"free water\" freezing characteristic for any subsurface layer. Assumes that state contains at least temperature (T), enthalpy (H), heat capacity (C), total water content (θwi), and liquid water content (θw).\n\n\n\n\n\n","category":"method"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.freezethaw!-Tuple{SubSurface, HeatBalance, Any}","page":"Heat Conduction","title":"CryoGrid.Heat.freezethaw!","text":"freezethaw!(sub::SubSurface, heat::HeatBalance, state)\n\nCalculates freezing and thawing effects, including evaluation of the freeze curve. In general, this function should compute at least the liquid/frozen water contents and the corresponding heat capacity. Other variables such as temperature or enthalpy may also need to be computed depending on the thermal scheme being implemented.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.heat_conduction_linear_periodic_ub-NTuple{4, Any}","page":"Heat Conduction","title":"CryoGrid.Heat.heat_conduction_linear_periodic_ub","text":"Analytical solution to linear form of the heat equation on a semi-infinite rod with periodic fluctuations at the upper boundary. Solution taken from Riseborough et al. 2008.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.heatcapacity!-Tuple{SubSurface, HeatBalance, Any}","page":"Heat Conduction","title":"CryoGrid.Heat.heatcapacity!","text":"heatcapacity!(sub::SubSurface, heat::HeatBalance, state)\n\nComputes the heat capacity for the given layer from the current state and stores the result in-place in the state variable C.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.heatcapacity-Tuple{SubSurface, Any, Any}","page":"Heat Conduction","title":"CryoGrid.Heat.heatcapacity","text":"heatcapacity(::SubSurface, state, i)\n\nComputes the heat capacity for the given SubSurface layer at grid cell i.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.heatcapacity-Tuple{SubSurface, HeatBalance, Any, Any}","page":"Heat Conduction","title":"CryoGrid.Heat.heatcapacity","text":"heatcapacity(sub::SubSurface, heat::HeatBalance, state, i)\n\nComputes the heat capacity as a weighted average over constituent capacities with volumetric fractions θfracs.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.thermalconductivity!-Tuple{SubSurface, HeatBalance, Any}","page":"Heat Conduction","title":"CryoGrid.Heat.thermalconductivity!","text":"thermalconductivity!(sub::SubSurface, heat::HeatBalance, state)\n\nComputes the thermal conductivity for the given layer from the current state and stores the result in-place in the state variable k.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.thermalconductivity-Tuple{SubSurface, Any, Any}","page":"Heat Conduction","title":"CryoGrid.Heat.thermalconductivity","text":"thermalconductivity(::SubSurface, state, i)\n\nComputes the thermal conductivity for the given SubSurface layer at grid cell i.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.thermalconductivity-Tuple{SubSurface, HeatBalance, Any, Any}","page":"Heat Conduction","title":"CryoGrid.Heat.thermalconductivity","text":"thermalconductivity(sub::SubSurface, heat::HeatBalance, state, i)\n\nComputes the thermal conductivity as a squared weighted sum over constituent conductivities with volumetric fractions θfracs.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/heat_conduction/#CryoGrid.Heat.thermalproperties-Tuple{SubSurface}","page":"Heat Conduction","title":"CryoGrid.Heat.thermalproperties","text":"thermalproperties(::SubSurface)\n\nReturns the thermal properties for the given subsurface layer.\n\n\n\n\n\n","category":"method"},{"location":"installation/#Installation","page":"Installation","title":"Installation","text":"","category":"section"},{"location":"installation/","page":"Installation","title":"Installation","text":"CryoGrid.jl can be installed via the Julia package manager:","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"add https://gitlab.awi.de/sparcs/cryogrid/cryogridjulia","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"or equivalently in code/REPL:","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"import Pkg\nPkg.add([\"https://gitlab.awi.de/sparcs/cryogrid/cryogridjulia\"])","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"Be aware that CryoGrid.jl is a relatively large package with quite a few dependencies, so installation into a blank Julia environment could take several minutes.","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"It is recommended that you work with CryoGrid.jl as a Julia package rather than cloning the repository and hacking on it directly. This will allow for more rapid development and minimize latency from precompile time. It is also recommended to create a dedicated Julia environment in your workspace to better manage package dependencies. This can be accomplished by running:","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"activate .","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"in your working directory, or by starting Julia with the --project=. option. Then, you can proceed to install CryoGrid.jl into the environment via the commands above.","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"You can load CryoGrid.jl in your Julia REPL or editor by running:","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"using CryoGrid","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"or similarly:","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"import CryoGrid","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"The latter option will bring only the CryoGrid module name into scope rather than all of its exported components.","category":"page"},{"location":"api/utils/#utils","page":"Utilities","title":"Utility methods and types","text":"","category":"section"},{"location":"api/utils/","page":"Utilities","title":"Utilities","text":"This module provides miscellaneous utility methods and types that are used throughout the CryoGrid.jl codebase. Note that the Utils module is not exported by the top-level CryoGrid module. It may, however, be explicitly imported by the user via using CryoGrid.Utils or import CryoGrid.Utils when needed.","category":"page"},{"location":"api/utils/","page":"Utilities","title":"Utilities","text":"Modules = [CryoGrid.Utils]\nPrivate = false\nOrder = [:type, :function, :macro]","category":"page"},{"location":"api/utils/#CryoGrid.Utils.Named","page":"Utilities","title":"CryoGrid.Utils.Named","text":"Named{name,T}\n\nWraps a value of type T with a name type parameter.\n\n\n\n\n\n","category":"type"},{"location":"api/utils/#CryoGrid.Utils.NamedTupleWrapper","page":"Utilities","title":"CryoGrid.Utils.NamedTupleWrapper","text":"NamedTupleWrapper\n\nBase type for container types that hold a NamedTuple of arbitrary field values. NamedTupleWrapper provides dispatches for getproperty and propertynames that forward property name queries to the NamedTuple container. Subtypes are by default assumed to have a field named values that corresponds to the NamedTuple container, but this can be overriden by providing a dispatch for Base.values.\n\n\n\n\n\n","category":"type"},{"location":"api/utils/#CryoGrid.Utils.applyunits-Tuple{Unitful.Units, Number}","page":"Utilities","title":"CryoGrid.Utils.applyunits","text":"applyunits(u::Unitful.Units, x::Number)\n\nConditionally applies unit u to x if and only if x is a unit-free quantity. If x is a unitful quantity, asserts that the unit matches u.\n\n\n\n\n\n","category":"method"},{"location":"api/utils/#CryoGrid.Utils.convert_t-Tuple{DateTime}","page":"Utilities","title":"CryoGrid.Utils.convert_t","text":"convert_t(t::DateTime)\nconvert_t(t::Float64)\n\nConvenience method for converting between Dates.DateTime and solver time.\n\n\n\n\n\n","category":"method"},{"location":"api/utils/#CryoGrid.Utils.convert_tspan-Tuple{Tuple{DateTime, DateTime}}","page":"Utilities","title":"CryoGrid.Utils.convert_tspan","text":"convert_tspan(tspan::Tuple{DateTime,DateTime})\nconvert_tspan(tspan::Tuple{Float64,Float64})\n\nConvenience method for converting between Dates.DateTime and solver time.\n\n\n\n\n\n","category":"method"},{"location":"api/utils/#CryoGrid.Utils.fastiterate-Union{Tuple{N}, Tuple{F}, Tuple{F, Vararg{Tuple{Vararg{Any, N}}, N1} where N1}} where {F, N}","page":"Utilities","title":"CryoGrid.Utils.fastiterate","text":"fastiterate(f!::F, iters::NTuple{N,Any}...) where {F,N}\n\nSame as fastmap but simply invokes f! on each argument set without constructing a tuple.\n\n\n\n\n\n","category":"method"},{"location":"api/utils/#CryoGrid.Utils.fastmap-Union{Tuple{N}, Tuple{F}, Tuple{F, Vararg{Tuple{Vararg{Any, N}}, N1} where N1}} where {F, N}","page":"Utilities","title":"CryoGrid.Utils.fastmap","text":"fastmap(f::F, iter::NTuple{N,Any}...) where {F,N}\n\nSame as map for NTuples but with guaranteed type stability. fastmap is a @generated function which unrolls calls to f into a loop-free tuple construction expression.\n\n\n\n\n\n","category":"method"},{"location":"api/utils/#CryoGrid.Utils.getscalar-Tuple{Number}","page":"Utilities","title":"CryoGrid.Utils.getscalar","text":"getscalar(x)\ngetscalar(x, i)\n\nHelper method for generalizing between arrays and scalars. Without an index, retrieves the first element of x if x is an array, otherwise simply returning x. If an index i, is specified, returns the ith value of x if x is an array, or x otherwise. Note that this method is not strictly necessary since Julia allows for scalar quantities to be accessed at the first index like an array; however, the point is to make it expliclty clear in scalar-typed code that a state variable is treated as such and is not a vector valued quantity.\n\n\n\n\n\n","category":"method"},{"location":"api/utils/#CryoGrid.Utils.pstrip-Tuple{Any}","page":"Utilities","title":"CryoGrid.Utils.pstrip","text":"pstrip(obj; keep_units=false)\n\nStrips Param types and units from obj. If keep_units=true, then Param types will be stripped but units preserved.\n\n\n\n\n\n","category":"method"},{"location":"api/utils/#CryoGrid.Utils.tuplejoin-Tuple{}","page":"Utilities","title":"CryoGrid.Utils.tuplejoin","text":"tuplejoin([x, y], z...)\n\nConcatenates one or more tuples together; should generally be type stable.\n\n\n\n\n\n","category":"method"},{"location":"api/utils/#CryoGrid.Utils.@UFloat_str-Tuple{Any}","page":"Utilities","title":"CryoGrid.Utils.@UFloat_str","text":"Similar to Unitful.@u_str (i.e. u\"kg\") but produces the type of the quantity rather than the instance. NOT conditional on debug mode.\n\n\n\n\n\n","category":"macro"},{"location":"api/utils/#CryoGrid.Utils.@UT_str-Tuple{Any}","page":"Utilities","title":"CryoGrid.Utils.@UT_str","text":"Similar to Unitful.@u_str (i.e. u\"kg\") but produces the type of the unit rather than the instance. NOT conditional on debug mode.\n\n\n\n\n\n","category":"macro"},{"location":"api/utils/#CryoGrid.Utils.@pstrip-Tuple{Any, Vararg{Any, N} where N}","page":"Utilities","title":"CryoGrid.Utils.@pstrip","text":"@pstrip(expr, kwargs...)\n\nConvenience macro for Utils.pstrip; equivalent to pstrip(expr, kwargs...).\n\n\n\n\n\n","category":"macro"},{"location":"api/utils/#CryoGrid.Utils.@setscalar-Tuple{Any}","page":"Utilities","title":"CryoGrid.Utils.@setscalar","text":"Convenience macro for setting scalar (single-element) arrays/vectors. It turns an expression of the form: a.b = ... into a.b[1] = ...\n\nThis is primarily intended for code clarity, i.e to clearly discern scalar and non-scalar values.\n\n\n\n\n\n","category":"macro"},{"location":"api/utils/#CryoGrid.Utils.@sym_str-Tuple{Any}","page":"Utilities","title":"CryoGrid.Utils.@sym_str","text":"sym_str(val)\n\nConvenience macro, sym\"val\", for creating a Symbol from val. Equivalent to Symbol(val). Use in situations where normal Julia :val syntax is not possible, e.g. sym\"1\" instead of Symbol(1) or sym\"my.var\" instead of Symbol(\"my.var\").\n\n\n\n\n\n","category":"macro"},{"location":"api/utils/#CryoGrid.Utils.@threaded-Tuple{Any}","page":"Utilities","title":"CryoGrid.Utils.@threaded","text":"Prepends expr with Threads.@threads if and only if Threads.nthreads() > 1, thus avoiding the overhead of @threads when running in single-threaded mode.\n\nCredit to @ranocha (Hendrik Ranocha) https://discourse.julialang.org/t/overhead-of-threads-threads/53964/22\n\n\n\n\n\n","category":"macro"},{"location":"api/#Index-of-public-API","page":"Index","title":"Index of public API","text":"","category":"section"},{"location":"api/","page":"Index","title":"Index","text":"","category":"page"},{"location":"api/toplevel/#toplevel","page":"CryoGrid","title":"Top level methods and types","text":"","category":"section"},{"location":"api/toplevel/","page":"CryoGrid","title":"CryoGrid","text":"Modules = [CryoGrid]\nPrivate = false\nOrder = [:type, :constant, :function, :macro]","category":"page"},{"location":"api/toplevel/#CryoGrid.Algebraic","page":"CryoGrid","title":"CryoGrid.Algebraic","text":"Algebraic{name,S,T,units,domain} <: Var{name,S,T,units,domain}\n\nDefines an algebraic (implicit) state variable.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.BCKind","page":"CryoGrid","title":"CryoGrid.BCKind","text":"BCKind\n\nTrait that specifies the kind of boundary condition. This can be used to write generic implementations of interact! that are (relatively) agnostic to specific implementations of BoundaryProcess. A good example of this can be found in the boundaryflux method interface.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.BCKind-Union{Tuple{Type{BP}}, Tuple{BP}} where BP<:BoundaryProcess","page":"CryoGrid","title":"CryoGrid.BCKind","text":"BCKind(::Type{T})\n\nCan be overriden by BoundaryProcess types to indicate the type of boundary condition, e.g:\n\nBCKind(::Type{BP}) = Dirichlet()\n\nwhere BP is a BoundaryProcess that provides the boundary conditions.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.Bottom","page":"CryoGrid","title":"CryoGrid.Bottom","text":"Bottom{TProc} <: Layer\n\nGeneric \"bottom\" layer that marks the lower boundary of the subsurface grid.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.BoundaryProcess","page":"CryoGrid","title":"CryoGrid.BoundaryProcess","text":"BoundaryProcess{T<:SubSurfaceProcess}\n\nAbstract base type for boundary processes, i.e. processes that operate at the boundaries of the subsurface. A BoundaryProcess represents the boundary conditions of one or more SubSurfaceProcesses but may include its own diagnostic (or even prognostic) variables, if necessary.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.CGEuler","page":"CryoGrid","title":"CryoGrid.CGEuler","text":"CGEuler <: SciMLBase.AbstractODEAlgorithm\n\nSimple, lightweight implementation of the forward Euler integration algorithm. Does not include support for fancier features such as interpolation, adaptive timestepping, or event handling. In order to get these features, you must install the OrdinaryDiffEq package.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.ConstantBC","page":"CryoGrid","title":"CryoGrid.ConstantBC","text":"ConstantBC{P,S,T} <: BoundaryProcess{P}\n\nConstant boundary condition (of any type/unit) specified by value.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.Coupled2","page":"CryoGrid","title":"CryoGrid.Coupled2","text":"Coupled2{P1,P2} = CoupledProcesses{Tuple{T1,T2}} where {T1,T2}\n\nType alias for coupled processes, i.e. CoupledProcesses{Tuple{P1,P2}}. Coupled provides a simple mechanism for defining new behaviors on multi-processes systems.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.CoupledProcesses","page":"CryoGrid","title":"CryoGrid.CoupledProcesses","text":"CoupledProcesses{TProcs} <: Process\n\nRepresents an explicitly or implicitly coupled system of processes. TProcs is always a Tuple of other processes.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.CryoGridProblem","page":"CryoGrid","title":"CryoGrid.CryoGridProblem","text":"CryoGridProblem{iip,Tu,Tt,Tp,TT,Tsv,Tsf,Tcb,Tdf,Tkw} <: SciMLBase.AbstractODEProblem{Tu,Tt,iip}\n\nRepresents a CryoGrid discretized PDE forward model configuration using the SciMLBase/DiffEqBase problem interface.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.CryoGridProblem-2","page":"CryoGrid","title":"CryoGrid.CryoGridProblem","text":"CryoGridProblem(\n tile::Tile,\n u0::ComponentVector,\n tspan::NTuple{2,Float64},\n p=nothing;\n saveat=3600.0,\n savevars=(),\n save_everystep=false,\n save_start=true,\n save_end=true,\n step_limiter=timestep,\n safety_factor=1,\n max_step=true,\n callback=nothing,\n isoutofdomain=Tiles.domain(tile),\n specialization=SciMLBase.AutoSpecialize,\n function_kwargs=(),\n prob_kwargs...\n)\n\nConstructor for CryoGridProblem that automatically generates all necessary callbacks.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.CryoGridProblem-Tuple{Tile, ComponentArrays.ComponentVector{T, A, Axes} where {T, A, Axes}, Tuple{DateTime, DateTime}, Vararg{Any, N} where N}","page":"CryoGrid","title":"CryoGrid.CryoGridProblem","text":"CryoGridProblem(tile::Tile, u0::ComponentVector, tspan::NTuple{2,DateTime}, args...;kwargs...)\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.Diagnostic","page":"CryoGrid","title":"CryoGrid.Diagnostic","text":"Diagnostic{name,S,T,units,domain} <: Var{name,S,T,units,domain}\n\nDefines a diagnostic variable which is allocated and cached per timestep but not integrated over time.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.DiagnosticVolume","page":"CryoGrid","title":"CryoGrid.DiagnosticVolume","text":"DiagnosticVolume\n\nVolume trait instance for layers with time varying volume where the volume should be treated as a diagnostic state variable.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.FixedVolume","page":"CryoGrid","title":"CryoGrid.FixedVolume","text":"FixedVolume\n\nVolume trait instance for fixed volume layers. Default for all Layer types.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.GridOffset","page":"CryoGrid","title":"CryoGrid.GridOffset","text":"Base type for grid alignment, i.e. either \"edges\" or \"cells\".\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.Layer","page":"CryoGrid","title":"CryoGrid.Layer","text":"Layer\n\nAbstract base type for all layers.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.PeriodicBC","page":"CryoGrid","title":"CryoGrid.PeriodicBC","text":"PeriodicBC{P,S,T1,T2,T3,T4} <: BoundaryProcess{P}\n\nPeriodic boundary condition (of any type/unit) specified by period, amplitude, and phaseshift.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.Process","page":"CryoGrid","title":"CryoGrid.Process","text":"Abstract base type for all dynamical processes.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.Prognostic","page":"CryoGrid","title":"CryoGrid.Prognostic","text":"Prognostic{name,S,T,units,domain} <: Var{name,S,T,units,domain}\n\nDefines a prognostic (time-integrated) state variable.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.PrognosticVolume","page":"CryoGrid","title":"CryoGrid.PrognosticVolume","text":"PrognosticVolume\n\nVolume trait instance for layers with time varying volume where the volume should be treated as a prognostic state variable.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.SubSurface","page":"CryoGrid","title":"CryoGrid.SubSurface","text":"SubSurface <: Layer\n\nAbstract base type for layers in the stratigraphy, e.g. soil, snow, pond, etc.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.SubSurfaceProcess","page":"CryoGrid","title":"CryoGrid.SubSurfaceProcess","text":"SubSurfaceProcess <: Process\n\nAbstract base type for subsurface processes, i.e. processes that operate at or below the surface, such as heat conduction, water infiltration, etc.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.Top","page":"CryoGrid","title":"CryoGrid.Top","text":"Top{TProc} <: Layer\n\nGeneric \"top\" layer that marks the upper boundary of the subsurface grid.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.Var","page":"CryoGrid","title":"CryoGrid.Var","text":"Var{name,S<:VarDim,T,units,domain}\n\nBase type for symbolic state variables in the model.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.VarInitializer","page":"CryoGrid","title":"CryoGrid.VarInitializer","text":"VarInitializer{varname}\n\nBase type for state variable initializers. Initializers of this type are dedicated to a specific state variable with name varname and are run before all other initializers.\n\n\n\n\n\n","category":"type"},{"location":"api/toplevel/#CryoGrid.Volume-Tuple{Type{var\"#s59\"} where var\"#s59\"<:Layer}","page":"CryoGrid","title":"CryoGrid.Volume","text":"Volume(::Type{<:Layer})\n\nTrait for layer types that determines whether its spatial volume is temporally invariant, FixedVolume, or varying with time, DiagnosticVolume or PrognosticVolume.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.Coupled-Tuple{Vararg{Process, N} where N}","page":"CryoGrid","title":"CryoGrid.Coupled","text":"Coupled(ps::SubSurfaceProcess...)\n\nConstructs a composite/coupled process from one or more subsurface processes. Alias for CoupledProcesses(ps...).\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.Coupled-Tuple{Vararg{Type{var\"#s28\"} where var\"#s28\"<:Process, N} where N}","page":"CryoGrid","title":"CryoGrid.Coupled","text":"Coupled(types::Type{<:Process}...)\n\nConvenince method which constructs a CoupledProcesses type corresponding to each type in types, e.g:\n\nCoupled(SnowMassBalance, HeatBalance) = CoupledProcesses{Tuple{T1,T2}} where {T1<:SnowMassBalance, T2<:HeatBalance}\n\nalso equivalent to Coupled2{<:SnowMassBalance,<:HeatBalance}.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.boundaryflux-Tuple{BoundaryProcess, Union{Bottom, Top}, SubSurfaceProcess, SubSurface, Any, Any}","page":"CryoGrid","title":"CryoGrid.boundaryflux","text":"boundaryflux(bc::BoundaryProcess, b::Union{Top,Bottom}, p::SubSurfaceProcess, sub::SubSurface, sbc, ssub)\nboundaryflux(s::BCKind, bc::BoundaryProcess, b::Union{Top,Bottom}, p::SubSurfaceProcess, sub::SubSurface, sbc, ssub)\n\nComputes the flux dH/dt at the boundary layer. Calls boundaryflux(BCKind(B),...) to allow for generic implementations by boundary condition type. Note that this method uses a different argument order convention than interact!. This is intended to faciliate stratigraphy independent implementations of certain boundary conditions (e.g. a simple Dirichlet boundary could be applied in the same manner to both the upper and lower boundary).\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.boundaryvalue-Tuple{BoundaryProcess, Any}","page":"CryoGrid","title":"CryoGrid.boundaryvalue","text":"boundaryvalue(bc::BoundaryProcess, state)\n\nComputes the value of the boundary condition specified by bc for the given layer/process combinations. Note that this method uses a different argument order convention than interact!. This is intended to faciliate stratigraphy independent implementations of certain boundary conditions (e.g. a simple Dirichlet boundary could be applied in the same manner to both the upper and lower boundary).\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.caninteract-Tuple{Layer, Layer, Any, Any}","page":"CryoGrid","title":"CryoGrid.caninteract","text":"caninteract(layer1::Layer, layer2::Layer, state1, state2)\ncaninteract(l1::Layer, ::Process, l2::Layer, ::Process, state1, state2)\n\nReturns true if and only if the given layer/process types are able to interact based on the current state. Defaults to checking whether both layers are currently active. This behavior should be overridden by subtypes where necessary.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.computediagnostic!-Tuple{Layer, Any}","page":"CryoGrid","title":"CryoGrid.computediagnostic!","text":"computediagnostic!(l::Layer, state)\ncomputediagnostic!(l::Layer, p::Process, state)\n\nUpdates all diagnostic/non-flux state variables for the given Layer based on the current prognostic state.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.computefluxes!-Tuple{Layer, Any}","page":"CryoGrid","title":"CryoGrid.computefluxes!","text":"computefluxes!(l::Layer, p::Process, state)\n\nCalculates all internal fluxes for a given layer. Note that an instance of computefluxes! must be provided for all non-boundary (subsurface) processes/layers.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.criterion!-Tuple{AbstractArray, GridContinuousEvent, Layer, Any}","page":"CryoGrid","title":"CryoGrid.criterion!","text":"criterion!(out::AbstractArray, ev::GridContinuousEvent, ::Layer, ::Process, state)\n\nEvent criterion for on-grid (i.e. multi-valued) continuous events. The condition for each grid cell should be stored in out.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.criterion-Tuple{Union{ContinuousEvent, DiscreteEvent}, Layer, Any}","page":"CryoGrid","title":"CryoGrid.criterion","text":"criterion(::Event, ::Layer, ::Process, state)\n\nEvent criterion/condition. Should return a Bool for discrete events. For continuous events, this should be a real-valued function where the event is fired at the zeros/roots.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.diagnosticstep!-Tuple{Layer, Any}","page":"CryoGrid","title":"CryoGrid.diagnosticstep!","text":"diagnosticstep!(layer::Layer, state)\n\nOptionally performs discontinuous/discrete-time updates to the layer state. Should return true if the prognostic state was modified and false otherwise. Defaults to returning false.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.initialcondition!-Tuple{Layer, Any}","page":"CryoGrid","title":"CryoGrid.initialcondition!","text":"initialcondition!(::Layer, state)\ninitialcondition!(::Layer, ::Process, state)\ninitialcondition!(::VarInitializer, ::Layer, state)\n\nDefines the initial condition for a given Layer and possibly an initializer. initialcondition! should compute initial values into all relevant state variables in state.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.initialcondition!-Tuple{Layer, Layer, Any, Any}","page":"CryoGrid","title":"CryoGrid.initialcondition!","text":"initialcondition!(layer1::Layer, layer2::Layer, state1, state2)\ninitialcondition!(::Layer, ::Process, ::Layer, ::Process, state1, state2)\n\nDefines the initial condition for two processes on adjacent layers. initialcondition! should write initial values into all relevant state variables in state.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.initializer-Tuple{Symbol, Vararg{Any, N} where N}","page":"CryoGrid","title":"CryoGrid.initializer","text":"initializer(varname::Symbol, args...) = initializer(Val{varname}(), args...)\ninitializer(::Val{varname}, x::Number) => FunctionInitializer w/ constant\ninitializer(::Val{varname}, f::Function) => FunctionInitializer\ninitializer(::Val{varname}, profile::Profile, interp=Linear(), extrap=Flat()) => InterpInitializer\n\nConvenience constructor for VarInitializer that selects the appropriate initializer type based on the arguments.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.initializers-Tuple{Layer}","page":"CryoGrid","title":"CryoGrid.initializers","text":"initializers(::Layer)\ninitializers(::Layer, ::Process)\n\nOptional method that can be used to provide default initializers for state variables that will be run before user provided ones.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.interact!-Tuple{Layer, Layer, Any, Any}","page":"CryoGrid","title":"CryoGrid.interact!","text":"interact!(::Layer, ::Process, ::Layer, ::Process, state1, state2)\n\nDefines a boundary interaction between two processes on adjacent layers. For any interaction, the order of the arguments follows decreasing depth, i.e. the first layer/process is always on top of the second layer/process. This ordering matters and separate dispatches must be provided for interactions in reverse order.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.interactmaybe!-Tuple{Layer, Layer, Any, Any}","page":"CryoGrid","title":"CryoGrid.interactmaybe!","text":"interactmaybe!(layer1::Layer, layer2::Layer, state1, state2)\ninteractmaybe!(layer1::Layer, p1::Process, layer2::Layer, p2::Process, state1, state2)\n\nConditionally invokes interact! if and only if caninteract is true.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.isactive-Tuple{Layer, Any}","page":"CryoGrid","title":"CryoGrid.isactive","text":"isactive(::Layer, state)\n\nReturns a boolean whether or not this layer is currently active in the stratigraphy and should interact with other layers. Note that computediagnostic! and computefluxes! are always invoked regardless of the current state of isactive. The default implementation of isactive always returns true.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.processes-Tuple{Layer}","page":"CryoGrid","title":"CryoGrid.processes","text":"processes(l::Layer)\n\nFetches the process(es) attached to this layer, if any. Returned value must be of type Process. If the layer has more than one process, they should be combined together with Coupled(procs...).\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.resetfluxes!-Tuple{Layer, Any}","page":"CryoGrid","title":"CryoGrid.resetfluxes!","text":"resetfluxes!(layer::Layer, state)\nresetfluxes!(layer::Layer, ::Process, state)\n\nResets all flux variables for the given layer/process to zero.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.timestep-Tuple{Layer, Any}","page":"CryoGrid","title":"CryoGrid.timestep","text":"timestep(::Layer, ::Process, state)\n\nRetrieves the recommended timestep for the given Process defined on the given Layer. The default implementation returns Inf which indicates no timestep restriction. The actual chosen timestep will depend on the integrator being used and other user configuration options.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.timestep-Union{Tuple{P}, Tuple{Layer, CoupledProcesses{P}, Any}} where P","page":"CryoGrid","title":"CryoGrid.timestep","text":"timestep(l::Layer, ps::CoupledProcesses{P}, state) where {P}\n\nDefault implementation of timestep for coupled process types. Calls each process in sequence.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.trigger!-Tuple{CryoGrid.Event, Layer, Any}","page":"CryoGrid","title":"CryoGrid.trigger!","text":"trigger!(::Event, ::Layer, ::Process, state)\ntrigger!(ev::ContinuousEvent, ::ContinuousTrigger, ::Layer, ::Process, state)\ntrigger!(ev::GridContinuousEvent, ::ContinuousTrigger, ::Layer, ::Process, state)\n\nEvent action executed when criterion is met.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.variables-Tuple{Layer, Process}","page":"CryoGrid","title":"CryoGrid.variables","text":"variables(layer::Layer, process::Process)\nvariables(::Layer)\nvariables(::Any)\n\nDefines variables for a given Layer, Process, or arbitrary user-defined type. Implementations should return a Tuple of Vars.\n\n\n\n\n\n","category":"method"},{"location":"api/toplevel/#CryoGrid.volumetricfractions-Tuple{SubSurface, Any}","page":"CryoGrid","title":"CryoGrid.volumetricfractions","text":"volumetricfractions(::SubSurface, state)\nvolumetricfractions(::SubSurface, state, i)\n\nGet the volumetric fractions of each constituent in the volume (at grid cell i, if specificed). All implementations of volumetricfractions are expected to obey a semi-consistent order in the returned Tuple of fractions; the first three consituents should always be θw,θi,θa, i.e. water, ice, and air, followed by any number of additional constituents which may be defined by the specific layer. There is no feasible way to verify that client code actually obeys this ordering, so be sure to double check your implementation, otherwise this can cause very subtle bugs!\n\n\n\n\n\n","category":"method"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"EditURL = \"../../../examples/heat_freeW_samoylov.jl\"","category":"page"},{"location":"examples/heat_freeW_samoylov/#example1","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"","category":"section"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"In this example, we use the preset SoilHeatTile to construct a Tile consisting of a soil column with heat conduction forced using air temperatures from Samoylov Island. The enthalpy-based HeatBalance process defaults to the so-called \"free water\" freezing characteristic which assumes that water only freezes and thaws at a melting temperature of 0°C.","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"First we load the built-in forcing file from Nitzbon et al. 2020 (CryoGrid 3). Note that this will download the forcing files from the AWI NextCloud if they are not already present in the input/ folder.","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"using CryoGrid\nforcings = loadforcings(CryoGrid.Presets.Forcings.Samoylov_ERA_obs_fitted_1979_2014_spinup_extended_2044);\nnothing #hide","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"We use the provided default soil and temperature profiles for Samoylov.","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"soilprofile, tempprofile = CryoGrid.Presets.SamoylovDefault;\nnothing #hide","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"We choose the default grid discretization with 5 cm spacing at the surface.","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"grid = CryoGrid.Presets.DefaultGrid_5cm;\nnothing #hide","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"We construct a state variable initializer for temperature T from the temperature profile.","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"initT = initializer(:T, tempprofile)\ntile = CryoGrid.Presets.SoilHeatTile(\n :H,\n TemperatureBC(forcings.Tair, NFactor(nf=0.6)),\n GeothermalHeatFlux(0.053u\"W/m^2\"),\n soilprofile,\n initT;\n grid=grid\n);\nnothing #hide","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"Here we define the time span:","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"tspan = (DateTime(2010,10,30),DateTime(2011,10,30));\nnothing #hide","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"Evaluate the initial condition","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"u0, du0 = initialcondition!(tile, tspan);\nnothing #hide","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"Here we construct a CryoGridProblem with tile, initial condition, and timespan.","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"prob = CryoGridProblem(tile, u0, tspan, saveat=24*3600.0, savevars=(:T,));\nnothing #hide","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"Solve the configured problem with the built-in forward Euler method. note that, due to compile time, this may take 1-2 minutes when executed in a fresh Julia session. Subsequent solves will be much faster.","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"sol = @time solve(prob);\nout = CryoGridOutput(sol)","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"Now we plot the reuslts!","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"import Plots\nzs = [1,10,20,30,50,100,200,500,1000]u\"cm\"\ncg = Plots.cgrad(:copper,rev=true);\nPlots.plot(out.T[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Temperature\", leg=false, size=(800,500), dpi=150)","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"","category":"page"},{"location":"examples/heat_freeW_samoylov/","page":"Soil heat with free water freeze curve","title":"Soil heat with free water freeze curve","text":"This page was generated using Literate.jl.","category":"page"},{"location":"api/numerics/#Numerics","page":"Numerics","title":"Numerics","text":"","category":"section"},{"location":"api/numerics/","page":"Numerics","title":"Numerics","text":"This module contains a wide range of numerical utilities including math and discretization routines, state variable array caches, and helper types for supporting automatic differentiation.","category":"page"},{"location":"api/numerics/","page":"Numerics","title":"Numerics","text":"DocTestSetup = quote\n using CryoGrid\nend","category":"page"},{"location":"api/numerics/","page":"Numerics","title":"Numerics","text":"Modules = [CryoGrid.Numerics]\nPrivate = false\nOrder = [:type, :function, :macro]","category":"page"},{"location":"api/numerics/#CryoGrid.Numerics.ArrayCache","page":"Numerics","title":"CryoGrid.Numerics.ArrayCache","text":"ArrayCache{T,TA} <: StateVarCache\n\nSimple state variable cache that writes directly into the given array.\n\n\n\n\n\n","category":"type"},{"location":"api/numerics/#CryoGrid.Numerics.AutoGrid","page":"Numerics","title":"CryoGrid.Numerics.AutoGrid","text":"AutoGrid <: DiscretizationStrategy\n\n\n\n\n\n","category":"type"},{"location":"api/numerics/#CryoGrid.Numerics.DiffCache","page":"Numerics","title":"CryoGrid.Numerics.DiffCache","text":"DiffCache{T,TCache}\n\nWrapper around PreallocationTools.DiffCache that stores state variables in forward-diff compatible cache arrays.\n\n\n\n\n\n","category":"type"},{"location":"api/numerics/#CryoGrid.Numerics.DiscretizationStrategy","page":"Numerics","title":"CryoGrid.Numerics.DiscretizationStrategy","text":"Base type for discretization \"strategies\" that generate a spatial discretization (typically a grid).\n\n\n\n\n\n","category":"type"},{"location":"api/numerics/#CryoGrid.Numerics.Grid","page":"Numerics","title":"CryoGrid.Numerics.Grid","text":"struct Grid{S,G,Q,A} <: AbstractDiscretization{Q,1}\n\nRepresents the 1D spatial discretization on which time integration is performed. S is a GridOffset, either Edges or Cells (always edges upon initial construction). The grid representation can be converted (allocation free) between grid edges and cells via the cells and edges methods. G represents the geometry/volume on which the vertical 1D discretization is applied. A is the underlying array type, and Q is the numerical type (e.g. Float64 or a Unitful.Quantity).\n\n\n\n\n\n","category":"type"},{"location":"api/numerics/#CryoGrid.Numerics.PresetGrid","page":"Numerics","title":"CryoGrid.Numerics.PresetGrid","text":"Simple discretization strategy that just supplies a pre-specified grid.\n\n\n\n\n\n","category":"type"},{"location":"api/numerics/#CryoGrid.Numerics.Profile","page":"Numerics","title":"CryoGrid.Numerics.Profile","text":"Profile{N,idxTypes,valTypes}\n\nRepresents a \"profile\" of values indexed typically over depth, i.e:\n\nx₁: value 1 x₂: value 2 ...\n\nwhere xᵢ are the indices.\n\n\n\n\n\n","category":"type"},{"location":"api/numerics/#CryoGrid.Numerics.StateVars","page":"Numerics","title":"CryoGrid.Numerics.StateVars","text":"StateVars{names,griddvars,TU,TV,DF,DG}\n\nGeneric container for holding discretized state arrays from symbolic variables (Var types). The uproto field represetns a \"prototype\" of the prognostic state array which should fully define the state of the system at any given point.\n\n\n\n\n\n","category":"type"},{"location":"api/numerics/#CryoGrid.Numerics.StateVars-Union{Tuple{TArray}, Tuple{TCache}, Tuple{NamedTuple, CryoGrid.Numerics.AbstractDiscretization, Type{TCache}}, Tuple{NamedTuple, CryoGrid.Numerics.AbstractDiscretization, Type{TCache}, Type{TArray}}} where {TCache, TArray<:(AbstractVector{T} where T)}","page":"Numerics","title":"CryoGrid.Numerics.StateVars","text":"StateVars(vars::NamedTuple, D::Numerics.AbstractDiscretization, cachector::Function, arrayproto::Type{A}=Vector) where {A<:AbstractVector}\n\nConstructs a StateVars container from vars and the given discretization D. The function cachector must accept argments f(name::Symbol, x::AbstractVector) where name is the name of the state variable and x is the array generated by the discretization.\n\n\n\n\n\n","category":"method"},{"location":"api/numerics/#CryoGrid.Numerics.divergence!-Tuple{AbstractVector{T} where T, AbstractVector{T} where T, AbstractVector{T} where T}","page":"Numerics","title":"CryoGrid.Numerics.divergence!","text":"divergence!(dx::AbstractVector, j::AbstractVector, Δj::AbstractVector)\n\nCalculates the first-order divergence over a 1D flux vector field j and grid cell lengths Δj. Divergences are added to existing values in dx.\n\n\n\n\n\n","category":"method"},{"location":"api/numerics/#CryoGrid.Numerics.flux!-NTuple{4, AbstractVector{T} where T}","page":"Numerics","title":"CryoGrid.Numerics.flux!","text":"flux!(j::AbstractVector, x::AbstractVector, Δx::AbstractVector, k::AbstractVector)\n\nCalculates the first-order, non-linear spatial flux over a discretized variable x with conductivity k. x is assumed to have shape (N,), Δx shape (N-1,), and j and k shape (N+1,) such that j[2:end-1] represents the fluxes over the inner grid cell faces. Fluxes are added to existing values in j.\n\n\n\n\n\n","category":"method"},{"location":"api/numerics/#CryoGrid.Numerics.harmonicmean!-Tuple{AbstractVector{T} where T, AbstractVector{T} where T, AbstractVector{T} where T}","page":"Numerics","title":"CryoGrid.Numerics.harmonicmean!","text":"harmonicmean!(h::AbstractVector, x::AbstractVector, w::AbstractVector)\n\nVectorized harmonic mean of elements in x with weights w. Output is stored in h, which should have size length(x)-1.\n\n\n\n\n\n","category":"method"},{"location":"api/numerics/#CryoGrid.Numerics.harmonicmean-NTuple{4, Any}","page":"Numerics","title":"CryoGrid.Numerics.harmonicmean","text":"harmonicmean(x₁, x₂, w₁, w₂)\n\nSimple weighted harmonic mean of two values, x₁ and x₂.\n\n\n\n\n\n","category":"method"},{"location":"api/numerics/#CryoGrid.Numerics.makegrid-Tuple{PresetGrid, Tuple{var\"#s59\", var\"#s59\"} where var\"#s59\"<:(Quantity{T, 𝐋, U} where {T, U<:(Unitful.FreeUnits{N, 𝐋, nothing} where N)})}","page":"Numerics","title":"CryoGrid.Numerics.makegrid","text":"makegrid(strategy::DiscretizationStrategy, bounds::NTuple{2,<:DistQuantity})\nmakegrid(layer::Layer, strategy::DiscretizationStrategy, bounds::NTuple{2,<:DistQuantity})\n\nConstructs a Grid spanning bounds using the given strategy. makegrid can also be specified for specific Layer types when layers have specific discretization requirements.\n\n\n\n\n\n","category":"method"},{"location":"api/numerics/#CryoGrid.Numerics.nonlineardiffusion!-NTuple{6, AbstractVector{T} where T}","page":"Numerics","title":"CryoGrid.Numerics.nonlineardiffusion!","text":"nonlineardiffusion!(dx::AbstractVector, j::AbstractVector, x::AbstractVector, Δx::AbstractVector, k::AbstractVector, Δk::AbstractVector)\n\nFast alternative to flux! and divergence! which computes fluxes and divergences (via _flux_kernel and _div_kernel) in a single pass. Note, however, that loop vectorization with @turbo is not possible because of necessary loop-carried dependencies. Fluxes and divergences are added to the existing values stored in j and dx.\n\n\n\n\n\n","category":"method"},{"location":"api/numerics/#CryoGrid.Numerics.updategrid!-Tuple{Grid{Edges, G, Q, A} where {G, Q, A}, AbstractVector{T} where T}","page":"Numerics","title":"CryoGrid.Numerics.updategrid!","text":"updategrid!(grid::Grid{Edges}, edges)\nupdategrid!(grid::Grid{Edges}, z0, thick::AbstractVector)\n\nUpdates all grid values based on new grid edges or an initial z0 + cell thick.\n\n\n\n\n\n","category":"method"},{"location":"api/numerics/#CryoGrid.Numerics.∇-Union{Tuple{F}, Tuple{F, AbstractArray}} where F","page":"Numerics","title":"CryoGrid.Numerics.∇","text":"∇(f::F, x::AbstractArray) where {F}\n\nTakes a function y = f(x) and vector-valued argument x and returns a tuple: (y, ∇ₓy). The gradient is calculated using forward-mode automatic differentiation.\n\n\n\n\n\n","category":"method"},{"location":"api/numerics/#CryoGrid.Numerics.∇-Union{Tuple{F}, Tuple{F, Number}} where F","page":"Numerics","title":"CryoGrid.Numerics.∇","text":"∇(f::F, x::Number) where {F}\n\nTakes a function y = f(x) and argument x and returns a tuple: (y, ∂y∂x). The derivative is calculated using forward-mode automatic differentiation.\n\n\n\n\n\n","category":"method"},{"location":"dev/concepts/#concepts","page":"Concepts","title":"Concepts","text":"","category":"section"},{"location":"dev/concepts/","page":"Concepts","title":"Concepts","text":"This page provides a brief(-ish) overview of the basic programming and Julia-language concepts needed in order to develop and extend CryoGrid.jl.","category":"page"},{"location":"dev/concepts/#Multiple-dispatch","page":"Concepts","title":"Multiple dispatch","text":"","category":"section"},{"location":"dev/concepts/","page":"Concepts","title":"Concepts","text":"The CryoGrid community model in MATLAB reuses code through object-oriented programming (OOP), namely by separating process implementations into standalone classes. These classes are then subtyped by layer classes (e.g. GROUND_freeW_ubT) which then inherit their state variables, parameters, and functions.","category":"page"},{"location":"dev/concepts/","page":"Concepts","title":"Concepts","text":"Unlike MATLAB, Julia is not object-oriented and has no concept of a class (the closest equivalent is a struct). Furthermore, while Julia allows for inheritance from abstract types, it does not allow structs to inherit from other structs, as explained by the Julia documentation:","category":"page"},{"location":"dev/concepts/","page":"Concepts","title":"Concepts","text":"One particularly distinctive feature of Julia's type system is that concrete types may not subtype each other: all concrete types are final and may only have abstract types as their supertypes. While this might at first seem unduly restrictive, it has many beneficial consequences with surprisingly few drawbacks. It turns out that being able to inherit behavior is much more important than being able to inherit structure, and inheriting both causes significant difficulties in traditional object-oriented languages.","category":"page"},{"location":"dev/concepts/","page":"Concepts","title":"Concepts","text":"In light of this, CryoGrid.jl takes a different approach to effectively reuse code between model components. Rather than having layers \"inherit\" processes, subtypes of Layer are composed of one or more processes as well as parameter types which then determine which methods are invoked at runtime. This is facilitated by one of Julia's key features, multiple dispatch. Multiple dispatch means that methods are dynamically invoked based on the (runtime) types of all their arguments. This is in constrast to most OOP languages (also MATLAB) where dynamic dispatch occurs based on only one (implicit) argument, i.e. the type of the \"object\" or class itself. As an example, consider the CryoGrid method computediagnostic!:","category":"page"},{"location":"dev/concepts/","page":"Concepts","title":"Concepts","text":"using CryoGrid\n\n# Declare two new SubSurface layer types;\n# note that <: basically means \"is a subtype of\"\nstruct Foo <: SubSurface end\nstruct Bar <: SubSurface end\n\nCryoGrid.computediagnostic!(layer::Foo, state) = println(\"hello Foo\")\nCryoGrid.computediagnostic!(layer::Bar, state) = println(\"hello Bar\")\n\nstate = nothing # we can ignore the state for the sake of the example\ncomputediagnostic!(Foo(), state)\ncomputediagnostic!(Bar(), state)","category":"page"},{"location":"dev/concepts/","page":"Concepts","title":"Concepts","text":"Output:","category":"page"},{"location":"dev/concepts/","page":"Concepts","title":"Concepts","text":"hello Foo\nhello Bar","category":"page"},{"location":"dev/concepts/","page":"Concepts","title":"Concepts","text":"In this example, we can see that which computediagnostic! implementation gets invoked is determined by which type is supplied by the caller.","category":"page"},{"location":"dev/concepts/","page":"Concepts","title":"Concepts","text":"Multiple dispatch allows us to extend this naturally to cases where more than one method argument has a declared type:","category":"page"},{"location":"dev/concepts/","page":"Concepts","title":"Concepts","text":"struct MyProcess <: SubSurfaceProcess end\n\nCryoGrid.computediagnostic!(::SubSurface, ::MyProcess, state) = println(\"hello MyProcess on any SubSurface\")\nCryoGrid.computediagnostic!(::Bar, ::MyProcess, state) = println(\"hello MyProcess on Bar\")\n\ncomputediagnostic!(Layer1(), MyProcess() state)\ncomputediagnostic!(Layer2(), MyProcess(), state)","category":"page"},{"location":"dev/concepts/","page":"Concepts","title":"Concepts","text":"Output:","category":"page"},{"location":"dev/concepts/","page":"Concepts","title":"Concepts","text":"hello MyProcess on any SubSurface\nhello MyProcess on Bar","category":"page"},{"location":"dev/concepts/","page":"Concepts","title":"Concepts","text":"Thus, multiple dispatch allows us to write generic code in computediagnostic! that implements MyProcess for any SubSurface layer (i.e. the parent type of both Foo and Bar) in addition to adding specialized code for more specific layer types.","category":"page"},{"location":"api/tiles/#tiles","page":"Tiles","title":"Tiles","text":"","category":"section"},{"location":"api/tiles/","page":"Tiles","title":"Tiles","text":"This module contains Tile, Stratigraphy, and all related methods and types necessary for constructing a 1-D CryoGrid process model.","category":"page"},{"location":"api/tiles/","page":"Tiles","title":"Tiles","text":"Modules = [Tiles]\nPrivate = false\nOrder = [:type, :function, :macro]","category":"page"},{"location":"api/tiles/#CryoGrid.Tiles.JacobianStyle","page":"Tiles","title":"CryoGrid.Tiles.JacobianStyle","text":"JacobianStyle\n\nTrait for indicating Jacobian sparsity of a CryoGrid ODEProblem.\n\n\n\n\n\n","category":"type"},{"location":"api/tiles/#CryoGrid.Tiles.JacobianStyle-Tuple{CryoGrid.Tiles.AbstractTile}","page":"Tiles","title":"CryoGrid.Tiles.JacobianStyle","text":"JacobianStyle(::AbstractTile)\n\nCan be overriden/extended to specify Jacobian structure for specific Tiles.\n\n\n\n\n\n","category":"method"},{"location":"api/tiles/#CryoGrid.Tiles.Stratigraphy","page":"Tiles","title":"CryoGrid.Tiles.Stratigraphy","text":"Stratigraphy{N,TLayers<:NamedTuple,TBoundaries}\n\nDefines a 1-dimensional stratigraphy by connecting a top and bottom layer to one or more subsurface layers.\n\n\n\n\n\n","category":"type"},{"location":"api/tiles/#CryoGrid.Tiles.Tile","page":"Tiles","title":"CryoGrid.Tiles.Tile","text":"Tile{TStrat,TGrid,TStates,TInits,TEvents,iip} <: AbstractTile{iip}\n\nDefines the full specification of a single CryoGrid tile; i.e. stratigraphy, grid, and state variables.\n\n\n\n\n\n","category":"type"},{"location":"api/tiles/#CryoGrid.Tiles.Tile-Tuple{SciMLBase.DEIntegrator}","page":"Tiles","title":"CryoGrid.Tiles.Tile","text":"Tile(integrator::SciMLBase.DEIntegrator)\n\nConstructs a Tile from a SciMLBase DEIntegrator.\n\n\n\n\n\n","category":"method"},{"location":"api/tiles/#CryoGrid.Tiles.Tile-Union{Tuple{A}, Tuple{T}, Tuple{Stratigraphy, DiscretizationStrategy, Vararg{CryoGrid.Initializer, N} where N}} where {T<:CryoGrid.Numerics.StateVarCache, A<:AbstractArray}","page":"Tiles","title":"CryoGrid.Tiles.Tile","text":"Tile(\n @nospecialize(strat::Stratigraphy),\n @nospecialize(discretization_strategy::DiscretizationStrategy),\n @nospecialize(inits::CryoGrid.Initializer...);\n metadata::Dict=Dict(),\n arraytype::Type{A}=Vector,\n iip::Bool=true,\n chunk_size=nothing,\n)\n\nConstructs a Tile from the given stratigraphy and discretization strategy. arraytype keyword arg should be an array instance (of any arbitrary length, including zero, contents are ignored) that will determine the array type used for all state vectors.\n\n\n\n\n\n","category":"method"},{"location":"api/tiles/#CryoGrid.Tiles.TileState","page":"Tiles","title":"CryoGrid.Tiles.TileState","text":"TileState{TGrid,TStates,Tu,Tt,Tdt}\n\nRepresents the state of a CryoGrid Tile.\n\n\n\n\n\n","category":"type"},{"location":"api/tiles/#CryoGrid.Tiles.getstate","page":"Tiles","title":"CryoGrid.Tiles.getstate","text":"getstate(tile::Tile, u, du, t, dt=1.0)\n\nConstructs a LayerState representing the full state of layername given tile, state vectors u and du, and the time step t.\n\n\n\n\n\n","category":"function"},{"location":"api/tiles/#CryoGrid.Tiles.getstate-Tuple{SciMLBase.DEIntegrator}","page":"Tiles","title":"CryoGrid.Tiles.getstate","text":"getstate(integrator::SciMLBase.DEIntegrator)\n\nBuilds the TileState given an initialized integrator.\n\n\n\n\n\n","category":"method"},{"location":"api/tiles/#CryoGrid.Tiles.withaxes-Tuple{AbstractArray, Tile}","page":"Tiles","title":"CryoGrid.Tiles.withaxes","text":"withaxes(u::AbstractArray, ::Tile)\n\nConstructs a ComponentArray with labeled axes from the given state vector u. Assumes u to be of the same type/shape as setup.uproto.\n\n\n\n\n\n","category":"method"},{"location":"api/tiles/#CryoGrid.Tiles.@Stratigraphy-Tuple","page":"Tiles","title":"CryoGrid.Tiles.@Stratigraphy","text":"Convenience macro for defining stratigraphies with multiple subsurface layers.\n\n\n\n\n\n","category":"macro"},{"location":"dev/contributing/#contrib","page":"Contributing","title":"Contributing","text":"","category":"section"},{"location":"dev/contributing/","page":"Contributing","title":"Contributing","text":"TODO","category":"page"},{"location":"api/solvers/basic_solvers/#Basic-built-in-solvers","page":"Built-in","title":"Basic built-in solvers","text":"","category":"section"},{"location":"api/physics/hydrology/#Hydrology","page":"Hydrology","title":"Hydrology","text":"","category":"section"},{"location":"api/physics/hydrology/","page":"Hydrology","title":"Hydrology","text":"Modules = [Hydrology]\nPrivate = false\nOrder = [:type, :function, :macro]","category":"page"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.BucketScheme","page":"Hydrology","title":"CryoGrid.Hydrology.BucketScheme","text":"BucketScheme <: WaterFlow\n\n\"Bucket\" water scheme for downward advective flow due to gravity.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.DampedET","page":"Hydrology","title":"CryoGrid.Hydrology.DampedET","text":"DampedET{Tftr,Tfev,Tdtr,Tdev}\n\nCorresponds to evapotranspiration scheme 2 described in section 2.2.4 of Westermann et al. (2022).\n\n\n\n\n\n","category":"type"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.Evapotranspiration","page":"Hydrology","title":"CryoGrid.Hydrology.Evapotranspiration","text":"Evapotranspiration\n\nBase type for parameterizations of evapotranspiration (ET).\n\n\n\n\n\n","category":"type"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.HydraulicProperties","page":"Hydrology","title":"CryoGrid.Hydrology.HydraulicProperties","text":"HydraulicProperties\n\nDefault material hydraulic properties.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.NoFlow","page":"Hydrology","title":"CryoGrid.Hydrology.NoFlow","text":"NoFlow <: WaterFlow\n\nRepresents a zero flow scheme \n\n\n\n\n\n","category":"type"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.WaterBalance","page":"Hydrology","title":"CryoGrid.Hydrology.WaterBalance","text":"WaterBalance{TFlow<:WaterFlow,TET<:Union{Nothing,Evapotranspiration},Tdt,Taux,TProp} <: CryoGrid.SubSurfaceProcess\n\nRepresents subsurface water transport processes.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.WaterBalanceProperties","page":"Hydrology","title":"CryoGrid.Hydrology.WaterBalanceProperties","text":"WaterBalanceProperties\n\nNumerical constants shared across water balance implementations.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.WaterFlow","page":"Hydrology","title":"CryoGrid.Hydrology.WaterFlow","text":"WaterFlow\n\nBase type for different formulations of water flow in WaterBalance.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.WaterTableInitializer","page":"Hydrology","title":"CryoGrid.Hydrology.WaterTableInitializer","text":"WaterTableInitializer <: VarInitializer{:sat}\n\nSimple, piecewise constant initializer for saturation state that takes a surface-level saturation sat0 and water table depth z_tab and produces a two-segment, piecewise constant profile with the saturation level set to (sat0 + 1.0) / 2 from the halfway point down to the water table.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.hydraulicconductivity!-Tuple{SubSurface, WaterBalance, Any}","page":"Hydrology","title":"CryoGrid.Hydrology.hydraulicconductivity!","text":"hydraulicconductivity!(sub::SubSurface, water::WaterBalance, state)\n\nComputes hydraulic conductivities for the given subsurface layer and water balance scheme.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.hydraulicproperties-Tuple{SubSurface}","page":"Hydrology","title":"CryoGrid.Hydrology.hydraulicproperties","text":"hydraulicproperties(::SubSurface)\n\nRetrieves the hydraulic properties from the given subsurface layer.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.maxwater-Tuple{SubSurface, WaterBalance}","page":"Hydrology","title":"CryoGrid.Hydrology.maxwater","text":"maxwater(sub::SubSurface, ::WaterBalance) \nmaxwater(sub::SubSurface, water::WaterBalance, state)\nmaxwater(::SubSurface, ::WaterBalance, state, i)\n\nReturns the maximum volumetric water content (saturation point) for grid cell i.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.minwater-Tuple{SubSurface, WaterBalance}","page":"Hydrology","title":"CryoGrid.Hydrology.minwater","text":"minwater(::SubSurface, water::WaterBalance)\nminwater(::SubSurface, water::WaterBalance, state, i)\n\nReturns the minimum volumetric water content (typically field capacity for simplified schemes) for grid cell i. Defaults to zero.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.watercontent!-Tuple{SubSurface, WaterBalance, Any}","page":"Hydrology","title":"CryoGrid.Hydrology.watercontent!","text":"watercontent!(::SubSurface, ::WaterBalance, state)\n\nComputes the volumetric water content from current saturation or pressure state.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.watercontent-Tuple{SubSurface, Any}","page":"Hydrology","title":"CryoGrid.Hydrology.watercontent","text":"watercontent(::SubSurface, state)\nwatercontent(::SubSurface, state, i)\n\nReturns the total water content θwi from the given subsurface layer and/or current state.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/hydrology/#CryoGrid.Hydrology.waterdensity-Tuple{SubSurface}","page":"Hydrology","title":"CryoGrid.Hydrology.waterdensity","text":"waterdensity(sub::SubSurface)\n\nRetrieves the density of water ρw from the given SubSurface layer. Default implementation assumes that WaterBalance is provided as a field water on sub; this can of course, however, be overridden.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/salt/#Salt","page":"Salt","title":"Salt","text":"","category":"section"},{"location":"api/physics/salt/","page":"Salt","title":"Salt","text":"Modules = [CryoGrid.Salt]\nPrivate = false\nOrder = [:type, :function, :macro]","category":"page"},{"location":"api/physics/snow/#Snow","page":"Snow","title":"Snow","text":"","category":"section"},{"location":"api/physics/snow/","page":"Snow","title":"Snow","text":"Modules = [Snow]\nPrivate = false\nOrder = [:type, :function, :macro]","category":"page"},{"location":"api/physics/snow/#CryoGrid.Snow.SnowBC","page":"Snow","title":"CryoGrid.Snow.SnowBC","text":"SnowBC\n\nType alias for any BoundaryProcess compatible with SnowMassBalance.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/snow/#CryoGrid.Snow.SnowMassBalance","page":"Snow","title":"CryoGrid.Snow.SnowMassBalance","text":"SnowMassBalance{TAcc,TAbl} <: CryoGrid.SubSurfaceProcess\n\nSubsurface process for snow layers governing how snow is accumulated and ablated.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/snow/#CryoGrid.Snow.Snowpack","page":"Snow","title":"CryoGrid.Snow.Snowpack","text":"Snowpack{Tpara<:SnowpackParameterization,Tmass<:SnowMassBalance,Theat<:HeatBalance,Twater<:WaterBalance,Taux} <: CryoGrid.SubSurface\n\nGeneric representation of a snowpack \"subsurface\" layer.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/snow/#CryoGrid.Snow.Snowpack-Tuple{CryoGrid.Snow.SnowpackParameterization}","page":"Snow","title":"CryoGrid.Snow.Snowpack","text":"Snowpack(para::SnowpackParameterization; kwargs...)\n\nConvenience constructor that accepts the parameterization as a positional argument.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/snow/#CryoGrid.Snow.ablation!-Tuple{Top, SnowBC{T} where SnowMassBalance<:T<:SubSurfaceProcess, Snowpack, SnowMassBalance, Any, Any}","page":"Snow","title":"CryoGrid.Snow.ablation!","text":"ablation!(::Top, ::SnowBC, ::Snowpack, ::SnowMassBalance, stop, ssnow)\n\nComputes snow mass balance fluxes due to ablation (e.g. snow melt).\n\n\n\n\n\n","category":"method"},{"location":"api/physics/snow/#CryoGrid.Snow.accumulation!-Tuple{Top, SnowBC{T} where SnowMassBalance<:T<:SubSurfaceProcess, Snowpack, SnowMassBalance, Any, Any}","page":"Snow","title":"CryoGrid.Snow.accumulation!","text":"accumulation!(::Top, ::SnowBC, ::Snowpack, ::SnowMassBalance, stop, ssnow)\n\nComputes snow mass balance fluxes due to accumulation (e.g. snowfall).\n\n\n\n\n\n","category":"method"},{"location":"api/physics/snow/#CryoGrid.Snow.snowdensity-Tuple{Snowpack, Any}","page":"Snow","title":"CryoGrid.Snow.snowdensity","text":"snowdensity(::Snowpack, state)\n\nRetrieve the current snow density.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/snow/#CryoGrid.Snow.snowdepth-Tuple{Snowpack, SnowMassBalance, Any}","page":"Snow","title":"CryoGrid.Snow.snowdepth","text":"snowdepth(::Snowpack, ::SnowMassBalance, state)\n\nRetrieve the current snow depth.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/snow/#CryoGrid.Snow.snowfall-Tuple{SnowBC{T} where SnowMassBalance<:T<:SubSurfaceProcess, Any}","page":"Snow","title":"CryoGrid.Snow.snowfall","text":"snowfall(::SnowBC, state)\n\nRetrieves the current snowfall flux for the given SnowBC. Defaults to state.jw_snow.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/soils/#Soils","page":"Soils","title":"Soils","text":"","category":"section"},{"location":"api/physics/soils/","page":"Soils","title":"Soils","text":"Modules = [Soils]\nPrivate = false\nOrder = [:type, :function, :macro]","category":"page"},{"location":"api/physics/soils/#CryoGrid.Soils.AbstractGround","page":"Soils","title":"CryoGrid.Soils.AbstractGround","text":"AbstractGround{Tpara<:GroundParameterization,Theat<:Optional{HeatBalance},Twater<:Optional{WaterBalance}} <: SubSurface\n\nBase type for all ground layers defining heat and water balance schemes.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/soils/#CryoGrid.Soils.Ground","page":"Soils","title":"CryoGrid.Soils.Ground","text":"Ground{Tpara,Theat<:Optional{HeatBalance},Twater<:Optional{WaterBalance},Taux} <: Soil{Tpara,Theat,Twater}\n\nGeneric representation of a Ground layer with material parameterization para.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/soils/#CryoGrid.Soils.Ground-Tuple{CryoGrid.Numerics.Profile{N, IT, VT} where {N, IT<:(Tuple{Vararg{T, N}} where T), VT<:Tuple{Vararg{SoilParameterization, N}}}}","page":"Soils","title":"CryoGrid.Soils.Ground","text":"Ground(soilprofile::SoilProfile; kwargs...)\n\n\n\n\n\n","category":"method"},{"location":"api/physics/soils/#CryoGrid.Soils.Heterogeneous","page":"Soils","title":"CryoGrid.Soils.Heterogeneous","text":"Heterogeneous{V,N,D,Taux} <: SoilParameterization\n\nSpecial SoilParameterization which wraps a Profile of another soil parameterization type to indicate that it should be heterogeneous with over depth.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/soils/#CryoGrid.Soils.MineralOrganic","page":"Soils","title":"CryoGrid.Soils.MineralOrganic","text":"MineralOrganic{Tpor,Tsat,Torg} <: SoilParameterization\n\nRepresents a simple organic/mineral soil mixutre in terms of its characteristic fractions: i.e. natural porosity, saturation, and organic solid fraction. This is the standard CryoGrid representation of a discrete soil volume.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/soils/#CryoGrid.Soils.RichardsEq","page":"Soils","title":"CryoGrid.Soils.RichardsEq","text":"RichardsEq{Tform<:RichardsEqFormulation,Tswrc<:SWRC,Taux,TΩ} <: Hydrology.WaterFlow\n\nThe Richardson-Richards equation describes the flow of water in porous media under unsaturated condition.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/soils/#CryoGrid.Soils.Soil","page":"Soils","title":"CryoGrid.Soils.Soil","text":"Soil{Tpara,Theat,Twater}\n\nType alias for any AbstractGround layer with parameterization of type SoilParameterization.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/soils/#CryoGrid.Soils.SoilParameterization","page":"Soils","title":"CryoGrid.Soils.SoilParameterization","text":"SoilParameterization\n\nBase type for parameterizations of soil consituents.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/soils/#CryoGrid.Soils.SoilProfile","page":"Soils","title":"CryoGrid.Soils.SoilProfile","text":"SoilProfile{N,IT,VT} = Profile{N,IT,VT} where {N,IT<:NTuple{N},VT<:NTuple{N,SoilParameterization}}\n\nAlias for depthwise Profile where the values are SoilParameterization types.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/soils/#CryoGrid.Soils.SoilProfile-Tuple{Vararg{Pair{var\"#s208\", var\"#s207\"} where {var\"#s208\"<:(Quantity{T, 𝐋, U} where {T, U<:(Unitful.FreeUnits{N, 𝐋, nothing} where N)}), var\"#s207\"<:SoilParameterization}, N} where N}","page":"Soils","title":"CryoGrid.Soils.SoilProfile","text":"SoilProfile(pairs::Pair{<:DistQuantity,<:SoilParameterization}...)\n\nAlias for Profile(pairs...) specific for SoilProfiles.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/soils/#CryoGrid.Soils.SoilTexture","page":"Soils","title":"CryoGrid.Soils.SoilTexture","text":"SoilTexture{Tsand,Tsilt,Tclay}\n\nRepresents soil \"texture\" as a simple mixture of sand, silt, and clay.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/soils/#CryoGrid.Soils.mineral-Tuple{Soil{Tpara, Theat, Twater} where {Tpara<:SoilParameterization, Theat<:Union{Nothing, HeatBalance}, Twater<:Union{Nothing, WaterBalance}}, Any, Any}","page":"Soils","title":"CryoGrid.Soils.mineral","text":"mineral(soil::Soil, state, i)\nmineral(soil::Soil, state)\nmineral(soil::Soil)\n\nRetrieves the volumetric mineral content for the given layer at grid cell i, if provided.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/soils/#CryoGrid.Soils.organic-Tuple{Soil{Tpara, Theat, Twater} where {Tpara<:SoilParameterization, Theat<:Union{Nothing, HeatBalance}, Twater<:Union{Nothing, WaterBalance}}, Any, Any}","page":"Soils","title":"CryoGrid.Soils.organic","text":"organic(soil::Soil, state, i)\norganic(soil::Soil, state)\norganic(soil::Soil)\n\nRetrieves the volumetric organic content for the given layer at grid cell i, if provided.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/soils/#CryoGrid.Soils.porosity-Tuple{Soil{Tpara, Theat, Twater} where {Tpara<:SoilParameterization, Theat<:Union{Nothing, HeatBalance}, Twater<:Union{Nothing, WaterBalance}}, Any, Any}","page":"Soils","title":"CryoGrid.Soils.porosity","text":"porosity(soil::Soil, state, i)\nporosity(soil::Soil, state)\nporosity(soil::Soil)\n\nRetrieves the porosity for the given layer at grid cell i, if provided.\n\n\n\n\n\n","category":"method"},{"location":"api/physics/seb/#Surface-Energy-Balance","page":"Surface Energy Balance","title":"Surface Energy Balance","text":"","category":"section"},{"location":"api/physics/seb/","page":"Surface Energy Balance","title":"Surface Energy Balance","text":"Modules = [CryoGrid.Surface]\nPrivate = false\nOrder = [:type, :function, :macro]","category":"page"},{"location":"api/physics/seb/#CryoGrid.Surface.SurfaceEnergyBalance","page":"Surface Energy Balance","title":"CryoGrid.Surface.SurfaceEnergyBalance","text":"SurfaceEnergyBalance{TSolution,TStabFun,TPara,F} <: BoundaryProcess{HeatBalance}\n\nSurface energy balance upper boundary condition.\n\n\n\n\n\n","category":"type"},{"location":"api/physics/seb/#CryoGrid.Surface.SurfaceWaterBalance","page":"Surface Energy Balance","title":"CryoGrid.Surface.SurfaceWaterBalance","text":"SurfaceWaterBalance{TR,TS} <: BoundaryProcess{Union{WaterBalance, SnowMassBalance}}\n\nThe SurfaceWaterBalance represents the closure of the water balance at the surface and acts as both a Neumann-type upper boundary condition for snow and water fluxes as well as an accountant for the water mass balance at the surface.\n\n\n\n\n\n","category":"type"},{"location":"examples/heat_freeW_lite_implicit/","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"EditURL = \"../../../examples/heat_freeW_lite_implicit.jl\"","category":"page"},{"location":"examples/heat_freeW_lite_implicit/#example7","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"","category":"section"},{"location":"examples/heat_freeW_lite_implicit/","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"This example is very similar to Example 1 but uses the fast implicit CryoGridLite solver of Langer et al. 2023.","category":"page"},{"location":"examples/heat_freeW_lite_implicit/","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"Make sure to explicitly import the LiteImplicit submodule which has the relevant solver types.","category":"page"},{"location":"examples/heat_freeW_lite_implicit/","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"using CryoGrid\nusing CryoGrid.LiteImplicit","category":"page"},{"location":"examples/heat_freeW_lite_implicit/","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"Load forcings and build stratigraphy like before.","category":"page"},{"location":"examples/heat_freeW_lite_implicit/","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"forcings = loadforcings(CryoGrid.Presets.Forcings.Samoylov_ERA_MkL3_CCSM4_long_term);\nsoilprofile = SoilProfile(\n 0.0u\"m\" => MineralOrganic(por=0.80,sat=1.0,org=0.75),\n 0.1u\"m\" => MineralOrganic(por=0.80,sat=1.0,org=0.25),\n 0.4u\"m\" => MineralOrganic(por=0.55,sat=1.0,org=0.25),\n 3.0u\"m\" => MineralOrganic(por=0.50,sat=1.0,org=0.0),\n 10.0u\"m\" => MineralOrganic(por=0.30,sat=1.0,org=0.0),\n)\nz_top = -2.0u\"m\"\nz_bot = 1000.0u\"m\"\nupperbc = TemperatureBC(forcings.Tair, NFactor())\nssinit = ThermalSteadyStateInit(T0=-15.0u\"°C\")\nheatop = Heat.EnthalpyImplicit()\nfreezecurve = FreeWater()\nheat = HeatBalance(heatop; freezecurve)\nsoil_layers = map(para -> Ground(para; heat), soilprofile)\nstrat = Stratigraphy(\n z_top => Top(upperbc),\n soil_layers,\n z_bot => Bottom(GeothermalHeatFlux(0.053u\"W/m^2\"))\n);\nmodelgrid = CryoGrid.Presets.DefaultGrid_2cm\ntile = Tile(strat, modelgrid, ssinit);\nnothing #hide","category":"page"},{"location":"examples/heat_freeW_lite_implicit/","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"Since the solver can take daily timesteps, we can easily specify longer simulation time spans at minimal cost. Here we specify a time span of 20 years.","category":"page"},{"location":"examples/heat_freeW_lite_implicit/","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"tspan = (DateTime(2000,1,1), DateTime(2020,1,1))\nu0, du0 = initialcondition!(tile, tspan);\nprob = CryoGridProblem(tile, u0, tspan, saveat=24*3600.0, savevars=(:T,))\nsol = @time solve(prob, LiteImplicitEuler(), dt=24*3600.0)\nout = CryoGridOutput(sol)","category":"page"},{"location":"examples/heat_freeW_lite_implicit/","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"Plot the results!","category":"page"},{"location":"examples/heat_freeW_lite_implicit/","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"import Plots\nzs = [5,10,15,20,25,30,40,50,100,500,1000,5000]u\"cm\"\ncg = Plots.cgrad(:copper,rev=true);\nPlots.plot(out.T[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Temperature\", title=\"\", leg=false, dpi=150)","category":"page"},{"location":"examples/heat_freeW_lite_implicit/","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"CryoGridLite can also be embedded into integrators from OrdinaryDiffEq.jl via the NLCGLite nonlinear solver interface. Note that these sovers generally will not be faster (in execution time) but may be more stable in some cases. Adaptive timestepping can be employed by removing the adaptive=false argument.","category":"page"},{"location":"examples/heat_freeW_lite_implicit/","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"using OrdinaryDiffEq\nsol2 = @time solve(prob, ImplicitEuler(nlsolve=NLCGLite()), adaptive=false, dt=24*3600.0, saveat=24*3600);\nnothing #hide","category":"page"},{"location":"examples/heat_freeW_lite_implicit/","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"","category":"page"},{"location":"examples/heat_freeW_lite_implicit/","page":"Fast heat conduction with CryoGridLite","title":"Fast heat conduction with CryoGridLite","text":"This page was generated using Literate.jl.","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"EditURL = \"../../../examples/heat_simple_autodiff_grad.jl\"","category":"page"},{"location":"examples/heat_simple_autodiff_grad/#example10","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"","category":"section"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"This example demonstrates how to parameterize and differentiate a simulation with two parameters (summer and winter n-factors) using forward-mode automatic simulation.","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"TODO: add more detail/background","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"Set up forcings and boundary conditions similarly to other examples:","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"using CryoGrid\nforcings = loadforcings(CryoGrid.Presets.Forcings.Samoylov_ERA_obs_fitted_1979_2014_spinup_extended_2044);\nsoilprofile, tempprofile = CryoGrid.Presets.SamoylovDefault\ngrid = CryoGrid.Presets.DefaultGrid_5cm\ninitT = initializer(:T, tempprofile)\ntile = CryoGrid.Presets.SoilHeatTile(\n :T,\n TemperatureBC(forcings.Tair, NFactor(nf=Param(0.5), nt=Param(0.9))),\n GeothermalHeatFlux(0.053u\"W/m^2\"),\n soilprofile,\n initT;\n freezecurve=PainterKarra(),\n grid=grid\n)\ntspan = (DateTime(2010,10,30),DateTime(2011,10,30))\nu0, du0 = @time initialcondition!(tile, tspan);\nnothing #hide","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"Collect model parameters","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"p = CryoGrid.parameters(tile)","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"Create the CryoGridProblem.","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"prob = CryoGridProblem(tile, u0, tspan, p, saveat=24*3600.0);\nnothing #hide","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"Solve the forward problem with default parameter settings:","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"sol = @time solve(prob)\nout = CryoGridOutput(sol)","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"Define a \"loss\" function; here we'll just take the mean over the final temperature field.","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"using Statistics\nfunction loss(p)\n local u0, _ = initialcondition!(tile, tspan, p)\n local prob = CryoGridProblem(tile, u0, tspan, p, saveat=24*3600.0)\n local sol = solve(prob, CGEuler());\n local out = CryoGridOutput(sol)\n return mean(ustrip.(out.T[:,end]))\nend","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"ForwardDiff provides tools for forward-mode automatic differentiation.","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"using ForwardDiff\npvec = vec(p)","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"Compute gradient with forward diff:","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"grad = @time ForwardDiff.gradient(loss, pvec)","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"","category":"page"},{"location":"examples/heat_simple_autodiff_grad/","page":"Computing parameter sensitivities with autodiff","title":"Computing parameter sensitivities with autodiff","text":"This page was generated using Literate.jl.","category":"page"},{"location":"examples/heat_sfcc_samoylov/","page":"Soil heat with SFCC","title":"Soil heat with SFCC","text":"EditURL = \"../../../examples/heat_sfcc_samoylov.jl\"","category":"page"},{"location":"examples/heat_sfcc_samoylov/#example3","page":"Soil heat with SFCC","title":"Soil heat with SFCC","text":"","category":"section"},{"location":"examples/heat_sfcc_samoylov/","page":"Soil heat with SFCC","title":"Soil heat with SFCC","text":"In this example, we use the preset SoilHeatTile to construct a Tile consisting of a soil column with heat conduction forced using air temperatures from Samoylov Island. We use the SFCC formulation of Painter and Karra (2014). For the purpose of demonstration, we use the apparent heat capacity form of the heat equation in this example (i.e. Heat.Diffusion1D(:T)).","category":"page"},{"location":"examples/heat_sfcc_samoylov/","page":"Soil heat with SFCC","title":"Soil heat with SFCC","text":"using CryoGrid","category":"page"},{"location":"examples/heat_sfcc_samoylov/","page":"Soil heat with SFCC","title":"Soil heat with SFCC","text":"First we set up the model:","category":"page"},{"location":"examples/heat_sfcc_samoylov/","page":"Soil heat with SFCC","title":"Soil heat with SFCC","text":"forcings = loadforcings(CryoGrid.Presets.Forcings.Samoylov_ERA5_fitted_daily_1979_2020);\ngrid = CryoGrid.Presets.DefaultGrid_5cm\nsoilprofile, tempprofile = CryoGrid.Presets.SamoylovDefault\ninitT = initializer(:T, tempprofile)\nsfcc = PainterKarra(swrc=VanGenuchten(α=0.1, n=2.0))\nupperbc = TemperatureBC(forcings.Tair, NFactor(nf=0.6))\nlowerbc = GeothermalHeatFlux(0.053u\"W/m^2\")\ntile = CryoGrid.Presets.SoilHeatTile(upperbc, lowerbc, soilprofile, initT; grid=grid, freezecurve=sfcc)\ntspan = (DateTime(2010,10,30),DateTime(2011,10,30))\nu0, du0 = initialcondition!(tile, tspan)\nprob = CryoGridProblem(tile, u0, tspan, saveat=3*3600.0, savevars=(:T,));\nnothing #hide","category":"page"},{"location":"examples/heat_sfcc_samoylov/","page":"Soil heat with SFCC","title":"Soil heat with SFCC","text":"... then solve it with the built-in forward Euler integrator.","category":"page"},{"location":"examples/heat_sfcc_samoylov/","page":"Soil heat with SFCC","title":"Soil heat with SFCC","text":"sol = @time solve(prob);\nout = CryoGridOutput(sol)","category":"page"},{"location":"examples/heat_sfcc_samoylov/","page":"Soil heat with SFCC","title":"Soil heat with SFCC","text":"Finally, plot the resulting temperatures.","category":"page"},{"location":"examples/heat_sfcc_samoylov/","page":"Soil heat with SFCC","title":"Soil heat with SFCC","text":"import Plots\nzs = [5,10,15,20,25,30,40,50,100,500]u\"cm\"\nDiagnostics.plot_at_depths(:T, out, zs, ylabel=\"Temperature (°C)\")","category":"page"},{"location":"examples/heat_sfcc_samoylov/","page":"Soil heat with SFCC","title":"Soil heat with SFCC","text":"","category":"page"},{"location":"examples/heat_sfcc_samoylov/","page":"Soil heat with SFCC","title":"Soil heat with SFCC","text":"This page was generated using Literate.jl.","category":"page"},{"location":"api/io/#InputOutput","page":"InputOutput","title":"InputOutput","text":"","category":"section"},{"location":"api/io/","page":"InputOutput","title":"InputOutput","text":"This module provides types and utilities for reading input files (i.e. parameters and forcings) as well as saving model outputs.","category":"page"},{"location":"api/io/","page":"InputOutput","title":"InputOutput","text":"Modules = [CryoGrid.InputOutput]\nPrivate = false\nOrder = [:type, :function, :macro]","category":"page"},{"location":"api/io/#CryoGrid.InputOutput.ConstantForcing","page":"InputOutput","title":"CryoGrid.InputOutput.ConstantForcing","text":" ConstantForcing{unit,T} <: Forcing{unit,T}\n\nSimple Forcing type that just returns a constant value. This type is primarily intended for writing tests but could still be used in applications if necessary.\n\n\n\n\n\n","category":"type"},{"location":"api/io/#CryoGrid.InputOutput.CryoGridOutput","page":"InputOutput","title":"CryoGrid.InputOutput.CryoGridOutput","text":"CryoGridOutput{TSol}\n\nHelper type that stores the raw output from a CryoGrid run along with DimArray views of all logged variables. CryoGridOutput overrides Base.getproperty to allow for direct dot-syntax access of state variables. For example, if your model has a grid variable named T, out.T returns a DimArray with indexed time and depth axes. For OrdinaryDiffEq.jl outputs, the ODESolution can be accessed via out.sol, or for convenience, the continuous solution at time t can be computed via out(t) which is equivalent to withaxes(out.sol(t)).\n\n\n\n\n\n","category":"type"},{"location":"api/io/#CryoGrid.InputOutput.CryoGridOutput-Tuple{Real}","page":"InputOutput","title":"CryoGrid.InputOutput.CryoGridOutput","text":"Evaluates the continuous solution at time t.\n\n\n\n\n\n","category":"method"},{"location":"api/io/#CryoGrid.InputOutput.CryoGridOutput-Tuple{SciMLBase.AbstractODESolution, Tuple{DateTime, DateTime}}","page":"InputOutput","title":"CryoGrid.InputOutput.CryoGridOutput","text":"CryoGridOutput(sol::TSol, tspan::NTuple{2,Float64}=(-Inf,Inf)) where {TSol<:SciMLBase.AbstractODESolution}\n\nConstructs a CryoGridOutput from the given ODESolution. Optional argument tspan restricts the time span of the output.\n\n\n\n\n\n","category":"method"},{"location":"api/io/#CryoGrid.InputOutput.CryoGridParams","page":"InputOutput","title":"CryoGrid.InputOutput.CryoGridParams","text":"CryoGridParams{T,TM} <: DenseArray{T,1}\n\nWraps a ModelParameters.Model parameter handler for CryoGrid types. It is recommended not to use this type directly in math or linear algebra operations but rather to use Base.values to obtain a normal array of parameter values.\n\n\n\n\n\n","category":"type"},{"location":"api/io/#CryoGrid.InputOutput.CryoGridParams-Tuple{Any}","page":"InputOutput","title":"CryoGrid.InputOutput.CryoGridParams","text":"CryoGridParams(obj)\n\nConstructs a modelParameters.Model wrapped with CryoGridParams from obj. If full_metadata is true, additonal fields for nested Parameterization types will be added.\n\n\n\n\n\n","category":"method"},{"location":"api/io/#CryoGrid.InputOutput.Forcing","page":"InputOutput","title":"CryoGrid.InputOutput.Forcing","text":" Forcing{unit,T}\n\nAbstract type representing a generic external forcing term.\n\n\n\n\n\n","category":"type"},{"location":"api/io/#CryoGrid.InputOutput.ForcingFormat","page":"InputOutput","title":"CryoGrid.InputOutput.ForcingFormat","text":"Represents an externally specified format for forcing inputs. IO functions should dispatch on specific types T<:ForcingFormat that they implement.\n\n\n\n\n\n","category":"type"},{"location":"api/io/#CryoGrid.InputOutput.ForcingFormatJSON","page":"InputOutput","title":"CryoGrid.InputOutput.ForcingFormatJSON","text":"JSON forcing input format (from CryoGridLite) with specified version indicator.\n\n\n\n\n\n","category":"type"},{"location":"api/io/#CryoGrid.InputOutput.ForcingFormatNCD","page":"InputOutput","title":"CryoGrid.InputOutput.ForcingFormatNCD","text":"NetCDF forcing input format.\n\n\n\n\n\n","category":"type"},{"location":"api/io/#CryoGrid.InputOutput.Forcings","page":"InputOutput","title":"CryoGrid.InputOutput.Forcings","text":" Forcings{names,TF,TMeta}\n\nGeneric container for forcing types with optional metadata.\n\n\n\n\n\n","category":"type"},{"location":"api/io/#CryoGrid.InputOutput.InterpolatedForcing","page":"InputOutput","title":"CryoGrid.InputOutput.InterpolatedForcing","text":" InterpolatedForcing{unit,T,TI}\n\nForcing data provided by a discrete time series of data.\n\n\n\n\n\n","category":"type"},{"location":"api/io/#CryoGrid.InputOutput.InterpolatedForcing-Tuple{Number}","page":"InputOutput","title":"CryoGrid.InputOutput.InterpolatedForcing","text":"Get interpolated forcing value at t seconds from t0.\n\n\n\n\n\n","category":"method"},{"location":"api/io/#CryoGrid.InputOutput.ParamsJSON","page":"InputOutput","title":"CryoGrid.InputOutput.ParamsJSON","text":"JSON parameter input format (from CryoGridLite). Not yet implemented.\n\n\n\n\n\n","category":"type"},{"location":"api/io/#CryoGrid.InputOutput.ParamsYAML","page":"InputOutput","title":"CryoGrid.InputOutput.ParamsYAML","text":"YAML parameter input format matching that of the CryoGrid community model. Not yet implemented.\n\n\n\n\n\n","category":"type"},{"location":"api/io/#CryoGrid.InputOutput.TimeVaryingForcing","page":"InputOutput","title":"CryoGrid.InputOutput.TimeVaryingForcing","text":" TimeVaryingForcing{unit,T} <: Forcing{unit,T}\n\nSimple Forcing type that evaluates a given function f(t) of where t is the current time.\n\n\n\n\n\n","category":"type"},{"location":"api/io/#CryoGrid.InputOutput.TransformedForcing","page":"InputOutput","title":"CryoGrid.InputOutput.TransformedForcing","text":" TransformedForcing(transformed_unit,orig_unit,TF,T,TO<:Forcing{orig_unit,T}) <: Forcing{transformed_unit,T}\n\nWraps another Forcing and applies an arbitrary transformation f when evaluated. The transformed unit can either be automatically determined on construction or specified directly.\n\n\n\n\n\n","category":"type"},{"location":"api/io/#CryoGrid.InputOutput.loadforcings-Tuple{String}","page":"InputOutput","title":"CryoGrid.InputOutput.loadforcings","text":"loadforcings(filename::String)::Forcings\nloadforcings(resource::Resource; outdir=DEFAULT_FORCINGS_DIR)::Forcings\nloadforcings([format::ForcingFormat], filename::String; outdir=DEFAULT_FORCINGS_DIR)::Forcings\n\nLoads forcing data from the given file according to the format specified by format. By default, the forcing format is automatically detected via detectformat. Returns a Forcings struct containing all forcing data and metadata \n\n\n\n\n\n","category":"method"},{"location":"api/io/#CryoGrid.InputOutput.time_derivative_forcing-Union{Tuple{InterpolatedForcing{unit, T, TI} where {T, TI<:(Interpolations.AbstractInterpolation{T, N, IT} where {N, IT<:Union{Tuple{Vararg{Interpolations.InterpolationType, N} where N}, Interpolations.InterpolationType}})}}, Tuple{unit}, Tuple{InterpolatedForcing{unit, T, TI} where {T, TI<:(Interpolations.AbstractInterpolation{T, N, IT} where {N, IT<:Union{Tuple{Vararg{Interpolations.InterpolationType, N} where N}, Interpolations.InterpolationType}})}, Symbol}} where unit","page":"InputOutput","title":"CryoGrid.InputOutput.time_derivative_forcing","text":"time_derivative_forcing(\n f::InterpolatedForcing{unit},\n new_name::Symbol;\n interp=Numerics.Linear()\n) where {unit}\n\nComputes the finite difference time derivative of the given InterpolatedForcing time series and returns a new forcing with units [unit].s⁻¹\n\n\n\n\n\n","category":"method"},{"location":"manual/coupling/#coupling","page":"Coupling layers and processes","title":"Coupling","text":"","category":"section"},{"location":"manual/coupling/","page":"Coupling layers and processes","title":"Coupling layers and processes","text":"TODO","category":"page"},{"location":"manual/overview/#overview","page":"Overview","title":"Overview","text":"","category":"section"},{"location":"manual/overview/#Setting-up-a-model","page":"Overview","title":"Setting up a model","text":"","category":"section"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"DocTestSetup = quote\n using CryoGrid\nend","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"At the highest level, a model in CryoGrid.jl is defined by one or more Tiles each consisting of a Grid and a Stratigraphy, constructed top-down from individual Layers, each of which has one or more Processes. Each layer in the Stratigraphy is assigned a depth, which then aligns it with the Grid. All models must consist of at least three layers/nodes: Top and Bottom layers with corresponding boundary conditions, as well as one or more SubSurface layers. Here we define a simple three-layer model (or one-layer, exlcuding the boundaries) with a single sub-surface process, i.e. HeatBalance (heat conduction):","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"# ... load forcings, set up profiles, etc.\n# see examples/heat_vgfc_seb_saoylov_custom.jl for more details\nstrat = Stratigraphy(\n -2.0u\"m\" => Top(SurfaceEnergyBalance(Tair,pr,q,wind,Lin,Sin,z)),\n 0.0u\"m\" => Ground(soilprofile, HeatBalance(:H; freezecurve=DallAmico())),\n 1000.0u\"m\" => Bottom(GeothermalHeatFlux(0.053u\"J/s/m^2\"))\n);\ngrid = CryoGrid.Presets.DefaultGrid_5cm\n# define initial conditions for temperature using a given profile;\n# The default initializer linearly interpolates between profile points.\ninitT = initializer(:T, tempprofile)\ntile = Tile(strat, grid, initT);","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"This model can then be used to construct a CryoGridProblem:","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"tspan = (DateTime(2010,10,30),DateTime(2011,10,30))\np = parameters(tile)\nu0 = initialcondition!(tile, tspan, p, initT)\nprob = CryoGridProblem(tile, u0, tspan, p, saveat=24*3600.0, savevars=(:T,)) # produces an ODEProblem with problem type CryoGridODEProblem","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"It can then be solved/integrated using the solve function (from DiffEqBase and OrdinaryDiffEq):","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"# solve and construct CryoGridOutput from solution\nsol = @time solve(prob, saveat=24*3600.0, progress=true);\nout = CryoGridOutput(sol)","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"The resulting CryoGridOutput type provides DimArrays containing the model outputs over time and space:","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"julia> out.T\n278×366 DimArray{Float64,2} with dimensions: \n Z: Quantity{Float64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}[0.01 m, 0.03 m, …, 850.0 m, 950.0 m] Sampled: Ordered Irregular Points,\n Ti (Time): DateTime[2010-10-30T00:00:00, …, 2011-10-30T00:00:00] Sampled: Ordered Irregular Points","category":"page"},{"location":"manual/overview/#Defining-model-behavior","page":"Overview","title":"Defining model behavior","text":"","category":"section"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"Notice that, in the example above, it is types such as Ground, HeatBalance, DallAmico, etc. that specify which components the model should use. These components are defined by adding method dispatches to the CryoGrid interface methods. State variables are declared via the variables method, e.g:","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"variables(soil::Soil, heat::HeatBalance{<:EnthalpyBased}) = (\n Prognostic(:H, OnGrid(Cells), u\"J/m^3\"),\n Diagnostic(:T, OnGrid(Cells), u\"°C\"),\n Diagnostic(:C, OnGrid(Cells), u\"J//K*/m^3\"),\n Diagnostic(:∂H∂T, OnGrid(Cells), u\"J/K/m^3\"),\n Diagnostic(:k, OnGrid(Edges), u\"W/m/K\"),\n Diagnostic(:kc, OnGrid(Cells), u\"W//m/K\"),\n)","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"When the HeatBalance process is assigned to a Soil layer, Tile will invoke this method and create state variables corresponding to each Var. Prognostic variables are assigned derivatives (in this case, dH, since H is the prognostic state variable) and integrated over time. Diagnostic variables provide in-place caches for derived/intermediary state variables.","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"Each variable definition consists of a name (a Julia Symbol), a type, and a shape. For variables discretized on the grid, the shape is specified by OnGrid, which will generate an array of the appropriate size when the model is compiled. The arguments Cells and Edges specify whether the variable should be defined on the grid cells or edges respecitvely.","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"The real work finally happens in computediagnostic! and computefluxes!, the latter of which should be used to compute the time derivatives (here dH). interact! defines the behavior at the boundaries and should be used to compute the derivatives (and any other necessary values) at the interface between layers.","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"We can take as an example the implementation of computefluxes! for enthalpy-based heat conduction (note that jH is a diagnostic variable representing the energy flux over each cell edge):","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"function CryoGrid.computefluxes!(::SubSurface, ::HeatBalance{<:FreezeCurve,<:EnthalpyBased}, state)\n Δk = Δ(state.grid) # cell sizes\n ΔT = Δ(cells(state.grid)) # midpoint distances\n # compute internal fluxes and non-linear diffusion assuming boundary fluxes have been set\n nonlineardiffusion!(state.dH, state.jH, state.T, ΔT, state.k, Δk)\n return nothing\nend","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"warning: Warning\nPrognostic state variables like H in the example above should not be directly modified in the model code. They should only be modified by the calling solver/integrator. This is especially important when using higher order or implicit integrators as unexpected changes to prognostic state may destroy the accuracy of their internal interpolant. For modeling discontinuities, use Events instead.","category":"page"},{"location":"manual/overview/","page":"Overview","title":"Overview","text":"Note that state is (typically) of type LayerState with properties corresponding to the state variables declared by the variables function for Soil and HeatBalance. Additionally, output arrays for the time derivatives are provided (here dH), as well as the current timestep, layer boundary depths, and variable grids (accessible via state.t, and state.grid respectively). Note that state will also contain other variables declared on this Soil layer by other SubSurfaceProcesses, allowing for implicit coupling between processes where appropriate.","category":"page"},{"location":"manual/architecture/#arch","page":"Architecture","title":"Architecture","text":"","category":"section"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"This page provides a general overview of the code organization and architecture of CryoGrid.jl.","category":"page"},{"location":"manual/architecture/#Modular-design","page":"Architecture","title":"Modular design","text":"","category":"section"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"Modular programming in software design revolves around the separation of computer programs into \"modules\" that can be independently constructed, tested, and coupled together into a larger system. The benefits of modular programming are well documented and have been common practice in software engineering for decades [1]. In the context of physical modeling, modular programming has the potential to facilitate rapid prototyping and comparison of different model configurations, parameterizations, and process interactions [2].","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"The term \"modular programming\" is fairly abstract and encompasses a wide range of patterns and techniques centered around the central aim of building robust and reusable software components. Namespaces are a commonly employed tool for organizing code into standalone modules or packages that share functionality and naming patterns. Namespaces help avoid name collisions by localizing variable and function names to their enclosing namespace, therefore resolving possible ambiguities.","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"In Julia, namespaces are declared via modules. Modules are more-or-less self-contained namespaces which can be used to organize and isolate code. Modules can \"export\" methods or variables which are intended for external use via export statements. Other modules can then import these methods or variables into their namespace via using and import statements; e.g. using Dates brings all exported names from the Dates module into the current namespace. Note that the top-level module (i.e. in a script or in the REPL) is always called Main.","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"The CryoGrid module provided by CryoGrid.jl is organized into a series of submodules:","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"Name Description Depends on\nUtils Miscellaneous utility methods and types. \nNumerics Utilities for math, array caches, and spatial discretization. Utils\nInputOutput Methods and types related to reading and writing input and output data. Utils,Numerics\nDiagnostics Tools for model diagnostics. Utils,Numerics\nHydrology Methods and types for computing water related quanities. Utils,Numerics\nHeat Methods and types for computing heat and energy related quanities. Utils,Numerics,Hydrology\nSoils Defines Soil layers and provides dispatches for soil-specific physical processes. Utils,Numerics,Hydrology,Heat\nSnow Defines Snowpack layer and provides dispatches for snow processes. Utils,Numerics,Hydrology,Heat\nSalt Provides types and dispatches for coupled heat/salt diffusion in saline soils. Utils,Numerics,Hydrology,Heat,Soils\nSurface Defines boundary processes for the surface such as the surface energy and water balance equations. Utils,Numerics,Hydrology,Heat,Soils,Snow\nTiles Defines the Tile and Stratigraphy types for constructing 1D land models. Utils,Numerics,InputOutput\nDiffEq Provides dispatches and utilities for integrating with solvers from the SciML OrdinaryDiffEq package. Utils,Numerics,InputOutput\nLiteImplicit Provides an implementation of the CryoGridLite solver scheme from Langer et al. 2023. Utils,Numerics\nPresets Provides pre-defined stratigraphies, forcings, and layer configurations to facilitate rapid prototyping. Utils,Numerics,InputOutput,Heat,Hydrology,Soils","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"Note that all submodules depend on the top-level CryoGrid module which declares all of the \"core\" types and method interfaces for defining model behavior. Each submodule may additionally define its own method interfaces related to its own specific process(es) or layer(s).","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"The @reexport macro from the Reexport package is used extensively to propagate exported methods and types to the top-level CryoGrid namespace. This is intended to alleviate the user of the burden to keep track of which types/methods are exported by which submodules. In most cases, it is sufficient to simply import or using the CryoGrid module in order to bring all CryoGrid-related methods and types into scope.","category":"page"},{"location":"manual/architecture/#Model-structure","page":"Architecture","title":"Model structure","text":"","category":"section"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"In the context of CryoGrid, a \"model\" typically refers to one or more Tiles [2] which may or may not be laterally coupled together. A Tile typically corresponds to a rectangular volume discretized along the vertical z-axis, i.e. corresponding physically to depth/elevation. CryoGrid.jl implements this concept by defining a single Tile as a composition of the following:","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"A Stratigraphy with three or more Layers, including a Top layer and a Bottom layer.\nA StateVars cache which stores all non-prognostic state and grid data.\nZero or more VarInitializers that define the intial condition of the prognostic state.\nZero or more layer Events that may or may not be invoked when their trigger conditions are met.","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"The Stratigraphy is simply a Tuple of layers in ascending order of depth (i.e. top to bottom) paired with (initial) upper boundary depths. The thickness of each stratigraphy layer is therefore determined by the distance between the upper boundary of the layer and the upper boundary of the following layer. Depending on the configuration of the layer, this thickness may be either static or dynamic over time. In the latter case, the layer thickness Δz is automatically included as a prognostic state variable.","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"Each SubSurface layer in the stratigraphy will typically consist of one or more Processes as fields on the layer struct which should then be explicitly declared via a dispatch of the processes method. The variables and events methods similarly declare state variables and events respectively that should be defined for any given configuration of the layer.","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"The Tile constructor collects all of the relevant state variables declared by variables and discretizes them according to the given DiscretizationStrategy. The resulting state vectors are initialized in the forward-diff compatible StateVars cache. On each invocation of Tile, the current TileState is constructed from the current prognostic state variable u, parameter vector p, and time step t. The TileState consists of named LayerStates which provide layer-local views of each state variable array, i.e. only grid cells within the layer boundaries are included.","category":"page"},{"location":"manual/architecture/#Control-flow","page":"Architecture","title":"Control flow","text":"","category":"section"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"The CryoGrid module defines three primary methods that can be used to implement the behavior of each Layer/Process in any given model configuration. When updating the model at a particular timestep, these methods are typically invoked in the following order:","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"computediagnostic! updates all (non-flux) state variables and/or derived quantities based on the current (prognostic) state.\ninteract! defines interactions between adjacent layers in the stratigraphy, including fluxes over the layer boundary.\ncomputefluxes! computes all internal fluxes (and the divergence thereof) within each layer, after boundary fluxes are taken into account by interact!.","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"Layer and/or process specific implementations of each of these methods can generally assume that the previous methods have already been invoked by the caller (it is the responsibility of the calling code to ensure that this is the case). This is, for example, the order in which these methods will be invoked by tile(du, u, p t).","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"Note that, due to the nature of multiple dispatch, the execution path (i.e. with respect to the actual source code) of any given model configuration will typically be quite nonlinear and may span multiple source files depending on where the matching method dispatches are defined. Users may find the which provided by Julia (and correspondingly the @which macro from InteractiveUtils) useful in figuring out where executing code is located. For example:","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"using CryoGrid\nusing CryoGrid.Diagnostics\n\nsoil = Ground()\ngrid = CryoGrid.Presets.DefaultGrid_5cm\nstate = Diagnostics.build_dummy_state(grid, soil)\n\n@which CryoGrid.computediagnostic!(soil, state)","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"Output:","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"computediagnostic!(layer::Layer, state)\n @ CryoGrid ~/workspace/sparc-local/repos/CryoGrid/CryoGrid.jl/src/methods.jl:55","category":"page"},{"location":"manual/architecture/#State-variables","page":"Architecture","title":"State variables","text":"","category":"section"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"In order to facilitate modularity and ease-of-use, CryoGrid.jl provides an automated system for initializing and configuring state variables for any given model configuration. Note that there is an important distinction between two types of model state: prognostic and diagnostic.","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"Prognostic(@ref) state variables fully define the state of the system at any given time t. They form what is typically called the \"phase space\" or \"state space\" in the mathematics and engineering literature. In order to be compatible with standard ODE solvers (e.g. like those in OrdinaryDiffEq), CryoGrid.jl automatically assembles prognostic state variables into a single array u (and its corresponding time derivative du) which is returned when initializing a Tile with the initialcondition! method. Note again that this array should always fully define the state of the system.","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"Diagnostic(@ref) state variables act as caches for intermediate and derived quantities defined by the model. They also may, in some cases, provide a means of coupling between different processes (e.g. the heat and water flux variables jH and jw might be updated by more than one Process). For any model configuration, all diagnostic variables should be fully updated (and thus consistent) with the given prognostic state after invoking computediagnostic!, interact!, and computefluxes!.","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"When a Tile is constructed, all variables defined by each layer in the Stratigraphy are collected and then intiailized in StateVars according to the given DiscretizationStrategy.","category":"page"},{"location":"manual/architecture/#References","page":"Architecture","title":"References","text":"","category":"section"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"[1] Bass L, Clements P, Kazman R. Software architecture in practice. Addison-Wesley Professional; 2003.","category":"page"},{"location":"manual/architecture/","page":"Architecture","title":"Architecture","text":"[2] Westermann S, Ingeman-Nielsen T, Scheer J, Aalstad K, Aga J, Chaudhary N, Etzelmüller B, Filhol S, Kääb A, Renette C, Schmidt LS. The CryoGrid community model (version 1.0)–a multi-physics toolbox for climate-driven simulations in the terrestrial cryosphere. Geoscientific Model Development. 2023 May 15;16(9):2607-47.","category":"page"},{"location":"quickstart/#Quick-start","page":"Getting Started","title":"Quick start","text":"","category":"section"},{"location":"quickstart/","page":"Getting Started","title":"Getting Started","text":"After installing CryoGrid.jl, you can get started right away with a simple soil heat model. The Presets module (aliased CryoGrid.Presets) provides pre-specified model configurations that can be obtained with a single function call. It is also possible to modify the soil and initial temperature profiles via SoilLayerConfig; here SamoylovDefault is used.","category":"page"},{"location":"quickstart/","page":"Getting Started","title":"Getting Started","text":"Single layer heat conduction model with free water freeze curve and air temperature upper boundary condition:","category":"page"},{"location":"quickstart/","page":"Getting Started","title":"Getting Started","text":"using CryoGrid\nusing Plots\n\n# load provided forcing data from Samoylov;\n# The forcing file will be automatically downloaded to the input/ folder if not already present.\nforcings = loadforcings(CryoGrid.Presets.Forcings.Samoylov_ERA_obs_fitted_1979_2014_spinup_extended_2044, :Tair => u\"°C\");\n# get preset soil and initial temperature profile for Samoylov\nsoilprofile, tempprofile = CryoGrid.Presets.SamoylovDefault\ninitT = initializer(:T, tempprofile)\n# choose grid with 5cm spacing\ngrid = CryoGrid.Presets.DefaultGrid_5cm\n# basic 1-layer heat conduction model (defaults to free water freezing scheme)\ntile = CryoGrid.Presets.SoilHeatTile(TemperatureBC(forcings.Tair), GeothermalHeatFlux(0.053u\"W/m^2\"), soilprofile, initT, grid=grid)\n# define time span (1 year)\ntspan = (DateTime(2010,11,30),DateTime(2011,11,30))\nu0, du0 = initialcondition!(tile, tspan)\n# CryoGrid front-end for ODEProblem\nprob = CryoGridProblem(tile, u0, tspan, savevars=(:T,))\n# solve discretized system, saving every 3 hours;\nout = @time solve(prob, saveat=3*3600.0, progress=true) |> CryoGridOutput;\nzs = [2,7,12,22,32,42,50,100,500]u\"cm\"\ncg = Plots.cgrad(:copper,rev=true)\nplot(out.T[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Temperature\", leg=false)","category":"page"},{"location":"quickstart/","page":"Getting Started","title":"Getting Started","text":"(Image: Ts_output_freew)","category":"page"},{"location":"quickstart/","page":"Getting Started","title":"Getting Started","text":"Alternatively, we can use a Dall'Amico freeze curve:","category":"page"},{"location":"quickstart/","page":"Getting Started","title":"Getting Started","text":"sfcc = SFCC(DallAmico(swrc=VanGenuchten(α=0.02, n=1.8))) # silt/clay-like freeze curve\ntile2 = CryoGrid.Presets.SoilHeatTile(TemperatureBC(forcings.Tair), GeothermalHeatFlux(0.053u\"W/m^2\"), soilprofile, initT, grid=grid, freezecurve=sfcc)\nu0, du0 = initialcondition!(tile2, tspan)\n# CryoGrid front-end for ODEProblem\nprob2 = CryoGridProblem(tile2, u0, tspan, savevars=(:T,))\nout2 = @time solve(prob2, saveat=3*3600.0, progress=true) |> CryoGridOutput;\nplot(out2.T[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Temperature\", leg=false)","category":"page"},{"location":"quickstart/","page":"Getting Started","title":"Getting Started","text":"Note that SoilHeatTile uses energy as the state variable by default. To use temperature as the state variable instead:","category":"page"},{"location":"quickstart/","page":"Getting Started","title":"Getting Started","text":"# :T is the variable name for temperature, :H represents enthalpy/energy.\n# This is used in the specification of the HeatBalance process type.\n# While this will work with any freeze curve, here we use Westermann (2011) as an example.\nmodel = CryoGrid.Presets.SoilHeatTile(:T, TemperatureBC(forcings.Tair), soilprofile, freezecurve=SFCC(Westermann()))","category":"page"},{"location":"api/solvers/diffeq/#SciML/DiffEq-solvers","page":"SciML/DiffEq","title":"SciML/DiffEq solvers","text":"","category":"section"},{"location":"api/solvers/diffeq/","page":"SciML/DiffEq","title":"SciML/DiffEq","text":"Modules = [CryoGrid.DiffEq]\nPrivate = false\nOrder = [:type, :function, :macro]","category":"page"},{"location":"api/solvers/diffeq/#CryoGrid.DiffEq.CryoGridParameterEnsemble-Tuple{CryoGridProblem, AbstractMatrix{T} where T}","page":"SciML/DiffEq","title":"CryoGrid.DiffEq.CryoGridParameterEnsemble","text":"CryoGridParameterEnsemble(\n prob::CryoGridProblem,\n Θ::AbstractMatrix;\n transform=identity,\n output_func=(sol, i) -> CryoGridOutput(sol),\n reduction=(u,data,i) -> (append!(u,data),false),\n ensprob_kwargs...\n)\n\nConstructs an EnsembleProblem for a m x N parameter matrix Θ, where N is the size of the ensemble and m is the dimensionality of the ensmeble parameter space (e.g. the number of parameters). transform should be a transform function that accepts an m-dimensional vector and produces a parameter vector (or CryoGridParams instance) which matches the output of CryoGrid.parameters. By default, param_map is the identity function; however, it may be customized to permit the construction of reduced-rank or reparameterized ensembles for which the parameter space differs from the full CryoGrid model parameter space.\n\nKeyword arguments:\n\noutput_func: a function (sol,i)::Any which processes the ODESolution for ensemble member i and returns the result. It is recommended to save output to disk for non-trivial time spans to avoid slowdowns from serialization time when running the ensemble using parallel workers.\n\nreduction: a function (u,data,i) which accumulates the result of output_func in u. Defaults to just appending data to u.\n\noutput_dir: Only used to specify the output directory for the default implementation of output_func. If a custom output_func is provided, this arugment is ignored.\n\nAll additional keyword arguments will be passed to EnsembleProblem.\n\nSee also SciMLBase.EnsembleProblem\n\n\n\n\n\n","category":"method"},{"location":"api/diagnostics/#Diagnostics","page":"Diagnostics","title":"Diagnostics","text":"","category":"section"},{"location":"api/diagnostics/","page":"Diagnostics","title":"Diagnostics","text":"Modules = [Diagnostics]\nPrivate = false\nOrder = [:type, :function, :macro]","category":"page"},{"location":"api/diagnostics/#CryoGrid.Diagnostics.active_layer_thickness-Tuple{AbstractDimArray{var\"#s206\", N, D, A} where {var\"#s206\"<:(Quantity{T, 𝚯, U} where {T, U<:(Unitful.FreeUnits{N, 𝚯, A} where {N, A})}), N, D<:Tuple, A}}","page":"Diagnostics","title":"CryoGrid.Diagnostics.active_layer_thickness","text":"active_layer_thickness(T::AbstractDimArray{<:TempQuantity})\n\nComputes active layer thickness annually. The active layer thickness is defined here as the maximum thaw depth throughout the calendar year. Assumes T to have dimensions Ti (time) and Z (depth) in any order.\n\n\n\n\n\n","category":"method"},{"location":"api/diagnostics/#CryoGrid.Diagnostics.computejac-Tuple{Tile, Any, Any, Any}","page":"Diagnostics","title":"CryoGrid.Diagnostics.computejac","text":"computejac(tile::Tile, u, p, t)\n\nHelper function that computes the Jacobian of the given tile at u with parameters p and time t.\n\n\n\n\n\n","category":"method"},{"location":"api/diagnostics/#CryoGrid.Diagnostics.integrate-Union{Tuple{G}, Tuple{AbstractDimArray, Grid{Edges, G, var\"#s206\", A} where {var\"#s206\"<:(Quantity{T, 𝐋, U} where {T, U<:(Unitful.FreeUnits{N, 𝐋, nothing} where N)}), A}}} where G","page":"Diagnostics","title":"CryoGrid.Diagnostics.integrate","text":"integrate(X::AbstractDimArray, grid::Grid{Edges}; upper_limit=0u\"m\", lower_limit=10u\"m\")\n\nIntegrates the quantity X over the given grid, which is assumed to be spatially alligned, i.e. length(grid) == length(dims(X,Z)) + 1 and cells(grid) .≈ dims(X,Z) are necessary preconditions.\n\n\n\n\n\n","category":"method"},{"location":"api/diagnostics/#CryoGrid.Diagnostics.mean_annual_ground_temperature-Tuple{AbstractDimArray{var\"#s206\", N, D, A} where {var\"#s206\"<:(Quantity{T, 𝚯, U} where {T, U<:(Unitful.FreeUnits{N, 𝚯, A} where {N, A})}), N, D<:Tuple, A}}","page":"Diagnostics","title":"CryoGrid.Diagnostics.mean_annual_ground_temperature","text":"mean_annual_ground_temperature(T::AbstractDimArray; upper_limit=0u\"m\", lower_limit=10u\"m\")\n\nComputes mean annual ground temperature between upper_limit and lower_limit. Assumes T to have dimensions Ti (time) and Z (depth) in any order.\n\n\n\n\n\n","category":"method"},{"location":"api/diagnostics/#CryoGrid.Diagnostics.permafrostbase-Tuple{AbstractDimArray{var\"#s206\", N, D, A} where {var\"#s206\"<:(Quantity{T, 𝚯, U} where {T, U<:(Unitful.FreeUnits{N, 𝚯, A} where {N, A})}), N, D<:Tuple, A}}","page":"Diagnostics","title":"CryoGrid.Diagnostics.permafrostbase","text":"permafrostbase(T::AbstractDimArray{<:TempQuantity})\n\nComputes depth of permafrost base for all years, i.e. the closest depth to the \"bottom\" at which the maximum annual temperature is strictly < 0°C. Assumes T to have dimensions Ti (time) and Z (depth) in any order.\n\n\n\n\n\n","category":"method"},{"location":"api/diagnostics/#CryoGrid.Diagnostics.permafrosttable-Tuple{AbstractDimArray{var\"#s206\", N, D, A} where {var\"#s206\"<:(Quantity{T, 𝚯, U} where {T, U<:(Unitful.FreeUnits{N, 𝚯, A} where {N, A})}), N, D<:Tuple, A}}","page":"Diagnostics","title":"CryoGrid.Diagnostics.permafrosttable","text":"permafrosttable(T::AbstractDimArray{<:TempQuantity})\n\nComputes depth of permafrost table for all years, i.e. the closest depth to the surface at which the maximum annual temperature is strictly less than Tmelt. Assumes T to have dimensions Ti (time) and Z (depth) in any order.\n\n\n\n\n\n","category":"method"},{"location":"api/diagnostics/#CryoGrid.Diagnostics.spinup-Tuple{Tile, Tuple{DateTime, DateTime}, Any, Any, Any}","page":"Diagnostics","title":"CryoGrid.Diagnostics.spinup","text":"spinup(setup::Tile, tspan::NTuple{2,DateTime}, p, tol, layername; kwargs...)\n\nImplements a simple, iterative spin-up procedure. Runs the model specified by setup over tspan until the profile mean up to maxdepth over the whole time span changes only within the given tolerance tol. Returns the ODESolution generated by the final iteration.\n\n\n\n\n\n","category":"method"},{"location":"api/diagnostics/#CryoGrid.Diagnostics.thawdepth-Tuple{AbstractDimArray{var\"#s206\", N, D, A} where {var\"#s206\"<:(Quantity{T, 𝚯, U} where {T, U<:(Unitful.FreeUnits{N, 𝚯, A} where {N, A})}), N, D<:Tuple, A}}","page":"Diagnostics","title":"CryoGrid.Diagnostics.thawdepth","text":"thawdepth(T::AbstractDimArray{<:TempQuantity}; Tmelt=0.0u\"°C\")\n\nComputes sub-grid thaw depth (a.k.a freezing front) from temperature at all time steps. The sub-grid depth of the zero degree isotherm is determined by linearly interpolating between grid cell temperatures in T. Note that T is assumed to have units °C and dimensions Ti (time) and Z (depth) in any order.\n\n\n\n\n\n","category":"method"},{"location":"api/diagnostics/#CryoGrid.Diagnostics.zero_annual_amplitude-Tuple{AbstractDimArray{var\"#s206\", N, D, A} where {var\"#s206\"<:(Quantity{T, 𝚯, U} where {T, U<:(Unitful.FreeUnits{N, 𝚯, A} where {N, A})}), N, D<:Tuple, A}}","page":"Diagnostics","title":"CryoGrid.Diagnostics.zero_annual_amplitude","text":"zero_annual_amplitude(T::AbstractDimArray{<:TempQuantity}; threshold=0.5u\"K\")\n\nComputes annual depth of zero amplitude (where |max - min| < threshold) and returns the result for each year. Assumes T to have dimensions Ti (time) and Z (depth) in any order.\n\n\n\n\n\n","category":"method"},{"location":"api/solvers/lite_implicit/#CryoGridLite","page":"CryoGridLite","title":"CryoGridLite","text":"","category":"section"},{"location":"api/solvers/lite_implicit/","page":"CryoGridLite","title":"CryoGridLite","text":"Modules = [CryoGrid.LiteImplicit]\nPrivate = false\nOrder = [:type, :function, :macro]","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"EditURL = \"../../../examples/heat_freeW_bucketW_samoylov.jl\"","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/#example5","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"","category":"section"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"In this example, we construct a Tile consisting of a soil column with (i) heat conduction and (ii) a bucket hydrology scheme. The rainfall data comes from the ERA5-Interim reanalysis product.","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"Frist, load forcings and define boundary conditions.","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"using CryoGrid\nforcings = loadforcings(CryoGrid.Presets.Forcings.Samoylov_ERA_obs_fitted_1979_2014_spinup_extended_2044);\n_, tempprofile = CryoGrid.Presets.SamoylovDefault;\ninitT = initializer(:T, tempprofile)\ninitsat = initializer(:sat, (l,state) -> state.sat .= l.para.sat);\nupperbc = WaterHeatBC(SurfaceWaterBalance(forcings), TemperatureBC(forcings.Tair, NFactor(0.5,0.9)));\nnothing #hide","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"The @Stratigraphy macro is just a small convenience that automatically wraps the three subsurface layers in a tuple. It would be equivalent to use the Stratigraphy constructor directly and wrap these layers in a tuple or list.","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"strat = @Stratigraphy(\n 0.0u\"m\" => Top(upperbc),\n 0.0u\"m\" => Ground(MineralOrganic(por=0.80,sat=0.5,org=0.75), heat=HeatBalance(), water=WaterBalance(BucketScheme())),\n 0.2u\"m\" => Ground(MineralOrganic(por=0.40,sat=0.75,org=0.10), heat=HeatBalance(), water=WaterBalance(BucketScheme())),\n 2.0u\"m\" => Ground(MineralOrganic(por=0.10,sat=1.0,org=0.0), heat=HeatBalance(), water=WaterBalance(BucketScheme())),\n 1000.0u\"m\" => Bottom(GeothermalHeatFlux(0.053u\"W/m^2\")),\n);\nmodelgrid = CryoGrid.Presets.DefaultGrid_2cm\ntile = Tile(strat, modelgrid, initT, initsat);\nnothing #hide","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"Now we set up the problem and solve using the integrator interface.","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"tspan = (DateTime(2010,5,30),DateTime(2012,8,30))\nu0, du0 = initialcondition!(tile, tspan)\nprob = CryoGridProblem(tile, u0, tspan, savevars=(:T,:jw,:θw,:θwi), saveat=3*3600.0)\nintegrator = init(prob, CGEuler())\n# Take a single step:\nstep!(integrator)\n# ...then iterate over the remaining steps.\n@time for i in integrator\n # can add code here if necessary\nend\nout = CryoGridOutput(integrator.sol)","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"Now let's check mass conservation for water.","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"water_added = values(sum(forcings.rainfall.(tspan[1]:Hour(3):tspan[2]).*u\"m/s\".*(3*3600.0u\"s\")))[1]\nwater_mass = Diagnostics.integrate(out.θwi, tile.grid)\nΔwater = water_mass[end] - water_mass[1]","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"Plot the results:","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"import Plots\nzs = [1,5,9,15,21,25,33,55,65,75,100]u\"cm\"\ncg = Plots.cgrad(:copper,rev=true);\nnothing #hide","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"Temperature:","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"Plots.plot(out.T[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Temperature\", leg=false, size=(800,500), dpi=150)","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"Liquid water:","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"Plots.plot(out.θw[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Unfrozen water content\", leg=false, size=(800,500), dpi=150)","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"Saturation:","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"Plots.plot(out.sat[Z(Near(zs))], color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Saturation\", leg=false, size=(800,500), dpi=150)","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"Runoff:","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"Plots.plot(out.top.runoff[1,:], ylabel=\"Runoff\")","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"","category":"page"},{"location":"examples/heat_freeW_bucketW_samoylov/","page":"Soil heat with bucket water scheme","title":"Soil heat with bucket water scheme","text":"This page was generated using Literate.jl.","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"EditURL = \"../../../examples/heat_freeW_seb_snow_bucketW_samoylov.jl\"","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/#example6","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"","category":"section"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"In this example, we construct a Tile consisting of a soil column with (i) heat conduction forced by the surface energy balance (SEB), (ii) a bulk snow scheme, and (iii) a bucket hydrology scheme.","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"For this example, we need to use an OrdinaryDiffEq integrator.","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"using CryoGrid\nusing OrdinaryDiffEq","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"First, load the forcings and construct the Tile.","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"modelgrid = CryoGrid.Presets.DefaultGrid_2cm;\nsoilprofile = SoilProfile(\n 0.0u\"m\" => MineralOrganic(por=0.80,sat=1.0,org=0.75),\n 0.1u\"m\" => MineralOrganic(por=0.80,sat=1.0,org=0.25),\n 0.4u\"m\" => MineralOrganic(por=0.55,sat=1.0,org=0.25),\n 3.0u\"m\" => MineralOrganic(por=0.50,sat=1.0,org=0.0),\n 10.0u\"m\" => MineralOrganic(por=0.30,sat=1.0,org=0.0),\n);\n# mid-winter temperature profile\ntempprofile = CryoGrid.Presets.SamoylovDefault.tempprofile\nforcings = loadforcings(CryoGrid.Presets.Forcings.Samoylov_ERA_obs_fitted_1979_2014_spinup_extended_2044);\ntempprofile = CryoGrid.Presets.SamoylovDefault.tempprofile\ninitT = initializer(:T, tempprofile)\nz = 2.0u\"m\"; # height [m] for which the forcing variables (Temp, humidity, wind, pressure) are provided\nseb = SurfaceEnergyBalance(forcings, z)\nswb = SurfaceWaterBalance(forcings)\nupperbc = WaterHeatBC(swb, seb)\nheat = HeatBalance()\nwater = WaterBalance(BucketScheme(), DampedET())\n# build stratigraphy\nstrat = @Stratigraphy(\n -z => Top(upperbc),\n -z => Snowpack(heat=HeatBalance(), water=water),\n 0.0u\"m\" => Ground(soilprofile; heat, water),\n 1000.0u\"m\" => Bottom(GeothermalHeatFlux(0.053u\"J/s/m^2\")),\n);\n# create Tile\ntile = Tile(strat, modelgrid, initT);\nnothing #hide","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"Set up the problem and solve it!","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"tspan = (DateTime(2010,10,30), DateTime(2011,10,30))\n# generate initial condition and set up CryoGridProblem\nu0, du0 = @time initialcondition!(tile, tspan)\n\nprob = CryoGridProblem(\n tile,\n u0,\n tspan,\n savevars=(:T,:jH,:top => (:Qh,:Qe,:Qg,),:snowpack => (:dsn,)),\n saveat=3*3600.0\n)\nintegrator = init(prob, Euler(), dt=60.0)\n# step forwards 24 hours and check for NaN/Inf values\n@time step!(integrator); integrator.dt\n@assert all(isfinite.(integrator.u))\n# iterate over remaining timespan at fixed points using `TimeChoiceIterator`\n@time for (u,t) in TimeChoiceIterator(integrator, convert_t.(tspan[1]:Day(1):tspan[end]))\n state = getstate(integrator)\n @assert isfinite(state.top.Qg[1])\n @info \"Current t=$(Date(convert_t(t))), dt=$(integrator.dt), Tsurf=$(state.ground.T[1]), infil=$(state.top.jw_infil[1])\"\n if integrator.sol.retcode != ReturnCode.Default\n break\n end\nend\nout = CryoGridOutput(integrator.sol)","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"Plot it!","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"import Plots\nzs = [1,3,5,7,10,15,20,25,30,40,50,100,150,200,500,1000]u\"cm\"\ncg = Plots.cgrad(:copper,rev=true);\nPlots.plot(ustrip.(out.T[Z(Near(zs))]), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Temperature\", leg=false, size=(800,500), dpi=150)","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"Saturation:","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"Plots.plot(ustrip.(out.sat[Z(Near(zs))]), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Soil saturation\", leg=false, size=(800,500), dpi=150)","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"Runoff","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"Plots.plot(ustrip.(out.top.runoff), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Total runoff\", leg=false, size=(800,500), dpi=150)","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"Evapotranspiration","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"Plots.plot(ustrip.(out.top.ET), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Total ET\", leg=false, size=(800,500), dpi=150)","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"Snow depth:","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"Plots.plot(ustrip.(out.snowpack.dsn), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Snow depth\", leg=false, size=(800,500), dpi=150)","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"Integrated ground heat flux:","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"Plots.plot(ustrip.(cumsum(out.top.Qg, dims=2)), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Integrated ground heat flux\", leg=false, size=(800,500), dpi=150)","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"Integratoed ground latent heat flux:","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"Plots.plot(ustrip.(cumsum(out.top.Qe, dims=2)), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Integrated ground heat flux\", leg=false, size=(800,500), dpi=150)","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"","category":"page"},{"location":"examples/heat_freeW_seb_snow_bucketW_samoylov/","page":"Soil heat w/ SEB, snow cover, and bucket water scheme","title":"Soil heat w/ SEB, snow cover, and bucket water scheme","text":"This page was generated using Literate.jl.","category":"page"},{"location":"#CryoGrid.jl","page":"Home","title":"CryoGrid.jl","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"CryoGrid.jl is a Julia implementation of the CryoGrid land surface model using DifferentialEquations.jl and the SciML package ecosystem. Its primary goal is to provide a fast, flexible, and feature rich framework for modeling permafrost in Julia while simultaneously laying the groundwork for rapid prototyping of data-driven parameter estimation, uncertainty quantification, and causal analysis of complex Arctic land surface processes.","category":"page"},{"location":"","page":"Home","title":"Home","text":"This package is part of the broader research project: Quantifying and explaining uncertainty in permafrost modeling under a warming climate","category":"page"},{"location":"","page":"Home","title":"Home","text":"Pages = [\"index.md\",\"installation.md\",\"quickstart.md\",\"manual/overview.md\",\"api/index.md\"]","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"EditURL = \"../../../examples/heat_freeW_snow_samoylov.jl\"","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/#example4","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"","category":"section"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"In this example, we construct a Tile consisting of a soil column with (i) heat conduction and (ii) a bulk (single-layer) snow scheme. The snowfall data comes from the ERA-Interim reanalysis product.","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"using CryoGrid\nusing OrdinaryDiffEq","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"First we set up the model:","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"forcings = loadforcings(CryoGrid.Presets.Forcings.Samoylov_ERA_obs_fitted_1979_2014_spinup_extended_2044);\nsoilprofile, tempprofile = CryoGrid.Presets.SamoylovDefault\ninitT = initializer(:T, tempprofile)\ninitsat = initializer(:sat, 1.0)\nz_top = -2.0u\"m\"\nz_sub = keys(soilprofile)\nz_bot = 1000.0u\"m\"\nupperbc = WaterHeatBC(\n SurfaceWaterBalance(forcings),\n TemperatureBC(forcings.Tair)\n)\nsnowmass = SnowMassBalance(\n ablation = Snow.DegreeDayMelt(factor=5.0u\"mm/K/d\")\n)\nsnowpack = Snowpack(\n para=Snow.Bulk(),\n mass=snowmass,\n heat=HeatBalance(),\n water=WaterBalance(),\n)\nground_layers = map(soilprofile) do para\n Ground(para, heat=HeatBalance(), water=WaterBalance())\nend\nstrat = @Stratigraphy(\n z_top => Top(upperbc),\n z_top => snowpack,\n ground_layers...,\n z_bot => Bottom(GeothermalHeatFlux(0.053u\"J/s/m^2\"))\n);\nmodelgrid = CryoGrid.Presets.DefaultGrid_5cm\ntile = Tile(strat, modelgrid, initT, initsat)","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"define time span, 2 years + 3 months","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"tspan = (DateTime(2010,9,30), DateTime(2012,9,30))\nu0, du0 = @time initialcondition!(tile, tspan)\nprob = CryoGridProblem(tile, u0, tspan, saveat=3*3600.0, savevars=(:T, :top => (:T_ub), :snowpack => (:dsn,)))","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"solve full tspan with forward Euler and initial timestep of 5 minutes","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"@info \"Running model ...\"\nsol = @time solve(prob, Euler(), dt=300.0);\nout = CryoGridOutput(sol)","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"Plot it!","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"using Plots: plot, plot!, heatmap, cgrad, Measures\nzs = [1,10,20,30,50,100,200,500]u\"cm\"\ncg = cgrad(:copper,rev=true);\nplot(ustrip(out.T[Z(Near(zs))]), color=cg[LinRange(0.0,1.0,length(zs))]', ylabel=\"Temperature (°C)\", leg=false, dpi=150)\nplot!(ustrip(out.T[1,:]), color=:darkgray, ylabel=\"Temperature (°C)\", leg=false, dpi=150)\nplt1 = plot!(ustrip.(out.top.T_ub), color=:skyblue, linestyle=:dash, alpha=0.5, leg=false, dpi=150)","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"Plot snow water equivalent and depth:","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"plot(ustrip(out.snowpack.swe), ylabel=\"Depth (m)\", label=\"Snow water equivalent\", dpi=150)\nplt2 = plot!(ustrip.(out.snowpack.dsn), label=\"Snow depth\", ylabel=\"Depth (m)\", legendtitle=nothing, dpi=150)\nplot(plt1, plt2, size=(1600,700), margins=5*Measures.mm)","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"Temperature heatmap:","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"T_sub = out.T[Z(Between(0.0u\"m\",10.0u\"m\"))]\nheatmap(T_sub, yflip=true, size=(1200,600), dpi=150)","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"Thaw depth:","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"td = Diagnostics.thawdepth(out.T[Z(Where(>=(0.0u\"m\")))])\nplot(td, yflip=true, ylabel=\"Thaw depth (m)\", size=(1200,600))","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"","category":"page"},{"location":"examples/heat_freeW_snow_samoylov/","page":"Soil heat with bulk snow scheme","title":"Soil heat with bulk snow scheme","text":"This page was generated using Literate.jl.","category":"page"}] }