diff --git a/src/atmos_param/cloud_simple/cloud_spookie.F90 b/src/atmos_param/cloud_simple/cloud_spookie.F90 index 5c951ca83..7a594986a 100644 --- a/src/atmos_param/cloud_simple/cloud_spookie.F90 +++ b/src/atmos_param/cloud_simple/cloud_spookie.F90 @@ -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 = & diff --git a/src/atmos_param/socrates/interface/read_control.F90 b/src/atmos_param/socrates/interface/read_control.F90 index 2b6e56406..c877f9fbe 100644 --- a/src/atmos_param/socrates/interface/read_control.F90 +++ b/src/atmos_param/socrates/interface/read_control.F90 @@ -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 @@ -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. @@ -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 diff --git a/src/atmos_param/socrates/interface/socrates_interface.F90 b/src/atmos_param/socrates/interface/socrates_interface.F90 index 4dbe92a4c..dc7fbc7de 100644 --- a/src/atmos_param/socrates/interface/socrates_interface.F90 +++ b/src/atmos_param/socrates/interface/socrates_interface.F90 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 ) @@ -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(:,:,:) @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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)) @@ -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, & @@ -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) ) diff --git a/src/atmos_spectral/driver/solo/idealized_moist_phys.F90 b/src/atmos_spectral/driver/solo/idealized_moist_phys.F90 index 0f2005411..46e168f95 100644 --- a/src/atmos_spectral/driver/solo/idealized_moist_phys.F90 +++ b/src/atmos_spectral/driver/solo/idealized_moist_phys.F90 @@ -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 @@ -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 @@ -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 @@ -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), & @@ -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. @@ -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 @@ -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 diff --git a/src/atmos_spectral/driver/solo/mixed_layer.F90 b/src/atmos_spectral/driver/solo/mixed_layer.F90 index 6f2f957f8..74830085e 100644 --- a/src/atmos_spectral/driver/solo/mixed_layer.F90 +++ b/src/atmos_spectral/driver/solo/mixed_layer.F90 @@ -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', & @@ -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)