Skip to content

Commit

Permalink
Allowing both SimCloud and SPOOKIE to be passed to SOCRATES
Browse files Browse the repository at this point in the history
  • Loading branch information
daw538 committed Mar 16, 2023
1 parent 386ec8a commit 3d506c8
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 29 deletions.
2 changes: 1 addition & 1 deletion src/atmos_param/cloud_simple/cloud_spookie.F90
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ subroutine cloud_spookie_init (axes, Time)
endif
call close_file(unit)

call error_mesg(mod_name_cld, 'Using SimCloud cloud scheme', NOTE)
call error_mesg(mod_name_cld, 'Using SPOOKIE protocol cloud scheme', NOTE)

!register diagnostics
id_cf = &
Expand Down
6 changes: 3 additions & 3 deletions src/atmos_param/socrates/interface/read_control.F90
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ MODULE read_control_mod

! Subroutine to set input algorithmic options for the core radiation code
!------------------------------------------------------------------------------
SUBROUTINE read_control(control, spectrum, do_cloud_simple)
SUBROUTINE read_control(control, spectrum, do_clouds)

USE rad_pcf
USE def_control, ONLY: StrCtrl, allocate_control
Expand All @@ -27,7 +27,7 @@ SUBROUTINE read_control(control, spectrum, do_cloud_simple)
! Spectral data:
TYPE (StrSpecData), INTENT(IN) :: spectrum

LOGICAL, INTENT(IN), OPTIONAL :: do_cloud_simple
LOGICAL, INTENT(IN), OPTIONAL :: do_clouds


! Local variables.
Expand Down Expand Up @@ -97,7 +97,7 @@ SUBROUTINE read_control(control, spectrum, do_cloud_simple)
control%i_gas_overlap = ip_overlap_k_eqv_scl

! Properties of clouds
if (do_cloud_simple) then
if (do_clouds) then
control%i_cloud_representation = ip_cloud_ice_water
else
control%i_cloud_representation = ip_cloud_off
Expand Down
41 changes: 25 additions & 16 deletions src/atmos_param/socrates/interface/socrates_interface.F90
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,11 @@ MODULE socrates_interface_mod

REAL(r_def), allocatable, dimension(:,:,:) :: outputted_soc_spectral_olr, spectral_olr_store, outputted_soc_spectral_olr_clr
REAL(r_def), allocatable, dimension(:) :: soc_bins_lw, soc_bins_sw
LOGICAL :: do_clouds = .false.

CONTAINS

SUBROUTINE socrates_init(is, ie, js, je, num_levels, axes, Time, lat, lonb, latb, delta_t_atmos, do_cloud_simple)
SUBROUTINE socrates_init(is, ie, js, je, num_levels, axes, Time, lat, lonb, latb, delta_t_atmos, do_cloud_simple, do_cloud_spookie)
!! Initialises Socrates spectra, arrays, and constants

USE astronomy_mod, only: astronomy_init
Expand All @@ -104,7 +105,7 @@ SUBROUTINE socrates_init(is, ie, js, je, num_levels, axes, Time, lat, lonb, latb
INTEGER, INTENT(in) :: is, ie, js, je, num_levels
REAL, INTENT(in) , DIMENSION(:,:) :: lat
REAL, INTENT(in) , DIMENSION(:,:) :: lonb, latb
LOGICAL, INTENT(IN) :: do_cloud_simple
LOGICAL, INTENT(IN) :: do_cloud_simple, do_cloud_spookie

integer :: io, stdlog_unit
integer :: res, time_step_seconds
Expand Down Expand Up @@ -189,6 +190,10 @@ SUBROUTINE socrates_init(is, ie, js, je, num_levels, axes, Time, lat, lonb, latb
endif
sw_hires_spectral_filename = sw_spectral_filename
endif

if ((do_cloud_simple) .or. (do_cloud_spookie)) then
do_clouds = .true.
endif

! Socrates spectral files -- should be set by namelist
control_lw%spectral_file = lw_spectral_filename
Expand All @@ -204,10 +209,10 @@ SUBROUTINE socrates_init(is, ie, js, je, num_levels, axes, Time, lat, lonb, latb
CALL read_spectrum(control_sw_hires%spectral_file,spectrum_sw_hires)

! Set Socrates configuration
CALL read_control(control_lw,spectrum_lw, do_cloud_simple)
CALL read_control(control_lw_hires,spectrum_lw_hires, do_cloud_simple)
CALL read_control(control_sw,spectrum_sw, do_cloud_simple)
CALL read_control(control_sw_hires,spectrum_sw_hires, do_cloud_simple)
CALL read_control(control_lw,spectrum_lw, do_clouds)
CALL read_control(control_lw_hires,spectrum_lw_hires, do_clouds)
CALL read_control(control_sw,spectrum_sw, do_clouds)
CALL read_control(control_sw_hires,spectrum_sw_hires, do_clouds)

! Specify LW and SW setups
control_sw%isolir=1
Expand Down Expand Up @@ -538,7 +543,7 @@ subroutine socrates_interface(Time_diag, rlat, rlon, soc_lw_mode, &
fms_cld_frac, fms_reff_rad, fms_mmr_cl_rad, &
output_heating_rate, output_flux_down, output_flux_up, &
output_flux_down_clr, output_flux_up_clr, &
do_cloud_simple, &
do_cloud_simple, do_cloud_spookie, &
!optionals
output_soc_spectral_olr, output_flux_direct, &
output_flux_direct_clr, t_half_level_out, tot_cloud_cover )
Expand Down Expand Up @@ -581,7 +586,7 @@ subroutine socrates_interface(Time_diag, rlat, rlon, soc_lw_mode, &
real(r_def), intent(in) :: fms_rrsun
real(r_def), intent(in) :: fms_cld_frac(:,:,:), fms_reff_rad(:,:,:), fms_mmr_cl_rad(:,:,:)

logical, intent(in) :: do_cloud_simple
logical, intent(in) :: do_cloud_simple, do_cloud_spookie

! Output arrays
real(r_def), intent(out) :: output_heating_rate(:,:,:)
Expand Down Expand Up @@ -715,11 +720,15 @@ subroutine socrates_interface(Time_diag, rlat, rlon, soc_lw_mode, &

! Zero heating rate
soc_heating_rate = 0.0

if (do_cloud_simple .or. do_cloud_spookie) then
do_clouds = .true.
endif

! Test if LW or SW mode
if (soc_lw_mode .eqv. .TRUE.) then
control_lw%isolir = 2
CALL read_control(control_lw, spectrum_lw, do_cloud_simple)
CALL read_control(control_lw, spectrum_lw, do_clouds)
if (socrates_hires_mode .eqv. .FALSE.) then
control_calc = control_lw
spectrum_calc = spectrum_lw
Expand All @@ -730,7 +739,7 @@ subroutine socrates_interface(Time_diag, rlat, rlon, soc_lw_mode, &

else
control_sw%isolir = 1
CALL read_control(control_sw, spectrum_sw, do_cloud_simple)
CALL read_control(control_sw, spectrum_sw, do_clouds)
if(socrates_hires_mode .eqv. .FALSE.) then
control_calc = control_sw
spectrum_calc = spectrum_sw
Expand All @@ -742,7 +751,7 @@ subroutine socrates_interface(Time_diag, rlat, rlon, soc_lw_mode, &
end if

! Do calculation
CALL read_control(control_calc, spectrum_calc, do_cloud_simple)
CALL read_control(control_calc, spectrum_calc, do_clouds)

n_chunk_loop = (si*sj)/chunk_size
n_profile_chunk = n_profile / n_chunk_loop
Expand Down Expand Up @@ -847,7 +856,7 @@ subroutine socrates_interface(Time_diag, rlat, rlon, soc_lw_mode, &
end subroutine socrates_interface

subroutine run_socrates(Time, Time_diag, rad_lat, rad_lon, temp_in, q_in, t_surf_in, p_full_in, p_half_in, z_full_in, z_half_in, albedo_in, &
temp_tend, net_surf_sw_down, surf_lw_down, delta_t, do_cloud_simple, cf_rad, reff_rad, qcl_rad)
temp_tend, net_surf_sw_down, surf_lw_down, delta_t, do_cloud_simple, do_cloud_spookie, cf_rad, reff_rad, qcl_rad)

use astronomy_mod, only: diurnal_solar
use constants_mod, only: pi, wtmco2, wtmozone, rdgas, gas_constant
Expand All @@ -862,7 +871,7 @@ subroutine run_socrates(Time, Time_diag, rad_lat, rad_lon, temp_in, q_in, t_surf
real, intent(inout), dimension(:,:,:) :: temp_tend
real, intent(out), dimension(:,:) :: net_surf_sw_down, surf_lw_down
real, intent(in) :: delta_t
logical, intent(in) :: do_cloud_simple
logical, intent(in) :: do_cloud_simple, do_cloud_spookie
real, intent(in), dimension(:,:,:) :: cf_rad, reff_rad, qcl_rad

integer(i_def) :: n_profile, n_layer
Expand Down Expand Up @@ -1198,7 +1207,7 @@ subroutine run_socrates(Time, Time_diag, rad_lat, rad_lon, temp_in, q_in, t_surf
endif
endif

if(do_cloud_simple) then
if(do_cloud_simple .or. do_cloud_spookie) then
cld_frac_soc = REAL(cf_rad, kind(r_def))
reff_rad_soc = REAL(reff_rad, kind(r_def))

Expand Down Expand Up @@ -1239,7 +1248,7 @@ subroutine run_socrates(Time, Time_diag, rad_lat, rad_lon, temp_in, q_in, t_surf
n_profile, n_layer, cld_frac_soc, reff_rad_soc, mmr_cl_rad_soc, &
output_heating_rate_lw, output_soc_flux_lw_down, output_soc_flux_lw_up, &
output_soc_flux_lw_down_clr, output_soc_flux_lw_up_clr, &
do_cloud_simple, &
do_cloud_simple, do_cloud_spookie, &
!optional outs
output_soc_spectral_olr = outputted_soc_spectral_olr, &
t_half_level_out = t_half_out, &
Expand Down Expand Up @@ -1267,7 +1276,7 @@ subroutine run_socrates(Time, Time_diag, rad_lat, rad_lon, temp_in, q_in, t_surf
n_profile, n_layer, cld_frac_soc, reff_rad_soc, mmr_cl_rad_soc, &
output_heating_rate_sw, output_soc_flux_sw_down, output_soc_flux_sw_up, &
output_soc_flux_sw_down_clr, output_soc_flux_sw_up_clr, &
do_cloud_simple)
do_cloud_simple, do_cloud_spookie)

tg_tmp_soc = tg_tmp_soc + output_heating_rate_sw*delta_t !Output heating rate in K/s, so is a temperature tendency
net_surf_sw_down(:,:) = REAL(output_soc_flux_sw_down(:,:, n_layer+1)-output_soc_flux_sw_up(:,:,n_layer+1) )
Expand Down
31 changes: 23 additions & 8 deletions src/atmos_spectral/driver/solo/idealized_moist_phys.F90
Original file line number Diff line number Diff line change
Expand Up @@ -378,11 +378,11 @@ subroutine idealized_moist_phys_init(Time, Time_step_in, nhum, rad_lon_2d, rad_l
if(two_stream_gray .and. do_rrtm_radiation) &
call error_mesg('physics_driver_init','do_grey_radiation and do_rrtm_radiation cannot both be .true.',FATAL)

if(two_stream_gray .and. do_cloud_simple) &
if(two_stream_gray .and. (do_cloud_simple .or. do_cloud_spookie)) &
call error_mesg('idealized_moist_phys','Gray radiation is not configured to run with the cloud scheme at present.',FATAL)

!if(do_rrtm_radiation .and. do_cloud_simple) &
! call error_mesg('idealized_moist_phys','RRTM is not configured to run with the cloud scheme at present.',FATAL)
if(do_rrtm_radiation .and. (do_cloud_simple .or. do_cloud_spookie)) &
call error_mesg('idealized_moist_phys','RRTM is not configured to run with the cloud scheme at present.',FATAL)

if(uppercase(trim(convection_scheme)) == 'NONE') then
r_conv_scheme = NO_CONV
Expand Down Expand Up @@ -781,7 +781,7 @@ subroutine idealized_moist_phys_init(Time, Time_step_in, nhum, rad_lon_2d, rad_l
endif
#else
if (do_socrates_radiation) then
call socrates_init(is, ie, js, je, num_levels, axes, Time, rad_lat, rad_lonb_2d, rad_latb_2d, Time_step_in, do_cloud_simple)
call socrates_init(is, ie, js, je, num_levels, axes, Time, rad_lat, rad_lonb_2d, rad_latb_2d, Time_step_in, do_cloud_simple, do_cloud_spookie)
endif
#endif

Expand Down Expand Up @@ -820,7 +820,7 @@ subroutine idealized_moist_phys(Time, p_half, p_full, z_half, z_full, ug, vg, ps
real, dimension(size(ug,1), size(ug,2), size(ug,3)) :: tg_tmp, qg_tmp, RH,tg_interp, mc, dt_ug_conv, dt_vg_conv

! Simple cloud scheme variabilies to pass to radiation
real, dimension(size(ug,1), size(ug,2), size(ug,3)) :: cf_rad, reff_rad, qcl_rad
real, dimension(size(ug,1), size(ug,2), size(ug,3)) :: cf_rad, reff_rad, qcl_rad, cca_rad

real, intent(in) , dimension(:,:,:), optional :: mask
integer, intent(in) , dimension(:,:), optional :: kbot
Expand Down Expand Up @@ -992,10 +992,11 @@ subroutine idealized_moist_phys(Time, p_half, p_full, z_half, z_full, ug, vg, ps

! initialise outs to zero

!Set to zero regarles of if clouds are used in radiation code
!Set to zero regardless of if clouds are used in radiation code
cf_rad = 0.
reff_rad = 0.
qcl_rad = 1e-8
cca_rad = 0.

if(do_cloud_simple) then
call cloud_simple(p_half(:,:,:,current), &
Expand All @@ -1015,6 +1016,20 @@ subroutine idealized_moist_phys(Time, p_half, p_full, z_half, z_full, ug, vg, ps
cf_rad(:,:,:), &
reff_rad(:,:,:), &
qcl_rad(:,:,:) )
elseif(do_cloud_spookie) then
cf_rad(:,:,:) = 0.
reff_rad(:,:,:) = 0.
qcl_rad(:,:,:) = 0.
cca_rad(:,:,:) = 0.

call cloud_spookie(p_half(:,:,:,current), &
p_full(:,:,:,current), &
Time, &
tg(:,:,:,previous), &
grid_tracers(:,:,:,previous,nsphum), &
! inouts -
cf_rad(:,:,:), cca_rad(:,:,:), &
reff_rad(:,:,:), qcl_rad(:,:,:) )
endif

! Begin the radiation calculation by computing downward fluxes.
Expand Down Expand Up @@ -1157,7 +1172,7 @@ subroutine idealized_moist_phys(Time, p_half, p_full, z_half, z_full, ug, vg, ps
#else
if (do_socrates_radiation) then
! Socrates interface
if(do_cloud_simple) then
if((do_cloud_simple) .or. (do_cloud_spookie)) then
! Simple cloud scheme outputs radii in microns, but Socrates expects
! it in metres so convert it.
reff_rad = 1.e-6 * reff_rad
Expand All @@ -1169,7 +1184,7 @@ subroutine idealized_moist_phys(Time, p_half, p_full, z_half, z_full, ug, vg, ps
p_half(:,:,:,current), z_full(:,:,:,current), &
z_half(:,:,:,current), albedo, dt_tg(:,:,:), &
net_surf_sw_down(:,:), surf_lw_down(:,:), delta_t, &
do_cloud_simple, cf_rad(:,:,:), &
do_cloud_simple, do_cloud_spookie, cf_rad(:,:,:), &
reff_rad(:,:,:), qcl_rad(:,:,:) )
endif
#endif
Expand Down
5 changes: 4 additions & 1 deletion src/atmos_spectral/driver/solo/mixed_layer.F90
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,10 @@ subroutine mixed_layer_init(is, ie, js, je, num_levels, t_surf, bucket_depth, ax

endif

if(trim(ice_albedo_method) == 'ramp_function') then
call error_mesg('mixed_layer','Alternative method ramp_function used for ice albedo output.', NOTE)
endif

id_t_surf = register_diag_field(mod_name, 't_surf', &
axes(1:2), Time, 'surface temperature','K')
id_flux_t = register_diag_field(mod_name, 'flux_t', &
Expand Down Expand Up @@ -764,7 +768,6 @@ subroutine albedo_calc(albedo_inout,Time)
end where
else if(trim(ice_albedo_method) == 'ramp_function') then
albedo_inout = albedo_inout*(1.0-ice_concentration) + ice_albedo_value*ice_concentration
call error_mesg('mixed_layer','Alternative method ramp_function used for ice albedo output.', NOTE)
else
call error_mesg('mixed_layer','"'//trim(ice_albedo_method)//'"'//' is not a valid method for determining'// &
'albedo when ice is present. Choices are: step_function or ramp_function.', FATAL)
Expand Down

0 comments on commit 3d506c8

Please sign in to comment.