List of submissions
It follows the code and plot of the RainGauge
of all RainMaker submissions to /submissions sorted in alphabetical order of the filename.
Chris Rackauckas: Global BBO optimization
path: /submissions/chris_global_bbo.jl
rank: 1. of 12 submissions
author = "Chris Rackauckas"
description = "Global BBO optimization"
#=
using SpeedyWeather
using RainMaker
using Optimization, OptimizationBBO
const PARAMETER_KEYS = (
:orography_scale, # [1], default: 1, scale of global orography
:mountain_height, # [m], default: 0, height of an additional azores mountain
:mountain_size, # [˚], default: 1, horizontal size of an additional azores mountain
:mountain_lon, # [˚E], default: -27.25, longitude of an additional azores mountain
:mountain_lat, # [˚N], default: 38.7, latitude of an additional azores mountain
:temperature_equator, # [K], default: 300, sea surface temperature at the equator
:temperature_pole, # [K], default: 273, sea surfaec temperature at the poles
:temperature_atlantic, # [K], default: 0, sea surface temperature anomaly in the atlantic
:temperature_azores, # [K], default: 0, sea surface temperature anomaly at the azores
:zonal_wind, # [m/s], default: 35, zonal wind speed
:rotation, # [], default: 7.9e-5, Earth rotation
:ocean_temp, # [K], default: 175,
)
function calc_precip(u)
best_param_sample = u
# wrap into named tuple
parameters = NamedTuple{PARAMETER_KEYS}(best_param_sample)
# define resolution. Use trunc=42, 63, 85, 127, ... for higher resolution, cubically slower
spectral_grid = SpectralGrid(trunc=31, nlayers=8)
# Define AquaPlanet ocean, for idealised sea surface temperatures
# but don't change land-sea mask = retain real ocean basins
ocean = AquaPlanet(spectral_grid,
temp_equator=parameters.temperature_equator,
temp_poles=parameters.temperature_pole)
# add initial conditions with a stronger zonal wind matching temperature
initial_conditions = InitialConditions(
vordiv = ZonalWind(u₀=parameters.zonal_wind),
temp = JablonowskiTemperature(u₀=parameters.zonal_wind),
pres = PressureOnOrography(),
humid = ConstantRelativeHumidity())
# Earth's orography but scaled
orography = EarthOrography(spectral_grid, scale=parameters.orography_scale)
# construct model
model = PrimitiveWetModel(spectral_grid; ocean, initial_conditions, orography, planet=Earth(Float32, rotation=parameters.rotation))
# Add rain gauge, locate on Terceira Island
rain_gauge = RainGauge(spectral_grid, lond=-27.25, latd=38.7)
add!(model, rain_gauge)
# Initialize
simulation = initialize!(model, time=DateTime(2025, 1, 10))
# Add additional mountain
H = parameters.mountain_height
λ₀, φ₀, σ = parameters.mountain_lon, parameters.mountain_lat, parameters.mountain_size
set!(model, orography=(λ,φ) -> H*exp(-spherical_distance((λ,φ), (λ₀,φ₀), radius=360/2π)^2/2σ^2), add=true)
set!(simulation, temp = (λ, ϕ, σ) -> parameters.ocean_temp)
# set sea surface temperature anomalies
# 1. Atlantic
set!(simulation, sea_surface_temperature=
(λ, φ) -> (30 < φ < 60) && (270 < λ < 360) ? parameters.temperature_atlantic : 0, add=true)
# 2. Azores
A = parameters.temperature_azores
λ_az, φ_az, σ_az = -27.25, 38.7, 4 # location [˚], size [˚] of Azores
set!(simulation, sea_surface_temperature=
(λ, φ) -> A*exp(-spherical_distance((λ, φ), (λ_az, φ_az), radius=360/2π)^2/2σ_az^2), add=true)
# Run simulation for 20 days, maybe longer for more stable statistics? Could be increased to 30, 40, ... days ?
run!(simulation, period=Day(20))
skip!(rain_gauge, Day(5))
maximum(rain_gauge.accumulated_rain_convection + rain_gauge.accumulated_rain_large_scale)
end
loss(u,p) = -Float64(calc_precip(u))
f = OptimizationFunction(loss)
lb = [0, -2000, 0, -180, -90, 270, 270, -5, -5, 5, 0.0 ,0.0]
ub = [2, 5000, 30, 180, 90, 300, 300, 5, 5, 50, 1e-4, 305]
x0 = (lb .+ ub) ./ 2
prob = Optimization.OptimizationProblem(f, x0; lb, ub)
function callback(state, l) #callback function to observe training
display(l)
return false
end
sol = solve(prob, BBO_adaptive_de_rand_1_bin_radiuslimited(), maxiters = 10000,
maxtime = 10000.0, callback = callback)
loss(sol.u, nothing)
=#
using SpeedyWeather
using RainMaker
PARAMETER_KEYS = (
:orography_scale, # [1], default: 1, scale of global orography
:mountain_height, # [m], default: 0, height of an additional azores mountain
:mountain_size, # [˚], default: 1, horizontal size of an additional azores mountain
:mountain_lon, # [˚E], default: -27.25, longitude of an additional azores mountain
:mountain_lat, # [˚N], default: 38.7, latitude of an additional azores mountain
:temperature_equator, # [K], default: 300, sea surface temperature at the equator
:temperature_pole, # [K], default: 273, sea surfaec temperature at the poles
:temperature_atlantic, # [K], default: 0, sea surface temperature anomaly in the atlantic
:temperature_azores, # [K], default: 0, sea surface temperature anomaly at the azores
:zonal_wind, # [m/s], default: 35, zonal wind speed
:rotation, # [], default: 7.9e-5, Earth rotation
:ocean_temp, # [K], default: 175,
)
# output from the surrogate model
best_param_sample = [
1.1225500464800942,
220.31392224420077,
12.01763511440397,
-15.841509987790861,
-86.12422836923388,
288.90809710269053,
298.96513672809175,
4.925009771675318,
3.5009899916848117,
6.871195942673129,
3.0197768190150545e-5,
173.24948639303884
]
parameters = NamedTuple{PARAMETER_KEYS}(best_param_sample)
# define resolution. Use trunc=42, 63, 85, 127, ... for higher resolution, cubically slower
spectral_grid = SpectralGrid(trunc=31, nlayers=8)
# Define AquaPlanet ocean, for idealised sea surface temperatures
# but don't change land-sea mask = retain real ocean basins
ocean = AquaPlanet(spectral_grid,
temp_equator=parameters.temperature_equator,
temp_poles=parameters.temperature_pole)
# add initial conditions with a stronger zonal wind matching temperature
initial_conditions = InitialConditions(
vordiv = ZonalWind(u₀=parameters.zonal_wind),
temp = JablonowskiTemperature(u₀=parameters.zonal_wind),
pres = PressureOnOrography(),
humid = ConstantRelativeHumidity())
# Earth's orography but scaled
orography = EarthOrography(spectral_grid, scale=parameters.orography_scale)
# construct model
model = PrimitiveWetModel(spectral_grid; ocean, initial_conditions, orography, planet=Earth(Float32, rotation=parameters.rotation))
# Add rain gauge, locate on Terceira Island
rain_gauge = RainGauge(spectral_grid, lond=-27.25, latd=38.7)
add!(model, rain_gauge)
# Initialize
simulation = initialize!(model, time=DateTime(2025, 1, 10))
# Add additional mountain
H = parameters.mountain_height
λ₀, φ₀, σ = parameters.mountain_lon, parameters.mountain_lat, parameters.mountain_size
set!(model, orography=(λ,φ) -> H*exp(-spherical_distance((λ,φ), (λ₀,φ₀), radius=360/2π)^2/2σ^2), add=true)
set!(simulation, temp = (λ, ϕ, σ) -> parameters.ocean_temp)
# set sea surface temperature anomalies
# 1. Atlantic
set!(simulation, sea_surface_temperature=
(λ, φ) -> (30 < φ < 60) && (270 < λ < 360) ? parameters.temperature_atlantic : 0, add=true)
# 2. Azores
A = parameters.temperature_azores
λ_az, φ_az, σ_az = -27.25, 38.7, 4 # location [˚], size [˚] of Azores
set!(simulation, sea_surface_temperature=
(λ, φ) -> A*exp(-spherical_distance((λ, φ), (λ_az, φ_az), radius=360/2π)^2/2σ_az^2), add=true)
# Run simulation for 20 days, maybe longer for more stable statistics? Could be increased to 30, 40, ... days ?
run!(simulation, period=Day(20))
Simone: A veeery cold atmosphere
path: /submissions/simone_submission.jl
rank: 2. of 12 submissions
author = "Simone"
description = "A veeery cold atmosphere"
using SpeedyWeather
using RainMaker
using Dates
# define resolution. Use trunc=42, 63, 85, 127, ... for higher resolution, cubically slower
spectral_grid = SpectralGrid(trunc=31, nlayers=8)
# Define AquaPlanet ocean, for idealised sea surface temperatures
# but don't change land-sea mask = retain real ocean basins
ocean = AquaPlanet(spectral_grid)
# add initial conditions with a stronger zonal wind matching temperature
initial_conditions = InitialConditions(
vordiv = ZonalWind(u₀=50),
temp = JablonowskiTemperature(),
pres = PressureOnOrography(),
humid = ConstantRelativeHumidity())
# Earth's orography but scaled
orography = EarthOrography(spectral_grid, scale=0.25)
# Let's reduce the rotation rate to make the planet run slower
model = PrimitiveWetModel(spectral_grid; ocean, initial_conditions, orography, planet=Earth(Float32, rotation=1e-5))
# Pick the location of the Azores (Terceira Island)
λₒ = -27.25
φ₀ = 38.7
# Add rain gauge, locate on Terceira Island
rain_gauge = RainGauge(spectral_grid, lond=λₒ, latd=φ₀)
add!(model, rain_gauge)
# Initialize
simulation = initialize!(model, time=DateTime(2025, 1, 10))
# A hot ocean under a veeeeeeeeery cold atmosphere
set!(simulation, sea_surface_temperature=(λ, φ)->305)
set!(simulation, temp=(λ, ϕ, σ)->175)
run!(simulation, period=Day(20))
# Plot the results (not needed for submission but doesn't hurt!)
using CairoMakie
# heatmap(model.orography.orography, title="My orogoraphy [m]") # check orography
RainMaker.plot(rain_gauge, rate_Δt=Hour(1), skip=Day(5))
Anas: Surrogate best parameters
path: /submissions/anas_surrogate.jl
rank: 3. of 12 submissions
author = "Anas"
description = "Surrogate best parameters"
using SpeedyWeather
using RainMaker
PARAMETER_KEYS = (
:orography_scale, # [1], default: 1, scale of global orography
:mountain_height, # [m], default: 0, height of an additional azores mountain
:mountain_size, # [˚], default: 1, horizontal size of an additional azores mountain
:mountain_lon, # [˚E], default: -27.25, longitude of an additional azores mountain
:mountain_lat, # [˚N], default: 38.7, latitude of an additional azores mountain
:temperature_equator, # [K], default: 300, sea surface temperature at the equator
:temperature_pole, # [K], default: 273, sea surfaec temperature at the poles
:temperature_atlantic, # [K], default: 0, sea surface temperature anomaly in the atlantic
:temperature_azores, # [K], default: 0, sea surface temperature anomaly at the azores
:zonal_wind, # [m/s], default: 35, zonal wind speed
)
# output from the surrogate model
best_param_sample = [
0.243467,
3456.64,
21.2324,
-90.1826,
58.4064,
287.617,
295.99,
4.98632,
3.45722,
50.0179,
]
# wrap into named tuple
parameters = NamedTuple{PARAMETER_KEYS}(best_param_sample)
# define resolution. Use trunc=42, 63, 85, 127, ... for higher resolution, cubically slower
spectral_grid = SpectralGrid(trunc=31, nlayers=8)
# Define AquaPlanet ocean, for idealised sea surface temperatures
# but don't change land-sea mask = retain real ocean basins
ocean = AquaPlanet(spectral_grid,
temp_equator=parameters.temperature_equator,
temp_poles=parameters.temperature_pole)
# add initial conditions with a stronger zonal wind matching temperature
initial_conditions = InitialConditions(
vordiv = ZonalWind(u₀=parameters.zonal_wind),
temp = JablonowskiTemperature(u₀=parameters.zonal_wind),
pres = PressureOnOrography(),
humid = ConstantRelativeHumidity())
# Earth's orography but scaled
orography = EarthOrography(spectral_grid, scale=parameters.orography_scale)
# construct model
model = PrimitiveWetModel(spectral_grid; ocean, initial_conditions, orography)
# Add rain gauge, locate on Terceira Island
rain_gauge = RainGauge(spectral_grid, lond=-27.25, latd=38.7)
add!(model, rain_gauge)
# Initialize
simulation = initialize!(model, time=DateTime(2025, 1, 10))
# Add additional mountain
H = parameters.mountain_height
λ₀, φ₀, σ = parameters.mountain_lon, parameters.mountain_lat, parameters.mountain_size
set!(model, orography=(λ,φ) -> H*exp(-spherical_distance((λ,φ), (λ₀,φ₀), radius=360/2π)^2/2σ^2), add=true)
# set sea surface temperature anomalies
# 1. Atlantic
set!(simulation, sea_surface_temperature=
(λ, φ) -> (30 < φ < 60) && (270 < λ < 360) ? parameters.temperature_atlantic : 0, add=true)
# 2. Azores
A = parameters.temperature_azores
λ_az, φ_az, σ_az = -27.25, 38.7, 4 # location [˚], size [˚] of Azores
set!(simulation, sea_surface_temperature=
(λ, φ) -> A*exp(-spherical_distance((λ, φ), (λ_az, φ_az), radius=360/2π)^2/2σ_az^2), add=true)
# Run simulation for 20 days, maybe longer for more stable statistics? Could be increased to 30, 40, ... days ?
run!(simulation, period=Day(20))
Chris Rackauckas: XGBoost surrogate, global BBO optimization
path: /submissions/chris_xgboost_global.jl
rank: 4. of 12 submissions
author = "Chris Rackauckas"
description = "XGBoost surrogate, global BBO optimization"
#=
# Same data as the neural network, just a dead simple surrogate
using JLSO
cd(raw"/Users/chrisrackauckas/.julia/external/speedier_speedyweather_juliaEO25")
data = JLSO.load("10kdata.jlso")[:d]
X = data.inputs'
y = data.outputs
Xtrain = X[1:2:end, :]
Xtest = X[2:2:end, :]
ytrain = y[1:2:end]
ytest = y[2:2:end]
using XGBoost, Statistics
bst = xgboost((Xtrain, ytrain), num_round=1000, max_depth=7, objective="reg:squarederror")
# obtain model predictions
ŷ = predict(bst, Xtest)
mean(abs2,ŷ - ytest)
evaluate(x) = predict(bst, reshape(x,1,10))[1]
using Optimization, OptimizationBBO
function loss(x,p)
-Float64(evaluate(x))
end
f = OptimizationFunction(loss)
lb = [0, -2000, 0, -180, -90, 270, 270, -5, -5, 5]
ub = [2, 5000, 30, 180, 90, 300, 300, 5, 5, 50]
x0 = Xtest[1,:]
prob = Optimization.OptimizationProblem(f, x0; lb, ub)
function callback(state, l) #callback function to observe training
display(l)
return false
end
sol = solve(prob, BBO_adaptive_de_rand_1_bin_radiuslimited(), maxiters = 100000,
maxtime = 1000.0, callback = callback)
=#
using SpeedyWeather
using RainMaker
PARAMETER_KEYS = (
:orography_scale, # [1], default: 1, scale of global orography
:mountain_height, # [m], default: 0, height of an additional azores mountain
:mountain_size, # [˚], default: 1, horizontal size of an additional azores mountain
:mountain_lon, # [˚E], default: -27.25, longitude of an additional azores mountain
:mountain_lat, # [˚N], default: 38.7, latitude of an additional azores mountain
:temperature_equator, # [K], default: 300, sea surface temperature at the equator
:temperature_pole, # [K], default: 273, sea surfaec temperature at the poles
:temperature_atlantic, # [K], default: 0, sea surface temperature anomaly in the atlantic
:temperature_azores, # [K], default: 0, sea surface temperature anomaly at the azores
:zonal_wind, # [m/s], default: 35, zonal wind speed
)
# output from the surrogate model
best_param_sample = [0.35952993077958434,
3703.1625800261263,
26.34236279617161,
-68.84186967475854,
75.45866186852497,
298.51854709388454,
296.03786989719214,
4.737936621135976,
4.397474802331573,
46.17772842581346
]
# wrap into named tuple
parameters = NamedTuple{PARAMETER_KEYS}(best_param_sample)
# define resolution. Use trunc=42, 63, 85, 127, ... for higher resolution, cubically slower
spectral_grid = SpectralGrid(trunc=31, nlayers=8)
# Define AquaPlanet ocean, for idealised sea surface temperatures
# but don't change land-sea mask = retain real ocean basins
ocean = AquaPlanet(spectral_grid,
temp_equator=parameters.temperature_equator,
temp_poles=parameters.temperature_pole)
# add initial conditions with a stronger zonal wind matching temperature
initial_conditions = InitialConditions(
vordiv = ZonalWind(u₀=parameters.zonal_wind),
temp = JablonowskiTemperature(u₀=parameters.zonal_wind),
pres = PressureOnOrography(),
humid = ConstantRelativeHumidity())
# Earth's orography but scaled
orography = EarthOrography(spectral_grid, scale=parameters.orography_scale)
# construct model
model = PrimitiveWetModel(spectral_grid; ocean, initial_conditions, orography)
# Add rain gauge, locate on Terceira Island
rain_gauge = RainGauge(spectral_grid, lond=-27.25, latd=38.7)
add!(model, rain_gauge)
# Initialize
simulation = initialize!(model, time=DateTime(2025, 1, 10))
# Add additional mountain
H = parameters.mountain_height
λ₀, φ₀, σ = parameters.mountain_lon, parameters.mountain_lat, parameters.mountain_size
set!(model, orography=(λ,φ) -> H*exp(-spherical_distance((λ,φ), (λ₀,φ₀), radius=360/2π)^2/2σ^2), add=true)
# set sea surface temperature anomalies
# 1. Atlantic
set!(simulation, sea_surface_temperature=
(λ, φ) -> (30 < φ < 60) && (270 < λ < 360) ? parameters.temperature_atlantic : 0, add=true)
# 2. Azores
A = parameters.temperature_azores
λ_az, φ_az, σ_az = -27.25, 38.7, 4 # location [˚], size [˚] of Azores
set!(simulation, sea_surface_temperature=
(λ, φ) -> A*exp(-spherical_distance((λ, φ), (λ_az, φ_az), radius=360/2π)^2/2σ_az^2), add=true)
# Run simulation for 20 days, maybe longer for more stable statistics? Could be increased to 30, 40, ... days ?
run!(simulation, period=Day(20))
Chris Rackauckas: Global BBO optimization with hot water
path: /submissions/chris_global_bbo_hotwater.jl
rank: 5. of 12 submissions
author = "Chris Rackauckas"
description = "Global BBO optimization with hot water"
#=
using SpeedyWeather
using RainMaker
using Optimization, OptimizationBBO
PARAMETER_KEYS = (
:orography_scale, # [1], default: 1, scale of global orography
:mountain_height, # [m], default: 0, height of an additional azores mountain
:mountain_size, # [˚], default: 1, horizontal size of an additional azores mountain
:mountain_lon, # [˚E], default: -27.25, longitude of an additional azores mountain
:mountain_lat, # [˚N], default: 38.7, latitude of an additional azores mountain
:temperature_equator, # [K], default: 300, sea surface temperature at the equator
:temperature_pole, # [K], default: 273, sea surfaec temperature at the poles
:sea_surface_temperature, # [K], default: 273, sea surface temperature anomaly in the atlantic
:zonal_wind, # [m/s], default: 35, zonal wind speed
:rotation, # [], default: 7.9e-5, Earth rotation
:ocean_temp, # [K], default: 175,
)
function calc_precip(u)
best_param_sample = u
# wrap into named tuple
parameters = NamedTuple{PARAMETER_KEYS}(best_param_sample)
# define resolution. Use trunc=42, 63, 85, 127, ... for higher resolution, cubically slower
spectral_grid = SpectralGrid(trunc=31, nlayers=8)
# Define AquaPlanet ocean, for idealised sea surface temperatures
# but don't change land-sea mask = retain real ocean basins
ocean = AquaPlanet(spectral_grid,
temp_equator=parameters.temperature_equator,
temp_poles=parameters.temperature_pole)
# add initial conditions with a stronger zonal wind matching temperature
initial_conditions = InitialConditions(
vordiv = ZonalWind(u₀=parameters.zonal_wind),
temp = JablonowskiTemperature(u₀=parameters.zonal_wind),
pres = PressureOnOrography(),
humid = ConstantRelativeHumidity())
# Earth's orography but scaled
orography = EarthOrography(spectral_grid, scale=parameters.orography_scale)
# construct model
model = PrimitiveWetModel(spectral_grid; ocean, initial_conditions, orography, planet=Earth(Float32, rotation=parameters.rotation))
# Add rain gauge, locate on Terceira Island
rain_gauge = RainGauge(spectral_grid, lond=-27.25, latd=38.7)
add!(model, rain_gauge)
# Initialize
simulation = initialize!(model, time=DateTime(2025, 1, 10))
# Add additional mountain
H = parameters.mountain_height
λ₀, φ₀, σ = parameters.mountain_lon, parameters.mountain_lat, parameters.mountain_size
set!(model, orography=(λ,φ) -> H*exp(-spherical_distance((λ,φ), (λ₀,φ₀), radius=360/2π)^2/2σ^2), add=true)
set!(simulation, temp = (λ, ϕ, σ) -> parameters.ocean_temp)
set!(simulation, sea_surface_temperature = (λ, φ) -> parameters.sea_surface_temperature)
# Run simulation for 20 days, maybe longer for more stable statistics? Could be increased to 30, 40, ... days ?
run!(simulation, period=Day(20))
skip!(rain_gauge, Day(5))
maximum(rain_gauge.accumulated_rain_convection + rain_gauge.accumulated_rain_large_scale)
end
loss(u,p) = -Float64(calc_precip(u))
f = OptimizationFunction(loss)
lb = [0, -2000, 0, -180, -90, 270, 270, 280, 5, 0.0 ,0.0]
ub = [2, 5000, 30, 180, 90, 300, 300, 305, 50, 1e-4, 305]
x0 = (lb .+ ub) ./ 2
prob = Optimization.OptimizationProblem(f, x0; lb, ub)
function callback(state, l) #callback function to observe training
display(l)
return false
end
sol = solve(prob, BBO_adaptive_de_rand_1_bin_radiuslimited(), maxiters = 10000,
maxtime = 10000.0, callback = callback)
loss(sol.u, nothing)
julia> @show sol.u
sol.u = [0.35189195474845386, -777.7890066578076, 14.561382886621368, 151.4405147870285, -0.8557381444610144, 296.3475643734993, 277.9450731849207, 304.0433587248594, 31.637335763119115, 6.329669836967033e-6, 169.16288037057643]
=#
using SpeedyWeather
using RainMaker
PARAMETER_KEYS = (
:orography_scale, # [1], default: 1, scale of global orography
:mountain_height, # [m], default: 0, height of an additional azores mountain
:mountain_size, # [˚], default: 1, horizontal size of an additional azores mountain
:mountain_lon, # [˚E], default: -27.25, longitude of an additional azores mountain
:mountain_lat, # [˚N], default: 38.7, latitude of an additional azores mountain
:temperature_equator, # [K], default: 300, sea surface temperature at the equator
:temperature_pole, # [K], default: 273, sea surfaec temperature at the poles
:sea_surface_temperature, # [K], default: 273, sea surface temperature anomaly in the atlantic
:zonal_wind, # [m/s], default: 35, zonal wind speed
:rotation, # [], default: 7.9e-5, Earth rotation
:ocean_temp, # [K], default: 175,
)
# output from the surrogate model
best_param_sample = [0.35189195474845386,
-777.7890066578076,
14.561382886621368,
151.4405147870285,
-0.8557381444610144,
296.3475643734993,
277.9450731849207,
304.0433587248594,
31.637335763119115,
6.329669836967033e-6,
169.16288037057643
]
# wrap into named tuple
parameters = NamedTuple{PARAMETER_KEYS}(best_param_sample)
# define resolution. Use trunc=42, 63, 85, 127, ... for higher resolution, cubically slower
spectral_grid = SpectralGrid(trunc=31, nlayers=8)
# Define AquaPlanet ocean, for idealised sea surface temperatures
# but don't change land-sea mask = retain real ocean basins
ocean = AquaPlanet(spectral_grid,
temp_equator=parameters.temperature_equator,
temp_poles=parameters.temperature_pole)
# add initial conditions with a stronger zonal wind matching temperature
initial_conditions = InitialConditions(
vordiv = ZonalWind(u₀=parameters.zonal_wind),
temp = JablonowskiTemperature(u₀=parameters.zonal_wind),
pres = PressureOnOrography(),
humid = ConstantRelativeHumidity())
# Earth's orography but scaled
orography = EarthOrography(spectral_grid, scale=parameters.orography_scale)
# construct model
model = PrimitiveWetModel(spectral_grid; ocean, initial_conditions, orography, planet=Earth(Float32, rotation=parameters.rotation))
# Add rain gauge, locate on Terceira Island
rain_gauge = RainGauge(spectral_grid, lond=-27.25, latd=38.7)
add!(model, rain_gauge)
# Initialize
simulation = initialize!(model, time=DateTime(2025, 1, 10))
# Add additional mountain
H = parameters.mountain_height
λ₀, φ₀, σ = parameters.mountain_lon, parameters.mountain_lat, parameters.mountain_size
set!(model, orography=(λ,φ) -> H*exp(-spherical_distance((λ,φ), (λ₀,φ₀), radius=360/2π)^2/2σ^2), add=true)
set!(simulation, temp = (λ, ϕ, σ) -> parameters.ocean_temp)
set!(simulation, sea_surface_temperature = (λ, φ) -> parameters.sea_surface_temperature)
# Run simulation for 20 days, maybe longer for more stable statistics? Could be increased to 30, 40, ... days ?
run!(simulation, period=Day(20))
Chris Rackauckas: XGBoost surrogate, best parameters
path: /submissions/chris_xgboost.jl
rank: 6. of 12 submissions
author = "Chris Rackauckas"
description = "XGBoost surrogate, best parameters"
#=
# Same data as the neural network, just a dead simple surrogate
using JLSO
cd(raw"/Users/chrisrackauckas/.julia/external/speedier_speedyweather_juliaEO25")
data = JLSO.load("10kdata.jlso")[:d]
X = data.inputs'
y = data.outputs
Xtrain = X[1:2:end, :]
Xtest = X[2:2:end, :]
ytrain = y[1:2:end]
ytest = y[2:2:end]
using XGBoost, Statistics
bst = xgboost((Xtrain, ytrain), num_round=1000, max_depth=7, objective="reg:squarederror")
# obtain model predictions
ŷ = predict(bst, Xtest)
mean(abs2,ŷ - ytest)
evaluate(x) = predict(bst, reshape(x,1,10))[1]
using Optimization, OptimizationBBO
function loss(x,p)
-Float64(evaluate(x))
end
f = OptimizationFunction(loss)
lb = [0, -2000, 0, -180, -90, 270, 270, -5, -5, 5]
ub = [2, 5000, 30, 180, 90, 300, 300, 5, 5, 50]
x0 = Xtest[1,:]
prob = Optimization.OptimizationProblem(f, x0; lb, ub)
function callback(state, l) #callback function to observe training
display(l)
return false
end
sol = solve(prob, BBO_adaptive_de_rand_1_bin_radiuslimited(), maxiters = 100000,
maxtime = 1000.0, callback = callback)
=#
using SpeedyWeather
using RainMaker
PARAMETER_KEYS = (
:orography_scale, # [1], default: 1, scale of global orography
:mountain_height, # [m], default: 0, height of an additional azores mountain
:mountain_size, # [˚], default: 1, horizontal size of an additional azores mountain
:mountain_lon, # [˚E], default: -27.25, longitude of an additional azores mountain
:mountain_lat, # [˚N], default: 38.7, latitude of an additional azores mountain
:temperature_equator, # [K], default: 300, sea surface temperature at the equator
:temperature_pole, # [K], default: 273, sea surfaec temperature at the poles
:temperature_atlantic, # [K], default: 0, sea surface temperature anomaly in the atlantic
:temperature_azores, # [K], default: 0, sea surface temperature anomaly at the azores
:zonal_wind, # [m/s], default: 35, zonal wind speed
)
# output from the surrogate model
best_param_sample = [0.3705309673344287,
3693.5996052143146,
26.3392947114213,
-68.49507115449609,
75.0016456129241,
295.8298679043166,
296.00395874468376,
4.7262056077412495,
4.371020708252552,
46.16767297988565
]
# wrap into named tuple
parameters = NamedTuple{PARAMETER_KEYS}(best_param_sample)
# define resolution. Use trunc=42, 63, 85, 127, ... for higher resolution, cubically slower
spectral_grid = SpectralGrid(trunc=31, nlayers=8)
# Define AquaPlanet ocean, for idealised sea surface temperatures
# but don't change land-sea mask = retain real ocean basins
ocean = AquaPlanet(spectral_grid,
temp_equator=parameters.temperature_equator,
temp_poles=parameters.temperature_pole)
# add initial conditions with a stronger zonal wind matching temperature
initial_conditions = InitialConditions(
vordiv = ZonalWind(u₀=parameters.zonal_wind),
temp = JablonowskiTemperature(u₀=parameters.zonal_wind),
pres = PressureOnOrography(),
humid = ConstantRelativeHumidity())
# Earth's orography but scaled
orography = EarthOrography(spectral_grid, scale=parameters.orography_scale)
# construct model
model = PrimitiveWetModel(spectral_grid; ocean, initial_conditions, orography)
# Add rain gauge, locate on Terceira Island
rain_gauge = RainGauge(spectral_grid, lond=-27.25, latd=38.7)
add!(model, rain_gauge)
# Initialize
simulation = initialize!(model, time=DateTime(2025, 1, 10))
# Add additional mountain
H = parameters.mountain_height
λ₀, φ₀, σ = parameters.mountain_lon, parameters.mountain_lat, parameters.mountain_size
set!(model, orography=(λ,φ) -> H*exp(-spherical_distance((λ,φ), (λ₀,φ₀), radius=360/2π)^2/2σ^2), add=true)
# set sea surface temperature anomalies
# 1. Atlantic
set!(simulation, sea_surface_temperature=
(λ, φ) -> (30 < φ < 60) && (270 < λ < 360) ? parameters.temperature_atlantic : 0, add=true)
# 2. Azores
A = parameters.temperature_azores
λ_az, φ_az, σ_az = -27.25, 38.7, 4 # location [˚], size [˚] of Azores
set!(simulation, sea_surface_temperature=
(λ, φ) -> A*exp(-spherical_distance((λ, φ), (λ_az, φ_az), radius=360/2π)^2/2σ_az^2), add=true)
# Run simulation for 20 days, maybe longer for more stable statistics? Could be increased to 30, 40, ... days ?
run!(simulation, period=Day(20))
Shirin Ermis: Aqua-planet simulation with a mountain
path: /submissions/aquaplanet_mountain.jl
rank: 7. of 12 submissions
author = "Shirin Ermis"
description = "Aqua-planet simulation with a mountain"
using SpeedyWeather, RainMaker
spectral_grid = SpectralGrid(trunc=31, nlayers=10)
model = PrimitiveWetModel(spectral_grid)
# Set up aqauaplanet but add large mountain in "North Sea" after initialization!
ocean = AquaPlanet(spectral_grid, temp_equator=302, temp_poles=300)
land_sea_mask = AquaPlanetMask(spectral_grid)
model = PrimitiveWetModel(spectral_grid; ocean, land_sea_mask)
# Add rain gauge
rain_gauge = RainGauge(spectral_grid, lond=-27.25, latd=38.7)
add!(model, rain_gauge)
# Initialize and run simulation
simulation = initialize!(model, time=DateTime(2000, 9, 1))
# Add mountain now! details for mountain
H, λ₀, φ₀, σ = 4000, 2, 51, 5 # height, lon, lat position, and width
set!(model, orography=(λ,φ) -> H*exp(-spherical_distance((λ,φ), (λ₀,φ₀), radius=360/2π)^2/2σ^2))
# Run simulation for 20 days
run!(simulation, period=Day(20))
# Plot the results (not needed for submission but doesn't hurt!)
using CairoMakie
# heatmap(model.orography.orography, title="My orogoraphy [m]") # check orography
RainMaker.plot(rain_gauge, rate_Δt=Hour(1))
Milan: Aquaplanet
path: /submissions/aquaplanet.jl
rank: 8. of 12 submissions
author = "Milan"
description = "Aquaplanet"
using SpeedyWeather, RainMaker
spectral_grid = SpectralGrid(trunc=31, nlayers=8)
# define aquaplanet
ocean = AquaPlanet(spectral_grid, temp_equator=302, temp_poles=273)
land_sea_mask = AquaPlanetMask(spectral_grid)
orography = NoOrography(spectral_grid)
model = PrimitiveWetModel(spectral_grid; ocean, land_sea_mask, orography)
rain_gauge = RainGauge(spectral_grid, lond=-27.25, latd=38.7)
add!(model, rain_gauge)
simulation = initialize!(model)
run!(simulation, period=Day(20))
Iga: Just playing around
path: /submissions/iga_model.jl
rank: 9. of 12 submissions
author = "Iga"
description = "Just playing around"
using SpeedyWeather # v0.13 (or #main)
using RainMaker # v0.2 (or #main)
spectral_grid = SpectralGrid(trunc=31, nlayers=8)
model = PrimitiveWetModel(spectral_grid)
rain_gauge = RainGauge(spectral_grid, lond=-27.25, latd=38.7)
add!(model, rain_gauge)
simulation = initialize!(model, time=DateTime(2000, 2, 1))
H = 8000 # height [m]
λ_azores = -27.25 # longitude [˚E]
φ_azores = 37.3 # latitude [˚N]
σ = 4 # size [˚]
# define bigger azores as anonymous function, Gaussian mountain, use radius=360/2π for distance in [˚]
bigger_azores = (λ, φ) -> H*exp(-spherical_distance((λ, φ), (λ_azores, φ_azores), radius=360/2π)^2/2σ^2)
# add to default orography, don't replace
set!(model, orography=bigger_azores, land_sea_mask=0, add=true)
set!(simulation, temp=0, sea_surface_temperature=(λ, φ) -> (30 < φ < 60) && (270 < λ < 360) ? 2 : 0, add=true)
run!(simulation, period=Day(20))
Tim Reichelt: North Sea mountain
path: /submissions/north_sea_mountain.jl
rank: 10. of 12 submissions
author = "Tim Reichelt"
description = "North Sea mountain"
using SpeedyWeather, RainMaker
spectral_grid = SpectralGrid(trunc=31, nlayers=8)
model = PrimitiveWetModel(spectral_grid)
rain_gauge = RainGauge(spectral_grid, lond=-27.25, latd=38.7)
add!(model, rain_gauge)
simulation = initialize!(model)
# add a massive mountain at 51.75°N, 0°W, *after* model initialization
# using spherical_distance for geodesic distances, use radius=360/2π for distance in degrees
H, λ₀, φ₀, σ = 4000, 2, 51, 5 # height, lon, lat position, and width
set!(model, orography=(λ,φ) -> H*exp(-spherical_distance((λ,φ), (λ₀,φ₀), radius=360/2π)^2/2σ^2))
run!(simulation, period=Day(20))
Milan: default
path: /submissions/default.jl
rank: 11. of 12 submissions
author = "Milan"
description = "default"
using SpeedyWeather, RainMaker
spectral_grid = SpectralGrid(trunc=31, nlayers=8)
model = PrimitiveWetModel(spectral_grid)
rain_gauge = RainGauge(spectral_grid, lond=-27.25, latd=38.7)
add!(model, rain_gauge)
simulation = initialize!(model)
run!(simulation, period=Day(20))
Milan: Atlantic mountain
path: /submissions/atlantic_mountain.jl
rank: 12. of 12 submissions
author = "Milan"
description = "Atlantic mountain"
using SpeedyWeather, RainMaker
spectral_grid = SpectralGrid(trunc=31, nlayers=8)
model = PrimitiveWetModel(spectral_grid)
rain_gauge = RainGauge(spectral_grid, lond=-27.25, latd=38.7)
add!(model, rain_gauge)
simulation = initialize!(model)
# add a massive mountain at 50°N, 35°W, *after* model initialization
H, λ₀, φ₀, σ = 4000, 325, 50, 5 # height, lon, lat position, and width
set!(model, orography=(λ,φ) -> H*exp((-(λ-λ₀)^2 - (φ-φ₀)^2)/2σ^2), add=true)
run!(simulation, period=Day(20))