diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 592ef8e..9d000b6 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -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 }} @@ -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: diff --git a/Project.toml b/Project.toml index 9dfd094..ae488ed 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "Huginn" uuid = "9cb796e9-d0ea-421b-b37d-eb97bc1add55" authors = ["Jordi Bolibar ", "Facundo Sapienza "] -version = "0.6.0" +version = "0.7.0" [deps] BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" @@ -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" @@ -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" diff --git a/src/Huginn.jl b/src/Huginn.jl index 812d8f6..64331b4 100644 --- a/src/Huginn.jl +++ b/src/Huginn.jl @@ -16,7 +16,6 @@ using CairoMakie import Pkg using Distributed using ProgressMeter -using PyCall ### ODINN.jl dependencies ### using Reexport @@ -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 ############## # ############################################## diff --git a/src/parameters/SolverParameters.jl b/src/parameters/SolverParameters.jl index 79326ee..a1ed31f 100644 --- a/src/parameters/SolverParameters.jl +++ b/src/parameters/SolverParameters.jl @@ -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 diff --git a/src/setup/config.jl b/src/setup/config.jl index b1791b2..8cd8812 100644 --- a/src/setup/config.jl +++ b/src/setup/config.jl @@ -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 diff --git a/src/simulations/predictions/prediction_utils.jl b/src/simulations/predictions/prediction_utils.jl index 1132857..877b0b0 100644 --- a/src/simulations/predictions/prediction_utils.jl +++ b/src/simulations/predictions/prediction_utils.jl @@ -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 @@ -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?) diff --git a/test/PDE_UDE_solve.jl b/test/PDE_UDE_solve.jl index 13d33fd..720fa36 100644 --- a/test/PDE_UDE_solve.jl +++ b/test/PDE_UDE_solve.jl @@ -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 @@ -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"] @@ -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 @@ -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] diff --git a/test/data/PDE/H_w_MB_ref.jld2 b/test/data/PDE/H_w_MB_ref.jld2 index c1e5c20..e08ed35 100644 Binary files a/test/data/PDE/H_w_MB_ref.jld2 and b/test/data/PDE/H_w_MB_ref.jld2 differ diff --git a/test/data/PDE/MB_ref.jld2 b/test/data/PDE/MB_ref.jld2 index d3d3ffe..a736a92 100644 Binary files a/test/data/PDE/MB_ref.jld2 and b/test/data/PDE/MB_ref.jld2 differ diff --git a/test/data/PDE/PDE_refs_MB.jld2 b/test/data/PDE/PDE_refs_MB.jld2 index f66336e..5336e5f 100644 Binary files a/test/data/PDE/PDE_refs_MB.jld2 and b/test/data/PDE/PDE_refs_MB.jld2 differ diff --git a/test/data/PDE/PDE_refs_noMB.jld2 b/test/data/PDE/PDE_refs_noMB.jld2 index c946751..0b5fa7f 100644 Binary files a/test/data/PDE/PDE_refs_noMB.jld2 and b/test/data/PDE/PDE_refs_noMB.jld2 differ diff --git a/test/data/params/solver_params_default.jld2 b/test/data/params/solver_params_default.jld2 index 78b7451..fa7c0bb 100644 Binary files a/test/data/params/solver_params_default.jld2 and b/test/data/params/solver_params_default.jld2 differ diff --git a/test/data/params/solver_params_specified.jld2 b/test/data/params/solver_params_specified.jld2 index 4fed05e..410fc58 100644 Binary files a/test/data/params/solver_params_specified.jld2 and b/test/data/params/solver_params_specified.jld2 differ diff --git a/test/halfar.jl b/test/halfar.jl index 13c5c98..3a5bcc7 100644 --- a/test/halfar.jl +++ b/test/halfar.jl @@ -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] diff --git a/test/mass_conservation.jl b/test/mass_conservation.jl index efb1fe3..04257aa 100644 --- a/test/mass_conservation.jl +++ b/test/mass_conservation.jl @@ -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โ‚€ diff --git a/test/plotting.jl b/test/plotting.jl index 0f1e9b3..38d1b40 100644 --- a/test/plotting.jl +++ b/test/plotting.jl @@ -1,23 +1,22 @@ function plot_analysis_flow_parameters_test() - + working_dir = joinpath(dirname(Base.current_project()), "data") if !ispath(working_dir) mkdir("data") end - params = Parameters(OGGM = OGGMparameters(working_dir=working_dir, - multiprocessing=false, - workers=1, - ice_thickness_source = "Farinotti19"), - simulation = SimulationParameters(use_MB=true, + rgi_paths = get_rgi_paths() + + params = Huginn.Parameters(simulation = SimulationParameters(use_MB=true, tspan=(2010.0, 2015.0), working_dir = working_dir, test_mode = true, multiprocessing=false, - workers=1), + workers=1, + 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.01450"] glaciers = initialize_glaciers(rgi_ids, params) @@ -27,14 +26,14 @@ function plot_analysis_flow_parameters_test() A_values = [8.5e-20] n_values = [3.0] - + try plot_analysis_flow_parameters(prediction, A_values, n_values) @test true # Test passes if no error is thrown catch e println("Error occurred: ", e) @test false # Test fails if any error is caught - + end end