1+ using CondaPkg
2+
3+ using ClimaOcean. OceanSeaIceModels: reference_density, heat_capacity, SeaIceSimulation
4+
5+ import Oceananigans. Fields: set!
6+ import Oceananigans. TimeSteppers: time_step!
7+
8+ import ClimaOcean. OceanSeaIceModels: OceanSeaIceModel
9+
10+ """
11+ install_veros()
12+
13+ Install the Copernicus Marine CLI using CondaPkg.
14+ Returns a NamedTuple containing package information if successful.
15+ """
16+ function install_veros ()
17+ CondaPkg. add (" veros" ; channel = " conda-forge" )
18+ cli = CondaPkg. which (" veros" )
19+ @info " ... the veros CLI has been installed at $(cli) ."
20+ return cli
21+ end
22+
23+ struct VerosOceanSimulation{S}
24+ setup :: S
25+ end
26+
27+ time_step! (sim:: VerosOceanSimulation , Δt) = sim. setup. step ()
28+
29+ function remove_outputs (setup:: Symbol )
30+ rm (" $(setup) .averages.nc" , force= true )
31+ rm (" $(setup) .energy.nc" , force= true )
32+ rm (" $(setup) .overturning.nc" , force= true )
33+ rm (" $(setup) .snapshot.nc" , force= true )
34+ return nothing
35+ end
36+
37+ const Field2D = Field{<: Any , <: Any , <: Nothing }
38+
39+ function set! (field:: Field2D , pyarray:: Py , k= pyconvert (Int, pyarray. shape[2 ]))
40+ array = PyArray (pyarray)
41+ Nx, Ny, Nz = size (array)
42+ set! (field, view (array, 3 : Nx- 2 , 3 : Ny- 2 , k, 1 ))
43+ return field
44+ end
45+
46+ function veros_ocean_simulation (setup, setup_name)
47+ setups = pyimport (" veros.setups." * setup)
48+ setup = @eval $ setups.$ setup_name ()
49+
50+ # instantiate the setup
51+ setup. setup ()
52+
53+ return VerosOceanSimulation (setup)
54+ end
55+
56+ function surface_grid (setup:: VerosOceanSimulation )
57+
58+ xf = Array (PyArray (setup. state. variables. xu))
59+ yf = Array (PyArray (setup. state. variables. yu))
60+
61+ xc = Array (PyArray (setup. state. variables. xt))
62+ yc = Array (PyArray (setup. state. variables. yt))
63+
64+ xf = xf[2 : end - 2 ]
65+ yf = yf[2 : end - 2 ]
66+
67+ xc = xc[3 : end - 2 ]
68+ yc = yc[3 : end - 2 ]
69+
70+ xf[1 ] = xf[2 ] - 2 xc[1 ]
71+ yf[1 ] = sign (yf[2 ]) * (yf[2 ] - 2 yc[1 ])
72+
73+ TX = if xf[1 ] == 0 && xf[end ] == 360
74+ Periodic
75+ else
76+ Bounded
77+ end
78+
79+ Nx = length (xc)
80+ Ny = length (yc)
81+
82+ return LatitudeLongitudeGrid (size= (Nx, Ny), longitude= xf, latitude= yf, topology= (TX, Bounded, Flat))
83+ end
84+
85+ function veros_set! (ocean:: VerosOceanSimulation , v, x)
86+ s = ocean. setup
87+ pyexec ("""
88+ with setup.state.variables.unlock():
89+ setup.state.variables.__setattr__(y, t)
90+ """ , Main, (y= v, t= x, setup= s))
91+ end
92+
93+ function veros_settings_set! (ocean:: VerosOceanSimulation , v, x)
94+ s = ocean. setup
95+ pyexec ("""
96+ with setup.state.settings.unlock():
97+ setup.state.settings.__setattr__(y, t)
98+ """ , Main, (y= v, t= x, setup= s))
99+ end
100+
101+ function OceanSeaIceModel (ocean:: VerosOceanSimulation , sea_ice= nothing ;
102+ atmosphere = nothing ,
103+ radiation = Radiation (),
104+ clock = Clock (time= 0 ),
105+ ocean_reference_density = 1020.0 ,
106+ ocean_heat_capacity = 3998.0 ,
107+ sea_ice_reference_density = reference_density (sea_ice),
108+ sea_ice_heat_capacity = heat_capacity (sea_ice),
109+ interfaces = nothing )
110+
111+ if sea_ice isa SeaIceSimulation
112+ if ! isnothing (sea_ice. callbacks)
113+ pop! (sea_ice. callbacks, :stop_time_exceeded , nothing )
114+ pop! (sea_ice. callbacks, :stop_iteration_exceeded , nothing )
115+ pop! (sea_ice. callbacks, :wall_time_limit_exceeded , nothing )
116+ pop! (sea_ice. callbacks, :nan_checker , nothing )
117+ end
118+ end
119+
120+ # Contains information about flux contributions: bulk formula, prescribed fluxes, etc.
121+ if isnothing (interfaces) && ! (isnothing (atmosphere) && isnothing (sea_ice))
122+ interfaces = ComponentInterfaces (atmosphere, ocean, sea_ice;
123+ ocean_reference_density,
124+ ocean_heat_capacity,
125+ sea_ice_reference_density,
126+ sea_ice_heat_capacity,
127+ radiation)
128+ end
129+
130+ arch = CPU ()
131+
132+ ocean_sea_ice_model = OceanSeaIceModel (arch,
133+ clock,
134+ atmosphere,
135+ sea_ice,
136+ ocean,
137+ interfaces)
138+
139+ # Make sure the initial temperature of the ocean
140+ # is not below freezing and above melting near the surface
141+ initialization_update_state! (ocean_sea_ice_model)
142+
143+ return ocean_sea_ice_model
144+ end
0 commit comments