!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! !!
!! GNU General Public License !!
!! !!
!! This file is part of the Flexible Modeling System (FMS). !!
!! !!
!! FMS is free software; you can redistribute it and/or modify !!
!! it and are expected to follow the terms of the GNU General Public !!
!! License as published by the Free Software Foundation. !!
!! !!
!! FMS is distributed in the hope that it will be useful, !!
!! but WITHOUT ANY WARRANTY; without even the implied warranty of !!
!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the !!
!! GNU General Public License for more details. !!
!! !!
!! You should have received a copy of the GNU General Public License !!
!! along with FMS; if not, write to: !!
!! Free Software Foundation, Inc. !!
!! 59 Temple Place, Suite 330 !!
!! Boston, MA 02111-1307 USA !!
!! or see: !!
!! http://www.gnu.org/licenses/gpl.txt !!
!! !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
module radiation_driver_mod
!
! fil
!
!
!
!
!
!
! radiation_driver_mod is the interface between physics_driver_mod
! and a specific radiation parameterization, currently either the
! original_fms_rad or sea_esf_rad radiation package. it provides
! radiative heating rates, boundary radiative fluxes, and any other
! radiation package output fields to other component models of the
! modeling system.
!
!
! The following modules are called from this driver module:
!
! 1) astronomy
!
! 2) cloud properties
!
! 3) prescribed zonal ozone
!
! 4) longwave and shortwave radiation driver
!
!
! Diagnostic fields may be output to a netcdf file by specifying the
! module name radiation and the desired field names (given below)
! in file diag_table. See the documentation for diag_manager.
!
! Diagnostic fields for module name: radiation
!
! field name field description
! ---------- -----------------
!
! alb_sfc surface albedo (percent)
! coszen cosine of the solar zenith angle
!
! tdt_sw temperature tendency for SW radiation (deg_K/sec)
! tdt_lw Temperature tendency for LW radiation (deg_K/sec)
! swdn_toa SW flux down at TOA (watts/m2)
! swup_toa SW flux up at TOA (watts/m2)
! olr outgoing longwave radiation (watts/m2)
! swup_sfc SW flux up at surface (watts/m2)
! swdn_sfc SW flux down at surface (watts/m2)
! lwup_sfc LW flux up at surface (watts/m2)
! lwdn_sfc LW flux down at surface (watts/m2)
!
! NOTE: When namelist variable do_clear_sky_pass = .true. an additional clear sky
! diagnostic fields may be saved.
!
! tdt_sw_clr clear sky temperature tendency for SW radiation (deg_K/sec)
! tdt_lw_clr clear sky Temperature tendency for LW radiation (deg_K/sec)
! swdn_toa_clr clear sky SW flux down at TOA (watts/m2)
! swup_toa_clr clear sky SW flux up at TOA (watts/m2)
! olr_clr clear sky outgoing longwave radiation (watts/m2)
! swup_sfc_clr clear sky SW flux up at surface (watts/m2)
! swdn_sfc_clr clear sky SW flux down at surface (watts/m2)
! lwup_sfc_clr clear sky LW flux up at surface (watts/m2)
! lwdn_sfc_clr clear sky LW flux down at surface (watts/m2)
!
!
! For a specific list of radiation references see the
! longwave and shortwave documentation.
!
!
!
!
!
!For some of the diagnostics fields that represent fractional amounts,
! such as reflectivity and absorptivity, the units are incorrectly
! given as percent.
!
!
!CHANGE HISTORY
!changes prior to 1/24/2000
!
! * Modified the radiation alarm.
! The module can now be stopped/started on a time step that is not the
! radiation time step.
!
! * Modified the radiation restart format.
! Added a version number and radiation alarm information.
!
! * Fixed a bug that occurred when namelist variable do_average = true.
! An addition averaging variable was added for array "solar".
! This averaging information was also added to the restart file.
! ***NOTE: As of this code, this namelist variable has been removed.***
!
! * Removed the initialization for the astronomy package. This is now done
! by the astronomy namelist.
!
!changes prior to 10/4/1999
!
! * MPP version created. Changes to open_file and error_mesg arguments,
! Fortran write statements to standard output only on PE 0, Fortran close
! statement changed to call close_file, and Fortran read/write statements
! for restart files changed to call read_data/write_data.
!
! * Implementation of the new MPP diagnostics package. This required major
! changes to the diagnostic interface and the manner in which diagnostics
! quantities are selected.
!
! * There were no changes made that would cause answers to changes.
!
!changes prior to 5/26/1999
!
! * added namelist variables for modifying the co2 mixing ratio.
!
! * changed the units of namelist variable solar_constant from ly/min to watts/m2.
!
!
!
!
! shared modules:
use fms_mod, only: fms_init, mpp_clock_id, &
mpp_clock_begin, mpp_clock_end, &
CLOCK_MODULE, field_exist, &
mpp_pe, mpp_root_pe, &
open_namelist_file, stdlog, &
file_exist, FATAL, WARNING, NOTE, &
close_file, read_data, write_data, &
write_version_number, check_nml_error,&
error_mesg, open_restart_file, &
read_data, mpp_error
use fms_io_mod, only: get_restart_io_mode, &
register_restart_field, restart_file_type, &
save_restart, get_mosaic_tile_file
use diag_manager_mod, only: register_diag_field, send_data, &
diag_manager_init, get_base_time
use time_manager_mod, only: time_type, set_date, set_time, &
get_time, operator(+), &
print_date, time_manager_init, &
assignment(=), &
operator(-), operator(/=), get_date,&
operator(<), operator(>=), operator(>)
use sat_vapor_pres_mod, only: sat_vapor_pres_init, compute_qs
use constants_mod, only: constants_init, RDGAS, RVGAS, &
STEFAN, GRAV, SECONDS_PER_DAY, &
RADIAN, diffac
use data_override_mod, only: data_override
! shared radiation package modules:
use rad_utilities_mod, only: radiation_control_type, Rad_control, &
radiative_gases_type, &
check_derived_types, &
cldrad_properties_type, &
astronomy_type, surface_type, &
cld_specification_type, &
aerosol_diagnostics_type, &
atmos_input_type, rad_utilities_init,&
aerosol_properties_type, aerosol_type,&
sw_output_type, lw_output_type, &
rad_output_type, microphysics_type, &
shortwave_control_type, Sw_control, &
Lw_control, &
fsrad_output_type, &
astronomy_inp_type, &
cloudrad_control_type, Cldrad_control,&
rad_utilities_end
use esfsw_parameters_mod, only: Solar_spect, esfsw_parameters_init
! physics support modules:
use diag_integral_mod, only: diag_integral_init, &
diag_integral_field_init, &
sum_diag_integral_field
use astronomy_mod, only: astronomy_init, annual_mean_solar, &
daily_mean_solar, diurnal_solar, &
astronomy_end
! component modules:
use original_fms_rad_mod, only: original_fms_rad_init, &
original_fms_rad, &
original_fms_rad_end
use sea_esf_rad_mod, only: sea_esf_rad_init, sea_esf_rad, &
sea_esf_rad_time_vary, &
sea_esf_rad_endts, &
sea_esf_rad_end
use rad_output_file_mod, only: rad_output_file_init, &
write_rad_output_file, &
rad_output_file_end
use cloudrad_package_mod, only: cloudrad_package_init, &
cloud_radiative_properties, &
cldrad_props_dealloc, &
cloudrad_package_end
use cloudrad_diagnostics_mod, &
only: model_micro_dealloc, &
obtain_cloud_tau_and_em, &
modis_yim, modis_cmip
use microphys_rad_mod, only: isccp_microphys_sw_driver, &
isccp_microphys_lw_driver
use aerosolrad_package_mod, only: aerosolrad_package_init, &
aerosolrad_package_alloc, &
aerosolrad_package_endts, &
aerosolrad_package_time_vary, &
aerosol_radiative_properties, &
aerosolrad_package_end
use field_manager_mod, only: MODEL_ATMOS
use tracer_manager_mod, only: get_tracer_index, NO_TRACER
!--------------------------------------------------------------------
implicit none
private
!----------------------------------------------------------------------
! radiation_driver_mod is the interface between physics_driver_mod
! and a specific radiation parameterization, currently either the
! original_fms_rad or sea_esf_rad radiation package. it provides
! radiative heating rates, boundary radiative fluxes, and any other
! radiation package output fields to other component models of the
! modeling system.
!----------------------------------------------------------------------
!----------------------------------------------------------------------
!------------ version number for this module --------------------------
character(len=128) :: version = '$Id: radiation_driver.F90,v 17.0.2.1.4.1.2.1.2.1 2009/11/24 14:24:26 rsh Exp $'
character(len=128) :: tagname = '$Name: mom4p1_pubrel_dec2009_nnz $'
!---------------------------------------------------------------------
!------ interfaces -----
!
!use radiation_driver_mod [,only: radiation_driver_init,
! radiation_driver,
! radiation_driver_end]
! radiation_driver_init
! Must be called once before subroutine radiation_driver to
! initialize the module (read namelist input and restart file).
! Also calls the initialization routines for other modules used.
! radiation_driver
! Called every time step (not on the radiation time step)
! to compute the longwave and shortwave radiative tendencies.
! radiation_driver_end
! Called once at the end of a model run to terminate the module (write
! a restart file). Also calls the termination routines for other
! modules used.
!Notes:
! 1) A namelist interface controls runtime options.
! 3) A restart file radiation_driver.res is generated by this module.
!
public radiation_driver_init, radiation_driver, return_cosp_inputs, &
radiation_driver_time_vary, radiation_driver_endts, &
define_rad_times, define_atmos_input_fields, &
define_surface, surface_dealloc, atmos_input_dealloc, &
microphys_dealloc, &
radiation_driver_end, radiation_driver_restart
private &
! called from radiation_driver_init:
read_restart_file, initialize_diagnostic_integrals, &
diag_field_init, read_restart_nc, &
! called from radiation_driver_end:
write_restart_file, write_restart_nc, &
! called from radiation_driver:
obtain_astronomy_variables, radiation_calc, &
update_rad_fields, produce_radiation_diagnostics, &
deallocate_arrays, &
flux_trop_calc, &
! called from define_atmos_input_fields:
calculate_auxiliary_variables
!-----------------------------------------------------------------------
!------- namelist ---------
logical :: using_restart_file = .true. ! if set to .false, restart file
! will NOT be written by this
! module; this will not affect
! answers as long as job is
! restarted on a radiation
! timestep
integer :: rad_time_step = 0 ! radiative time step in seconds
integer :: sw_rad_time_step = 0 ! radiative time step in seconds
logical :: use_single_lw_sw_ts = .true. ! lw and sw are integrated
! using rad_time_step ? if
! false, then lw uses
! rad_time_step, sw uses
! sw_rad_time_step
logical :: use_hires_coszen = .false. ! calculate for multiple zen angs
! within sw calc?
integer :: nzens_per_sw_rad_timestep = 1 ! number of cloudy
! sw calcs done on a sw rad
! timestep
logical :: allow_nonrepro_across_restarts = .false.
! when set true, allows the
! use_hires_coszen case to
! restart on non-radiation steps,
! with solution dependent on
! restart interval
! (temporary until needed vari-
! ables added to restart file)
logical :: do_clear_sky_pass= .false.! are the clear-sky radiation
! diagnostics to be calculated ?
character(len=24) :: &
zenith_spec = ' ' ! string defining how zenith
! angle is computed. acceptable
! values: 'daily_mean', 'annual_
! mean', 'diurnally_varying'
character(len=16) :: &
rad_package='sea_esf' ! string defining the radiation
! package being used. acceptable
! values : 'sea_esf',
! 'original_fms'
logical :: &
calc_hemi_integrals = .false.! are hemispheric integrals
! desired ?
logical :: &
all_step_diagnostics = .false.! are lw and sw radiative bdy
! fluxes and atmospheric heating
! rates to be output on physics
! steps ?
logical :: &
renormalize_sw_fluxes=.false.! should sw fluxes and the zenith
! angle be renormalized on each
! timestep because of the
! movement of earth wrt the sun ?
integer, dimension(6) :: &
rad_date = (/ 0, 0, 0, 0, 0, 0 /) ! fixed date for which radiation
! is to be valid (applies to
! solar info, ozone, clouds)
! [yr, mo, day, hr, min, sec]
logical :: &
all_level_radiation = .true. ! is radiation to be calculated
! at all model levels ?
integer :: &
topmost_radiation_level=-99 ! if all_level_radiation is
! false., this is the lowest
! model index at which radiation
! is calculated
logical :: &
drop_upper_levels = .false. ! if all_level_radiation is false
! and drop_upper_levels is true,
! radiation will be calculated
! at all model levels from
! topmost_radiation_level to the
! surface
logical :: &
all_column_radiation = .true.! is radiation to be calculated
! in all model columns ?
logical :: rsd=.false. ! (repeat same day) - call
! radiation for the specified
! rad_date (yr,mo,day), but run
! through the diurnal cycle (hr,
! min,sec)
logical :: use_mixing_ratio = .false. ! assumes q is mixing ratio
! rather than specific humidity
real :: solar_constant = 1365.0 ! annual mean solar flux at top
! of atmosphere [ W/(m**2) ]
logical :: doing_data_override = .false.
! input fields to the radiation
! package are being overriden
! using data_override_mod ?
logical :: overriding_temps = .false. ! temperature and ts fields are
! overriden ?
logical :: overriding_sphum = .false. ! specific humidity field is
! overriden ?
logical :: overriding_clouds = .false.! cloud specification fields are
! overriden ?
logical :: overriding_albedo = .false.! surface albedo field is
! overriden ?
logical :: overriding_aerosol = .false.
! aerosol fields are overriden ?
logical :: use_co2_tracer_field = .false.
! obtain co2 field for use by
! radiation package from co2
! tracer field ?
logical :: do_swaerosol_forcing = .false.
! calculating aerosol forcing in
! shortwave ?
logical :: do_lwaerosol_forcing = .false.
! calculating aerosol forcing in
! longwave ?
real :: trop_ht_at_poles = 30000. ! assumed height of tropoause at
! poles for case of tropause
! linearly varying with latitude
! [ Pa ]
real :: trop_ht_at_eq = 10000. ! assumed height of tropoause at
! equator for case of tropause
! linearly varying with latitude
! [ Pa ]
real :: trop_ht_constant = 20000. ! assumed height of tropoause
! when assumed constant
! [ Pa ]
logical :: constant_tropo = .true. ! generate tropopause fluxes when
! tropopause ht assumed constant?
logical :: linear_tropo = .true. ! generate tropopause fluxes when
! tropopause assumed to vary
! linearly with latitude?
logical :: thermo_tropo = .false. ! generate tropopause fluxes when
! tropopause determined thermo-
! dynamically ?
logical :: time_varying_solar_constant = .false.
! solar_constant is to vary with
! time ?
logical :: use_uniform_solar_input = .false.
! the (lat,lon) values used to
! calculate zenith angle are
! uniform across the grid ?
real :: lat_for_solar_input = 100. ! latitude to be used when uni-
! form solar input is activated
! [ degrees ]
real :: lon_for_solar_input = 500. ! longitude to be used when uni-
! form solar input is activated
! [ degrees ]
logical :: always_calculate = .false. ! radiation calculation is done
! on every call to
! radiation_driver ?
logical :: do_h2o = .true. ! h2o radiative effects are
! included in the radiation
! calculation ?
logical :: do_o3 = .true. ! o3 radiative effects are
! included in the radiation
! calculation ?
integer, dimension(6) :: solar_dataset_entry = (/ 1, 1, 1, 0, 0, 0 /)
! time in solar data set corresp-
! onding to model initial time
! (yr, mo, dy, hr, mn, sc)
!
!
!The radiative time step in seconds.
!
!
! are the clear-sky radiation
! diagnostics to be calculated ?
!
!
!string defining how zenith
! angle is computed. acceptable
! values: 'daily_mean', 'annual_
! mean', 'diurnally_varying'
!
!
!string defining the radiation
! package being used. acceptable
! values : 'sea_esf',
! 'original_fms'
!
!
!are hemispheric integrals
! desired ?
!
!
!are lw and sw radiative bdy
! fluxes and atmospheric heating
! rates to be output on physics
! steps ?
!
!
!should sw fluxes and the zenith
! angle be renormalized on each
! timestep because of the
! movement of earth wrt the sun ?
!
!
!fixed date for which radiation
! is to be valid (applies to
! solar info, ozone, clouds)
! [yr, mo, day, hr, min, sec]
!
!
!is radiation to be calculated
! at all model levels ?
!
!
!if all_level_radiation is
! false., this is the lowest
! model index at which radiation
! is calculated
!
!
!if all_level_radiation is false
! and drop_upper_levels is true,
! radiation will be calculated
! at all model levels from
! topmost_radiation_level to the
! surface
!
!
!is radiation to be calculated
! in all model columns ?
!
!
!(repeat same day) - call
! radiation for the specified
! rad_date (yr,mo,day), but run
! through the diurnal cycle (hr,
! min,sec)
!
!
!assumes q is mixing ratio
! rather than specific humidity
!
!
!annual mean solar flux at top
! of atmosphere [ W/(m**2) ]
!
!
!input fields to the radiation
! package are being overriden
! using data_override_mod ?
!
!
!temperature and ts fields are
! overriden ?
!
!
! specific humidity field is
! overriden ?
!
!
! cloud specification fields are
! overriden ?
!
!
! surface albedo field is
! overriden ?
!
!
!aerosol fields are overriden ?
!
!
!use co2 value from co2 tracer field?
!
!
!assumed height of tropoause at
! poles for case of tropause
! linearly varying with latitude
! [ Pa ]
!
!
!assumed height of tropoause at
! equator for case of tropause
! linearly varying with latitude
! [ Pa ]
!
!
!assumed height of tropoause
! when assumed constant
! [ Pa ]
!
!
! generate tropopause fluxes when
! tropopause ht assumed constant?
!
!
! generate tropopause fluxes when
! tropopause assumed to vary
! linearly with latitude?
!
!
! generate tropopause fluxes when
! tropopause determined thermo-
! dynamically ?
!
!
!solar_constant is to vary with
! time ?
!
!
! calculate radiative fluxes and heating rates on every call to
! radiation_driver ?
!
!
! include h2o effects in radiation calculation ?
!
!
! include o3 effects in radiation calculation ?
!
!
!time in solar data set corresp-
! onding to model initial time
! (yr, mo, dy, hr, mn, sc)
!
!
!fluxes and heating rates should
! be calculatd on each call to
! radiation_driver ? (true for
! standalone applications)
!
!
! the (lat,lon) values used to
! calculate zenith angle are
! uniform across the grid ?
!
!
! latitude to be used when uni-
! form solar input is activated
! [ degrees ]
!
!
! longitude to be used when uni-
! form solar input is activated
! [ degrees ]
!
!
!
namelist /radiation_driver_nml/ rad_time_step, do_clear_sky_pass, &
using_restart_file, &
sw_rad_time_step, &
use_single_lw_sw_ts, &
use_hires_coszen, &
allow_nonrepro_across_restarts, &
nzens_per_sw_rad_timestep, &
zenith_spec, rad_package, &
calc_hemi_integrals, &
all_step_diagnostics, &
renormalize_sw_fluxes, &
rad_date, all_level_radiation, &
topmost_radiation_level, &
drop_upper_levels, &
all_column_radiation, rsd, &
use_mixing_ratio, solar_constant, &
doing_data_override, &
overriding_temps, overriding_sphum, &
overriding_clouds, overriding_albedo, &
overriding_aerosol, &
use_co2_tracer_field, &
do_swaerosol_forcing, &
do_lwaerosol_forcing, &
trop_ht_at_poles, trop_ht_at_eq, &
trop_ht_constant, constant_tropo, &
linear_tropo, thermo_tropo, &
time_varying_solar_constant, &
solar_dataset_entry, &
always_calculate, do_h2o, do_o3, &
use_uniform_solar_input, &
lat_for_solar_input, lon_for_solar_input
!---------------------------------------------------------------------
!---- public data ----
!---------------------------------------------------------------------
!---- private data ----
!-- for netcdf restart
type(restart_file_type), pointer, save :: Rad_restart => NULL()
type(restart_file_type), pointer, save :: Til_restart => NULL()
logical :: do_netcdf_restart = .true. ! netcdf/native restart
logical :: in_different_file = .false.
integer :: int_renormalize_sw_fluxes
integer :: int_do_clear_sky_pass
!---------------------------------------------------------------------
! logical flags.
logical :: module_is_initialized = .false. ! module initialized?
logical :: do_rad ! is this a radiation step ?
logical :: do_lw_rad, do_sw_rad ! is this a radiation step ?
logical :: use_rad_date ! specify time of radiation
! independent of model time?
logical :: do_sea_esf_rad ! using sea_esf_rad package?
!---------------------------------------------------------------------
! list of restart files readable by this module.
!
! sea_esf_rad.res:
!
! version 1: sea_esf_rad.res file version used initially in
! AM2 model series (through galway code, AM2p8). this
! is the only version of sea_esf_rad.res ever produced.
!
! radiation_driver.res:
!
! version 1: not readable by this module.
! version 2: added cosine of zenith angle as an output to
! radiation_driver.res (6/27/00)
! version 3: added restart variables needed when sw renormalization
! is active. (3/21/02)
! version 4: added longwave heating rate as separate output
! variable, since it is needed as input to edt_mod
! and entrain_mod. (7/17/02)
! version 5: removed variables associated with the former
! do_average namelist option (7/23/03)
! version 6: added writing of sw tropospheric fluxes (up and
! down) so that they are available for the renormal-
! ization case (developed by ds, 10/03; added to
! trunk code 01/14/04).
! version 7: added swdn to saved variables (developed by slm
! 11/23/03, added to trunk code 01/14/04).
! version 8: includes additional sw fluxes at sfc, used with
! land model (11/13/03).
! version 9: consolidation of version 6 and version 8. (version 7
! replaced by version 8.)
! version 10: adds 2 clr sky sw down diffuse and direct sfc flux
! diagnostic variables (10/18/04)
! version 11: adds flux_sw_down_vis_clr diagnostic variable for use
! in assessing polar ice maintainability (6/19/07)
!---------------------------------------------------------------------
integer, dimension(10) :: restart_versions = (/ 2, 3, 4, 5, 6, &
7, 8, 9, 10, 11 /)
integer :: vers ! version number of the restart file being read
!-----------------------------------------------------------------------
! these arrays must be preserved across timesteps:
!
! Rad_output is a rad_output_type variable with the following
! components:
! tdt_rad radiative (sw + lw) heating rate
! flux_sw_surf net (down-up) sw flux at surface
! flux_sw_surf_dir net (down-up) sw flux at surface
! flux_sw_surf_dif net (down-up) sw flux at surface
! flux_sw_down_vis_dir downward visible sw flux at surface
! flux_sw_down_vis_dif downward visible sw flux at surface
! flux_sw_down_total_dir downward total sw flux at surface
! flux_sw_down_total_dif downward total sw flux at surface
! flux_sw_down_total_dir_clr downward total direct sw flux at
! surface (clear sky)
! flux_sw_down_total_dif_clr downward total diffuse sw flux
! at surface (clear sky)
! flux_sw_down_vis_clr downward visible sw flux at surface
! (clear sky)
! flux_sw_vis net visible sw flux at surface
! flux_sw_vis_dir net visible sw flux at surface
! flux_sw_vis_dif net visible sw flux at surface
! flux_lw_surf downward lw flux at surface
! coszen_angle cosine of the zenith angle (used for the
! last radiation calculation)
! tdt_rad_clr net radiative heating rate in the absence of
! cloud
! tdtsw shortwave heating rate
! tdtsw_clr shortwave heating rate in he absence of cloud
! tdtlw_clr longwave heating rate in he absence of cloud
! tdtlw longwave heating rate
! ufsw upward sw flux
! dfsw downward sw flux
! ufsw_clr upward sw flux
! dfsw_clr downward sw flux
! flxnet net lw flux
! flxnetcf net lw flux, cloud free
! solar_save is used when renormalize_sw_fluxes is active, to save
! the solar factor (fracday*cosz/r**2) from the previous radiation
! step so that the radiative forcing terms may be adjusted on each
! timestep to reflect the current solar forcing.
!
! sw_heating_clr, tot_heating_clr_save, sw_heating_save,
! tot_heating_save, flux_sw_surf_save, flux_sw_surf_dir_save,
! flux_sw_surf_dif_save, flux_sw_down_vis_dir_save,
! flux_sw_down_vis_dif_save, flux_sw_down_vis_clr_save,
! flux_sw_down_total_dir_clr_save, flux_sw_down_total_dif_clr_save,
! flux_sw_down_total_dir_save, flux_sw_down_total_dif_save and
! flux_sw_vis_save, flux_sw_vis_dir_save, flux_sw_vis_dif_save are
! the radiative forcing terms on radiation steps which also must be
! saved when renormalization is activated.
! swdn_special_save, swup_special_save, swdn_special_clr_save,
! swup_special_clr_save are also saved.
!
! the ***sw_save arrays are currently saved so that their values may
! be adjusted during sw renormalization for diagnostic purposes.
!
! the **lw_save arrays are currently saved so that they may be output
! in the diagnostics file on every physics step, if desired, so that
! when renormalize_sw_fluxes is active, total radiative terms may be
! easily generated.
!-----------------------------------------------------------------------
type(rad_output_type),save :: Rad_output
real, allocatable, dimension(:,:) :: solar_save, &
dum_idjd
real, allocatable, dimension(:,:,:) :: &
flux_sw_down_total_dir_clr_save, &
flux_sw_down_total_dif_clr_save, &
flux_sw_down_vis_clr_save
real, allocatable, dimension(:,:,:) :: flux_sw_surf_save, &
flux_sw_surf_dir_save, &
flux_sw_surf_dif_save, &
flux_sw_down_vis_dir_save, &
flux_sw_down_vis_dif_save, &
flux_sw_down_total_dir_save, &
flux_sw_down_total_dif_save, &
flux_sw_vis_save, &
flux_sw_vis_dir_save, &
flux_sw_vis_dif_save
real, allocatable, dimension(:,:,:,:) :: sw_heating_save, &
tot_heating_save, &
dfsw_save, ufsw_save, fsw_save,&
hsw_save
real, allocatable, dimension(:,:,:,:) :: sw_heating_clr_save, &
tot_heating_clr_save, &
dfswcf_save, &
ufswcf_save, fswcf_save, &
hswcf_save
real, allocatable, dimension(:,:,:) :: tdtlw_save, tdtlw_clr_save
real, allocatable, dimension(:,:,:) :: flxnet_save, flxnetcf_save
real, allocatable, dimension(:,:) :: olr_save, lwups_save, &
lwdns_save, olr_clr_save, &
lwups_clr_save, lwdns_clr_save
real, allocatable, dimension(:,:,:,:) :: swdn_special_save, &
swdn_special_clr_save, &
swup_special_save,&
swup_special_clr_save
real, allocatable, dimension(:,:,:) :: netlw_special_save, &
netlw_special_clr_save
real, allocatable, dimension(:,:,:,:) :: dfsw_ad_save, ufsw_ad_save
real, allocatable, dimension(:,:,:,:) :: dfswcf_ad_save, ufswcf_ad_save
real, allocatable, dimension(:,:) :: olr_ad_save, lwups_ad_save, &
lwdns_ad_save, olr_ad_clr_save, &
lwups_ad_clr_save, lwdns_ad_clr_save
!-----------------------------------------------------------------------
! time-step-related constants
integer :: lwrad_alarm ! time interval until the next radiation
! calculation (seconds)
integer :: swrad_alarm ! time interval until the next radiation
! calculation (seconds)
integer :: current_sw_zenith_step = 1
! current zenith angle index being used
! for cloudy sw calculations when
! use_hires_coszen is .true.
integer :: num_pts=0 ! counter for current number of grid
! columns processed (when num_pts=0 or
! num_pts=total_pts certain things happen)
integer :: total_pts ! number of grid columns to be processed
! every time step (note: all grid columns
! must be processed every time step)
type(time_type) :: Rad_time ! time at which the climatologically-
! determined, time-varying input fields to
! radiation should apply
! [ time_type (days, seconds)]
integer :: dt ! physics time step (frequency of calling
! radiation_driver) [ seconds ]
integer :: lw_rad_time_step
!-----------------------------------------------------------------------
! diagnostics variables
integer, parameter :: MX_SPEC_LEVS = 4
! number of special levels at
! which radiative fluxes are to be
! calculated for diagnostic purposes
character(len=16) :: mod_name = 'radiation'
integer :: id_alb_sfc, id_cosz, id_fracday, &
id_alb_sfc_avg, &
id_alb_sfc_vis_dir, id_alb_sfc_nir_dir,&
id_alb_sfc_vis_dif, id_alb_sfc_nir_dif
integer :: id_flux_sw_dir, id_flux_sw_dif, &
id_flux_sw_down_vis_dir, &
id_flux_sw_down_vis_dif, &
id_flux_sw_down_total_dir, &
id_flux_sw_down_total_dif, &
id_flux_sw_down_total_dir_clr, &
id_flux_sw_down_total_dif_clr, &
id_flux_sw_down_vis_clr, &
id_flux_sw_vis, &
id_flux_sw_vis_dir, &
id_flux_sw_vis_dif, &
id_rrvco2, id_rrvf11, id_rrvf12, &
id_rrvf113, id_rrvf22, id_rrvch4, &
id_rrvn2o, id_co2_tf, id_ch4_tf, &
id_n2o_tf, id_sol_con
integer :: id_conc_drop, id_conc_ice
integer :: id_allradp
integer, dimension(2) :: id_tdt_sw, id_tdt_lw, &
id_ufsw, id_dfsw, &
id_flxnet, &
id_swdn_toa, id_swup_toa, id_olr, &
id_netrad_toa, id_netrad_1_Pa, &
id_swup_sfc, id_swdn_sfc, &
id_lwup_sfc, id_lwdn_sfc
integer, dimension(MX_SPEC_LEVS,2) :: id_swdn_special, &
id_swup_special, &
id_netlw_special
integer, dimension(2) :: id_swtoa, id_swsfc, &
id_lwsfc, &
id_swtoa_ad, id_swsfc_ad, &
id_swdn_sfc_ad, &
id_swup_sfc_ad, &
id_swup_toa_ad, &
id_olr_ad, id_lwsfc_ad
real :: missing_value = -999.
character(len=8) :: std_digits = 'f8.3'
character(len=8) :: extra_digits = 'f16.11'
!-----------------------------------------------------------------------
! timing clocks
integer :: misc_clock, clouds_clock, calc_clock
!--------------------------------------------------------------------
! miscellaneous variables and indices
integer :: ks ! model grid coordinate of top level
! at which radiation is calculated
! (topmost_radiation_level)
integer :: ke ! model grid coordinate of bottommost
! level at which radiation is calculated
integer :: ksrad=1 ! always set to 1
integer :: kerad ! number of layers in radiation grid
real :: rh2o_lower_limit_orig=3.0E-06
! smallest value of h2o mixing ratio
! allowed with original_fms_rad package
real :: rh2o_lower_limit_seaesf=2.0E-07
! smallest value of h2o mixing ratio
! allowed with sea_esf_rad package
real :: rh2o_lower_limit
! smallest value of h2o mixing ratio
! allowed in the current experiment
real :: temp_lower_limit=100.0 ! [ K ]
! smallest value of temperature
! allowed in the current experiment
real :: temp_upper_limit=370.00 ! [ K ]
! largest value of temperature
! allowed in the current experiment
real :: surf_flx_init=50.0 ! [w / m^2 ]
! value to which surface lw and sw fluxes
! are set in the absence of a .res file
! containing them
real :: coszen_angle_init=0.50
! value to which cosine of zenith angle
! is set in the absence of a .res file
! containing it
real :: log_p_at_top=2.0
! assumed value of ln of ratio of pres-
! sure at flux level 2 to that at model
! top (needed for deltaz calculation,
! is infinite for model top at p = 0.0,
! this value is used to give a reasonable
! deltaz)
real,parameter :: D608 = (RVGAS-RDGAS)/RDGAS
! virtual temperature factor
real,parameter :: D622 = RDGAS/RVGAS
! ratio of gas constants - dry air to
! water vapor
real,parameter :: D378 = 1.0 - D622
! 1 - gas constant ratio
integer :: id, jd
integer :: size_of_lwoutput = 1
integer :: size_of_swoutput = 1
integer :: indx_lwaf = 0
integer :: indx_swaf = 0
real, dimension(:,:), allocatable :: solflxtot_lean
real :: solflxtot_lean_ann_1882, solflxtot_lean_ann_2000
integer :: first_yr_lean, last_yr_lean, &
nvalues_per_year_lean, numbands_lean
integer :: years_of_data_lean
type(time_type) :: Model_init_time, Solar_offset, &
Solar_entry
logical :: negative_offset = .false.
real, dimension(:,:), allocatable :: swups_acc, swdns_acc
real, dimension(:,:), allocatable :: olr_intgl, swabs_intgl
!
! Several ascii files are required that can be easily setup by a
! script for getting physics data sets.
!
!
! A restart data set called radiation_driver.res(.nc) saves the
! global fields for the current radiative tendency, net shortwave
! surface flux, downward longwave surface flux, and cosine of the
! zenith angle. If the namelist variable do_average=true,
! then additional time averaged global data is written.
! If the restart file is not present when initializing then the
! radiative tendency is set to zero, the SW and LW surface fluxes
! to 50 watts/m2, and the cosine of the zenith angle to 0.50.
! Since radiation is usually computed on the first time step when
! restarting, these values may have little or no effect. If the
! restart file is not present time average data is also set to zero.
!
! For a specific list of radiation references see the
! longwave and shortwave documentation.
!---------------------------------------------------------------------
!---------------------------------------------------------------------
contains
!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
!
! PUBLIC SUBROUTINES
!
!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
!######################################################################
!
!
! radiation_driver_init is the constructor for radiation_driver_mod.
!
!
! radiation_driver_init is the constructor for radiation_driver_mod.
!
!
! call radiation_driver_init (lonb, latb, pref, axes, Time, &
! aerosol_names)
!
!
!
! lonb Longitude in radians for all (i.e., the global size)
! grid box corners, the size of lonb should be one more
! than the number of points along the x-axis and y-axis.
! [real, dimension(:,:)]
!
!
! latb Latitude in radians for all (i.e., the global size)
! grid box corners, the size of latb should be one more
! than the number of latitude points along the x-axis and y-axis.
! [real, dimension(:,:)]
!
!
! pref Two reference profiles of pressure at full model levels
! plus the surface (nlev+1). The first profile assumes a surface
! pressure of 101325 pa, and the second profile assumes
! 81060 pa. [real, dimension(nlev+1,2)]
!
!
! axes The axis indices that are returned by previous calls to
! diag_axis_init. The values of this array correspond to the
! x, y, full (p)level, and half (p)level axes. These are the
! axes that diagnostic fields are output on.
! [integer, dimension(4)]
!
!
! Time The current time. [time_type]
!
!
! Aerosol names
!
!
! The input argument pref must have a second dimension size of 2.
!
!
! You have attempted to read a radiation_driver.res file with either
! no restart version number or an incorrect restart version number.
!
!
!
! radiation time step has changed, next radiation time also changed
! The radiation time step from the namelist input did not match
! the radiation time step from the radiation restart file.
! The next time for radiation will be adjusted for the new namelist
! input) value.
!
!
!
subroutine radiation_driver_init (lonb, latb, pref, axes, Time, &
aerosol_names, aerosol_family_names,&
do_cosp, ncol)
!---------------------------------------------------------------------
! radiation_driver_init is the constructor for radiation_driver_mod.
!---------------------------------------------------------------------
!--------------------------------------------------------------------
real, dimension(:,:), intent(in) :: lonb, latb
real, dimension(:,:), intent(in) :: pref
integer, dimension(4), intent(in) :: axes
type(time_type), intent(in) :: Time
character(len=*), dimension(:), intent(in) :: aerosol_names
character(len=*), dimension(:), intent(in) :: aerosol_family_names
logical, intent(in) :: do_cosp
integer, intent(out) :: ncol
!----------------------------------------------------------------------
!---------------------------------------------------------------------
! intent(in) variables:
!
! lonb 2d array of model longitudes on cell corners
! [ radians ]
! latb 2d array of model latitudes at cell corners
! [ radians ]
! pref array containing two reference pressure profiles
! for use in defining transmission functions
! [ pascals ]
! axes diagnostic variable axes
! Time current time [time_type(days, seconds)]
! aerosol_names names associated with the activated aerosol
! species
! aerosol_family_names
! names associated with the activated aerosol
! families
!
!----------------------------------------------------------------------
!---------------------------------------------------------------------
! local variables
integer :: unit, io, ierr, logunit
integer :: kmax
integer :: nyr, nv, nband
integer :: yr, month, year, dum
integer :: ico2
integer :: nzens
!---------------------------------------------------------------------
! local variables
!
! unit io unit number for namelist file
! io error status returned from io operation
! ierr error code
! id number of grid points in x direction (on processor)
! jd number of grid points in y direction (on processor)
! kmax number of model layers
!
!---------------------------------------------------------------------
!---------------------------------------------------------------------
! if routine has already been executed, exit.
!---------------------------------------------------------------------
if (module_is_initialized) return
!---------------------------------------------------------------------
! verify that modules used by this module that are not called later
! have already been initialized. note that data_override_init cannot
! be called successfully from here (a data_override_mod feature);
! instead it relies upon a check for previous initialization when
! subroutine data_override is called.
!---------------------------------------------------------------------
call fms_init
call rad_utilities_init
call diag_manager_init
call time_manager_init
call sat_vapor_pres_init
call constants_init
call diag_integral_init
call esfsw_parameters_init
!---------------------------------------------------------------------
! read namelist.
!---------------------------------------------------------------------
if ( file_exist('input.nml')) then
unit = open_namelist_file ( )
ierr=1; do while (ierr /= 0)
read (unit, nml=radiation_driver_nml, iostat=io, end=10)
ierr = check_nml_error(io,'radiation_driver_nml')
enddo
10 call close_file (unit)
endif
call get_restart_io_mode(do_netcdf_restart)
!--------------------------------------------------------------------
! make sure other namelist variables are consistent with
! doing_data_override. Validate here to prevent potentially mis-
! leading values from going into the stdlog file.
!--------------------------------------------------------------------
if (.not. doing_data_override) then
overriding_temps = .false.
overriding_sphum = .false.
overriding_albedo = .false.
overriding_clouds = .false.
overriding_aerosol = .false.
endif
!---------------------------------------------------------------------
! write version number and namelist to logfile.
!---------------------------------------------------------------------
call write_version_number (version, tagname)
logunit = stdlog()
if (mpp_pe() == mpp_root_pe() ) &
write (logunit, nml=radiation_driver_nml)
!---------------------------------------------------------------------
! set logical variable defining the radiation scheme desired from the
! namelist-input character string. set lower limit to water vapor
! mixing ratio that the radiation code will see, to assure keeping
! within radiation lookup tables. exit if value is invalid.
!---------------------------------------------------------------------
if (rad_package == 'original_fms') then
do_sea_esf_rad = .false.
rh2o_lower_limit = rh2o_lower_limit_orig
else if (rad_package == 'sea_esf') then
do_sea_esf_rad = .true.
rh2o_lower_limit = rh2o_lower_limit_seaesf
else
call error_mesg ('radiation_driver_mod', &
'string provided for rad_package is not valid', FATAL)
endif
!---------------------------------------------------------------------
! set control variable indicating whether water vapor effects are to
! be included in the radiative calculation. if h2o effects are not
! to be included in the radiative calculations, set the lower limit
! for h2o to zero. set flag to indicate do_h2o has been initialized.
!---------------------------------------------------------------------
Lw_control%do_h2o = do_h2o
if (.not. do_h2o) then
rh2o_lower_limit = 0.0
endif
Lw_control%do_h2o_iz = .true.
!---------------------------------------------------------------------
! set control variable indicating whether ozone effects are to be
! included in the radiative calculation. set flag to indicate the
! control variable has been initialized.
!---------------------------------------------------------------------
Lw_control%do_o3 = do_o3
Lw_control%do_o3_iz = .true.
!---------------------------------------------------------------------
! stop execution if overriding of aerosol data has been requested.
! code to do so has not yet been written.
!---------------------------------------------------------------------
if (overriding_aerosol) then
call error_mesg ('radiation_driver_mod', &
'overriding of aerosol data not yet implemented', FATAL)
endif
!RSH:
!RSH if use_co2_tracer_field is .true., verify here that there is
!RSH in fact a co2 field included within the tracer array. if not,
!RSH call error_mesg and abort execution.
!RSH
if(use_co2_tracer_field) then
ico2 = get_tracer_index(MODEL_ATMOS, 'co2')
if(ico2 == NO_TRACER) then
call error_mesg('radiation_driver_mod', &
'co2 must be present as a tracer when use_co2_tracer_field is .true.', FATAL)
endif
endif
!--------------------------------------------------------------------
! set logical variables defining how the solar zenith angle is to
! be defined from the namelist-input character string. exit if the
! character string is invalid.
!--------------------------------------------------------------------
if (zenith_spec == 'diurnally_varying') then
Sw_control%do_diurnal = .true.
Sw_control%do_annual = .false.
Sw_control%do_daily_mean = .false.
else if (zenith_spec == 'daily_mean') then
Sw_control%do_diurnal = .false.
Sw_control%do_annual = .false.
Sw_control%do_daily_mean = .true.
else if (zenith_spec == 'annual_mean') then
Sw_control%do_diurnal = .false.
Sw_control%do_annual = .true.
Sw_control%do_daily_mean = .false.
else
call error_mesg ('radiation_driver_mod', &
'string provided for zenith_spec is invalid', FATAL)
endif
!--------------------------------------------------------------------
! check if spacially-uniform solar input has been requested. if it
! has, verify that the requested lat and lon are valid, and convert
! them to radians.
!--------------------------------------------------------------------
if (use_uniform_solar_input) then
if (lat_for_solar_input < -90. .or. &
lat_for_solar_input > 90. ) then
call error_mesg ('radiation_driver_mod', &
'specified latitude for uniform solar input is invalid', &
FATAL)
else
lat_for_solar_input = lat_for_solar_input/RADIAN
endif
if (lon_for_solar_input < 0. .or. &
lon_for_solar_input > 360. ) then
call error_mesg ('radiation_driver_mod', &
'specified longitude for uniform solar input is invalid', &
FATAL)
else
lon_for_solar_input = lon_for_solar_input/RADIAN
endif
endif
!--------------------------------------------------------------------
! code to handle time-varying solar input
!--------------------------------------------------------------------
if (file_exist('INPUT/lean_solar_spectral_data.dat')) then
unit = open_namelist_file &
('INPUT/lean_solar_spectral_data.dat')
read (unit, FMT = '(4i8)') first_yr_lean, last_yr_lean, &
nvalues_per_year_lean, numbands_lean
if (numbands_lean /= Solar_spect%nbands) then
call error_mesg ('radiation_driver_mod', &
' number of sw parameterization bands in solar_spectral &
&data file differs from that defined in esfsw_parameters',&
FATAL)
endif
years_of_data_lean = last_yr_lean - first_yr_lean + 1
allocate (solflxtot_lean &
(years_of_data_lean, nvalues_per_year_lean))
allocate (Solar_spect%solflxband_lean &
(years_of_data_lean, nvalues_per_year_lean, numbands_lean))
allocate (Solar_spect%solflxband_lean_ann_1882(numbands_lean))
read (unit, FMT = '(2i6,f17.4)') yr, month, &
solflxtot_lean_ann_1882
read (unit, FMT = '(6e12.5 )') &
(Solar_spect%solflxband_lean_ann_1882 &
(nband), nband =1,numbands_lean)
do nyr=1,years_of_data_lean
do nv=1,nvalues_per_year_lean
read (unit, FMT = '(2i6,f17.4)') yr, month, &
solflxtot_lean(nyr,nv)
read (unit, FMT = '(6e12.5 )') &
(Solar_spect%solflxband_lean &
(nyr,nv,nband), nband =1,numbands_lean)
end do
end do
allocate (Solar_spect%solflxband_lean_ann_2000(numbands_lean))
read (unit, FMT = '(2i6,f17.4)') yr, month, &
solflxtot_lean_ann_2000
read (unit, FMT = '(6e12.5 )') &
(Solar_spect%solflxband_lean_ann_2000 &
(nband), nband =1,numbands_lean)
call close_file (unit)
else
if (time_varying_solar_constant) then
call error_mesg ('radiation_driver_mod', &
'desired solar_spectral_data input file is not present', &
FATAL)
endif
endif
if (time_varying_solar_constant) then
!----------------------------------------------------------------------
! define the model base time.
!----------------------------------------------------------------------
Model_init_time = get_base_time()
!----------------------------------------------------------------------
! if no solar_dataset_entry is supplied, use the model base time,
! meaning that the timeseries data will be mapped to the model time
! without any offset.
!----------------------------------------------------------------------
if (solar_dataset_entry(1) == 1 .and. &
solar_dataset_entry(2) == 1 .and. &
solar_dataset_entry(3) == 1 .and. &
solar_dataset_entry(4) == 0 .and. &
solar_dataset_entry(5) == 0 .and. &
solar_dataset_entry(6) == 0 ) then
Solar_entry = Model_init_time
!----------------------------------------------------------------------
! if a solar_dataset_entry is supplied, define a corresponding
! time-type variable.
!----------------------------------------------------------------------
else
Solar_entry = set_date (solar_dataset_entry(1), &
solar_dataset_entry(2), &
solar_dataset_entry(3), &
solar_dataset_entry(4), &
solar_dataset_entry(5), &
solar_dataset_entry(6))
endif
call error_mesg ('radiation_driver_mod', &
'Solar data is varying in time', NOTE)
call print_date (Solar_entry , str='Data from solar timeseries &
&at time:')
call print_date (Model_init_time , str='This data is mapped to &
&model time:')
Solar_offset = Solar_entry - Model_init_time
if (Model_init_time > Solar_entry) then
negative_offset = .true.
else
negative_offset = .false.
endif
Rad_control%using_solar_timeseries_data = .true.
Rad_control%using_solar_timeseries_data_iz = .true.
!---------------------------------------------------------------------
! if solar input not time-varying, define solar constant and set
! offset to 0.0.
!---------------------------------------------------------------------
else
if (solar_dataset_entry(1) == 1 .and. &
solar_dataset_entry(2) == 1 .and. &
solar_dataset_entry(3) == 1 .and. &
solar_dataset_entry(4) == 0 .and. &
solar_dataset_entry(5) == 0 .and. &
solar_dataset_entry(6) == 0 ) then
Sw_control%solar_constant = solar_constant
Solar_offset = set_time(0,0)
call error_mesg ('radiation_driver_mod', &
'Solar data is fixed in time at nml value', NOTE)
Rad_control%using_solar_timeseries_data = .false.
Rad_control%using_solar_timeseries_data_iz = .true.
else
!----------------------------------------------------------------------
! convert solar_dataset_entry to a time_type variable.
!----------------------------------------------------------------------
Solar_entry = set_date (solar_dataset_entry(1), &
solar_dataset_entry(2), &
solar_dataset_entry(3), &
solar_dataset_entry(4), &
solar_dataset_entry(5), &
solar_dataset_entry(6))
call error_mesg ('radiation_driver_mod', &
'Solar data is fixed in time', NOTE)
call print_date (Solar_entry , &
str='Data used in this experiment is from solar &
×eries at time:')
if (size(Solar_spect%solflxband(:)) /= numbands_lean) then
call error_mesg ('radiation_driver_mod', &
'bands present in solar constant time data differs from &
&model parameterization band number', FATAL)
endif
!--------------------------------------------------------------------
! define time to be used for solar input data.
!--------------------------------------------------------------------
call get_date (Solar_entry, year, month, dum, dum, dum, dum)
!--------------------------------------------------------------------
! define input value based on year and month of Solar_time.
!--------------------------------------------------------------------
if (year < first_yr_lean) then
Sw_control%solar_constant = solflxtot_lean_ann_1882
do nband=1,numbands_lean
Solar_spect%solflxband(nband) = &
Solar_spect%solflxband_lean_ann_1882(nband)
end do
else if (year > last_yr_lean) then
Sw_control%solar_constant = solflxtot_lean_ann_2000
do nband=1,numbands_lean
Solar_spect%solflxband(nband) = &
Solar_spect%solflxband_lean_ann_2000(nband)
end do
else
Sw_control%solar_constant = &
solflxtot_lean(year-first_yr_lean+1, month)
do nband=1,numbands_lean
Solar_spect%solflxband(nband) = &
Solar_spect%solflxband_lean(year-first_yr_lean+1, month, nband)
end do
endif
Rad_control%using_solar_timeseries_data = .true.
Rad_control%using_solar_timeseries_data_iz = .true.
endif
endif
!---------------------------------------------------------------------
! include logical control in Rad_control derived-type variable.
!---------------------------------------------------------------------
Rad_control%time_varying_solar_constant = &
time_varying_solar_constant
Rad_control%time_varying_solar_constant_iz = .true.
!---------------------------------------------------------------------
! set flags indicating that the Sw_control variables have been
! defined.
!---------------------------------------------------------------------
Sw_control%do_diurnal_iz = .true.
Sw_control%do_annual_iz = .true.
Sw_control%do_daily_mean_iz = .true.
!---------------------------------------------------------------------
! be sure that sw renormalization and hi-res zenith angle are not
! both selected as options. they are mutually exclusive.
!---------------------------------------------------------------------
if (renormalize_sw_fluxes .and. use_hires_coszen) then
call error_mesg ('radiation_driver_init', &
' cannot select both hi-res zenith angle and sw &
&renormalization at same time -- choose only one', FATAL)
endif
!---------------------------------------------------------------------
! verify that radiation has been requested at all model levels and in
! all model columns when the original fms radiation is activated.
! verify that renormalize_sw_fluxes has not been requested along
! with the original fms radiation package. verify that all_step_diag-
! nostics has not been requested with the original fms radiation
! package.
!---------------------------------------------------------------------
if (.not. do_sea_esf_rad) then
if (.not. all_level_radiation .or. &
.not. all_column_radiation) then
call error_mesg ( 'radiation_driver_mod', &
' must specify all_level_radiation and all_column_radiation'//&
' as true when using original fms radiation', FATAL)
endif
if (renormalize_sw_fluxes) then
call error_mesg ( 'radiation_driver_mod', &
' cannot renormalize shortwave fluxes with original_fms '//&
'radiation package.', FATAL)
endif
if (all_step_diagnostics) then
call error_mesg ( 'radiation_driver_mod', &
' cannot request all_step_diagnostics with original_fms '//&
'radiation package.', FATAL)
endif
endif
!---------------------------------------------------------------------
! can only renormalize shortwave fluxes when diurnally_varying
! radiation is used.
!---------------------------------------------------------------------
if (renormalize_sw_fluxes .and. .not. Sw_control%do_diurnal) then
call error_mesg ('radiation_driver_mod', &
' can only renormalize sw fluxes when using diurnally-varying'//&
' solar radiation', FATAL)
endif
!---------------------------------------------------------------------
! verify that a valid radiation time step has been specified.
!---------------------------------------------------------------------
if (rad_time_step <= 0) then
call error_mesg ('radiation_driver_mod', &
' radiation timestep must be set to a positive integer', &
FATAL)
endif
if (.not. use_single_lw_sw_ts) then
if (sw_rad_time_step <= 0) then
call error_mesg ('radiation_driver_mod', &
' sw radiation timestep must be set to a positive integer', &
FATAL)
endif
endif
if (use_single_lw_sw_ts .and. (sw_rad_time_step /= 0.0 .and. &
sw_rad_time_step /= rad_time_step) ) then
call error_mesg ('radiation_driver', &
'to avoid confusion, sw_rad_time_step must either remain at &
&default value of 0.0, or be same as rad_time_step &
&when use_single_lw_sw_ts is .true.', FATAL)
endif
if (use_single_lw_sw_ts) then
sw_rad_time_step = rad_time_step
endif
lw_rad_time_step = rad_time_step
Rad_control%rad_time_step = rad_time_step
Rad_control%rad_time_step_iz = .true.
Rad_control%lw_rad_time_step = lw_rad_time_step
Rad_control%lw_rad_time_step_iz = .true.
Rad_control%sw_rad_time_step = sw_rad_time_step
Rad_control%sw_rad_time_step_iz = .true.
if (MOD(INT(SECONDS_PER_DAY), lw_rad_time_step) /= 0) then
call error_mesg ('radiation_driver_mod', &
'lw radiation timestep currently restricted to be an &
&integral factor of seconds in a day', FATAL)
endif
if (MOD(INT(SECONDS_PER_DAY), sw_rad_time_step) /= 0) then
call error_mesg ('radiation_driver_mod', &
'sw radiation timestep currently restricted to be an &
&integral factor of seconds in a day', FATAL)
endif
!----------------------------------------------------------------------
! store the radiation time step in a derived-type variable for
! transfer to other modules.
!----------------------------------------------------------------------
Rad_control%rad_time_step = rad_time_step
Rad_control%rad_time_step_iz = .true.
!----------------------------------------------------------------------
! store the controls for hires cloudy coszen calculations.
!----------------------------------------------------------------------
if (use_hires_coszen) then
Rad_control%hires_coszen = .true.
else
Rad_control%hires_coszen = .false.
endif
Rad_control%hires_coszen_iz = .true.
if (nzens_per_sw_rad_timestep > 1 .and. &
.not. (use_hires_coszen) ) then
call error_mesg ('radiation_driver_init', &
'uncertainty in what is desired wrt nzens; if &
&nzens_per_sw_rad_timestep is not default, &
&use_hires_coszen must be set to .true.' , FATAL)
endif
if (use_hires_coszen) then
Rad_control%nzens = nzens_per_sw_rad_timestep
else
Rad_control%nzens = 1
endif
Rad_control%nzens_iz = .true.
!---------------------------------------------------------------------
! define the dimensions of the local processors portion of the grid.
!---------------------------------------------------------------------
id = size(lonb,1) - 1
jd = size(latb,2) - 1
kmax = size(pref,1) - 1
!---------------------------------------------------------------------
! save the number of special levels at which fluxes may be defined
! for diagnostic purposes.
!---------------------------------------------------------------------
Rad_control%mx_spec_levs = MX_SPEC_LEVS
Rad_control%mx_spec_levs_iz = .true.
!---------------------------------------------------------------------
! check for consistency if drop_upper_levels is activated.
!----------------------------------------------------------------------
if (drop_upper_levels .and. all_level_radiation) then
call error_mesg ( 'radiation_driver_mod', &
' drop_upper_levels and all_level_radiation are '//&
'incompatible', FATAL)
endif
!---------------------------------------------------------------------
! define the starting and ending vertical indices of the radiation
! grid. if all_level_radiation is .true., then radiation is done
! at all model levels. ks, ke are model-based coordinates, while
! ksrad and kerad are radiation-grid based coordinates (ksrad always
! is equal to 1).
!---------------------------------------------------------------------
if (all_level_radiation) then
ks = 1
ke = kmax
kerad = kmax
topmost_radiation_level = 1
else
if (topmost_radiation_level <= 0) then
call error_mesg ('radiation_driver_mod', &
' when all_level_radiation is .false., topmost_radiation'//&
'_level must be specified as a positive integer.', FATAL)
endif
if (drop_upper_levels) then
ks = topmost_radiation_level
ke = kmax
kerad = ke - ks + 1
call error_mesg ( ' radiation_driver_mod', &
' code has not been validated for all_level_radiation = '//&
'false. DO NOT USE!', FATAL)
else
call error_mesg ( ' radiation_driver_mod', &
' currently only drop_upper_levels is available as option '//&
'when all_level_radiation = false.', FATAL)
endif
endif
!---------------------------------------------------------------------
! exit if all_column_radiation is not .true. -- this option is not
! yet certified.
!---------------------------------------------------------------------
if (.not. all_column_radiation) then
call error_mesg ('radiation_driver_mod', &
' code currently not validated for all_column_radiation = '//&
'false. DO NOT USE!', FATAL)
endif
!----------------------------------------------------------------------
! be sure both reference pressure profiles have been provided.
!----------------------------------------------------------------------
if (size(pref,2) /= 2) &
call error_mesg ('radiation_driver_mod', &
'must provide two reference pressure profiles (pref).', FATAL)
!---------------------------------------------------------------------
! allocate space for variables which must be saved when sw fluxes
! are renormalized or diagnostics are desired to be output on every
! physics step.
!---------------------------------------------------------------------
nzens = Rad_control%nzens
if (renormalize_sw_fluxes .or. all_step_diagnostics) then
allocate (solar_save (id,jd))
allocate (dum_idjd (id,jd))
allocate (flux_sw_surf_save (id,jd,nzens))
allocate (flux_sw_surf_dir_save (id,jd,nzens))
allocate (flux_sw_surf_dif_save (id,jd,nzens))
allocate (flux_sw_down_vis_dir_save (id,jd,nzens))
allocate (flux_sw_down_vis_dif_save (id,jd,nzens))
allocate (flux_sw_down_total_dir_save (id,jd,nzens))
allocate (flux_sw_down_total_dif_save (id,jd,nzens))
allocate (flux_sw_vis_save (id,jd,nzens))
allocate (flux_sw_vis_dir_save (id,jd,nzens))
allocate (flux_sw_vis_dif_save (id,jd,nzens))
allocate (sw_heating_save (id,jd,kmax,nzens))
allocate (tot_heating_save (id,jd,kmax,nzens))
allocate (dfsw_save (id,jd,kmax+1,nzens))
allocate (ufsw_save (id,jd,kmax+1,nzens))
allocate ( fsw_save (id,jd,kmax+1,nzens))
allocate ( hsw_save (id,jd,kmax,nzens))
allocate (swdn_special_save (id,jd,MX_SPEC_LEVS,nzens))
allocate (swup_special_save (id,jd,MX_SPEC_LEVS,nzens))
if (do_swaerosol_forcing) then
allocate (dfsw_ad_save (id,jd,kmax+1,nzens))
allocate (ufsw_ad_save (id,jd,kmax+1,nzens))
endif
if (do_clear_sky_pass) then
allocate (sw_heating_clr_save (id,jd,kmax,nzens))
allocate (tot_heating_clr_save (id,jd,kmax,nzens))
allocate (dfswcf_save (id,jd,kmax+1,nzens))
allocate (ufswcf_save (id,jd,kmax+1,nzens))
allocate ( fswcf_save (id,jd,kmax+1,nzens))
allocate ( hswcf_save (id,jd,kmax,nzens))
allocate (flux_sw_down_total_dir_clr_save (id,jd,nzens))
allocate (flux_sw_down_total_dif_clr_save (id,jd,nzens))
allocate (flux_sw_down_vis_clr_save (id,jd,nzens))
allocate (swdn_special_clr_save(id,jd, MX_SPEC_LEVS,nzens))
allocate (swup_special_clr_save(id,jd, MX_SPEC_LEVS,nzens))
if (do_swaerosol_forcing) then
allocate (dfswcf_ad_save (id,jd,kmax+1,nzens))
allocate (ufswcf_ad_save (id,jd,kmax+1,nzens))
endif
endif
endif
!---------------------------------------------------------------------
! allocate space for variables which must be saved when lw fluxes
! are to be output on every physics step.
!---------------------------------------------------------------------
if (all_step_diagnostics) then
allocate (olr_save (id,jd))
allocate (lwups_save (id,jd))
allocate (lwdns_save (id,jd))
allocate (tdtlw_save (id,jd,kmax))
allocate (flxnet_save (id,jd,kmax+1))
allocate (netlw_special_save (id,jd,MX_SPEC_LEVS))
if (do_lwaerosol_forcing) then
allocate (olr_ad_save (id,jd))
allocate (lwups_ad_save (id,jd))
allocate (lwdns_ad_save (id,jd))
endif
if (do_clear_sky_pass) then
allocate (olr_clr_save (id,jd))
allocate (lwups_clr_save (id,jd))
allocate (lwdns_clr_save (id,jd))
allocate (tdtlw_clr_save (id,jd,kmax))
allocate (flxnetcf_save (id,jd,kmax+1))
allocate (netlw_special_clr_save (id,jd,MX_SPEC_LEVS))
if (do_lwaerosol_forcing) then
allocate (olr_ad_clr_save (id,jd))
allocate (lwups_ad_clr_save (id,jd))
allocate (lwdns_ad_clr_save (id,jd))
endif
endif
endif
!---------------------------------------------------------------------
! allocate space for the global integrals being accumulated in
! this module.
!---------------------------------------------------------------------
allocate (olr_intgl(id,jd))
allocate (swabs_intgl(id,jd))
!---------------------------------------------------------------------
! allocate space for module variables to contain values which must
! be saved between timesteps (these are used on every timestep,
! but only calculated on radiation steps).
!---------------------------------------------------------------------
allocate (Rad_output%tdt_rad (id,jd,kmax,nzens))
allocate (Rad_output%tdt_rad_clr (id,jd,kmax,nzens))
allocate (Rad_output%tdtsw (id,jd,kmax,nzens))
allocate (Rad_output%tdtsw_clr (id,jd,kmax,nzens))
allocate (Rad_output%ufsw (id,jd,kmax+1,nzens))
allocate (Rad_output%dfsw (id,jd,kmax+1,nzens))
allocate (Rad_output%ufsw_clr (id,jd,kmax+1,nzens))
allocate (Rad_output%dfsw_clr (id,jd,kmax+1,nzens))
allocate (Rad_output%flxnet (id,jd,kmax+1))
allocate (Rad_output%flxnetcf (id,jd,kmax+1))
allocate (Rad_output%tdtlw (id,jd,kmax))
allocate (Rad_output%tdtlw_clr (id,jd,kmax))
allocate (Rad_output%flux_sw_surf_dir(id,jd,nzens))
allocate (Rad_output%flux_sw_surf_dif(id,jd,nzens))
allocate (Rad_output%flux_sw_down_vis_dir(id,jd,nzens))
allocate (Rad_output%flux_sw_down_vis_dif(id,jd,nzens))
allocate (Rad_output%flux_sw_down_total_dir(id,jd,nzens))
allocate (Rad_output%flux_sw_down_total_dif(id,jd,nzens))
allocate (Rad_output%flux_sw_down_total_dir_clr(id,jd,nzens))
allocate (Rad_output%flux_sw_down_total_dif_clr(id,jd,nzens))
allocate (Rad_output%flux_sw_down_vis_clr(id,jd,nzens))
allocate (Rad_output%flux_sw_vis(id,jd,nzens))
allocate (Rad_output%flux_sw_vis_dir(id,jd,nzens))
allocate (Rad_output%flux_sw_vis_dif(id,jd,nzens))
allocate (Rad_output%flux_sw_surf(id,jd,nzens))
allocate (Rad_output%flux_lw_surf(id,jd))
allocate (Rad_output%coszen_angle(id,jd))
Rad_output%tdtsw = 0.0
Rad_output%tdtsw_clr = 0.0
Rad_output%ufsw = 0.0
Rad_output%dfsw = 0.0
Rad_output%ufsw_clr = 0.0
Rad_output%dfsw_clr = 0.0
Rad_output%flxnet = 0.0
Rad_output%flxnetcf = 0.0
Rad_output%tdtlw = 0.0
Rad_output%tdtlw_clr = 0.0
!-----------------------------------------------------------------------
! if two radiation restart files exist, exit.
!-----------------------------------------------------------------------
if ( file_exist('INPUT/sea_esf_rad.res') .and. &
file_exist('INPUT/radiation_driver.res') ) then
call error_mesg ('radiation_driver_mod', &
' both sea_esf_rad.res and radiation_driver.res files are'//&
' present in INPUT directory. which one to use ?', FATAL)
endif
if (using_restart_file) then
!----------------------------------------------------------------------
! Register fields to be written out to restart file.
if(do_netcdf_restart) call rad_driver_register_restart('radiation_driver.res.nc')
!-----------------------------------------------------------------------
! if a valid restart file exists, call read_restart_file to read it.
!-----------------------------------------------------------------------
if ( file_exist('INPUT/radiation_driver.res.nc')) then
call read_restart_nc
else if ( (do_sea_esf_rad .and. &
(file_exist('INPUT/sea_esf_rad.res') .or. &
file_exist('INPUT/radiation_driver.res') ) ) .or. &
(.not. do_sea_esf_rad .and. &
file_exist('INPUT/radiation_driver.res') ) ) then
call read_restart_file
!----------------------------------------------------------------------
! if no restart file is present, initialize the needed fields until
! the radiation package may be called. initial surface flux is set
! to 100 wm-2, and is only used for initial guess of sea ice temp.
! set rad_alarm to be 1 second from now, ie., on the first step of
! the job.
!-----------------------------------------------------------------------
else
lwrad_alarm = 1
swrad_alarm = 1
if (mpp_pe() == mpp_root_pe() ) then
call error_mesg ('radiation_driver_mod', &
'radiation to be calculated on first step: no restart file&
& present', NOTE)
endif
Rad_output%tdt_rad = 0.0
Rad_output%tdt_rad_clr = 0.0
Rad_output%tdtlw = 0.0
Rad_output%flux_sw_surf = surf_flx_init
!!! BETTER INITIAL VALUES FOR THESE ARRAYS NEEDED ??
Rad_output%flux_sw_surf_dir = surf_flx_init
Rad_output%flux_sw_surf_dif = surf_flx_init
!!! BETTER INITIAL VALUES FOR THESE ARRAYS NEEDED ??
Rad_output%flux_sw_down_vis_dir = 0.0
Rad_output%flux_sw_down_vis_dif = 0.0
Rad_output%flux_sw_down_total_dir = 0.0
Rad_output%flux_sw_down_total_dif = 0.0
Rad_output%flux_sw_down_total_dir_clr = 0.0
Rad_output%flux_sw_down_total_dif_clr = 0.0
Rad_output%flux_sw_down_vis_clr = 0.0
Rad_output%flux_sw_vis = 0.0
Rad_output%flux_sw_vis_dir = 0.0
Rad_output%flux_sw_vis_dif = 0.0
Rad_output%flux_lw_surf = surf_flx_init
Rad_output%coszen_angle = coszen_angle_init
if (mpp_pe() == mpp_root_pe() ) then
call error_mesg ('radiation_driver_mod', &
'no acceptable radiation restart file present; therefore'//&
' will initialize input fields', NOTE)
endif
endif
!---------------------------------------------------------------------
! if not using restart file, then initialize fields it would contain.
! it is the responsibility of the user to assure restart is on a
! radiation timestep so that restart seamlessness is maintained. if
! restart is done on a non-radiation step, restart seamlessness will
! be lost if a restart file is not available.
!---------------------------------------------------------------------
else ! (using_restart_file)
lwrad_alarm = 1
swrad_alarm = 1
if (mpp_pe() == mpp_root_pe() ) then
call error_mesg ('radiation_driver_mod', &
'radiation to be calculated on first step: user asserts that&
& this is a scheduled radiation step; if it is not, &
&restart seamlessness will be lost ', NOTE)
endif
Rad_output%tdt_rad = 0.0
Rad_output%tdt_rad_clr = 0.0
Rad_output%tdtlw = 0.0
Rad_output%flux_sw_surf = surf_flx_init
Rad_output%flux_sw_surf_dir = surf_flx_init
Rad_output%flux_sw_surf_dif = surf_flx_init
Rad_output%flux_sw_down_vis_dir = 0.0
Rad_output%flux_sw_down_vis_dif = 0.0
Rad_output%flux_sw_down_total_dir = 0.0
Rad_output%flux_sw_down_total_dif = 0.0
Rad_output%flux_sw_down_total_dir_clr = 0.0
Rad_output%flux_sw_down_total_dif_clr = 0.0
Rad_output%flux_sw_down_vis_clr = 0.0
Rad_output%flux_sw_vis = 0.0
Rad_output%flux_sw_vis_dir = 0.0
Rad_output%flux_sw_vis_dif = 0.0
Rad_output%flux_lw_surf = surf_flx_init
Rad_output%coszen_angle = coszen_angle_init
endif ! (using_restart_file)
!--------------------------------------------------------------------
! do the initialization specific to the sea_esf_rad radiation
! package.
!--------------------------------------------------------------------
if (do_sea_esf_rad) then
!---------------------------------------------------------------------
! define control variables indicating whether the clear-sky forcing
! should be calculated. set a flag to indicate that the variable
! has been defined.
!---------------------------------------------------------------------
Rad_control%do_totcld_forcing = do_clear_sky_pass
Rad_control%do_totcld_forcing_iz = .true.
!---------------------------------------------------------------------
! define control variables indicating whether the aerosol forcings
! should be calculated. set a flag to indicate that the variables
! have been defined.
!---------------------------------------------------------------------
Rad_control%do_lwaerosol_forcing = do_lwaerosol_forcing
Rad_control%do_lwaerosol_forcing_iz = .true.
Rad_control%do_swaerosol_forcing = do_swaerosol_forcing
Rad_control%do_swaerosol_forcing_iz = .true.
if (do_lwaerosol_forcing) then
size_of_lwoutput = size_of_lwoutput + 1
indx_lwaf = size_of_lwoutput
Rad_control%indx_lwaf = indx_lwaf
endif
if (do_swaerosol_forcing) then
size_of_swoutput = size_of_swoutput + 1
indx_swaf = size_of_swoutput
Rad_control%indx_swaf = indx_swaf
endif
Rad_control%indx_lwaf_iz = .true.
Rad_control%indx_swaf_iz = .true.
!---------------------------------------------------------------------
! initialize the modules that are accessed from radiation_driver_mod.
!---------------------------------------------------------------------
call sea_esf_rad_init (lonb, latb, pref(ks:ke+1,:))
call cloudrad_package_init (pref(ks:ke+1,:), lonb, latb, &
axes, Time)
call aerosolrad_package_init (kmax, aerosol_names, lonb, latb)
call rad_output_file_init (axes, Time, aerosol_names, &
aerosol_family_names)
!---------------------------------------------------------------------
! do the initialization specific to the original fms radiation
! package.
!---------------------------------------------------------------------
else
call original_fms_rad_init (lonb, latb, pref, axes, Time, kmax)
endif
!--------------------------------------------------------------------
! initialize the astronomy_package.
!--------------------------------------------------------------------
if (Sw_control%do_annual) then
call astronomy_init (latb, lonb)
else
call astronomy_init
endif
!---------------------------------------------------------------------
! initialize the total number of columns in the processor's domain.
!---------------------------------------------------------------------
total_pts = id*jd
!-----------------------------------------------------------------------
! check if optional radiative date should be used.
!-----------------------------------------------------------------------
if (rad_date(1) > 1900 .and. &
rad_date(2) > 0 .and. rad_date(2) < 13 .and. &
rad_date(3) > 0 .and. rad_date(3) < 32 ) then
use_rad_date = .true.
else
use_rad_date = .false.
endif
!----------------------------------------------------------------------
! define characteristics of desired diagnostic integrals.
!----------------------------------------------------------------------
call initialize_diagnostic_integrals
!----------------------------------------------------------------------
! register the desired netcdf output variables with the
! diagnostics_manager.
!----------------------------------------------------------------------
call diag_field_init (Time, axes)
!--------------------------------------------------------------------
! initialize clocks to time portions of the code called from
! radiation_driver.
!--------------------------------------------------------------------
misc_clock = &
mpp_clock_id (' Physics_down: Radiation: misc', &
grain = CLOCK_MODULE)
clouds_clock = &
mpp_clock_id (' Physics_down: Radiation: clds', &
grain = CLOCK_MODULE)
calc_clock = &
mpp_clock_id (' Physics_down: Radiation: calc', &
grain = CLOCK_MODULE)
!---------------------------------------------------------------------
! call check_derived_types to verify that all logical elements of
! public derived-type variables stored in rad_utilities_mod but
! initialized elsewhere have been initialized.
!---------------------------------------------------------------------
if (do_sea_esf_rad) then
call check_derived_types
endif
!---------------------------------------------------------------------
! verify that stochastic clouds have been activated if the COSP
! simulator output has been requested.
!---------------------------------------------------------------------
if (do_cosp .and. &
(.not. Cldrad_control%do_stochastic_clouds) ) then
call error_mesg ('radiation_driver_init', &
'cannot call COSP simulator unless stochastic clouds are &
&activated (do_stochastic_clouds in strat_clouds_W_nml)', &
FATAL)
endif
!--------------------------------------------------------------------
! return the potential number of stochastic columns.
!--------------------------------------------------------------------
ncol = Solar_spect%nbands + Cldrad_control%nlwcldb
!---------------------------------------------------------------------
! set flag to indicate that module has been successfully initialized.
!---------------------------------------------------------------------
module_is_initialized = .true.
!--------------------------------------------------------------------
end subroutine radiation_driver_init
!######################################################################
subroutine radiation_driver_time_vary (Time, Rad_gases_tv)
!---------------------------------------------------------------------
! radiation_driver_time_vary calculates time-dependent,
! space-independent quantities needed within the modules of the
! radiation package.
!---------------------------------------------------------------------
type(time_type), intent(in) :: Time
type(radiative_gases_type), intent(inout) :: Rad_gases_tv
call aerosolrad_package_time_vary (Time)
call sea_esf_rad_time_vary (Time, Rad_gases_tv)
end subroutine radiation_driver_time_vary
!####################################################################
subroutine radiation_driver_endts (is, js, Rad_gases_tv)
integer, intent(in) :: is,js
type(radiative_gases_type), intent(in) :: Rad_gases_tv
!---------------------------------------------------------------------
call sum_diag_integral_field ('olr', olr_intgl)
call sum_diag_integral_field ('abs_sw', swabs_intgl )
call aerosolrad_package_endts
call sea_esf_rad_endts (Rad_gases_tv)
!---------------------------------------------------------------------
! complete radiation step. if this was a radiation step, set the
! radiation alarm to go off rad_time_step seconds from now, and
! set do_rad to false, so that radiation will not be calculated
! again until the alarm goes off.
!--------------------------------------------------------------------
if (.not. always_calculate) then
if (do_lw_rad) then
lwrad_alarm = lwrad_alarm + lw_rad_time_step
do_lw_rad = .false.
endif
if (do_sw_rad) then
swrad_alarm = swrad_alarm + sw_rad_time_step
do_sw_rad = .false.
endif
if (.not. do_lw_rad .and. .not. do_sw_rad) then
do_rad = .false.
else
do_rad = .true.
endif
endif ! (always_calculate)
Rad_control%do_lw_rad = do_lw_rad
Rad_control%do_sw_rad = do_sw_rad
end subroutine radiation_driver_endts
!#####################################################################
!
!
! radiation_driver adds the radiative heating rate to the temperature
! tendency and obtains the radiative boundary fluxes and cosine of
! the solar zenith angle to be used in the other component models.
!
!
! radiation_driver adds the radiative heating rate to the temperature
! tendency and obtains the radiative boundary fluxes and cosine of
! the solar zenith angle to be used in the other component models.
!
!
! call radiation_driver (is, ie, js, je, Time, Time_next, &
! lat, lon, Surface, Atmos_input, &
! Aerosol, Cld_spec, Rad_gases, &
! Lsc_microphys, Meso_microphys, &
! Cell_microphys, Radiation, mask, kbot)
!
!
!
! starting/ending i,j indices in global storage arrays
!
!
! current model time
!
!
! The time used for diagnostic output
!
!
! lon mean longitude (in radians) of all grid boxes processed by
! this call to radiation_driver [real, dimension(:,:)]
!
!
! lat mean latitude (in radians) of all grid boxes processed by this
! call to radiation_driver [real, dimension(:,:)]
!
!
! Surface input data to radiation package
!
!
! Atmospheric input data to radiation package
!
!
! Aerosol climatological input data to radiation package
!
!
! 4 dimensional tracer array, last index is the number of all tracers
!
!
! Cloud microphysical and physical parameters to radiation package,
! contains var-
! iables defining the cloud distribution, passed
! through to lower level routines
!
!
! Radiative gases properties to radiation package, , contains var-
! iables defining the radiatively active gases,
! passed through to lower level routines
!
!
! microphysical specification for large-scale
! clouds
!
!
! microphysical specification for convective cell
! clouds associated with donner convection
!
!
! microphysical specification for meso-scale
! clouds assciated with donner convection
!
!
! Radiation output from radiation package, contains variables
! which are output from radiation_driver to the
! calling routine, and then used elsewhere within
! the component models.
!
!
! OPTIONAL: present when running eta vertical coordinate,
! index of lowest model level above ground
!
!
! OPTIONAL: present when running eta vertical coordinate,
! mask to remove points below ground
!
!
! You have not called radiation_driver_init before calling
! radiation_driver.
!
!
! Time arguments to radiation_driver are producing a time step <= 0.
! Check that the time argumnets passed to the physics_driver are
! correct.
!
!
!
subroutine radiation_driver (is, ie, js, je, Time, Time_next, &
lat, lon, Surface, Atmos_input, &
Aerosol, r, Cld_spec, Rad_gases, &
Lsc_microphys, Meso_microphys, &
Cell_microphys, Shallow_microphys, &
Model_microphys, &
Radiation, Astronomy_inp, &
mask, kbot)
!---------------------------------------------------------------------
! radiation_driver adds the radiative heating rate to the temperature
! tendency and obtains the radiative boundary fluxes and cosine of
! the solar zenith angle to be used in the other component models.
!---------------------------------------------------------------------
!--------------------------------------------------------------------
integer, intent(in) :: is, ie, js, je
type(time_type), intent(in) :: Time, Time_next
real, dimension(:,:), intent(in) :: lat, lon
type(surface_type), intent(inout) :: Surface
type(atmos_input_type), intent(inout) :: Atmos_input
type(aerosol_type), intent(inout) :: Aerosol
real, dimension(:,:,:,:), intent(inout) :: r
type(cld_specification_type), intent(inout) :: Cld_spec
type(radiative_gases_type), intent(inout) :: Rad_gases
type(microphysics_type), intent(inout) :: Lsc_microphys,&
Meso_microphys,&
Cell_microphys, &
Shallow_microphys, &
Model_microphys
type(rad_output_type), intent(inout), optional :: Radiation
type(astronomy_inp_type), intent(inout), optional :: Astronomy_inp
real, dimension(:,:,:), intent(in), optional :: mask
integer, dimension(:,:), intent(in), optional :: kbot
!----------------------------------------------------------------------
!---------------------------------------------------------------------
! intent(in) variables:
!
! is,ie,js,je starting/ending subdomain i,j indices of data in
! the physics_window being integrated
! Time current model time [ time_type (days, seconds) ]
! Time_next time on next timestep, used as stamp for diagnos-
! tic output [ time_type (days, seconds) ]
! lat latitude of model points [ radians ]
! lon longitude of model points [ radians ]
!
! intent(inout) variables:
!
! Surface surface_type structure, contains variables
! defining the surface characteristics, including
! the following component referenced in this
! routine:
!
! asfc surface albedo [ dimensionless ]
!
! Atmos_input atmos_input_type structure, contains variables
! defining atmospheric state, including the follow-
! ing component referenced in this routine
!
! tsfc surface temperature [ deg K ]
!
! Aerosol aerosol_type structure, contains variables
! defining aerosol fields, passed through to
! lower level routines
! Cld_spec cld_specification_type structure, contains var-
! iables defining the cloud distribution, passed
! through to lower level routines
! Rad_gases radiative_gases_type structure, contains var-
! iables defining the radiatively active gases,
! passed through to lower level routines
! Lsc_microphys microphysics_type structure, contains variables
! describing the microphysical properties of the
! large-scale clouds, passed through to lower
! level routines
! Meso_microphys microphysics_type structure, contains variables
! describing the microphysical properties of the
! meso-scale clouds, passed through to lower
! level routines
! Cell_microphys microphysics_type structure, contains variables
! describing the microphysical properties of the
! convective cell-scale clouds, passed through to
! lower level routines
!
! intent(inout), optional variables:
!
! Radiation rad_output_type structure, contains variables
! which are output from radiation_driver to the
! calling routine, and then used elsewhere within
! the component models. present when running gcm,
! not present when running sa_gcm or standalone
! columns mode. variables defined here are:
!
! tdt_rad radiative (sw + lw) heating rate
! [ deg K / sec ]
! flux_sw_surf net (down-up) sw surface flux
! [ watts / m^^2 ]
! flux_lw_surf downward lw surface flux
! [ watts / m^^2 ]
! coszen_angle cosine of the zenith angle which will be used
! for the next ocean_albedo calculation
! [ dimensionless ]
! tdtlw longwave heating rate
! [ deg K / sec ]
! Astronomy_inp astronomy_input_type structure, optionally used
! to input astronomical forcings, when it is desired
! to specify them rather than use astronomy_mod.
! Used in various standalone applications.
!
! intent(in), optional variables:
!
! mask present when running eta vertical coordinate,
! mask to remove points below ground
! kbot present when running eta vertical coordinate,
! index of lowest model level above ground
!
!----------------------------------------------------------------------
!----------------------------------------------------------------------
! local variables:
type(cldrad_properties_type) :: Cldrad_props
type(astronomy_type) :: Astro, Astro2
type(lw_output_type), dimension(size_of_lwoutput) :: Lw_output
type(sw_output_type), dimension(size_of_swoutput) :: Sw_output
type(fsrad_output_type) :: Fsrad_output
type(aerosol_properties_type) :: Aerosol_props
type(aerosol_diagnostics_type) :: Aerosol_diags
real, dimension (ie-is+1, je-js+1) :: flux_ratio, &
lat_uniform, lon_uniform
integer :: nz
!-------------------------------------------------------------------
! local variables:
!
! Cldrad_props cloud radiative properties on model grid,
! [cldrad_properties_type]
! Astro astronomical properties on model grid, usually
! valid over radiation timestep
! [astronomy_type]
! Astro2 astronomical properties on model grid, valid
! over current physics timestep
! [astronomy_type]
! Lw_output sea longwave output fields on model grid,
! [lw_output_type]
! Sw_output esf shortwave output fields on model grid,
! [sw_output_type]
! Fsrad_output original fms radiation output fields on model
! grid, [fsrad_output_type]
! flux_ratio value used to renormalize sw fluxes and
! heating rates to account for earth-sun motion
! during the radiation timestep
!
!----------------------------------------------------------------------
!-------------------------------------------------------------------
! verify that this module has been initialized. if not, exit.
!-------------------------------------------------------------------
if (.not. module_is_initialized) &
call error_mesg ('radiation_driver_mod', &
'module has not been initialized', FATAL)
!---------------------------------------------------------------------
! if this is a radiation step, or if the astronomical inputs to
! radiation (solar, cosz, fracday, rrsun) need to be obtained
! because of time averaging or renormalization, call
! obtain_astronomy_variables to do so.
!---------------------------------------------------------------------
call mpp_clock_begin (misc_clock)
if (do_rad .or. renormalize_sw_fluxes .or. &
present(Astronomy_inp)) then
if (use_uniform_solar_input) then
if (present (Astronomy_inp)) then
call error_mesg ('radiation_driver_mod', &
'cannot specify both use_uniform_solar_input AND use&
& Astronomy_inp to specify astronomical variables', &
FATAL)
endif
lat_uniform(:,:) = lat_for_solar_input
lon_uniform(:,:) = lon_for_solar_input
call obtain_astronomy_variables (is, ie, js, je, &
lat_uniform, lon_uniform, &
Astro, Astro2)
else
if (present (Astronomy_inp)) then
Sw_control%do_diurnal = .false.
Sw_control%do_annual = .false.
Sw_control%do_daily_mean = .false.
endif
call obtain_astronomy_variables (is, ie, js, je, lat, lon, &
Astro, Astro2, &
Astronomy_inp = &
Astronomy_inp)
endif
endif
! print *, 'before aerosol ', mpp_pe()
if (do_rad) then
if (Rad_control%do_aerosol) then
call aerosolrad_package_alloc (ie-is+1, je-js+1, &
size(Aerosol%aerosol,3), Aerosol_props)
call aerosol_radiative_properties (is, ie, js, je, &
Rad_time, &
Atmos_input%pflux, &
Aerosol_diags, &
Aerosol, Aerosol_props)
! allocate (Aerosol_diags%extopdep (size(Aerosol%aerosol,1), &
! size(Aerosol%aerosol,2), &
! size(Aerosol%aerosol,3), &
! size(Aerosol%aerosol,4) ))
! Aerosol_diags%extopdep = 0.0
! allocate (Aerosol_diags%absopdep (size(Aerosol%aerosol,1), &
! size(Aerosol%aerosol,2), &
! size(Aerosol%aerosol,3), &
! size(Aerosol%aerosol,4) ))
! Aerosol_diags%absopdep = 0.0
! allocate (Aerosol_diags%extopdep_vlcno &
! (size(Aerosol%aerosol,1), &
! size(Aerosol%aerosol,2), &
! size(Aerosol%aerosol,3),3))
! Aerosol_diags%extopdep_vlcno = 0.0
! allocate (Aerosol_diags%absopdep_vlcno &
! (size(Aerosol%aerosol,1), &
! size(Aerosol%aerosol,2), &
! size(Aerosol%aerosol,3),3))
! Aerosol_diags%absopdep_vlcno = 0.0
! allocate (Aerosol_diags%sw_heating_vlcno &
! (size(Aerosol%aerosol,1), &
! size(Aerosol%aerosol,2), &
! size(Aerosol%aerosol,3)))
! Aerosol_diags%sw_heating_vlcno = 0.0
! allocate (Aerosol_diags%lw_extopdep_vlcno &
! (size(Aerosol%aerosol,1), &
! size(Aerosol%aerosol,2), &
! size(Aerosol%aerosol,3)+1,3))
! Aerosol_diags%lw_extopdep_vlcno = 0.0
! allocate (Aerosol_diags%lw_absopdep_vlcno &
! (size(Aerosol%aerosol,1), &
! size(Aerosol%aerosol,2), &
! size(Aerosol%aerosol,3)+1,3))
! Aerosol_diags%lw_absopdep_vlcno = 0.0
endif
endif
call mpp_clock_end (misc_clock)
!--------------------------------------------------------------------
! when using the sea-esf radiation, call cloud_radiative_properties
! to obtain the cloud-radiative properties needed for the radiation
! calculation. (these properties are obtained within radiation_calc
! when executing the original fms radiation code). if these fields
! are to be time-averaged, this call is made on all steps; otherwise
! just on radiation steps.
!--------------------------------------------------------------------
! print *, 'before cloud_rad', mpp_pe()
call mpp_clock_begin (clouds_clock)
if (do_rad) then
if (do_sea_esf_rad) then
if (present(kbot) ) then
call cloud_radiative_properties ( &
is, ie, js, je, Rad_time, Time_next, Astro, &
Atmos_input, Cld_spec, Lsc_microphys, &
Meso_microphys, Cell_microphys, &
Shallow_microphys, Cldrad_props, &
Model_microphys, kbot=kbot, mask=mask)
else
call cloud_radiative_properties ( &
is, ie, js, je, Rad_time, Time_next, Astro, &
Atmos_input, Cld_spec, Lsc_microphys, &
Meso_microphys, Cell_microphys, &
Shallow_microphys, Cldrad_props, Model_microphys)
endif
endif
endif
call mpp_clock_end (clouds_clock)
!---------------------------------------------------------------------
! on radiation timesteps, call radiation_calc to determine new radia-
! tive fluxes and heating rates.
!---------------------------------------------------------------------
! print *, 'before _calc ', mpp_pe()
call mpp_clock_begin (calc_clock)
if (do_rad) then
call radiation_calc (is, ie, js, je, Rad_time, Time_next, lat, &
lon, Atmos_input, Surface, Rad_gases, &
Aerosol_props, Aerosol, r, Cldrad_props, &
Cld_spec, Astro, Rad_output, Lw_output, &
Sw_output, Fsrad_output, Aerosol_diags, &
mask=mask, &
kbot=kbot)
endif
call mpp_clock_end (calc_clock)
!-------------------------------------------------------------------
! on all timesteps, call update_rad_fields to update the temperature
! tendency and define the fluxes needed by other component models.
! if the shortwave fluxes are to be renormalized because of the
! change in zenith angle since the last radiation timestep, that also
! is done in this subroutine.
!-------------------------------------------------------------------
! print *, 'before update ', mpp_pe()
call mpp_clock_begin (misc_clock)
! if (Environment%running_gcm .or. &
! Environment%running_sa_model .or. &
! (Environment%running_standalone .and. &
! Environment%column_type == 'fms')) then
call update_rad_fields (is, ie, js, je, Time_next, Astro2, &
Sw_output, Astro, Rad_output, &
flux_ratio)
!-------------------------------------------------------------------
! call produce_radiation_diagnostics to produce radiation
! diagnostics, both fields and integrals.
!-------------------------------------------------------------------
if (do_sea_esf_rad) then
call produce_radiation_diagnostics &
(is, ie, js, je, Time_next, Time, lat, &
Atmos_input%tsfc, Surface, &
flux_ratio, Astro, Rad_output, &
Rad_gases, Lw_output=Lw_output,&
Sw_output=Sw_output, &
Cld_spec=Cld_spec, &
Lsc_microphys=Lsc_microphys)
else
call produce_radiation_diagnostics &
(is, ie, js, je, Time_next, Time, lat, &
Atmos_input%tsfc, Surface, &
flux_ratio, Astro, Rad_output, &
Rad_gases, Fsrad_output=Fsrad_output, &
mask=mask)
endif
!---------------------------------------------------------------------
! call write_rad_output_file to produce a netcdf output file of
! radiation-package-relevant variables. note that this is called
! only on radiation steps, so that the effects of sw renormalization
! will not be seen in the variables of the data file written by
! write_rad_output_file.
!---------------------------------------------------------------------
if (do_lw_rad .and. do_sw_rad .and. do_sea_esf_rad) then
if (Rad_control%do_aerosol) then
call write_rad_output_file (is, ie, js, je, &
Atmos_input, Surface, &
Rad_output, Sw_output(1), &
Lw_output(1), Rad_gases, &
Cldrad_props, Cld_spec, &
Time_next, &
Aerosol=Aerosol, &
Aerosol_props=Aerosol_props, &
Aerosol_diags=Aerosol_diags)
else
call write_rad_output_file (is, ie, js, je, &
Atmos_input,Surface, &
Rad_output, Sw_output(1), &
Lw_output(1), Rad_gases, &
Cldrad_props, Cld_spec, &
Time_next)
endif
endif ! (do_rad and do_sea_esf_rad)
! endif ! (running_gcm)
!---------------------------------------------------------------------
! call deallocate_arrays to deallocate the array space associated
! with stack-resident derived-type variables.
!---------------------------------------------------------------------
call deallocate_arrays (Cldrad_props, Astro, Astro2, &
Aerosol_props, &
Lw_output, Fsrad_output, Sw_output, &
Aerosol_diags)
!--------------------------------------------------------------------
! define the elements of the rad_output_type variable which will
! return the needed radiation package output to the calling routine.
! Radiation is currently present when running within a gcm, but
! not present for other applications.
!--------------------------------------------------------------------
if (present (Radiation)) then
nz = current_sw_zenith_step
Radiation%coszen_angle(:,:) = &
Rad_output%coszen_angle(is:ie,js:je)
Radiation%tdt_rad(:,:,:,1) = &
Rad_output%tdt_rad(is:ie,js:je,:,nz)
Radiation%flux_sw_surf(:,:,1) = &
Rad_output%flux_sw_surf(is:ie,js:je,nz)
Radiation%flux_sw_surf_dir(:,:,1) = &
Rad_output%flux_sw_surf_dir(is:ie,js:je,nz)
Radiation%flux_sw_surf_dif(:,:,1) = &
Rad_output%flux_sw_surf_dif(is:ie,js:je,nz)
Radiation%flux_sw_down_vis_dir(:,:,1) = &
Rad_output%flux_sw_down_vis_dir(is:ie,js:je,nz)
Radiation%flux_sw_down_vis_dif(:,:,1) = &
Rad_output%flux_sw_down_vis_dif(is:ie,js:je,nz)
Radiation%flux_sw_down_total_dir(:,:,1) = &
Rad_output%flux_sw_down_total_dir(is:ie,js:je,nz)
Radiation%flux_sw_down_total_dif(:,:,1) = &
Rad_output%flux_sw_down_total_dif(is:ie,js:je,nz)
Radiation%flux_sw_vis (:,:,1) = &
Rad_output%flux_sw_vis (is:ie,js:je,nz)
Radiation%flux_sw_vis_dir (:,:,1) = &
Rad_output%flux_sw_vis_dir (is:ie,js:je,nz)
Radiation%flux_sw_vis_dif (:,:,1) = &
Rad_output%flux_sw_vis_dif (is:ie,js:je,nz)
Radiation%flux_lw_surf(:,:) = &
Rad_output%flux_lw_surf(is:ie,js:je)
Radiation%flxnet(:,:,:) = &
Rad_output%flxnet(is:ie,js:je,:)
Radiation%tdtlw(:,:,:) = &
Rad_output%tdtlw(is:ie,js:je,:)
Radiation%ufsw(:,:,:,1) = Rad_output%ufsw(is:ie,js:je,:,nz)
Radiation%dfsw(:,:,:,1) = Rad_output%dfsw(is:ie,js:je,:,nz)
Radiation%flxnetcf(:,:,:) = &
Rad_output%flxnetcf(is:ie,js:je,:)
Radiation%ufsw_clr(:,:,:,1) = Rad_output%ufsw_clr(is:ie,js:je,:,nz)
Radiation%dfsw_clr(:,:,:,1) = Rad_output%dfsw_clr(is:ie,js:je,:,nz)
endif
call mpp_clock_end (misc_clock)
!---------------------------------------------------------------------
end subroutine radiation_driver
!#####################################################################
!
!
! subroutine define_rad_times determines whether radiation is to be
! calculated on the current timestep, and defines logical variables
! which determine whether various input fields to radiation_driver
! need to be retrieved on the current step.
!
!
! subroutine define_rad_times determines whether radiation is to be
! calculated on the current timestep, and defines logical variables
! which determine whether various input fields to radiation_driver
! need to be retrieved on the current step.
!
!
! call define_rad_times (Time, Time_next, Rad_time_out, &
! need_aerosols, need_clouds, need_gases, &
! need_basic)
!
!
! current model time
!
!
! The time used for diagnostic output
!
!
! time at which the climatologically-determined,
! time-varying input fields to radiation should
! apply
!
!
! aersosol input data is needed on this step ?
!
!
! cloud input data is needed on this step ?
!
!
! radiative gas input data is needed on this step ?
!
!
! atmospheric input fields are needed on this step ?
!
!
!
subroutine define_rad_times (Time, Time_next, Rad_time_out, &
need_aerosols, need_clouds, need_gases, &
need_basic)
!--------------------------------------------------------------------
! subroutine define_rad_times determines whether radiation is to be
! calculated on the current timestep, and defines logical variables
! which determine whether various input fields to radiation_driver
! need to be retrieved on the current step.
!--------------------------------------------------------------------
!---------------------------------------------------------------------
type(time_type), intent(in) :: Time, Time_next
type(time_type), intent(inout) :: Rad_time_out
logical, intent(out) :: need_aerosols, need_clouds, &
need_gases, need_basic
!---------------------------------------------------------------------
!---------------------------------------------------------------------
! intent(in) variables:
!
! Time current model time
! [ time_type, days and seconds]
! Time_next model time on the next atmospheric timestep
! [ time_type, days and seconds]
!
! intent(inout) variables:
!
! Rad_time_out time at which the climatologically-determined,
! time-varying input fields to radiation should
! apply
! [ time_type, days and seconds]
!
! intent(out) variables:
!
! need_aerosols aersosol input data is needed on this step ?
! need_clouds cloud input data is needed on this step ?
! need_gases radiative gas input data is needed on this step ?
! need_basic atmospheric input fields are needed on this step ?
!
!---------------------------------------------------------------------
!---------------------------------------------------------------------
! local variables:
integer :: year, month, day, sec
integer :: dum, tod(3)
integer :: nband
type(time_type) :: Solar_time
!---------------------------------------------------------------------
! local variables:
!
! day day component of atmospheric timestep
! [ days ]
! sec seconds component of atmospheric timestep
! [ seconds ]
! dum dummy variable
! tod hours, minutes and seconds components of current
! time
! [ hours, minutes, seconds ]
!
!---------------------------------------------------------------------
!-------------------------------------------------------------------
! verify that this module has been initialized. if not, exit.
!-------------------------------------------------------------------
if (.not. module_is_initialized) &
call error_mesg ('radiation_driver_mod', &
'module has not been initialized', FATAL)
!--------------------------------------------------------------------
! store the atmospheric timestep into a module variable for later
! use.
!--------------------------------------------------------------------
call get_time (Time_next-Time, sec, day)
dt = day*SECONDS_PER_DAY + sec
!--------------------------------------------------------------------
! verify that the radiation timestep is an even multiple of the
! physics timestep.
!---------------------------------------------------------------------
if (MOD(lw_rad_time_step, dt) /= 0) then
call error_mesg ('radiation_driver_mod', &
' lw radiation timestep is not integral multiple of physics step', &
FATAL)
endif
if (MOD(sw_rad_time_step, dt) /= 0) then
call error_mesg ('radiation_driver_mod', &
' sw radiation timestep is not integral multiple of physics step', &
FATAL)
endif
if (MOD(sw_rad_time_step/nzens_per_sw_rad_timestep, dt) /= 0) then
call error_mesg ( 'radiation_driver_mod', &
'requested nzens per sw timestep incompatible with physics &
×tep', FATAL)
endif
!-------------------------------------------------------------------
! for the standalone case, new radiation outputs are calculated on
! every step, using climatological variable values at the time spec-
! ified by the input argument Time.
!-------------------------------------------------------------------
if (always_calculate) then
do_rad = .true.
do_sw_rad = .true.
do_lw_rad = .true.
Rad_time = Time
current_sw_zenith_step = 1
Rad_control%do_lw_rad = do_lw_rad
Rad_control%do_sw_rad = do_sw_rad
!--------------------------------------------------------------------
! if running a gcm aplication, if this is the first call by this
! processor on this time step to radiation_driver (i.e. num_pts = 0),
! determine if this is a radiation time step by decrementing the time
! to alarm by the current model timestep. if the alarm "goes off",
! i.e., is .le. 0, set do_rad to true, indicating this is a radiation
! step. otherwise set it to .false. .
!--------------------------------------------------------------------
else
if (num_pts == 0) then
lwrad_alarm = lwrad_alarm - dt
swrad_alarm = swrad_alarm - dt
endif
if (lwrad_alarm <= 0) then
do_lw_rad = .true.
else
do_lw_rad = .false.
endif
if (swrad_alarm <= 0) then
do_sw_rad = .true.
current_sw_zenith_step = 1
else
do_sw_rad = .false.
if (use_hires_coszen) then
current_sw_zenith_step = current_sw_zenith_step + 1
endif
endif
if (do_sw_rad .or. do_lw_rad) then
do_rad = .true.
else
do_rad = .false.
endif
Rad_control%do_lw_rad = do_lw_rad
Rad_control%do_sw_rad = do_sw_rad
!-------------------------------------------------------------------
! define the time to be used in defining the time-varying input
! fields for the radiation calculation (Rad_time).
!-------------------------------------------------------------------
if (rsd) then
!--------------------------------------------------------------------
! if this is a repeat-same-day (rsd) experiment, define Rad_time
! as the specified year-month-day (rad_date(1:3)), and the
! hr-min-sec of the current time (Time).
!---------------------------------------------------------------------
if (.not. use_rad_date) &
call error_mesg ('radiation_driver_mod', &
'if (rsd), must set rad_date(1:3) to valid date', FATAL)
call get_date (Time, dum, dum, dum, tod(1), tod(2), tod(3))
Rad_time = set_date (rad_date(1), rad_date(2),&
rad_date(3), tod(1), tod(2), &
tod(3))
!---------------------------------------------------------------------
! if the specified date option is active, define Rad_time to be that
! date and time.
!----------------------------------------------------------------------
else if (use_rad_date) then
Rad_time = set_date (rad_date(1), rad_date(2), rad_date(3), &
rad_date(4), rad_date(5), rad_date(6))
!---------------------------------------------------------------------
! if neither of these special cases is active, define Rad_time as
! the current time (Time).
!---------------------------------------------------------------------
else
Rad_time = Time
endif ! (rsd)
endif ! (always_calculate)
!---------------------------------------------------------------------
! define the solar_constant appropriate at Rad_time, including any
! offset defined via the namelist.
!---------------------------------------------------------------------
if (Rad_control%time_varying_solar_constant) then
if (size(Solar_spect%solflxband(:)) /= numbands_lean) then
call error_mesg ('radiation_driver_mod', &
'bands present in solar constant time data differs from &
&model parameterization band number', FATAL)
endif
!--------------------------------------------------------------------
! define time to be used for solar input data.
!--------------------------------------------------------------------
if (negative_offset) then
Solar_time = Rad_time - Solar_offset
else
Solar_time = Rad_time + Solar_offset
endif
call get_date (Solar_time, year, month, dum, dum, dum, dum)
!--------------------------------------------------------------------
! define input value based on year and month of Solar_time.
!--------------------------------------------------------------------
if (year < first_yr_lean) then
Sw_control%solar_constant = solflxtot_lean_ann_1882
do nband=1,numbands_lean
Solar_spect%solflxband(nband) = &
Solar_spect%solflxband_lean_ann_1882(nband)
end do
else if (year > last_yr_lean) then
Sw_control%solar_constant = solflxtot_lean_ann_2000
do nband=1,numbands_lean
Solar_spect%solflxband(nband) = &
Solar_spect%solflxband_lean_ann_2000(nband)
end do
else
Sw_control%solar_constant = &
solflxtot_lean(year-first_yr_lean+1, month)
do nband=1,numbands_lean
Solar_spect%solflxband(nband) = &
Solar_spect%solflxband_lean(year-first_yr_lean+1, month, nband)
end do
endif
endif
!--------------------------------------------------------------------
! set a logical variable indicating whether radiative gas input data
! is needed on this step.
!--------------------------------------------------------------------
if (do_rad) then
need_gases = .true.
else
need_gases = .false.
endif
!--------------------------------------------------------------------
! set a logical variable indicating whether aerosol input data
! is needed on this step.
!--------------------------------------------------------------------
if (do_rad .and. Rad_control%do_aerosol) then
need_aerosols = .true.
else
need_aerosols = .false.
endif
!--------------------------------------------------------------------
! set a logical variable indicating whether cloud input data
! is needed on this step.
!--------------------------------------------------------------------
if (do_sea_esf_rad .and. do_rad) then
need_clouds = .true.
else
need_clouds = .false.
endif
!--------------------------------------------------------------------
! set a logical variable indicating whether atmospheric input data
! is needed on this step.
!--------------------------------------------------------------------
if (need_clouds .or. need_aerosols .or. need_gases) then
need_basic = .true.
else
need_basic = .false.
endif
!---------------------------------------------------------------------
! place the time at which radiation is to be applied into an output
! variable.
!---------------------------------------------------------------------
Rad_time_out = Rad_time
!---------------------------------------------------------------------
end subroutine define_rad_times
!######################################################################
!
!
! define_atmos_input_fields converts the atmospheric input fields
! (pfull, phalf, t, q, ts) to the form needed by the radiation
! modules, and when needed returns radiation-ready fields of pressure
! (press, psfc), temperature (temp, tsfc), water vapor mixing ratio
! (rh2o) and several auxiliary variables in the derived type
! structure Atmos_input. the optional input variables are present
! when running radiative feedback studies (sa_model), and are needed
! to allow variation of temperature and vapor fields while holding
! the aerosol and cloud amounts fixed.
!
!
! define_atmos_input_fields converts the atmospheric input fields
! (pfull, phalf, t, q, ts) to the form needed by the radiation
! modules, and when needed returns radiation-ready fields of pressure
! (press, psfc), temperature (temp, tsfc), water vapor mixing ratio
! (rh2o) and several auxiliary variables in the derived type
! structure Atmos_input. the optional input variables are present
! when running radiative feedback studies (sa_model), and are needed
! to allow variation of temperature and vapor fields while holding
! the aerosol and cloud amounts fixed.
!
!
! call define_atmos_input_fields (is, ie, js, je, pfull, phalf, &
! t, q, ts, r, gavg_rrv, Atmos_input, &
! cloudtemp, cloudvapor, &
! aerosoltemp, aerosolvapor, &
! aerosolpress, kbot)
!
!
! starting/ending subdomain i,j indices of data in
! the physics_window being integrated
!
!
! pressure at full levels
!
!
! pressure at half levels
!
!
! temperature at full levels
!
!
! specific humidity of water vapor at full levels
!
!
! surface temperature
!
!
! tracer array
!
!
! global average array of tracer volume mixxing ratio
!
!
! atmos_input type structure, contains the
! following components defined in this subroutine
!
!
! temperature to be seen by clouds (used in
! sa_gcm feedback studies)
!
!
! water vapor to be seen by clouds (used in
! sa_gcm feedback studies)
!
!
! required in sa_gcm mode, absent otherwise:
! temperature field to be used by aerosol param-
! eterization
!
!
! required in sa_gcm mode, absent otherwise:
! water vapor field to be used by aerosol param-
! eterization
!
!
! required in sa_gcm mode, absent otherwise:
! pressure field to be used by aerosol param-
! eterization
!
!
! present when running eta vertical coordinate,
! index of lowest model level above ground
!
!
!
subroutine define_atmos_input_fields (is, ie, js, je, pfull, phalf, &
t, q, ts, r, gavg_rrv, Atmos_input, &
cloudtemp, cloudvapor, &
aerosoltemp, aerosolvapor, &
aerosolpress, kbot)
!---------------------------------------------------------------------
! define_atmos_input_fields converts the atmospheric input fields
! (pfull, phalf, t, q, ts) to the form needed by the radiation
! modules, and when needed returns radiation-ready fields of pressure
! (press, psfc), temperature (temp, tsfc), water vapor mixing ratio
! (rh2o) and several auxiliary variables in the derived type
! structure Atmos_input. the optional input variables are present
! when running radiative feedback studies (sa_model), and are needed
! to allow variation of temperature and vapor fields while holding
! the aerosol and cloud amounts fixed.
!---------------------------------------------------------------------
integer, intent(in) :: is, ie, js, je
real, dimension(:,:,:), intent(in) :: pfull, phalf, t, q
real, dimension(:,:), intent(in) :: ts
real, dimension(:), intent(in) :: gavg_rrv
real, dimension(:,:,:,:),intent(in) :: r
type(atmos_input_type), intent(inout) :: Atmos_input
integer, dimension(:,:), intent(in), optional :: kbot
real, dimension(:,:,:), intent(in), optional :: cloudtemp, &
cloudvapor, &
aerosoltemp, &
aerosolvapor, &
aerosolpress
!---------------------------------------------------------------------
! intent(in) variables:
!
! is,ie,js,je starting/ending subdomain i,j indices of data in
! the physics_window being integrated
! pfull pressure at full levels [ kg / (m s^2) ]
! phalf pressure at half levels [ kg / (m s^2) ]
! t temperature at full levels [ deg K]
! q specific humidity of water vapor at full levels
! [ dimensionless ]
! ts surface temperature [ deg K ]
!
! intent(out) variables:
!
! Atmos_input atmos_input type structure, contains the
! following components defined in this subroutine
! psfc surface pressure
! [ (kg /( m s^2) ]
! tsfc surface temperature
! [ deg K ]
! temp temperature at model levels (1:nlev), surface
! temperature is stored at value nlev+1; if eta
! coordinates, surface value stored in below
! ground points
! [ deg K ]
! press pressure at model levels (1:nlev), surface
! pressure is stored at index value nlev+1
! [ (kg /( m s^2) ]
! rh2o mixing ratio of water vapor at model full levels
! [ non-dimensional ]
! deltaz model vertical grid separation
! [meters]
! pflux average of pressure at adjacent model levels
! [ (kg /( m s^2) ]
! tflux average of temperature at adjacent model levels
! [ deg K ]
! rel_hum relative humidity
! [ dimensionless ]
! cloudtemp temperature to be seen by clouds (used in
! sa_gcm feedback studies)
! [ degrees K ]
! cloudvapor water vapor to be seen by clouds (used in
! sa_gcm feedback studies)
! [ nondimensional ]
! clouddeltaz deltaz to be used in defining cloud paths (used
! in sa_gcm feedback studies)
! [ meters ]
! aerosoltemp temperature to be seen by aerosols (used in
! sa_gcm feedback studies)
! [ degrees K ]
! aerosolvapor water vapor to be seen by aerosols (used in
! sa_gcm feedback studies)
! [ nondimensional ]
! aerosolpress pressure field to be seen by aerosols (used in
! sa_gcm feedback studies)
! [ Pa ]
! aerosolrelhum relative humidity seen by aerosol package,
! used in sa_gcm feedback studies
! [ dimensionless ]
!
! intent(in), optional variables:
!
! kbot present when running eta vertical coordinate,
! index of lowest model level above ground (???)
! cloudtemp temperature to be seen by clouds (used in
! sa_gcm feedback studies)
! [ degrees K ]
! cloudvapor water vapor to be seen by clouds (used in
! sa_gcm feedback studies)
! [ nondimensional ]
! aerosoltemp required in sa_gcm mode, absent otherwise:
! temperature field to be used by aerosol param-
! eterization
! aerosolvapor required in sa_gcm mode, absent otherwise:
! water vapor field to be used by aerosol param-
! eterization
! aerosolpress required in sa_gcm mode, absent otherwise:
! pressure field to be used by aerosol param-
! eterization
!
!---------------------------------------------------------------------
!---------------------------------------------------------------------
! local variables
integer :: i, j, k, kb
integer :: kmax
integer :: d1, d2, d3, d4, d5, d6
logical :: override
type(time_type) :: Data_time
real, dimension (size(q,1), size(q,2), size(q,3)) :: q2
real, dimension (size(t,1), size(t,2), size(t,3)) :: t2, pfull2
real, dimension (size(t,1), size(t,2), size(t,3)+1) :: phalf2
real, dimension (size(ts,1), size(ts,2)) :: ts2
real, dimension (id, jd, size(t,3)) :: r_proc, t_proc, press_proc
real, dimension (id, jd, size(t,3)+1) :: phalf_proc
real, dimension (id, jd) :: ts_proc
integer :: ico2
!---------------------------------------------------------------------
! local variables
!
! i, j, k do loop indices
! kb vertical index of lowest atmospheric level (when
! using eta coordinates)
! kmax number of model layers
!
!---------------------------------------------------------------------
!-------------------------------------------------------------------
! verify that this module has been initialized. if not, exit.
!-------------------------------------------------------------------
if (.not. module_is_initialized) &
call error_mesg ('radiation_driver_mod', &
'module has not been initialized', FATAL)
!----------------------------------------------------------------------
! define the number of model layers.
!----------------------------------------------------------------------
kmax = size(t,3)
!---------------------------------------------------------------------
! if the temperature, cloud, or aerosol input data is to be over-
! riden, define the time slice of data which is to be used. allocate
! storage for the temperature data which will be needed for these
! cases.
!---------------------------------------------------------------------
if (doing_data_override) then
Data_time = Rad_time
if (overriding_temps .or. overriding_aerosol .or. &
overriding_clouds) then
!---------------------------------------------------------------------
! call data_override to retrieve the processor subdomain's temper-
! ature data from the override file. if the process fails, write
! an error message; if it succeeds move the data fro the current
! window into array t2.
!---------------------------------------------------------------------
call data_override ('ATM', 'tnew', t_proc, Data_time , &
override=override)
if ( .not. override) then
call error_mesg ('radiation_driver_mod', &
'temp => t not overridden successfully', FATAL)
else
t2(:,:,1:kmax) = t_proc(is:ie,js:je,:)
endif
else
t2 = t
endif
!---------------------------------------------------------------------
! if the temperature data is to be overriden, allocate storage for
! the surface temperature data which will be needed in this cases.
!---------------------------------------------------------------------
if (overriding_temps) then
!---------------------------------------------------------------------
! call data_override to retrieve the processor subdomain's surface
! temperature data from the override file. if the process fails,
! write an error message; if it succeeds move the data from the
! current window into array ts2, and also into array ts2.
!---------------------------------------------------------------------
call data_override ('ATM', 'ts', ts_proc, Data_time , &
override=override)
if ( .not. override) then
call error_mesg ('radiation_driver_mod', &
't_surf => ts not overridden successfully', FATAL)
else
ts2(:,:) = ts_proc(is:ie,js:je)
t2(:,:,kmax+1) = ts_proc(is:ie,js:je)
endif
else
ts2 = ts
endif
!---------------------------------------------------------------------
! if the humidity, cloud, or aerosol input data is to be over-
! riden, define the time slice of data which is to be used. allocate
! storage for the humidity data which will be needed for these
! cases.
!---------------------------------------------------------------------
if (overriding_sphum .or. overriding_aerosol .or. &
overriding_clouds) then
!---------------------------------------------------------------------
! call data_override to retrieve the processor subdomain's surface
! humidity data from the override file. if the process fails,
! write an error message; if it succeeds move the data from the
! current window into array q2.
!---------------------------------------------------------------------
call data_override ('ATM', 'q', r_proc, Data_time , &
override=override)
if ( .not. override) then
call error_mesg ('radiation_driver_mod', &
'sphum => q not overridden successfully', FATAL)
else
q2(:,:,:) = r_proc(is:ie,js:je,:)
endif
else
q2 = q
endif
!---------------------------------------------------------------------
! if the aerosol input data is to be overriden, allocate storage
! for the pressure data which will be needed in this case.
!---------------------------------------------------------------------
if (overriding_aerosol) then
!---------------------------------------------------------------------
! call data_override to retrieve the processor subdomain's pressure
! data from the override file. if the process fails, write an error
! message; if it succeeds move the data from the current window into
! array pfull2 and phalf2.
!---------------------------------------------------------------------
call data_override ('ATM', 'pfull2', press_proc, &
Data_time , override=override)
if ( .not. override) then
call error_mesg ('radiation_driver_mod', &
'pressm => pfull2 not overridden successfully', FATAL)
else
pfull2(:,:,:) = press_proc(is:ie,js:je,:)
endif
call data_override ('ATM', 'phalf2', phalf_proc, &
Data_time, override=override)
if ( .not. override) then
call error_mesg ('radiation_driver_mod', &
'phalfm => phalf2 not overridden successfully', FATAL)
else
phalf2(:,:,kmax+1) = phalf_proc(is:ie,js:je,kmax+1)
endif
else
pfull2 = pfull
phalf2(:,:,kmax+1) = phalf(:,:,kmax+1)
endif
!---------------------------------------------------------------------
! if not doing data_override, define the arrays which will be
! used to define the components of Atmos_input%.
!---------------------------------------------------------------------
else
t2 = t
ts2 = ts
q2 = q
pfull2 = pfull
phalf2(:,:,kmax+1) = phalf(:,:,kmax+1)
endif
!---------------------------------------------------------------------
! allocate space for the components of the derived type variable
! Atmos_input.
!---------------------------------------------------------------------
allocate ( Atmos_input%press(size(t,1), size(t,2), size(t,3)+1) )
allocate ( Atmos_input%phalf(size(t,1), size(t,2), size(t,3)+1) )
allocate ( Atmos_input%temp (size(t,1), size(t,2), size(t,3)+1) )
allocate ( Atmos_input%rh2o (size(t,1), size(t,2), size(t,3) ) )
allocate ( Atmos_input%rel_hum(size(t,1), size(t,2), &
size(t,3) ) )
allocate ( Atmos_input%cloudtemp(size(t,1), size(t,2), &
size(t,3) ) )
allocate ( Atmos_input%cloudvapor(size(t,1), size(t,2), &
size(t,3) ) )
allocate ( Atmos_input%clouddeltaz(size(t,1), size(t,2), &
size(t,3) ) )
allocate ( Atmos_input%aerosoltemp(size(t,1), size(t,2), &
size(t,3) ) )
allocate ( Atmos_input%aerosolpress(size(t,1), size(t,2), &
size(t,3)+1) )
allocate ( Atmos_input%aerosolvapor(size(t,1), size(t,2), &
size(t,3) ) )
allocate ( Atmos_input%aerosolrelhum(size(t,1), size(t,2), &
size(t,3) ) )
allocate ( Atmos_input%deltaz(size(t,1), size(t,2), size(t,3) ) )
allocate ( Atmos_input%pflux (size(t,1), size(t,2), size(t,3)+1) )
allocate ( Atmos_input%tflux (size(t,1), size(t,2), size(t,3)+1) )
allocate ( Atmos_input%psfc (size(t,1), size(t,2) ) )
allocate ( Atmos_input%tsfc (size(t,1), size(t,2) ) )
if (use_co2_tracer_field) then
allocate ( Atmos_input%tracer_co2(size(t,1), size(t,2), size(t,3) ) )
endif
!---------------------------------------------------------------------
! define the cloudtemp component of Atmos_input.
!---------------------------------------------------------------------
if (present (cloudtemp) ) then
Atmos_input%cloudtemp(:,:,:) = cloudtemp(:,:,:)
else
if (overriding_clouds) then
Atmos_input%cloudtemp(:,:,:) = t2(:,:,:)
else
Atmos_input%cloudtemp(:,:,:) = t(:,:,:)
endif
endif
!---------------------------------------------------------------------
! define the cloudvapor component of Atmos_input.
!---------------------------------------------------------------------
if (present (cloudvapor) ) then
Atmos_input%cloudvapor(:,:,:) = cloudvapor(:,:,:)
else
if (overriding_clouds) then
Atmos_input%cloudvapor(:,:,:) = q2(:,:,:)
else
Atmos_input%cloudvapor(:,:,:) = q(:,:,:)
endif
endif
!---------------------------------------------------------------------
! define the aerosoltemp component of Atmos_input.
!---------------------------------------------------------------------
if (present (aerosoltemp) ) then
Atmos_input%aerosoltemp(:,:,:) = aerosoltemp(:,:,:)
else
if (overriding_aerosol) then
Atmos_input%aerosoltemp(:,:,:) = t2(:,:,:)
else
Atmos_input%aerosoltemp(:,:,:) = t(:,:,:)
endif
endif
!---------------------------------------------------------------------
! define the aerosolvapor component of Atmos_input.
!---------------------------------------------------------------------
if (present (aerosolvapor) ) then
Atmos_input%aerosolvapor(:,:,:) = aerosolvapor(:,:,:)
else
if (overriding_aerosol) then
Atmos_input%aerosolvapor(:,:,:) = q2(:,:,:)
else
Atmos_input%aerosolvapor(:,:,:) = q(:,:,:)
endif
endif
!---------------------------------------------------------------------
! define values of surface pressure and temperature.
!--------------------------------------------------------------------
if (present(kbot)) then
do j=1,je-js+1
do i=1,ie-is+1
kb = kbot(i,j)
Atmos_input%psfc(i,j) = phalf2(i,j,kb+1)
end do
end do
else
Atmos_input%psfc(:,:) = phalf2(:,:,kmax+1)
endif
Atmos_input%tsfc(:,:) = ts2(:,:)
!------------------------------------------------------------------
! define the atmospheric pressure and temperature arrays.
!------------------------------------------------------------------
do k=1,kmax
Atmos_input%press(:,:,k) = pfull2(:,:,k)
Atmos_input%phalf(:,:,k) = phalf(:,:,k)
Atmos_input%temp (:,:,k) = t2(:,:,k)
end do
Atmos_input%press(:,:,kmax+1) = phalf2(:,:,kmax+1)
Atmos_input%phalf(:,:,kmax+1) = phalf2(:,:,kmax+1)
Atmos_input%temp (:,:,kmax+1) = ts2 (:,:)
!---------------------------------------------------------------------
! define the aerosolpress component of Atmos_input.
!---------------------------------------------------------------------
if (present (aerosolpress) ) then
do k=1,kmax
Atmos_input%aerosolpress(:,:,k) = aerosolpress(:,:,k)
end do
else
if (overriding_aerosol) then
do k=1,kmax
Atmos_input%aerosolpress(:,:,k) = pfull2(:,:,k)
end do
Atmos_input%aerosolpress(:,:,kmax+1) = phalf2(:,:,kmax+1)
else
do k=1,kmax
Atmos_input%aerosolpress(:,:,k) = pfull(:,:,k)
end do
Atmos_input%aerosolpress(:,:,kmax+1) = phalf(:,:,kmax+1)
endif
endif
!------------------------------------------------------------------
! if in eta coordinates, fill in underground temperatures with
! surface value.
!------------------------------------------------------------------
if (present(kbot)) then
do j=1,je-js+1
do i=1,ie-is+1
kb = kbot(i,j)
if (kb < kmax) then
do k=kb+1,kmax
Atmos_input%temp(i,j,k) = Atmos_input%temp(i,j,kmax+1)
end do
endif
end do
end do
endif
!------------------------------------------------------------------
! when running the gcm, convert the input water vapor specific
! humidity field to mixing ratio. it is assumed that water vapor
! mixing ratio is the input in the standalone case.
!------------------------------------------------------------------
if (use_mixing_ratio) then
Atmos_input%rh2o (:,:,:) = q2(:,:,:)
else
if (.not. overriding_sphum .and. &
.not. overriding_clouds .and. &
.not. overriding_aerosol) then
Atmos_input%rh2o (:,:,:) = q2(:,:,:)/(1.0 - q2(:,:,:))
else ! for override, values are already mixing ratio
Atmos_input%rh2o (:,:,:) = q2(:,:,:)
endif
if (.not. overriding_clouds) then
Atmos_input%cloudvapor(:,:,:) = &
Atmos_input%cloudvapor(:,:,:)/ &
(1.0 - Atmos_input%cloudvapor(:,:,:))
endif
if (.not. overriding_aerosol) then
Atmos_input%aerosolvapor(:,:,:) = &
Atmos_input%aerosolvapor(:,:,:)/ &
(1.0 - Atmos_input%aerosolvapor(:,:,:))
endif
endif
!------------------------------------------------------------------
! be sure that the magnitude of the water vapor mixing ratio field
! to be input to the radiation code is no smaller than the value of
! rh2o_lower_limit, which is 2.0E-07 when running the sea_esf
! radiation code and 3.0e-06 when running the original radiation
! code. Likewise, the temperature that the radiation code sees is
! constrained to lie between 100K and 370K. these are the limits of
! the tables referenced within the radiation package.
! exception:
! if do_h2o is false, the lower limit of h2o is zero, and radiation
! tables will not be called.
!-----------------------------------------------------------------------
if (do_rad) then
Atmos_input%rh2o(:,:,ks:ke) = &
MAX(Atmos_input%rh2o(:,:,ks:ke), rh2o_lower_limit)
Atmos_input%cloudvapor(:,:,ks:ke) = &
MAX(Atmos_input%cloudvapor(:,:,ks:ke), rh2o_lower_limit)
Atmos_input%aerosolvapor(:,:,ks:ke) = &
MAX(Atmos_input%aerosolvapor(:,:,ks:ke), rh2o_lower_limit)
Atmos_input%temp(:,:,ks:ke) = &
MAX(Atmos_input%temp(:,:,ks:ke), temp_lower_limit)
Atmos_input%temp(:,:,ks:ke) = &
MIN(Atmos_input%temp(:,:,ks:ke), temp_upper_limit)
Atmos_input%cloudtemp(:,:,ks:ke) = &
MAX(Atmos_input%cloudtemp(:,:,ks:ke), temp_lower_limit)
Atmos_input%cloudtemp(:,:,ks:ke) = &
MIN(Atmos_input%cloudtemp(:,:,ks:ke), temp_upper_limit)
Atmos_input%aerosoltemp(:,:,ks:ke) = &
MAX(Atmos_input%aerosoltemp(:,:,ks:ke), temp_lower_limit)
Atmos_input%aerosoltemp(:,:,ks:ke) = &
MIN(Atmos_input%aerosoltemp(:,:,ks:ke), temp_upper_limit)
endif
!--------------------------------------------------------------------
! call calculate_aulixiary_variables to compute pressure and
! temperature arrays at flux levels and an array of model deltaz.
!--------------------------------------------------------------------
if (do_rad) then
call calculate_auxiliary_variables (Atmos_input)
endif
!RSH
!RSH define here the values for Atmos_input%tracer_co2.
!RSH
!fil the error message should never be printed as that code should never
! be executed, it's an extra guard against user error.
if (use_co2_tracer_field ) then
ico2 = get_tracer_index(MODEL_ATMOS, 'co2')
if(ico2 /= NO_TRACER) then
Atmos_input%tracer_co2(:,:,:) = r(:,:,:,ico2)
Atmos_input%g_rrvco2 = gavg_rrv(ico2)
else
call error_mesg('radiation_driver', &
'ico2 cannot be NO_TRACER when use_co2_tracer_field is .true.', FATAL)
endif
endif
!----------------------------------------------------------------------
end subroutine define_atmos_input_fields
!#####################################################################
!
!
! define_surface stores the input values of land fraction and
! surface albedo in a surface_type structure Surface.
!
!
! define_surface stores the input values of land fraction and
! surface albedo in a surface_type structure Surface.
!
!
! call define_surface (is, ie, js, je, albedo, land, Surface)
!
!
! starting/ending subdomain i,j indices of data in
! the physics_window being integrated
!
!
! surface albedo
!
!
! fraction of grid box which is land
!
!
! surface_type structure to be valued
!
!
!
subroutine define_surface (is, ie, js, je, albedo, albedo_vis_dir, &
albedo_nir_dir, albedo_vis_dif, &
albedo_nir_dif, land, Surface)
!---------------------------------------------------------------------
! define_surface stores the input values of land fraction and
! surface albedo in a surface_type structure Surface.
!---------------------------------------------------------------------
integer, intent(in) :: is, ie, js, je
real, dimension(:,:), intent(in) :: albedo, land, &
albedo_vis_dir, &
albedo_nir_dir, &
albedo_vis_dif, &
albedo_nir_dif
type(surface_type), intent(inout) :: Surface
!---------------------------------------------------------------------
! intent(in) variables:
!
! is,ie,js,je starting/ending subdomain i,j indices of data in
! the physics_window being integrated
! albedo surface albedo [ dimensionless ]
! albedo_vis_dir surface visible direct albedo [ dimensionless ]
! albedo_nir_dir surface nir direct albedo [ dimensionless ]
! albedo_vis_dif surface visible diffuse albedo [ dimensionless ]
! albedo_nir_dif surface nir diffuse albedo [ dimensionless ]
! land fraction of grid box which is land [ dimensionless ]
!
! intent(out) variables:
!
! Surface surface_type structure, contains the
! following components defined in this subroutine
! asfc surface albedo
! [ non-dimensional ]
! asfc_vis_dir surface direct visible albedo
! [ non-dimensional ]
! asfc_nir_dir surface direct nir albedo
! [ non-dimensional ]
! asfc_vis_dif surface diffuse visible albedo
! [ non-dimensional ]
! asfc_nir_dif surface diffuse nir albedo
! [ non-dimensional ]
! land fraction of grid box covered by land
! [ non-dimensional ]
!
!---------------------------------------------------------------------
logical :: override
type(time_type) :: Data_time
real, dimension (size(albedo,1), size(albedo,2)) :: albedo2, &
albedo_vis_dir2, &
albedo_nir_dir2, &
albedo_vis_dif2, &
albedo_nir_dif2
real, dimension (id,jd) :: albedo_proc, &
albedo_vis_dir_proc, &
albedo_nir_dir_proc, &
albedo_vis_dif_proc, &
albedo_nir_dif_proc
!-------------------------------------------------------------------
! verify that the module has been initialized. if not, exit.
!-------------------------------------------------------------------
if (.not. module_is_initialized) &
call error_mesg ('radiation_driver_mod', &
'module has not been initialized', FATAL)
if (do_rad) then
if (doing_data_override) then
!---------------------------------------------------------------------
! if the albedo data is to be overriden, define the time from which
! the data is to be retrieved.
!---------------------------------------------------------------------
if (overriding_albedo) then
Data_time = Rad_time
!---------------------------------------------------------------------
! call data_override to retrieve the processor subdomain's surface
! albedo data from the override file. if the process fails,
! write an error message; if it succeeds move the data from the
! current window into array albedo2.
!---------------------------------------------------------------------
! call data_override ('ATM', 'albedonew', albedo_proc, &
! Data_time, override=override)
! if ( .not. override) then
! call error_mesg ('radiation_driver_mod', &
! 'cvisrfgd => albedo not overridden successfully', FATAL)
! else
! albedo2(:,:) = albedo_proc(is:ie,js:je)
! endif
call data_override ('ATM', 'albedo_nir_dir_new', &
albedo_nir_dir_proc, &
Data_time, override=override)
if ( .not. override) then
call error_mesg ('radiation_driver_mod', &
'nirdir => albedo not overridden successfully', FATAL)
else
albedo_nir_dir2(:,:) = albedo_nir_dir_proc(is:ie,js:je)
endif
call data_override ('ATM', 'albedo_nir_dif_new', &
albedo_nir_dif_proc, &
Data_time, override=override)
if ( .not. override) then
call error_mesg ('radiation_driver_mod', &
'nirdif => albedo not overridden successfully', FATAL)
else
albedo_nir_dif2(:,:) = albedo_nir_dif_proc(is:ie,js:je)
endif
call data_override ('ATM', 'albedo_vis_dir_new', &
albedo_vis_dir_proc, &
Data_time, override=override)
if ( .not. override) then
call error_mesg ('radiation_driver_mod', &
'visdir => albedo not overridden successfully', FATAL)
else
albedo_vis_dir2(:,:) = albedo_vis_dir_proc(is:ie,js:je)
endif
call data_override ('ATM', 'albedo_vis_dif_new', &
albedo_vis_dif_proc, &
Data_time, override=override)
if ( .not. override) then
call error_mesg ('radiation_driver_mod', &
'visdif => albedo not overridden successfully', FATAL)
else
albedo_vis_dif2(:,:) = albedo_vis_dif_proc(is:ie,js:je)
endif
!--------------------------------------------------------------------
! if albedo data is not being overriden, define albedo2 to be the
! model value of albedo.
!--------------------------------------------------------------------
else
! albedo2 = albedo
albedo_vis_dir2 = albedo_vis_dir
albedo_nir_dir2 = albedo_nir_dir
albedo_vis_dif2 = albedo_vis_dif
albedo_nir_dif2 = albedo_nir_dif
endif
else ! (doing data_override)
! albedo2 = albedo
albedo_vis_dir2 = albedo_vis_dir
albedo_nir_dir2 = albedo_nir_dir
albedo_vis_dif2 = albedo_vis_dif
albedo_nir_dif2 = albedo_nir_dif
endif
else ! (do_rad)
! albedo2 = albedo
albedo_vis_dir2 = albedo_vis_dir
albedo_nir_dir2 = albedo_nir_dir
albedo_vis_dif2 = albedo_vis_dif
albedo_nir_dif2 = albedo_nir_dif
endif ! (do_rad)
!---------------------------------------------------------------------
! allocate space for the components of the derived type variable
! Surface.
!---------------------------------------------------------------------
allocate (Surface%asfc (size(albedo,1), size(albedo,2)) )
allocate (Surface%asfc_vis_dir (size(albedo,1), size(albedo,2) ) )
allocate (Surface%asfc_nir_dir (size(albedo,1), size(albedo,2) ) )
allocate (Surface%asfc_vis_dif (size(albedo,1), size(albedo,2) ) )
allocate (Surface%asfc_nir_dif (size(albedo,1), size(albedo,2) ) )
allocate (Surface%land (size(albedo,1), size(albedo,2)) )
!------------------------------------------------------------------
! define the fractional land area of each grid box and the surface
! albedo from the input argument values.
!------------------------------------------------------------------
Surface%land(:,:) = land(:,:)
Surface%asfc(:,:) = albedo (:,:)
!pjp Should the albedos below all be set to albedo2,
!pjp or should they be included in the override data,
!pjp or should it not be changed?
Surface%asfc_vis_dir(:,:) = albedo_vis_dir2(:,:)
Surface%asfc_nir_dir(:,:) = albedo_nir_dir2(:,:)
Surface%asfc_vis_dif(:,:) = albedo_vis_dif2(:,:)
Surface%asfc_nir_dif(:,:) = albedo_nir_dif2(:,:)
!----------------------------------------------------------------------
end subroutine define_surface
!#####################################################################
!
!
! surface_dealloc deallocates the array components of the
! surface_type structure Surface.
!
!
! surface_dealloc deallocates the array components of the
! surface_type structure Surface.
!
!
! call surface_dealloc (Surface)
!
!
! surface_type structure to be deallocated
!
!
!
subroutine surface_dealloc (Surface)
!----------------------------------------------------------------------
! surface_dealloc deallocates the array components of the
! surface_type structure Surface.
!----------------------------------------------------------------------
type(surface_type), intent(inout) :: Surface
!--------------------------------------------------------------------
! intent(inout) variable:
!
! Surface surface_type structure, contains variables
! defining the surface albedo and land fraction
!
!--------------------------------------------------------------------
!-------------------------------------------------------------------
! verify that this module has been initialized. if not, exit.
!-------------------------------------------------------------------
if (.not. module_is_initialized) &
call error_mesg ('radiation_driver_mod', &
'module has not been initialized', FATAL)
!-------------------------------------------------------------------
! deallocate components of surface_type structure.
!-------------------------------------------------------------------
deallocate (Surface%asfc)
deallocate (Surface%asfc_vis_dir )
deallocate (Surface%asfc_nir_dir )
deallocate (Surface%asfc_vis_dif )
deallocate (Surface%asfc_nir_dif )
deallocate (Surface%land)
!--------------------------------------------------------------------
end subroutine surface_dealloc
!#####################################################################
!
!
! atmos_input_dealloc deallocates the array components of the
! atmos_input_type structure Atmos_input.
!
!
! atmos_input_dealloc deallocates the array components of the
! atmos_input_type structure Atmos_input.
!
!
! call atmos_input_dealloc (Atmos_input)
!
!
! atmos_input_type structure, contains variables
! defining the atmospheric pressure, temperature
! and moisture distribution.
!
!
!
subroutine atmos_input_dealloc (Atmos_input)
!----------------------------------------------------------------------
! atmos_input_dealloc deallocates the array components of the
! atmos_input_type structure Atmos_input.
!----------------------------------------------------------------------
type(atmos_input_type), intent(inout) :: Atmos_input
!--------------------------------------------------------------------
! intent(inout) variable:
!
! Atmos_input atmos_input_type structure, contains variables
! defining the atmospheric pressure, temperature
! and moisture distribution.
!
!--------------------------------------------------------------------
!-------------------------------------------------------------------
! verify that this module has been initialized. if not, exit.
!-------------------------------------------------------------------
if (.not. module_is_initialized) &
call error_mesg ('radiation_driver_mod', &
'module has not been initialized', FATAL)
!---------------------------------------------------------------------
! deallocate components of atmos_input_type structure.
!---------------------------------------------------------------------
deallocate (Atmos_input%press )
deallocate (Atmos_input%phalf )
deallocate (Atmos_input%temp )
deallocate (Atmos_input%rh2o )
deallocate (Atmos_input%rel_hum )
deallocate (Atmos_input%pflux )
deallocate (Atmos_input%tflux )
deallocate (Atmos_input%deltaz )
deallocate (Atmos_input%psfc )
deallocate (Atmos_input%tsfc )
deallocate (Atmos_input%cloudtemp )
deallocate (Atmos_input%cloudvapor )
deallocate (Atmos_input%clouddeltaz)
deallocate (Atmos_input%aerosoltemp)
deallocate (Atmos_input%aerosolvapor )
deallocate (Atmos_input%aerosolpress )
deallocate (Atmos_input%aerosolrelhum )
if(ASSOCIATED(Atmos_input%tracer_co2)) deallocate(Atmos_input%tracer_co2)
!--------------------------------------------------------------------
end subroutine atmos_input_dealloc
!#####################################################################
subroutine microphys_dealloc (Model_microphys)
type(microphysics_type), intent(inout) :: Model_microphys
!----------------------------------------------------------------------
! microphys_dealloc calls model_micro_dealloc to deallocate the
! array components of the microphysics_type structure Model_microphys.
!----------------------------------------------------------------------
!-------------------------------------------------------------------
! verify that this module has been initialized. if not, exit.
!-------------------------------------------------------------------
if (.not. module_is_initialized) &
call error_mesg ('radiation_driver_mod', &
'module has not been initialized', FATAL)
!---------------------------------------------------------------------
! deallocate the components of module variable Model_microphys.
!---------------------------------------------------------------------
call model_micro_dealloc (Model_microphys)
!--------------------------------------------------------------------
end subroutine microphys_dealloc
!#####################################################################
!
!
! radiation_driver_end is the destructor for radiation_driver_mod.
!
!
! radiation_driver_end is the destructor for radiation_driver_mod.
!
!
! call radiation_driver_end
!
!
!
subroutine radiation_driver_end
!----------------------------------------------------------------------
! radiation_driver_end is the destructor for radiation_driver_mod.
!----------------------------------------------------------------------
!-------------------------------------------------------------------
! verify that this module has been initialized. if not, exit.
!-------------------------------------------------------------------
if (.not. module_is_initialized) &
call error_mesg ('radiation_driver_mod', &
'module has not been initialized', FATAL)
!---------------------------------------------------------------------
! write restart file if desired; the file is not necessary if job
! ends on step prior to radiation ts, or if restart seamlessness
! is not required.
!---------------------------------------------------------------------
if (using_restart_file) then
! Make sure that the restart_versions variable is up to date.
vers = restart_versions(size(restart_versions(:)))
if ( do_netcdf_restart ) then
call radiation_driver_restart
else
call write_restart_file
endif
endif
!---------------------------------------------------------------------
! wrap up modules initialized by this module.
!---------------------------------------------------------------------
call astronomy_end
!---------------------------------------------------------------------
! wrap up modules specific to the radiation package in use.
!---------------------------------------------------------------------
if (do_sea_esf_rad) then
call cloudrad_package_end
call aerosolrad_package_end
call rad_output_file_end
call sea_esf_rad_end
else
call original_fms_rad_end
endif
!---------------------------------------------------------------------
! release space for renormalization arrays, if that option is active.
!---------------------------------------------------------------------
! if (renormalize_sw_fluxes .or. use_hires_coszen .or. &
if (renormalize_sw_fluxes .or. &
all_step_diagnostics) then
deallocate (solar_save, flux_sw_surf_save, sw_heating_save, &
dum_idjd, &
flux_sw_surf_dir_save, &
flux_sw_surf_dif_save, &
flux_sw_down_vis_dir_save, &
flux_sw_down_vis_dif_save, &
flux_sw_down_total_dir_save, &
flux_sw_down_total_dif_save, &
flux_sw_vis_save, &
flux_sw_vis_dir_save, &
flux_sw_vis_dif_save, &
tot_heating_save, dfsw_save, ufsw_save, &
swdn_special_save, swup_special_save, &
fsw_save, hsw_save)
if (do_swaerosol_forcing) then
deallocate (dfsw_ad_save, ufsw_ad_save)
endif
if (do_clear_sky_pass) then
deallocate (sw_heating_clr_save, tot_heating_clr_save, &
dfswcf_save, ufswcf_save, fswcf_save, &
swdn_special_clr_save, swup_special_clr_save, &
flux_sw_down_total_dir_clr_save, &
flux_sw_down_total_dif_clr_save, &
flux_sw_down_vis_clr_save, &
hswcf_save)
if (do_swaerosol_forcing) then
deallocate (dfswcf_ad_save, ufswcf_ad_save)
endif
endif
endif
!---------------------------------------------------------------------
! release space needed when all_step_diagnostics is active.
!---------------------------------------------------------------------
if (all_step_diagnostics) then
deallocate (olr_save, lwups_save, lwdns_save, flxnet_save, &
tdtlw_save)
deallocate (netlw_special_save)
if (do_lwaerosol_forcing) then
deallocate (olr_ad_save, lwups_ad_save, lwdns_ad_save)
endif
if (do_clear_sky_pass) then
deallocate (olr_clr_save, lwups_clr_save, lwdns_clr_save, &
flxnetcf_save, tdtlw_clr_save)
deallocate (netlw_special_clr_save)
if (do_lwaerosol_forcing) then
deallocate (olr_ad_clr_save, lwups_ad_clr_save, &
lwdns_ad_clr_save)
endif
endif
endif
!---------------------------------------------------------------------
! release space used for module variables that hold data between
! timesteps.
!---------------------------------------------------------------------
deallocate (Rad_output%tdt_rad, Rad_output%tdt_rad_clr, &
Rad_output%tdtsw, Rad_output%tdtsw_clr, &
Rad_output%ufsw, Rad_output%dfsw, &
Rad_output%ufsw_clr, Rad_output%dfsw_clr, &
Rad_output%tdtlw_clr, &
Rad_output%flxnet, Rad_output%flxnetcf, &
Rad_output%tdtlw, Rad_output%flux_sw_surf, &
Rad_output%flux_sw_surf_dir, &
Rad_output%flux_sw_surf_dif, &
Rad_output%flux_sw_down_vis_dir, &
Rad_output%flux_sw_down_vis_dif, &
Rad_output%flux_sw_down_total_dir, &
Rad_output%flux_sw_down_total_dif, &
Rad_output%flux_sw_down_total_dir_clr, &
Rad_output%flux_sw_down_total_dif_clr, &
Rad_output%flux_sw_down_vis_clr, &
Rad_output%flux_sw_vis, &
Rad_output%flux_sw_vis_dir, &
Rad_output%flux_sw_vis_dif, &
Rad_output%flux_lw_surf, Rad_output%coszen_angle)
!----------------------------------------------------------------------
! deallocate arrays related to the time_varying solar constant.
!----------------------------------------------------------------------
if (time_varying_solar_constant) then
deallocate (solflxtot_lean, Solar_spect%solflxband_lean, &
Solar_spect%solflxband_lean_ann_1882, &
Solar_spect%solflxband_lean_ann_2000)
endif
!---------------------------------------------------------------------
! call rad_utilities_end to uninitialize that module.
!---------------------------------------------------------------------
call rad_utilities_end
!----------------------------------------------------------------------
! set initialization status flag.
!----------------------------------------------------------------------
module_is_initialized = .false.
end subroutine radiation_driver_end
!######################################################################
subroutine return_cosp_inputs ( &
is, ie, js, je, donner_meso_is_largescale, &
Time_diag, Atmos_input, stoch_cloud_type, &
stoch_conc_drop, stoch_conc_ice, stoch_size_drop,&
stoch_size_ice, tau_stoch, lwem_stoch, &
Model_microphys, &
do_cosp, do_modis_yim, Lsc_microphys)
!---------------------------------------------------------------------
! subroutine return_cosp_inputs calculates and returns the fields
! needed as input by the COSP simulator.
!---------------------------------------------------------------------
integer, intent(in) :: is,ie, js, je
logical, intent(in) :: donner_meso_is_largescale
logical, intent(in) :: do_cosp, do_modis_yim
type(time_type), intent(in) :: Time_diag
type(atmos_input_type), intent(inout) :: Atmos_input
type(microphysics_type), intent(inout) :: Model_microphys
type(microphysics_type), intent(in) :: Lsc_microphys
real, dimension(:,:,:,:), intent(inout) :: &
stoch_cloud_type, stoch_conc_drop, &
stoch_conc_ice, stoch_size_drop, &
stoch_size_ice, tau_stoch, lwem_stoch
!-------------------------------------------------------------------
! local variables
!-------------------------------------------------------------------
integer :: nswbands, isccpSwBand, isccpLwBand, ncol
real :: isccp_scale_factor
integer :: n
!-------------------------------------------------------------------
call obtain_cloud_tau_and_em (is, js, Model_microphys, &
Atmos_input, &
tau_stoch(is:ie,js:je,:,:), &
lwem_stoch(is:ie,js:je,:,:) )
!-------------------------------------------------------------------
if (do_cosp) then
!---------------------------------------------------------------------
! save the stochastic cloud type in each subcolumn.
! output values of 0 --> no cloud
! values of 1 --> stratiform cloud
! values of 2 --> convective cloud
! input values are 0(none), 1(strat), 2(donnermeso), 3(donnercell),
! 4(uw)
!---------------------------------------------------------------------
stoch_cloud_type(is:ie,js:je,:,:) = &
Model_microphys%stoch_cloud_type(:,:,:,:)
!---------------------------------------------------------------------
! donner meso clouds may be treated either as large-scale or
! convective clouds, dependent on donner_meso_is_largescale.
!---------------------------------------------------------------------
if (donner_meso_is_largescale) then
where (stoch_cloud_type(is:ie,js:je,:,:) == 2)
stoch_cloud_type(is:ie,js:je,:,:) = 1
end where
where (stoch_cloud_type(is:ie,js:je,:,:) >= 3)
stoch_cloud_type(is:ie,js:je,:,:) = 2
end where
else
where (stoch_cloud_type(is:ie,js:je,:,:) >= 2)
stoch_cloud_type(is:ie,js:je,:,:) = 2
end where
endif
!---------------------------------------------------------------------
! save the particle concentrations and sizes seen by the radiation
! package in each stochastic column.
!---------------------------------------------------------------------
stoch_conc_drop(is:ie,js:je,:,:) = &
Model_microphys%stoch_conc_drop(:,:,:,:)
stoch_conc_ice (is:ie,js:je,:,:) = &
Model_microphys%stoch_conc_ice (:,:,:,:)
stoch_size_drop(is:ie,js:je,:,:) = &
Model_microphys%stoch_size_drop(:,:,:,:)
stoch_size_ice (is:ie,js:je,:,:) = &
Model_microphys%stoch_size_ice (:,:,:,:)
endif
!-------------------------------------------------------------------
if (do_modis_yim) then
call modis_yim (is, js, Time_diag, Tau_stoch(is:ie,js:je,:,:),&
Model_microphys, Atmos_input)
endif
call modis_cmip (is, js, Time_diag, Lsc_microphys, &
Atmos_input)
!-------------------------------------------------------------------
end subroutine return_cosp_inputs
!#######################################################################
!#######################################################################
!
!
!
! write out restart file.
! Arguments:
! timestamp (optional, intent(in)) : A character string that represents the model time,
! used for writing restart. timestamp will append to
! the any restart file name as a prefix.
!
!
subroutine radiation_driver_restart(timestamp)
character(len=*), intent(in), optional :: timestamp
! Make sure that the restart_versions variable is up to date.
vers = restart_versions(size(restart_versions(:)))
if ( do_netcdf_restart ) then
call write_restart_nc(timestamp)
else
call error_mesg ('radiation_driver_restart', &
'Native intermediate restart files are not supported.', FATAL)
endif
end subroutine radiation_driver_restart
! NAME="radiation_driver_restart"
!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
!
! PRIVATE SUBROUTINES
!
!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
subroutine write_restart_file
integer :: unit
!----------------------------------------------------------------------
! when running in gcm, write a restart file. this is not done in the
! standalone case.
!---------------------------------------------------------------------
if(mpp_pe() == mpp_root_pe()) then
call error_mesg('radiation_driver_mod', 'Writing native formatted restart file.', NOTE)
endif
unit = open_restart_file &
('RESTART/radiation_driver.res', 'write')
!---------------------------------------------------------------------
! only the root pe will write control information -- the last value
! in the list of restart versions and the alarm information.
!---------------------------------------------------------------------
if (mpp_pe() == mpp_root_pe() ) then
write (unit) restart_versions(size(restart_versions(:)))
! write (unit) rad_alarm, rad_time_step
write (unit) lwrad_alarm, rad_time_step
endif
!---------------------------------------------------------------------
! write out the restart data.
!---------------------------------------------------------------------
call write_data (unit, Rad_output%tdt_rad)
call write_data (unit, Rad_output%tdtlw)
call write_data (unit, Rad_output%flux_sw_surf)
call write_data (unit, Rad_output%flux_sw_surf_dir)
call write_data (unit, Rad_output%flux_sw_surf_dif)
call write_data (unit, Rad_output%flux_sw_down_vis_dir)
call write_data (unit, Rad_output%flux_sw_down_vis_dif)
call write_data (unit, Rad_output%flux_sw_down_total_dir)
call write_data (unit, Rad_output%flux_sw_down_total_dif)
call write_data (unit, Rad_output%flux_sw_vis)
call write_data (unit, Rad_output%flux_sw_vis_dir)
call write_data (unit, Rad_output%flux_sw_vis_dif)
call write_data (unit, Rad_output%flux_lw_surf)
call write_data (unit, Rad_output%coszen_angle)
!---------------------------------------------------------------------
! write out the optional time average restart data. note that
! do_average and renormalize_sw_fluxes may not both be true.
!---------------------------------------------------------------------
if (mpp_pe() == mpp_root_pe() ) then
write (unit) renormalize_sw_fluxes, do_clear_sky_pass
endif
!---------------------------------------------------------------------
! write out the optional shortwave renormalization data.
!---------------------------------------------------------------------
if (renormalize_sw_fluxes) then
call write_data (unit, solar_save)
call write_data (unit, flux_sw_surf_save)
call write_data (unit, flux_sw_surf_dir_save)
call write_data (unit, flux_sw_surf_dif_save)
call write_data (unit, flux_sw_down_vis_dir_save)
call write_data (unit, flux_sw_down_vis_dif_save)
call write_data (unit, flux_sw_down_total_dir_save)
call write_data (unit, flux_sw_down_total_dif_save)
call write_data (unit, flux_sw_vis_save)
call write_data (unit, flux_sw_vis_dir_save)
call write_data (unit, flux_sw_vis_dif_save)
call write_data (unit, sw_heating_save(:,:,:,1))
call write_data (unit, tot_heating_save(:,:,:,1))
call write_data (unit, dfsw_save(:,:,:,1))
call write_data (unit, ufsw_save(:,:,:,1))
call write_data (unit, fsw_save(:,:,:,1))
call write_data (unit, hsw_save(:,:,:,1))
call write_data (unit, swdn_special_save(:,:,:,1))
call write_data (unit, swup_special_save(:,:,:,1))
if (do_clear_sky_pass) then
call write_data (unit, sw_heating_clr_save)
call write_data (unit, tot_heating_clr_save)
call write_data (unit, dfswcf_save)
call write_data (unit, ufswcf_save)
call write_data (unit, fswcf_save)
call write_data (unit, hswcf_save)
call write_data (unit, flux_sw_down_total_dir_clr_save)
call write_data (unit, flux_sw_down_total_dif_clr_save)
call write_data (unit, flux_sw_down_vis_clr_save)
call write_data (unit, swdn_special_clr_save(:,:,:,1))
call write_data (unit, swup_special_clr_save(:,:,:,1))
endif
endif ! (renormalize)
!---------------------------------------------------------------------
! close the radiation_driver.res file
!---------------------------------------------------------------------
call close_file (unit)
end subroutine write_restart_file
!---------------------------------------------------------------------
subroutine write_restart_nc(timestamp)
character(len=*), intent(in), optional :: timestamp
character(len=65) :: fname='RESTART/radiation_driver.res.nc'
real :: flag1=0., flag2=0.
!---------------------------------------------------------------------
! only the root pe will write control information -- the last value
! in the list of restart versions and the alarm information.
!---------------------------------------------------------------------
if (mpp_pe() == mpp_root_pe() ) then
call error_mesg('radiation_driver_mod', 'Writing netCDF formatted restart file: RESTART/radiation_driver.res.nc', NOTE)
endif
!---------------------------------------------------------------------
! write out the optional time average restart data. note that
! do_average and renormalize_sw_fluxes may not both be true.
!---------------------------------------------------------------------
int_renormalize_sw_fluxes = 0
int_do_clear_sky_pass = 0
if(renormalize_sw_fluxes) then
int_renormalize_sw_fluxes = 1
else if (use_hires_coszen) then
if (current_sw_zenith_step == nzens_per_sw_rad_timestep) then
int_renormalize_sw_fluxes = 2
else
int_renormalize_sw_fluxes = -2
call error_mesg ('radiation_driver/write_restart_nc', &
' you are writing restart file on a non-radiation &
×tep. As a consequence, model results will be &
&different if the model is run with different restart &
& intervals. To correct, make sure rad_time_step &
& is an integral factor of the requested run length.', &
NOTE)
endif
endif
if(do_clear_sky_pass) int_do_clear_sky_pass = 1
! Make sure that the restart_versions variable is up to date.
vers = restart_versions(size(restart_versions(:)))
call save_restart(Rad_restart, timestamp)
if(in_different_file) call save_restart(Til_restart, timestamp)
end subroutine write_restart_nc
!#####################################################################
!
!
! read_restart_file reads a restart file containing radiation
! restart information. it may be either a radiation_driver.res, or
! an older sea_esf_rad.res file.
!
!
! read_restart_file reads a restart file containing radiation
! restart information. it may be either a radiation_driver.res, or
! an older sea_esf_rad.res file.
!
!
! call read_restart_file
!
!
!
subroutine read_restart_file
!-------------------------------------------------------------------
! read_restart_file reads a restart file containing radiation
! restart information. it may be either a radiation_driver.res, or
! an older sea_esf_rad.res file.
!---------------------------------------------------------------------
!--------------------------------------------------------------------
! local variables
integer :: unit
logical :: end
logical :: avg_present, renorm_present, &
cldfree_present
character(len=4) :: chvers
logical :: avg_gases, avg_clouds
integer, dimension(5) :: dummy
integer :: kmax
integer :: new_rad_time, lw_old_time_step, &
sw_old_time_step, old_time_step
integer :: rad_alarm, rad_time_step
!--------------------------------------------------------------------
! local variables:
!
! unit i/o unit number connected to .res file
! end logical variable indicating, if true, that
! end of file has been reached on the current
! read operation
! avg_present if true, time-average data is present in the
! restart file
! renorm_present if true, sw renormalization data is present
! in the restart file
! cldfree_present if true, and if renorm_present is true, then
! the clear-sky sw renormalization data is
! present in the restart file
! chvers character form of restart_version (i4)
! avg_gases if true, then time-average data for radiative
! gases is present in restart file
! avg_clouds if true, then time-average data for clouds is
! present in restart file
! dummy dummy array used as location to read older
! restart version data into
! kmax number of model layers
! new_rad_time time remaining until next radiation calcul-
! ation; replaces the rad_alarm value read from
! restart file when the radiation timestep
! changes upon restart
! old_time_step radiation timestep that was used in job
! which wrote the restart file
!
!---------------------------------------------------------------------
if (mpp_pe() == mpp_root_pe() ) then
call error_mesg('radiation_driver_mod', 'Reading native formatted restart file.', NOTE)
endif
!---------------------------------------------------------------------
! if one is using the sea_esf_rad package and there is a
! sea_esf_rad.res restart file present in the input directory, it
! must be version 1 in order to be readable by the current module.
! this file is where radiation restart data for the sea_esf radiation
! package was written, through AM2p8, or the galway code release.
! if this file is present and not version 1, exit.
!---------------------------------------------------------------------
if (do_sea_esf_rad .and. file_exist('INPUT/sea_esf_rad.res')) then
unit = open_restart_file ('INPUT/sea_esf_rad.res', 'read')
read (unit) vers
if ( vers /= 1 ) then
write (chvers,'(i4)') vers
call error_mesg ('radiation_driver_mod', &
'restart version '//chvers//' cannot be read '//&
'by this module version', FATAL)
endif
!---------------------------------------------------------------------
! if a radiation_driver.res file is present, then it must be one
! of the versions listed as readable for the radiation package
! being employed. these allowable versions are found in the array
! restart_versions. if the version is not acceptable, exit.
!---------------------------------------------------------------------
else if ( file_exist('INPUT/radiation_driver.res') ) then
unit = open_restart_file ('INPUT/radiation_driver.res', 'read')
read (unit) vers
if ( .not. any(vers == restart_versions) ) then
write (chvers,'(i4)') vers
call error_mesg ('radiation_driver_mod', &
'restart version '//chvers//' cannot be read '//&
'by this module version', FATAL)
endif
endif
!-----------------------------------------------------------------------
! read alarm information. if reading an sea_esf_rad.res file
! (version 1), recover the time step previously used, and set the
! radiation alarm to be 1 second from now, assuring radiation
! recalculation on the first model step of this run. for later
! restarts, read the previous radiation timestep and the rad_alarm
! that was present when the restart was written.
!-----------------------------------------------------------------------
if (vers == 1) then
read (unit) dummy
old_time_step = SECONDS_PER_DAY*dummy(4) + dummy(3)
rad_alarm = 1
if (mpp_pe() == mpp_root_pe() ) then
call error_mesg ('radiation_driver_mod', &
' radiation to be calculated on first step: restart file&
& is sea_esf_rad.res, additional fields needed to run with &
¤t code', NOTE)
endif
else
read (unit) rad_alarm, old_time_step
if (mpp_pe() == mpp_root_pe() ) then
print *, 'NOTE from PE 0: rad_alarm as read from restart &
&file is ', rad_alarm, 'second(s).'
endif
endif
!---------------------------------------------------------------------
! read the radiation restart data. it consists of radiative temper-
! ature tendencies, sw surface fluxes, lw surface fluxes and the
! value of the cosine of the zenith angle to be used for the next
! ocean albedo calcuation, in restart versions after version 1. for
! restart version 1, set the cosine of the zenith angle to the value
! used on initialization for use in diagnostics. since in this case
! rad_alarm has been set so that radiation is called on the next
! step, the proper zenith angles will be calculated and then used to
! define the albedos.
!---------------------------------------------------------------------
call read_data (unit, Rad_output%tdt_rad )
if (vers >= 4) then
call read_data (unit, Rad_output%tdtlw )
else
Rad_output%tdtlw = 0.0
endif
call read_data (unit, Rad_output%flux_sw_surf )
if (vers == 7) then
call read_data (unit, dum_idjd )
rad_alarm = 1
if (mpp_pe() == mpp_root_pe() ) then
call error_mesg ('radiation_driver_mod', &
' radiation to be calculated on first step: restart file&
& is version 7, additional fields needed to run with &
¤t code', NOTE)
endif
endif
if (vers >= 8) then
call read_data (unit, Rad_output%flux_sw_surf_dir )
call read_data (unit, Rad_output%flux_sw_surf_dif )
call read_data (unit, Rad_output%flux_sw_down_vis_dir )
call read_data (unit, Rad_output%flux_sw_down_vis_dif )
call read_data (unit, Rad_output%flux_sw_down_total_dir )
call read_data (unit, Rad_output%flux_sw_down_total_dif )
call read_data (unit, Rad_output%flux_sw_vis )
call read_data (unit, Rad_output%flux_sw_vis_dir )
call read_data (unit, Rad_output%flux_sw_vis_dif )
else
! SUITABLE INITIALIZATION ??
Rad_output%flux_sw_surf_dir = 0.0
Rad_output%flux_sw_surf_dif = 0.0
Rad_output%flux_sw_down_vis_dir = 0.0
Rad_output%flux_sw_down_vis_dif = 0.0
Rad_output%flux_sw_down_total_dir = 0.0
Rad_output%flux_sw_down_total_dif = 0.0
Rad_output%flux_sw_vis = 0.0
Rad_output%flux_sw_vis_dir = 0.0
Rad_output%flux_sw_vis_dif = 0.0
endif
call read_data (unit, Rad_output%flux_lw_surf )
if (vers /= 1) then
call read_data (unit, Rad_output%coszen_angle)
else
Rad_output%coszen_angle = coszen_angle_init
endif
!----------------------------------------------------------------------
! versions 3 and 4 include variables needed when sw renormalization
! is active, and logical variables indicating which additional fields
! are present.
!----------------------------------------------------------------------
if (vers == 3 .or. vers == 4) then
!---------------------------------------------------------------------
! determine if accumulation arrays are present in the restart file.
! if input fields are to be time-averaged, read the values from the
! files. note that avg_present and renorm_present cannot both be
! true.
!---------------------------------------------------------------------
read (unit) avg_present, renorm_present, cldfree_present
!---------------------------------------------------------------------
! if renormalize_sw_fluxes is true and the data is present in the
! restart file, read it.
!---------------------------------------------------------------------
if (renormalize_sw_fluxes) then
if (renorm_present) then
call read_data (unit, solar_save)
call read_data (unit, flux_sw_surf_save)
call read_data (unit, sw_heating_save)
call read_data (unit, tot_heating_save)
call read_data (unit, dfsw_save)
call read_data (unit, ufsw_save)
call read_data (unit, fsw_save)
call read_data (unit, hsw_save)
! if (vers >= 6) then
! call read_data (unit, swdn_trop_save)
! call read_data (unit, swup_trop_save)
! endif
!---------------------------------------------------------------------
! if cldfree data is desired and the data is present in the
! restart file, read it.
!---------------------------------------------------------------------
if (do_clear_sky_pass) then
if (cldfree_present) then
call read_data (unit, sw_heating_clr_save)
call read_data (unit, tot_heating_clr_save)
call read_data (unit, dfswcf_save)
call read_data (unit, ufswcf_save)
call read_data (unit, fswcf_save)
call read_data (unit, hswcf_save)
! if (vers >= 6) then
! call read_data (unit, swdn_trop_clr_save)
! call read_data (unit, swup_trop_clr_save)
! endif
!--------------------------------------------------------------------
! if cldfree data is desired and the data is not present in the
! restart file, force a radiation call on next model step.
!---------------------------------------------------------------------
else
rad_alarm = 1
if (mpp_pe() == mpp_root_pe() ) then
call error_mesg ('radiation_driver_mod', &
' radiation to be calculated on first step: cloud-free &
&calculations are desired, but needed fluxes and heating &
&rates are notpresent in restart file', NOTE)
endif
endif ! (cldfree_present)
endif
!---------------------------------------------------------------------
! if renormalize_sw_fluxes is true and the data is not present in the
! restart file, force a radiation call on next model step.
!---------------------------------------------------------------------
else ! (renorm_present)
rad_alarm = 1
if (mpp_pe() == mpp_root_pe() ) then
call error_mesg ('radiation_driver_mod', &
' radiation to be calculated on first step: renormaliz&
&ation of sw fluxes is desired, but needed data is not &
&present in restart file', NOTE)
endif
endif ! (renorm_present)
endif ! (renormalize)
! else if (vers == 5) then
else if (vers >= 5) then
!---------------------------------------------------------------------
! determine if accumulation arrays are present in the restart file.
! if input fields are to be time-averaged, read the values from the
! files. note that avg_present and renorm_present cannot both be
! true.
!---------------------------------------------------------------------
read (unit) renorm_present, cldfree_present
!---------------------------------------------------------------------
! if renormalize_sw_fluxes is true and the data is present in the
! restart file, read it.
!---------------------------------------------------------------------
if (renormalize_sw_fluxes) then
if (renorm_present) then
call read_data (unit, solar_save)
call read_data (unit, flux_sw_surf_save)
if (vers == 7) then
call read_data (unit, dum_idjd )
endif
if (vers >= 8) then
call read_data (unit, flux_sw_surf_dir_save)
call read_data (unit, flux_sw_surf_dif_save)
call read_data (unit, flux_sw_down_vis_dir_save)
call read_data (unit, flux_sw_down_vis_dif_save)
call read_data (unit, flux_sw_down_total_dir_save)
call read_data (unit, flux_sw_down_total_dif_save)
call read_data (unit, flux_sw_vis_save)
call read_data (unit, flux_sw_vis_dir_save)
call read_data (unit, flux_sw_vis_dif_save)
else
!! SUITABLE INITIALIZATION ??
flux_sw_surf_dir_save =0.0
flux_sw_surf_dif_save =0.0
flux_sw_down_vis_dir_save =0.0
flux_sw_down_vis_dif_save =0.0
flux_sw_down_total_dir_save =0.0
flux_sw_down_total_dif_save =0.0
flux_sw_vis_save =0.0
flux_sw_vis_dir_save =0.0
flux_sw_vis_dif_save =0.0
endif
call read_data (unit, sw_heating_save)
call read_data (unit, tot_heating_save)
call read_data (unit, dfsw_save)
call read_data (unit, ufsw_save)
call read_data (unit, fsw_save)
call read_data (unit, hsw_save)
!---------------------------------------------------------------------
! if this is a pre-version 9 restart (other than version 6), then
! radiation must be called on the first step in order to define the
! troopause fluxes.
!---------------------------------------------------------------------
if ( (vers >= 9) .or. (vers == 6) ) then
call read_data (unit, swdn_special_save(:,:,:,1))
call read_data (unit, swup_special_save(:,:,:,1))
else
rad_alarm = 1
if (mpp_pe() == mpp_root_pe() ) then
call error_mesg ('radiation_driver_mod', &
' radiation to be calculated on first step: tropopause &
&fluxes diagnostics are desired, but needed data is not &
&present in restart file', NOTE)
endif
endif
!---------------------------------------------------------------------
! if cldfree data is desired and the data is present in the
! restart file, read it.
!---------------------------------------------------------------------
if (do_clear_sky_pass) then
if (cldfree_present) then
call read_data (unit, sw_heating_clr_save)
call read_data (unit, tot_heating_clr_save)
call read_data (unit, dfswcf_save)
call read_data (unit, ufswcf_save)
call read_data (unit, fswcf_save)
call read_data (unit, hswcf_save)
if (vers >= 10) then
call read_data (unit, flux_sw_down_total_dir_clr_save)
call read_data (unit, flux_sw_down_total_dif_clr_save)
else
flux_sw_down_total_dir_clr_save =0.0
flux_sw_down_total_dif_clr_save =0.0
endif
if (vers >= 11) then
call read_data (unit, flux_sw_down_vis_clr_save)
else
flux_sw_down_vis_clr_save =0.0
endif
!---------------------------------------------------------------------
! if this is a pre-version 9 restart (other than version 6), then
! radiation must be called on the first step in order to define the
! troopause fluxes.
!---------------------------------------------------------------------
if ( (vers >= 9) .or. (vers == 6) ) then
call read_data (unit, swdn_special_clr_save(:,:,:,1))
call read_data (unit, swup_special_clr_save(:,:,:,1))
else
rad_alarm = 1
if (mpp_pe() == mpp_root_pe() ) then
call error_mesg ('radiation_driver_mod', &
' radiation to be calculated on first step: tropopause &
&fluxes diagnostics are desired, but needed data is not &
&present in restart file', NOTE)
endif
endif
!--------------------------------------------------------------------
! if cldfree data is desired and the data is not present in the
! restart file, force a radiation call on next model step.
!---------------------------------------------------------------------
else
rad_alarm = 1
if (mpp_pe() == mpp_root_pe() ) then
call error_mesg ('radiation_driver_mod', &
' radiation to be calculated on first step: cloud-free &
&diagnostics are desired, but needed data is not &
&present in restart file', NOTE)
endif
endif ! (cldfree_present)
endif
!---------------------------------------------------------------------
! if renormalize_sw_fluxes is true and the data is not present in the
! restart file, force a radiation call on next model step.
!---------------------------------------------------------------------
else ! (renorm_present)
rad_alarm = 1
if (mpp_pe() == mpp_root_pe() ) then
call error_mesg ('radiation_driver_mod', &
' radiation to be calculated on first step: renormaliz&
&ation of sw fluxes is desired, but needed data is not &
&present in restart file', NOTE)
endif
endif ! (renorm_present)
endif ! (renormalize)
endif ! (vers == 3 or 4)
!--------------------------------------------------------------------
! close the unit used to read the .res file.
!--------------------------------------------------------------------
call close_file (unit)
!----------------------------------------------------------------------
! if all_step_diagnostics is active and rad_alarm is not 1, abort
! job with error message. all_step_diagnostics may only be activated
! when radiation is to be calculated on the first step of a job,
! unless additional arrays are added to the radiation restart file.
!----------------------------------------------------------------------
if (rad_alarm /= 1 .and. all_step_diagnostics) then
if (mpp_pe() == mpp_root_pe() ) then
call error_mesg ('radiation_driver_mod', &
'cannot set all_step_diagnostics to be .true. unless &
& starting job on step just prior to radiation call; &
&doing so will lead to non-reproducibility of restarts', &
FATAL)
endif
endif
!----------------------------------------------------------------------
! adjust radiation alarm if radiation step has changed from restart
! file value, if it has not already been set to the first step.
!----------------------------------------------------------------------
if (rad_alarm /= 1) then
! if (rad_alarm == 1) then
! if (mpp_pe() == mpp_root_pe() ) then
! call error_mesg ('radiation_driver_mod', &
! 'radiation will be called on first step of run', NOTE)
! endif
! else
if (rad_time_step /= old_time_step ) then
new_rad_time = rad_alarm - old_time_step + rad_time_step
if ( new_rad_time > 0 ) then
if (mpp_pe() == mpp_root_pe() ) then
print *, 'radiation time step has changed, therefore '//&
'next time to next do radiation also changed; &
&new rad_alarm is', new_rad_time
endif
rad_alarm = new_rad_time
else
rad_alarm = 1
if (mpp_pe() == mpp_root_pe() ) then
call error_mesg ('radiation_driver_mod', &
' radiation to be calculated on first step: radiation &
×tep has gotten shorter and is past due', NOTE)
endif
endif
endif
endif ! (rad_alarm == 1)
lwrad_alarm = rad_alarm
swrad_alarm = rad_alarm
!--------------------------------------------------------------------
end subroutine read_restart_file
!#####################################################################
subroutine rad_driver_register_restart(fname)
character(len=*), intent(in) :: fname
character(len=64) :: fname2
integer :: id_restart
call get_mosaic_tile_file(fname, fname2, .false. )
allocate(Rad_restart)
if(trim(fname2) == trim(fname)) then
Til_restart => Rad_restart
in_different_file = .false.
else
in_different_file = .true.
allocate(Til_restart)
endif
id_restart = register_restart_field(Rad_restart, fname, 'vers', vers)
id_restart = register_restart_field(Rad_restart, fname, 'lwrad_alarm', lwrad_alarm, mandatory=.false.)
id_restart = register_restart_field(Rad_restart, fname, 'swrad_alarm', swrad_alarm, mandatory=.false.)
id_restart = register_restart_field(Rad_restart, fname, 'lw_rad_time_step', lw_rad_time_step, mandatory=.false.)
id_restart = register_restart_field(Rad_restart, fname, 'sw_rad_time_step', sw_rad_time_step, mandatory=.false.)
id_restart = register_restart_field(Til_restart, fname, 'tdt_rad', Rad_output%tdt_rad(:,:,:,1) )
id_restart = register_restart_field(Til_restart, fname, 'tdtlw', Rad_output%tdtlw)
id_restart = register_restart_field(Til_restart, fname, 'flux_sw_surf', Rad_output%flux_sw_surf)
id_restart = register_restart_field(Til_restart, fname, 'flux_sw_surf_dir', Rad_output%flux_sw_surf_dir)
id_restart = register_restart_field(Til_restart, fname, 'flux_sw_surf_dif', Rad_output%flux_sw_surf_dif)
id_restart = register_restart_field(Til_restart, fname, 'flux_sw_down_vis_dir', Rad_output%flux_sw_down_vis_dir)
id_restart = register_restart_field(Til_restart, fname, 'flux_sw_down_vis_dif', Rad_output%flux_sw_down_vis_dif)
id_restart = register_restart_field(Til_restart, fname, 'flux_sw_down_total_dir', Rad_output%flux_sw_down_total_dir)
id_restart = register_restart_field(Til_restart, fname, 'flux_sw_down_total_dif', Rad_output%flux_sw_down_total_dif)
id_restart = register_restart_field(Til_restart, fname, 'flux_sw_vis', Rad_output%flux_sw_vis)
id_restart = register_restart_field(Til_restart, fname, 'flux_sw_vis_dir', Rad_output%flux_sw_vis_dir)
id_restart = register_restart_field(Til_restart, fname, 'flux_sw_vis_dif', Rad_output%flux_sw_vis_dif)
id_restart = register_restart_field(Til_restart, fname, 'flux_lw_surf', Rad_output%flux_lw_surf)
id_restart = register_restart_field(Til_restart, fname, 'coszen_angle', Rad_output%coszen_angle)
id_restart = register_restart_field(Rad_restart, fname, 'renormalize_sw_fluxes', int_renormalize_sw_fluxes)
id_restart = register_restart_field(Rad_restart, fname, 'do_clear_sky_pass', int_do_clear_sky_pass)
if (renormalize_sw_fluxes ) then
id_restart = register_restart_field(Til_restart, fname, 'solar_save', solar_save)
id_restart = register_restart_field(Til_restart, fname, 'flux_sw_surf_save', flux_sw_surf_save)
id_restart = register_restart_field(Til_restart, fname, 'flux_sw_surf_dir_save', flux_sw_surf_dir_save)
id_restart = register_restart_field(Til_restart, fname, 'flux_sw_surf_dif_save', flux_sw_surf_dif_save)
id_restart = register_restart_field(Til_restart, fname, 'flux_sw_down_vis_dir_save', flux_sw_down_vis_dir_save)
id_restart = register_restart_field(Til_restart, fname, 'flux_sw_down_vis_dif_save', flux_sw_down_vis_dif_save)
id_restart = register_restart_field(Til_restart, fname, 'flux_sw_down_total_dir_save', flux_sw_down_total_dir_save)
id_restart = register_restart_field(Til_restart, fname, 'flux_sw_down_total_dif_save', flux_sw_down_total_dif_save)
id_restart = register_restart_field(Til_restart, fname, 'flux_sw_vis_save', flux_sw_vis_save)
id_restart = register_restart_field(Til_restart, fname, 'flux_sw_vis_dir_save', flux_sw_vis_dir_save)
id_restart = register_restart_field(Til_restart, fname, 'flux_sw_vis_dif_save', flux_sw_vis_dif_save)
id_restart = register_restart_field(Til_restart, fname, 'sw_heating_save', sw_heating_save(:,:,:,1))
id_restart = register_restart_field(Til_restart, fname, 'tot_heating_save', tot_heating_save(:,:,:,1))
id_restart = register_restart_field(Til_restart, fname, 'dfsw_save', dfsw_save(:,:,:,1))
id_restart = register_restart_field(Til_restart, fname, 'ufsw_save', ufsw_save(:,:,:,1))
id_restart = register_restart_field(Til_restart, fname, 'fsw_save', fsw_save(:,:,:,1))
id_restart = register_restart_field(Til_restart, fname, 'hsw_save', hsw_save(:,:,:,1))
id_restart = register_restart_field(Til_restart, fname, 'swdn_special_save', swdn_special_save(:,:,:,1))
id_restart = register_restart_field(Til_restart, fname, 'swup_special_save', swup_special_save(:,:,:,1))
if (do_clear_sky_pass) then
id_restart = register_restart_field(Til_restart, fname, 'sw_heating_clr_save', sw_heating_clr_save(:,:,:,1))
id_restart = register_restart_field(Til_restart, fname, 'tot_heating_clr_save', tot_heating_clr_save(:,:,:,1))
id_restart = register_restart_field(Til_restart, fname, 'dfswcf_save', dfswcf_save(:,:,:,1))
id_restart = register_restart_field(Til_restart, fname, 'ufswcf_save', ufswcf_save(:,:,:,1))
id_restart = register_restart_field(Til_restart, fname, 'fswcf_save', fswcf_save(:,:,:,1))
id_restart = register_restart_field(Til_restart, fname, 'hswcf_save', hswcf_save(:,:,:,1))
id_restart = register_restart_field(Til_restart, fname, 'flux_sw_down_total_dir_clr_save', &
flux_sw_down_total_dir_clr_save(:,:,1))
id_restart = register_restart_field(Til_restart, fname, 'flux_sw_down_total_dif_clr_save', &
flux_sw_down_total_dif_clr_save(:,:,1))
id_restart = register_restart_field(Til_restart, fname, 'flux_sw_down_vis_clr_save', &
flux_sw_down_vis_clr_save(:,:,1))
id_restart = register_restart_field(Til_restart, fname, 'swdn_special_clr_save', swdn_special_clr_save(:,:,:,1))
id_restart = register_restart_field(Til_restart, fname, 'swup_special_clr_save', swup_special_clr_save(:,:,:,1))
endif
endif
end subroutine rad_driver_register_restart
!#####################################################################
!
!
! read_restart_nc reads a netcdf restart file containing radiation
! restart information.
!
!
! read_restart_nc reads a netcdf restart file containing radiation
! restart information.
!
!
! call read_restart_nc
!
!
!
subroutine read_restart_nc
character(len=64) :: fname='INPUT/radiation_driver.res.nc'
real :: flag1, flag2
logical :: renorm_present, cldfree_present
integer :: new_rad_time, old_time_step
integer :: lw_old_time_step, sw_old_time_step
logical :: field_found
integer, dimension(4) :: siz
!----------------------------------------------------------------------
! when running in gcm, read a restart file. this is not done in the
! standalone case.
!---------------------------------------------------------------------
if (mpp_pe() == mpp_root_pe() ) then
call error_mesg('radiation_driver_mod', 'Reading netCDF formatted restart file: INPUT/radiation_driver.res.nc', NOTE)
endif
call read_data(fname, 'vers', vers, no_domain=.true.)
!--------------------------------------------------------------------
if (field_exist (fname, 'rad_alarm')) then
call read_data(fname, 'rad_alarm', lwrad_alarm, no_domain=.true.)
call read_data(fname, 'rad_alarm', swrad_alarm, no_domain=.true.)
else
call read_data(fname, 'lwrad_alarm', lwrad_alarm, no_domain=.true.)
call read_data(fname, 'swrad_alarm', swrad_alarm, no_domain=.true.)
endif
!--------------------------------------------------------------------
if (field_exist (fname, 'rad_time_step')) then
call read_data(fname, 'rad_time_step', lw_old_time_step, no_domain=.true.)
call read_data(fname, 'rad_time_step', sw_old_time_step, no_domain=.true.)
else
call read_data(fname, 'sw_rad_time_step', sw_old_time_step, no_domain=.true.)
call read_data(fname, 'lw_rad_time_step', lw_old_time_step, no_domain=.true.)
endif
call read_data(fname, 'renormalize_sw_fluxes', flag1, no_domain=.true.)
call read_data(fname, 'do_clear_sky_pass', flag2, no_domain=.true.)
renorm_present = .false.
cldfree_present = .false.
if (flag1 == 1.0) then
renorm_present = .true.
else if (flag1 == 2.0) then
else if (flag1 == -2.0) then
if (.not. allow_nonrepro_across_restarts) then
call error_mesg ( 'radiation_driver/read_restart_nc', &
'the restart was written on a non-radiation step, so model&
& solution will NOT be independent of restart interval. If &
& you dont care about this, set nml variable &
&allow_nonrepro_across_restarts to .true. and resubmit; &
&if you do, contact developer so additional code may be &
&added to allow seamless restart, OR rerun last job segment &
& so that it is an integral number of rad_time_steps &
&long.', FATAL)
else
call error_mesg ( 'radiation_driver/read_restart_nc', &
'the restart was written on a non-radiation step, so model&
& solution will NOT be independent of restart interval. You &
& have chosen to proceed anyway by setting nml variable &
&allow_nonrepro_across_restarts to .true.', NOTE )
swrad_alarm = 1
lwrad_alarm = 1
endif
endif
if(flag2 .EQ. 1.0) cldfree_present = .true.
!---------------------------------------------------------------------
! read the restart data.
! currently this need not be done when hires_coszen = .true.
!---------------------------------------------------------------------
if (flag1 == 0.0 .or. flag1 == 1.0) then
call read_data (fname, 'tdt_rad', Rad_output%tdt_rad(:,:,:,1))
call read_data (fname, 'tdtlw', Rad_output%tdtlw)
call read_data (fname, 'flux_sw_surf', Rad_output%flux_sw_surf(:,:,1))
call read_data (fname, 'flux_sw_surf_dir', Rad_output%flux_sw_surf_dir(:,:,1))
call read_data (fname, 'flux_sw_surf_dif', Rad_output%flux_sw_surf_dif(:,:,1))
call read_data (fname, 'flux_sw_down_vis_dir', Rad_output%flux_sw_down_vis_dir(:,:,1))
call read_data (fname, 'flux_sw_down_vis_dif', Rad_output%flux_sw_down_vis_dif(:,:,1))
call read_data (fname, 'flux_sw_down_total_dir', Rad_output%flux_sw_down_total_dir(:,:,1))
call read_data (fname, 'flux_sw_down_total_dif', Rad_output%flux_sw_down_total_dif(:,:,1))
call read_data (fname, 'flux_sw_vis', Rad_output%flux_sw_vis(:,:,1))
call read_data (fname, 'flux_sw_vis_dir', Rad_output%flux_sw_vis_dir(:,:,1))
call read_data (fname, 'flux_sw_vis_dif', Rad_output%flux_sw_vis_dif(:,:,1))
call read_data (fname, 'flux_lw_surf', Rad_output%flux_lw_surf)
call read_data (fname, 'coszen_angle', Rad_output%coszen_angle)
endif
!---------------------------------------------------------------------
! read the optional shortwave renormalization data.
!---------------------------------------------------------------------
if (renormalize_sw_fluxes ) then
if(renorm_present) then
call read_data (fname, 'solar_save', solar_save)
call read_data (fname, 'flux_sw_surf_save', flux_sw_surf_save(:,:,1))
call read_data (fname, 'flux_sw_surf_dir_save', flux_sw_surf_dir_save(:,:,1))
call read_data (fname, 'flux_sw_surf_dif_save', flux_sw_surf_dif_save(:,:,1))
call read_data (fname, 'flux_sw_down_vis_dir_save', flux_sw_down_vis_dir_save(:,:,1))
call read_data (fname, 'flux_sw_down_vis_dif_save', flux_sw_down_vis_dif_save(:,:,1))
call read_data (fname, 'flux_sw_down_total_dir_save', flux_sw_down_total_dir_save(:,:,1))
call read_data (fname, 'flux_sw_down_total_dif_save', flux_sw_down_total_dif_save(:,:,1))
call read_data (fname, 'flux_sw_vis_save', flux_sw_vis_save(:,:,1))
call read_data (fname, 'flux_sw_vis_dir_save', flux_sw_vis_dir_save(:,:,1))
call read_data (fname, 'flux_sw_vis_dif_save', flux_sw_vis_dif_save(:,:,1))
call read_data (fname, 'sw_heating_save', sw_heating_save(:,:,:,1))
call read_data (fname, 'tot_heating_save', tot_heating_save(:,:,:,1))
call read_data (fname, 'dfsw_save', dfsw_save(:,:,:,1))
call read_data (fname, 'ufsw_save', ufsw_save(:,:,:,1))
call read_data (fname, 'fsw_save', fsw_save(:,:,:,1))
call read_data (fname, 'hsw_save', hsw_save(:,:,:,1))
call read_data (fname, 'swdn_special_save', swdn_special_save(:,:,:,1))
call read_data (fname, 'swup_special_save', swup_special_save(:,:,:,1))
if (do_clear_sky_pass) then
if(cldfree_present) then
call read_data (fname, 'sw_heating_clr_save', sw_heating_clr_save(:,:,:,1))
call read_data (fname, 'tot_heating_clr_save', tot_heating_clr_save(:,:,:,1))
call read_data (fname, 'dfswcf_save', dfswcf_save(:,:,:,1))
call read_data (fname, 'ufswcf_save', ufswcf_save(:,:,:,1))
call read_data (fname, 'fswcf_save', fswcf_save(:,:,:,1))
call read_data (fname, 'hswcf_save', hswcf_save(:,:,:,1))
if (vers >= 10) then
call read_data (fname, 'flux_sw_down_total_dir_clr_save', flux_sw_down_total_dir_clr_save(:,:,1))
call read_data (fname, 'flux_sw_down_total_dif_clr_save', flux_sw_down_total_dif_clr_save(:,:,1))
else
flux_sw_down_total_dir_clr_save = 0.0
flux_sw_down_total_dif_clr_save = 0.0
endif
if (vers >= 11) then
call read_data (fname, 'flux_sw_down_vis_clr_save', flux_sw_down_vis_clr_save(:,:,1))
else
flux_sw_down_vis_clr_save = 0.0
endif
call read_data (fname, 'swdn_special_clr_save', swdn_special_clr_save(:,:,:,1))
call read_data (fname, 'swup_special_clr_save', swup_special_clr_save(:,:,:,1))
endif
endif
endif ! (do_clear_sky_pass)
endif ! (renormalize_sw_fluxes)
!----------------------------------------------------------------------
! if all_step_diagnostics is active and rad_alarm is not 1, abort
! job with error message. all_step_diagnostics may only be activated
! when radiation is to be calculated on the first step of a job,
! unless additional arrays are added to the radiation restart file.
!----------------------------------------------------------------------
if (lwrad_alarm /= 1 .and. all_step_diagnostics) then
if (mpp_pe() == mpp_root_pe() ) then
call error_mesg ('radiation_driver_mod', &
'cannot set all_step_diagnostics to be .true. unless &
& starting job on step just prior to radiation call; &
&doing so will lead to non-reproducibility of restarts', &
FATAL)
endif
endif
if (swrad_alarm /= 1 .and. all_step_diagnostics) then
if (mpp_pe() == mpp_root_pe() ) then
call error_mesg ('radiation_driver_mod', &
'cannot set all_step_diagnostics to be .true. unless &
& starting job on step just prior to radiation call; &
&doing so will lead to non-reproducibility of restarts', &
FATAL)
endif
endif
if (lwrad_alarm /= 1 .and. &
(do_lwaerosol_forcing .or. do_swaerosol_forcing)) then
if (mpp_pe() == mpp_root_pe() ) then
call error_mesg ('radiation_driver_mod', &
'aerosol forcing diagnostics will only be strictly valid &
&when restarting a job on the step just prior to radiation&
&call; not doing so will lead to invalid diagnostics between time&
& of restart and next radiation calculation, since these fields &
&are not saved in the restart file', FATAL)
endif
endif
if (swrad_alarm /= 1 .and. &
(do_lwaerosol_forcing .or. do_swaerosol_forcing)) then
if (mpp_pe() == mpp_root_pe() ) then
call error_mesg ('radiation_driver_mod', &
'aerosol forcing diagnostics will only be strictly valid &
&when restarting a job on the step just prior to radiation&
&call; not doing so will lead to invalid diagnostics between time&
& of restart and next radiation calculation, since these fields &
&are not saved in the restart file', FATAL)
endif
endif
!----------------------------------------------------------------------
! adjust radiation alarm if radiation step has changed from restart
! file value, if it has not already been set to the first step.
!----------------------------------------------------------------------
if (lwrad_alarm /= 1) then
! if (rad_alarm == 1) then
! if (mpp_pe() == mpp_root_pe() ) then
! call error_mesg ('radiation_driver_mod', &
! 'radiation will be called on first step of run', NOTE)
! endif
! else
if (rad_time_step /= lw_old_time_step ) then
new_rad_time = lwrad_alarm - lw_old_time_step + lw_rad_time_step
if ( new_rad_time > 0 ) then
if (mpp_pe() == mpp_root_pe() ) then
print *, 'radiation time step has changed, therefore '//&
'next time to next do lw radiation also changed; &
&new lwrad_alarm is', new_rad_time
endif
lwrad_alarm = new_rad_time
else
lwrad_alarm = 1
if (mpp_pe() == mpp_root_pe() ) then
call error_mesg ('radiation_driver_mod', &
' radiation to be calculated on first step: lw radiation &
×tep has gotten shorter and is past due', NOTE)
endif
endif
endif
endif ! (lwrad_alarm == 1)
if (swrad_alarm /= 1) then
! if (rad_alarm == 1) then
! if (mpp_pe() == mpp_root_pe() ) then
! call error_mesg ('radiation_driver_mod', &
! 'radiation will be called on first step of run', NOTE)
! endif
! else
if (sw_rad_time_step /= sw_old_time_step ) then
new_rad_time = swrad_alarm - sw_old_time_step + sw_rad_time_step
if ( new_rad_time > 0 ) then
if (mpp_pe() == mpp_root_pe() ) then
print *, 'radiation time step has changed, therefore '//&
'next time to next do sw radiation also changed; &
&new swrad_alarm is', new_rad_time
endif
swrad_alarm = new_rad_time
else
swrad_alarm = 1
if (mpp_pe() == mpp_root_pe() ) then
call error_mesg ('radiation_driver_mod', &
' radiation to be calculated on first step: sw radiation &
×tep has gotten shorter and is past due', NOTE)
endif
endif
endif
endif ! (swrad_alarm == 1)
vers = restart_versions(size(restart_versions(:)))
end subroutine read_restart_nc
!#####################################################################
!
!
! initialize_diagnostic_integrals registers the desired integrals
! with diag_integral_mod.
!
!
! initialize_diagnostic_integrals registers the desired integrals
! with diag_integral_mod.
!
!
! call initialize_diagnostic_integrals
!
!
!
subroutine initialize_diagnostic_integrals
!---------------------------------------------------------------------
! initialize_diagnostic_integrals registers the desired integrals
! with diag_integral_mod.
!---------------------------------------------------------------------
!----------------------------------------------------------------------
! initialize standard global quantities for integral package.
!----------------------------------------------------------------------
call diag_integral_field_init ('olr', std_digits)
call diag_integral_field_init ('abs_sw', std_digits)
! call diag_integral_field_init ('olr_clr', std_digits)
! call diag_integral_field_init ('abs_sw_clr', std_digits)
!----------------------------------------------------------------------
! if hemispheric integrals and global integrals with extended signif-
! icance are desired, inform diag_integrals_mod.
!----------------------------------------------------------------------
if (calc_hemi_integrals) then
call diag_integral_field_init ('sntop_tot_sh', extra_digits)
call diag_integral_field_init ('lwtop_tot_sh', extra_digits)
call diag_integral_field_init ('sngrd_tot_sh', extra_digits)
call diag_integral_field_init ('lwgrd_tot_sh', extra_digits)
call diag_integral_field_init ('sntop_tot_nh', extra_digits)
call diag_integral_field_init ('lwtop_tot_nh', extra_digits)
call diag_integral_field_init ('sngrd_tot_nh', extra_digits)
call diag_integral_field_init ('lwgrd_tot_nh', extra_digits)
call diag_integral_field_init ('sntop_tot_gl', extra_digits)
call diag_integral_field_init ('lwtop_tot_gl', extra_digits)
call diag_integral_field_init ('sngrd_tot_gl', extra_digits)
call diag_integral_field_init ('lwgrd_tot_gl', extra_digits)
!---------------------------------------------------------------------
! if clear-sky integrals are desired, include them.
!---------------------------------------------------------------------
if (do_clear_sky_pass) then
call diag_integral_field_init ('sntop_clr_sh', extra_digits)
call diag_integral_field_init ('lwtop_clr_sh', extra_digits)
call diag_integral_field_init ('sngrd_clr_sh', extra_digits)
call diag_integral_field_init ('lwgrd_clr_sh', extra_digits)
call diag_integral_field_init ('sntop_clr_nh', extra_digits)
call diag_integral_field_init ('lwtop_clr_nh', extra_digits)
call diag_integral_field_init ('sngrd_clr_nh', extra_digits)
call diag_integral_field_init ('lwgrd_clr_nh', extra_digits)
call diag_integral_field_init ('sntop_clr_gl', extra_digits)
call diag_integral_field_init ('lwtop_clr_gl', extra_digits)
call diag_integral_field_init ('sngrd_clr_gl', extra_digits)
call diag_integral_field_init ('lwgrd_clr_gl', extra_digits)
endif
endif
!--------------------------------------------------------------------
end subroutine initialize_diagnostic_integrals
!#######################################################################
!
!
! diag_field_init registers the desired diagnostic fields with the
! diagnostics manager.
!
!
! diag_field_init registers the desired diagnostic fields with the
! diagnostics manager.
!
!
! call diag_field_init ( Time, axes )
!
!
! Current time
!
!
! diagnostic variable axes for netcdf files
!
!
!
subroutine diag_field_init ( Time, axes )
!---------------------------------------------------------------------
! diag_field_init registers the desired diagnostic fields with the
! diagnostics manager.
!---------------------------------------------------------------------
type(time_type), intent(in) :: Time
integer , intent(in) :: axes(4)
!--------------------------------------------------------------------
! intent(in) variables
!
! Time current time
! axes data axes for use with diagnostic fields
!
!---------------------------------------------------------------------
!--------------------------------------------------------------------
! local variables
character(len=8) :: clr
character(len=16) :: clr2, lwaer_prep, swaer_prep
integer :: bxes(4)
integer :: i, n
!--------------------------------------------------------------------
! local variables:
!
! clr character string used in netcdf variable short name
! clr2 character string used in netcdf variable long name
! n number of passes through name generation loop
! i do-loop index
!
!--------------------------------------------------------------------
!-------------------------------------------------------------------
! define variable axis array with elements (1:3) valid for variables
! defined at flux levels.
!-------------------------------------------------------------------
bxes(1:2) = axes(1:2)
bxes(3) = axes(4)
bxes(4) = axes(4)
!---------------------------------------------------------------------
! determine how many passes are needed through the name generation
! loop.
!---------------------------------------------------------------------
if (do_clear_sky_pass) then
n= 2
else
n= 1
endif
if (Sw_control%do_swaerosol ) then
swaer_prep = 'without'
else
swaer_prep = 'with'
endif
if (Lw_control%do_lwaerosol ) then
lwaer_prep = 'without'
else
lwaer_prep = 'with'
endif
!---------------------------------------------------------------------
! generate names for standard and clear sky diagnostic fields. if
! clear sky values being generated, generate the clear sky names
! on pass 1, followed by the standard names.
!---------------------------------------------------------------------
do i = 1, n
if ( i == n) then
clr = " "
clr2 = " "
else
clr = "_clr"
clr2 = "clear sky "
endif
id_swdn_special(1,i) = register_diag_field (mod_name, &
'swdn_200hPa'//trim(clr), axes(1:2), Time, &
trim(clr2)//'SW flux down at 200 hPa', &
'watts/m2', missing_value=missing_value)
id_swdn_special(2,i) = register_diag_field (mod_name, &
'swdn_lin_trop'//trim(clr), axes(1:2), Time, &
trim(clr2)//'SW flux down at linear tropopause', &
'watts/m2', missing_value=missing_value)
id_swdn_special(3,i) = register_diag_field (mod_name, &
'swdn_therm_trop'//trim(clr), axes(1:2), Time, &
trim(clr2)//'SW flux down at thermo tropopause', &
'watts/m2', missing_value=missing_value)
id_swdn_special(4,i) = register_diag_field (mod_name, &
'swdn_1_Pa'//trim(clr), axes(1:2), Time, &
trim(clr2)//'SW flux down at 1 Pa', &
'watts/m2', missing_value=missing_value)
id_swup_special(1,i) = register_diag_field (mod_name, &
'swup_200hPa'//trim(clr), axes(1:2), Time, &
trim(clr2)//'SW flux up at 200 hPa', &
'watts/m2', missing_value=missing_value)
id_swup_special(2,i) = register_diag_field (mod_name, &
'swup_lin_trop'//trim(clr), axes(1:2), Time, &
trim(clr2)//'SW flux up at linear tropopause', &
'watts/m2', missing_value=missing_value)
id_swup_special(3,i) = register_diag_field (mod_name, &
'swup_therm_trop'//trim(clr), axes(1:2), Time, &
trim(clr2)//'SW flux up at thermo tropopause', &
'watts/m2', missing_value=missing_value)
id_swup_special(4,i) = register_diag_field (mod_name, &
'swup_1_Pa'//trim(clr), axes(1:2), Time, &
trim(clr2)//'SW flux up at 1 Pa', &
'watts/m2', missing_value=missing_value)
id_netlw_special(1,i) = register_diag_field (mod_name, &
'netlw_200hPa'//trim(clr), axes(1:2), Time, &
trim(clr2)//'net LW flux at 200 hPa', &
'watts/m2', missing_value=missing_value)
id_netlw_special(2,i) = register_diag_field (mod_name, &
'netlw_lin_trop'//trim(clr), axes(1:2), Time, &
trim(clr2)//'net LW flux at linear tropopause', &
'watts/m2', missing_value=missing_value)
id_netlw_special(3,i) = register_diag_field (mod_name, &
'netlw_therm_trop'//trim(clr), axes(1:2), Time, &
trim(clr2)//'net LW flux at thermo tropopause', &
'watts/m2', missing_value=missing_value)
id_netlw_special(4,i) = register_diag_field (mod_name, &
'netlw_1_Pa'//trim(clr), axes(1:2), Time, &
trim(clr2)//'net LW flux at 1 Pa', &
'watts/m2', missing_value=missing_value)
id_tdt_sw(i) = register_diag_field (mod_name, &
'tdt_sw'//trim(clr), axes(1:3), Time, &
trim(clr2)//'temperature tendency for SW radiation', &
'deg_K/sec', missing_value=missing_value)
id_ufsw(i) = register_diag_field (mod_name, &
'allufsw'//trim(clr), bxes(1:3), Time, &
trim(clr2)//'upward sw flux', &
'watts/m2', missing_value=missing_value)
id_dfsw(i) = register_diag_field (mod_name, &
'alldfsw'//trim(clr), bxes(1:3), Time, &
trim(clr2)//'downward sw flux', &
'watts/m2', missing_value=missing_value)
id_flxnet(i) = register_diag_field (mod_name, &
'allnetlw'//trim(clr), bxes(1:3), Time, &
trim(clr2)//'net lw flux', &
'watts/m2', missing_value=missing_value)
id_tdt_lw(i) = register_diag_field (mod_name, &
'tdt_lw'//trim(clr), axes(1:3), Time, &
trim(clr2)//'temperature tendency for LW radiation', &
'deg_K/sec', missing_value=missing_value)
id_swdn_toa(i) = register_diag_field (mod_name, &
'swdn_toa'//trim(clr), axes(1:2), Time, &
trim(clr2)//'SW flux down at TOA', &
'watts/m2', missing_value=missing_value)
id_swup_toa(i) = register_diag_field (mod_name, &
'swup_toa'//trim(clr), axes(1:2), Time, &
trim(clr2)//'SW flux up at TOA', &
'watts/m2', missing_value=missing_value)
id_olr(i) = register_diag_field (mod_name, &
'olr'//trim(clr), axes(1:2), Time, &
trim(clr2)//'outgoing longwave radiation', &
'watts/m2', missing_value=missing_value)
id_netrad_toa(i) = register_diag_field (mod_name, &
'netrad_toa'//trim(clr), axes(1:2), Time, &
trim(clr2)//'net radiation (lw + sw) at toa', &
'watts/m2', missing_value=missing_value)
id_netrad_1_Pa(i) = register_diag_field (mod_name, &
'netrad_1_Pa'//trim(clr), axes(1:2), Time, &
trim(clr2)//'net radiation (lw + sw) at 1 Pa', &
'watts/m2', missing_value=missing_value)
id_swup_sfc(i) = register_diag_field (mod_name, &
'swup_sfc'//trim(clr), axes(1:2), Time, &
trim(clr2)//'SW flux up at surface', &
'watts/m2', missing_value=missing_value)
id_swdn_sfc(i) = register_diag_field (mod_name, &
'swdn_sfc'//trim(clr), axes(1:2), Time, &
trim(clr2)//'SW flux down at surface', &
'watts/m2', missing_value=missing_value)
id_lwup_sfc(i) = register_diag_field (mod_name, &
'lwup_sfc'//trim(clr), axes(1:2), Time, &
trim(clr2)//'LW flux up at surface', &
'watts/m2', missing_value=missing_value)
id_lwdn_sfc(i) = register_diag_field (mod_name, &
'lwdn_sfc'//trim(clr), axes(1:2), Time, &
trim(clr2)//'LW flux down at surface', &
'watts/m2', missing_value=missing_value)
id_swtoa(i) = register_diag_field (mod_name, &
'swtoa'//trim(clr), axes(1:2), Time, &
trim(clr2)//' Net SW flux at TOA ', &
'watts/m2', missing_value=missing_value)
id_swsfc(i) = register_diag_field (mod_name, &
'swsfc'//trim(clr), axes(1:2), Time, &
trim(clr2)//' Net SW flux at surface', &
'watts/m2', missing_value=missing_value)
id_lwsfc(i) = register_diag_field (mod_name, &
'lwsfc'//trim(clr), axes(1:2), Time, &
trim(clr2)//' Net LW flux at surface', &
'watts/m2', missing_value=missing_value)
id_swtoa_ad(i) = register_diag_field (mod_name, &
'swtoa_ad'//trim(clr), axes(1:2), Time, &
trim(clr2)//' Net SW flux at TOA '// trim(swaer_prep) &
// ' aerosol', &
'watts/m2', missing_value=missing_value)
id_swsfc_ad(i) = register_diag_field (mod_name, &
'swsfc_ad'//trim(clr), axes(1:2), Time, &
trim(clr2)//' Net SW flux at surface '// trim(swaer_prep) &
// ' aerosol', &
'watts/m2', missing_value=missing_value)
id_swdn_sfc_ad(i) = register_diag_field (mod_name, &
'swdn_sfc_ad'//trim(clr), axes(1:2), Time, &
trim(clr2)//' SW flux down at surface '// &
trim(swaer_prep) // ' aerosol', &
'watts/m2', missing_value=missing_value)
id_swup_sfc_ad(i) = register_diag_field (mod_name, &
'swup_sfc_ad'//trim(clr), axes(1:2), Time, &
trim(clr2)//' SW flux up at surface ' // &
trim(swaer_prep) // ' aerosol', &
'watts/m2', missing_value=missing_value)
id_swup_toa_ad(i) = register_diag_field (mod_name, &
'swup_toa_ad'//trim(clr), axes(1:2), Time, &
trim(clr2)//' SW flux up at TOA ' // &
trim(swaer_prep) // ' aerosol', &
'watts/m2', missing_value=missing_value)
id_olr_ad(i) = register_diag_field (mod_name, &
'lwtoa_ad'//trim(clr), axes(1:2), Time, &
trim(clr2)//' Net LW flux at TOA (olr) ' // &
trim(lwaer_prep) // ' aerosol', &
'watts/m2', missing_value=missing_value)
id_lwsfc_ad(i) = register_diag_field (mod_name, &
'lwsfc_ad'//trim(clr), axes(1:2), Time, &
trim(clr2)//' Net LW flux at surface ' // &
trim(lwaer_prep) // ' aerosol', &
'watts/m2', missing_value=missing_value)
end do
id_allradp = register_diag_field (mod_name, &
'allradp', axes(1:3), Time, &
'temperature tendency for SW + LW radiation', &
'deg_K/sec', missing_value=missing_value)
!----------------------------------------------------------------------
! register fields that are not clear-sky depedent.
!----------------------------------------------------------------------
id_conc_drop = register_diag_field (mod_name, &
'conc_drop', axes(1:3), Time, &
'drop concentration ', &
'g/m^3', missing_value=missing_value)
id_conc_ice = register_diag_field (mod_name, &
'conc_ice', axes(1:3), Time, &
'ice concentration ', &
'g/m^3', missing_value=missing_value)
id_flux_sw_dir = register_diag_field (mod_name, &
'flux_sw_dir', axes(1:2), Time, &
'net direct sfc sw flux', 'watts/m2', &
missing_value=missing_value)
id_flux_sw_dif = register_diag_field (mod_name, &
'flux_sw_dif', axes(1:2), Time, &
'net diffuse sfc sw flux', 'watts/m2', &
missing_value=missing_value)
id_flux_sw_down_vis_dir = register_diag_field (mod_name, &
'flux_sw_down_vis_dir', axes(1:2), Time, &
'downward direct visible sfc sw flux', 'watts/m2', &
missing_value=missing_value)
id_flux_sw_down_vis_dif = register_diag_field (mod_name, &
'flux_sw_down_vis_dif', axes(1:2), Time, &
'downward diffuse visible sfc sw flux', 'watts/m2', &
missing_value=missing_value)
id_flux_sw_down_total_dir = register_diag_field (mod_name, &
'flux_sw_down_total_dir', axes(1:2), Time, &
'downward direct total sfc sw flux', 'watts/m2', &
missing_value=missing_value)
id_flux_sw_down_total_dif = register_diag_field (mod_name, &
'flux_sw_down_total_dif', axes(1:2), Time, &
'downward diffuse total sfc sw flux', 'watts/m2', &
missing_value=missing_value)
if (do_clear_sky_pass) then
id_flux_sw_down_total_dir_clr = register_diag_field (mod_name, &
'flux_sw_down_total_dir_clr', axes(1:2), Time, &
'downward clearsky direct total sfc sw flux', &
'watts/m2', missing_value=missing_value)
id_flux_sw_down_total_dif_clr = register_diag_field (mod_name, &
'flux_sw_down_total_dif_clr', axes(1:2), Time, &
'downward clearsky diffuse total sfc sw flux', &
'watts/m2', missing_value=missing_value)
id_flux_sw_down_vis_clr = register_diag_field (mod_name, &
'flux_sw_down_vis_clr', axes(1:2), Time, &
'downward visible sfc sw flux clear sky', 'watts/m2', &
missing_value=missing_value)
endif
id_flux_sw_vis = register_diag_field (mod_name, &
'flux_sw_vis', axes(1:2), Time, &
'net visible sfc sw flux', 'watts/m2', &
missing_value=missing_value)
id_flux_sw_vis_dir = register_diag_field (mod_name, &
'flux_sw_vis_dir', axes(1:2), Time, &
'net direct visible sfc sw flux', 'watts/m2', &
missing_value=missing_value)
id_flux_sw_vis_dif = register_diag_field (mod_name, &
'flux_sw_vis_dif', axes(1:2), Time, &
'net diffuse visible sfc sw flux', 'watts/m2', &
missing_value=missing_value)
id_sol_con = register_diag_field (mod_name, &
'solar_constant', Time, &
'solar constant', 'watts/m2', &
missing_value=missing_value)
id_co2_tf = register_diag_field (mod_name, &
'co2_tf', Time, &
'co2 mixing ratio used for tf calculation', 'ppmv', &
missing_value=missing_value)
id_ch4_tf = register_diag_field (mod_name, &
'ch4_tf', Time, &
'ch4 mixing ratio used for tf calculation', 'ppbv', &
missing_value=missing_value)
id_n2o_tf = register_diag_field (mod_name, &
'n2o_tf', Time, &
'n2o mixing ratio used for tf calculation', 'ppbv', &
missing_value=missing_value)
id_rrvco2 = register_diag_field (mod_name, &
'rrvco2', Time, &
'co2 mixing ratio', 'ppmv', &
missing_value=missing_value)
id_rrvf11 = register_diag_field (mod_name, &
'rrvf11', Time, &
'f11 mixing ratio', 'pptv', &
missing_value=missing_value)
id_rrvf12 = register_diag_field (mod_name, &
'rrvf12', Time, &
'f12 mixing ratio', 'pptv', &
missing_value=missing_value)
id_rrvf113 = register_diag_field (mod_name, &
'rrvf113', Time, &
'f113 mixing ratio', 'pptv', &
missing_value=missing_value)
id_rrvf22 = register_diag_field (mod_name, &
'rrvf22', Time, &
'f22 mixing ratio', 'pptv', &
missing_value=missing_value)
id_rrvch4 = register_diag_field (mod_name, &
'rrvch4', Time, &
'ch4 mixing ratio', 'ppbv', &
missing_value=missing_value)
id_rrvn2o = register_diag_field (mod_name, &
'rrvn2o', Time, &
'n2o mixing ratio', 'ppbv', &
missing_value=missing_value)
id_alb_sfc_avg = register_diag_field (mod_name, &
'averaged_alb_sfc', axes(1:2), Time, &
'surface albedo', 'percent', &
missing_value=missing_value)
if (id_alb_sfc_avg > 0) then
allocate (swdns_acc(id,jd))
allocate (swups_acc(id,jd))
swups_acc = 0.0
swdns_acc = 1.0e-35
endif
id_alb_sfc = register_diag_field (mod_name, &
'alb_sfc', axes(1:2), Time, &
'surface albedo', 'percent', &
missing_value=missing_value)
id_alb_sfc_vis_dir = register_diag_field (mod_name, &
'alb_sfc_vis_dir', axes(1:2), Time, &
! 'surface albedo_vis_dir', 'percent')
! BUGFIX
'surface albedo_vis_dir', 'percent', &
missing_value=missing_value)
id_alb_sfc_nir_dir = register_diag_field (mod_name, &
'alb_sfc_nir_dir', axes(1:2), Time, &
! 'surface albedo_nir', 'percent')
! BUGFIX
'surface albedo_nir_dir', 'percent', &
missing_value=missing_value)
id_alb_sfc_vis_dif = register_diag_field (mod_name, &
'alb_sfc_vis_dif', axes(1:2), Time, &
! 'surface albedo_vis', 'percent')
! BUGFIX
'surface albedo_vis_dif', 'percent', &
missing_value=missing_value)
id_alb_sfc_nir_dif = register_diag_field (mod_name, &
'alb_sfc_nir_dif', axes(1:2), Time, &
! 'surface albedo_nir', 'percent')
! BUGFIX
'surface albedo_nir_dif', 'percent', &
missing_value=missing_value)
id_cosz = register_diag_field (mod_name, &
'cosz',axes(1:2), Time, &
'cosine of zenith angle', &
'none', missing_value=missing_value)
id_fracday = register_diag_field (mod_name, &
'fracday',axes(1:2), Time, &
'daylight fraction of radiation timestep', &
'percent', missing_value=missing_value)
!-----------------------------------------------------------------------
end subroutine diag_field_init
!######################################################################
!
!
! obtain_astronomy_variables retrieves astronomical variables, valid
! at the requested time and over the requested time intervals.
!
!
! obtain_astronomy_variables retrieves astronomical variables, valid
! at the requested time and over the requested time intervals.
!
!
! call obtain_astronomy_variables (is, ie, js, je, lat, lon, &
! Astro, Astro2)
!
!
!
! starting/ending i,j indices in global storage arrays
!
!
! astronomy_type structure; It will
! be used to determine the insolation at toa seen
! by the shortwave radiation code
!
!
! astronomy_type structure, defined when renormal-
! ization is active. the same components are defined
! as for Astro, but they are valid over the current
! physics timestep.
!
!
! astronomy_inp_type structure, optionally used to input astronom-
! ical forcings, when it is desired to specify them rather than use
! astronomy_mod. Used in various standalone applications.
!
!
! lon mean longitude (in radians) of all grid boxes processed by
! this call to radiation_driver [real, dimension(:,:)]
!
!
! lat mean latitude (in radians) of all grid boxes processed by this
! call to radiation_driver [real, dimension(:,:)]
!
!
!
subroutine obtain_astronomy_variables (is, ie, js, je, lat, lon, &
Astro, Astro2, Astronomy_inp)
!---------------------------------------------------------------------
! obtain_astronomy_variables retrieves astronomical variables, valid
! at the requested time and over the requested time intervals.
!---------------------------------------------------------------------
integer, intent(in) :: is, ie, js, je
real, dimension(:,:), intent(in) :: lat, lon
type(astronomy_type), intent(inout) :: Astro, Astro2
type(astronomy_inp_type), intent(inout), optional :: &
Astronomy_inp
!---------------------------------------------------------------------
! intent(in) variables:
!
! is,ie,js,je starting/ending subdomain i,j indices of data in
! the physics_window being integrated
! lat latitude of model points
! [ radians ]
! lon longitude of model points
! [ radians ]
!
! intent(inout) variables:
!
! Astro astronomy_type structure; contains the following
! components defined in this subroutine that will
! be used to determine the insolation at toa seen
! by the shortwave radiation code
! solar shortwave flux factor: cosine of zenith angle *
! daylight fraction / (earth-sun distance squared)
! [ non-dimensional ]
! cosz cosine of zenith angle -- mean value over
! appropriate averaging interval
! [ non-dimensional ]
! fracday fraction of timestep during which the sun is
! shining
! [ non-dimensional ]
! rrsun inverse of square of earth-sun distance,
! relative to the mean square of earth-sun
! distance
! [ non-dimensional ]
!
! Astro2 astronomy_type structure, defined when renormal-
! ization is active. the same components are defined
! as for Astro, but they are valid over the current
! physics timestep.
!
!---------------------------------------------------------------------
!--------------------------------------------------------------------
! local variables:
type(time_type) :: Dt_zen, Dt_zen2
type(time_type) :: Rad1
real, dimension(ie-is+1, je-js+1) :: &
cosz_r, solar_r, fracday_r, &
cosz_p, solar_p, fracday_p, &
cosz_a, solar_a, fracday_a
real :: rrsun_r, rrsun_p, rrsun_a
integer :: nz
!--------------------------------------------------------------------
! local variables:
!
! Dt_zen time-type variable containing the components of the
! radiation time step, needed unless do_average is
! true or this is not a radiation step and renormal-
! ize_sw_fluxes is true
! Dt_zen2 time-type variable containing the components of the
! physics time step, needed when renormalize_sw_fluxes
! or do_average is true
! cosz_r cosine of zenith angle -- mean value over
! radiation time step
! [ non-dimensional ]
! solar_r shortwave flux factor relevant over radiation time
! step: cosine of zenith angle * daylight fraction /
! (earth-sun distance squared)
! [ non-dimensional ]
! fracday_r fraction of timestep during which the sun is
! shining over radiation time step
! [ non-dimensional ]
! cosz_p cosine of zenith angle -- mean value over
! physics time step
! [ non-dimensional ]
! solar_p shortwave flux factor relevant over physics time
! step: cosine of zenith angle * daylight fraction /
! (earth-sun distance squared)
! [ non-dimensional ]
! fracday_p fraction of timestep during which the sun is
! shining over physics time step
! [ non-dimensional ]
! cosz_a cosine of zenith angle -- mean value over
! next radiation time step
! [ non-dimensional ]
! solar_a shortwave flux factor relevant over next radiation
! time step: cosine of zenith angle * daylight
! fraction / (earth-sun distance squared)
! [ non-dimensional ]
! fracday_a fraction of timestep during which the sun is
! shining over next radiation time step
! [ non-dimensional ]
! rrsun_r inverse of square of earth-sun distance,
! relative to the mean square of earth-sun
! distance, valid over radiation time step
! [ non-dimensional ]
! rrsun_p inverse of square of earth-sun distance,
! relative to the mean square of earth-sun
! distance, valid over physics time step
! [ non-dimensional ]
! rrsun_a inverse of square of earth-sun distance,
! relative to the mean square of earth-sun
! distance, valid over next radiation time step
! [ non-dimensional ]
!
!---------------------------------------------------------------------
!---------------------------------------------------------------------
! allocate the components of the astronomy_type structure which will
! return the astronomical inputs to radiation (cosine of zenith
! angle, daylight fraction, solar flux factor and earth-sun distance)
! that are to be used on the current step.
!---------------------------------------------------------------------
allocate ( Astro%cosz (size(lat,1), size(lat,2) ) )
allocate ( Astro%fracday(size(lat,1), size(lat,2) ) )
allocate ( Astro%solar (size(lat,1), size(lat,2) ) )
allocate ( Astro%cosz_p (size(lat,1), size(lat,2), &
Rad_control%nzens) )
allocate ( Astro%fracday_p(size(lat,1), size(lat,2), &
Rad_control%nzens) )
allocate ( Astro%solar_p (size(lat,1), size(lat,2), &
Rad_control%nzens) )
!---------------------------------------------------------------------
! case 0: input parameters.
!---------------------------------------------------------------------
if (present (Astronomy_inp)) then
Astro%rrsun = Astronomy_inp%rrsun
Astro%fracday(:,:) = Astronomy_inp%fracday(is:ie,js:je)
Astro%cosz (:,:) = cos( &
Astronomy_inp%zenith_angle(is:ie,js:je)/RADIAN)
Astro%solar(:,:) = Astro%cosz(:,:)*Astro%fracday(:,:)* &
Astro%rrsun
Rad_output%coszen_angle(is:ie,js:je) = Astro%cosz(:,:)
do nz = 1, Rad_control%nzens
Astro%fracday_p(:,:,nz) = Astro%fracday(:,:)
Astro%cosz_p(:,:,nz) = Astro%cosz(:,:)
Astro%solar_p(:,:,nz) = Astro%solar(:,:)
end do
!---------------------------------------------------------------------
! case 1: diurnally-varying shortwave radiation.
!---------------------------------------------------------------------
else if (Sw_control%do_diurnal) then
!-------------------------------------------------------------------
! convert the radiation timestep and the model physics timestep
! to time_type variables.
!-------------------------------------------------------------------
Dt_zen = set_time (sw_rad_time_step, 0)
Dt_zen2 = set_time (dt, 0)
!---------------------------------------------------------------------
! calculate the astronomical factors averaged over the radiation time
! step between Rad_time and Rad_time + Dt_zen. these values are
! needed on radiation steps. output is stored in Astro_rad.
!---------------------------------------------------------------------
if (do_sw_rad) then
if (Rad_control%hires_coszen) then
Rad1 = Rad_time
do nz=1,Rad_control%nzens
call diurnal_solar (lat, lon, Rad1, cosz_r, &
fracday_r, rrsun_r, dt_time=Dt_zen2)
fracday_r = MIN (fracday_r, 1.00)
solar_r = cosz_r*fracday_r*rrsun_r
Astro%cosz_p(:,:,nz) = cosz_r
Astro%fracday_p(:,:,nz) = fracday_r
Astro%solar_p(:,:,nz) = solar_r
Rad1 = Rad1 + Dt_zen2
end do
endif
! calculation for full radiation step:
call diurnal_solar (lat, lon, Rad_time, cosz_r, fracday_r, &
rrsun_r, dt_time=Dt_zen)
fracday_r = MIN (fracday_r, 1.00)
solar_r = cosz_r*fracday_r*rrsun_r
endif
!---------------------------------------------------------------------
! calculate the astronomical factors averaged over the physics time
! step between Rad_time and Rad_time + Dt_zen2. these values are
! needed if either renormalization or time-averaging is active. store
! the astronomical outputs in Astro_phys.
!---------------------------------------------------------------------
if (renormalize_sw_fluxes) then
call diurnal_solar (lat, lon, Rad_time, cosz_p, fracday_p, &
rrsun_p, dt_time=Dt_zen2)
fracday_p = MIN (fracday_p, 1.00)
solar_p = cosz_p*fracday_p*rrsun_p
endif
!--------------------------------------------------------------------
! define the astronomy_type variable(s) to be returned and used in
! the radiation calculation. Astro contains the values to be used
! in the radiation calculation, Astro2 contains values relevant
! over the current physics timestep and is used for renormalization.
! when renormalization is active, the physics step set is always
! needed, and in addition on radiation steps, the radiation step
! values are needed.
!---------------------------------------------------------------------
if (renormalize_sw_fluxes) then
if (.not. do_sw_rad) then
Astro%cosz = cosz_p
Astro%fracday = fracday_p
Astro%solar = solar_p
Astro%rrsun = rrsun_p
else
Astro%cosz = cosz_r
Astro%fracday = fracday_r
Astro%solar = solar_r
Astro%rrsun = rrsun_r
allocate ( Astro2%fracday(size(lat,1), size(lat,2) ) )
allocate ( Astro2%cosz (size(lat,1), size(lat,2) ) )
allocate ( Astro2%solar (size(lat,1), size(lat,2) ) )
Astro2%cosz = cosz_p
Astro2%fracday = fracday_p
Astro2%solar = solar_p
Astro2%rrsun = rrsun_p
endif
!---------------------------------------------------------------------
! if renormalization is active, then only the values applicable over
! radiation steps are needed.
!---------------------------------------------------------------------
else
Astro%cosz = cosz_r
Astro%fracday = fracday_r
Astro%solar = solar_r
Astro%rrsun = rrsun_r
endif
!---------------------------------------------------------------------
! when in the gcm and on a radiation calculation step, define cosine
! of zenith angle valid over the next radiation step. this is needed
! so that the ocean albedo (function of zenith angle) may be properly
! defined and provided as input to the radiation package on the next
! timestep.
!----------------------------------------------------------------------
if (do_sw_rad) then
call diurnal_solar (lat, lon, Rad_time+Dt_zen, cosz_a, &
fracday_a, rrsun_a, dt_time=Dt_zen)
Rad_output%coszen_angle(is:ie,js:je) = cosz_a(:,:)
endif ! (do_sw_rad)
!---------------------------------------------------------------------
! case 2: annual-mean shortwave radiation.
!---------------------------------------------------------------------
else if (Sw_control%do_annual) then
call annual_mean_solar (js, je, lat, Astro%cosz, Astro%solar,&
Astro%fracday, Astro%rrsun)
!---------------------------------------------------------------------
! save the cosine of zenith angle on the current step to be used to
! calculate ocean albedo for use on the next radiation timestep.
!---------------------------------------------------------------------
Rad_output%coszen_angle(is:ie,js:je) = Astro%cosz(:,:)
!---------------------------------------------------------------------
! case 3: daily-mean shortwave radiation.
!---------------------------------------------------------------------
else if (Sw_control%do_daily_mean) then
call daily_mean_solar (lat, Rad_time, Astro%cosz, &
Astro%fracday, Astro%rrsun)
Astro%solar = Astro%cosz*Astro%rrsun*Astro%fracday
!---------------------------------------------------------------------
! save the cosine of zenith angle on the current step to be used to
! calculate ocean albedo for use on the next radiation timestep.
!---------------------------------------------------------------------
Rad_output%coszen_angle(is:ie,js:je) = Astro%cosz(:,:)
!----------------------------------------------------------------------
! if none of the above options are active, write an error message and
! stop execution.
!----------------------------------------------------------------------
else
call error_mesg('radiation_driver_mod', &
' no valid zenith angle specification', FATAL)
endif
!-------------------------------------------------------------------
end subroutine obtain_astronomy_variables
!####################################################################
!
!
! radiation_calc is called on radiation timesteps and calculates
! the long- and short-wave radiative fluxes and heating rates, and
! obtains the radiation output fields needed in other portions of
! the model.
!
!
! radiation_calc is called on radiation timesteps and calculates
! the long- and short-wave radiative fluxes and heating rates, and
! obtains the radiation output fields needed in other portions of
! the model.
!
!
! call radiation_calc (is, ie, js, je, Rad_time, Time_diag, &
! lat, lon, Atmos_input, Surface, Rad_gases, &
! Aerosol_props, Aerosol, r, Cldrad_props, &
! Cld_spec, Astro, Rad_output, Lw_output, &
! Sw_output, Fsrad_output, mask, kbot)
!
!
! starting/ending i,j indices in global storage arrays
!
!
! Rad_time time at which the radiative fluxes are to apply
! [ time_type (days, seconds) ]
!
!
! Time_diag time on next timestep, used as stamp for diag-
! nostic output [ time_type (days, seconds) ]
!
!
! lon mean longitude (in radians) of all grid boxes processed by
! this call to radiation_driver [real, dimension(:,:)]
!
!
! lat mean latitude (in radians) of all grid boxes processed by this
! call to radiation_driver [real, dimension(:,:)]
!
!
! Surface input data to radiation package
!
!
! Atmospheric input data to radiation package
!
!
! Aerosol climatological input data to radiation package
!
!
! Aerosol radiative properties
!
!
! Cloud radiative properties
!
!
! Cloud microphysical and physical parameters to radiation package,
! contains var-
! iables defining the cloud distribution, passed
! through to lower level routines
!
!
! astronomical input data for the radiation package
!
!
! Radiative gases properties to radiation package, , contains var-
! iables defining the radiatively active gases,
! passed through to lower level routines
!
!
! Radiation output from radiation package, contains variables
! which are output from radiation_driver to the
! calling routine, and then used elsewhere within
! the component models.
!
!
! longwave radiation output data from the
! sea_esf_rad radiation package, when that
! package is active
!
!
! shortwave radiation output data from the
! sea_esf_rad radiation package when that
! package is active
!
!
! radiation output data from the original_fms_rad
! radiation package, when that package
! is active
!
!
! OPTIONAL: present when running eta vertical coordinate,
! index of lowest model level above ground
!
!
! OPTIONAL: present when running eta vertical coordinate,
! mask to remove points below ground
!
!
!
subroutine radiation_calc (is, ie, js, je, Rad_time, Time_diag, &
lat, lon, Atmos_input, Surface, Rad_gases, &
Aerosol_props, Aerosol, r, Cldrad_props, &
Cld_spec, Astro, Rad_output, Lw_output, &
Sw_output, Fsrad_output, Aerosol_diags, &
mask, kbot)
!--------------------------------------------------------------------
! radiation_calc is called on radiation timesteps and calculates
! the long- and short-wave radiative fluxes and heating rates, and
! obtains the radiation output fields needed in other portions of
! the model.
!-----------------------------------------------------------------------
!--------------------------------------------------------------------
integer, intent(in) :: is, ie, js, je
type(time_type), intent(in) :: Rad_time, &
Time_diag
real, dimension(:,:), intent(in) :: lat, lon
type(atmos_input_type), intent(in) :: Atmos_input
type(surface_type), intent(in) :: Surface
type(radiative_gases_type), intent(inout) :: Rad_gases
type(aerosol_type), intent(in) :: Aerosol
real, dimension(:,:,:,:), intent(inout) :: r
type(aerosol_properties_type),intent(inout) :: Aerosol_props
type(cldrad_properties_type), intent(in) :: Cldrad_props
type(cld_specification_type), intent(in) :: Cld_spec
type(astronomy_type), intent(in) :: Astro
type(rad_output_type), intent(inout) :: Rad_output
type(lw_output_type), dimension(:), intent(inout) :: Lw_output
type(sw_output_type), dimension(:), intent(inout) :: Sw_output
type(fsrad_output_type), intent(inout) :: Fsrad_output
type(aerosol_diagnostics_type), intent(inout) :: Aerosol_diags
real, dimension(:,:,:), intent(in), optional :: mask
integer, dimension(:,:), intent(in), optional :: kbot
!-----------------------------------------------------------------------
! intent(in) variables:
!
! is,ie,js,je starting/ending subdomain i,j indices of data
! in the physics_window being integrated
! Rad_time time at which the radiative fluxes are to apply
! [ time_type (days, seconds) ]
! Time_diag time on next timestep, used as stamp for diag-
! nostic output [ time_type (days, seconds) ]
! lat latitude of model points on model grid
! [ radians ]
! lon longitude of model points on model grid
! [ radians ]
! Atmos_input atmospheric input data for the radiation
! package
! [ atmos_input_type ]
! Surface surface input data to the radiation package
! [ surface_type ]
! Rad_gases radiative gas input data for the radiation
! package
! [ radiative_gases_type ]
! Aerosol_props aerosol radiative property input data for the
! radiation package
! [ aerosol_properties_type ]
! Aerosol aerosol input data to the radiation package
! [ aerosol_type ]
! Cldrad_props cloud radiative property input data for the
! radiation package
! [ cldrad_properties_type ]
! Cld_spec cloud specification input data for the
! radiation package
! [ cld_specification_type ]
! Astro astronomical input data for the radiation
! package
! [ astronomy_type ]
! Aerosol_diags aerosol diagnostic output
! [ aerosol_diagnostics_type ]
!
!
! intent(out) variables:
!
! Rad_output radiation output data needed by other modules
! [ rad_output_type ]
! Lw_output longwave radiation output data from the
! sea_esf_rad radiation package, when that
! package is active
! [ lw_output_type ]
! The following are the components of Lw_output:
! flxnet net longwave flux at model flux levels
! (including the ground and the top of the
! atmosphere).
! heatra longwave heating rates in model layers.
! flxnetcf net longwave flux at model flux levels
! (including the ground and the top of the
! atmosphere) computed for cloud-free case.
! heatra longwave heating rates in model layers
! computed for cloud-free case.
! Sw_output shortwave radiation output data from the
! sea_esf_rad radiation package when that
! package is active
! [ sw_output_type ]
! Fsrad_output radiation output data from the original_fms_rad
! radiation package, when that package
! is active
! [ fsrad_output_type ]
!
! intent(in), optional variables:
!
! mask present when running eta vertical coordinate,
! mask to define values at points below ground
! kbot present when running eta vertical coordinate,
! index of lowest model level above ground
!
!----------------------------------------------------------------------
real, dimension (size(r,1), size(r,2), size(r,3)) :: tmp1
integer :: kmax, nz
!---------------------------------------------------------------------
! all_column_radiation and all_level_radiation are included as
! future controls which may be utiliized to execute the radiation
! code on a grid other than the model grid. in the current release
! however, both must be .true..
!---------------------------------------------------------------------
if (all_column_radiation .and. all_level_radiation) then
!--------------------------------------------------------------------
! call routines to perform radiation calculations, either using the
! sea_esf_rad or original_fms_rad radiation package.
!---------------------------------------------------------------------
if (do_sea_esf_rad) then
call sea_esf_rad (is, ie, js, je, Rad_time, Atmos_input, &
Surface, Astro, Rad_gases, Aerosol, &
Aerosol_props, Cldrad_props, Cld_spec, &
Lw_output, Sw_output, Aerosol_diags, r)
!--------------------------------------------------------------------
! define tropopause fluxes for diagnostic use later.
!--------------------------------------------------------------------
if (do_lw_rad .or. do_sw_rad) then
call flux_trop_calc (is, ie, js, je, lat, &
Atmos_input, Lw_output(1), Sw_output(1) )
endif
else
call original_fms_rad (is, ie, js, je, Atmos_input%phalf, &
lat, lon, do_clear_sky_pass, &
Rad_time, Time_diag, Atmos_input, &
Surface, Astro, Rad_gases, &
Cldrad_props, Cld_spec, &
Fsrad_output, mask=mask, kbot=kbot)
endif
else
!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
!
! when this option is coded, replace this error_mesg code with
! code which will map the input fields from the model grid to
! the desired radiation grid. A preliminary version of code to per-
! form this task (at least some of it) is found with the inchon
! tagged version of this module. it is removed here, since it has
! not been tested or validated and is considered undesirable in
! a code being prepared for public release. no immediate need for
! it is seen at this time, but it will be added back when such need
! arises.
!
!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
call error_mesg ('radiation_driver_mod', &
' ability to calculate radiation on subset of columns'//&
' and/or levels not yet implemented', FATAL)
endif ! (all_column .and. all_level)
!---------------------------------------------------------------------
! define the components of Rad_output to be passed back to
! radiation_driver -- total and shortwave radiative heating rates
! for standard and clear-sky case (if desired), and surface long-
! and short-wave fluxes. mask out any below ground values if
! necessary.
!---------------------------------------------------------------------
if (do_sea_esf_rad) then
if (do_sw_rad) then
Rad_output%tdtsw(is:ie,js:je,:,:) = &
Sw_output(1)%hsw(:,:,:,:)/SECONDS_PER_DAY
Rad_output%ufsw(is:ie,js:je,:,:) = &
Sw_output(1)%ufsw(:,:,:,:)
Rad_output%dfsw(is:ie,js:je,:,:) = &
Sw_output(1)%dfsw(:,:,:,:)
endif
if (present(mask)) then
if (do_lw_rad) then
Rad_output%tdtlw(is:ie,js:je,:) = &
(Lw_output(1)%heatra(:,:,:)/SECONDS_PER_DAY)* &
mask(:,:,:)
Rad_output%flxnet(is:ie,js:je,:) = &
Lw_output(1)%flxnet(:,:,:)*mask(:,:,:)
endif
do nz = 1, Rad_control%nzens
Rad_output%tdt_rad (is:ie,js:je,:,nz) = &
(Rad_output%tdtsw(is:ie,js:je,:,nz) + &
Rad_output%tdtlw(is:ie,js:je,:))*mask(:,:,:)
end do
else
if (do_lw_rad) then
Rad_output%tdtlw(is:ie,js:je,:) = &
Lw_output(1)%heatra(:,:,:)/SECONDS_PER_DAY
Rad_output%flxnet(is:ie,js:je,:) = &
Lw_output(1)%flxnet(:,:,:)
endif
do nz = 1, Rad_control%nzens
Rad_output%tdt_rad (is:ie,js:je,:,nz) = &
(Rad_output%tdtsw(is:ie,js:je,:,nz) + &
Rad_output%tdtlw(is:ie,js:je,:))
end do
endif
if (do_clear_sky_pass) then
do nz = 1, Rad_control%nzens
if (do_sw_rad) then
Rad_output%tdtsw_clr(is:ie,js:je,:,nz) = &
Sw_output(1)%hswcf(:,:,:,nz)/SECONDS_PER_DAY
Rad_output%ufsw_clr(is:ie,js:je,:,nz) = &
Sw_output(1)%ufswcf(:,:,:,nz)
Rad_output%dfsw_clr(is:ie,js:je,:,nz) = &
Sw_output(1)%dfswcf(:,:,:,nz)
Rad_output%flux_sw_down_total_dir_clr(is:ie,js:je,nz) =&
Sw_output(1)%dfsw_dir_sfc_clr(:,:,nz)
Rad_output%flux_sw_down_total_dif_clr(is:ie,js:je,nz) =&
Sw_output(1)%dfsw_dif_sfc_clr(:,:,nz)
Rad_output%flux_sw_down_vis_clr(is:ie,js:je,nz) = &
Sw_output(1)%dfsw_vis_sfc_clr(:,:,nz)
endif
if (do_lw_rad) then
Rad_output%tdtlw_clr(is:ie,js:je,:) = &
Lw_output(1)%heatracf(:,:,:)/SECONDS_PER_DAY
Rad_output%flxnetcf(is:ie,js:je,:) = &
Lw_output(1)%flxnet(:,:,:)
endif
if (present(mask)) then
Rad_output%tdt_rad_clr(is:ie,js:je,:,nz) = &
(Rad_output%tdtsw_clr(is:ie,js:je,:,nz) + &
Rad_output%tdtlw_clr(is:ie,js:je,:))*mask(:,:,:)
else
Rad_output%tdt_rad_clr(is:ie,js:je,:,nz) = &
(Rad_output%tdtsw_clr(is:ie,js:je,:,nz) + &
Rad_output%tdtlw_clr(is:ie,js:je,:))
endif
end do
endif
kmax = size (Rad_output%tdtsw,3)
if (do_sw_rad) then
Rad_output%flux_sw_surf(is:ie,js:je,:) = &
Sw_output(1)%dfsw(:,:,kmax+1,:) - &
Sw_output(1)%ufsw(:,:,kmax+1,:)
Rad_output%flux_sw_surf_dir(is:ie,js:je,:) = &
Sw_output(1)%dfsw_dir_sfc(:,:,:)
Rad_output%flux_sw_surf_dif(is:ie,js:je,:) = &
Sw_output(1)%dfsw_dif_sfc(:,:,:) - &
Sw_output(1)%ufsw_dif_sfc(:,:,:)
Rad_output%flux_sw_down_vis_dir(is:ie,js:je,:) = &
Sw_output(1)%dfsw_vis_sfc_dir(:,:,:)
Rad_output%flux_sw_down_vis_dif(is:ie,js:je,:) = &
Sw_output(1)%dfsw_vis_sfc_dif(:,:,:)
Rad_output%flux_sw_down_total_dir(is:ie,js:je,:) = &
Sw_output(1)%dfsw_dir_sfc(:,:,:)
Rad_output%flux_sw_down_total_dif(is:ie,js:je,:) = &
Sw_output(1)%dfsw_dif_sfc(:,:,:)
Rad_output%flux_sw_vis (is:ie,js:je,:) = &
Sw_output(1)%dfsw_vis_sfc(:,:,:) - &
Sw_output(1)%ufsw_vis_sfc(:,:,:)
Rad_output%flux_sw_vis_dir (is:ie,js:je,:) = &
Sw_output(1)%dfsw_vis_sfc_dir(:,:,:)
Rad_output%flux_sw_vis_dif (is:ie,js:je,:) = &
Sw_output(1)%dfsw_vis_sfc_dif(:,:,:) - &
Sw_output(1)%ufsw_vis_sfc_dif(:,:,:)
endif
if (do_lw_rad) then
Rad_output%flux_lw_surf(is:ie,js:je) = &
STEFAN*Atmos_input%temp(:,:,kmax+1)**4 - &
Lw_output(1)%flxnet(:,:,kmax+1)
endif
else
Rad_output%tdtsw(is:ie,js:je,:,1) = Fsrad_output%tdtsw(:,:,:)
if (present(mask)) then
Rad_output%tdt_rad (is:ie,js:je,:,1) = &
(Rad_output%tdtsw(is:ie,js:je,:,1) + &
Fsrad_output%tdtlw (:,:,:))*mask(:,:,:)
else
Rad_output%tdt_rad (is:ie,js:je,:,1) = &
(Rad_output%tdtsw(is:ie,js:je,:,1) + &
Fsrad_output%tdtlw (:,:,:))
endif
if (do_clear_sky_pass) then
Rad_output%tdtsw_clr(is:ie,js:je,:,1) = &
Fsrad_output%tdtsw_clr(:,:,:)
if (present(mask)) then
Rad_output%tdt_rad_clr(is:ie,js:je,:,1) = &
(Rad_output%tdtsw_clr(is:ie,js:je,:,1) + &
Fsrad_output%tdtlw_clr(:,:,:))*mask(:,:,:)
else
Rad_output%tdt_rad_clr(is:ie,js:je,:,1) = &
(Rad_output%tdtsw_clr(is:ie,js:je,:,1) + &
Fsrad_output%tdtlw_clr(:,:,:))
endif
endif
Rad_output%flux_sw_surf(is:ie,js:je,1) = &
Fsrad_output%swdns(:,:) - &
Fsrad_output%swups(:,:)
Rad_output%flux_lw_surf(is:ie,js:je) = Fsrad_output%lwdns(:,:)
endif ! (do_sea_esf_rad)
!---------------------------------------------------------------------
end subroutine radiation_calc
!######################################################################
!
!
! update_rad_fields defines the current radiative heating rate,
! surface long and short wave fluxes and cosine of zenith angle
! to be returned to physics_driver, including renormalization
! effects when that option is activated.
!
!
! update_rad_fields defines the current radiative heating rate,
! surface long and short wave fluxes and cosine of zenith angle
! to be returned to physics_driver, including renormalization
! effects when that option is activated.
!
!
! call update_rad_fields (is, ie, js, je, Time_diag, Astro2, &
! Sw_output, Astro, Rad_output, flux_ratio)
!
!
! starting/ending i,j indices in global storage arrays
!
!
! Time on next timestep, used as stamp for diag-
! nostic output [ time_type (days, seconds) ]
!
!
! astronomical properties on model grid, usually
! valid over radiation timestep on entry, on exit are
! valid over model timestep when renormalizing
!
!
! astronomical properties on model grid, valid over
! physics timestep, used when renormalizing sw fluxes
!
!
! Radiation output from radiation package, contains variables
! which are output from radiation_driver to the
! calling routine, and then used elsewhere within
! the component models.
!
!
! shortwave radiation output data from the
! sea_esf_rad radiation package when that
! package is active
!
!
! factor to multiply the radiation step values of
! sw fluxes and heating rates by in order to get
! current physics timestep values
!
!
!
subroutine update_rad_fields (is, ie, js, je, Time_diag, Astro2, &
Sw_output, Astro, Rad_output, flux_ratio)
!---------------------------------------------------------------------
! update_rad_fields defines the current radiative heating rate,
! surface long and short wave fluxes and cosine of zenith angle
! to be returned to physics_driver, including renormalization
! effects when that option is activated.
!--------------------------------------------------------------------
integer, intent(in) :: is, ie, js, je
type(time_type), intent(in) :: Time_diag
type(astronomy_type), intent(in) :: Astro2
type(sw_output_type), dimension(:), intent(inout) :: Sw_output
type(astronomy_type), intent(inout) :: Astro
type(rad_output_type), intent(inout) :: Rad_output
real, dimension(:,:), intent(out) :: flux_ratio
!-------------------------------------------------------------------
! intent(in) variables:
!
! is,ie,js,je starting/ending subdomain i,j indices of data
! in the physics_window being integrated
! Time_diag time on next timestep, used as stamp for diag-
! nostic output [ time_type (days, seconds) ]
! Astro2 astronomical properties on model grid, valid over
! physics timestep, used when renormalizing sw fluxes
! [astronomy_type]
! Sw_output shortwave output variables on model grid,
! [sw_output_type]
!
! intent(inout) variables:
!
! Astro astronomical properties on model grid, usually
! valid over radiation timestep on entry, on exit are
! valid over model timestep when renormalizing
! [astronomy_type]
! Rad_output radiation output variables on model grid, valid
! on entry over either physics or radiation timestep,
! on exit are valid over physics step when renormal-
! izing sw fluxes
! [rad_output_type]
!
! intent(out) variables:
!
! flux_ratio factor to multiply the radiation step values of
! sw fluxes and heating rates by in order to get
! current physics timestep values
!
!--------------------------------------------------------------------
!---------------------------------------------------------------------
! local variables:
!
real, dimension (is:ie, js:je, &
size(Rad_output%tdt_rad,3)) :: tdtlw, tdtlw_clr
integer :: i, j, k
integer :: nz
!---------------------------------------------------------------------
! local variables:
!
! tdtlw longwave heating rate
! [ deg K sec(-1) ]
! tdtlw_clr longwave heating rate under clear sky
! conditions
! [ deg K sec(-1) ]
! i,j,k do-loop indices
!
!---------------------------------------------------------------------
if (renormalize_sw_fluxes) then
!----------------------------------------------------------------------
! if sw fluxes are to be renormalized, save the heating rates, fluxes
! and solar factor calculated on radiation steps.
!---------------------------------------------------------------------
if (do_sw_rad) then
solar_save(is:ie,js:je) = Astro%solar(:,:)
dfsw_save(is:ie,js:je,:,:) = Sw_output(1)%dfsw(:, :,:,:)
ufsw_save(is:ie,js:je,:,:) = Sw_output(1)%ufsw(:, :,:,:)
if (do_swaerosol_forcing) then
dfsw_ad_save(is:ie,js:je,:,:) = &
Sw_output(indx_swaf)%dfsw(:, :,:,:)
ufsw_ad_save(is:ie,js:je,:,:) = &
Sw_output(indx_swaf)%ufsw(:, :,:,:)
endif
fsw_save(is:ie,js:je,:,:) = Sw_output(1)%fsw(:, :,:,:)
hsw_save(is:ie,js:je,:,:) = Sw_output(1)%hsw(:, :,:,:)
flux_sw_surf_save(is:ie,js:je,:) = &
Rad_output%flux_sw_surf(is:ie,js:je,:)
flux_sw_surf_dir_save(is:ie,js:je,:) = &
Rad_output%flux_sw_surf_dir(is:ie,js:je,:)
flux_sw_surf_dif_save(is:ie,js:je,:) = &
Rad_output%flux_sw_surf_dif(is:ie,js:je,:)
flux_sw_down_vis_dir_save(is:ie,js:je,:) = &
Rad_output%flux_sw_down_vis_dir(is:ie,js:je,:)
flux_sw_down_vis_dif_save(is:ie,js:je,:) = &
Rad_output%flux_sw_down_vis_dif(is:ie,js:je,:)
flux_sw_down_total_dir_save(is:ie,js:je,:) = &
Rad_output%flux_sw_down_total_dir(is:ie,js:je,:)
flux_sw_down_total_dif_save(is:ie,js:je,:) = &
Rad_output%flux_sw_down_total_dif(is:ie,js:je,:)
flux_sw_vis_save(is:ie,js:je,:) = &
Rad_output%flux_sw_vis(is:ie,js:je,:)
flux_sw_vis_dir_save(is:ie,js:je,:) = &
Rad_output%flux_sw_vis_dir(is:ie,js:je,:)
flux_sw_vis_dif_save(is:ie,js:je,:) = &
Rad_output%flux_sw_vis_dif(is:ie,js:je,:)
sw_heating_save(is:ie,js:je,:,:) = &
Rad_output%tdtsw(is:ie,js:je,:,:)
tot_heating_save(is:ie,js:je,:,:) = &
Rad_output%tdt_rad(is:ie,js:je,:,:)
swdn_special_save(is:ie,js:je,:,:) = &
Sw_output(1)%swdn_special(:,:,:,:)
swup_special_save(is:ie,js:je,:,:) = &
Sw_output(1)%swup_special(:,:,:,:)
if (do_clear_sky_pass) then
sw_heating_clr_save(is:ie,js:je,:,:) = &
Rad_output%tdtsw_clr(is:ie,js:je,:,:)
tot_heating_clr_save(is:ie,js:je,:,:) = &
Rad_output%tdt_rad_clr(is:ie,js:je,:,:)
dfswcf_save(is:ie,js:je,:,:) = Sw_output(1)%dfswcf(:, :,:,:)
ufswcf_save(is:ie,js:je,:,:) = Sw_output(1)%ufswcf(:, :,:,:)
if (do_swaerosol_forcing) then
dfswcf_ad_save(is:ie,js:je,:,:) = &
Sw_output(indx_swaf)%dfswcf(:, :,:,:)
ufswcf_ad_save(is:ie,js:je,:,:) = &
Sw_output(indx_swaf)%ufswcf(:, :,:,:)
endif
fswcf_save(is:ie,js:je,:,:) = Sw_output(1)%fswcf(:, :,:,:)
hswcf_save(is:ie,js:je,:,:) = Sw_output(1)%hswcf(:, :,:,:)
flux_sw_down_total_dir_clr_save(is:ie,js:je,:) = &
Rad_output%flux_sw_down_total_dir_clr(is:ie,js:je,:)
flux_sw_down_total_dif_clr_save(is:ie,js:je,:) = &
Rad_output%flux_sw_down_total_dif_clr(is:ie,js:je,:)
flux_sw_down_vis_clr_save(is:ie,js:je,:) = &
Rad_output%flux_sw_down_vis_clr(is:ie,js:je,:)
swdn_special_clr_save(is:ie,js:je,:,:) = &
Sw_output(1)%swdn_special_clr(:,:,:,:)
swup_special_clr_save(is:ie,js:je,:,:) = &
Sw_output(1)%swup_special_clr(:,:,:,:)
endif
!---------------------------------------------------------------------
! define the ratio of the solar factor valid over this physics step
! to that valid over the current radiation timestep.
!---------------------------------------------------------------------
do j=1,je-js+1
do i=1,ie-is+1
if (solar_save(i+is-1,j+js-1) /= 0.0) then
flux_ratio(i, j) = Astro2%solar(i,j)/ &
solar_save(i+is-1,j+js-1)
else
flux_ratio(i,j) = 0.0
endif
!---------------------------------------------------------------------
! move the physics-step values(Astro2) to Astro, which will be used
! to calculate diagnostics. the radiation_step values (Astro) are no
! longer needed.
!---------------------------------------------------------------------
Astro%cosz(i,j) = Astro2%cosz(i,j)
Astro%fracday(i,j) = Astro2%fracday(i,j)
Astro%solar(i,j) = Astro2%solar(i,j)
Astro%rrsun = Astro2%rrsun
end do
end do
!----------------------------------------------------------------------
! on non-radiation steps define the ratio of the current solar factor
! valid for this physics step to that valid for the last radiation
! step.
!----------------------------------------------------------------------
else
do j=1,je-js+1
do i=1,ie-is+1
if (solar_save(i+is-1,j+js-1) /= 0.0) then
flux_ratio(i, j) = Astro%solar(i,j)/ &
solar_save(i+is-1,j+js-1)
else
flux_ratio(i,j) = 0.0
endif
end do
end do
endif ! (do_sw_rad)
!---------------------------------------------------------------------
! redefine the total and shortwave heating rates, along with surface
! sw fluxes, as a result of the difference in solar factor (the
! relative earth-sun motion) between the current physics and current
! radiation timesteps.
!---------------------------------------------------------------------
nz = current_sw_zenith_step
tdtlw(:,:,:) = tot_heating_save(is:ie,js:je,:,nz) - &
sw_heating_save(is:ie,js:je,:,nz)
do k=1, size(Rad_output%tdt_rad,3)
Rad_output%tdtsw(is:ie,js:je,k,nz) = &
sw_heating_save(is:ie,js:je,k,nz)*flux_ratio(:,:)
end do
do k=1, size(Rad_output%tdt_rad,3)+1
Rad_output%ufsw(is:ie,js:je,k,nz) = &
ufsw_save(is:ie,js:je,k,nz)*flux_ratio(:,:)
Rad_output%dfsw(is:ie,js:je,k,nz) = &
dfsw_save(is:ie,js:je,k,nz)*flux_ratio(:,:)
end do
Rad_output%tdt_rad(is:ie,js:je,:,nz) = tdtlw(:,:,:) + &
Rad_output%tdtsw(is:ie,js:je,:,nz)
Rad_output%flux_sw_surf(is:ie,js:je,nz) = flux_ratio(:,:)* &
flux_sw_surf_save(is:ie,js:je,nz)
Rad_output%flux_sw_surf_dir(is:ie,js:je,nz) = flux_ratio(:,:)* &
flux_sw_surf_dir_save(is:ie,js:je,nz)
Rad_output%flux_sw_surf_dif(is:ie,js:je,nz) = flux_ratio(:,:)* &
flux_sw_surf_dif_save(is:ie,js:je,nz)
Rad_output%flux_sw_down_vis_dir(is:ie,js:je,nz) = &
flux_ratio(:,:)*flux_sw_down_vis_dir_save(is:ie,js:je,nz)
Rad_output%flux_sw_down_vis_dif(is:ie,js:je,nz) = &
flux_ratio(:,:)*flux_sw_down_vis_dif_save(is:ie,js:je,nz)
Rad_output%flux_sw_down_total_dir(is:ie,js:je,nz) = &
flux_ratio(:,:)*flux_sw_down_total_dir_save(is:ie,js:je,nz)
Rad_output%flux_sw_down_total_dif(is:ie,js:je,nz) = &
flux_ratio(:,:)*flux_sw_down_total_dif_save(is:ie,js:je,nz)
Rad_output%flux_sw_vis(is:ie,js:je,nz) = flux_ratio(:,:)* &
flux_sw_vis_save(is:ie,js:je,nz)
Rad_output%flux_sw_vis_dir(is:ie,js:je,nz) = flux_ratio(:,:)* &
flux_sw_vis_dir_save(is:ie,js:je,nz)
Rad_output%flux_sw_vis_dif(is:ie,js:je,nz) = flux_ratio(:,:)* &
flux_sw_vis_dif_save(is:ie,js:je,nz)
if (do_clear_sky_pass) then
tdtlw_clr(:,:,:) = tot_heating_clr_save(is:ie,js:je,:,nz) - &
sw_heating_clr_save (is:ie,js:je,:,nz)
Rad_output%flux_sw_down_total_dir_clr(is:ie,js:je,nz) = &
flux_ratio(:,:)* &
flux_sw_down_total_dir_clr_save(is:ie,js:je,nz)
Rad_output%flux_sw_down_total_dif_clr(is:ie,js:je,nz) = &
flux_ratio(:,:) * &
flux_sw_down_total_dif_clr_save(is:ie,js:je,nz)
Rad_output%flux_sw_down_vis_clr(is:ie,js:je,nz) = &
flux_ratio(:,:)*flux_sw_down_vis_clr_save(is:ie,js:je,nz)
do k=1, size(Rad_output%tdt_rad,3)
Rad_output%tdtsw_clr(is:ie,js:je,k,nz) = &
sw_heating_clr_save (is:ie,js:je,k,nz)* &
flux_ratio(:,:)
end do
do k=1, size(Rad_output%tdt_rad,3)+1
Rad_output%ufsw_clr(is:ie,js:je,k,nz) = &
ufswcf_save(is:ie,js:je,k,nz)*flux_ratio(:,:)
Rad_output%dfsw_clr(is:ie,js:je,k,nz) = &
dfswcf_save(is:ie,js:je,k,nz)*flux_ratio(:,:)
end do
Rad_output%tdt_rad_clr(is:ie,js:je,:,nz) = tdtlw_clr(:,:,:) +&
Rad_output%tdtsw_clr(is:ie,js:je,:,nz)
endif
else if (all_step_diagnostics) then
!----------------------------------------------------------------------
! if sw fluxes are to be output on every physics step, save the
! heating rates and fluxes calculated on radiation steps.
!---------------------------------------------------------------------
if (do_sw_rad) then
if (do_swaerosol_forcing) then
dfsw_ad_save(is:ie,js:je,:,:) = &
Sw_output(indx_swaf)%dfsw(:, :,:,:)
ufsw_ad_save(is:ie,js:je,:,:) = &
Sw_output(indx_swaf)%ufsw(:, :,:,:)
endif
dfsw_save(is:ie,js:je,:,:) = Sw_output(1)%dfsw(:, :,:,:)
ufsw_save(is:ie,js:je,:,:) = Sw_output(1)%ufsw(:, :,:,:)
fsw_save(is:ie,js:je,:,:) = Sw_output(1)%fsw(:, :,:,:)
hsw_save(is:ie,js:je,:,:) = Sw_output(1)%hsw(:, :,:,:)
flux_sw_surf_save(is:ie,js:je,:) = &
Rad_output%flux_sw_surf(is:ie,js:je,:)
flux_sw_surf_dir_save(is:ie,js:je,:) = &
Rad_output%flux_sw_surf_dir(is:ie,js:je,:)
flux_sw_surf_dif_save(is:ie,js:je,:) = &
Rad_output%flux_sw_surf_dif(is:ie,js:je,:)
flux_sw_down_vis_dir_save(is:ie,js:je,:) = &
Rad_output%flux_sw_down_vis_dir(is:ie,js:je,:)
flux_sw_down_vis_dif_save(is:ie,js:je,:) = &
Rad_output%flux_sw_down_vis_dif(is:ie,js:je,:)
flux_sw_down_total_dir_save(is:ie,js:je,:) = &
Rad_output%flux_sw_down_total_dir(is:ie,js:je,:)
flux_sw_down_total_dif_save(is:ie,js:je,:) = &
Rad_output%flux_sw_down_total_dif(is:ie,js:je,:)
flux_sw_vis_save(is:ie,js:je,:) = &
Rad_output%flux_sw_vis(is:ie,js:je,:)
flux_sw_vis_dir_save(is:ie,js:je,:) = &
Rad_output%flux_sw_vis_dir(is:ie,js:je,:)
flux_sw_vis_dif_save(is:ie,js:je,:) = &
Rad_output%flux_sw_vis_dif(is:ie,js:je,:)
sw_heating_save(is:ie,js:je,:,:) = &
Rad_output%tdtsw(is:ie,js:je,:,:)
tot_heating_save(is:ie,js:je,:,:) = &
Rad_output%tdt_rad(is:ie,js:je,:,:)
swdn_special_save(is:ie,js:je,:,:) = &
Sw_output(1)%swdn_special(:,:,:,:)
swup_special_save(is:ie,js:je,:,:) = &
Sw_output(1)%swup_special(:,:,:,:)
if (do_clear_sky_pass) then
sw_heating_clr_save(is:ie,js:je,:,:) = &
Rad_output%tdtsw_clr(is:ie,js:je,:,:)
tot_heating_clr_save(is:ie,js:je,:,:) = &
Rad_output%tdt_rad_clr(is:ie,js:je,:,:)
dfswcf_save(is:ie,js:je,:,:) = Sw_output(1)%dfswcf(:, :,:,:)
ufswcf_save(is:ie,js:je,:,:) = Sw_output(1)%ufswcf(:, :,:,:)
if (do_swaerosol_forcing) then
dfswcf_ad_save(is:ie,js:je,:,:) = &
Sw_output(indx_swaf)%dfswcf(:, :,:,:)
ufswcf_ad_save(is:ie,js:je,:,:) = &
Sw_output(indx_swaf)%ufswcf(:, :,:,:)
endif
fswcf_save(is:ie,js:je,:,:) = Sw_output(1)%fswcf(:, :,:,:)
hswcf_save(is:ie,js:je,:,:) = Sw_output(1)%hswcf(:, :,:,:)
flux_sw_down_total_dir_clr_save(is:ie,js:je,:) = &
Rad_output%flux_sw_down_total_dir_clr(is:ie,js:je,:)
flux_sw_down_total_dif_clr_save(is:ie,js:je,:) = &
Rad_output%flux_sw_down_total_dif_clr(is:ie,js:je,:)
flux_sw_down_vis_clr_save(is:ie,js:je,:) = &
Rad_output%flux_sw_down_vis_clr(is:ie,js:je,:)
swdn_special_clr_save(is:ie,js:je,:,:) = &
Sw_output(1)%swdn_special_clr(:,:,:,:)
swup_special_clr_save(is:ie,js:je,:,:) = &
Sw_output(1)%swup_special_clr(:,:,:,:)
endif
endif
else
flux_ratio(:,:) = 1.0
endif ! (renormalize_sw_fluxes)
!--------------------------------------------------------------------
end subroutine update_rad_fields
!####################################################################
!
!
! flux_trop_calc defines the shortwave and longwave fluxes at the
! tropopause immediately after the computation of fluxes at model
! levels by the radiation algorithms (invoked by radiation_calc).
!
!
! flux_trop_calc defines the shortwave and longwave fluxes at the
! tropopause immediately after the computation of fluxes at model
! levels by the radiation algorithms (invoked by radiation_calc).
!
!
! call flux_trop_calc (is, ie, js, je, lat, &
! Atmos_input, &
! Lw_output, Sw_output )
!
!
! starting/ending i,j indices in global storage arrays
!
!
! mean latitude (in radians) of all grid boxes processed by this
! call to flux_trop_calc [real, dimension(:,:)]
!
!
! Atmospheric input data to radiation package
!
!
! longwave radiation output data from the
! sea_esf_rad radiation package, when that
! package is active
!
!
! shortwave radiation output data from the
! sea_esf_rad radiation package when that
! package is active
!
!
subroutine flux_trop_calc (is, ie, js, je, lat, Atmos_input, &
Lw_output, Sw_output )
integer, intent(in) :: is, ie, js, je
real,dimension(:,:), intent(in) :: lat
type(atmos_input_type), intent(in) :: Atmos_input
type(lw_output_type), intent(inout) :: Lw_output
type(sw_output_type), intent(inout) :: Sw_output
!---------------------------------------------------------------------
! intent(in) variables:
!
! is,ie,js,je starting/ending subdomain i,j indices of data
! in the physics_window being integrated
! lat latitude of model points [ radians ]
! Atmos_input component pflux (pressure at layer boundaries [ Pa ]
! is used
!
! intent(inout) variables:
! Lw_output lw_output_type variable containing output from
! the longwave radiation code of the
! sea_esf_rad package, on the model grid
! Sw_output sw_output_type variable containing output from
! the shortwave radiation code of the
! sea_esf_rad package, on the model grid
real, dimension (ie-is+1,je-js+1) :: lat_deg, tropo_ht
real, dimension (ie-is+1,je-js+1) :: netlw_trop, &
swdn_trop, swup_trop, &
netlw_trop_clr, &
swdn_trop_clr, &
swup_trop_clr
integer :: j, k, nz
integer :: ki, i
integer :: kmax
real :: wtlo, wthi
kmax = size(Atmos_input%pflux,3) - 1
!---------------------------------------------------------------------
! compute net downward flux at 1 Pa (top of dynmamical model)
! here dynamical pressure top is hard-wired to 1 Pa.
!---------------------------------------------------------------------
do j = 1,je-js+1
do i = 1,ie-is+1
wtlo = (1.0 - Atmos_input%pflux(i,j,1))/ &
(Atmos_input%pflux(i,j,2) - Atmos_input%pflux(i,j,1))
wthi = 1.0 - wtlo
if (Rad_control%do_lw_rad) then
netlw_trop(i,j) = wthi*Lw_output%flxnet(i,j,1) + &
wtlo*Lw_output%flxnet(i,j,2)
Lw_output%netlw_special(i,j,4) = netlw_trop(i,j)
if (do_clear_sky_pass) then
netlw_trop_clr(i,j) = wthi*Lw_output%flxnetcf(i,j,1) + &
wtlo*Lw_output%flxnetcf(i,j,2)
Lw_output%netlw_special_clr(i,j,4) = netlw_trop_clr(i,j)
endif
endif
if (Rad_control%do_sw_rad) then
do nz = 1,Rad_control%nzens
swdn_trop(i,j) = wthi*Sw_output%dfsw(i,j,1,nz) + &
wtlo*Sw_output%dfsw(i,j,2,nz)
swup_trop(i,j) = wthi*Sw_output%ufsw(i,j,1,nz) + &
wtlo*Sw_output%ufsw(i,j,2,nz)
Sw_output%swdn_special(i,j,4,nz) = swdn_trop(i,j)
Sw_output%swup_special(i,j,4,nz) = swup_trop(i,j)
if (do_clear_sky_pass) then
swdn_trop_clr(i,j) = wthi*Sw_output%dfswcf(i,j,1,nz) +&
wtlo*Sw_output%dfswcf(i,j,2,nz)
swup_trop_clr(i,j) = wthi*Sw_output%ufswcf(i,j,1,nz) +&
wtlo*Sw_output%ufswcf(i,j,2,nz)
Sw_output%swdn_special_clr(i,j,4,nz) = &
swdn_trop_clr(i,j)
Sw_output%swup_special_clr(i,j,4,nz) = &
swup_trop_clr(i,j)
endif
end do
endif
enddo
enddo
if (constant_tropo) then
tropo_ht(:,:) = trop_ht_constant
! interpolate the fluxes between the appropriate pressures bracketing
! (trop)
do j = 1,je-js+1
do i = 1,ie-is+1
do k = kmax+1,2,-1
if (Atmos_input%pflux(i,j,k) >= tropo_ht(i,j) .and. &
Atmos_input%pflux(i,j,k-1) < tropo_ht(i,j)) then
ki = k
! the indices for high,low pressure bracketing "tropo_ht" are ki, ki-1
wtlo = (tropo_ht(i,j) - Atmos_input%pflux(i,j,ki-1))/ &
(Atmos_input%pflux(i,j,ki) - Atmos_input%pflux(i,j,ki-1))
wthi = 1.0 - wtlo
if (Rad_control%do_lw_rad) then
netlw_trop(i,j) = wtlo*Lw_output%flxnet(i,j,ki) + &
wthi*Lw_output%flxnet(i,j,ki-1)
Lw_output%netlw_special(i,j,1) = netlw_trop(i,j)
if (do_clear_sky_pass) then
netlw_trop_clr(i,j) = wtlo*Lw_output%flxnetcf(i,j,ki) + &
wthi*Lw_output%flxnetcf(i,j,ki-1)
Lw_output%netlw_special_clr(i,j,1) = netlw_trop_clr(i,j)
endif
endif
if (Rad_control%do_sw_rad) then
do nz = 1,Rad_control%nzens
swdn_trop(i,j) = wtlo*Sw_output%dfsw(i,j,ki,nz) + &
wthi*Sw_output%dfsw(i,j,ki-1,nz)
swup_trop(i,j) = wtlo*Sw_output%ufsw(i,j,ki,nz) + &
wthi*Sw_output%ufsw(i,j,ki-1,nz)
Sw_output%swdn_special(i,j,1,nz) = swdn_trop(i,j)
Sw_output%swup_special(i,j,1,nz) = swup_trop(i,j)
if (do_clear_sky_pass) then
swdn_trop_clr(i,j) = wtlo*Sw_output%dfswcf(i,j,ki,nz) +&
wthi*Sw_output%dfswcf(i,j,ki-1,nz)
swup_trop_clr(i,j) = wtlo*Sw_output%ufswcf(i,j,ki,nz) +&
wthi*Sw_output%ufswcf(i,j,ki-1,nz)
Sw_output%swdn_special_clr(i,j,1,nz) = &
swdn_trop_clr(i,j)
Sw_output%swup_special_clr(i,j,1,nz) = &
swup_trop_clr(i,j)
endif
end do
endif
exit
endif
enddo
enddo
enddo
endif
if (linear_tropo) then
lat_deg(:,:) = lat(:,:)*RADIAN
tropo_ht(:,:) = trop_ht_at_eq + ABS(lat_deg(:,:))* &
(trop_ht_at_poles - trop_ht_at_eq)/90.
! interpolate the fluxes between the appropriate pressures bracketing
! (trop)
do i = 1,ie-is+1
do j = 1,je-js+1
do k = kmax+1,2,-1
if (Atmos_input%pflux(i,j,k) >= tropo_ht(i,j) .and. &
Atmos_input%pflux(i,j,k-1) < tropo_ht(i,j)) then
ki = k
! the indices for high,low pressure bracketing "tropo_ht" are ki, ki-1
wtlo = (tropo_ht(i,j) - Atmos_input%pflux(i,j,ki-1))/ &
(Atmos_input%pflux(i,j,ki) - Atmos_input%pflux(i,j,ki-1))
wthi = 1.0 - wtlo
if (Rad_control%do_lw_rad) then
netlw_trop(i,j) = wtlo*Lw_output%flxnet(i,j,ki) + &
wthi*Lw_output%flxnet(i,j,ki-1)
Lw_output%netlw_special(i,j,2) = netlw_trop(i,j)
if (do_clear_sky_pass) then
netlw_trop_clr(i,j) = wtlo*Lw_output%flxnetcf(i,j,ki) + &
wthi*Lw_output%flxnetcf(i,j,ki-1)
Lw_output%netlw_special_clr(i,j,2) = netlw_trop_clr(i,j)
endif
endif
if (Rad_control%do_sw_rad) then
do nz = 1,Rad_control%nzens
swdn_trop(i,j) = wtlo*Sw_output%dfsw(i,j,ki,nz) + &
wthi*Sw_output%dfsw(i,j,ki-1,nz)
swup_trop(i,j) = wtlo*Sw_output%ufsw(i,j,ki,nz) + &
wthi*Sw_output%ufsw(i,j,ki-1,nz)
Sw_output%swdn_special(i,j,2,nz) = swdn_trop(i,j)
Sw_output%swup_special(i,j,2,nz) = swup_trop(i,j)
if (do_clear_sky_pass) then
swdn_trop_clr(i,j) = wtlo*Sw_output%dfswcf(i,j,ki,nz) + &
wthi*Sw_output%dfswcf(i,j,ki-1,nz)
swup_trop_clr(i,j) = wtlo*Sw_output%ufswcf(i,j,ki,nz) + &
wthi*Sw_output%ufswcf(i,j,ki-1,nz)
Sw_output%swdn_special_clr(i,j,2,nz) = swdn_trop_clr(i,j)
Sw_output%swup_special_clr(i,j,2,nz) = swup_trop_clr(i,j)
endif
end do
endif
exit
endif
enddo
enddo
enddo
endif
if (thermo_tropo) then
call error_mesg ( 'radiation_driver_mod', &
'thermo_tropo option not yet available', FATAL)
! interpolate the fluxes between the appropriate pressures bracketing
! (trop)
do i = 1,ie-is+1
do j = 1,je-js+1
do k = kmax+1,2,-1
if (Atmos_input%pflux(i,j,k) >= tropo_ht(i,j) .and. &
Atmos_input%pflux(i,j,k-1) < tropo_ht(i,j)) then
ki = k
! the indices for high,low pressure bracketing "tropo_ht" are ki, ki-1
wtlo = (tropo_ht(i,j) - Atmos_input%pflux(i,j,ki-1))/ &
(Atmos_input%pflux(i,j,ki) - Atmos_input%pflux(i,j,ki-1))
wthi = 1.0 - wtlo
if (Rad_control%do_lw_rad) then
netlw_trop(i,j) = wtlo*Lw_output%flxnet(i,j,ki) + &
wthi*Lw_output%flxnet(i,j,ki-1)
Lw_output%netlw_special(i,j,3) = netlw_trop(i,j)
if (do_clear_sky_pass) then
netlw_trop_clr(i,j) = wtlo*Lw_output%flxnetcf(i,j,ki) + &
wthi*Lw_output%flxnetcf(i,j,ki-1)
Lw_output%netlw_special_clr(i,j,3) = netlw_trop_clr(i,j)
endif
endif
if (Rad_control%do_sw_rad) then
do nz = 1,Rad_control%nzens
swdn_trop(i,j) = wtlo*Sw_output%dfsw(i,j,ki,nz) + &
wthi*Sw_output%dfsw(i,j,ki-1,nz)
swup_trop(i,j) = wtlo*Sw_output%ufsw(i,j,ki,nz) + &
wthi*Sw_output%ufsw(i,j,ki-1,nz)
Sw_output%swdn_special(i,j,3,nz) = swdn_trop(i,j)
Sw_output%swup_special(i,j,3,nz) = swup_trop(i,j)
if (do_clear_sky_pass) then
swdn_trop_clr(i,j) = wtlo*Sw_output%dfswcf(i,j,ki,nz) + &
wthi*Sw_output%dfswcf(i,j,ki-1,nz)
swup_trop_clr(i,j) = wtlo*Sw_output%ufswcf(i,j,ki,nz) + &
wthi*Sw_output%ufswcf(i,j,ki-1,nz)
Sw_output%swdn_special_clr(i,j,3,nz) = swdn_trop_clr(i,j)
Sw_output%swup_special_clr(i,j,3,nz) = swup_trop_clr(i,j)
endif
end do
endif
exit
endif
enddo
enddo
enddo
endif
end subroutine flux_trop_calc
!####################################################################
!
!
! produce_radiation_diagnostics produces netcdf output and global
! and hemispheric integrals of radiation package variables.
!
!
! produce_radiation_diagnostics produces netcdf output and global
! and hemispheric integrals of radiation package variables.
!
!
! call produce_radiation_diagnostics &
! (is, ie, js, je, Time_diag, lat, ts, asfc, &
! flux_ratio, Astro, Rad_output, Lw_output, &
! Sw_output, Cld_spec, Lsc_microphys, &
! Fsrad_output, mask)
!
!
! starting/ending i,j indices in global storage arrays
!
!
! Time_diag time on next timestep, used as stamp for diag-
! nostic output [ time_type (days, seconds) ]
!
!
! lat mean latitude (in radians) of all grid boxes processed by this
! call to radiation_driver [real, dimension(:,:)]
!
!
! Surface skin temperature
!
!
! surface albedo
!
!
! renormalization factor for sw fluxes and heating
! rates
!
!
! astronomical input data for the radiation package
!
!
! Radiation output from radiation package, contains variables
! which are output from radiation_driver to the
! calling routine, and then used elsewhere within
! the component models.
!
!
! longwave radiation output data from the
! sea_esf_rad radiation package, when that
! package is active
!
!
! shortwave radiation output data from the
! sea_esf_rad radiation package when that
! package is active
!
!
! Cloud microphysical and physical parameters to radiation package,
! when the microphysical package is active
!
!
! microphysical specification for large-scale clouds,
! when the microphysical package is active
!
!
! OPTIONAL: present when running eta vertical coordinate,
! mask to remove points below ground
!
!
!
subroutine produce_radiation_diagnostics &
(is, ie, js, je, Time_diag, Time, lat, ts, Surface, &
flux_ratio, Astro, Rad_output, Rad_gases,&
Lw_output, Sw_output, Cld_spec, &
Lsc_microphys, Fsrad_output, mask)
!--------------------------------------------------------------------
! produce_radiation_diagnostics produces netcdf output and global
! and hemispheric integrals of radiation package variables.
!--------------------------------------------------------------------
!--------------------------------------------------------------------
integer, intent(in) :: is, ie, js, je
type(time_type), intent(in) :: Time_diag
type(time_type), intent(in) :: Time
real,dimension(:,:), intent(in) :: lat, ts
type(surface_type), intent(in) :: Surface
real,dimension(:,:), intent(in) :: flux_ratio
type(astronomy_type), intent(in) :: Astro
type(rad_output_type), intent(in) :: Rad_output
type(radiative_gases_type), intent(in) :: Rad_gases
type(lw_output_type), dimension(:), intent(in), optional :: Lw_output
type(fsrad_output_type), intent(in), optional :: Fsrad_output
type(sw_output_type), dimension(:), intent(in), optional :: Sw_output
type(cld_specification_type), intent(in), optional :: Cld_spec
type(microphysics_type), intent(in), optional :: Lsc_microphys
real,dimension(:,:,:), intent(in), optional :: mask
!--------------------------------------------------------------------
!---------------------------------------------------------------------
! intent(in) variables:
!
! is,ie,js,je starting/ending subdomain i,j indices of data
! in the physics_window being integrated
! Time_diag time on next timestep, used as stamp for diagnostic
! output [ time_type (days, seconds) ]
! lat latitude of model points [ radians ]
! ts surface temperature [ deg K ]
! asfc surface albedo [ dimensionless ]
! flux_ratio renormalization factor for sw fluxes and heating
! rates [ dimensionless ]
! Astro astronomical variables input to the radiation
! package [ dimensionless ]
! Rad_output rad_output_type variable containing radiation
! output fields
! Rad_gases radiative_gases_type variable containing co2 mixing
! ratio
!
!
! intent(in) optional variables:
!
! Lw_output lw_output_type variable containing output from
! the longwave radiation code of the
! sea_esf_rad package, on the model grid
! Sw_output sw_output_type variable containing output from
! the shortwave radiation code of the
! sea_esf_rad package, on the model grid
! Cld_spec cloud specification input data for the
! radiation package
! [ cld_specification_type ]
! Lsc_microphys microphysics_type structure, contains variables
! describing the microphysical properties of the
! large-scale clouds, passed through to lower
! level routines
! Fsrad_output fsrad_output_type variable containing
! output from the original_fms_rad radiation
! package, on the model grid
! mask present when running eta vertical coordinate,
! mask to remove points below ground
!
!----------------------------------------------------------------------
!-----------------------------------------------------------------------
! local variables
real, dimension (ie-is+1,je-js+1) :: &
asfc, asfc_vis_dir, &
asfc_nir_dir, &
asfc_vis_dif, &
asfc_nir_dif, &
swin, swout, olr, &
swups, swdns, lwups, &
lwdns, swin_clr, &
swout_clr, olr_clr, &
swups_clr, swdns_clr,&
lwups_clr, lwdns_clr
real, dimension (ie-is+1,je-js+1, MX_SPEC_LEVS) :: &
swdn_trop, &
swdn_trop_clr, &
swup_trop, &
swup_trop_clr, &
netlw_trop, &
netlw_trop_clr
real, dimension (ie-is+1,je-js+1, size(Rad_output%tdtsw,3)) :: &
tdtlw, tdtlw_clr,&
hsw, hswcf
real, dimension (ie-is+1,je-js+1, size(Rad_output%tdtsw,3)+1) :: &
dfsw, ufsw, &
dfswcf, ufswcf,&
flxnet, flxnetcf, &
fsw, fswcf
real, dimension (ie-is+1,je-js+1) :: &
swin_ad, swout_ad, olr_ad,&
swups_ad, swdns_ad, lwups_ad,lwdns_ad,&
swin_ad_clr, swout_ad_clr, olr_ad_clr,&
swups_ad_clr, swdns_ad_clr, lwups_ad_clr, lwdns_ad_clr
real, dimension (ie-is+1,je-js+1, size(Rad_output%tdtsw,3)+1) :: &
dfsw_ad, ufsw_ad, &
dfswcf_ad, ufswcf_ad
integer :: j, k
integer :: ipass
logical :: used
integer :: iind, jind
integer :: kmax
integer :: nz
! asfc surface albedo [ dimensionless ]
! asfc_vis_dir surface visible albedo [ dimensionless ]
! asfc_nir_dir surface nir albedo [ dimensionless ]
! asfc_vis_dif surface visible albedo [ dimensionless ]
! asfc_nir_dif surface nir albedo [ dimensionless ]
!---------------------------------------------------------------------
! if sw flux renormalization is active, modify the fluxes calculated
! on the last radiation step by the normalization factor based on
! the difference in solar factor between the current model step and
! the current radiation step.
!----------------------------------------------------------------------
nz = current_sw_zenith_step
kmax = size (Rad_output%tdtsw,3)
if (renormalize_sw_fluxes) then
do k=1, kmax
hsw(:,:,k) = hsw_save(is:ie,js:je,k,nz)*flux_ratio(:,:)
end do
do k=1, kmax+1
if (do_swaerosol_forcing) then
dfsw_ad(:,:,k) = &
dfsw_ad_save(is:ie,js:je,k,nz)*flux_ratio(:,:)
ufsw_ad(:,:,k) = &
ufsw_ad_save(is:ie,js:je,k,nz)*flux_ratio(:,:)
endif
dfsw(:,:,k) = dfsw_save(is:ie,js:je,k,nz)*flux_ratio(:,:)
ufsw(:,:,k) = ufsw_save(is:ie,js:je,k,nz)*flux_ratio(:,:)
fsw(:,:,k) = fsw_save(is:ie,js:je,k,nz)*flux_ratio(:,:)
end do
do k=1,Rad_control%mx_spec_levs
swdn_trop(:,:,k) = swdn_special_save(is:ie,js:je,k,nz)* &
flux_ratio(:,:)
swup_trop(:,:,k) = swup_special_save(is:ie,js:je,k,nz)* &
flux_ratio(:,:)
end do
if (do_clear_sky_pass) then
do k=1, kmax
hswcf(:,:,k) = hswcf_save(is:ie,js:je,k,nz)*flux_ratio(:,:)
end do
do k=1, kmax+1
if (do_swaerosol_forcing) then
dfswcf_ad(:,:,k) = dfswcf_ad_save(is:ie,js:je,k,nz)* &
flux_ratio(:,:)
ufswcf_ad(:,:,k) = ufswcf_ad_save(is:ie,js:je,k,nz)* &
flux_ratio(:,:)
endif
dfswcf(:,:,k) = &
dfswcf_save(is:ie,js:je,k,nz)*flux_ratio(:,:)
ufswcf(:,:,k) = &
ufswcf_save(is:ie,js:je,k,nz)*flux_ratio(:,:)
fswcf(:,:,k) = fswcf_save(is:ie,js:je,k,nz)*flux_ratio(:,:)
end do
do k=1,Rad_control%mx_spec_levs
swdn_trop_clr(:,:,k) = &
swdn_special_clr_save(is:ie,js:je,k,nz)*flux_ratio(:,:)
swup_trop_clr(:,:,k) = &
swup_special_clr_save(is:ie,js:je,k,nz)*flux_ratio(:,:)
end do
endif
!----------------------------------------------------------------------
! if renormalization is not active and this is a radiation step
! (i.e., diagnostics desired), define the variables to be output as
! the values present in Sw_output.
!---------------------------------------------------------------------
else if (do_sw_rad .and. do_sea_esf_rad) then
do k=1, kmax
hsw(:,:,k) = Sw_output(1)%hsw(:,:,k,nz)
end do
do k=1, kmax+1
if (do_swaerosol_forcing) then
dfsw_ad(:,:,k) = Sw_output(indx_swaf)%dfsw(:,:,k,nz)
ufsw_ad(:,:,k) = Sw_output(indx_swaf)%ufsw(:,:,k,nz)
endif
dfsw(:,:,k) = Sw_output(1)%dfsw(:,:,k,nz)
ufsw(:,:,k) = Sw_output(1)%ufsw(:,:,k,nz)
fsw(:,:,k) = Sw_output(1)%fsw(:,:,k,nz)
end do
swdn_trop(:,:,:) = Sw_output(1)%swdn_special(:,:,:,nz)
swup_trop(:,:,:) = Sw_output(1)%swup_special(:,:,:,nz)
if (do_clear_sky_pass) then
do k=1, kmax
hswcf(:,:,k) = Sw_output(1)%hswcf(:,:,k,nz)
end do
do k=1, kmax+1
if (do_swaerosol_forcing) then
dfswcf_ad(:,:,k) = Sw_output(indx_swaf)%dfswcf(:,:,k,nz)
ufswcf_ad(:,:,k) = Sw_output(indx_swaf)%ufswcf(:,:,k,nz)
endif
dfswcf(:,:,k) = Sw_output(1)%dfswcf(:,:,k,nz)
ufswcf(:,:,k) = Sw_output(1)%ufswcf(:,:,k,nz)
fswcf(:,:,k) = Sw_output(1)%fswcf(:,:,k,nz)
end do
swdn_trop_clr(:,:,:) = Sw_output(1)%swdn_special_clr(:,:,:,nz)
swup_trop_clr(:,:,:) = Sw_output(1)%swup_special_clr(:,:,:,nz)
endif
!----------------------------------------------------------------------
! if renormalization is not active and this is not a radiation step
! but all_step_diagnostics is activated (i.e., diagnostics desired),
! define the variables to be output as the values previously saved
! in the xxx_save variables.
!---------------------------------------------------------------------
else if (do_sea_esf_rad .and. all_step_diagnostics) then
do k=1, kmax
hsw(:,:,k) = hsw_save(is:ie,js:je,k,nz)
end do
do k=1, kmax+1
if (do_swaerosol_forcing) then
dfsw_ad(:,:,k) = dfsw_ad_save(is:ie,js:je,k,nz)
ufsw_ad(:,:,k) = ufsw_ad_save(is:ie,js:je,k,nz)
endif
dfsw(:,:,k) = dfsw_save(is:ie,js:je,k,nz)
ufsw(:,:,k) = ufsw_save(is:ie,js:je,k,nz)
fsw(:,:,k) = fsw_save(is:ie,js:je,k,nz)
end do
swdn_trop(:,:,:) = swdn_special_save(is:ie,js:je,:,nz)
swup_trop(:,:,:) = swup_special_save(is:ie,js:je,:,nz)
if (do_clear_sky_pass) then
do k=1, kmax
hswcf(:,:,k) = hswcf_save(is:ie,js:je,k,nz)
end do
do k=1, kmax+1
if (do_swaerosol_forcing) then
dfswcf_ad(:,:,k) = dfswcf_ad_save(is:ie,js:je,k,nz)
ufswcf_ad(:,:,k) = ufswcf_ad_save(is:ie,js:je,k,nz)
endif
dfswcf(:,:,k) = dfswcf_save(is:ie,js:je,k,nz)
ufswcf(:,:,k) = ufswcf_save(is:ie,js:je,k,nz)
fswcf(:,:,k) = fswcf_save(is:ie,js:je,k,nz)
end do
swdn_trop_clr(:,:,:) = swdn_special_clr_save(is:ie,js:je,:,nz)
swup_trop_clr(:,:,:) = swup_special_clr_save(is:ie,js:je,:,nz)
endif
endif
!---------------------------------------------------------------------
! define the sw diagnostic arrays.
!---------------------------------------------------------------------
if (renormalize_sw_fluxes .or. do_sw_rad .or. &
use_hires_coszen .or. all_step_diagnostics) then
if (do_sea_esf_rad) then
if (do_swaerosol_forcing) then
swin_ad (:,:) = dfsw_ad(:,:,1)
swout_ad(:,:) = ufsw_ad(:,:,1)
swups_ad(:,:) = ufsw_ad(:,:,kmax+1)
swdns_ad(:,:) = dfsw_ad(:,:,kmax+1)
endif
swin (:,:) = dfsw(:,:,1)
swout(:,:) = ufsw(:,:,1)
swups(:,:) = ufsw(:,:,kmax+1)
swdns(:,:) = dfsw(:,:,kmax+1)
if (do_clear_sky_pass) then
if (do_swaerosol_forcing) then
swin_ad_clr (:,:) = dfswcf_ad(:,:,1)
swout_ad_clr(:,:) = ufswcf_ad(:,:,1)
swups_ad_clr(:,:) = ufswcf_ad(:,:,kmax+1)
swdns_ad_clr(:,:) = dfswcf_ad(:,:,kmax+1)
endif
swin_clr (:,:) = dfswcf(:,:,1)
swout_clr(:,:) = ufswcf(:,:,1)
swups_clr(:,:) = ufswcf(:,:,kmax+1)
swdns_clr(:,:) = dfswcf(:,:,kmax+1)
endif
else ! original fms rad
swin (:,:) = Fsrad_output%swin(:,:)
swout(:,:) = Fsrad_output%swout(:,:)
swups(:,:) = Fsrad_output%swups(:,:)
swdns(:,:) = Fsrad_output%swdns(:,:)
if (do_clear_sky_pass) then
swin_clr (:,:) = Fsrad_output%swin_clr(:,:)
swout_clr(:,:) = Fsrad_output%swout_clr(:,:)
swups_clr(:,:) = Fsrad_output%swups_clr(:,:)
swdns_clr(:,:) = Fsrad_output%swdns_clr(:,:)
endif
endif ! do_sea_esf_rad
if (id_alb_sfc_avg > 0) then
swups_acc(is:ie,js:je) = swups_acc(is:ie, js:je) + swups(:,:)
swdns_acc(is:ie,js:je) = swdns_acc(is:ie, js:je) + swdns(:,:)
endif
!---------------------------------------------------------------------
! send standard sw diagnostics to diag_manager.
!---------------------------------------------------------------------
if (Time_diag > Time) then
if (do_clear_sky_pass) then
ipass = 2
else
ipass = 1
endif
!------- sw tendency -----------
if (id_tdt_sw(ipass) > 0 ) then
used = send_data (id_tdt_sw(ipass), &
Rad_output%tdtsw(is:ie,js:je,:,nz), &
Time_diag, is, js, 1, rmask=mask )
endif
!---- 3d upward sw flux ---------
if (id_ufsw(ipass) > 0 ) then
used = send_data (id_ufsw(ipass), &
Rad_output%ufsw(is:ie,js:je,:,nz), &
Time_diag, is, js, 1, rmask=mask )
endif
!---- 3d downward sw flux ---------
if (id_dfsw(ipass) > 0 ) then
used = send_data (id_dfsw(ipass), &
Rad_output%dfsw(is:ie,js:je,:,nz), &
Time_diag, is, js, 1, rmask=mask )
endif
!------- incoming sw flux toa -------
if (id_swdn_toa(ipass) > 0 ) then
used = send_data (id_swdn_toa(ipass), swin, &
Time_diag, is, js )
endif
!------- outgoing sw flux toa -------
if (id_swup_toa(ipass) > 0 ) then
used = send_data (id_swup_toa(ipass), swout, &
Time_diag, is, js )
endif
!------- incoming sw flux trop -------
if (id_swdn_special(1,ipass) > 0 ) then
used = send_data (id_swdn_special(1,ipass), &
swdn_trop(:,:,1), &
Time_diag, is, js )
endif
!------- incoming sw flux trop -------
if (id_swdn_special(2,ipass) > 0 ) then
used = send_data (id_swdn_special(2,ipass), &
swdn_trop(:,:,2), &
Time_diag, is, js )
endif
!------- incoming sw flux trop -------
if (id_swdn_special(3, ipass) > 0 ) then
used = send_data (id_swdn_special(3,ipass), &
swdn_trop(:,:,3), &
Time_diag, is, js )
endif
!------- net sw downward flux at model dynamics top (1 Pa) ----
if (id_swdn_special(4, ipass) > 0 ) then
used = send_data (id_swdn_special(4,ipass), &
swdn_trop(:,:,4), &
Time_diag, is, js )
endif
!------- outgoing sw flux trop -------
if (id_swup_special(1,ipass) > 0 ) then
used = send_data (id_swup_special(1,ipass), &
swup_trop(:,:,1), &
Time_diag, is, js )
endif
!------- outgoing sw flux trop -------
if (id_swup_special(2,ipass) > 0 ) then
used = send_data (id_swup_special(2,ipass), &
swup_trop(:,:,2), &
Time_diag, is, js )
endif
!------- outgoing sw flux trop -------
if (id_swup_special(3,ipass) > 0 ) then
used = send_data (id_swup_special(3,ipass), &
swup_trop(:,:,3), &
Time_diag, is, js )
endif
!------- net sw upward flux at model dynamics top (1 Pa) ----
if (id_swdn_special(4, ipass) > 0 ) then
used = send_data (id_swup_special(4,ipass), &
swup_trop(:,:,4), &
Time_diag, is, js )
endif
!------- upward sw flux surface -------
if (id_swup_sfc(ipass) > 0 ) then
used = send_data (id_swup_sfc(ipass), swups, &
Time_diag, is, js )
endif
!------- downward sw flux surface -------
if (id_swdn_sfc(ipass) > 0 ) then
used = send_data (id_swdn_sfc(ipass), swdns, &
Time_diag, is, js )
endif
!------- net sw flux at toa -------
if (id_swtoa(ipass) > 0 ) then
used = send_data (id_swtoa(ipass), swin-swout, &
Time_diag, is, js )
endif
!------- net sw flux at surface -------
if (id_swsfc(ipass) > 0 ) then
used = send_data (id_swsfc(ipass), swdns-swups, &
Time_diag, is, js )
endif
if (do_swaerosol_forcing) then
!------- net sw flux at toa -------
if (id_swtoa_ad(ipass) > 0 ) then
used = send_data (id_swtoa_ad(ipass), swin_ad-swout_ad, &
Time_diag, is, js )
endif
!------- net sw flux at surface -------
if (id_swsfc_ad(ipass) > 0 ) then
used = send_data (id_swsfc_ad(ipass), swdns_ad-swups_ad, &
Time_diag, is, js )
endif
!------- sw flux down at surface -------
if (id_swdn_sfc_ad(ipass) > 0 ) then
used = send_data (id_swdn_sfc_ad(ipass), swdns_ad, &
Time_diag, is, js )
endif
!------- sw flux up at surface -------
if (id_swup_sfc_ad(ipass) > 0 ) then
used = send_data (id_swup_sfc_ad(ipass), swups_ad, &
Time_diag, is, js )
endif
!------- outgoing sw flux toa -------
if (id_swup_toa_ad(ipass) > 0 ) then
used = send_data (id_swup_toa_ad(ipass), swout_ad, &
Time_diag, is, js )
endif
endif
!----------------------------------------------------------------------
! now pass clear-sky diagnostics, if they have been calculated.
!----------------------------------------------------------------------
if (do_clear_sky_pass) then
ipass = 1
!------- sw tendency -----------
if (id_tdt_sw(ipass) > 0 ) then
used = send_data (id_tdt_sw(ipass), &
Rad_output%tdtsw_clr(is:ie,js:je,:,nz), &
Time_diag, is, js, 1, rmask=mask )
endif
!---- 3d upward sw flux ---------
if (id_ufsw(ipass) > 0 ) then
used = send_data (id_ufsw(ipass), &
Rad_output%ufsw_clr(is:ie,js:je,:,nz), &
Time_diag, is, js, 1, rmask=mask )
endif
!---- 3d downward sw flux ---------
if (id_dfsw(ipass) > 0 ) then
used = send_data (id_dfsw(ipass), &
Rad_output%dfsw_clr(is:ie,js:je,:,nz), &
Time_diag, is, js, 1, rmask=mask )
endif
!------- incoming sw flux toa -------
if (id_swdn_toa(ipass) > 0 ) then
used = send_data (id_swdn_toa(ipass), swin_clr, &
Time_diag, is, js )
endif
!------- outgoing sw flux toa -------
if (id_swup_toa(ipass) > 0 ) then
used = send_data (id_swup_toa(ipass), swout_clr, &
Time_diag, is, js )
endif
!------- incoming sw flux trop -------
if (id_swdn_special(1,ipass) > 0 ) then
used = send_data (id_swdn_special(1, ipass), &
swdn_trop_clr(:,:,1), &
Time_diag, is, js )
endif
!------- incoming sw flux trop -------
if (id_swdn_special(2,ipass) > 0 ) then
used = send_data (id_swdn_special(2, ipass), &
swdn_trop_clr(:,:,2), &
Time_diag, is, js )
endif
!------- incoming sw flux trop -------
if (id_swdn_special(3,ipass) > 0 ) then
used = send_data (id_swdn_special(3, ipass), &
swdn_trop_clr(:,:,3), &
Time_diag, is, js )
endif
!------- outgoing sw flux trop -------
if (id_swup_special(1,ipass) > 0 ) then
used = send_data (id_swup_special(1,ipass), &
swup_trop_clr(:,:,1), &
Time_diag, is, js )
endif
!------- outgoing sw flux trop -------
if (id_swup_special(2,ipass) > 0 ) then
used = send_data (id_swup_special(2,ipass), &
swup_trop_clr(:,:,2), &
Time_diag, is, js )
endif
!------- outgoing sw flux trop -------
if (id_swup_special(3,ipass) > 0 ) then
used = send_data (id_swup_special(3,ipass), &
swup_trop_clr(:,:,3), &
Time_diag, is, js )
endif
!------- upward sw flux surface -------
if (id_swup_sfc(ipass) > 0 ) then
used = send_data (id_swup_sfc(ipass), swups_clr, &
Time_diag, is, js )
endif
!------- downward sw flux surface -------
if (id_swdn_sfc(ipass) > 0 ) then
used = send_data (id_swdn_sfc(ipass), swdns_clr, &
Time_diag, is, js )
endif
!------- net sw flux at toa -------
if (id_swtoa(ipass) > 0 ) then
used = send_data (id_swtoa(ipass), swin_clr-swout_clr, &
Time_diag, is, js )
endif
!------- net sw flux at surface -------
if (id_swsfc(ipass) > 0 ) then
used = send_data (id_swsfc(ipass), swdns_clr-swups_clr, &
Time_diag, is, js )
endif
if (do_swaerosol_forcing) then
!------- net sw flux at toa -------
if (id_swtoa_ad(ipass) > 0 ) then
used = send_data (id_swtoa_ad(ipass), swin_ad_clr-swout_ad_clr, &
Time_diag, is, js )
endif
!------- net sw flux at surface -------
if (id_swsfc_ad(ipass) > 0 ) then
used = send_data (id_swsfc_ad(ipass), swdns_ad_clr-swups_ad_clr, &
Time_diag, is, js )
endif
!------- sw flux down at surface -------
if (id_swdn_sfc_ad(ipass) > 0 ) then
used = send_data (id_swdn_sfc_ad(ipass), swdns_ad_clr, &
Time_diag, is, js )
endif
!------- sw flux up at surface -------
if (id_swup_sfc_ad(ipass) > 0 ) then
used = send_data (id_swup_sfc_ad(ipass), swups_ad_clr, &
Time_diag, is, js )
endif
!------- outgoing sw flux toa -------
if (id_swup_toa_ad(ipass) > 0 ) then
used = send_data (id_swup_toa_ad(ipass), swout_ad_clr, &
Time_diag, is, js )
endif
endif
endif ! (do_clear_sky_pass)
!-----------------------------------------------------------------------
! send cloud-forcing-independent diagnostics to diagnostics manager.
!-----------------------------------------------------------------------
!---- 3d total radiative heating ---------
if (id_allradp > 0 ) then
used = send_data (id_allradp , &
Rad_output%tdt_rad(is:ie,js:je,:,nz), &
Time_diag, is, js, 1, rmask=mask )
endif
!------- conc_drop -------------------------
if (do_rad) then
if ( id_conc_drop > 0 ) then
used = send_data (id_conc_drop, Lsc_microphys%conc_drop, &
Time_diag, is, js, 1, rmask=mask )
endif
endif
!------- conc_ice -------------------------
if (do_rad) then
if (id_conc_ice > 0 ) then
used = send_data (id_conc_ice, Lsc_microphys%conc_ice, &
Time_diag, is, js, 1, rmask=mask )
endif
endif
!------- solar constant -------------------------
if (do_rad) then
if ( id_sol_con > 0 ) then
used = send_data ( id_sol_con, Sw_control%solar_constant, &
Time_diag )
endif
endif
!------- co2 mixing ratio used for tf calculation -------------------
if (do_rad) then
if ( id_co2_tf > 0 ) then
used = send_data ( id_co2_tf, &
1.0E6*Rad_gases%co2_for_last_tf_calc, &
Time_diag )
endif
endif
!------- ch4 mixing ratio used for tf calculation ---------------
if (do_rad) then
if ( id_ch4_tf > 0 ) then
used = send_data ( id_ch4_tf, &
1.0E9*Rad_gases%ch4_for_last_tf_calc, &
Time_diag )
endif
endif
!------- n2o mixing ratio used for tf calculation ---------------
if (do_rad) then
if ( id_n2o_tf > 0 ) then
used = send_data ( id_n2o_tf, &
1.0E9*Rad_gases%n2o_for_last_tf_calc, &
Time_diag )
endif
endif
!------- co2 mixing ratio -------------------------
if (do_rad) then
if ( id_rrvco2 > 0 ) then
used = send_data ( id_rrvco2, 1.0E6*Rad_gases%rrvco2, &
Time_diag )
endif
endif
!------- f11 mixing ratio -------------------------
if (do_rad) then
if ( id_rrvf11 > 0 ) then
used = send_data ( id_rrvf11, 1.0E12*Rad_gases%rrvf11, &
Time_diag )
endif
endif
!------- f12 mixing ratio -------------------------
if (do_rad) then
if ( id_rrvf12 > 0 ) then
used = send_data ( id_rrvf12, 1.0E12*Rad_gases%rrvf12, &
Time_diag )
endif
endif
!------- f113 mixing ratio -------------------------
if (do_rad) then
if ( id_rrvf113 > 0 ) then
used = send_data ( id_rrvf113, 1.0E12*Rad_gases%rrvf113, &
Time_diag )
endif
endif
!------- f22 mixing ratio -------------------------
if (do_rad) then
if ( id_rrvf22 > 0 ) then
used = send_data ( id_rrvf22, 1.0E12*Rad_gases%rrvf22, &
Time_diag )
endif
endif
!------- ch4 mixing ratio -------------------------
if (do_rad) then
if ( id_rrvch4 > 0 ) then
used = send_data ( id_rrvch4, 1.0E9*Rad_gases%rrvch4, &
Time_diag )
endif
endif
!------- n2o mixing ratio -------------------------
if (do_rad) then
if ( id_rrvn2o > 0 ) then
used = send_data ( id_rrvn2o, 1.0E9*Rad_gases%rrvn2o, &
Time_diag )
endif
endif
!------- surface albedo -------------------------
if ( id_alb_sfc_avg > 0 ) then
! used = send_data ( id_alb_sfc, 100.*Surface%asfc, &
used = send_data ( id_alb_sfc_avg, &
100.*swups_acc(is:ie,js:je)/swdns_acc(is:ie,js:je), &
Time_diag, is, js )
endif
if ( id_alb_sfc > 0 ) then
! used = send_data ( id_alb_sfc, 100.*Surface%asfc, &
used = send_data ( id_alb_sfc, 100.*swups/(1.0e-35 + swdns), &
Time_diag, is, js )
endif
!------- surface visible albedo -------------------------
if ( id_alb_sfc_vis_dir > 0 ) then
used = send_data ( id_alb_sfc_vis_dir, &
100.*Surface%asfc_vis_dir, Time_diag, is, js )
endif
if ( id_alb_sfc_vis_dif > 0 ) then
used = send_data ( id_alb_sfc_vis_dif, &
100.*Surface%asfc_vis_dif, Time_diag, is, js )
endif
!------- surface nir albedo -------------------------
if ( id_alb_sfc_nir_dir > 0 ) then
used = send_data ( id_alb_sfc_nir_dir, &
100.*Surface%asfc_nir_dir, Time_diag, is, js )
endif
if ( id_alb_sfc_nir_dif > 0 ) then
used = send_data ( id_alb_sfc_nir_dif, &
100.*Surface%asfc_nir_dif, Time_diag, is, js )
endif
!------- surface net sw flux, direct and diffuse --------------------
if ( id_flux_sw_dir > 0 ) then
used = send_data ( id_flux_sw_dir, &
Rad_output%flux_sw_surf_dir( is:ie,js:je,nz), Time_diag, &
is, js )
endif
if ( id_flux_sw_dif > 0 ) then
used = send_data ( id_flux_sw_dif, &
Rad_output%flux_sw_surf_dif(is:ie,js:je,nz), Time_diag, &
is, js )
endif
!------- surface downward visible sw flux, direct and diffuse ----------
if ( id_flux_sw_down_vis_dir > 0 ) then
used = send_data ( id_flux_sw_down_vis_dir, &
Rad_output%flux_sw_down_vis_dir(is:ie,js:je,nz), &
Time_diag, is, js )
endif
if ( id_flux_sw_down_vis_dif > 0 ) then
used = send_data ( id_flux_sw_down_vis_dif, &
Rad_output%flux_sw_down_vis_dif(is:ie, js:je,nz), &
Time_diag, is, js )
endif
!------- surface downward total sw flux, direct and diffuse ----------
if ( id_flux_sw_down_total_dir > 0 ) then
used = send_data ( id_flux_sw_down_total_dir, &
Rad_output%flux_sw_down_total_dir(is:ie,js:je,nz), &
Time_diag, is, js )
endif
if ( id_flux_sw_down_total_dif > 0 ) then
used = send_data ( id_flux_sw_down_total_dif, &
Rad_output%flux_sw_down_total_dif(is:ie,js:je,nz), &
Time_diag, is, js )
endif
if (do_clear_sky_pass) then
!------- surface downward total sw flux, direct and diffuse ----------
if ( id_flux_sw_down_total_dir_clr > 0 ) then
used = send_data ( id_flux_sw_down_total_dir_clr, &
Rad_output%flux_sw_down_total_dir_clr(is:ie,js:je,nz),&
Time_diag, is, js )
endif
if ( id_flux_sw_down_total_dif_clr > 0 ) then
used = send_data ( id_flux_sw_down_total_dif_clr, &
Rad_output%flux_sw_down_total_dif_clr(is:ie,js:je,nz), &
Time_diag, is, js )
endif
if ( id_flux_sw_down_vis_clr > 0 ) then
used = send_data ( id_flux_sw_down_vis_clr, &
Rad_output%flux_sw_down_vis_clr(is:ie, js:je,nz), &
Time_diag, is, js )
endif
endif
!------- surface net visible sw flux, total, direct and diffuse -------
if ( id_flux_sw_vis > 0 ) then
used = send_data ( id_flux_sw_vis, &
Rad_output%flux_sw_vis(is:ie,js:je,nz), Time_diag, is, js )
endif
if ( id_flux_sw_vis_dir > 0 ) then
used = send_data ( id_flux_sw_vis_dir, &
Rad_output%flux_sw_vis_dir(is:ie,js:je,nz), Time_diag, is, js )
endif
if ( id_flux_sw_vis_dif > 0 ) then
used = send_data ( id_flux_sw_vis_dif, &
Rad_output%flux_sw_vis_dif(is:ie,js:je,nz), Time_diag, is, js )
endif
!------- cosine of zenith angle ----------------
if ( id_cosz > 0 ) then
used = send_data ( id_cosz, Astro%cosz, Time_diag, is, js )
endif
!------- daylight fraction --------------
if ( id_fracday > 0 ) then
used = send_data (id_fracday, Astro%fracday, Time_diag, &
is, js )
end if
endif
endif ! (renormalize_sw_fluxes .or. do_rad .or.
! all_step_diagnostics)
!---------------------------------------------------------------------
! define the longwave diagnostic arrays for the sea-esf radiation
! package. convert to mks units.
!---------------------------------------------------------------------
if (do_sea_esf_rad) then
! if (do_rad) then
if (do_lw_rad) then
olr (:,:) = Lw_output(1)%flxnet(:,:,1)
lwups(:,:) = STEFAN*ts(:,: )**4
lwdns(:,:) = lwups(:,:) - Lw_output(1)%flxnet(:,:,kmax+1)
tdtlw(:,:,:) = Lw_output(1)%heatra(:,:,:)/ SECONDS_PER_DAY
netlw_trop(:,:,:) = Lw_output(1)%netlw_special(:,:,:)
flxnet(:,:,:) = Lw_output(1)%flxnet(:,:,:)
if (do_lwaerosol_forcing) then
olr_ad (:,:) = Lw_output(indx_lwaf)%flxnet(:,:,1)
lwups_ad(:,:) = STEFAN*ts(:,: )**4
lwdns_ad(:,:) = lwups_ad(:,:) - &
Lw_output(indx_lwaf)%flxnet(:,:,kmax+1)
endif
if (do_clear_sky_pass) then
olr_clr (:,:) = Lw_output(1)%flxnetcf(:,:,1)
lwups_clr(:,:) = STEFAN*ts(:,: )**4
lwdns_clr(:,:) = lwups_clr(:,:) - &
Lw_output(1)%flxnetcf(:,:,kmax+1)
tdtlw_clr(:,:,:) = Lw_output(1)%heatracf(:,:,:)/SECONDS_PER_DAY
netlw_trop_clr(:,:,:) = Lw_output(1)%netlw_special_clr(:,:,:)
flxnetcf(:,:,:) = Lw_output(1)%flxnetcf(:,:,:)
if (do_lwaerosol_forcing) then
olr_ad_clr (:,:) = Lw_output(indx_lwaf)%flxnetcf(:,:,1)
lwups_ad_clr(:,:) = STEFAN*ts(:,: )**4
lwdns_ad_clr(:,:) = lwups_ad_clr(:,:) - &
Lw_output(indx_lwaf)%flxnetcf(:,:,kmax+1)
endif
endif
!---------------------------------------------------------------------
! if diagnostics are desired on all physics steps, save the arrays
! for later use.
!---------------------------------------------------------------------
if (all_step_diagnostics) then
if (do_lwaerosol_forcing) then
olr_ad_save (is:ie,js:je) = olr_ad(:,:)
lwups_ad_save(is:ie,js:je) = lwups_ad(:,:)
lwdns_ad_save(is:ie,js:je) = lwdns_ad(:,:)
endif
olr_save (is:ie,js:je) = olr(:,:)
lwups_save(is:ie,js:je) = lwups(:,:)
lwdns_save(is:ie,js:je) = lwdns(:,:)
tdtlw_save(is:ie,js:je,:) = tdtlw(:,:,:)
flxnet_save(is:ie,js:je,:) = Lw_output(1)%flxnet(:,:,:)
netlw_special_save(is:ie,js:je,:) = netlw_trop(:,:,:)
if (do_clear_sky_pass) then
if (do_lwaerosol_forcing) then
olr_ad_clr_save (is:ie,js:je) = olr_ad_clr(:,:)
lwups_ad_clr_save(is:ie,js:je) = lwups_ad_clr(:,:)
lwdns_ad_clr_save(is:ie,js:je) = lwdns_ad_clr(:,:)
endif
olr_clr_save (is:ie,js:je) = olr_clr(:,:)
flxnetcf_save(is:ie,js:je,:) = Lw_output(1)%flxnetcf(:,:,:)
lwups_clr_save(is:ie,js:je) = lwups_clr(:,:)
lwdns_clr_save(is:ie,js:je) = lwdns_clr(:,:)
tdtlw_clr_save(is:ie,js:je,:) = tdtlw_clr(:,:,:)
netlw_special_clr_save(is:ie,js:je,:) = &
netlw_trop_clr(:,:,:)
endif
endif
!---------------------------------------------------------------------
! if this is not a radiation step, but diagnostics are desired,
! define the fields from the xxx_save variables.
!---------------------------------------------------------------------
! else if (all_step_diagnostics) then ! (do_rad)
else if (all_step_diagnostics) then ! (do_lw_rad)
if (do_lwaerosol_forcing) then
olr_ad(:,:) = olr_ad_save (is:ie,js:je)
lwups_ad(:,:) = lwups_ad_save(is:ie,js:je)
lwdns_ad(:,:) = lwdns_ad_save(is:ie,js:je)
endif
olr(:,:) = olr_save (is:ie,js:je)
lwups(:,:) = lwups_save(is:ie,js:je)
lwdns(:,:) = lwdns_save(is:ie,js:je)
tdtlw(:,:,:) = tdtlw_save(is:ie,js:je,:)
flxnet(:,:,:) = flxnet_save(is:ie,js:je,:)
netlw_trop(:,:,:) = netlw_special_save(is:ie,js:je,:)
if (do_clear_sky_pass) then
if (do_lwaerosol_forcing) then
olr_ad_clr(:,:) = olr_ad_clr_save (is:ie,js:je)
lwups_ad_clr(:,:) = lwups_ad_clr_save(is:ie,js:je)
lwdns_ad_clr(:,:) = lwdns_ad_clr_save(is:ie,js:je)
endif
olr_clr(:,:) = olr_clr_save (is:ie,js:je)
lwups_clr(:,:) = lwups_clr_save(is:ie,js:je)
lwdns_clr(:,:) = lwdns_clr_save(is:ie,js:je)
tdtlw_clr(:,:,:) = tdtlw_clr_save(is:ie,js:je,:)
flxnetcf (:,:,:) = flxnetcf_save(is:ie,js:je,:)
netlw_trop_clr(:,:,:) = &
netlw_special_clr_save(is:ie,js:je,:)
endif
endif
!---------------------------------------------------------------------
! on radiation steps, define the longwave diagnostic arrays for the
! original_fms_rad package.
!---------------------------------------------------------------------
else ! original fms rad
if (do_lw_rad) then
olr (:,:) = Fsrad_output%olr(:,:)
lwups(:,:) = Fsrad_output%lwups(:,:)
lwdns(:,:) = Fsrad_output%lwdns(:,:)
tdtlw(:,:,:) = Fsrad_output%tdtlw(:,:,:)
if (do_clear_sky_pass) then
olr_clr (:,:) = Fsrad_output%olr_clr(:,:)
lwups_clr(:,:) = Fsrad_output%lwups_clr(:,:)
lwdns_clr(:,:) = Fsrad_output%lwdns_clr(:,:)
tdtlw_clr(:,:,:) = Fsrad_output%tdtlw_clr(:,:,:)
endif
endif
endif ! do_sea_esf_rad
if (do_lw_rad .or. all_step_diagnostics) then
if (Time_diag > Time) then
!---------------------------------------------------------------------
! send standard lw diagnostics to diag_manager.
!---------------------------------------------------------------------
if (do_clear_sky_pass) then
ipass = 2
else
ipass = 1
endif
!---- net lw flux ---------
if (id_flxnet(ipass) > 0 ) then
used = send_data (id_flxnet(ipass), &
flxnet, &
Time_diag, is, js, 1, rmask=mask )
endif
!------- lw tendency -----------
if (id_tdt_lw(ipass) > 0 ) then
used = send_data (id_tdt_lw(ipass), tdtlw, &
Time_diag, is, js, 1, rmask=mask )
endif
!------- outgoing lw flux toa (olr) -------
if (id_olr(ipass) > 0 ) then
used = send_data (id_olr(ipass), olr, &
Time_diag, is, js )
endif
!------- net radiation (lw + sw) at toa -------
if (id_netrad_toa(ipass) > 0 ) then
used = send_data (id_netrad_toa(ipass), &
swin - swout - olr, &
Time_diag, is, js )
endif
!------- net radiation (lw + sw) at 1 Pa-------
if (id_netrad_1_Pa(ipass) > 0 ) then
used = send_data (id_netrad_1_Pa(ipass), &
swdn_trop(:,:,4) -swup_trop(:,:,4) -netlw_trop(:,:,4), &
Time_diag, is, js )
endif
!------- net lw flux trop (netlw_trop) -------
if (id_netlw_special(1,ipass) > 0 ) then
used = send_data (id_netlw_special(1, ipass), &
netlw_trop(:,:,1), &
Time_diag, is, js )
endif
!------- net lw flux trop (netlw_trop) -------
if (id_netlw_special(2,ipass) > 0 ) then
used = send_data (id_netlw_special(2, ipass), &
netlw_trop(:,:,2), &
Time_diag, is, js )
endif
!------- net lw flux trop (netlw_trop) -------
if (id_netlw_special(3,ipass) > 0 ) then
used = send_data (id_netlw_special(3, ipass), &
netlw_trop(:,:,3), &
Time_diag, is, js )
endif
!------- net lw flux 1 Pa (netlw_trop) -------
if (id_netlw_special(4,ipass) > 0 ) then
used = send_data (id_netlw_special(4, ipass), &
netlw_trop(:,:,4), &
Time_diag, is, js )
endif
!------- upward lw flux surface -------
if ( id_lwup_sfc(ipass) > 0 ) then
used = send_data (id_lwup_sfc(ipass), lwups, &
Time_diag, is, js )
endif
!------- downward lw flux surface -------
if (id_lwdn_sfc(ipass) > 0 ) then
used = send_data (id_lwdn_sfc(ipass), lwdns, &
Time_diag, is, js )
endif
!------- net lw flux surface -------
if ( id_lwsfc(ipass) > 0 ) then
used = send_data (id_lwsfc(ipass), lwups-lwdns, &
Time_diag, is, js )
endif
if (do_lwaerosol_forcing) then
!------- outgoing lw flux toa (olr) with aerosols-------
if (id_olr_ad(ipass) > 0 ) then
used = send_data (id_olr_ad(ipass), olr_ad, &
Time_diag, is, js )
endif
!------- net lw flux surface -------
if ( id_lwsfc_ad(ipass) > 0 ) then
used = send_data (id_lwsfc_ad(ipass), lwups_ad-lwdns_ad, &
Time_diag, is, js )
endif
endif
!----------------------------------------------------------------------
! now pass clear-sky diagnostics, if they have been calculated.
!----------------------------------------------------------------------
if (do_clear_sky_pass) then
ipass = 1
!---- net lw flux ---------
if (id_flxnet(ipass) > 0 ) then
used = send_data (id_flxnet(ipass), &
flxnetcf, &
Time_diag, is, js, 1, rmask=mask )
endif
!------- lw tendency -----------
if (id_tdt_lw(ipass) > 0 ) then
used = send_data (id_tdt_lw(ipass), tdtlw_clr, &
Time_diag, is, js, 1, rmask=mask )
endif
!------- outgoing lw flux toa (olr) -------
if (id_olr(ipass) > 0 ) then
used = send_data (id_olr(ipass), olr_clr, &
Time_diag, is, js )
endif
!------- net radiation (lw + sw) toa -------
if (id_netrad_toa(ipass) > 0 ) then
used = send_data (id_netrad_toa(ipass), &
swin_clr - swout_clr - olr_clr, &
Time_diag, is, js )
endif
!------- net lw flux trop (netlw_trop) -------
if (id_netlw_special(1,ipass) > 0 ) then
used = send_data (id_netlw_special(1, ipass), &
netlw_trop_clr(:,:,1), &
Time_diag, is, js )
endif
!------- net lw flux trop (netlw_trop) -------
if (id_netlw_special(2,ipass) > 0 ) then
used = send_data (id_netlw_special(2, ipass), &
netlw_trop_clr(:,:,2), &
Time_diag, is, js )
endif
!------- net lw flux trop (netlw_trop) -------
if (id_netlw_special(3,ipass) > 0 ) then
used = send_data (id_netlw_special(3, ipass), &
netlw_trop_clr(:,:,3), &
Time_diag, is, js )
endif
!------- upward lw flux surface -------
if (id_lwup_sfc(ipass) > 0 ) then
used = send_data (id_lwup_sfc(ipass), lwups_clr, &
Time_diag, is, js )
endif
!------- downward lw flux surface -------
if (id_lwdn_sfc(ipass) > 0 ) then
used = send_data (id_lwdn_sfc(ipass), lwdns_clr, &
Time_diag, is, js )
endif
!------- net lw flux surface -------
if ( id_lwsfc(ipass) > 0 ) then
used = send_data (id_lwsfc(ipass), lwups_clr-lwdns_clr, &
Time_diag, is, js )
endif
if (do_lwaerosol_forcing) then
!------- outgoing lw flux toa (olr) with aerosols-------
if (id_olr_ad(ipass) > 0 ) then
used = send_data (id_olr_ad(ipass), olr_ad_clr, &
Time_diag, is, js )
endif
!------- net lw flux surface -------
if ( id_lwsfc_ad(ipass) > 0 ) then
used = send_data (id_lwsfc_ad(ipass), lwups_ad_clr-lwdns_ad_clr, &
Time_diag, is, js )
endif
endif
endif ! (do_clear_sky_pass)
endif
endif ! (do_lw_rad .or. all_step_diagnostics)
!--------------------------------------------------------------------
! now define various diagnostic integrals.
!--------------------------------------------------------------------
!--------------------------------------------------------------------
! accumulate global integral quantities
!--------------------------------------------------------------------
olr_intgl(is:ie,js:je) = olr(:,:)
swabs_intgl(is:ie,js:je) = swin(:,:) - swout(:,:)
! call sum_diag_integral_field ('olr_clr', olr_clr, is, js)
! call sum_diag_integral_field ('abs_sw_clr', &
! swin_clr-swout_clr, is, js)
!--------------------------------------------------------------------
! accumulate hemispheric integral quantities, if desired.
!--------------------------------------------------------------------
if (calc_hemi_integrals) then
do j=js,je
jind = j - js + 1
iind = 1 ! are assuming all i points are at same latitude
!---------------------------------------------------------------------
! calculate southern hemisphere integrals.
!---------------------------------------------------------------------
if (lat(iind,jind) <= 0.0) then
call sum_diag_integral_field ('sntop_tot_sh ', &
swin-swout, is, ie, j, j)
call sum_diag_integral_field ('lwtop_tot_sh ', olr, &
is, ie, j, j)
call sum_diag_integral_field ('sngrd_tot_sh ', &
swdns-swups, is, ie, j, j)
call sum_diag_integral_field ('lwgrd_tot_sh ', &
Lw_output(1)%flxnet(:,:,kmax+1),&
is, ie, j, j)
if (do_clear_sky_pass) then
call sum_diag_integral_field ('sntop_clr_sh ', &
swin_clr-swout_clr, &
is, ie, j, j)
call sum_diag_integral_field ('lwtop_clr_sh ', olr_clr,&
is, ie, j, j)
call sum_diag_integral_field ('sngrd_clr_sh ', &
swdns_clr-swups_clr, &
is, ie, j, j)
call sum_diag_integral_field ('lwgrd_clr_sh ', &
Lw_output(1)%flxnetcf(:,:,kmax+1),&
is, ie, j, j)
endif
!---------------------------------------------------------------------
! calculate northern hemisphere integrals.
!---------------------------------------------------------------------
else
call sum_diag_integral_field ('sntop_tot_nh ', &
swin-swout, is, ie, j, j)
call sum_diag_integral_field ('lwtop_tot_nh ', olr, &
is, ie, j, j)
call sum_diag_integral_field ('sngrd_tot_nh ', &
swdns-swups, is, ie, j, j)
call sum_diag_integral_field ('lwgrd_tot_nh ', &
Lw_output(1)%flxnet(:,:,kmax+1),&
is, ie, j, j)
if (do_clear_sky_pass) then
call sum_diag_integral_field ('sntop_clr_nh ', &
swin_clr-swout_clr, &
is, ie, j, j)
call sum_diag_integral_field ('lwtop_clr_nh ', olr_clr,&
is, ie, j, j)
call sum_diag_integral_field ('sngrd_clr_nh ', &
swdns_clr-swups_clr, &
is, ie, j, j)
call sum_diag_integral_field ('lwgrd_clr_nh ', &
Lw_output(1)%flxnetcf(:,:,kmax+1),&
is, ie, j, j)
endif
endif
end do
!--------------------------------------------------------------------
! accumulate global integral quantities
!--------------------------------------------------------------------
call sum_diag_integral_field ('sntop_tot_gl ', swin-swout, &
is, js)
call sum_diag_integral_field ('lwtop_tot_gl ', olr, is, js)
call sum_diag_integral_field ('sngrd_tot_gl ', swdns-swups, &
is, js)
call sum_diag_integral_field ('lwgrd_tot_gl ', &
Lw_output(1)%flxnet(:,:,kmax+1), is, js)
if (do_clear_sky_pass) then
call sum_diag_integral_field ('sntop_clr_gl ', &
swin_clr-swout_clr, is, js)
call sum_diag_integral_field ('lwtop_clr_gl ', olr_clr, &
is, js)
call sum_diag_integral_field ('sngrd_clr_gl ', &
swdns_clr-swups_clr, is, js)
call sum_diag_integral_field ('lwgrd_clr_gl ', &
Lw_output(1)%flxnetcf(:,:,kmax+1),&
is, js)
endif
endif ! (calc_hemi_integrals)
!---------------------------------------------------------------------
end subroutine produce_radiation_diagnostics
!###################################################################
!
!
! deallocate_arrays deallocates the array space of local
! derived-type variables.
!
!
! deallocate_arrays deallocates the array space of local
! derived-type variables.
!
!
! call deallocate_arrays (Cldrad_props, Astro, Astro2, Lw_output, &
! Fsrad_output, Sw_output)
!
!
! Cloud radiative properties
!
!
! astronomical data for the radiation package
!
!
! astronomical data for the radiation package
!
!
! radiation output data from the
! original_fms_rad radiation package, when that
! package is active
!
!
! longwave radiation output data from the
! sea_esf_rad radiation package, when that
! package is active
!
!
! shortwave radiation output data from the
! sea_esf_rad radiation package when that
! package is active
!
!
!
subroutine deallocate_arrays (Cldrad_props, Astro, Astro2, &
Aerosol_props, Lw_output, &
Fsrad_output, Sw_output, Aerosol_diags)
!---------------------------------------------------------------------
! deallocate_arrays deallocates the array space of local
! derived-type variables.
!---------------------------------------------------------------------
type(cldrad_properties_type), intent(inout) :: Cldrad_props
type(astronomy_type) , intent(inout) :: Astro, Astro2
type(aerosol_properties_type), intent(inout) :: Aerosol_props
type(lw_output_type),dimension(:), intent(inout) :: Lw_output
type(fsrad_output_type) , intent(inout) :: Fsrad_output
type(sw_output_type),dimension(:), intent(inout) :: Sw_output
type(aerosol_diagnostics_type), intent(inout) :: Aerosol_diags
integer :: n
!--------------------------------------------------------------------
! deallocate the variables in Aerosol_props.
!--------------------------------------------------------------------
if ( do_rad .and. Rad_control%do_aerosol) then
if (Rad_control%volcanic_sw_aerosols) then
deallocate (Aerosol_props%sw_ext)
deallocate (Aerosol_props%sw_ssa)
deallocate (Aerosol_props%sw_asy)
endif
if (Rad_control%volcanic_lw_aerosols) then
deallocate (Aerosol_props%lw_ext)
deallocate (Aerosol_props%lw_ssa)
deallocate (Aerosol_props%lw_asy)
endif
deallocate (Aerosol_props%ivol)
if (Sw_control%do_swaerosol .or. &
Rad_control%do_swaerosol_forcing) then
deallocate (Aerosol_props%aerextband)
deallocate (Aerosol_props%aerssalbband)
deallocate (Aerosol_props%aerasymmband)
endif
if (Lw_control%do_lwaerosol .or. &
Rad_control%do_lwaerosol_forcing) then
deallocate (Aerosol_props%aerextbandlw)
deallocate (Aerosol_props%aerssalbbandlw)
deallocate (Aerosol_props%aerextbandlw_cn)
deallocate (Aerosol_props%aerssalbbandlw_cn)
endif
deallocate (Aerosol_props%sulfate_index)
deallocate (Aerosol_props%optical_index)
deallocate (Aerosol_props%omphilic_index)
deallocate (Aerosol_props%bcphilic_index)
deallocate (Aerosol_props%seasalt1_index)
deallocate (Aerosol_props%seasalt2_index)
deallocate (Aerosol_props%seasalt3_index)
deallocate (Aerosol_props%seasalt4_index)
deallocate (Aerosol_props%seasalt5_index)
endif
!--------------------------------------------------------------------
! deallocate the variables in Astro and Astro2.
!--------------------------------------------------------------------
if ( do_rad .or. renormalize_sw_fluxes ) then
deallocate (Astro%solar)
deallocate (Astro%cosz )
deallocate (Astro%fracday)
deallocate (Astro%solar_p)
deallocate (Astro%cosz_p )
deallocate (Astro%fracday_p)
if ( do_sw_rad .and. renormalize_sw_fluxes &
.and. Sw_control%do_diurnal ) then
deallocate (Astro2%solar)
deallocate (Astro2%cosz )
deallocate (Astro2%fracday)
endif
endif
!--------------------------------------------------------------------
! deallocate the variables in Lw_output.
!--------------------------------------------------------------------
if (do_sea_esf_rad) then
if (do_lw_rad) then
do n=1,size_of_lwoutput
deallocate (Lw_output(n)%heatra )
deallocate (Lw_output(n)%flxnet )
deallocate (Lw_output(n)%netlw_special)
deallocate (Lw_output(n)%bdy_flx)
if (Rad_control%do_totcld_forcing) then
deallocate (Lw_output(n)%heatracf )
deallocate (Lw_output(n)%flxnetcf )
deallocate (Lw_output(n)%netlw_special_clr)
deallocate (Lw_output(n)%bdy_flx_clr)
endif
end do
endif
!--------------------------------------------------------------------
! deallocate the variables in Sw_output.
!--------------------------------------------------------------------
if (do_sw_rad) then
do n=1,size_of_swoutput
deallocate (Sw_output(n)%dfsw )
deallocate (Sw_output(n)%ufsw )
deallocate (Sw_output(n)%dfsw_dir_sfc )
deallocate (Sw_output(n)%dfsw_dif_sfc )
deallocate (Sw_output(n)%ufsw_dif_sfc )
deallocate (Sw_output(n)%fsw )
deallocate (Sw_output(n)%hsw )
deallocate (Sw_output(n)%dfsw_vis_sfc )
deallocate (Sw_output(n)%ufsw_vis_sfc )
deallocate (Sw_output(n)%dfsw_vis_sfc_dir )
deallocate (Sw_output(n)%dfsw_vis_sfc_dif )
deallocate (Sw_output(n)%ufsw_vis_sfc_dif )
deallocate (Sw_output(n)%swdn_special)
deallocate (Sw_output(n)%swup_special)
deallocate (Sw_output(n)%bdy_flx)
if (Rad_control%do_totcld_forcing) then
deallocate (Sw_output(n)%dfswcf )
deallocate (Sw_output(n)%ufswcf )
deallocate (Sw_output(n)%fswcf )
deallocate (Sw_output(n)%hswcf )
deallocate (Sw_output(n)%dfsw_dir_sfc_clr)
deallocate (Sw_output(n)%dfsw_dif_sfc_clr)
deallocate (Sw_output(n)%dfsw_vis_sfc_clr)
deallocate (Sw_output(n)%swdn_special_clr)
deallocate (Sw_output(n)%swup_special_clr)
deallocate (Sw_output(n)%bdy_flx_clr)
endif
end do
endif
endif
!--------------------------------------------------------------------
! call cldrad_props_dealloc to deallocate the variables in
! Cldrad_props.
!--------------------------------------------------------------------
if (do_rad .and. do_sea_esf_rad) then
call cldrad_props_dealloc (Cldrad_props)
endif
!--------------------------------------------------------------------
! deallocate the variables in Fsrad_output.
!--------------------------------------------------------------------
if (.not. do_sea_esf_rad .and. do_rad) then
deallocate (Fsrad_output%tdtsw )
deallocate (Fsrad_output%tdtlw )
deallocate (Fsrad_output%swdns )
deallocate (Fsrad_output%swups )
deallocate (Fsrad_output%lwdns )
deallocate (Fsrad_output%lwups )
deallocate (Fsrad_output%swin )
deallocate (Fsrad_output%swout )
deallocate (Fsrad_output%olr )
if (do_clear_sky_pass) then
deallocate (Fsrad_output%tdtsw_clr )
deallocate (Fsrad_output%tdtlw_clr )
deallocate (Fsrad_output%swdns_clr )
deallocate (Fsrad_output%swups_clr )
deallocate (Fsrad_output%lwdns_clr )
deallocate (Fsrad_output%lwups_clr )
deallocate (Fsrad_output%swin_clr )
deallocate (Fsrad_output%swout_clr )
deallocate (Fsrad_output%olr_clr )
endif
endif
!--------------------------------------------------------------------
! deallocate the window-resident variables in Aerosol_props.
!--------------------------------------------------------------------
if (do_rad .and. Rad_control%do_aerosol) then
deallocate (Aerosol_diags%extopdep)
deallocate (Aerosol_diags%absopdep)
deallocate (Aerosol_diags%extopdep_vlcno)
deallocate (Aerosol_diags%absopdep_vlcno)
deallocate (Aerosol_diags%sw_heating_vlcno)
deallocate (Aerosol_diags%lw_extopdep_vlcno)
deallocate (Aerosol_diags%lw_absopdep_vlcno)
endif
!---------------------------------------------------------------------
end subroutine deallocate_arrays
!#####################################################################
!
!
! calculate_auxiliary_variables defines values of model delta z and
! relative humidity, and the values of pressure and temperature at
! the grid box vertical interfaces.
!
!
! calculate_auxiliary_variables defines values of model delta z and
! relative humidity, and the values of pressure and temperature at
! the grid box vertical interfaces.
!
!
! call calculate_auxiliary_variables (Atmos_input)
!
!
! atmos_input_type variable, its press and temp
! components are input, and its deltaz, rel_hum,
! pflux, tflux and aerosolrelhum components are
! calculated here and output.
!
!
!
subroutine calculate_auxiliary_variables (Atmos_input)
!----------------------------------------------------------------------
! calculate_auxiliary_variables defines values of model delta z and
! relative humidity, and the values of pressure and temperature at
! the grid box vertical interfaces.
!---------------------------------------------------------------------
type(atmos_input_type), intent(inout) :: Atmos_input
!--------------------------------------------------------------------
! intent(inout) variables
!
! Atmos_input atmos_input_type variable, its press and temp
! components are input, and its deltaz, rel_hum,
! pflux, tflux and aerosolrelhum components are
! calculated here and output.
!
!---------------------------------------------------------------------
!----------------------------------------------------------------------
! local variables
real, dimension (size(Atmos_input%temp, 1), &
size(Atmos_input%temp, 2), &
size(Atmos_input%temp, 3) - 1) :: &
esat, qsat, qv, tv
integer :: k
integer :: kmax
!--------------------------------------------------------------------
! define flux level pressures (pflux) as midway between data level
! (layer-mean) pressures. specify temperatures at flux levels
! (tflux).
!--------------------------------------------------------------------
do k=ks+1,ke
Atmos_input%pflux(:,:,k) = 0.5E+00* &
(Atmos_input%press(:,:,k-1) + Atmos_input%press(:,:,k))
Atmos_input%tflux(:,:,k) = 0.5E+00* &
(Atmos_input%temp (:,:,k-1) + Atmos_input%temp (:,:,k))
end do
Atmos_input%pflux(:,:,ks ) = 0.0E+00
Atmos_input%pflux(:,:,ke+1) = Atmos_input%press(:,:,ke+1)
Atmos_input%tflux(:,:,ks ) = Atmos_input%temp (:,:,ks )
Atmos_input%tflux(:,:,ke+1) = Atmos_input%temp (:,:,ke+1)
!-------------------------------------------------------------------
! define deltaz in meters.
!-------------------------------------------------------------------
tv(:,:,:) = Atmos_input%temp(:,:,ks:ke)* &
(1.0 + D608*Atmos_input%rh2o(:,:,:))
Atmos_input%deltaz(:,:,ks) = log_p_at_top*RDGAS*tv(:,:,ks)/GRAV
do k =ks+1,ke
Atmos_input%deltaz(:,:,k) = alog(Atmos_input%pflux(:,:,k+1)/ &
Atmos_input%pflux(:,:,k))* &
RDGAS*tv(:,:,k)/GRAV
end do
!-------------------------------------------------------------------
! define deltaz in meters to be used in cloud feedback analysis.
!-------------------------------------------------------------------
tv(:,:,:) = Atmos_input%cloudtemp(:,:,ks:ke)* &
(1.0 + D608*Atmos_input%cloudvapor(:,:,:))
Atmos_input%clouddeltaz(:,:,ks) = log_p_at_top*RDGAS* &
tv(:,:,ks)/GRAV
do k =ks+1,ke
Atmos_input%clouddeltaz(:,:,k) = &
alog(Atmos_input%pflux(:,:,k+1)/ &
Atmos_input%pflux(:,:,k))* &
RDGAS*tv(:,:,k)/GRAV
end do
!------------------------------------------------------------------
! define the relative humidity.
!------------------------------------------------------------------
kmax = size(Atmos_input%temp,3) - 1
qv(:,:,1:kmax) = Atmos_input%rh2o(:,:,1:kmax) / &
(1.0 + Atmos_input%rh2o(:,:,1:kmax))
call compute_qs (Atmos_input%temp(:,:,1:kmax), &
Atmos_input%press(:,:,1:kmax), &
qsat(:,:,1:kmax), q = qv(:,:,1:kmax))
do k=1,kmax
Atmos_input%rel_hum(:,:,k) = qv(:,:,k) / qsat(:,:,k)
Atmos_input%rel_hum(:,:,k) = &
MIN (Atmos_input%rel_hum(:,:,k), 1.0)
end do
!------------------------------------------------------------------
! define the relative humidity seen by the aerosol code.
!------------------------------------------------------------------
qv(:,:,1:kmax) = Atmos_input%aerosolvapor(:,:,1:kmax) / &
(1.0 + Atmos_input%aerosolvapor(:,:,1:kmax))
call compute_qs (Atmos_input%aerosoltemp(:,:,1:kmax), &
Atmos_input%aerosolpress(:,:,1:kmax), &
qsat(:,:,1:kmax), q = qv(:,:,1:kmax))
do k=1,kmax
Atmos_input%aerosolrelhum(:,:,k) = qv(:,:,k) / qsat(:,:,k)
Atmos_input%aerosolrelhum(:,:,k) = &
MIN (Atmos_input%aerosolrelhum(:,:,k), 1.0)
end do
!----------------------------------------------------------------------
end subroutine calculate_auxiliary_variables
!#######################################################################
end module radiation_driver_mod