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

Migrate to pure julia #59

Merged
merged 6 commits into from
Jan 23, 2025
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
53 changes: 14 additions & 39 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,42 +22,14 @@ jobs:
fail-fast: false
matrix:
version:
- '1.10'
python: [3.9]
- '1.11'
os:
- ubuntu-latest
- macos-latest
arch:
- x64
steps:
- uses: actions/checkout@v2
- name: Set up Python 🐍 ${{ matrix.python }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python }}
- name: Create environment with micromamba 🐍🖤
uses: mamba-org/setup-micromamba@v1
with:
micromamba-version: '1.5.6-0'
environment-file: ./environment.yml
environment-name: oggm_env # it is recommendable to add both name and yml file.
init-shell: bash
cache-environment: true
# condarc-file: ./condarc.yml # If necessary, we can include .condarc to configure environment
- name: Test creation of environment with micromamba 🔧🐍🖤
run: |
which python
conda env export
shell: bash -el {0}
- name: Update certifi
run: |
pip install --upgrade certifi
shell: bash -el {0}
# - name: Test OGGM installation 🔧🌎
# run: pytest.oggm
# shell: bash -el {0}
- name: Set ENV Variables for PyCall.jl 🐍 📞
run: export PYTHON=/home/runner/micromamba/envs/oggm_env/bin/python
shell: bash -el {0}
- uses: julia-actions/setup-julia@v1
with:
version: ${{ matrix.version }}
Expand All @@ -69,15 +41,18 @@ jobs:
with:
cache-registries: "true"
cache-compiled: "true"
- uses: julia-actions/julia-buildpkg@v1
env:
PYTHON : /home/runner/micromamba/envs/oggm_env/bin/python
# The SSL certificate path can be readed from the action "Check Julia SSL certifications"
SSL_CERT_FILE: /etc/ssl/certs/ca-certificates.crt
- uses: julia-actions/julia-runtest@v1
env:
PYTHON : /home/runner/micromamba/envs/oggm_env/bin/python
SSL_CERT_FILE: /etc/ssl/certs/ca-certificates.crt
- name: Build Julia packages in Ubuntu
uses: julia-actions/julia-buildpkg@v1
if: matrix.os == 'ubuntu-latest'
- name: Build Julia packages in MacOS
uses: julia-actions/julia-buildpkg@v1
if: matrix.os == 'macos-latest'
- name: Run tests in Ubuntu
uses: julia-actions/julia-runtest@v1
if: matrix.os == 'ubuntu-latest'
- name: Run tests in MacOS
uses: julia-actions/julia-runtest@v1
if: matrix.os == 'macos-latest'
- uses: julia-actions/julia-processcoverage@v1
- uses: codecov/codecov-action@v3
with:
Expand Down
10 changes: 4 additions & 6 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "Huginn"
uuid = "9cb796e9-d0ea-421b-b37d-eb97bc1add55"
authors = ["Jordi Bolibar <[email protected]>", "Facundo Sapienza <[email protected]>"]
version = "0.6.0"
version = "0.7.0"

[deps]
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
Expand All @@ -17,7 +17,6 @@ Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
PlotThemes = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a"
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"
Expand All @@ -27,19 +26,18 @@ Tullio = "bc48ee85-29a4-5162-ae0b-a64e1601d4bc"
[compat]
BenchmarkTools = "1"
CairoMakie = "0.11, 0.12"
Infiltrator = "1"
Infiltrator = "1.8"
JLD2 = "0.4"
Muninn = "0.3"
Muninn = "0.4.0"
Optimization = "3"
OptimizationOptimJL = "0.3"
OrdinaryDiffEq = "6"
PlotThemes = "3"
Plots = "1"
ProgressMeter = "1"
PyCall = "1"
Reexport = "1"
Revise = "3"
Sleipnir = "0.6"
Sleipnir = "0.7.0"
Tullio = "0.3"
julia = "1.7"

Expand Down
23 changes: 0 additions & 23 deletions src/Huginn.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ using CairoMakie
import Pkg
using Distributed
using ProgressMeter
using PyCall

### ODINN.jl dependencies ###
using Reexport
Expand All @@ -30,28 +29,6 @@ cd(@__DIR__)
const global root_dir::String = dirname(Base.current_project())
const global root_plots::String = joinpath(root_dir, "plots")

# ##############################################
# ############ PYTHON LIBRARIES ##############
# ##############################################

# We either retrieve the reexported Python libraries from Sleipnir or we start from scratch
const netCDF4::PyObject = isdefined(Sleipnir, :netCDF4) ? Sleipnir.netCDF4 : PyNULL()
const cfg::PyObject = isdefined(Sleipnir, :cfg) ? Sleipnir.cfg : PyNULL()
const utils::PyObject = isdefined(Sleipnir, :utils) ? Sleipnir.utils : PyNULL()
const workflow::PyObject = isdefined(Sleipnir, :workflow) ? Sleipnir.workflow : PyNULL()
const tasks::PyObject = isdefined(Sleipnir, :tasks) ? Sleipnir.tasks : PyNULL()
const global_tasks::PyObject = isdefined(Sleipnir, :global_tasks) ? Sleipnir.global_tasks : PyNULL()
const graphics::PyObject = isdefined(Sleipnir, :graphics) ? Sleipnir.graphics : PyNULL()
const bedtopo::PyObject = isdefined(Sleipnir, :bedtopo) ? Sleipnir.bedtopo : PyNULL()
const millan22::PyObject = isdefined(Sleipnir, :millan22) ? Sleipnir.millan22 : PyNULL()
const MBsandbox::PyObject = isdefined(Sleipnir, :MBsandbox) ? Sleipnir.MBsandbox : PyNULL()
const salem::PyObject = isdefined(Sleipnir, :salem) ? Sleipnir.salem : PyNULL()

# Essential Python libraries
const xr::PyObject = isdefined(Sleipnir, :xr) ? Sleipnir.xr : PyNULL()
const rioxarray::PyObject = isdefined(Sleipnir, :rioxarray) ? Sleipnir.rioxarray : PyNULL()
const pd::PyObject = isdefined(Sleipnir, :pd) ? Sleipnir.pd : PyNULL()

# ##############################################
# ############ HUGINN LIBRARIES ##############
# ##############################################
Expand Down
16 changes: 6 additions & 10 deletions src/parameters/SolverParameters.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,40 +38,36 @@ function SolverParameters(;
return solver_parameters
end

Base.:(==)(a::SolverParameters, b::SolverParameters) = a.solver == b.solver && a.reltol == b.reltol && a.step == b.step &&
Base.:(==)(a::SolverParameters, b::SolverParameters) = a.solver == b.solver && a.reltol == b.reltol && a.step == b.step &&
a.tstops == b.tstops && a.save_everystep == b.save_everystep && a.progress == b.progress &&
a.progress_steps == b.progress_steps

"""
Parameters(;
simulation::SimulationParameters = SimulationParameters()
physical::PhysicalParameters = PhysicalParameters()
OGGM::OGGMparameters = OGGMparameters(),
physical::PhysicalParameters = PhysicalParameters(),
simulation::SimulationParameters = SimulationParameters(),
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,
parameters = Sleipnir.Parameters(physical, simulation,
nothing, solver, nothing, nothing)

if parameters.simulation.multiprocessing
enable_multiprocessing(parameters)
end

oggm_config(OGGM.working_dir; oggm_processes=OGGM.workers)

return parameters
end
Expand Down
35 changes: 5 additions & 30 deletions src/setup/config.jl
Original file line number Diff line number Diff line change
@@ -1,35 +1,10 @@
function __init__()

# Create structural folders if needed
OGGM_path = joinpath(homedir(), "Python/OGGM_data")
if !isdir(OGGM_path)
mkpath(OGGM_path)
end

try
# Only load Python packages if not previously loaded by Sleipnir
if cfg == PyNULL() && workflow == PyNULL() && utils == PyNULL() && MBsandbox == PyNULL()
println("Initializing Python libraries in Huginn...")
copy!(netCDF4, pyimport("netCDF4"))
copy!(cfg, pyimport("oggm.cfg"))
copy!(utils, pyimport("oggm.utils"))
copy!(workflow, pyimport("oggm.workflow"))
copy!(tasks, pyimport("oggm.tasks"))
copy!(global_tasks, pyimport("oggm.global_tasks"))
copy!(graphics, pyimport("oggm.graphics"))
copy!(bedtopo, pyimport("oggm.shop.bedtopo"))
copy!(millan22, pyimport("oggm.shop.millan22"))
copy!(MBsandbox, pyimport("MBsandbox.mbmod_daily_oneflowline"))
copy!(salem, pyimport("salem"))
copy!(pd, pyimport("pandas"))
copy!(xr, pyimport("xarray"))
copy!(rioxarray, pyimport("rioxarray"))
end
catch e
@warn "It looks like you have not installed and/or activated the virtual Python environment. \n
Please follow the guidelines in: https://github.com/ODINN-SciML/ODINN.jl#readme"
@warn exception=(e, catch_backtrace())
end
# # Create structural folders if needed
# OGGM_path = joinpath(homedir(), "Python/OGGM_data")
# if !isdir(OGGM_path)
# mkpath(OGGM_path)
# end

end

Expand Down
4 changes: 2 additions & 2 deletions src/simulations/predictions/prediction_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ function batch_iceflow_PDE!(glacier_idx::I, simulation::Prediction) where {I <:
params = simulation.parameters
glacier = simulation.glaciers[glacier_idx]

glacier_id = isnothing(glacier.gdir) ? "unnamed" : glacier.rgi_id
glacier_id = isnothing(glacier.rgi_id) ? "unnamed" : glacier.rgi_id
println("Processing glacier: ", glacier_id)

# Initialize glacier ice flow model
Expand Down Expand Up @@ -130,7 +130,7 @@ function batch_iceflow_PDE(glacier_idx::I, simulation::Prediction) where {I <: I
params = simulation.parameters
glacier = simulation.glaciers[glacier_idx]

glacier_id = isnothing(glacier.gdir) ? "unnamed" : glacier.rgi_id
glacier_id = isnothing(glacier.rgi_id) ? "unnamed" : glacier.rgi_id
println("Processing glacier: ", glacier_id)

# Initialize glacier ice flow model (don't needed for out-of-place? maybe a simplified version?)
Expand Down
45 changes: 22 additions & 23 deletions test/PDE_UDE_solve.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,32 @@ function pde_solve_test(; rtol::F, atol::F, save_refs::Bool=false, MB::Bool=fals

println("PDE solving with MB = $MB")
working_dir = joinpath(homedir(), "OGGM/Huginn_tests")

params = Parameters(OGGM = OGGMparameters(working_dir=working_dir,
multiprocessing=true,
workers=2,
ice_thickness_source = "Farinotti19"),
simulation = SimulationParameters(use_MB=MB,

rgi_paths = get_rgi_paths()

params = Huginn.Parameters(simulation = SimulationParameters(use_MB=MB,
velocities=false,
tspan=(2010.0, 2015.0),
working_dir = Huginn.root_dir,
test_mode = true),
test_mode = true,
rgi_paths = rgi_paths),
solver = SolverParameters(reltol=1e-12)
)
)

## Retrieving gdirs and climate for the following glaciers
## Fast version includes less glacier to reduce the amount of downloaded files and computation time on GitHub CI
## Fast version includes less glacier to reduce the amount of downloaded files and computation time on GitHub CI
if fast
rgi_ids = ["RGI60-11.03638", "RGI60-11.01450", "RGI60-08.00213", "RGI60-04.04351", "RGI60-01.02170"]
rgi_ids = ["RGI60-11.03638", "RGI60-11.01450"] #, "RGI60-08.00213", "RGI60-04.04351", "RGI60-01.02170"]
else
rgi_ids = ["RGI60-11.03638", "RGI60-11.01450", "RGI60-08.00213", "RGI60-04.04351", "RGI60-01.02170",
"RGI60-02.05098", "RGI60-01.01104", "RGI60-01.09162", "RGI60-01.00570", "RGI60-04.07051",
"RGI60-02.05098", "RGI60-01.01104", "RGI60-01.09162", "RGI60-01.00570", "RGI60-04.07051",
"RGI60-07.00274", "RGI60-07.01323", "RGI60-01.17316"]
end

if MB
model = Model(iceflow = SIA2Dmodel(params), mass_balance = TImodel1(params))
model = Huginn.Model(iceflow = SIA2Dmodel(params), mass_balance = TImodel1(params))
else
model = Model(iceflow = SIA2Dmodel(params), mass_balance = nothing)
model = Huginn.Model(iceflow = SIA2Dmodel(params), mass_balance = nothing)
end

# We retrieve some glaciers for the simulation
Expand All @@ -50,7 +49,7 @@ function pde_solve_test(; rtol::F, atol::F, save_refs::Bool=false, MB::Bool=fals
jldsave(joinpath(Huginn.root_dir, "test/data/PDE/PDE_refs_noMB.jld2"); prediction.results)
end
end

# Load reference values for the simulation
if MB
PDE_refs = load(joinpath(Huginn.root_dir, "test/data/PDE/PDE_refs_MB.jld2"))["results"]
Expand Down Expand Up @@ -86,7 +85,7 @@ function pde_solve_test(; rtol::F, atol::F, save_refs::Bool=false, MB::Bool=fals
@test all(isapprox.(result.H[end], test_ref.H[end], rtol=rtol, atol=atol))
@test all(isapprox.(result.Vx, test_ref.Vx, rtol=rtol, atol=vtol))
@test all(isapprox.(result.Vy, test_ref.Vy, rtol=rtol, atol=vtol))

end # let
end
end
Expand All @@ -95,18 +94,18 @@ end
function TI_run_test!(save_refs::Bool = false; rtol::F, atol::F) where {F <: AbstractFloat}

working_dir = joinpath(homedir(), "OGGM/Huginn_tests")
params = Parameters(OGGM = OGGMparameters(working_dir=working_dir,
multiprocessing=true,
workers=2,
ice_thickness_source = "Farinotti19"),
simulation = SimulationParameters(use_MB=true,

rgi_paths = get_rgi_paths()

params = Huginn.Parameters(simulation = SimulationParameters(use_MB=true,
velocities=false,
tspan=(2010.0, 2015.0),
working_dir = Huginn.root_dir,
test_mode = true),
test_mode = true,
rgi_paths = rgi_paths),
solver = SolverParameters(reltol=1e-8)
)
model = Model(iceflow = SIA2Dmodel(params), mass_balance = TImodel1(params))
)
model = Huginn.Model(iceflow = SIA2Dmodel(params), mass_balance = TImodel1(params))
rgi_ids = ["RGI60-11.03638"]

glacier = initialize_glaciers(rgi_ids, params)[1]
Expand Down
Binary file modified test/data/PDE/H_w_MB_ref.jld2
Binary file not shown.
Binary file modified test/data/PDE/MB_ref.jld2
Binary file not shown.
Binary file modified test/data/PDE/PDE_refs_MB.jld2
Binary file not shown.
Binary file modified test/data/PDE/PDE_refs_noMB.jld2
Binary file not shown.
Binary file modified test/data/params/solver_params_default.jld2
Binary file not shown.
Binary file modified test/data/params/solver_params_specified.jld2
Binary file not shown.
11 changes: 7 additions & 4 deletions test/halfar.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,22 @@ Arguments
"""
function unit_halfar_test(; A, n, t₀, t₁, Δx, Δy, nx, ny, h₀, r₀, rtol=0.02, atol=1.0, distance_to_border=3, save_plot=false, inplace=true)

# Get parameters for a simulation
parameters = Parameters(simulation=SimulationParameters(tspan=(t₀, t₁),
rgi_paths = get_rgi_paths()

# Get parameters for a simulation
parameters = Huginn.Parameters(simulation=SimulationParameters(tspan=(t₀, t₁),
multiprocessing=false,
use_MB=false,
use_iceflow=true,
working_dir=Huginn.root_dir),
working_dir=Huginn.root_dir,
rgi_paths=rgi_paths),
physical=PhysicalParameters(),
solver=SolverParameters(reltol=1e-12))

# Bed (it has to be flat for the Halfar solution)
B = zeros((nx,ny))

model = Model(iceflow = SIA2Dmodel(parameters), mass_balance = nothing)
model = Huginn.Model(iceflow = SIA2Dmodel(parameters), mass_balance = nothing)

# Initial condition of the glacier
R₀ = [sqrt((Δx * (i - nx/2))^2 + (Δy * (j - ny/2))^2) for i in 1:nx, j in 1:ny]
Expand Down
9 changes: 6 additions & 3 deletions test/mass_conservation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,17 @@ Arguments
"""
function unit_mass_test(; H₀, B, A, n, t_sim, Δx, Δy, rtol=0.02, save_plot=false)

rgi_paths = get_rgi_paths()

# Get parameters for a simulation
parameters = Parameters(simulation=SimulationParameters(tspan=(0.0, t_sim),
parameters = Huginn.Parameters(simulation=SimulationParameters(tspan=(0.0, t_sim),
use_MB=false,
use_iceflow=true),
use_iceflow=true,
rgi_paths=rgi_paths),
physical=PhysicalParameters(),
solver=SolverParameters(reltol=1e-12))

model = Model(iceflow = SIA2Dmodel(parameters), mass_balance = nothing)
model = Huginn.Model(iceflow = SIA2Dmodel(parameters), mass_balance = nothing)

# Surface
S = B + H₀
Expand Down
Loading
Loading