Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
801352f
thermodynamic sea ice
ntlewis Jan 16, 2023
3f76abb
options for single precision (won't work with socrates)
ntlewis Jan 16, 2023
420d998
changes to rrtm to have more control over coszen, and to allow for si…
ntlewis Jul 21, 2023
12d0bae
let my25 read restart so it actually works
ntlewis Jul 21, 2023
8021f3d
additions to two_stream_gray for tidally locked planets
ntlewis Jul 21, 2023
92f222d
add additional dry convection scheme (+ other changes?)
ntlewis Jul 21, 2023
f25a3f1
change valid range for wind for exoplanets
ntlewis Jul 21, 2023
990e907
add path to new dry convection scheme
ntlewis Jul 21, 2023
abc8241
add nudging options to sea ice code
ntlewis Jul 21, 2023
3cbfbdc
compiler options in python interface
ntlewis Oct 18, 2023
272d573
stuff to do with ozone in grey model
ntlewis Oct 18, 2023
e218620
remove modifications that only nudge ice for thickness greater than 0.1
ntlewis Oct 18, 2023
2630ea6
tidy sea ice branch, so only code necessary for thermodynamic sea ice…
ntlewis May 31, 2024
cbdc1c9
thermodynamic sea ice test case
ntlewis May 31, 2024
90f3acb
merge master into thermo sea ice branch
ntlewis May 31, 2024
0d3284e
re-add B_BYRNE (deleted by mistake)
ntlewis May 31, 2024
e2f9b0d
Delete mkmf.template.ubuntu_conda2
ntlewis May 31, 2024
a898b08
fix mixed_layer.F90 syntax error
ntlewis May 31, 2024
66268d1
try to fix mixed_layer syntax error again
ntlewis May 31, 2024
a8146a5
deleting code preventing compile that evaded initial tidy
ntlewis May 31, 2024
68aea1c
Merge branch 'master' into thermodynamic_sea_ice
ntlewis Sep 29, 2025
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
238 changes: 238 additions & 0 deletions exp/test_cases/thermodynamic_sea_ice/grey_thermo_ice_test_case.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
import os

import numpy as np

from isca import GreyCodeBase, DiagTable, Experiment, Namelist, GFDL_BASE

NCORES =16

# Point to code as defined by $GFDL_BASE
cb = GreyCodeBase.from_directory(GFDL_BASE)

base_dir = os.path.dirname(os.path.realpath(__file__))

cb.compile() # compile the source code to working directory $GFDL_WORK/codebase

# create an Experiment object to handle the configuration of model parameters
# and output diagnostics
exp = Experiment('thermo_ice_test_experiment', codebase=cb)


#Tell model how to write diagnostics
diag = DiagTable()
diag.add_file('atmos_monthly', 30, 'days', time_units='days')

#Tell model which diagnostics to write
diag.add_field('dynamics', 'ps', time_avg=True)
diag.add_field('dynamics', 'bk')
diag.add_field('dynamics', 'pk')
diag.add_field('atmosphere', 'temp_2m', time_avg=True)
diag.add_field('dynamics', 'ucomp', time_avg=True)
diag.add_field('dynamics', 'temp', time_avg=True)
diag.add_field('mixed_layer', 'albedo', time_avg=True)
diag.add_field('mixed_layer', 'h_thermo_ice', time_avg=True)
diag.add_field('mixed_layer', 't_surf', time_avg=True)
diag.add_field('mixed_layer', 'flux_oceanq', time_avg=True)
diag.add_field('two_stream', 'swdn_toa', time_avg=True)



exp.diag_table = diag # register diag table


#Empty the run directory ready to run
exp.clear_rundir()

#Define values for the 'core' namelist
exp.namelist = namelist = Namelist({
'main_nml': {
'days' : 360, # each run lasts one year, and then multiple runs are strung together below (loop on e.g. Line 310)
'hours' : 0, # a different output file is produced for each run (in this case, each year). Data
'minutes': 0, # output at the frequency specified in the diag table
'seconds': 0,
'dt_atmos':900,
'current_date' : [1,1,1,0,0,0],
'calendar' : 'thirty_day'
},

'idealized_moist_phys_nml': {
'two_stream_gray': True,
'do_rrtm_radiation': False,
'convection_scheme': 'SIMPLE_BETTS_MILLER',
'do_damping': True,
'turb':True,
'mixed_layer_bc':True,
'do_virtual' :True,
'roughness_mom':5.e-3,
'roughness_heat':1.e-5,
'roughness_moist':1.e-5,
'land_roughness_prefactor':1.0,
'do_simple':False,
},

'vert_turb_driver_nml': {
'do_mellor_yamada': False,
'do_diffusivity': True,
'do_edt':False,
'constant_gust': 1.0,
'use_tau': False,
'do_entrain':False,
'do_stable_bl':False,
'do_shallow_conv':False,
'do_simple':False
},

'diffusivity_nml': {
'do_entrain':False,
'entr_ratio': 0.0,
'free_atm_diff':False,
'do_simple': False,
'parcel_buoy': 0.0,
'frac_inner': 0.1,
'fixed_depth': False,
},

'surface_flux_nml': {
'use_virtual_temp': True,
'do_simple': False,
'old_dtaudv': False,
'gust_const':1.0,
'land_humidity_prefactor' : 1.0,
'land_evap_prefactor': 1.0,
},

'atmosphere_nml': {
'idealized_moist_model': True
},


'mixed_layer_nml': {
'depth': 30.,
'albedo_value': 0.1,
'prescribe_initial_dist':True,
'tconst' : 305.,
'delta_T': 60.,
'evaporation':True,
'do_qflux': True,
'load_qflux':False,
'time_varying_qflux' : False,
'do_thermo_ice':True, # turn on thermodynamic ice
'thermo_ice_albedo':0.55, # ice albedo
't_thermo_ice_base':273.15-2., # freezing point
't_surf_freeze':273.15-2., # freezing point
'do_var_thermo_ice_albedo':False,
'read_const_correct':False,
'read_nudge_out':False,

},

'qflux_nml':{
'qflux_amp':30.,
},



'qe_moist_convection_nml': {
'rhbm':0.7,
'tau_bm':7200.,
'Tmin':120.,
'Tmax':360.,
'val_inc': 0.01,
'precision':1.e-6
},

'lscale_cond_nml': {
'do_simple':False,
'do_evap':False
},

'sat_vapor_pres_nml': {
'do_simple':False,

},



'damping_driver_nml': {
'do_rayleigh': True,
'trayfric': -0.5, # neg. value: time in *days*
'sponge_pbottom': 2600.,
'do_conserve_energy': True,
},




'two_stream_gray_rad_nml': {
'rad_scheme': 'frierson', #Select radiation scheme to use
'do_seasonal': True,
'use_time_average_coszen':True,
'dt_rad_avg':86400.,
'atm_abs': 0.22,
'solar_exponent':2,
'ir_tau_eq':7.2,
'ir_tau_pole':3.6,#1.8,
'del_sol':0.98,
'solar_constant':1360,
'linear_tau':0.2,
'odp':1.4,
'do_toa_albedo':True,
},


'spectral_dynamics_nml': {
'damping_order': 4, # Yields lap^8 damping
'water_correction_limit': 200.e2,
'reference_sea_level_press':1.0e5,
'num_levels':30,
'valid_range_t':[100.,800.],
'initial_sphum':[2.e-6],
'use_virtual_temperature':True,
'vert_coord_option':'uneven_sigma',
'robert_coeff':0.03,
# set to T42 resolution
'lon_max': 128,
'lat_max': 64,
'num_fourier': 42,
'num_spherical':43,
'surf_res': 0.05,
'exponent': 3.,
'scale_heights': 5

},

'spectral_init_cond_nml':{
'initial_temperature':280.
},



'diag_manager_nml': {
'mix_snapshot_average_fields': False # time avg fields are labelled with time in middle of window
},

'fms_nml': {
'domains_stack_size': 600000 # default: 0
},

'fms_io_nml': {
'threading_write': 'single', # default: multi
'fileset_write': 'single', # default: multi
},




})

# Lets do a run!
if __name__=="__main__":


exp.run(1, use_restart=False, num_cores=NCORES, overwrite_data=False)

for i in range(1,11): # run for 10 years
exp.run(i, num_cores=NCORES, overwrite_data=False)



39 changes: 33 additions & 6 deletions src/atmos_param/two_stream_gray_rad/two_stream_gray_rad.F90
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ module two_stream_gray_rad_mod
character(len=256) :: co2_file='co2' ! file name of co2 file to read
character(len=256) :: co2_variable_name='co2' ! file name of co2 file to read

logical :: do_toa_albedo = .false.

namelist/two_stream_gray_rad_nml/ solar_constant, del_sol, &
ir_tau_eq, ir_tau_pole, odp, atm_abs, sw_diff, &
Expand All @@ -148,14 +149,15 @@ module two_stream_gray_rad_mod
window, carbon_conc, rad_scheme, &
do_read_co2, co2_file, co2_variable_name, solday, equinox_day, bog_a, bog_b, bog_mu, &
use_time_average_coszen, dt_rad_avg,&
diabatic_acce !Schneider Liu values
diabatic_acce, & !Schneider Liu values
do_toa_albedo

!==================================================================================
!-------------------- diagnostics fields -------------------------------

integer :: id_olr, id_swdn_sfc, id_swdn_toa, id_net_lw_surf, id_lwdn_sfc, id_lwup_sfc, &
id_tdt_rad, id_tdt_solar, id_flux_rad, id_flux_lw, id_flux_sw, id_coszen, id_fracsun, &
id_lw_dtrans, id_lw_dtrans_win, id_sw_dtrans, id_co2
id_lw_dtrans, id_lw_dtrans_win, id_sw_dtrans, id_co2, id_nudge_flux

character(len=10), parameter :: mod_name = 'two_stream'

Expand Down Expand Up @@ -347,7 +349,6 @@ subroutine two_stream_gray_rad_init(is, ie, js, je, num_levels, axes, Time, lonb
register_diag_field ( mod_name, 'flux_sw', axes(half), Time, &
'Net shortwave radiative flux (positive up)', &
'W/m^2', missing_value=missing_value )

id_coszen = &
register_diag_field ( mod_name, 'coszen', axes(1:2), Time, &
'cosine of zenith angle', &
Expand Down Expand Up @@ -378,13 +379,17 @@ subroutine two_stream_gray_rad_init(is, ie, js, je, num_levels, axes, Time, lonb
register_diag_field ( mod_name, 'lw_dtrans', axes(1:3), Time, &
'LW transmission (non window)', &
'none', missing_value=missing_value )
id_nudge_flux = &
register_diag_field ( mod_name, 'nudge_flux', axes(1:2), Time, &
'Sea ice nudging flux', &
'W/m2', missing_value=missing_value )
return
end subroutine two_stream_gray_rad_init

! ==================================================================================

subroutine two_stream_gray_rad_down (is, js, Time_diag, lat, lon, p_half, t, &
net_surf_sw_down, surf_lw_down, albedo, q)
net_surf_sw_down, surf_lw_down, albedo, q, const_correct, nudge_out)

! Begin the radiation calculation by computing downward fluxes.
! This part of the calculation does not depend on the surface temperature.
Expand All @@ -395,6 +400,7 @@ subroutine two_stream_gray_rad_down (is, js, Time_diag, lat, lon, p_half, t,
real, intent(out), dimension(:,:) :: net_surf_sw_down
real, intent(out), dimension(:,:) :: surf_lw_down
real, intent(in), dimension(:,:,:) :: t, q, p_half
real, intent(in), dimension(:,:) :: const_correct, nudge_out
integer :: i, j, k, n, dyofyr

integer :: seconds, year_in_s, days
Expand All @@ -404,6 +410,7 @@ subroutine two_stream_gray_rad_down (is, js, Time_diag, lat, lon, p_half, t,

real ,dimension(size(q,1),size(q,2),size(q,3)) :: co2f


n = size(t,3)


Expand Down Expand Up @@ -446,13 +453,21 @@ subroutine two_stream_gray_rad_down (is, js, Time_diag, lat, lon, p_half, t,
end if

insolation = solar_constant * coszen

if (do_toa_albedo) then
p2 = (1. - 3.*sin(lat)**2)/4.
insolation = insolation * (0.75 + 0.15 * 2. * p2)
endif

else if (sw_scheme==B_SCHNEIDER_LIU) then
insolation = (solar_constant/pi)*cos(lat)
else
! Default: Averaged Earth insolation at all longitudes
p2 = (1. - 3.*sin(lat)**2)/4.
insolation = 0.25 * solar_constant * (1.0 + del_sol * p2 + del_sw * sin(lat))
if (do_toa_albedo) then
insolation = insolation * (0.75 + 0.15 * 2. * p2)
endif
end if

select case(sw_scheme)
Expand All @@ -476,21 +491,25 @@ subroutine two_stream_gray_rad_down (is, js, Time_diag, lat, lon, p_half, t,
sw_down(:,:,k+1) = sw_down(:,:,k) * sw_dtrans(:,:,k)
end do


case(B_FRIERSON, B_BYRNE)
! Default: Frierson handling of SW radiation
! SW optical thickness
sw_tau_0 = (1.0 - sw_diff*sin(lat)**2)*atm_abs

! compute optical depths for each model level

do k = 1, n+1
sw_tau(:,:,k) = sw_tau_0 * (p_half(:,:,k)/pstd_mks)**solar_exponent
end do

! compute downward shortwave flux

do k = 1, n+1
sw_down(:,:,k) = insolation(:,:) * exp(-sw_tau(:,:,k))
end do


case(B_SCHNEIDER_LIU)
! Schneider & Liu 2009 Giant planet scheme
! SW optical thickness
Expand Down Expand Up @@ -618,9 +637,9 @@ subroutine two_stream_gray_rad_down (is, js, Time_diag, lat, lon, p_half, t,
end select

! =================================================================================
surf_lw_down = lw_down(:, :, n+1)
surf_lw_down = lw_down(:, :, n+1)
toa_sw_in = sw_down(:, :, 1)
net_surf_sw_down = sw_down(:, :, n+1) * (1. - albedo)
net_surf_sw_down = sw_down(:, :, n+1) * (1. - albedo)
! =================================================================================

if(lw_scheme.eq.B_SCHNEIDER_LIU) then
Expand All @@ -632,10 +651,18 @@ subroutine two_stream_gray_rad_down (is, js, Time_diag, lat, lon, p_half, t,
if ( id_lwdn_sfc > 0 ) then
used = send_data ( id_lwdn_sfc, surf_lw_down, Time_diag)
endif

!------- incoming sw flux toa -------
if ( id_swdn_toa > 0 ) then
used = send_data ( id_swdn_toa, toa_sw_in, Time_diag)
endif

! NTL NUDGING
if( id_nudge_flux > 0) then
used = send_data ( id_nudge_flux, const_correct+nudge_out, Time_diag)
endif


!------- downward sw flux surface -------
if ( id_swdn_sfc > 0 ) then
used = send_data ( id_swdn_sfc, net_surf_sw_down, Time_diag)
Expand Down
Loading
Loading