diff --git a/src/DataWrangling/ECCO/ECCO.jl b/src/DataWrangling/ECCO/ECCO.jl index e2c1d3a86..6c706701c 100644 --- a/src/DataWrangling/ECCO/ECCO.jl +++ b/src/DataWrangling/ECCO/ECCO.jl @@ -176,7 +176,13 @@ ECCO4_dataset_variable_names = Dict( :latent_heat_flux => "EXFhl", :net_longwave => "EXFlwnet", :downwelling_shortwave => "oceQsw", - :downwelling_longwave => "EXFlwdn", + :downwelling_longwave => "EXFlwdn", + :air_temperature => "EXFatemp", + :air_specific_humidity => "EXFaqh", + :sea_level_pressure => "EXFpress", + :eastward_wind => "EXFewind", + :northward_wind => "EXFnwind", + :rain_freshwater_flux => "EXFpreci", ) ECCO2_dataset_variable_names = Dict( @@ -187,24 +193,30 @@ ECCO2_dataset_variable_names = Dict( :free_surface => "SSH", :sea_ice_thickness => "SIheff", :sea_ice_concentration => "SIarea", - :net_heat_flux => "oceQnet" + :net_heat_flux => "oceQnet", ) ECCO_location = Dict( :temperature => (Center, Center, Center), :salinity => (Center, Center, Center), + :u_velocity => (Face, Center, Center), + :v_velocity => (Center, Face, Center), :free_surface => (Center, Center, Nothing), :sea_ice_thickness => (Center, Center, Nothing), :sea_ice_concentration => (Center, Center, Nothing), :net_heat_flux => (Center, Center, Nothing), - :u_velocity => (Face, Center, Center), - :v_velocity => (Center, Face, Center), :sensible_heat_flux => (Center, Center, Nothing), :latent_heat_flux => (Center, Center, Nothing), :net_longwave => (Center, Center, Nothing), - :downwelling_shortwave => (Center, Center, Nothing), :downwelling_longwave => (Center, Center, Nothing), -) + :downwelling_shortwave => (Center, Center, Nothing), + :air_temperature => (Center, Center, Nothing), + :air_specific_humidity => (Center, Center, Nothing), + :sea_level_pressure => (Center, Center, Nothing), + :eastward_wind => (Center, Center, Nothing), + :northward_wind => (Center, Center, Nothing), + :rain_freshwater_flux => (Center, Center, Nothing), +) const ECCOMetadata{D} = Metadata{<:ECCODataset, D} const ECCOMetadatum = Metadatum{<:ECCODataset} @@ -316,4 +328,6 @@ end inpainted_metadata_path(metadata::ECCOMetadata) = joinpath(metadata.dir, inpainted_metadata_filename(metadata)) +include("ECCO_atmosphere.jl") + end # Module diff --git a/src/DataWrangling/ECCO/ECCO_atmosphere.jl b/src/DataWrangling/ECCO/ECCO_atmosphere.jl new file mode 100644 index 000000000..7403690af --- /dev/null +++ b/src/DataWrangling/ECCO/ECCO_atmosphere.jl @@ -0,0 +1,75 @@ +using ClimaOcean.DataWrangling: DatasetBackend +using Oceananigans.OutputReaders +using ClimaOcean.OceanSeaIceModels: TwoBandDownwellingRadiation + +""" + ECCOPrescribedAtmosphere([architecture = CPU(), FT = Float32]; + dataset = ECCO4Montly(), + start_date = first_date(dataset, :temperature), + end_date = last_date(dataset, :temperature), + backend = DatasetBackend(10), + time_indexing = Cyclical(), + surface_layer_height = 10, # meters + include_rivers_and_icebergs = false, + other_kw...) + +Return a [`PrescribedAtmosphere`](@ref) representing JRA55 reanalysis data. +The atmospheric data will be held in `JRA55FieldTimeSeries` objects containing. +For a detailed description of the keyword arguments, see the [`JRA55FieldTimeSeries`](@ref) constructor. +""" +function ECCOPrescribedAtmosphere(architecture = CPU(), FT = Float32; + dataset = ECCO4Monthly(), + start_date = first_date(dataset, :air_temperature), + end_date = last_date(dataset, :air_temperature), + time_indexing = Cyclical(), + time_indices_in_memory = 10, + surface_layer_height = 2, # meters + other_kw...) + + ua_meta = Metadata(:eastward_wind; dataset, start_date, end_date) + va_meta = Metadata(:northward_wind; dataset, start_date, end_date) + Ta_meta = Metadata(:air_temperature; dataset, start_date, end_date) + qa_meta = Metadata(:air_specific_humidity; dataset, start_date, end_date) + pa_meta = Metadata(:sea_level_pressure; dataset, start_date, end_date) + Ql_meta = Metadata(:downwelling_longwave; dataset, start_date, end_date) + Qs_meta = Metadata(:downwelling_shortwave; dataset, start_date, end_date) + Fr_meta = Metadata(:rain_freshwater_flux; dataset, start_date, end_date) + + kw = (; time_indices_in_memory, time_indexing) + kw = merge(kw, other_kw) + + ua = FieldTimeSeries(ua_meta, architecture; kw...) + va = FieldTimeSeries(va_meta, architecture; kw...) + Ta = FieldTimeSeries(Ta_meta, architecture; kw...) + qa = FieldTimeSeries(qa_meta, architecture; kw...) + pa = FieldTimeSeries(pa_meta, architecture; kw...) + Ql = FieldTimeSeries(Ql_meta, architecture; kw...) + Qs = FieldTimeSeries(Qs_meta, architecture; kw...) + Fr = FieldTimeSeries(Fr_meta, architecture; kw...) + + auxiliary_freshwater_flux = nothing + freshwater_flux = (; rain = Fr) + + times = ua.times + grid = ua.grid + + velocities = (u = ua, v = va) + tracers = (T = Ta, q = qa) + pressure = pa + + downwelling_radiation = TwoBandDownwellingRadiation(shortwave=Qs, longwave=Ql) + + FT = eltype(ua) + surface_layer_height = convert(FT, surface_layer_height) + + atmosphere = PrescribedAtmosphere(grid, times; + velocities, + freshwater_flux, + auxiliary_freshwater_flux, + tracers, + downwelling_radiation, + surface_layer_height, + pressure) + + return atmosphere +end diff --git a/src/DataWrangling/metadata_field.jl b/src/DataWrangling/metadata_field.jl index a57b6622c..fa753992a 100644 --- a/src/DataWrangling/metadata_field.jl +++ b/src/DataWrangling/metadata_field.jl @@ -185,7 +185,7 @@ function set_metadata_field!(field, data, metadatum) nothing end - temp_units = if metadatum.name == :temperature + temp_units = if metadatum.name == :temperature temperature_units(metadatum.dataset) else nothing @@ -231,11 +231,9 @@ end @kernel function _set_3d_metadata_field!(field, data, mangling, temp_units, conc_units) i, j, k = @index(Global, NTuple) - d = mangle(i, j, k, data, mangling) - FT = eltype(field) + d = mangle(i, j, k, data, mangling) d = nan_convert_missing(FT, d) - if !isnothing(temp_units) d = convert_temperature(d, temp_units) elseif !isnothing(conc_units) diff --git a/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl b/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl index 592794f0e..db82d2a78 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl @@ -155,6 +155,7 @@ struct DegreesCelsius end struct DegreesKelvin end const celsius_to_kelvin = 273.15 + @inline convert_to_kelvin(::DegreesCelsius, T::FT) where FT = T + convert(FT, celsius_to_kelvin) @inline convert_to_kelvin(::DegreesKelvin, T) = T diff --git a/src/OceanSeaIceModels/InterfaceComputations/interpolate_atmospheric_state.jl b/src/OceanSeaIceModels/InterfaceComputations/interpolate_atmospheric_state.jl index d79a9caf9..2fddb2347 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/interpolate_atmospheric_state.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/interpolate_atmospheric_state.jl @@ -233,8 +233,7 @@ end interp_atmos_time_series(values(ΣJ), args...) @inline interp_atmos_time_series(ΣJ::Tuple{<:Any}, args...) = - interp_atmos_time_series(ΣJ[1], args...) + - interp_atmos_time_series(ΣJ[2], args...) + interp_atmos_time_series(ΣJ[1], args...) @inline interp_atmos_time_series(ΣJ::Tuple{<:Any, <:Any}, args...) = interp_atmos_time_series(ΣJ[1], args...) +