Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes in code API and structs to be compatible with Halfar tests #5

Merged
merged 2 commits into from
Jul 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,17 @@ Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
ProgressMeter = "92933f4c-e287-5a05-a399-4b506db050ca"
PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0"
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
Sleipnir = "f5e6c550-199f-11ee-3608-394420200519"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Tullio = "bc48ee85-29a4-5162-ae0b-a64e1601d4bc"

[extras]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test"]

[compat]
OrdinaryDiffEq = "6"
ProgressMeter = "1"
Expand Down
1 change: 0 additions & 1 deletion src/Huginn.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import Pkg
using Distributed
using ProgressMeter
using PyCall
using TimerOutputs
using Reexport

### ODINN.jl dependencies ###
Expand Down
23 changes: 20 additions & 3 deletions src/models/iceflow/IceflowModel.jl
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@

export Model

# Abstract type as a parent type for ice flow models
abstract type IceflowModel end
abstract type IceflowModel <: AbstractModel end

# Subtype structure for Shallow Ice Approximation models
abstract type SIAmodel <: IceflowModel end

include("SIA2D/SIA2D.jl")
include("iceflow_utils.jl")
include("SIA2D/SIA2D.jl")

"""
function Model(;
iceflow::IceflowModel
)
Initialize Huginn flow model

"""
function Model(;
iceflow::IceflowModel
)

model = Sleipnir.Model(iceflow, nothing, nothing)

return model
end
24 changes: 15 additions & 9 deletions src/models/iceflow/SIA2D/SIA2D.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@

export SIA2Dmodel

include("SIA2D_utils.jl")

###############################################
###### SHALLOW ICE APPROXIMATION MODELS #######
###############################################
Expand Down Expand Up @@ -34,7 +36,7 @@ mutable struct SIA2Dmodel{F <: AbstractFloat, I <: Integer} <: SIAmodel
glacier_idx::Union{Ref{I}, Nothing}
end

function SIA2Dmodel(params::Parameters;
function SIA2Dmodel(params::Sleipnir.Parameters;
A::Union{Ref{F}, Nothing} = nothing,
H::Union{Matrix{F}, Nothing} = nothing,
H̄::Union{Matrix{F}, Nothing} = nothing,
Expand Down Expand Up @@ -71,22 +73,26 @@ function SIA2Dmodel(params::Parameters;
end

"""
initialize_iceflow_model!(; glacier::Glacier,
params::Parameters
) where F <: AbstractFloat
function initialize_iceflow_model!(iceflow_model::IF,
glacier_idx::I,
glacier::AbstractGlacier,
params::Sleipnir.Parameters
) where {IF <: IceflowModel, I <: Int}

Initialize iceflow model data structures to enable in-place mutation.

Keyword arguments
=================
- `iceflow_model`: Iceflow model used for simulation.
- `glacier_idx`: Index of glacier.
- `glacier`: `Glacier` to provide basic initial state of the ice flow model.
- `parameters`: `Parameters` to configure some physical variables
- `parameters`: `Parameters` to configure some physical variables.
"""
function initialize_iceflow_model!(iceflow_model::IF,
glacier_idx::I,
glacier::Glacier,
params::Parameters
) where {IF <: IceflowModel, I <: Int}
glacier_idx::I,
glacier::Sleipnir.AbstractGlacier,
params::Sleipnir.Parameters
) where {IF <: IceflowModel, I <: Int}
nx, ny = glacier.nx, glacier.ny
F = params.simulation.float_type
iceflow_model.A = Ref{F}(params.physical.A)
Expand Down
47 changes: 18 additions & 29 deletions src/models/iceflow/SIA2D/SIA2D_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@ Compute an in-place step of the Shallow Ice Approximation PDE in a forward model
function SIA2D!(dH::Matrix{F}, H::Matrix{F}, simulation::SIM, t::F) where {F <: AbstractFloat, SIM <: Simulation}

# Retrieve parameters
@timeit get_timer("ODINN") "Variable assignment" begin
SIA2D_model::SIA2Dmodel = simulation.model.iceflow
glacier::Glacier = simulation.glaciers[simulation.model.iceflow.glacier_idx[]]
params::Parameters = simulation.parameters
int_type = simulation.parameters.simulation.int_type
glacier::Sleipnir.Glacier2D = simulation.glaciers[simulation.model.iceflow.glacier_idx[]]
params::Sleipnir.Parameters = simulation.parameters
int_type = simulation.parameters.simulation.int_type
H̄::Matrix{F} = SIA2D_model.H̄
A::Ref{F} = SIA2D_model.A
B::Matrix{F} = glacier.B
Expand All @@ -37,60 +36,46 @@ function SIA2D!(dH::Matrix{F}, H::Matrix{F}, simulation::SIM, t::F) where {F <:
n::int_type = simulation.parameters.physical.n
ρ::F = simulation.parameters.physical.ρ
g::F = simulation.parameters.physical.g
end

@timeit get_timer("ODINN") "H to zero" begin
# First, enforce values to be positive
map!(x -> ifelse(x>0.0,x,0.0), H, H)
# Update glacier surface altimetry
S .= B .+ H
end

# All grid variables computed in a staggered grid
# Compute surface gradients on edges
@timeit get_timer("ODINN") "Surface gradients" begin
diff_x!(dSdx, S, Δx)
diff_y!(dSdy, S, Δy)
avg_y!(∇Sx, dSdx)
avg_x!(∇Sy, dSdy)
∇S .= (∇Sx.^2 .+ ∇Sy.^2).^((n - 1)/2)
end

@timeit get_timer("ODINN") "Diffusivity" begin
# @infiltrate
avg!(H̄, H)
Γ[] = 2.0 * A[] * (ρ * g)^n / (n+2) # 1 / m^3 s
D .= Γ[] .* H̄.^(n + 2) .* ∇S
end

# Compute flux components
@timeit get_timer("ODINN") "Gradients edges" begin
@views diff_x!(dSdx_edges, S[:,2:end - 1], Δx)
@views diff_y!(dSdy_edges, S[2:end - 1,:], Δy)
end

# Cap surface elevaton differences with the upstream ice thickness to
# imporse boundary condition of the SIA equation
@timeit get_timer("ODINN") "Capping flux" begin
η₀ = params.physical.η₀
dSdx_edges .= @views @. min(dSdx_edges, η₀ * H[1:end-1, 2:end-1]/Δx, η₀ * H[2:end, 2:end-1]/Δx)
dSdy_edges .= @views @. min(dSdy_edges, η₀ * H[2:end-1, 1:end-1]/Δy, η₀ * H[2:end-1, 2:end]/Δy)
dSdx_edges .= @views @. max(dSdx_edges, -η₀ * H[1:end-1, 2:end-1]/Δx, -η₀ * H[2:end, 2:end-1]/Δx)
dSdy_edges .= @views @. max(dSdy_edges, -η₀ * H[2:end-1, 1:end-1]/Δy, -η₀ * H[2:end-1, 2:end]/Δy)
end
dSdx_edges .= @views @. min(dSdx_edges, η₀ * H[2:end, 2:end-1]/Δx)
dSdx_edges .= @views @. max(dSdx_edges, -η₀ * H[1:end-1, 2:end-1]/Δx)
dSdy_edges .= @views @. min(dSdy_edges, η₀ * H[2:end-1, 2:end]/Δy)
dSdy_edges .= @views @. max(dSdy_edges, -η₀ * H[2:end-1, 1:end-1]/Δy)

@timeit get_timer("ODINN") "Flux" begin
avg_y!(Dx, D)
avg_x!(Dy, D)
Fx .= .-Dx .* dSdx_edges
Fy .= .-Dy .* dSdy_edges
end

# Flux divergence
@timeit get_timer("ODINN") "dH" begin
diff_x!(Fxx, Fx, Δx)
diff_y!(Fyy, Fy, Δy)
inn(dH) .= .-(Fxx .+ Fyy)
end
end

# Dummy function to bypass ice flow
Expand Down Expand Up @@ -130,10 +115,14 @@ function SIA2D(H, SIA2Dmodel)
# imporse boundary condition of the SIA equation
# We need to do this with Tullio or something else that allow us to set indices.
η₀ = 1.0
dSdx_edges .= min.(dSdx_edges, η₀ * H[1:end-1, 2:end-1]./Δx, η₀ * H[2:end, 2:end-1]./Δx)
dSdy_edges .= min.(dSdy_edges, η₀ * H[2:end-1, 1:end-1]./Δy, η₀ * H[2:end-1, 2:end]./Δy)
dSdx_edges .= max.(dSdx_edges, -η₀ * H[1:end-1, 2:end-1]./Δx, -η₀ * H[2:end, 2:end-1]./Δx)
dSdy_edges .= max.(dSdy_edges, -η₀ * H[2:end-1, 1:end-1]./Δy, -η₀ * H[2:end-1, 2:end]./Δy)
dSdx_edges .= @views @. min(dSdx_edges, η₀ * H[2:end, 2:end-1]/Δx)
dSdx_edges .= @views @. max(dSdx_edges, -η₀ * H[1:end-1, 2:end-1]/Δx)
dSdy_edges .= @views @. min(dSdy_edges, η₀ * H[2:end-1, 2:end]/Δy)
dSdy_edges .= @views @. max(dSdy_edges, -η₀ * H[2:end-1, 1:end-1]/Δy)
# dSdx_edges .= min.(dSdx_edges, η₀ * H[1:end-1, 2:end-1]./Δx, η₀ * H[2:end, 2:end-1]./Δx)
# dSdy_edges .= min.(dSdy_edges, η₀ * H[2:end-1, 1:end-1]./Δy, η₀ * H[2:end-1, 2:end]./Δy)
# dSdx_edges .= max.(dSdx_edges, -η₀ * H[1:end-1, 2:end-1]./Δx, -η₀ * H[2:end, 2:end-1]./Δx)
# dSdy_edges .= max.(dSdy_edges, -η₀ * H[2:end-1, 1:end-1]./Δy, -η₀ * H[2:end-1, 2:end]./Δy)

Fx = .-avg_y(D) .* dSdx_edges
Fy = .-avg_x(D) .* dSdy_edges
Expand Down Expand Up @@ -190,11 +179,11 @@ end
Computes the ice surface velocity for a given glacier state
"""
function surface_V!(H::Matrix{F}, simulation::SIM) where {F <: AbstractFloat, SIM <: Simulation}
params::Parameters = simulation.parameters
params::Sleipnir.Parameters = simulation.parameters
ft = params.simulation.float_type
it = params.simulation.int_type
iceflow_model = simulation.model.iceflow
glacier::Glacier = simulation.glaciers[iceflow_model.glacier_idx[]]
glacier::Sleipnir.Glacier2D = simulation.glaciers[iceflow_model.glacier_idx[]]
B::Matrix{ft} = glacier.B
H̄::Matrix{F} = iceflow_model.H̄
dSdx::Matrix{ft} = iceflow_model.dSdx
Expand Down
41 changes: 37 additions & 4 deletions src/parameters/SolverParameters.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
export SolverParameters, Parameters

mutable struct SolverParameters{F <: AbstractFloat, I <: Integer}
mutable struct SolverParameters{F <: AbstractFloat, I <: Integer} <: AbstractParameters
solver::OrdinaryDiffEq.OrdinaryDiffEqAdaptiveAlgorithm
reltol::F
step::F
tstops::Union{Nothing,Vector{F}}
save_everystep::Bool
progress::Bool
Expand All @@ -22,19 +24,50 @@ Keyword arguments
function SolverParameters(;
solver::OrdinaryDiffEq.OrdinaryDiffEqAdaptiveAlgorithm = RDPK3Sp35(),
reltol::F = 1e-12,
save_everystep = false,
step::F = 1.0/12.0,
tstops::Union{Nothing,Vector{F}} = nothing,
save_everystep = false,
progress::Bool = true,
progress_steps::I = 10
) where {F <: AbstractFloat, I <: Integer}
# Build the solver parameters based on input values
solver_parameters = SolverParameters(solver, reltol,
tstops,
save_everystep, progress, progress_steps)
step, tstops,
save_everystep, progress, progress_steps)

return solver_parameters
end

"""
Parameters(;
simulation::SimulationParameters = SimulationParameters()
physical::PhysicalParameters = PhysicalParameters()
OGGM::OGGMparameters = OGGMparameters(),
solver::SolverParameters = SolverParameters()
)
Initialize Huginn parameters

Keyword arguments
=================

"""

function Parameters(;
physical::PhysicalParameters = PhysicalParameters(),
simulation::SimulationParameters = SimulationParameters(),
OGGM::OGGMparameters = OGGMparameters(),
solver::SolverParameters = SolverParameters()
)

# Build the parameters based on all the subtypes of parameters
parameters = Sleipnir.Parameters(physical, simulation, OGGM,
nothing, solver, nothing)

return parameters
end

# Base.:(==)(a::Parameters, b::Parameters) = a.physical == b.physical && a.simulation == b.simulation && a.OGGM == b.OGGM && a.solver == b.solver

"""
define_callback_steps(tspan::Tuple{Float64, Float64}, step::Float64)

Expand Down
24 changes: 17 additions & 7 deletions src/simulations/predictions/Prediction.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,27 @@ export Prediction

# Subtype composite type for a prediction simulation
mutable struct Prediction <: Simulation
model::Model
glaciers::Vector{Glacier}
parameters::Parameters
model::Sleipnir.Model
glaciers::Vector{Sleipnir.AbstractGlacier}
parameters::Sleipnir.Parameters
results::Vector{Results}
end

function Prediction(
model::Model,
glaciers::Vector{Glacier},
parameters::Parameters
"""
function Prediction(
model::Sleipnir.Model,
glaciers::Vector{Sleipnir.AbstractGlacier},
parameters::Sleipnir.Parameters
)
Construnctor for Prediction struct with glacier model infomation, glaciers and parameters.
Keyword arguments
=================
"""
function Prediction(
model::Sleipnir.Model,
glaciers::Vector{Sleipnir.AbstractGlacier},
parameters::Sleipnir.Parameters
)

# Build the results struct based on input values
prediction = Prediction(model,
Expand Down
Loading
Loading