diff --git a/.gitignore b/.gitignore index 2213ac9bc..ff0eb4314 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,7 @@ # Auto-generated include files in Fortran code *.inc +physics/*cap.F90 +physics/*.xml +*.cmake +*.mk +*.html diff --git a/physics/GFS_rrtmg_pre.F90 b/physics/GFS_rrtmg_pre.F90 index 2e51e305f..8b930d370 100644 --- a/physics/GFS_rrtmg_pre.F90 +++ b/physics/GFS_rrtmg_pre.F90 @@ -11,7 +11,6 @@ module GFS_rrtmg_pre !! \section arg_table_GFS_rrtmg_pre_init Argument Table !! subroutine GFS_rrtmg_pre_init () - open(58,file='GFS_rrtmg_aux_dump.txt',status='unknown') end subroutine GFS_rrtmg_pre_init !> \section arg_table_GFS_rrtmg_pre_run Argument Table @@ -325,7 +324,7 @@ subroutine GFS_rrtmg_pre_run (Model, Grid, Sfcprop, Statein, & ! input tracer1(:,k1,j) = max(0.0, Statein%qgrs(:,k2,j)) enddo enddo -! + if (ivflip == 0) then ! input data from toa to sfc do i = 1, IM plvl(i,1+kd) = 0.01 * Statein%prsi(i,1) ! pa to mb (hpa) @@ -704,7 +703,39 @@ subroutine GFS_rrtmg_pre_run (Model, Grid, Sfcprop, Statein, & ! input ccnd(1:IM,1:LMK,1) = ccnd(1:IM,1:LMK,1) + cnvw(1:IM,1:LMK) + ccnd(1:IM,1:LMK,2) endif -! DJS2019: START + if (Model%uni_cld) then + if (Model%effr_in) then + do k=1,lm + k1 = k + kd + do i=1,im + cldcov(i,k1) = Tbd%phy_f3d(i,k,Model%indcld) + effrl(i,k1) = Tbd%phy_f3d(i,k,2) + effri(i,k1) = Tbd%phy_f3d(i,k,3) + effrr(i,k1) = Tbd%phy_f3d(i,k,4) + effrs(i,k1) = Tbd%phy_f3d(i,k,5) + enddo + enddo + else + do k=1,lm + k1 = k + kd + do i=1,im + cldcov(i,k1) = Tbd%phy_f3d(i,k,Model%indcld) + if (tracer1(i,k,ntcw) .gt. 0 .or. tracer1(i,k,ntiw) .gt. 0) then + cldcov(i,k1) = 0.1 + else + cldcov(i,k1) = 0.0 + endif + enddo + enddo + endif + elseif (Model%imp_physics == Model%imp_physics_gfdl) then ! GFDL MP + cldcov(1:IM,1+kd:LM+kd) = tracer1(1:IM,1:LM,Model%ntclamt) + else ! neither of the other two cases + cldcov = 0.0 + endif + + + ! DJS2019: START Hack ! Compute layer cloud fraction. clwmin = 0.0 cldcov(:,:) = 0.0 @@ -743,51 +774,8 @@ subroutine GFS_rrtmg_pre_run (Model, Grid, Sfcprop, Statein, & ! input enddo enddo endif -! DJS2019: END + ! DJS2019: END - if (Model%uni_cld) then - if (Model%effr_in) then - do k=1,lm - k1 = k + kd - do i=1,im - cldcov(i,k1) = Tbd%phy_f3d(i,k,Model%indcld) - effrl(i,k1) = Tbd%phy_f3d(i,k,2) - effri(i,k1) = Tbd%phy_f3d(i,k,3) - effrr(i,k1) = Tbd%phy_f3d(i,k,4) - effrs(i,k1) = Tbd%phy_f3d(i,k,5) - enddo - enddo - else - do k=1,lm - k1 = k + kd - do i=1,im - ! DJS2019: Tbd%phy_f3d(:,:,1) is mean layer temperature, not cloud amount - !cldcov(i,k1) = Tbd%phy_f3d(i,k,Model%indcld) - !if (tracer1(i,k,ntcw) .gt. 0 .or. tracer1(i,k,ntiw) .gt. 0) then - ! cldcov(i,k1) = 0.1 - !else - ! cldcov(i,k1) = 0.0 - !endif - enddo - enddo - endif - elseif (Model%imp_physics == Model%imp_physics_gfdl) then ! GFDL MP - cldcov(1:IM,1+kd:LM+kd) = tracer1(1:IM,1:LM,Model%ntclamt) - else ! neither of the other two cases - !cldcov = 0.0 - endif - - write(58,*) "Model%imp_physics: ",Model%imp_physics - write(58,*) "Model%uni_cld: ",Model%uni_cld - write(58,*) "Model%ncld: ",Model%ncld - write(58,*) "Model%lgfdlmprad: ",Model%lgfdlmprad - write(58,*) "Model%lmfshal: ",Model%lmfshal - write(58,*) "Model%lmfdeep2: ",Model%lmfdeep2 - do k = 1, LMK - do i = 1, IM - write(58,'(a19,2i8,f10.2)') " Cloud-cover: ",k,i,cldcov(i,k) - end do - enddo if (Model%imp_physics == 99 .or. Model%imp_physics == 10) then ! zhao/moorthi's prognostic cloud scheme ! or unified cloud and/or with MG microphysics @@ -802,8 +790,6 @@ subroutine GFS_rrtmg_pre_run (Model, Grid, Sfcprop, Statein, & ! input call progcld1 (plyr ,plvl, tlyr, tvly, qlyr, qstl, rhly, & ! --- inputs ccnd(1:IM,1:LMK,1), Grid%xlat,Grid%xlon, & Sfcprop%slmsk, dz, delp, IM, LMK, LMP, & -!DJS2019: Pass uni_cld=true to use prescribed cloud-cover amount -! .true., Model%lmfshal, & Model%uni_cld, Model%lmfshal, & Model%lmfdeep2, cldcov, & effrl, effri, effrr, effrs, Model%effr_in, & @@ -880,12 +866,6 @@ subroutine GFS_rrtmg_pre_run (Model, Grid, Sfcprop, Statein, & ! input enddo enddo - write(58,*) "#" - do k=1,Model%levr+LTP - write(58,"(5F10.3)") plyr(1,k),tlyr(1,k),clouds2(1,k), & - & clouds4(1,k), clouds1(1,k) - enddo - ! mg, sfc-perts ! --- scale random patterns for surface perturbations with @@ -906,7 +886,6 @@ end subroutine GFS_rrtmg_pre_run !> \section arg_table_GFS_rrtmg_pre_finalize Argument Table !! subroutine GFS_rrtmg_pre_finalize () - close(58) end subroutine GFS_rrtmg_pre_finalize !! @} diff --git a/physics/GFS_rrtmgp_lw.F90 b/physics/GFS_rrtmgp_lw.F90 index d46f5c74a..2721ed495 100644 --- a/physics/GFS_rrtmgp_lw.F90 +++ b/physics/GFS_rrtmgp_lw.F90 @@ -2,7 +2,7 @@ module GFS_rrtmgp_lw use GFS_typedefs, only: GFS_control_type use machine, only: kind_phys use physparam, only: isubclw, iovrlw - use rrtmgp_lw, only: nrghice_lw => nrghice, ipsdlw0 + use rrtmgp_aux, only: nrghice_lw, ipsdlw0 use mo_gas_optics_rrtmgp, only: ty_gas_optics_rrtmgp use mo_cloud_optics, only: ty_cloud_optics use mo_optical_props, only: ty_optical_props_1scl, ty_optical_props_2str @@ -37,9 +37,9 @@ end subroutine GFS_rrtmgp_lw_init !! | cld_rerain | mean_effective_radius_for_rain_drop | mean effective radius for rain cloud | micron | 2 | real | kind_phys | in | F | !! | gas_concentrations | Gas_concentrations_for_RRTMGP_suite | DDT containing gas concentrations for RRTMGP radiation scheme | DDT | 0 | ty_gas_concs | | in | F | !! | icseed_lw | seed_random_numbers_sw | seed for random number generation for shortwave radiation | none | 1 | integer | | in | F | -!! | kdist_lw | K_distribution_file_for_RRTMGP_LW_scheme | DDT containing spectral information for RRTMGP LW radiation scheme | DDT | 0 | ty_gas_optics_rrtmgp | | in | F | +!! | lw_gas_props | coefficients_for_lw_gas_optics | DDT containing spectral information for RRTMGP LW radiation scheme | DDT | 0 | ty_gas_optics_rrtmgp | | in | F | !! | aerosols | aerosol_optical_properties_for_longwave_bands_01-16 | aerosol optical properties for longwave bands 01-16 | various | 4 | real | kind_phys | in | F | -!! | kdist_cldy_lw | K_distribution_file_for_cloudy_RRTMGP_LW_scheme | DDT containing spectral information for cloudy RRTMGP LW radiation scheme | DDT | 0 | ty_cloud_optics | | in | F | +!! | lw_cloud_props | coefficients_for_lw_cloud_optics | DDT containing spectral information for cloudy RRTMGP LW radiation scheme | DDT | 0 | ty_cloud_optics | | in | F | !! | optical_props_clouds | longwave_optical_properties_for_cloudy_atmosphere | Fortran DDT containing RRTMGP optical properties | DDT | 0 | ty_optical_props_1scl | | out | F | !! | optical_props_aerosol | longwave_optical_properties_for_aerosols | Fortran DDT containing RRTMGP optical properties | DDT | 0 | ty_optical_props_1scl | | out | F | !! | cldtaulw | cloud_optical_depth_layers_at_10mu_band | approx 10mu band layer cloud optical depth | none | 2 | real | kind_phys | out | F | @@ -50,7 +50,7 @@ end subroutine GFS_rrtmgp_lw_init ! ######################################################################################### subroutine GFS_rrtmgp_lw_run(Model, ncol, icseed_lw, p_lay, t_lay, p_lev, cld_frac, & cld_lwp, cld_reliq, cld_iwp, cld_reice, cld_swp, cld_resnow, cld_rwp, cld_rerain, & - gas_concentrations, kdist_lw, aerosols, kdist_cldy_lw, & + gas_concentrations, lw_gas_props, aerosols, lw_cloud_props, & optical_props_clouds, optical_props_aerosol, cldtaulw, errmsg, errflg) ! Inputs @@ -81,10 +81,10 @@ subroutine GFS_rrtmgp_lw_run(Model, ncol, icseed_lw, p_lay, t_lay, p_lev, cld_fr type(ty_gas_concs),intent(in) :: & gas_concentrations ! type(ty_gas_optics_rrtmgp),intent(in) :: & - kdist_lw ! RRTMGP DDT containing spectral information for LW calculation + lw_gas_props ! RRTMGP DDT containing spectral information for LW calculation type(ty_cloud_optics),intent(in) :: & - kdist_cldy_lw ! - real(kind_phys), intent(in),dimension(ncol, model%levs, kdist_lw%get_nband(),3) :: & + lw_cloud_props ! + real(kind_phys), intent(in),dimension(ncol, model%levs, lw_gas_props%get_nband(),3) :: & aerosols ! real(kind_phys), dimension(ncol,Model%levs), intent(out) :: & cldtaulw ! approx 10.mu band layer cloud optical depth @@ -102,10 +102,10 @@ subroutine GFS_rrtmgp_lw_run(Model, ncol, icseed_lw, p_lay, t_lay, p_lev, cld_fr logical,dimension(ncol,model%levs) :: liqmask, icemask type(ty_optical_props_1scl) :: optical_props_cloudsByBand type(random_stat) :: rng_stat - real(kind_phys), dimension(kdist_lw%get_ngpt(),model%levs,ncol) :: rng3D - real(kind_phys), dimension(kdist_lw%get_ngpt()*model%levs) :: rng1D - logical, dimension(ncol,model%levs,kdist_lw%get_ngpt()) :: cldfracMCICA - real(kind_phys), dimension(ncol,model%levs,kdist_lw%get_nband()) :: & + real(kind_phys), dimension(lw_gas_props%get_ngpt(),model%levs,ncol) :: rng3D + real(kind_phys), dimension(lw_gas_props%get_ngpt()*model%levs) :: rng1D + logical, dimension(ncol,model%levs,lw_gas_props%get_ngpt()) :: cldfracMCICA + real(kind_phys), dimension(ncol,model%levs,lw_gas_props%get_nband()) :: & tau_cld ! Initialize CCPP error handling variables @@ -137,11 +137,11 @@ subroutine GFS_rrtmgp_lw_run(Model, ncol, icseed_lw, p_lay, t_lay, p_lev, cld_fr ! Allocate space for RRTMGP DDTs containing cloud and aerosol radiative properties ! ####################################################################################### ! Cloud optics [nCol,model%levs,nBands] - call check_error_msg('GFS_rrtmgp_lw_run',optical_props_cloudsByBand%alloc_1scl(ncol, model%levs, kdist_lw%get_band_lims_wavenumber())) + call check_error_msg('GFS_rrtmgp_lw_run',optical_props_cloudsByBand%alloc_1scl(ncol, model%levs, lw_gas_props%get_band_lims_wavenumber())) ! Aerosol optics [Ccol,model%levs,nBands] - call check_error_msg('GFS_rrtmgp_lw_run',optical_props_aerosol%alloc_1scl(ncol, model%levs, kdist_lw%get_band_lims_wavenumber())) + call check_error_msg('GFS_rrtmgp_lw_run',optical_props_aerosol%alloc_1scl(ncol, model%levs, lw_gas_props%get_band_lims_wavenumber())) ! Cloud optics [nCol,model%levs,nGpts] - call check_error_msg('GFS_rrtmgp_lw_run',optical_props_clouds%alloc_1scl(ncol, model%levs, kdist_lw)) + call check_error_msg('GFS_rrtmgp_lw_run',optical_props_clouds%alloc_1scl(ncol, model%levs, lw_gas_props)) ! ####################################################################################### ! Copy aerosol optical information to RRTMGP DDT @@ -151,12 +151,12 @@ subroutine GFS_rrtmgp_lw_run(Model, ncol, icseed_lw, p_lay, t_lay, p_lev, cld_fr ! ####################################################################################### ! Compute cloud-optics for RTE. ! ####################################################################################### - if (Model%rrtmgp_cld_phys .gt. 0) then + if (Model%rrtmgp_cld_optics .gt. 0) then ! i) RRTMGP cloud-optics. - call check_error_msg('GFS_rrtmgp_lw_run',kdist_cldy_lw%cloud_optics(& + call check_error_msg('GFS_rrtmgp_lw_run',lw_cloud_props%cloud_optics(& ncol, & ! IN - Number of horizontal gridpoints model%levs, & ! IN - Number of vertical layers - kdist_lw%get_nband(), & ! IN - Number of LW bands + lw_gas_props%get_nband(), & ! IN - Number of LW bands nrghice_lw, & ! IN - Number of ice-roughness categories liqmask, & ! IN - Liquid-cloud mask icemask, & ! IN - Ice-cloud mask @@ -169,7 +169,7 @@ subroutine GFS_rrtmgp_lw_run(Model, ncol, icseed_lw, p_lay, t_lay, p_lev, cld_fr else ! ii) RRTMG cloud-optics. if (any(cld_frac .gt. 0)) then - call rrtmgp_lw_cloud_optics(ncol, model%levs, kdist_lw%get_nband(), cld_lwp, & + call rrtmgp_lw_cloud_optics(ncol, model%levs, lw_gas_props%get_nband(), cld_lwp, & cld_reliq, cld_iwp, cld_reice, cld_rwp, cld_rerain, cld_swp, cld_resnow, & cld_frac, tau_cld) optical_props_cloudsByBand%tau = tau_cld @@ -184,7 +184,7 @@ subroutine GFS_rrtmgp_lw_run(Model, ncol, icseed_lw, p_lay, t_lay, p_lev, cld_fr do iCol=1,ncol call random_setseed(ipseed_lw(icol),rng_stat) call random_number(rng1D,rng_stat) - rng3D(:,:,iCol) = reshape(source = rng1D,shape=[kdist_lw%get_ngpt(),model%levs]) + rng3D(:,:,iCol) = reshape(source = rng1D,shape=[lw_gas_props%get_ngpt(),model%levs]) enddo ! Call McICA diff --git a/physics/GFS_rrtmgp_lw_post.F90 b/physics/GFS_rrtmgp_lw_post.F90 index f1b10da86..3562be382 100644 --- a/physics/GFS_rrtmgp_lw_post.F90 +++ b/physics/GFS_rrtmgp_lw_post.F90 @@ -14,6 +14,7 @@ module GFS_rrtmgp_lw_post use mo_gas_optics_rrtmgp, only: ty_gas_optics_rrtmgp use mo_fluxes_byband, only: ty_fluxes_byband use mo_heating_rates, only: compute_heating_rate + use rrtmgp_aux, only: check_error_msg implicit none public GFS_rrtmgp_lw_post_init,GFS_rrtmgp_lw_post_run,GFS_rrtmgp_lw_post_finalize @@ -41,7 +42,7 @@ end subroutine GFS_rrtmgp_lw_post_init !! | fluxlwDOWN_allsky | lw_flux_profile_downward_allsky | RRTMGP downward longwave all-sky flux profile | W m-2 | 2 | real | kind_phys | in | F | !! | fluxlwUP_clrsky | lw_flux_profile_upward_clrsky | RRTMGP upward longwave clr-sky flux profile | W m-2 | 2 | real | kind_phys | in | F | !! | fluxlwDOWN_clrsky | lw_flux_profile_downward_clrsky | RRTMGP downward longwave clr-sky flux profile | W m-2 | 2 | real | kind_phys | in | F | -!! | kdist_lw | K_distribution_file_for_RRTMGP_LW_scheme | DDT containing spectral information for RRTMGP LW radiation scheme | DDT | 0 | ty_gas_optics_rrtmgp | | in | F | +!! | lw_gas_props | coefficients_for_lw_gas_optics | DDT containing spectral information for RRTMGP LW radiation scheme | DDT | 0 | ty_gas_optics_rrtmgp | | in | F | !! | hlwc | tendency_of_air_temperature_due_to_longwave_heating_on_radiation_time_step | longwave total sky heating rate | K s-1 | 2 | real | kind_phys | out | F | !! | topflx_lw | lw_fluxes_top_atmosphere | longwave total sky fluxes at the top of the atm | W m-2 | 1 | topflw_type | | inout | F | !! | sfcflx_lw | lw_fluxes_sfc | longwave total sky fluxes at the Earth surface | W m-2 | 1 | sfcflw_type | | inout | F | @@ -52,7 +53,7 @@ end subroutine GFS_rrtmgp_lw_post_init !! #endif subroutine GFS_rrtmgp_lw_post_run (Model, Grid, Diag, Radtend, Statein, & - Coupling, im, p_lev, kdist_lw, & + Coupling, im, p_lev, lw_gas_props, & tsfa, fluxlwUP_allsky, fluxlwDOWN_allsky, fluxlwUP_clrsky, fluxlwDOWN_clrsky, & hlwc, topflx_lw, sfcflx_lw, flxprf_lw, hlw0, errmsg, errflg) @@ -74,7 +75,7 @@ subroutine GFS_rrtmgp_lw_post_run (Model, Grid, Diag, Radtend, Statein, & real(kind_phys), dimension(size(Grid%xlon,1)), intent(in) :: & tsfa ! Lowest model layer air temperature for radiation type(ty_gas_optics_rrtmgp),intent(in) :: & - kdist_lw ! DDT containing LW spectral information + lw_gas_props ! DDT containing LW spectral information real(kind_phys), dimension(size(Grid%xlon,1), Model%levs+1), intent(in) :: & p_lev ! Pressure @ model layer-interfaces (hPa) real(kind_phys), dimension(size(Grid%xlon,1), Model%levs+1), intent(in) :: & @@ -200,14 +201,4 @@ end subroutine GFS_rrtmgp_lw_post_run subroutine GFS_rrtmgp_lw_post_finalize () end subroutine GFS_rrtmgp_lw_post_finalize - subroutine check_error_msg(routine_name, error_msg) - character(len=*), intent(in) :: & - error_msg, routine_name - - if(error_msg /= "") then - print*,"ERROR("//trim(routine_name)//"): " - print*,trim(error_msg) - return - end if - end subroutine check_error_msg end module GFS_rrtmgp_lw_post diff --git a/physics/GFS_rrtmgp_pre.F90 b/physics/GFS_rrtmgp_pre.F90 index 613c9ad15..7a9c42cf1 100644 --- a/physics/GFS_rrtmgp_pre.F90 +++ b/physics/GFS_rrtmgp_pre.F90 @@ -54,7 +54,8 @@ module GFS_rrtmgp_pre ! RRTMGP types use mo_gas_optics_rrtmgp, only: ty_gas_optics_rrtmgp use mo_gas_concentrations, only: ty_gas_concs - + use rrtmgp_aux, only: check_error_msg + real(kind_phys), parameter :: & amd = 28.9644_kind_phys, & ! Molecular weight of dry-air (g/mol) amw = 18.0154_kind_phys, & ! Molecular weight of water vapor (g/mol) @@ -74,52 +75,52 @@ subroutine GFS_rrtmgp_pre_init () end subroutine GFS_rrtmgp_pre_init !> \section arg_table_GFS_rrtmgp_pre_run Argument Table -!! | local_name | standard_name | long_name | units | rank | type | kind | intent | optional | -!! |-------------------------|---------------------------------------------------------------|-------------------------------------------------------------------------------|----------|------|-----------------------|-----------|--------|----------| -!! | Model | GFS_control_type_instance | Fortran DDT containing FV3-GFS model control parameters | DDT | 0 | GFS_control_type | | in | F | -!! | Grid | GFS_grid_type_instance | Fortran DDT containing FV3-GFS grid and interpolation related data | DDT | 0 | GFS_grid_type | | in | F | -!! | Sfcprop | GFS_sfcprop_type_instance | Fortran DDT containing FV3-GFS surface fields | DDT | 0 | GFS_sfcprop_type | | in | F | -!! | Statein | GFS_statein_type_instance | Fortran DDT containing FV3-GFS prognostic state data in from dycore | DDT | 0 | GFS_statein_type | | in | F | -!! | Tbd | GFS_tbd_type_instance | Fortran DDT containing FV3-GFS data not yet assigned to a defined container | DDT | 0 | GFS_tbd_type | | in | F | -!! | Coupling | GFS_coupling_type_instance | Fortran DDT containing FV3-GFS fields needed for coupling | DDT | 0 | GFS_coupling_type | | in | F | -!! | Radtend | GFS_radtend_type_instance | Fortran DDT containing FV3-GFS radiation tendencies | DDT | 0 | GFS_radtend_type | | inout | F | -!! | ncol | horizontal_loop_extent | horizontal loop extent | count | 0 | integer | | in | F | -!! | kdist_lw | K_distribution_file_for_RRTMGP_LW_scheme | DDT containing spectral information for RRTMGP LW radiation scheme | DDT | 0 | ty_gas_optics_rrtmgp | | in | F | -!! | kdist_sw | K_distribution_file_for_RRTMGP_SW_scheme | DDT containing spectral information for RRTMGP SW radiation scheme | DDT | 0 | ty_gas_optics_rrtmgp | | in | F | -!! | raddt | time_step_for_radiation | radiation time step | s | 0 | real | kind_phys | out | F | -!! | p_lay | air_pressure_at_layer_for_RRTMGP_in_hPa | air pressure at vertical layer for radiation calculation | hPa | 2 | real | kind_phys | out | F | -!! | p_lev | air_pressure_at_interface_for_RRTMGP_in_hPa | air pressure at vertical interface for radiation calculation | hPa | 2 | real | kind_phys | out | F | -!! | t_lay | air_temperature_at_layer_for_RRTMGP | air temperature at vertical layer for radiation calculation | K | 2 | real | kind_phys | out | F | -!! | t_lev | air_temperature_at_interface_for_RRTMGP | air temperature at vertical interface for radiation calculation | K | 2 | real | kind_phys | out | F | -!! | tsfg | surface_ground_temperature_for_radiation | surface ground temperature for radiation | K | 1 | real | kind_phys | out | F | -!! | tsfa | surface_air_temperature_for_radiation | lowest model layer air temperature for radiation | K | 1 | real | kind_phys | out | F | -!! | cld_frac | total_cloud_fraction | layer total cloud fraction | frac | 2 | real | kind_phys | out | F | -!! | cld_lwp | cloud_liquid_water_path | layer cloud liquid water path | g m-2 | 2 | real | kind_phys | out | F | -!! | cld_reliq | mean_effective_radius_for_liquid_cloud | mean effective radius for liquid cloud | micron | 2 | real | kind_phys | out | F | -!! | cld_iwp | cloud_ice_water_path | layer cloud ice water path | g m-2 | 2 | real | kind_phys | out | F | -!! | cld_reice | mean_effective_radius_for_ice_cloud | mean effective radius for ice cloud | micron | 2 | real | kind_phys | out | F | -!! | cld_swp | cloud_snow_water_path | layer cloud snow water path | g m-2 | 2 | real | kind_phys | out | F | -!! | cld_resnow | mean_effective_radius_for_snow_flake | mean effective radius for snow cloud | micron | 2 | real | kind_phys | out | F | -!! | cld_rwp | cloud_rain_water_path | layer cloud rain water path | g m-2 | 2 | real | kind_phys | out | F | -!! | cld_rerain | mean_effective_radius_for_rain_drop | mean effective radius for rain cloud | micron | 2 | real | kind_phys | out | F | -!! | faerlw | aerosol_optical_properties_for_longwave_bands_01-16 | aerosol optical properties for longwave bands 01-16 | various | 4 | real | kind_phys | out | F | -!! | faersw | aerosol_optical_properties_for_shortwave_bands_01-16 | aerosol optical properties for shortwave bands 01-16 | various | 4 | real | kind_phys | out | F | -!! | alb1d | surface_albedo_perturbation | surface albedo perturbation | frac | 1 | real | kind_phys | out | F | -!! | gas_concentrations | Gas_concentrations_for_RRTMGP_suite | DDT containing gas concentrations for RRTMGP radiation scheme | DDT | 0 | ty_gas_concs | | out | F | -!! | sfc_emiss_byband | surface_longwave_emissivity_in_each_band | surface lw emissivity in fraction in each LW band | frac | 2 | real | kind_phys | out | F | -!! | sfc_alb_nir_dir | surface_shortwave_albedo_near_infrared_direct_in_each_band | surface sw near-infrared direct albedo in each SW band | frac | 2 | real | kind_phys | out | F | -!! | sfc_alb_nir_dif | surface_shortwave_albedo_near_infrared_diffuse_in_each_band | surface sw near-infrared diffuse albedo in each SW band | frac | 2 | real | kind_phys | out | F | -!! | sfc_alb_uvvis_dir | surface_shortwave_albedo_uv_visible_direct_in_each_band | surface sw uv-visible direct albedo in each SW band | frac | 2 | real | kind_phys | out | F | -!! | sfc_alb_uvvis_dif | surface_shortwave_albedo_uv_visible_diffuse_in_each_band | surface sw uv-visible diffuse albedo in each SW band | frac | 2 | real | kind_phys | out | F | -!! | nday | daytime_points_dimension | daytime points dimension | count | 0 | integer | | out | F | -!! | idxday | daytime_points | daytime points | index | 1 | integer | | out | F | -!! | errmsg | ccpp_error_message | error message for error handling in CCPP | none | 0 | character | len=* | out | F | -!! | errflg | ccpp_error_flag | error flag for error handling in CCPP | flag | 0 | integer | | out | F | +!! | local_name | standard_name | long_name | units | rank | type | kind | intent | optional | +!! |--------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------|----------|------|-----------------------|-----------|--------|----------| +!! | Model | GFS_control_type_instance | Fortran DDT containing FV3-GFS model control parameters | DDT | 0 | GFS_control_type | | in | F | +!! | Grid | GFS_grid_type_instance | Fortran DDT containing FV3-GFS grid and interpolation related data | DDT | 0 | GFS_grid_type | | in | F | +!! | Sfcprop | GFS_sfcprop_type_instance | Fortran DDT containing FV3-GFS surface fields | DDT | 0 | GFS_sfcprop_type | | in | F | +!! | Statein | GFS_statein_type_instance | Fortran DDT containing FV3-GFS prognostic state data in from dycore | DDT | 0 | GFS_statein_type | | in | F | +!! | Tbd | GFS_tbd_type_instance | Fortran DDT containing FV3-GFS data not yet assigned to a defined container | DDT | 0 | GFS_tbd_type | | in | F | +!! | Coupling | GFS_coupling_type_instance | Fortran DDT containing FV3-GFS fields needed for coupling | DDT | 0 | GFS_coupling_type | | in | F | +!! | Radtend | GFS_radtend_type_instance | Fortran DDT containing FV3-GFS radiation tendencies | DDT | 0 | GFS_radtend_type | | inout | F | +!! | ncol | horizontal_loop_extent | horizontal loop extent | count | 0 | integer | | in | F | +!! | lw_gas_props | coefficients_for_lw_gas_optics | DDT containing spectral information for RRTMGP LW radiation scheme | DDT | 0 | ty_gas_optics_rrtmgp | | in | F | +!! | sw_gas_props | coefficients_for_sw_gas_optics | DDT containing spectral information for RRTMGP SW radiation scheme | DDT | 0 | ty_gas_optics_rrtmgp | | in | F | +!! | raddt | time_step_for_radiation | radiation time step | s | 0 | real | kind_phys | out | F | +!! | p_lay | air_pressure_at_layer_for_RRTMGP_in_hPa | air pressure at vertical layer for radiation calculation | hPa | 2 | real | kind_phys | out | F | +!! | p_lev | air_pressure_at_interface_for_RRTMGP_in_hPa | air pressure at vertical interface for radiation calculation | hPa | 2 | real | kind_phys | out | F | +!! | t_lay | air_temperature_at_layer_for_RRTMGP | air temperature at vertical layer for radiation calculation | K | 2 | real | kind_phys | out | F | +!! | t_lev | air_temperature_at_interface_for_RRTMGP | air temperature at vertical interface for radiation calculation | K | 2 | real | kind_phys | out | F | +!! | tsfg | surface_ground_temperature_for_radiation | surface ground temperature for radiation | K | 1 | real | kind_phys | out | F | +!! | tsfa | surface_air_temperature_for_radiation | lowest model layer air temperature for radiation | K | 1 | real | kind_phys | out | F | +!! | cld_frac | total_cloud_fraction | layer total cloud fraction | frac | 2 | real | kind_phys | out | F | +!! | cld_lwp | cloud_liquid_water_path | layer cloud liquid water path | g m-2 | 2 | real | kind_phys | out | F | +!! | cld_reliq | mean_effective_radius_for_liquid_cloud | mean effective radius for liquid cloud | micron | 2 | real | kind_phys | out | F | +!! | cld_iwp | cloud_ice_water_path | layer cloud ice water path | g m-2 | 2 | real | kind_phys | out | F | +!! | cld_reice | mean_effective_radius_for_ice_cloud | mean effective radius for ice cloud | micron | 2 | real | kind_phys | out | F | +!! | cld_swp | cloud_snow_water_path | layer cloud snow water path | g m-2 | 2 | real | kind_phys | out | F | +!! | cld_resnow | mean_effective_radius_for_snow_flake | mean effective radius for snow cloud | micron | 2 | real | kind_phys | out | F | +!! | cld_rwp | cloud_rain_water_path | layer cloud rain water path | g m-2 | 2 | real | kind_phys | out | F | +!! | cld_rerain | mean_effective_radius_for_rain_drop | mean effective radius for rain cloud | micron | 2 | real | kind_phys | out | F | +!! | faerlw | aerosol_optical_properties_for_longwave_bands_01-16 | aerosol optical properties for longwave bands 01-16 | various | 4 | real | kind_phys | out | F | +!! | faersw | aerosol_optical_properties_for_shortwave_bands_01-16 | aerosol optical properties for shortwave bands 01-16 | various | 4 | real | kind_phys | out | F | +!! | alb1d | surface_albedo_perturbation | surface albedo perturbation | frac | 1 | real | kind_phys | out | F | +!! | gas_concentrations | Gas_concentrations_for_RRTMGP_suite | DDT containing gas concentrations for RRTMGP radiation scheme | DDT | 0 | ty_gas_concs | | out | F | +!! | sfc_emiss_byband | surface_longwave_emissivity_in_each_band | surface lw emissivity in fraction in each LW band | frac | 2 | real | kind_phys | out | F | +!! | sfc_alb_nir_dir | surface_shortwave_albedo_near_infrared_direct_in_each_band | surface sw near-infrared direct albedo in each SW band | frac | 2 | real | kind_phys | out | F | +!! | sfc_alb_nir_dif | surface_shortwave_albedo_near_infrared_diffuse_in_each_band | surface sw near-infrared diffuse albedo in each SW band | frac | 2 | real | kind_phys | out | F | +!! | sfc_alb_uvvis_dir | surface_shortwave_albedo_uv_visible_direct_in_each_band | surface sw uv-visible direct albedo in each SW band | frac | 2 | real | kind_phys | out | F | +!! | sfc_alb_uvvis_dif | surface_shortwave_albedo_uv_visible_diffuse_in_each_band | surface sw uv-visible diffuse albedo in each SW band | frac | 2 | real | kind_phys | out | F | +!! | nday | daytime_points_dimension | daytime points dimension | count | 0 | integer | | out | F | +!! | idxday | daytime_points | daytime points | index | 1 | integer | | out | F | +!! | errmsg | ccpp_error_message | error message for error handling in CCPP | none | 0 | character | len=* | out | F | +!! | errflg | ccpp_error_flag | error flag for error handling in CCPP | flag | 0 | integer | | out | F | !! ! Attention - the output arguments lm, im, lmk, lmp must not be set ! in the CCPP version - they are defined in the interstitial_create routine subroutine GFS_rrtmgp_pre_run (Model, Grid, Statein, Coupling, Radtend, Sfcprop, Tbd, & ! IN - ncol, kdist_lw, kdist_sw, & ! IN + ncol, lw_gas_props, sw_gas_props, & ! IN raddt, p_lay, t_lay, p_lev, t_lev, tsfg, tsfa, alb1d, cld_frac, cld_lwp, & ! OUT cld_reliq, cld_iwp, cld_reice, cld_swp, cld_resnow, cld_rwp, cld_rerain, faerlw, & ! OUT faersw, sfc_emiss_byband, nday, idxday, gas_concentrations, sfc_alb_nir_dir, & ! OUT @@ -143,8 +144,8 @@ subroutine GFS_rrtmgp_pre_run (Model, Grid, Statein, Coupling, Radtend, Sfcprop, integer, intent(in) :: & ncol ! Number of horizontal grid points type(ty_gas_optics_rrtmgp),intent(in) :: & - kdist_lw, & ! RRTMGP DDT containing spectral information for LW calculation - kdist_sw ! RRTMGP DDT containing spectral information for SW calculation + lw_gas_props, & ! RRTMGP DDT containing spectral information for LW calculation + sw_gas_props ! RRTMGP DDT containing spectral information for SW calculation ! Outputs real(kind_phys), dimension(ncol,Model%levs), intent(out) :: & @@ -158,7 +159,7 @@ subroutine GFS_rrtmgp_pre_run (Model, Grid, Statein, Coupling, Radtend, Sfcprop, real(kind_phys), dimension(ncol), intent(out) :: & tsfg, & ! tsfa ! - real(kind_phys),dimension(kdist_sw%get_nband(),NCOL),intent(out) :: & + real(kind_phys),dimension(sw_gas_props%get_nband(),NCOL),intent(out) :: & sfc_alb_nir_dir, & ! Shortwave surface albedo (nIR-direct) sfc_alb_nir_dif, & ! Shortwave surface albedo (nIR-diffuse) sfc_alb_uvvis_dir, & ! Shortwave surface albedo (uvvis-direct) @@ -175,7 +176,7 @@ subroutine GFS_rrtmgp_pre_run (Model, Grid, Statein, Coupling, Radtend, Sfcprop, errmsg ! Error message integer, intent(out) :: & errflg ! Error flag - real(kind_phys),dimension(kdist_sw%get_nband(),NCOL),intent(out) :: & + real(kind_phys),dimension(sw_gas_props%get_nband(),NCOL),intent(out) :: & sfc_emiss_byband ! Longwave surface emissivity in each band real(kind_phys), dimension(ncol,Model%levr+LTP),intent(out) :: & cld_frac, & ! Total cloud fraction @@ -187,9 +188,9 @@ subroutine GFS_rrtmgp_pre_run (Model, Grid, Statein, Coupling, Radtend, Sfcprop, cld_resnow, & ! Cloud snow effective radius cld_rwp, & ! Cloud rain water path cld_rerain ! Cloud rain effective radius - real(kind_phys), dimension(ncol,Model%levs,kdist_sw%get_nband(),NF_AESW), intent(out) ::& + real(kind_phys), dimension(ncol,Model%levs,sw_gas_props%get_nband(),NF_AESW), intent(out) ::& faersw ! Aerosol radiative properties in each SW band. - real(kind_phys), dimension(ncol,Model%levs,kdist_lw%get_nband(),NF_AELW), intent(out) ::& + real(kind_phys), dimension(ncol,Model%levs,lw_gas_props%get_nband(),NF_AELW), intent(out) ::& faerlw ! Aerosol radiative properties in each LW band. ! Local variables @@ -211,7 +212,7 @@ subroutine GFS_rrtmgp_pre_run (Model, Grid, Statein, Coupling, Radtend, Sfcprop, real(kind_phys), dimension(ncol, Model%levs, 2:Model%ntrac) :: tracer real(kind_phys), dimension(ncol, Model%levs, NF_VGAS) :: gas_vmr real(kind_phys), dimension(ncol, Model%levs, NF_CLDS) :: clouds - real(kind_phys), dimension(ncol, Model%levs, kdist_sw%get_nband(), NF_AESW)::faersw2 + real(kind_phys), dimension(ncol, Model%levs, sw_gas_props%get_nband(), NF_AESW)::faersw2 ! Initialize CCPP error handling variables errmsg = '' @@ -236,7 +237,7 @@ subroutine GFS_rrtmgp_pre_run (Model, Grid, Statein, Coupling, Radtend, Sfcprop, ! ####################################################################################### ! Copy state fields over for use in RRTMGP p_lev(1:NCOL,iSFC:iTOA) = Statein%prsi(1:NCOL,1:Model%levs) - p_lev(1:NCOL,iTOA+1) = spread(kdist_lw%get_press_min(),dim=1, ncopies=NCOL) + p_lev(1:NCOL,iTOA+1) = spread(lw_gas_props%get_press_min(),dim=1, ncopies=NCOL) p_lay(1:NCOL,iSFC:iTOA) = Statein%prsl(1:NCOL,1:Model%levs) t_lay(1:NCOL,iSFC:iTOA) = Statein%tgrs(1:NCOL,1:Model%levs) @@ -249,7 +250,7 @@ subroutine GFS_rrtmgp_pre_run (Model, Grid, Statein, Coupling, Radtend, Sfcprop, do iLay=iSFC+1,iTOA t_lev(iCol,iLay) = (t_lay(iCol,iLay)+t_lay(iCol,iLay-1))/2._kind_phys enddo - t_lev(iCol,iTOA+1) = kdist_lw%get_temp_min() + t_lev(iCol,iTOA+1) = lw_gas_props%get_temp_min() enddo ! Compute a bunch of thermodynamic fields needed by the macrophysics schemes. Relative humidity, @@ -273,7 +274,7 @@ subroutine GFS_rrtmgp_pre_run (Model, Grid, Statein, Coupling, Radtend, Sfcprop, do j = 2, model%NTRAC tracer(1:NCOL,1:Model%levs,j) = max(0.0, Statein%qgrs(1:NCOL,1:Model%levs,j)) enddo - + if (Model%ntoz > 0) then do iLay=iSFC,iTOA do iCol=1,NCOL @@ -360,12 +361,12 @@ subroutine GFS_rrtmgp_pre_run (Model, Grid, Statein, Coupling, Radtend, Sfcprop, ! SW. ! For RRTMGP SW the bands are now ordered from [IR(band) -> nIR -> UV], in RRTMG the ! band ordering was [nIR -> UV -> IR(band)] - faersw(1:NCOL,1:Model%levs,1,1) = faersw2(1:NCOL,1:Model%levs,kdist_sw%get_nband(),1) - faersw(1:NCOL,1:Model%levs,1,2) = faersw2(1:NCOL,1:Model%levs,kdist_sw%get_nband(),2) - faersw(1:NCOL,1:Model%levs,1,3) = faersw2(1:NCOL,1:Model%levs,kdist_sw%get_nband(),3) - faersw(1:NCOL,1:Model%levs,2:kdist_sw%get_nband(),1) = faersw2(1:NCOL,1:Model%levs,1:kdist_sw%get_nband()-1,1) - faersw(1:NCOL,1:Model%levs,2:kdist_sw%get_nband(),2) = faersw2(1:NCOL,1:Model%levs,1:kdist_sw%get_nband()-1,2) - faersw(1:NCOL,1:Model%levs,2:kdist_sw%get_nband(),3) = faersw2(1:NCOL,1:Model%levs,1:kdist_sw%get_nband()-1,3) + faersw(1:NCOL,1:Model%levs,1,1) = faersw2(1:NCOL,1:Model%levs,sw_gas_props%get_nband(),1) + faersw(1:NCOL,1:Model%levs,1,2) = faersw2(1:NCOL,1:Model%levs,sw_gas_props%get_nband(),2) + faersw(1:NCOL,1:Model%levs,1,3) = faersw2(1:NCOL,1:Model%levs,sw_gas_props%get_nband(),3) + faersw(1:NCOL,1:Model%levs,2:sw_gas_props%get_nband(),1) = faersw2(1:NCOL,1:Model%levs,1:sw_gas_props%get_nband()-1,1) + faersw(1:NCOL,1:Model%levs,2:sw_gas_props%get_nband(),2) = faersw2(1:NCOL,1:Model%levs,1:sw_gas_props%get_nband()-1,2) + faersw(1:NCOL,1:Model%levs,2:sw_gas_props%get_nband(),3) = faersw2(1:NCOL,1:Model%levs,1:sw_gas_props%get_nband()-1,3) ! Setup surface ground temperature and ground/air skin temperature if required. tsfg(1:NCOL) = Sfcprop%tsfc(1:NCOL) @@ -377,7 +378,7 @@ subroutine GFS_rrtmgp_pre_run (Model, Grid, Statein, Coupling, Radtend, Sfcprop, if (Model%lslwr) then call setemis (Grid%xlon, Grid%xlat, Sfcprop%slmsk, Sfcprop%snowd, Sfcprop%sncovr, & Sfcprop%zorl, tsfg, tsfa, Sfcprop%hprim, NCOL, Radtend%semis) - do iBand=1,kdist_lw%get_nband() + do iBand=1,lw_gas_props%get_nband() sfc_emiss_byband(iBand,1:NCOL) = Radtend%semis(1:NCOL) enddo endif @@ -415,7 +416,7 @@ subroutine GFS_rrtmgp_pre_run (Model, Grid, Statein, Coupling, Radtend, Sfcprop, endif ! Spread across all SW bands - do iBand=1,kdist_sw%get_nband() + do iBand=1,sw_gas_props%get_nband() sfc_alb_nir_dir(iBand,1:NCOL) = sfcalb(1:NCOL,1) sfc_alb_nir_dif(iBand,1:NCOL) = sfcalb(1:NCOL,2) sfc_alb_uvvis_dir(iBand,1:NCOL) = sfcalb(1:NCOL,3) @@ -429,20 +430,6 @@ end subroutine GFS_rrtmgp_pre_run subroutine GFS_rrtmgp_pre_finalize () end subroutine GFS_rrtmgp_pre_finalize - ! ####################################################################################### - ! SUBROUTINE check_error_msg() - ! ####################################################################################### - subroutine check_error_msg(routine_name, error_msg) - character(len=*), intent(in) :: & - error_msg, routine_name - - if(error_msg /= "") then - print*,"ERROR("//trim(routine_name)//"): " - print*,trim(error_msg) - return - end if - end subroutine check_error_msg - ! ####################################################################################### ! Subroutine cloud_microphysics() ! ####################################################################################### @@ -460,7 +447,7 @@ subroutine cloud_microphysics(Model, Tbd, Grid, Sfcprop, ncol, tracer, p_lay, t_ Sfcprop ! Fortran DDT containing FV3-GFS surface fields integer, intent(in) :: & ncol ! Number of horizontal gridpoints - real(kind_phys), dimension(ncol, Model%levs, Model%ntrac) :: & + real(kind_phys), dimension(ncol, Model%levs, 2:Model%ntrac),intent(in) :: & tracer ! real(kind_phys), dimension(ncol,Model%levs), intent(in) :: & p_lay, & ! @@ -630,7 +617,6 @@ subroutine cloud_microphysics(Model, Tbd, Grid, Sfcprop, ncol, tracer, p_lay, t_ endif ! DJS2019: END - ! ####################################################################################### ! MICROPHYSICS ! ####################################################################################### @@ -826,10 +812,6 @@ subroutine cloud_microphysics(Model, Tbd, Grid, Sfcprop, ncol, tracer, p_lay, t_ mbota, & ! OUT - vertical indices for low, mid, hi cloud bases (NCOL,3) de_lgth) ! OUT - clouds decorrelation length (km) endif ! end if_imp_physics - - - + end subroutine cloud_microphysics - - end module GFS_rrtmgp_pre diff --git a/physics/GFS_rrtmgp_sw.F90 b/physics/GFS_rrtmgp_sw.F90 index aa69982dc..ab2880eab 100644 --- a/physics/GFS_rrtmgp_sw.F90 +++ b/physics/GFS_rrtmgp_sw.F90 @@ -2,13 +2,13 @@ module GFS_rrtmgp_sw use GFS_typedefs, only: GFS_control_type use machine, only: kind_phys use physparam, only: isubcsw, iovrsw - use rrtmgp_sw, only: nrghice_sw => nrghice, ipsdsw0 use mo_gas_optics_rrtmgp, only: ty_gas_optics_rrtmgp use mo_cloud_optics, only: ty_cloud_optics use mo_optical_props, only: ty_optical_props_2str use mo_cloud_sampling, only: sampled_mask_max_ran, sampled_mask_exp_ran, draw_samples use mersenne_twister, only: random_setseed, random_number, random_stat use mo_rrtmgp_sw_cloud_optics, only: rrtmgp_sw_cloud_optics + use rrtmgp_aux, only: check_error_msg, nrghice_sw, ipsdsw0 public GFS_rrtmgp_sw_run,GFS_rrtmgp_sw_init,GFS_rrtmgp_sw_finalize @@ -37,9 +37,9 @@ end subroutine GFS_rrtmgp_sw_init !! | cld_rwp | cloud_rain_water_path | layer cloud rain water path | g m-2 | 2 | real | kind_phys | in | F | !! | cld_rerain | mean_effective_radius_for_rain_drop | mean effective radius for rain cloud | micron | 2 | real | kind_phys | in | F | !! | icseed_sw | seed_random_numbers_sw | seed for random number generation for shortwave radiation | none | 1 | integer | | in | F | -!! | kdist_sw | K_distribution_file_for_RRTMGP_SW_scheme | DDT containing spectral information for RRTMGP SW radiation scheme | DDT | 0 | ty_gas_optics_rrtmgp | | in | F | +!! | sw_gas_props | coefficients_for_sw_gas_optics | DDT containing spectral information for RRTMGP SW radiation scheme | DDT | 0 | ty_gas_optics_rrtmgp | | in | F | !! | aerosols | aerosol_optical_properties_for_shortwave_bands_01-16 | aerosol optical properties for shortwave bands 01-16 | various | 4 | real | kind_phys | in | F | -!! | kdist_cldy_sw | K_distribution_file_for_cloudy_RRTMGP_SW_scheme | DDT containing spectral information for cloudy RRTMGP SW radiation scheme | DDT | 0 | ty_cloud_optics | | in | F | +!! | sw_cloud_props | coefficients_for_sw_cloud_optics | DDT containing spectral information for cloudy RRTMGP SW radiation scheme | DDT | 0 | ty_cloud_optics | | in | F | !! | nday | daytime_points_dimension | daytime points dimension | count | 0 | integer | | in | F | !! | idxday | daytime_points | daytime points | index | 1 | integer | | in | F | !! | optical_props_clouds | shortwave_optical_properties_for_cloudy_atmosphere | Fortran DDT containing RRTMGP optical properties | DDT | 0 | ty_optical_props_2str | | out | F | @@ -52,7 +52,7 @@ end subroutine GFS_rrtmgp_sw_init ! ######################################################################################### subroutine GFS_rrtmgp_sw_run(Model, ncol, icseed_sw, p_lay, t_lay, p_lev, cld_frac, & ! IN cld_lwp, cld_reliq, cld_iwp, cld_reice, cld_swp, cld_resnow, cld_rwp, cld_rerain, & ! IN - kdist_sw, aerosols, kdist_cldy_sw, nday, idxday, & ! IN + sw_gas_props, aerosols, sw_cloud_props, nday, idxday, & ! IN optical_props_clouds, optical_props_aerosol, cldtausw, errmsg, errflg) ! OUT ! Inputs @@ -84,10 +84,10 @@ subroutine GFS_rrtmgp_sw_run(Model, ncol, icseed_sw, p_lay, t_lay, p_lev, cld_fr cld_rwp, & ! Cloud rain water path cld_rerain ! Cloud rain effective radius type(ty_gas_optics_rrtmgp),intent(in) :: & - kdist_sw ! RRTMGP DDT containing spectral information for SW calculation + sw_gas_props ! RRTMGP DDT containing spectral information for SW calculation type(ty_cloud_optics),intent(in) :: & - kdist_cldy_sw ! - real(kind_phys), intent(in),dimension(ncol, model%levs, kdist_sw%get_nband(),3) :: & + sw_cloud_props ! + real(kind_phys), intent(in),dimension(ncol, model%levs, sw_gas_props%get_nband(),3) :: & aerosols ! ! Outputs @@ -105,10 +105,10 @@ subroutine GFS_rrtmgp_sw_run(Model, ncol, icseed_sw, p_lay, t_lay, p_lev, cld_fr logical,dimension(ncol,model%levs) :: liqmask, icemask type(ty_optical_props_2str) :: optical_props_cloudsByBand type(random_stat) :: rng_stat - real(kind_phys), dimension(kdist_sw%get_ngpt(),model%levs,ncol) :: rng3D - real(kind_phys), dimension(kdist_sw%get_ngpt()*model%levs) :: rng1D - logical, dimension(ncol,model%levs,kdist_sw%get_ngpt()) :: cldfracMCICA - real(kind_phys), dimension(nday,model%levs,kdist_sw%get_nband()) :: & + real(kind_phys), dimension(sw_gas_props%get_ngpt(),model%levs,ncol) :: rng3D + real(kind_phys), dimension(sw_gas_props%get_ngpt()*model%levs) :: rng1D + logical, dimension(ncol,model%levs,sw_gas_props%get_ngpt()) :: cldfracMCICA + real(kind_phys), dimension(nday,model%levs,sw_gas_props%get_nband()) :: & tau_cld, ssa_cld, asy_cld ! Initialize CCPP error handling variables @@ -140,11 +140,11 @@ subroutine GFS_rrtmgp_sw_run(Model, ncol, icseed_sw, p_lay, t_lay, p_lev, cld_fr ! Allocate space for RRTMGP DDTs containing cloud and aerosol radiative properties ! ####################################################################################### ! Cloud optics [ncol,model%levs,nBands] - call check_error_msg('GFS_rrtmgp_sw_run',optical_props_cloudsByBand%alloc_2str(ncol, model%levs, kdist_sw%get_band_lims_wavenumber())) + call check_error_msg('GFS_rrtmgp_sw_run',optical_props_cloudsByBand%alloc_2str(ncol, model%levs, sw_gas_props%get_band_lims_wavenumber())) ! Aerosol optics [ncol,model%levs,nBands] - call check_error_msg('GFS_rrtmgp_sw_run',optical_props_aerosol%alloc_2str(ncol, model%levs, kdist_sw%get_band_lims_wavenumber())) + call check_error_msg('GFS_rrtmgp_sw_run',optical_props_aerosol%alloc_2str(ncol, model%levs, sw_gas_props%get_band_lims_wavenumber())) ! Cloud optics [ncol,model%levs,nGpts] - call check_error_msg('GFS_rrtmgp_sw_run',optical_props_clouds%alloc_2str(ncol, model%levs, kdist_sw)) + call check_error_msg('GFS_rrtmgp_sw_run',optical_props_clouds%alloc_2str(ncol, model%levs, sw_gas_props)) ! ####################################################################################### ! Copy aerosol optical information to RRTMGP DDT @@ -156,12 +156,12 @@ subroutine GFS_rrtmgp_sw_run(Model, ncol, icseed_sw, p_lay, t_lay, p_lev, cld_fr ! ####################################################################################### ! Compute cloud-optics for RTE. ! ####################################################################################### - if (Model%rrtmgp_cld_phys .gt. 0) then + if (Model%rrtmgp_cld_optics .gt. 0) then ! RRTMGP cloud-optics. - call check_error_msg('GFS_rrtmgp_sw_run',kdist_cldy_sw%cloud_optics(& + call check_error_msg('GFS_rrtmgp_sw_run',sw_cloud_props%cloud_optics(& ncol, & ! IN - Number of daylit gridpoints model%levs, & ! IN - Number of vertical layers - kdist_sw%get_nband(), & ! IN - Number of SW bands + sw_gas_props%get_nband(), & ! IN - Number of SW bands nrghice_sw, & ! IN - Number of ice-roughness categories liqmask, & ! IN - Liquid-cloud mask icemask, & ! IN - Ice-cloud mask @@ -177,7 +177,7 @@ subroutine GFS_rrtmgp_sw_run(Model, ncol, icseed_sw, p_lay, t_lay, p_lev, cld_fr optical_props_cloudsByBand%tau(:,:,:) = 0._kind_phys optical_props_cloudsByBand%ssa(:,:,:) = 0._kind_phys optical_props_cloudsByBand%g(:,:,:) = 0._kind_phys - call rrtmgp_sw_cloud_optics(nday, model%levs, kdist_sw%get_nband(), cld_lwp(idxday,:), & + call rrtmgp_sw_cloud_optics(nday, model%levs, sw_gas_props%get_nband(), cld_lwp(idxday,:), & cld_reliq(idxday,:), cld_iwp(idxday,:), cld_reice(idxday,:), cld_rwp(idxday,:), & cld_rerain(idxday,:), cld_swp(idxday,:), cld_resnow(idxday,:), cld_frac(idxday,:),& tau_cld, ssa_cld, asy_cld) @@ -194,7 +194,7 @@ subroutine GFS_rrtmgp_sw_run(Model, ncol, icseed_sw, p_lay, t_lay, p_lev, cld_fr do iCol=1,ncol call random_setseed(ipseed_sw(icol),rng_stat) call random_number(rng1D,rng_stat) - rng3D(:,:,iCol) = reshape(source = rng1D,shape=[kdist_sw%get_ngpt(),model%levs]) + rng3D(:,:,iCol) = reshape(source = rng1D,shape=[sw_gas_props%get_ngpt(),model%levs]) enddo ! Call McICA @@ -214,15 +214,5 @@ end subroutine GFS_rrtmgp_sw_run subroutine GFS_rrtmgp_sw_finalize() end subroutine GFS_rrtmgp_sw_finalize - - subroutine check_error_msg(routine_name, error_msg) - character(len=*), intent(in) :: & - error_msg, routine_name - - if(error_msg /= "") then - print*,"ERROR("//trim(routine_name)//"): " - print*,trim(error_msg) - return - end if - end subroutine check_error_msg + end module GFS_rrtmgp_sw diff --git a/physics/GFS_rrtmgp_sw_post.F90 b/physics/GFS_rrtmgp_sw_post.F90 index a8c2d87bc..122ce3f44 100644 --- a/physics/GFS_rrtmgp_sw_post.F90 +++ b/physics/GFS_rrtmgp_sw_post.F90 @@ -14,6 +14,7 @@ module GFS_rrtmgp_sw_post use mo_gas_optics_rrtmgp, only: ty_gas_optics_rrtmgp use mo_fluxes_byband, only: ty_fluxes_byband use mo_heating_rates, only: compute_heating_rate + use rrtmgp_aux, only: check_error_msg implicit none public GFS_rrtmgp_sw_post_init,GFS_rrtmgp_sw_post_run,GFS_rrtmgp_sw_post_finalize @@ -44,7 +45,7 @@ end subroutine GFS_rrtmgp_sw_post_init !! | fluxswDOWN_allsky | sw_flux_profile_downward_allsky | RRTMGP downward shortwave all-sky flux profile | W m-2 | 2 | real | kind_phys | in | F | !! | fluxswUP_clrsky | sw_flux_profile_upward_clrsky | RRTMGP upward shortwave clr-sky flux profile | W m-2 | 2 | real | kind_phys | in | F | !! | fluxswDOWN_clrsky | sw_flux_profile_downward_clrsky | RRTMGP downward shortwave clr-sky flux profile | W m-2 | 2 | real | kind_phys | in | F | -!! | kdist_sw | K_distribution_file_for_RRTMGP_SW_scheme | DDT containing spectral information for RRTMGP SW radiation scheme | DDT | 0 | ty_gas_optics_rrtmgp | | in | F | +!! | sw_gas_props | coefficients_for_sw_gas_optics | DDT containing spectral information for RRTMGP SW radiation scheme | DDT | 0 | ty_gas_optics_rrtmgp | | in | F | !! | sfc_alb_nir_dir | surface_shortwave_albedo_near_infrared_direct_in_each_band | surface sw near-infrared direct albedo in each SW band | frac | 2 | real | kind_phys | in | F | !! | sfc_alb_nir_dif | surface_shortwave_albedo_near_infrared_diffuse_in_each_band | surface sw near-infrared diffuse albedo in each SW band | frac | 2 | real | kind_phys | in | F | !! | sfc_alb_uvvis_dir | surface_shortwave_albedo_uv_visible_direct_in_each_band | surface sw uv-visible direct albedo in each SW band | frac | 2 | real | kind_phys | in | F | @@ -59,7 +60,7 @@ end subroutine GFS_rrtmgp_sw_post_init !! #endif subroutine GFS_rrtmgp_sw_post_run (Model, Grid, Diag, Radtend, Statein, Coupling, & - scmpsw, im, p_lev, kdist_sw, sfc_alb_nir_dir, sfc_alb_nir_dif, sfc_alb_uvvis_dir, & + scmpsw, im, p_lev, sw_gas_props, sfc_alb_nir_dir, sfc_alb_nir_dif, sfc_alb_uvvis_dir, & sfc_alb_uvvis_dif, tsfa, nday, idxday, fluxswUP_allsky, fluxswDOWN_allsky, & fluxswUP_clrsky, fluxswDOWN_clrsky, hswc, topflx_sw, sfcflx_sw, flxprf_sw, hsw0, & errmsg, errflg) @@ -85,10 +86,10 @@ subroutine GFS_rrtmgp_sw_post_run (Model, Grid, Diag, Radtend, Statein, Coupling real(kind_phys), dimension(size(Grid%xlon,1)), intent(in) :: & tsfa ! Lowest model layer air temperature for radiation type(ty_gas_optics_rrtmgp),intent(in) :: & - kdist_sw ! DDT containing SW spectral information + sw_gas_props ! DDT containing SW spectral information real(kind_phys), dimension(size(Grid%xlon,1), Model%levs+1), intent(in) :: & p_lev ! Pressure @ model layer-interfaces (hPa) - real(kind_phys),dimension(kdist_sw%get_nband(),size(Grid%xlon,1)),intent(in) :: & + real(kind_phys),dimension(sw_gas_props%get_nband(),size(Grid%xlon,1)),intent(in) :: & sfc_alb_nir_dir, & ! Shortwave surface albedo (nIR-direct) sfc_alb_nir_dif, & ! Shortwave surface albedo (nIR-diffuse) sfc_alb_uvvis_dir, & ! Shortwave surface albedo (uvvis-direct) @@ -274,14 +275,4 @@ end subroutine GFS_rrtmgp_sw_post_run subroutine GFS_rrtmgp_sw_post_finalize () end subroutine GFS_rrtmgp_sw_post_finalize - subroutine check_error_msg(routine_name, error_msg) - character(len=*), intent(in) :: & - error_msg, routine_name - - if(error_msg /= "") then - print*,"ERROR("//trim(routine_name)//"): " - print*,trim(error_msg) - return - end if - end subroutine check_error_msg end module GFS_rrtmgp_sw_post diff --git a/physics/rrtmgp_aux.F90 b/physics/rrtmgp_aux.F90 new file mode 100644 index 000000000..34c885ce4 --- /dev/null +++ b/physics/rrtmgp_aux.F90 @@ -0,0 +1,1370 @@ +module rrtmgp_aux + use machine, only: kind_phys + use GFS_typedefs, only: GFS_control_type + use mo_rte_kind, only: wl + use mo_gas_optics_rrtmgp, only: ty_gas_optics_rrtmgp + use mo_cloud_optics, only: ty_cloud_optics + use mo_gas_concentrations, only: ty_gas_concs + use netcdf + + ! Parameters + integer,parameter :: nGases = 6 + character(len=3),parameter, dimension(nGases) :: & + active_gases = (/ 'h2o', 'co2', 'o3 ', 'n2o', 'ch4', 'o2 '/) + integer :: nrghice_lw, nrghice_sw, ipsdlw0, ipsdsw0 + +contains + + subroutine rrtmgp_aux_init() + end subroutine rrtmgp_aux_init + subroutine rrtmgp_aux_run() + end subroutine rrtmgp_aux_run + subroutine rrtmgp_aux_finalize() + end subroutine rrtmgp_aux_finalize + + ! ######################################################################################### + ! SUBROUTINE rrtmgp_lw_cloud_optics_init() + ! ######################################################################################### + subroutine lw_cloud_optics_init(Model, mpicomm, mpirank, mpiroot, lw_cloud_props, & + errmsg, errflg) +#ifdef MPI + use mpi +#endif + + ! Inputs + type(GFS_control_type), intent(in) :: & + Model ! DDT containing model control parameters + integer,intent(in) :: & + mpicomm, & ! MPI communicator + mpirank, & ! Current MPI rank + mpiroot ! Master MPI rank + type(ty_cloud_optics),intent(inout) :: & + lw_cloud_props + + ! Outputs + character(len=*), intent(out) :: & + errmsg ! Error message + integer, intent(out) :: & + errflg ! Error code + + ! Variables that will be passed to cloud_optics%load() + real(kind_phys) :: & + radliq_lwr, & ! used by RRTGMP cloud optics + radliq_upr, & ! used by RRTGMP cloud optics + radliq_fac, & ! used by RRTGMP cloud optics + radice_lwr, & ! used by RRTGMP cloud optics + radice_upr, & ! used by RRTGMP cloud optics + radice_fac ! used by RRTGMP cloud optics + real(kind_phys), dimension(:), allocatable :: & + pade_sizereg_extliq, & ! used by RRTGMP cloud optics + pade_sizereg_ssaliq, & ! used by RRTGMP cloud optics + pade_sizereg_asyliq, & ! used by RRTGMP cloud optics + pade_sizereg_extice, & ! used by RRTGMP cloud optics + pade_sizereg_ssaice, & ! used by RRTGMP cloud optics + pade_sizereg_asyice ! used by RRTGMP cloud optics + real(kind_phys), dimension(:,:), allocatable :: & + lut_extliq, & ! used by RRTGMP cloud optics + lut_ssaliq, & ! used by RRTGMP cloud optics + lut_asyliq, & ! used by RRTGMP cloud optics + band_lims_cldy ! used by RRTGMP cloud optics + + real(kind_phys), dimension(:,:,:), allocatable :: & + lut_extice, & ! used by RRTGMP cloud optics + lut_ssaice, & ! used by RRTGMP cloud optics + lut_asyice, & ! used by RRTGMP cloud optics + pade_extliq, & ! used by RRTGMP cloud optics + pade_ssaliq, & ! used by RRTGMP cloud optics + pade_asyliq ! used by RRTGMP cloud optics + real(kind_phys), dimension(:,:,:,:), allocatable :: & + pade_extice, & ! used by RRTGMP cloud optics + pade_ssaice, & ! used by RRTGMP cloud optics + pade_asyice ! used by RRTGMP cloud optics + ! Dimensions + integer :: & + nbandLWcldy, & ! used by RRTGMP cloud optics + nsize_liq, & ! used by RRTGMP cloud optics + nsize_ice, & ! used by RRTGMP cloud optics + nsizereg, & ! used by RRTGMP cloud optics + ncoeff_ext, & ! used by RRTGMP cloud optics + ncoeff_ssa_g, & ! used by RRTGMP cloud optics + nbound, & ! used by RRTGMP cloud optics + npairsLWcldy ! used by RRTGMP cloud optics + + ! Local variables + integer :: dimID,varID,status,igpt,iGas,ij,ierr,ncid_lw_clds + integer,dimension(:),allocatable :: temp1,temp2,temp3,temp4,temp_log_array1,& + temp_log_array2, temp_log_array3, temp_log_array4 + character(len=264) :: lw_cloud_props_file + integer,parameter :: max_strlen=256 + + ! Initialize + errmsg = '' + errflg = 0 + + ! Filenames are set in the gfs_physics_nml (scm/src/GFS_typedefs.F90) + lw_cloud_props_file = trim(Model%rrtmgp_root)//trim(Model%lw_file_clouds) + ! Read dimensions for k-distribution fields (only on master processor(0)) + if (mpirank .eq. mpiroot) then + if(nf90_open(trim(lw_cloud_props_file), NF90_WRITE, ncid_lw_clds) == NF90_NOERR) then + status = nf90_inq_dimid(ncid_lw_clds, 'nband', dimid) + status = nf90_inquire_dimension(ncid_lw_clds, dimid, len=nbandLWcldy) + status = nf90_inq_dimid(ncid_lw_clds, 'nrghice', dimid) + status = nf90_inquire_dimension(ncid_lw_clds, dimid, len=nrghice_lw) + status = nf90_inq_dimid(ncid_lw_clds, 'nsize_liq', dimid) + status = nf90_inquire_dimension(ncid_lw_clds, dimid, len=nsize_liq) + status = nf90_inq_dimid(ncid_lw_clds, 'nsize_ice', dimid) + status = nf90_inquire_dimension(ncid_lw_clds, dimid, len=nsize_ice) + status = nf90_inq_dimid(ncid_lw_clds, 'nsizereg', dimid) + status = nf90_inquire_dimension(ncid_lw_clds, dimid, len=nsizereg) + status = nf90_inq_dimid(ncid_lw_clds, 'ncoeff_ext', dimid) + status = nf90_inquire_dimension(ncid_lw_clds, dimid, len=ncoeff_ext) + status = nf90_inq_dimid(ncid_lw_clds, 'ncoeff_ssa_g', dimid) + status = nf90_inquire_dimension(ncid_lw_clds, dimid, len=ncoeff_ssa_g) + status = nf90_inq_dimid(ncid_lw_clds, 'nbound', dimid) + status = nf90_inquire_dimension(ncid_lw_clds, dimid, len=nbound) + status = nf90_inq_dimid(ncid_lw_clds, 'pair', dimid) + status = nf90_inquire_dimension(ncid_lw_clds, dimid, len=npairsLWcldy) + status = nf90_close(ncid_lw_clds) + endif + endif + + ! Broadcast dimensions to all processors +#ifdef MPI + if (Model%rrtmgp_cld_optics .eq. 1 .or. Model%rrtmgp_cld_optics .eq. 2) then + call MPI_BCAST(nbandLWcldy, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(nrghice_lw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(nsize_liq, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(nsize_ice, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(nsizereg, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(ncoeff_ext, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(ncoeff_ssa_g, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(nbound, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(npairsLWcldy, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + endif +#endif + + if (Model%rrtmgp_cld_optics .eq. 1) then + allocate(lut_extliq(nsize_liq, nBandLWcldy)) + allocate(lut_ssaliq(nsize_liq, nBandLWcldy)) + allocate(lut_asyliq(nsize_liq, nBandLWcldy)) + allocate(lut_extice(nsize_ice, nBandLWcldy, nrghice_lw)) + allocate(lut_ssaice(nsize_ice, nBandLWcldy, nrghice_lw)) + allocate(lut_asyice(nsize_ice, nBandLWcldy, nrghice_lw)) + allocate(band_lims_cldy(2, nBandLWcldy)) + endif + if (Model%rrtmgp_cld_optics .eq. 2) then + allocate(pade_extliq(nbandLWcldy, nsizereg, ncoeff_ext )) + allocate(pade_ssaliq(nbandLWcldy, nsizereg, ncoeff_ssa_g)) + allocate(pade_asyliq(nbandLWcldy, nsizereg, ncoeff_ssa_g)) + allocate(pade_extice(nbandLWcldy, nsizereg, ncoeff_ext, nrghice_lw)) + allocate(pade_ssaice(nbandLWcldy, nsizereg, ncoeff_ssa_g, nrghice_lw)) + allocate(pade_asyice(nbandLWcldy, nsizereg, ncoeff_ssa_g, nrghice_lw)) + allocate(pade_sizereg_extliq(nbound)) + allocate(pade_sizereg_ssaliq(nbound)) + allocate(pade_sizereg_asyliq(nbound)) + allocate(pade_sizereg_extice(nbound)) + allocate(pade_sizereg_ssaice(nbound)) + allocate(pade_sizereg_asyice(nbound)) + allocate(band_lims_cldy(2,nbandLWcldy)) + endif + + ! On master processor, allocate space, read in fields, broadcast to all processors + if (mpirank .eq. mpiroot) then + ! + if (Model%rrtmgp_cld_optics .eq. 1) then + ! + if(nf90_open(trim(lw_cloud_props_file), NF90_WRITE, ncid_lw_clds) == NF90_NOERR) then + status = nf90_inq_varid(ncid_lw_clds,'radliq_lwr',varID) + status = nf90_get_var(ncid_lw_clds,varID,radliq_lwr) + status = nf90_inq_varid(ncid_lw_clds,'radliq_upr',varID) + status = nf90_get_var(ncid_lw_clds,varID,radliq_upr) + status = nf90_inq_varid(ncid_lw_clds,'radliq_fac',varID) + status = nf90_get_var(ncid_lw_clds,varID,radliq_fac) + status = nf90_inq_varid(ncid_lw_clds,'radice_lwr',varID) + status = nf90_get_var(ncid_lw_clds,varID,radice_lwr) + status = nf90_inq_varid(ncid_lw_clds,'radice_upr',varID) + status = nf90_get_var(ncid_lw_clds,varID,radice_upr) + status = nf90_inq_varid(ncid_lw_clds,'radice_fac',varID) + status = nf90_get_var(ncid_lw_clds,varID,radice_fac) + status = nf90_inq_varid(ncid_lw_clds,'lut_extliq',varID) + status = nf90_get_var(ncid_lw_clds,varID,lut_extliq) + status = nf90_inq_varid(ncid_lw_clds,'lut_ssaliq',varID) + status = nf90_get_var(ncid_lw_clds,varID,lut_ssaliq) + status = nf90_inq_varid(ncid_lw_clds,'lut_asyliq',varID) + status = nf90_get_var(ncid_lw_clds,varID,lut_asyliq) + status = nf90_inq_varid(ncid_lw_clds,'lut_extice',varID) + status = nf90_get_var(ncid_lw_clds,varID,lut_extice) + status = nf90_inq_varid(ncid_lw_clds,'lut_ssaice',varID) + status = nf90_get_var(ncid_lw_clds,varID,lut_ssaice) + status = nf90_inq_varid(ncid_lw_clds,'lut_asyice',varID) + status = nf90_get_var(ncid_lw_clds,varID,lut_asyice) + status = nf90_inq_varid(ncid_lw_clds,'bnd_limits_wavenumber',varID) + status = nf90_get_var(ncid_lw_clds,varID,band_lims_cldy) + status = nf90_close(ncid_lw_clds) + endif + endif + ! + if (Model%rrtmgp_cld_optics .eq. 2) then + ! + if(nf90_open(trim(lw_cloud_props_file), NF90_WRITE, ncid_lw_clds) == NF90_NOERR) then + status = nf90_inq_varid(ncid_lw_clds,'radliq_lwr',varID) + status = nf90_get_var(ncid_lw_clds,varID,radliq_lwr) + status = nf90_inq_varid(ncid_lw_clds,'radliq_upr',varID) + status = nf90_get_var(ncid_lw_clds,varID,radliq_upr) + status = nf90_inq_varid(ncid_lw_clds,'radliq_fac',varID) + status = nf90_get_var(ncid_lw_clds,varID,radliq_fac) + status = nf90_inq_varid(ncid_lw_clds,'radice_lwr',varID) + status = nf90_get_var(ncid_lw_clds,varID,radice_lwr) + status = nf90_inq_varid(ncid_lw_clds,'radice_upr',varID) + status = nf90_get_var(ncid_lw_clds,varID,radice_upr) + status = nf90_inq_varid(ncid_lw_clds,'radice_fac',varID) + status = nf90_get_var(ncid_lw_clds,varID,radice_fac) + status = nf90_inq_varid(ncid_lw_clds,'pade_extliq',varID) + status = nf90_get_var(ncid_lw_clds,varID,pade_extliq) + status = nf90_inq_varid(ncid_lw_clds,'pade_ssaliq',varID) + status = nf90_get_var(ncid_lw_clds,varID,pade_ssaliq) + status = nf90_inq_varid(ncid_lw_clds,'pade_asyliq',varID) + status = nf90_get_var(ncid_lw_clds,varID,pade_asyliq) + status = nf90_inq_varid(ncid_lw_clds,'pade_extice',varID) + status = nf90_get_var(ncid_lw_clds,varID,pade_extice) + status = nf90_inq_varid(ncid_lw_clds,'pade_ssaice',varID) + status = nf90_get_var(ncid_lw_clds,varID,pade_ssaice) + status = nf90_inq_varid(ncid_lw_clds,'pade_asyice',varID) + status = nf90_get_var(ncid_lw_clds,varID,pade_asyice) + status = nf90_inq_varid(ncid_lw_clds,'pade_sizreg_extliq',varID) + status = nf90_get_var(ncid_lw_clds,varID,pade_sizereg_extliq) + status = nf90_inq_varid(ncid_lw_clds,'pade_sizreg_ssaliq',varID) + status = nf90_get_var(ncid_lw_clds,varID,pade_sizereg_ssaliq) + status = nf90_inq_varid(ncid_lw_clds,'pade_sizreg_asyliq',varID) + status = nf90_get_var(ncid_lw_clds,varID,pade_sizereg_asyliq) + status = nf90_inq_varid(ncid_lw_clds,'pade_sizreg_extice',varID) + status = nf90_get_var(ncid_lw_clds,varID,pade_sizereg_extice) + status = nf90_inq_varid(ncid_lw_clds,'pade_sizreg_ssaice',varID) + status = nf90_get_var(ncid_lw_clds,varID,pade_sizereg_ssaice) + status = nf90_inq_varid(ncid_lw_clds,'pade_sizreg_asyice',varID) + status = nf90_get_var(ncid_lw_clds,varID,pade_sizereg_asyice) + status = nf90_inq_varid(ncid_lw_clds,'bnd_limits_wavenumber',varID) + status = nf90_get_var(ncid_lw_clds,varID,band_lims_cldy) + status = nf90_close(ncid_lw_clds) + endif + endif + endif + + ! Broadcast arrays to all processors +#ifdef MPI + if (Model%rrtmgp_cld_optics .eq. 1) then + call MPI_BCAST(radliq_lwr, size(radliq_lwr), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(radliq_upr, size(radliq_upr), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(radliq_fac, size(radliq_fac), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(radice_lwr, size(radice_lwr), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(radice_upr, size(radice_upr), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(radice_fac, size(radice_fac), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(lut_extliq, size(lut_extliq), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(lut_ssaliq, size(lut_ssaliq), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(lut_asyliq, size(lut_asyliq), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(lut_extice, size(lut_extice), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(lut_ssaice, size(lut_ssaice), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(lut_asyice, size(lut_asyice), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(band_lims_cldy), size(band_lims_cldy), kind_phys, mpiroot, mpicomm, ierr) + endif + if (Model%rrtmgp_cld_optics .eq. 2) then + call MPI_BCAST(pade_extliq, size(pade_extliq), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(pade_ssaliq, size(pade_ssaliq), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(pade_asyliq, size(pade_asyliq), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(pade_extice, size(pade_extice), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(pade_ssaice, size(pade_ssaice), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(pade_asyice, size(pade_asyice), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(pade_sizereg_extliq), size(pade_sizereg_extliq), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(pade_sizereg_ssaliq), size(pade_sizereg_ssaliq), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(pade_sizereg_asyliq), size(pade_sizereg_asyliq), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(pade_sizereg_extice), size(pade_sizereg_extice), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(pade_sizereg_ssaice), size(pade_sizereg_ssaice), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(pade_sizereg_asyice), size(pade_sizereg_asyice), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(band_lims_cldy), size(band_lims_cldy), kind_phys, mpiroot, mpicomm, ierr) + endif +#endif + + ! Load tables data for RRTGMP cloud-optics + if (Model%rrtmgp_cld_optics .eq. 1) then + call check_error_msg('lw_cloud_optics_init',lw_cloud_props%set_ice_roughness(nrghice_lw)) + call check_error_msg('lw_cloud_optics_init',lw_cloud_props%load(band_lims_cldy, & + radliq_lwr, radliq_upr, radliq_fac, radice_lwr, radice_upr, radice_fac, & + lut_extliq, lut_ssaliq, lut_asyliq, lut_extice, lut_ssaice, lut_asyice)) + endif + if (Model%rrtmgp_cld_optics .eq. 2) then + call check_error_msg('lw_cloud_optics_init',lw_cloud_props%set_ice_roughness(nrghice_lw)) + call check_error_msg('lw_cloud_optics_init',lw_cloud_props%load(band_lims_cldy, & + pade_extliq, pade_ssaliq, pade_asyliq, pade_extice, pade_ssaice, & + pade_asyice, pade_sizereg_extliq, pade_sizereg_ssaliq, pade_sizereg_asyliq,& + pade_sizereg_extice, pade_sizereg_ssaice, pade_sizereg_asyice)) + endif + end subroutine lw_cloud_optics_init + + ! ######################################################################################### + ! SUBROUTINE rrtmgp_lw_gas_optics_init() + ! ######################################################################################### + subroutine lw_gas_optics_init(Model, mpicomm, mpirank, mpiroot, lw_gas_props, & + errmsg, errflg) + use netcdf + +#ifdef MPI + use mpi +#endif + + ! Inputs + type(GFS_control_type), intent(in) :: & + Model ! DDT containing model control parameters + integer,intent(in) :: & + mpicomm, & ! MPI communicator + mpirank, & ! Current MPI rank + mpiroot ! Master MPI rank + type(ty_gas_optics_rrtmgp),intent(inout) :: & + lw_gas_props + + ! Outputs + character(len=*), intent(out) :: & + errmsg ! Error message + integer, intent(out) :: & + errflg ! Error code + + ! Variables that will be passed to gas_optics%load() + type(ty_gas_concs) :: & + gas_concentrations + integer, dimension(:), allocatable :: & + kminor_start_lower, & ! used by RRTGMP gas optics + kminor_start_upper ! used by RRTGMP gas optics + integer, dimension(:,:), allocatable :: & + band2gpt, & ! used by RRTGMP gas optics + minor_limits_gpt_lower, & ! used by RRTGMP gas optics + minor_limits_gpt_upper ! used by RRTGMP gas optics + integer, dimension(:,:,:), allocatable :: & + key_species ! used by RRTGMP gas optics + real(kind_phys) :: & + press_ref_trop, & ! used by RRTGMP gas optics + temp_ref_p, & ! used by RRTGMP gas optics + temp_ref_t ! used by RRTGMP gas optics + real(kind_phys), dimension(:), allocatable :: & + press_ref, & ! used by RRTGMP gas optics + temp_ref ! used by RRTGMP gas optics + real(kind_phys), dimension(:,:), allocatable :: & + band_lims, & ! used by RRTGMP gas optics + totplnk ! used by RRTGMP gas optics + real(kind_phys), dimension(:,:,:), allocatable :: & + vmr_ref, & ! used by RRTGMP gas optics + kminor_lower, & ! used by RRTGMP gas optics + kminor_upper, & ! used by RRTGMP gas optics + rayl_lower, & ! used by RRTGMP gas optics + rayl_upper ! used by RRTGMP gas optics + real(kind_phys), dimension(:,:,:,:), allocatable :: & + kmajor, & ! used by RRTGMP gas optics + planck_frac ! used by RRTGMP gas optics + character(len=32), dimension(:), allocatable :: & + gas_names, & ! used by RRTGMP gas optics + gas_minor, & ! used by RRTGMP gas optics + identifier_minor, & ! used by RRTGMP gas optics + minor_gases_lower, & ! used by RRTGMP gas optics + minor_gases_upper, & ! used by RRTGMP gas optics + scaling_gas_lower, & ! used by RRTGMP gas optics + scaling_gas_upper ! used by RRTGMP gas optics + logical(wl), dimension(:), allocatable :: & + minor_scales_with_density_lower, & ! used by RRTGMP gas optics + minor_scales_with_density_upper, & ! used by RRTGMP gas optics + scale_by_complement_lower, & ! used by RRTGMP gas optics + scale_by_complement_upper ! used by RRTGMP gas optics + + ! Dimensions (to be broadcast across all processors) + integer :: & + ntemps, & ! used by RRTGMP gas optics + npress, & ! used by RRTGMP gas optics + nabsorbers, & ! used by RRTGMP gas optics + nextrabsorbers, & ! used by RRTGMP gas optics + nminorabsorbers, & ! used by RRTGMP gas optics + nmixingfracs, & ! used by RRTGMP gas optics + nlayers, & ! used by RRTGMP gas optics + nbnds, & ! used by RRTGMP gas optics + ngpts, & ! used by RRTGMP gas optics + npairs, & ! used by RRTGMP gas optics + ninternalSourcetemps, & ! used by RRTGMP gas optics + nminor_absorber_intervals_lower, & ! used by RRTGMP gas optics + nminor_absorber_intervals_upper, & ! used by RRTGMP gas optics + ncontributors_lower, & ! used by RRTGMP gas optics + ncontributors_upper ! used by RRTGMP gas optics + + ! Local variables + integer :: ncid_lw,dimID,varID,status,igpt,iGas,ij,ierr + integer,dimension(:),allocatable :: temp1,temp2,temp3,temp4,temp_log_array1,& + temp_log_array2, temp_log_array3, temp_log_array4 + character(len=264) :: lw_gas_props_file + integer,parameter :: max_strlen=256 + + ! Initialize + errmsg = '' + errflg = 0 + + ! Filenames are set in the gfs_physics_nml (scm/src/GFS_typedefs.F90) + lw_gas_props_file = trim(Model%rrtmgp_root)//trim(Model%lw_file_gas) + + ! Read dimensions for k-distribution fields (only on master processor(0)) + if (mpirank .eq. mpiroot) then + if(nf90_open(trim(lw_gas_props_file), NF90_WRITE, ncid_lw) .eq. NF90_NOERR) then + status = nf90_inq_dimid(ncid_lw, 'temperature', dimid) + status = nf90_inquire_dimension(ncid_lw, dimid, len=ntemps) + status = nf90_inq_dimid(ncid_lw, 'pressure', dimid) + status = nf90_inquire_dimension(ncid_lw, dimid, len=npress) + status = nf90_inq_dimid(ncid_lw, 'absorber', dimid) + status = nf90_inquire_dimension(ncid_lw, dimid, len=nabsorbers) + status = nf90_inq_dimid(ncid_lw, 'minor_absorber', dimid) + status = nf90_inquire_dimension(ncid_lw, dimid, len=nminorabsorbers) + status = nf90_inq_dimid(ncid_lw, 'absorber_ext', dimid) + status = nf90_inquire_dimension(ncid_lw, dimid, len=nextrabsorbers) + status = nf90_inq_dimid(ncid_lw, 'mixing_fraction', dimid) + status = nf90_inquire_dimension(ncid_lw, dimid, len=nmixingfracs) + status = nf90_inq_dimid(ncid_lw, 'atmos_layer', dimid) + status = nf90_inquire_dimension(ncid_lw, dimid, len=nlayers) + status = nf90_inq_dimid(ncid_lw, 'bnd', dimid) + status = nf90_inquire_dimension(ncid_lw, dimid, len=nbnds) + status = nf90_inq_dimid(ncid_lw, 'gpt', dimid) + status = nf90_inquire_dimension(ncid_lw, dimid, len=ngpts) + status = nf90_inq_dimid(ncid_lw, 'pair', dimid) + status = nf90_inquire_dimension(ncid_lw, dimid, len=npairs) + status = nf90_inq_dimid(ncid_lw, 'contributors_lower', dimid) + status = nf90_inquire_dimension(ncid_lw, dimid, len=ncontributors_lower) + status = nf90_inq_dimid(ncid_lw, 'contributors_upper', dimid) + status = nf90_inquire_dimension(ncid_lw, dimid, len=ncontributors_upper) + status = nf90_inq_dimid(ncid_lw, 'minor_absorber_intervals_lower', dimid) + status = nf90_inquire_dimension(ncid_lw, dimid, len=nminor_absorber_intervals_lower) + status = nf90_inq_dimid(ncid_lw, 'minor_absorber_intervals_upper', dimid) + status = nf90_inquire_dimension(ncid_lw, dimid, len=nminor_absorber_intervals_upper) + status = nf90_inq_dimid(ncid_lw, 'temperature_Planck', dimid) + status = nf90_inquire_dimension(ncid_lw, dimid, len=ninternalSourcetemps) + status = nf90_close(ncid_lw) + endif + endif + + ! Broadcast dimensions to all processors +#ifdef MPI + call MPI_BCAST(ntemps, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(npress, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(nabsorbers, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(nminorabsorbers, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(nextraabsorbers, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(nmixingfracs, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(nlayers, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(nbnds, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(ngpts, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(npairs, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(ncontributors_lower, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(ncontributors_upper, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(nminor_absorber_intervals_lower, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(nminor_absorber_intervals_upper, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(ninternalSourcetemps, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) +#endif + + !if (mpirank .eq. mpiroot) then + ! Allocate space for arrays + allocate(gas_names(nabsorbers)) + allocate(scaling_gas_lower(nminor_absorber_intervals_lower)) + allocate(scaling_gas_upper(nminor_absorber_intervals_upper)) + allocate(gas_minor(nminorabsorbers)) + allocate(identifier_minor(nminorabsorbers)) + allocate(minor_gases_lower(nminor_absorber_intervals_lower)) + allocate(minor_gases_upper(nminor_absorber_intervals_upper)) + allocate(minor_limits_gpt_lower(npairs,nminor_absorber_intervals_lower)) + allocate(minor_limits_gpt_upper(npairs,nminor_absorber_intervals_upper)) + allocate(band2gpt(2,nbnds)) + allocate(key_species(2,nlayers,nbnds)) + allocate(band_lims(2,nbnds)) + allocate(press_ref(npress)) + allocate(temp_ref(ntemps)) + allocate(vmr_ref(nlayers, nextrabsorbers, ntemps)) + allocate(kminor_lower(ncontributors_lower, nmixingfracs, ntemps)) + allocate(kmajor(ngpts, nmixingfracs, npress+1, ntemps)) + allocate(kminor_start_lower(nminor_absorber_intervals_lower)) + allocate(kminor_upper(ncontributors_upper, nmixingfracs, ntemps)) + allocate(kminor_start_upper(nminor_absorber_intervals_upper)) + allocate(minor_scales_with_density_lower(nminor_absorber_intervals_lower)) + allocate(minor_scales_with_density_upper(nminor_absorber_intervals_upper)) + allocate(scale_by_complement_lower(nminor_absorber_intervals_lower)) + allocate(scale_by_complement_upper(nminor_absorber_intervals_upper)) + allocate(temp1(nminor_absorber_intervals_lower)) + allocate(temp2(nminor_absorber_intervals_upper)) + allocate(temp3(nminor_absorber_intervals_lower)) + allocate(temp4(nminor_absorber_intervals_upper)) + allocate(totplnk(ninternalSourcetemps, nbnds)) + allocate(planck_frac(ngpts, nmixingfracs, npress+1, ntemps)) + + if (mpirank .eq. mpiroot) then + ! Read in fields from file + if(nf90_open(trim(lw_gas_props_file), NF90_WRITE, ncid_lw) .eq. NF90_NOERR) then + status = nf90_inq_varid(ncid_lw,'gas_names',varID) + status = nf90_get_var(ncid_lw,varID,gas_names) + ! + status = nf90_inq_varid(ncid_lw,'scaling_gas_lower',varID) + status = nf90_get_var(ncid_lw,varID,scaling_gas_lower) + ! + status = nf90_inq_varid(ncid_lw,'scaling_gas_upper',varID) + status = nf90_get_var(ncid_lw,varID,scaling_gas_upper) + ! + status = nf90_inq_varid(ncid_lw,'gas_minor',varID) + status = nf90_get_var(ncid_lw,varID,gas_minor) + ! + status = nf90_inq_varid(ncid_lw,'identifier_minor',varID) + status = nf90_get_var(ncid_lw,varID,identifier_minor) + ! + status = nf90_inq_varid(ncid_lw,'minor_gases_lower',varID) + status = nf90_get_var(ncid_lw,varID,minor_gases_lower) + ! + status = nf90_inq_varid(ncid_lw,'minor_gases_upper',varID) + status = nf90_get_var(ncid_lw,varID,minor_gases_upper) + ! + status = nf90_inq_varid(ncid_lw,'minor_limits_gpt_lower',varID) + status = nf90_get_var(ncid_lw,varID,minor_limits_gpt_lower) + ! + status = nf90_inq_varid(ncid_lw,'minor_limits_gpt_upper',varID) + status = nf90_get_var(ncid_lw,varID,minor_limits_gpt_upper) + ! + status = nf90_inq_varid(ncid_lw,'bnd_limits_gpt',varID) + status = nf90_get_var(ncid_lw,varID,band2gpt) + ! + status = nf90_inq_varid(ncid_lw,'key_species',varID) + status = nf90_get_var(ncid_lw,varID,key_species) + ! + status = nf90_inq_varid(ncid_lw,'bnd_limits_wavenumber',varID) + status = nf90_get_var(ncid_lw,varID,band_lims) + ! + status = nf90_inq_varid(ncid_lw,'press_ref',varID) + status = nf90_get_var(ncid_lw,varID,press_ref) + ! + status = nf90_inq_varid(ncid_lw,'temp_ref',varID) + status = nf90_get_var(ncid_lw,varID,temp_ref) + ! + status = nf90_inq_varid(ncid_lw,'absorption_coefficient_ref_P',varID) + status = nf90_get_var(ncid_lw,varID,temp_ref_p) + ! + status = nf90_inq_varid(ncid_lw,'absorption_coefficient_ref_T',varID) + status = nf90_get_var(ncid_lw,varID,temp_ref_t) + ! + status = nf90_inq_varid(ncid_lw,'press_ref_trop',varID) + status = nf90_get_var(ncid_lw,varID,press_ref_trop) + ! + status = nf90_inq_varid(ncid_lw,'kminor_lower',varID) + status = nf90_get_var(ncid_lw,varID,kminor_lower) + ! + status = nf90_inq_varid(ncid_lw,'kminor_upper',varID) + status = nf90_get_var(ncid_lw,varID,kminor_upper) + ! + status = nf90_inq_varid(ncid_lw,'vmr_ref',varID) + status = nf90_get_var(ncid_lw,varID,vmr_ref) + ! + status = nf90_inq_varid(ncid_lw,'kmajor',varID) + status = nf90_get_var(ncid_lw,varID,kmajor) + ! + status = nf90_inq_varid(ncid_lw,'kminor_start_lower',varID) + status = nf90_get_var(ncid_lw,varID,kminor_start_lower) + ! + status = nf90_inq_varid(ncid_lw,'kminor_start_upper',varID) + status = nf90_get_var(ncid_lw,varID,kminor_start_upper) + ! + status = nf90_inq_varid(ncid_lw,'totplnk',varID) + status = nf90_get_var(ncid_lw,varID,totplnk) + ! + status = nf90_inq_varid(ncid_lw,'plank_fraction',varID) + status = nf90_get_var(ncid_lw,varID,planck_frac) + + ! Logical fields are read in as integers and then converted to logicals. + status = nf90_inq_varid(ncid_lw,'minor_scales_with_density_lower',varID) + status = nf90_get_var(ncid_lw,varID,temp1) + minor_scales_with_density_lower(:) = .false. + where(temp1 .eq. 1) minor_scales_with_density_lower(:) = .true. + ! + status = nf90_inq_varid(ncid_lw,'minor_scales_with_density_upper',varID) + status = nf90_get_var(ncid_lw,varID,temp2) + minor_scales_with_density_upper(:) = .false. + where(temp2 .eq. 1) minor_scales_with_density_upper(:) = .true. + ! + status = nf90_inq_varid(ncid_lw,'scale_by_complement_lower',varID) + status = nf90_get_var(ncid_lw,varID,temp3) + scale_by_complement_lower(:) = .false. + where(temp3 .eq. 1) scale_by_complement_lower(:) = .true. + ! + status = nf90_inq_varid(ncid_lw,'scale_by_complement_upper',varID) + status = nf90_get_var(ncid_lw,varID,temp4) + scale_by_complement_upper(:) = .false. + where(temp4 .eq. 1) scale_by_complement_upper(:) = .true. + + ! Close + status = nf90_close(ncid_lw) + endif + endif + + ! Broadcast arrays to all processors +#ifdef MPI + call MPI_BCAST(minor_limits_gpt_upper, size(minor_limits_gpt_upper), MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(minor_limits_gpt_lower, size(minor_limits_gpt_lower), MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(kminor_start_upper, size(kminor_start_upper), MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(kminor_start_lower, size(kminor_start_lower), MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(key_species, size(key_species), MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(band2gpt, size(band2gpt), MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(band_lims, size(band_lims), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(press_ref, size(press_ref), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(temp_ref, size(temp_ref), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(kminor_lower, size(kminor_lower), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(kminor_upper, size(kminor_upper), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(scaling_gas_lower, size(scaling_gas_lower), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(scaling_gas_upper, size(scaling_gas_upper), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(vmr_ref, size(vmr_ref), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(kmajor, size(kmajor), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(temp_ref_p, 1, kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(temp_ref_t, 1, kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(press_ref_trop, 1, kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(totplnk, size(totplnk), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(planck_frac, size(planck_frac), kind_phys, mpiroot, mpicomm, ierr) + ! Character arrays + do ij=1,nabsorbers + call MPI_BCAST(gas_names(ij), 32, MPI_CHAR, mpiroot, mpicomm, ierr) + enddo + do ij=1,nminorabsorbers + call MPI_BCAST(gas_minor(ij), 32, MPI_CHAR, mpiroot, mpicomm, ierr) + call MPI_BCAST(identifier_minor(ij), 32, MPI_CHAR, mpiroot, mpicomm, ierr) + enddo + do ij=1,nminor_absorber_intervals_lower + call MPI_BCAST(minor_gases_lower(ij), 32, MPI_CHAR, mpiroot, mpicomm, ierr) + enddo + do ij=1,nminor_absorber_intervals_upper + call MPI_BCAST(minor_gases_upper(ij), 32, MPI_CHAR, mpiroot, mpicomm, ierr) + enddo + ! Logical arrays (First convert to integer-array, then broadcast) + ! + allocate(temp_log_array1(nminor_absorber_intervals_lower)) + where(minor_scales_with_density_lower) + temp_log_array1 = 1 + elsewhere + temp_log_array1 = 0 + end where + call MPI_BCAST(temp_log_array1, size(temp_log_array1), MPI_INTEGER, mpiroot, mpicomm, ierr) + ! + allocate(temp_log_array2(nminor_absorber_intervals_lower)) + where(scale_by_complement_lower) + temp_log_array2 = 1 + elsewhere + temp_log_array2 = 0 + end where + call MPI_BCAST(temp_log_array2, size(temp_log_array2), MPI_INTEGER, mpiroot, mpicomm, ierr) + ! + allocate(temp_log_array3(nminor_absorber_intervals_upper)) + where(minor_scales_with_density_upper) + temp_log_array3 = 1 + elsewhere + temp_log_array3 = 0 + end where + call MPI_BCAST(temp_log_array3, size(temp_log_array3), MPI_INTEGER, mpiroot, mpicomm, ierr) + ! + allocate(temp_log_array4(nminor_absorber_intervals_upper)) + where(scale_by_complement_upper) + temp_log_array4 = 1 + elsewhere + temp_log_array4 = 0 + end where + call MPI_BCAST(temp_log_array4, size(temp_log_array4), MPI_INTEGER, mpiroot, mpicomm, ierr) +#endif + + ! Initialize gas concentrations and gas optics class with data + do iGas=1,nGases + call check_error_msg('lw_gas_optics_init',gas_concentrations%set_vmr(active_gases(iGas), 0._kind_phys)) + enddo + call check_error_msg('lw_gas_optics_init',lw_gas_props%load(gas_concentrations, gas_names, & + key_species, band2gpt, band_lims, press_ref, press_ref_trop, temp_ref, temp_ref_p, & + temp_ref_t, vmr_ref, kmajor, kminor_lower, kminor_upper, gas_minor,identifier_minor, & + minor_gases_lower, minor_gases_upper, minor_limits_gpt_lower, minor_limits_gpt_upper, & + minor_scales_with_density_lower, minor_scales_with_density_upper, scaling_gas_lower, & + scaling_gas_upper, scale_by_complement_lower, scale_by_complement_upper, & + kminor_start_lower, kminor_start_upper, totplnk, planck_frac, rayl_lower, rayl_upper)) + + ! Set initial permutation seed for McICA, initially set to number of G-points + ipsdlw0 = lw_gas_props%get_ngpt() + + end subroutine lw_gas_optics_init + + ! ######################################################################################### + ! SUBROUTINE sw_gas_optics_init + ! ######################################################################################### + subroutine sw_gas_optics_init(Model,mpicomm, mpirank, mpiroot, sw_gas_props, & + errmsg, errflg) + use netcdf +#ifdef MPI + use mpi +#endif + + ! Inputs + type(GFS_control_type), intent(in) :: & + Model ! DDT containing model control parameters + integer,intent(in) :: & + mpicomm, & ! MPI communicator + mpirank, & ! Current MPI rank + mpiroot ! Master MPI rank + type(ty_gas_optics_rrtmgp),intent(inout) :: & + sw_gas_props + + ! Outputs + character(len=*), intent(out) :: & + errmsg ! Error message + integer, intent(out) :: & + errflg ! Error code + + ! Fields from the K-distribution files + ! Variables that will be passed to gas_optics%load() + type(ty_gas_concs) :: & + gas_concentrations + integer, dimension(:), allocatable :: & + kminor_start_lower_sw, & ! used by RRTGMP gas optics + kminor_start_upper_sw ! used by RRTGMP gas optics + integer, dimension(:,:), allocatable :: & + band2gpt_sw, & ! used by RRTGMP gas optics + minor_limits_gpt_lower_sw, & ! used by RRTGMP gas optics + minor_limits_gpt_upper_sw ! used by RRTGMP gas optics + integer, dimension(:,:,:), allocatable :: & + key_species_sw ! used by RRTGMP gas optics + real(kind_phys) :: & + press_ref_trop_sw, & ! used by RRTGMP gas optics + temp_ref_p_sw, & ! used by RRTGMP gas optics + temp_ref_t_sw ! used by RRTGMP gas optics + real(kind_phys), dimension(:), allocatable :: & + press_ref_sw, & ! used by RRTGMP gas optics + temp_ref_sw, & ! used by RRTGMP gas optics + solar_source_sw ! used by RRTGMP gas optics + real(kind_phys), dimension(:,:), allocatable :: & + band_lims_sw ! used by RRTGMP gas optics + + real(kind_phys), dimension(:,:,:), allocatable :: & + vmr_ref_sw, & ! used by RRTGMP gas optics + kminor_lower_sw, & ! used by RRTGMP gas optics + kminor_upper_sw, & ! used by RRTGMP gas optics + rayl_lower_sw, & ! used by RRTGMP gas optics + rayl_upper_sw ! used by RRTGMP gas optics + real(kind_phys), dimension(:,:,:,:), allocatable :: & + kmajor_sw ! used by RRTGMP gas optics + character(len=32), dimension(:), allocatable :: & + gas_names_sw, & ! used by RRTGMP gas optics + gas_minor_sw, & ! used by RRTGMP gas optics + identifier_minor_sw, & ! used by RRTGMP gas optics + minor_gases_lower_sw, & ! used by RRTGMP gas optics + minor_gases_upper_sw, & ! used by RRTGMP gas optics + scaling_gas_lower_sw, & ! used by RRTGMP gas optics + scaling_gas_upper_sw ! used by RRTGMP gas optics + logical(wl), dimension(:), allocatable :: & + minor_scales_with_density_lower_sw, & ! used by RRTGMP gas optics + minor_scales_with_density_upper_sw, & ! used by RRTGMP gas optics + scale_by_complement_lower_sw, & ! used by RRTGMP gas optics + scale_by_complement_upper_sw ! used by RRTGMP gas optics + ! Dimensions (to be broadcast across all processors) + integer :: & + ntemps_sw, & ! used by RRTGMP gas optics + npress_sw, & ! used by RRTGMP gas optics + nabsorbers_sw, & ! used by RRTGMP gas optics + nextrabsorbers_sw, & ! used by RRTGMP gas optics + nminorabsorbers_sw, & ! used by RRTGMP gas optics + nmixingfracs_sw, & ! used by RRTGMP gas optics + nlayers_sw, & ! used by RRTGMP gas optics + nbnds_sw, & ! used by RRTGMP gas optics + ngpts_sw, & ! used by RRTGMP gas optics + npairs_sw, & ! used by RRTGMP gas optics + nminor_absorber_intervals_lower_sw, & ! used by RRTGMP gas optics + nminor_absorber_intervals_upper_sw, & ! used by RRTGMP gas optics + ncontributors_lower_sw, & ! used by RRTGMP gas optics + ncontributors_upper_sw ! used by RRTGMP gas optics + + ! Local variables + integer :: status,ncid_sw,ncid_sw_clds,dimid,varID,ij,iGas + integer,dimension(:),allocatable :: temp1,temp2,temp3,temp4,temp_log_array1,& + temp_log_array2, temp_log_array3, temp_log_array4 + character(len=264) :: sw_gas_props_file + + ! Initialize + errmsg = '' + errflg = 0 + + ! Filenames are set in the gfs_physics_nml (scm/src/GFS_typedefs.F90) + sw_gas_props_file = trim(Model%rrtmgp_root)//trim(Model%sw_file_gas) + + ! Read dimensions for k-distribution fields (only on master processor(0)) + if (mpirank .eq. mpiroot) then + if(nf90_open(trim(sw_gas_props_file), NF90_WRITE, ncid_sw) .eq. NF90_NOERR) then + status = nf90_inq_dimid(ncid_sw, 'temperature', dimid) + status = nf90_inquire_dimension(ncid_sw, dimid, len=ntemps_sw) + status = nf90_inq_dimid(ncid_sw, 'pressure', dimid) + status = nf90_inquire_dimension(ncid_sw, dimid, len=npress_sw) + status = nf90_inq_dimid(ncid_sw, 'absorber', dimid) + status = nf90_inquire_dimension(ncid_sw, dimid, len=nabsorbers_sw) + status = nf90_inq_dimid(ncid_sw, 'minor_absorber', dimid) + status = nf90_inquire_dimension(ncid_sw, dimid, len=nminorabsorbers_sw) + status = nf90_inq_dimid(ncid_sw, 'absorber_ext', dimid) + status = nf90_inquire_dimension(ncid_sw, dimid, len=nextrabsorbers_sw) + status = nf90_inq_dimid(ncid_sw, 'mixing_fraction', dimid) + status = nf90_inquire_dimension(ncid_sw, dimid, len=nmixingfracs_sw) + status = nf90_inq_dimid(ncid_sw, 'atmos_layer', dimid) + status = nf90_inquire_dimension(ncid_sw, dimid, len=nlayers_sw) + status = nf90_inq_dimid(ncid_sw, 'bnd', dimid) + status = nf90_inquire_dimension(ncid_sw, dimid, len=nbnds_sw) + status = nf90_inq_dimid(ncid_sw, 'gpt', dimid) + status = nf90_inquire_dimension(ncid_sw, dimid, len=ngpts_sw) + status = nf90_inq_dimid(ncid_sw, 'pair', dimid) + status = nf90_inquire_dimension(ncid_sw, dimid, len=npairs_sw) + status = nf90_inq_dimid(ncid_sw, 'contributors_lower', dimid) + status = nf90_inquire_dimension(ncid_sw, dimid, len=ncontributors_lower_sw) + status = nf90_inq_dimid(ncid_sw, 'contributors_upper', dimid) + status = nf90_inquire_dimension(ncid_sw, dimid, len=ncontributors_upper_sw) + status = nf90_inq_dimid(ncid_sw, 'minor_absorber_intervals_lower', dimid) + status = nf90_inquire_dimension(ncid_sw, dimid, len=nminor_absorber_intervals_lower_sw) + status = nf90_inq_dimid(ncid_sw, 'minor_absorber_intervals_upper', dimid) + status = nf90_inquire_dimension(ncid_sw, dimid, len=nminor_absorber_intervals_upper_sw) + status = nf90_close(ncid_sw) + endif + endif + + ! Broadcast dimensions to all processors +#ifdef MPI + call MPI_BCAST(ntemps_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(npress_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(nabsorbers_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(nminorabsorbers_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(nextraabsorbers_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(nmixingfracs_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(nlayers_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(nbnds_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(ngpts_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(npairs_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(ncontributors_lower_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(ncontributors_upper_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(nminor_absorber_intervals_lower_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(nminor_absorber_intervals_upper_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) +#endif + + ! Allocate space for arrays + allocate(gas_names_sw(nabsorbers_sw)) + allocate(scaling_gas_lower_sw(nminor_absorber_intervals_lower_sw)) + allocate(scaling_gas_upper_sw(nminor_absorber_intervals_upper_sw)) + allocate(gas_minor_sw(nminorabsorbers_sw)) + allocate(identifier_minor_sw(nminorabsorbers_sw)) + allocate(minor_gases_lower_sw(nminor_absorber_intervals_lower_sw)) + allocate(minor_gases_upper_sw(nminor_absorber_intervals_upper_sw)) + allocate(minor_limits_gpt_lower_sw(npairs_sw,nminor_absorber_intervals_lower_sw)) + allocate(minor_limits_gpt_upper_sw(npairs_sw,nminor_absorber_intervals_upper_sw)) + allocate(band2gpt_sw(2,nbnds_sw)) + allocate(key_species_sw(2,nlayers_sw,nbnds_sw)) + allocate(band_lims_sw(2,nbnds_sw)) + allocate(press_ref_sw(npress_sw)) + allocate(temp_ref_sw(ntemps_sw)) + allocate(vmr_ref_sw(nlayers_sw, nextrabsorbers_sw, ntemps_sw)) + allocate(kminor_lower_sw(ncontributors_lower_sw, nmixingfracs_sw, ntemps_sw)) + allocate(kmajor_sw(ngpts_sw, nmixingfracs_sw, npress_sw+1, ntemps_sw)) + allocate(kminor_start_lower_sw(nminor_absorber_intervals_lower_sw)) + allocate(kminor_upper_sw(ncontributors_upper_sw, nmixingfracs_sw, ntemps_sw)) + allocate(kminor_start_upper_sw(nminor_absorber_intervals_upper_sw)) + allocate(minor_scales_with_density_lower_sw(nminor_absorber_intervals_lower_sw)) + allocate(minor_scales_with_density_upper_sw(nminor_absorber_intervals_upper_sw)) + allocate(scale_by_complement_lower_sw(nminor_absorber_intervals_lower_sw)) + allocate(scale_by_complement_upper_sw(nminor_absorber_intervals_upper_sw)) + allocate(rayl_upper_sw(ngpts_sw, nmixingfracs_sw, ntemps_sw)) + allocate(rayl_lower_sw(ngpts_sw, nmixingfracs_sw, ntemps_sw)) + allocate(solar_source_sw(ngpts_sw)) + allocate(temp1(nminor_absorber_intervals_lower_sw)) + allocate(temp2(nminor_absorber_intervals_upper_sw)) + allocate(temp3(nminor_absorber_intervals_lower_sw)) + allocate(temp4(nminor_absorber_intervals_upper_sw)) + + ! On master processor, read in fields, broadcast to all processors + if (mpirank .eq. mpiroot) then + ! Read in fields from file + if(nf90_open(trim(sw_gas_props_file), NF90_WRITE, ncid_sw) .eq. NF90_NOERR) then + status = nf90_inq_varid(ncid_sw,'gas_names',varID) + status = nf90_get_var(ncid_sw,varID,gas_names_sw) + ! + status = nf90_inq_varid(ncid_sw,'scaling_gas_lower',varID) + status = nf90_get_var(ncid_sw,varID,scaling_gas_lower_sw) + ! + status = nf90_inq_varid(ncid_sw,'scaling_gas_upper',varID) + status = nf90_get_var(ncid_sw,varID,scaling_gas_upper_sw) + ! + status = nf90_inq_varid(ncid_sw,'gas_minor',varID) + status = nf90_get_var(ncid_sw,varID,gas_minor_sw) + ! + status = nf90_inq_varid(ncid_sw,'identifier_minor',varID) + status = nf90_get_var(ncid_sw,varID,identifier_minor_sw) + ! + status = nf90_inq_varid(ncid_sw,'minor_gases_lower',varID) + status = nf90_get_var(ncid_sw,varID,minor_gases_lower_sw) + ! + status = nf90_inq_varid(ncid_sw,'minor_gases_upper',varID) + status = nf90_get_var(ncid_sw,varID,minor_gases_upper_sw) + ! + status = nf90_inq_varid(ncid_sw,'minor_limits_gpt_lower',varID) + status = nf90_get_var(ncid_sw,varID,minor_limits_gpt_lower_sw) + ! + status = nf90_inq_varid(ncid_sw,'minor_limits_gpt_upper',varID) + status = nf90_get_var(ncid_sw,varID,minor_limits_gpt_upper_sw) + ! + status = nf90_inq_varid(ncid_sw,'bnd_limits_gpt',varID) + status = nf90_get_var(ncid_sw,varID,band2gpt_sw) + ! + status = nf90_inq_varid(ncid_sw,'key_species',varID) + status = nf90_get_var(ncid_sw,varID,key_species_sw) + ! + status = nf90_inq_varid(ncid_sw,'bnd_limits_wavenumber',varID) + status = nf90_get_var(ncid_sw,varID,band_lims_sw) + ! + status = nf90_inq_varid(ncid_sw,'press_ref',varID) + status = nf90_get_var(ncid_sw,varID,press_ref_sw) + ! + status = nf90_inq_varid(ncid_sw,'temp_ref',varID) + status = nf90_get_var(ncid_sw,varID,temp_ref_sw) + ! + status = nf90_inq_varid(ncid_sw,'absorption_coefficient_ref_P',varID) + status = nf90_get_var(ncid_sw,varID,temp_ref_p_sw) + ! + status = nf90_inq_varid(ncid_sw,'absorption_coefficient_ref_T',varID) + status = nf90_get_var(ncid_sw,varID,temp_ref_t_sw) + ! + status = nf90_inq_varid(ncid_sw,'press_ref_trop',varID) + status = nf90_get_var(ncid_sw,varID,press_ref_trop_sw) + ! + status = nf90_inq_varid(ncid_sw,'kminor_lower',varID) + status = nf90_get_var(ncid_sw,varID,kminor_lower_sw) + ! + status = nf90_inq_varid(ncid_sw,'kminor_upper',varID) + status = nf90_get_var(ncid_sw,varID,kminor_upper_sw) + ! + status = nf90_inq_varid(ncid_sw,'vmr_ref',varID) + status = nf90_get_var(ncid_sw,varID,vmr_ref_sw) + ! + status = nf90_inq_varid(ncid_sw,'kmajor',varID) + status = nf90_get_var(ncid_sw,varID,kmajor_sw) + ! + status = nf90_inq_varid(ncid_sw,'kminor_start_lower',varID) + status = nf90_get_var(ncid_sw,varID,kminor_start_lower_sw) + ! + status = nf90_inq_varid(ncid_sw,'kminor_start_upper',varID) + status = nf90_get_var(ncid_sw,varID,kminor_start_upper_sw) + ! + status = nf90_inq_varid(ncid_sw,'solar_source',varID) + status = nf90_get_var(ncid_sw,varID,solar_source_sw) + ! + status = nf90_inq_varid(ncid_sw,'rayl_lower',varID) + status = nf90_get_var(ncid_sw,varID,rayl_lower_sw) + + status = nf90_inq_varid(ncid_sw,'rayl_upper',varID) + status = nf90_get_var(ncid_sw,varID,rayl_upper_sw) + + ! Logical fields are read in as integers and then converted to logicals. + status = nf90_inq_varid(ncid_sw,'minor_scales_with_density_lower',varID) + status = nf90_get_var(ncid_sw,varID,temp1) + minor_scales_with_density_lower_sw(:) = .false. + where(temp1 .eq. 1) minor_scales_with_density_lower_sw(:) = .true. + ! + status = nf90_inq_varid(ncid_sw,'minor_scales_with_density_upper',varID) + status = nf90_get_var(ncid_sw,varID,temp2) + minor_scales_with_density_upper_sw(:) = .false. + where(temp2 .eq. 1) minor_scales_with_density_upper_sw(:) = .true. + ! + status = nf90_inq_varid(ncid_sw,'scale_by_complement_lower',varID) + status = nf90_get_var(ncid_sw,varID,temp3) + scale_by_complement_lower_sw(:) = .false. + where(temp3 .eq. 1) scale_by_complement_lower_sw(:) = .true. + ! + status = nf90_inq_varid(ncid_sw,'scale_by_complement_upper',varID) + status = nf90_get_var(ncid_sw,varID,temp4) + scale_by_complement_upper_sw(:) = .false. + where(temp4 .eq. 1) scale_by_complement_upper_sw(:) = .true. + + ! Close + status = nf90_close(ncid_sw) + endif + endif + + ! Broadcast arrays to all processors +#ifdef MPI + call MPI_BCAST(minor_limits_gpt_upper_sw, size(minor_limits_gpt_upper_sw), MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(minor_limits_gpt_lower_sw, size(minor_limits_gpt_lower_sw), MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(kminor_start_upper_sw, size(kminor_start_upper_sw), MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(kminor_start_lower_sw, size(kminor_start_lower_sw), MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(key_species_sw, size(key_species_sw), MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(band2gpt_sw, size(band2gpt_sw), MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(band_lims_sw, size(band_lims_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(press_ref_sw, size(press_ref_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(temp_ref_sw, size(temp_ref_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(kminor_lower_sw, size(kminor_lower_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(kminor_upper_sw, size(kminor_upper_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(scaling_gas_lower_sw, size(scaling_gas_lower_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(scaling_gas_upper_sw, size(scaling_gas_upper_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(vmr_ref_sw, size(vmr_ref_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(kmajor_sw, size(kmajor_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(temp_ref_p_sw, 1, kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(temp_ref_t_sw, 1, kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(press_ref_trop_sw, 1, kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(solar_source_sw, size(solar_source_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(rayl_lower_sw, size(rayl_lower_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(rayl_upper_sw, size(rayl_upper_sw), kind_phys, mpiroot, mpicomm, ierr) + ! Character arrays + do ij=1,nabsorbers_sw + call MPI_BCAST(gas_names_sw(ij), 32, MPI_CHAR, mpiroot, mpicomm, ierr) + enddo + do ij=1,nminorabsorbers_sw + call MPI_BCAST(gas_minor_sw(ij), 32, MPI_CHAR, mpiroot, mpicomm, ierr) + call MPI_BCAST(identifier_minor_sw(ij), 32, MPI_CHAR, mpiroot, mpicomm, ierr) + enddo + do ij=1,nminor_absorber_intervals_lower_sw + call MPI_BCAST(minor_gases_lower_sw(ij), 32, MPI_CHAR, mpiroot, mpicomm, ierr) + enddo + do ij=1,nminor_absorber_intervals_upper_sw + call MPI_BCAST(minor_gases_upper_sw(ij), 32, MPI_CHAR, mpiroot, mpicomm, ierr) + enddo + ! Logical arrays (First convert to integer-array, then broadcast) + ! + allocate(temp_log_array1(nminor_absorber_intervals_lower_sw)) + where(minor_scales_with_density_lower_sw) + temp_log_array1 = 1 + elsewhere + temp_log_array1 = 0 + end where + call MPI_BCAST(temp_log_array1, size(temp_log_array1), MPI_INTEGER, mpiroot, mpicomm, ierr) + ! + allocate(temp_log_array2(nminor_absorber_intervals_lower_sw)) + where(scale_by_complement_lower_sw) + temp_log_array2 = 1 + elsewhere + temp_log_array2 = 0 + end where + call MPI_BCAST(temp_log_array2, size(temp_log_array2), MPI_INTEGER, mpiroot, mpicomm, ierr) + ! + allocate(temp_log_array3(nminor_absorber_intervals_upper_sw)) + where(minor_scales_with_density_upper_sw) + temp_log_array3 = 1 + elsewhere + temp_log_array3 = 0 + end where + call MPI_BCAST(temp_log_array3, size(temp_log_array3), MPI_INTEGER, mpiroot, mpicomm, ierr) + ! + allocate(temp_log_array4(nminor_absorber_intervals_upper_sw)) + where(scale_by_complement_upper_sw) + temp_log_array4 = 1 + elsewhere + temp_log_array4 = 0 + end where + call MPI_BCAST(temp_log_array4, size(temp_log_array4), MPI_INTEGER, mpiroot, mpicomm, ierr) +#endif + + ! Initialize gas concentrations and gas optics class with data + do iGas=1,nGases + call check_error_msg('sw_gas_optics_init',gas_concentrations%set_vmr(active_gases(iGas), 0._kind_phys)) + enddo + call check_error_msg('sw_gas_optics_init',sw_gas_props%load(gas_concentrations, gas_names_sw, & + key_species_sw, band2gpt_sw, band_lims_sw, press_ref_sw, press_ref_trop_sw, temp_ref_sw, & + temp_ref_p_sw, temp_ref_t_sw, vmr_ref_sw, kmajor_sw, kminor_lower_sw, kminor_upper_sw, & + gas_minor_sw,identifier_minor_sw, minor_gases_lower_sw, minor_gases_upper_sw, & + minor_limits_gpt_lower_sw,minor_limits_gpt_upper_sw, minor_scales_with_density_lower_sw, & + minor_scales_with_density_upper_sw, scaling_gas_lower_sw, & + scaling_gas_upper_sw, scale_by_complement_lower_sw, & + scale_by_complement_upper_sw, kminor_start_lower_sw, kminor_start_upper_sw, & + solar_source_sw, rayl_lower_sw, rayl_upper_sw)) + + ! Set initial permutation seed for McICA, initially set to number of G-points + ipsdsw0 = sw_gas_props%get_ngpt() + + end subroutine sw_gas_optics_init + + ! ######################################################################################### + ! SUBROUTINE sw_cloud_optics_init + ! ######################################################################################### + subroutine sw_cloud_optics_init(Model,mpicomm, mpirank, mpiroot, sw_cloud_props, & + errmsg, errflg) + use netcdf +#ifdef MPI + use mpi +#endif + + ! Inputs + type(GFS_control_type), intent(in) :: & + Model ! DDT containing model control parameters + integer,intent(in) :: & + mpicomm, & ! MPI communicator + mpirank, & ! Current MPI rank + mpiroot ! Master MPI rank + type(ty_cloud_optics),intent(inout) :: & + sw_cloud_props + + ! Outputs + character(len=*), intent(out) :: & + errmsg ! Error message + integer, intent(out) :: & + errflg ! Error code + + ! Variables that will be passed to gas_optics%load() + real(kind_phys) :: & + radliq_lwr_sw, & ! used by RRTGMP cloud optics + radliq_upr_sw, & ! used by RRTGMP cloud optics + radliq_fac_sw, & ! used by RRTGMP cloud optics + radice_lwr_sw, & ! used by RRTGMP cloud optics + radice_upr_sw, & ! used by RRTGMP cloud optics + radice_fac_sw ! used by RRTGMP cloud optics + + real(kind_phys), dimension(:), allocatable :: & + pade_sizereg_extliq_sw, & ! used by RRTGMP cloud optics + pade_sizereg_ssaliq_sw, & ! used by RRTGMP cloud optics + pade_sizereg_asyliq_sw, & ! used by RRTGMP cloud optics + pade_sizereg_extice_sw, & ! used by RRTGMP cloud optics + pade_sizereg_ssaice_sw, & ! used by RRTGMP cloud optics + pade_sizereg_asyice_sw ! used by RRTGMP cloud optics + real(kind_phys), dimension(:,:), allocatable :: & + lut_extliq_sw, & ! used by RRTGMP cloud optics + lut_ssaliq_sw, & ! used by RRTGMP cloud optics + lut_asyliq_sw, & ! used by RRTGMP cloud optics + band_lims_cldy_sw ! used by RRTGMP cloud optics + + real(kind_phys), dimension(:,:,:), allocatable :: & + lut_extice_sw, & ! used by RRTGMP cloud optics + lut_ssaice_sw, & ! used by RRTGMP cloud optics + lut_asyice_sw, & ! used by RRTGMP cloud optics + pade_extliq_sw, & ! used by RRTGMP cloud optics + pade_ssaliq_sw, & ! used by RRTGMP cloud optics + pade_asyliq_sw ! used by RRTGMP cloud optics + real(kind_phys), dimension(:,:,:,:), allocatable :: & + pade_extice_sw, & ! used by RRTGMP cloud optics + pade_ssaice_sw, & ! used by RRTGMP cloud optics + pade_asyice_sw ! used by RRTGMP cloud optics + ! Dimensions (to be broadcast across all processors) + integer :: & + nbandSWcldy_sw, & ! used by RRTGMP cloud optics + nsize_liq_sw, & ! used by RRTGMP cloud optics + nsize_ice_sw, & ! used by RRTGMP cloud optics + nsizereg_sw, & ! used by RRTGMP cloud optics + ncoeff_ext_sw, & ! used by RRTGMP cloud optics + ncoeff_ssa_g_sw, & ! used by RRTGMP cloud optics + nbound_sw, & ! used by RRTGMP cloud optics + npairsSWcldy_sw ! used by RRTGMP cloud optics + + ! Local variables + integer :: status,ncid_sw,ncid_sw_clds,dimid,varID,ij,iGas + integer,dimension(:),allocatable :: temp1,temp2,temp3,temp4,temp_log_array1,& + temp_log_array2, temp_log_array3, temp_log_array4 + character(len=264) :: sw_cloud_props_file + + ! Initialize + errmsg = '' + errflg = 0 + + ! Filenames are set in the gfs_physics_nml (scm/src/GFS_typedefs.F90) + sw_cloud_props_file = trim(Model%rrtmgp_root)//trim(Model%sw_file_clouds) + + ! Read dimensions for k-distribution fields (only on master processor(0)) + if (mpirank .eq. mpiroot) then + if(nf90_open(trim(sw_cloud_props_file), NF90_WRITE, ncid_sw_clds) == NF90_NOERR) then + status = nf90_inq_dimid(ncid_sw_clds, 'nband', dimid) + status = nf90_inquire_dimension(ncid_sw_clds, dimid, len=nbandSWcldy_sw) + status = nf90_inq_dimid(ncid_sw_clds, 'nrghice', dimid) + status = nf90_inquire_dimension(ncid_sw_clds, dimid, len=nrghice_sw) + status = nf90_inq_dimid(ncid_sw_clds, 'nsize_liq', dimid) + status = nf90_inquire_dimension(ncid_sw_clds, dimid, len=nsize_liq_sw) + status = nf90_inq_dimid(ncid_sw_clds, 'nsize_ice', dimid) + status = nf90_inquire_dimension(ncid_sw_clds, dimid, len=nsize_ice_sw) + status = nf90_inq_dimid(ncid_sw_clds, 'nsizereg', dimid) + status = nf90_inquire_dimension(ncid_sw_clds, dimid, len=nsizereg_sw) + status = nf90_inq_dimid(ncid_sw_clds, 'ncoeff_ext', dimid) + status = nf90_inquire_dimension(ncid_sw_clds, dimid, len=ncoeff_ext_sw) + status = nf90_inq_dimid(ncid_sw_clds, 'ncoeff_ssa_g', dimid) + status = nf90_inquire_dimension(ncid_sw_clds, dimid, len=ncoeff_ssa_g_sw) + status = nf90_inq_dimid(ncid_sw_clds, 'nbound', dimid) + status = nf90_inquire_dimension(ncid_sw_clds, dimid, len=nbound_sw) + status = nf90_inq_dimid(ncid_sw_clds, 'pair', dimid) + status = nf90_inquire_dimension(ncid_sw_clds, dimid, len=npairsSWcldy_sw) + status = nf90_close(ncid_sw_clds) + endif + endif + + ! Broadcast dimensions to all processors +#ifdef MPI + if (Model%rrtmgp_cld_optics .eq. 1 .or. Model%rrtmgp_cld_optics .eq. 2) then + call MPI_BCAST(nbandSWcldy_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(nrghice_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(nsize_liq_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(nsize_ice_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(nsizereg_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(ncoeff_ext_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(ncoeff_ssa_g_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(nbound_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + call MPI_BCAST(npairsSWcldy_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) + endif +#endif + + if (Model%rrtmgp_cld_optics .eq. 1) then + allocate(lut_extliq_sw(nsize_liq_sw, nBandSWcldy_sw)) + allocate(lut_ssaliq_sw(nsize_liq_sw, nBandSWcldy_sw)) + allocate(lut_asyliq_sw(nsize_liq_sw, nBandSWcldy_sw)) + allocate(lut_extice_sw(nsize_ice_sw, nBandSWcldy_sw, nrghice_sw)) + allocate(lut_ssaice_sw(nsize_ice_sw, nBandSWcldy_sw, nrghice_sw)) + allocate(lut_asyice_sw(nsize_ice_sw, nBandSWcldy_sw, nrghice_sw)) + allocate(band_lims_cldy_sw(2, nBandSWcldy_sw)) + endif + if (Model%rrtmgp_cld_optics .eq. 2) then + allocate(pade_extliq_sw(nbandSWcldy_sw, nsizereg_sw, ncoeff_ext_sw )) + allocate(pade_ssaliq_sw(nbandSWcldy_sw, nsizereg_sw, ncoeff_ssa_g_sw)) + allocate(pade_asyliq_sw(nbandSWcldy_sw, nsizereg_sw, ncoeff_ssa_g_sw)) + allocate(pade_extice_sw(nbandSWcldy_sw, nsizereg_sw, ncoeff_ext_sw, nrghice_sw)) + allocate(pade_ssaice_sw(nbandSWcldy_sw, nsizereg_sw, ncoeff_ssa_g_sw, nrghice_sw)) + allocate(pade_asyice_sw(nbandSWcldy_sw, nsizereg_sw, ncoeff_ssa_g_sw, nrghice_sw)) + allocate(pade_sizereg_extliq_sw(nbound_sw)) + allocate(pade_sizereg_ssaliq_sw(nbound_sw)) + allocate(pade_sizereg_asyliq_sw(nbound_sw)) + allocate(pade_sizereg_extice_sw(nbound_sw)) + allocate(pade_sizereg_ssaice_sw(nbound_sw)) + allocate(pade_sizereg_asyice_sw(nbound_sw)) + allocate(band_lims_cldy_sw(2,nbandSWcldy_sw)) + endif + + ! On master processor, allocate space, read in fields, broadcast to all processors + if (mpirank .eq. mpiroot) then + ! + if (Model%rrtmgp_cld_optics .eq. 1) then + ! + if(nf90_open(trim(sw_cloud_props_file), NF90_WRITE, ncid_sw_clds) == NF90_NOERR) then + status = nf90_inq_varid(ncid_sw_clds,'radliq_lwr',varID) + status = nf90_get_var(ncid_sw_clds,varID,radliq_lwr_sw) + status = nf90_inq_varid(ncid_sw_clds,'radliq_upr',varID) + status = nf90_get_var(ncid_sw_clds,varID,radliq_upr_sw) + status = nf90_inq_varid(ncid_sw_clds,'radliq_fac',varID) + status = nf90_get_var(ncid_sw_clds,varID,radliq_fac_sw) + status = nf90_inq_varid(ncid_sw_clds,'radice_lwr',varID) + status = nf90_get_var(ncid_sw_clds,varID,radice_lwr_sw) + status = nf90_inq_varid(ncid_sw_clds,'radice_upr',varID) + status = nf90_get_var(ncid_sw_clds,varID,radice_upr_sw) + status = nf90_inq_varid(ncid_sw_clds,'radice_fac',varID) + status = nf90_get_var(ncid_sw_clds,varID,radice_fac_sw) + status = nf90_inq_varid(ncid_sw_clds,'lut_extliq',varID) + status = nf90_get_var(ncid_sw_clds,varID,lut_extliq_sw) + status = nf90_inq_varid(ncid_sw_clds,'lut_ssaliq',varID) + status = nf90_get_var(ncid_sw_clds,varID,lut_ssaliq_sw) + status = nf90_inq_varid(ncid_sw_clds,'lut_asyliq',varID) + status = nf90_get_var(ncid_sw_clds,varID,lut_asyliq_sw) + status = nf90_inq_varid(ncid_sw_clds,'lut_extice',varID) + status = nf90_get_var(ncid_sw_clds,varID,lut_extice_sw) + status = nf90_inq_varid(ncid_sw_clds,'lut_ssaice',varID) + status = nf90_get_var(ncid_sw_clds,varID,lut_ssaice_sw) + status = nf90_inq_varid(ncid_sw_clds,'lut_asyice',varID) + status = nf90_get_var(ncid_sw_clds,varID,lut_asyice_sw) + status = nf90_inq_varid(ncid_sw_clds,'bnd_limits_wavenumber',varID) + status = nf90_get_var(ncid_sw_clds,varID,band_lims_cldy_sw) + status = nf90_close(ncid_sw_clds) + endif + endif + ! + if (Model%rrtmgp_cld_optics .eq. 2) then + ! + if(nf90_open(trim(sw_cloud_props_file), NF90_WRITE, ncid_sw_clds) == NF90_NOERR) then + status = nf90_inq_varid(ncid_sw_clds,'radliq_lwr',varID) + status = nf90_get_var(ncid_sw_clds,varID,radliq_lwr_sw) + status = nf90_inq_varid(ncid_sw_clds,'radliq_upr',varID) + status = nf90_get_var(ncid_sw_clds,varID,radliq_upr_sw) + status = nf90_inq_varid(ncid_sw_clds,'radliq_fac',varID) + status = nf90_get_var(ncid_sw_clds,varID,radliq_fac_sw) + status = nf90_inq_varid(ncid_sw_clds,'radice_lwr',varID) + status = nf90_get_var(ncid_sw_clds,varID,radice_lwr_sw) + status = nf90_inq_varid(ncid_sw_clds,'radice_upr',varID) + status = nf90_get_var(ncid_sw_clds,varID,radice_upr_sw) + status = nf90_inq_varid(ncid_sw_clds,'radice_fac',varID) + status = nf90_get_var(ncid_sw_clds,varID,radice_fac_sw) + status = nf90_inq_varid(ncid_sw_clds,'pade_extliq',varID) + status = nf90_get_var(ncid_sw_clds,varID,pade_extliq_sw) + status = nf90_inq_varid(ncid_sw_clds,'pade_ssaliq',varID) + status = nf90_get_var(ncid_sw_clds,varID,pade_ssaliq_sw) + status = nf90_inq_varid(ncid_sw_clds,'pade_asyliq',varID) + status = nf90_get_var(ncid_sw_clds,varID,pade_asyliq_sw) + status = nf90_inq_varid(ncid_sw_clds,'pade_extice',varID) + status = nf90_get_var(ncid_sw_clds,varID,pade_extice_sw) + status = nf90_inq_varid(ncid_sw_clds,'pade_ssaice',varID) + status = nf90_get_var(ncid_sw_clds,varID,pade_ssaice_sw) + status = nf90_inq_varid(ncid_sw_clds,'pade_asyice',varID) + status = nf90_get_var(ncid_sw_clds,varID,pade_asyice_sw) + status = nf90_inq_varid(ncid_sw_clds,'pade_sizreg_extliq',varID) + status = nf90_get_var(ncid_sw_clds,varID,pade_sizereg_extliq_sw) + status = nf90_inq_varid(ncid_sw_clds,'pade_sizreg_ssaliq',varID) + status = nf90_get_var(ncid_sw_clds,varID,pade_sizereg_ssaliq_sw) + status = nf90_inq_varid(ncid_sw_clds,'pade_sizreg_asyliq',varID) + status = nf90_get_var(ncid_sw_clds,varID,pade_sizereg_asyliq_sw) + status = nf90_inq_varid(ncid_sw_clds,'pade_sizreg_extice',varID) + status = nf90_get_var(ncid_sw_clds,varID,pade_sizereg_extice_sw) + status = nf90_inq_varid(ncid_sw_clds,'pade_sizreg_ssaice',varID) + status = nf90_get_var(ncid_sw_clds,varID,pade_sizereg_ssaice_sw) + status = nf90_inq_varid(ncid_sw_clds,'pade_sizreg_asyice',varID) + status = nf90_get_var(ncid_sw_clds,varID,pade_sizereg_asyice_sw) + status = nf90_inq_varid(ncid_sw_clds,'bnd_limits_wavenumber',varID) + status = nf90_get_var(ncid_sw_clds,varID,band_lims_cldy_sw) + status = nf90_close(ncid_sw_clds) + endif + endif + endif + + ! Broadcast arrays to all processors +#ifdef MPI + if (Model%rrtmgp_cld_optics .eq. 1) then + call MPI_BCAST(radliq_lwr_sw, size(radliq_lwr_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(radliq_upr_sw, size(radliq_upr_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(radliq_fac_sw, size(radliq_fac_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(radice_lwr_sw, size(radice_lwr_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(radice_upr_sw, size(radice_upr_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(radice_fac_sw, size(radice_fac_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(lut_extliq_sw, size(lut_extliq_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(lut_ssaliq_sw, size(lut_ssaliq_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(lut_asyliq_sw, size(lut_asyliq_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(lut_extice_sw, size(lut_extice_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(lut_ssaice_sw, size(lut_ssaice_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(lut_asyice_sw, size(lut_asyice_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(band_lims_cldy_sw), size(band_lims_cldy_sw), kind_phys, mpiroot, mpicomm, ierr) + endif + if (Model%rrtmgp_cld_optics .eq. 2) then + call MPI_BCAST(pade_extliq_sw, size(pade_extliq_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(pade_ssaliq_sw, size(pade_ssaliq_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(pade_asyliq_sw, size(pade_asyliq_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(pade_extice_sw, size(pade_extice_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(pade_ssaice_sw, size(pade_ssaice_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(pade_asyice_sw, size(pade_asyice_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(pade_sizereg_extliq_sw), size(pade_sizereg_extliq_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(pade_sizereg_ssaliq_sw), size(pade_sizereg_ssaliq_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(pade_sizereg_asyliq_sw), size(pade_sizereg_asyliq_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(pade_sizereg_extice_sw), size(pade_sizereg_extice_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(pade_sizereg_ssaice_sw), size(pade_sizereg_ssaice_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(pade_sizereg_asyice_sw), size(pade_sizereg_asyice_sw), kind_phys, mpiroot, mpicomm, ierr) + call MPI_BCAST(band_lims_cldy_sw), size(band_lims_cldy_sw), kind_phys, mpiroot, mpicomm, ierr) + endif +#endif + + ! Load tables data for RRTGMP cloud-optics + if (Model%rrtmgp_cld_optics .eq. 1) then + call check_error_msg('sw_cloud_optics_init',sw_cloud_props%set_ice_roughness(nrghice_sw)) + call check_error_msg('sw_cloud_optics_init',sw_cloud_props%load(band_lims_cldy_sw, & + radliq_lwr_sw, radliq_upr_sw, radliq_fac_sw, radice_lwr_sw, radice_upr_sw, & + radice_fac_sw, lut_extliq_sw, lut_ssaliq_sw, lut_asyliq_sw, lut_extice_sw, & + lut_ssaice_sw, lut_asyice_sw)) + endif + if (Model%rrtmgp_cld_optics .eq. 2) then + call check_error_msg('sw_cloud_optics_init',sw_cloud_props%set_ice_roughness(nrghice_sw)) + call check_error_msg('sw_cloud_optics_init', sw_cloud_props%load(band_lims_cldy_sw, & + pade_extliq_sw, pade_ssaliq_sw, pade_asyliq_sw, pade_extice_sw, pade_ssaice_sw, & + pade_asyice_sw, pade_sizereg_extliq_sw, pade_sizereg_ssaliq_sw, & + pade_sizereg_asyliq_sw, pade_sizereg_extice_sw, pade_sizereg_ssaice_sw, & + pade_sizereg_asyice_sw)) + endif + + end subroutine sw_cloud_optics_init + + ! ######################################################################################### + ! SUBROUTINE check_error_msg + ! ######################################################################################### + subroutine check_error_msg(routine_name, error_msg) + character(len=*), intent(in) :: & + error_msg, routine_name + + if(error_msg /= "") then + print*,"ERROR("//trim(routine_name)//"): " + print*,trim(error_msg) + return + end if + end subroutine check_error_msg +end module rrtmgp_aux diff --git a/physics/rrtmgp_lw.F90 b/physics/rrtmgp_lw.F90 index c70f8bec1..e94ad41a8 100644 --- a/physics/rrtmgp_lw.F90 +++ b/physics/rrtmgp_lw.F90 @@ -10,37 +10,26 @@ module rrtmgp_lw use mo_rrtmgp_clr_all_sky, only: rte_lw use mo_gas_concentrations, only: ty_gas_concs use mo_fluxes_byband, only: ty_fluxes_byband - - ! Parameters - integer,parameter :: nGases = 6 - real(kind_phys),parameter :: epsilon=1.0e-6 - character(len=3),parameter, dimension(nGases) :: & - active_gases = (/ 'h2o', 'co2', 'o3 ', 'n2o', 'ch4', 'o2 '/) - integer :: nrghice, ipsdlw0 + use rrtmgp_aux, only: lw_gas_optics_init, lw_cloud_optics_init, check_error_msg public rrtmgp_lw_init, rrtmgp_lw_run, rrtmgp_lw_finalize contains !! \section arg_table_rrtmgp_lw_init Argument Table -!! | local_name | standard_name | long_name | units | rank | type | kind | intent | optional | -!! |--------------------|-------------------------------------------------|---------------------------------------------------------------------------|-------|------|----------------------|-----------|--------|----------| -!! | Model | GFS_control_type_instance | Fortran DDT containing FV3-GFS model control parameters | DDT | 0 | GFS_control_type | | in | F | -!! | mpirank | mpi_rank | current MPI rank | index | 0 | integer | | in | F | -!! | mpiroot | mpi_root | master MPI rank | index | 0 | integer | | in | F | -!! | mpicomm | mpi_comm | MPI communicator | index | 0 | integer | | in | F | -!! | errmsg | ccpp_error_message | error message for error handling in CCPP | none | 0 | character | len=* | out | F | -!! | errflg | ccpp_error_flag | error flag for error handling in CCPP | flag | 0 | integer | | out | F | -!! | kdist_lw | K_distribution_file_for_RRTMGP_LW_scheme | DDT containing spectral information for RRTMGP LW radiation scheme | DDT | 0 | ty_gas_optics_rrtmgp | | inout | F | -!! | kdist_cldy_lw | K_distribution_file_for_cloudy_RRTMGP_LW_scheme | DDT containing spectral information for cloudy RRTMGP LW radiation scheme | DDT | 0 | ty_cloud_optics | | inout | F | +!! | local_name | standard_name | long_name | units | rank | type | kind | intent | optional | +!! |----------------|----------------------------------|---------------------------------------------------------------------------|-------|------|----------------------|-----------|--------|----------| +!! | Model | GFS_control_type_instance | Fortran DDT containing FV3-GFS model control parameters | DDT | 0 | GFS_control_type | | in | F | +!! | mpirank | mpi_rank | current MPI rank | index | 0 | integer | | in | F | +!! | mpiroot | mpi_root | master MPI rank | index | 0 | integer | | in | F | +!! | mpicomm | mpi_comm | MPI communicator | index | 0 | integer | | in | F | +!! | errmsg | ccpp_error_message | error message for error handling in CCPP | none | 0 | character | len=* | out | F | +!! | errflg | ccpp_error_flag | error flag for error handling in CCPP | flag | 0 | integer | | out | F | +!! | lw_gas_props | coefficients_for_lw_gas_optics | DDT containing spectral information for RRTMGP LW radiation scheme | DDT | 0 | ty_gas_optics_rrtmgp | | inout | F | +!! | lw_cloud_props | coefficients_for_lw_cloud_optics | DDT containing spectral information for cloudy RRTMGP LW radiation scheme | DDT | 0 | ty_cloud_optics | | inout | F | !! ! ######################################################################################### - subroutine rrtmgp_lw_init(Model, mpicomm, mpirank, mpiroot, kdist_lw, kdist_cldy_lw, & + subroutine rrtmgp_lw_init(Model, mpicomm, mpirank, mpiroot, lw_gas_props, lw_cloud_props, & errmsg, errflg) - use netcdf - -#ifdef MPI - use mpi -#endif ! Inputs type(GFS_control_type), intent(in) :: & @@ -50,9 +39,9 @@ subroutine rrtmgp_lw_init(Model, mpicomm, mpirank, mpiroot, kdist_lw, kdist_cldy mpirank, & ! Current MPI rank mpiroot ! Master MPI rank type(ty_gas_optics_rrtmgp),intent(inout) :: & - kdist_lw + lw_gas_props type(ty_cloud_optics),intent(inout) :: & - kdist_cldy_lw + lw_cloud_props ! Outputs character(len=*), intent(out) :: & @@ -60,599 +49,12 @@ subroutine rrtmgp_lw_init(Model, mpicomm, mpirank, mpiroot, kdist_lw, kdist_cldy integer, intent(out) :: & errflg ! Error code - ! Variables that will be passed to gas_optics%load() - type(ty_gas_concs) :: & - gas_concentrations - integer, dimension(:), allocatable :: & - kminor_start_lower, & ! used by RRTGMP gas optics - kminor_start_upper ! used by RRTGMP gas optics - integer, dimension(:,:), allocatable :: & - band2gpt, & ! used by RRTGMP gas optics - minor_limits_gpt_lower, & ! used by RRTGMP gas optics - minor_limits_gpt_upper ! used by RRTGMP gas optics - integer, dimension(:,:,:), allocatable :: & - key_species ! used by RRTGMP gas optics - real(kind_phys) :: & - press_ref_trop, & ! used by RRTGMP gas optics - temp_ref_p, & ! used by RRTGMP gas optics - temp_ref_t, & ! used by RRTGMP gas optics - radliq_lwr, & ! used by RRTGMP cloud optics - radliq_upr, & ! used by RRTGMP cloud optics - radliq_fac, & ! used by RRTGMP cloud optics - radice_lwr, & ! used by RRTGMP cloud optics - radice_upr, & ! used by RRTGMP cloud optics - radice_fac ! used by RRTGMP cloud optics - real(kind_phys), dimension(:), allocatable :: & - press_ref, & ! used by RRTGMP gas optics - temp_ref, & ! used by RRTGMP gas optics - pade_sizereg_extliq, & ! used by RRTGMP cloud optics - pade_sizereg_ssaliq, & ! used by RRTGMP cloud optics - pade_sizereg_asyliq, & ! used by RRTGMP cloud optics - pade_sizereg_extice, & ! used by RRTGMP cloud optics - pade_sizereg_ssaice, & ! used by RRTGMP cloud optics - pade_sizereg_asyice ! used by RRTGMP cloud optics - real(kind_phys), dimension(:,:), allocatable :: & - band_lims, & ! used by RRTGMP gas optics - totplnk, & ! used by RRTGMP gas optics - lut_extliq, & ! used by RRTGMP cloud optics - lut_ssaliq, & ! used by RRTGMP cloud optics - lut_asyliq, & ! used by RRTGMP cloud optics - band_lims_cldy ! used by RRTGMP cloud optics - - real(kind_phys), dimension(:,:,:), allocatable :: & - vmr_ref, & ! used by RRTGMP gas optics - kminor_lower, & ! used by RRTGMP gas optics - kminor_upper, & ! used by RRTGMP gas optics - rayl_lower, & ! used by RRTGMP gas optics - rayl_upper, & ! used by RRTGMP gas optics - lut_extice, & ! used by RRTGMP cloud optics - lut_ssaice, & ! used by RRTGMP cloud optics - lut_asyice, & ! used by RRTGMP cloud optics - pade_extliq, & ! used by RRTGMP cloud optics - pade_ssaliq, & ! used by RRTGMP cloud optics - pade_asyliq ! used by RRTGMP cloud optics - real(kind_phys), dimension(:,:,:,:), allocatable :: & - kmajor, & ! used by RRTGMP gas optics - planck_frac, & ! used by RRTGMP gas optics - pade_extice, & ! used by RRTGMP cloud optics - pade_ssaice, & ! used by RRTGMP cloud optics - pade_asyice ! used by RRTGMP cloud optics - character(len=32), dimension(:), allocatable :: & - gas_names, & ! used by RRTGMP gas optics - gas_minor, & ! used by RRTGMP gas optics - identifier_minor, & ! used by RRTGMP gas optics - minor_gases_lower, & ! used by RRTGMP gas optics - minor_gases_upper, & ! used by RRTGMP gas optics - scaling_gas_lower, & ! used by RRTGMP gas optics - scaling_gas_upper ! used by RRTGMP gas optics - logical(wl), dimension(:), allocatable :: & - minor_scales_with_density_lower, & ! used by RRTGMP gas optics - minor_scales_with_density_upper, & ! used by RRTGMP gas optics - scale_by_complement_lower, & ! used by RRTGMP gas optics - scale_by_complement_upper ! used by RRTGMP gas optics - - ! Dimensions (to be broadcast across all processors) - integer :: & - ntemps, & ! used by RRTGMP gas optics - npress, & ! used by RRTGMP gas optics - nabsorbers, & ! used by RRTGMP gas optics - nextrabsorbers, & ! used by RRTGMP gas optics - nminorabsorbers, & ! used by RRTGMP gas optics - nmixingfracs, & ! used by RRTGMP gas optics - nlayers, & ! used by RRTGMP gas optics - nbnds, & ! used by RRTGMP gas optics - ngpts, & ! used by RRTGMP gas optics - npairs, & ! used by RRTGMP gas optics - ninternalSourcetemps, & ! used by RRTGMP gas optics - nminor_absorber_intervals_lower, & ! used by RRTGMP gas optics - nminor_absorber_intervals_upper, & ! used by RRTGMP gas optics - ncontributors_lower, & ! used by RRTGMP gas optics - ncontributors_upper, & ! used by RRTGMP gas optics - nbandLWcldy, & ! used by RRTGMP cloud optics - nsize_liq, & ! used by RRTGMP cloud optics - nsize_ice, & ! used by RRTGMP cloud optics - nsizereg, & ! used by RRTGMP cloud optics - ncoeff_ext, & ! used by RRTGMP cloud optics - ncoeff_ssa_g, & ! used by RRTGMP cloud optics - nbound, & ! used by RRTGMP cloud optics - npairsLWcldy ! used by RRTGMP cloud optics - - ! Local variables - integer :: ncid_lw,dimID,varID,status,igpt,iGas,ij,ierr,ncid_lw_clds - integer,dimension(:),allocatable :: temp1,temp2,temp3,temp4,temp_log_array1,& - temp_log_array2, temp_log_array3, temp_log_array4 - character(len=264) :: kdist_file,kdist_cldy_file - integer,parameter :: max_strlen=256 - - ! Initialize - errmsg = '' - errflg = 0 + ! Load gas-optics + call lw_gas_optics_init(Model, mpicomm, mpirank, mpiroot, lw_gas_props, errmsg, errflg) - ! How are we handling cloud-optics? - rrtmgp_lw_cld_phys = Model%rrtmgp_cld_phys - - ! Filenames are set in the gfs_physics_nml (scm/src/GFS_typedefs.F90) - kdist_file = trim(Model%rrtmgp_root)//trim(Model%kdist_lw_file_gas) - kdist_cldy_file = trim(Model%rrtmgp_root)//trim(Model%kdist_lw_file_clouds) - - ! Read dimensions for k-distribution fields (only on master processor(0)) - if (mpirank .eq. mpiroot) then - if(nf90_open(trim(kdist_file), NF90_WRITE, ncid_lw) .eq. NF90_NOERR) then - status = nf90_inq_dimid(ncid_lw, 'temperature', dimid) - status = nf90_inquire_dimension(ncid_lw, dimid, len=ntemps) - status = nf90_inq_dimid(ncid_lw, 'pressure', dimid) - status = nf90_inquire_dimension(ncid_lw, dimid, len=npress) - status = nf90_inq_dimid(ncid_lw, 'absorber', dimid) - status = nf90_inquire_dimension(ncid_lw, dimid, len=nabsorbers) - status = nf90_inq_dimid(ncid_lw, 'minor_absorber', dimid) - status = nf90_inquire_dimension(ncid_lw, dimid, len=nminorabsorbers) - status = nf90_inq_dimid(ncid_lw, 'absorber_ext', dimid) - status = nf90_inquire_dimension(ncid_lw, dimid, len=nextrabsorbers) - status = nf90_inq_dimid(ncid_lw, 'mixing_fraction', dimid) - status = nf90_inquire_dimension(ncid_lw, dimid, len=nmixingfracs) - status = nf90_inq_dimid(ncid_lw, 'atmos_layer', dimid) - status = nf90_inquire_dimension(ncid_lw, dimid, len=nlayers) - status = nf90_inq_dimid(ncid_lw, 'bnd', dimid) - status = nf90_inquire_dimension(ncid_lw, dimid, len=nbnds) - status = nf90_inq_dimid(ncid_lw, 'gpt', dimid) - status = nf90_inquire_dimension(ncid_lw, dimid, len=ngpts) - status = nf90_inq_dimid(ncid_lw, 'pair', dimid) - status = nf90_inquire_dimension(ncid_lw, dimid, len=npairs) - status = nf90_inq_dimid(ncid_lw, 'contributors_lower', dimid) - status = nf90_inquire_dimension(ncid_lw, dimid, len=ncontributors_lower) - status = nf90_inq_dimid(ncid_lw, 'contributors_upper', dimid) - status = nf90_inquire_dimension(ncid_lw, dimid, len=ncontributors_upper) - status = nf90_inq_dimid(ncid_lw, 'minor_absorber_intervals_lower', dimid) - status = nf90_inquire_dimension(ncid_lw, dimid, len=nminor_absorber_intervals_lower) - status = nf90_inq_dimid(ncid_lw, 'minor_absorber_intervals_upper', dimid) - status = nf90_inquire_dimension(ncid_lw, dimid, len=nminor_absorber_intervals_upper) - status = nf90_inq_dimid(ncid_lw, 'temperature_Planck', dimid) - status = nf90_inquire_dimension(ncid_lw, dimid, len=ninternalSourcetemps) - status = nf90_close(ncid_lw) - endif - endif - - ! Broadcast dimensions to all processors -#ifdef MPI - call MPI_BCAST(ntemps, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(npress, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(nabsorbers, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(nminorabsorbers, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(nextraabsorbers, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(nmixingfracs, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(nlayers, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(nbnds, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(ngpts, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(npairs, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(ncontributors_lower, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(ncontributors_upper, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(nminor_absorber_intervals_lower, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(nminor_absorber_intervals_upper, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(ninternalSourcetemps, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) -#endif - - !if (mpirank .eq. mpiroot) then - ! Allocate space for arrays - allocate(gas_names(nabsorbers)) - allocate(scaling_gas_lower(nminor_absorber_intervals_lower)) - allocate(scaling_gas_upper(nminor_absorber_intervals_upper)) - allocate(gas_minor(nminorabsorbers)) - allocate(identifier_minor(nminorabsorbers)) - allocate(minor_gases_lower(nminor_absorber_intervals_lower)) - allocate(minor_gases_upper(nminor_absorber_intervals_upper)) - allocate(minor_limits_gpt_lower(npairs,nminor_absorber_intervals_lower)) - allocate(minor_limits_gpt_upper(npairs,nminor_absorber_intervals_upper)) - allocate(band2gpt(2,nbnds)) - allocate(key_species(2,nlayers,nbnds)) - allocate(band_lims(2,nbnds)) - allocate(press_ref(npress)) - allocate(temp_ref(ntemps)) - allocate(vmr_ref(nlayers, nextrabsorbers, ntemps)) - allocate(kminor_lower(ncontributors_lower, nmixingfracs, ntemps)) - allocate(kmajor(ngpts, nmixingfracs, npress+1, ntemps)) - allocate(kminor_start_lower(nminor_absorber_intervals_lower)) - allocate(kminor_upper(ncontributors_upper, nmixingfracs, ntemps)) - allocate(kminor_start_upper(nminor_absorber_intervals_upper)) - allocate(minor_scales_with_density_lower(nminor_absorber_intervals_lower)) - allocate(minor_scales_with_density_upper(nminor_absorber_intervals_upper)) - allocate(scale_by_complement_lower(nminor_absorber_intervals_lower)) - allocate(scale_by_complement_upper(nminor_absorber_intervals_upper)) - allocate(temp1(nminor_absorber_intervals_lower)) - allocate(temp2(nminor_absorber_intervals_upper)) - allocate(temp3(nminor_absorber_intervals_lower)) - allocate(temp4(nminor_absorber_intervals_upper)) - allocate(totplnk(ninternalSourcetemps, nbnds)) - allocate(planck_frac(ngpts, nmixingfracs, npress+1, ntemps)) - - if (mpirank .eq. mpiroot) then - ! Read in fields from file - if(nf90_open(trim(kdist_file), NF90_WRITE, ncid_lw) .eq. NF90_NOERR) then - status = nf90_inq_varid(ncid_lw,'gas_names',varID) - status = nf90_get_var(ncid_lw,varID,gas_names) - ! - status = nf90_inq_varid(ncid_lw,'scaling_gas_lower',varID) - status = nf90_get_var(ncid_lw,varID,scaling_gas_lower) - ! - status = nf90_inq_varid(ncid_lw,'scaling_gas_upper',varID) - status = nf90_get_var(ncid_lw,varID,scaling_gas_upper) - ! - status = nf90_inq_varid(ncid_lw,'gas_minor',varID) - status = nf90_get_var(ncid_lw,varID,gas_minor) - ! - status = nf90_inq_varid(ncid_lw,'identifier_minor',varID) - status = nf90_get_var(ncid_lw,varID,identifier_minor) - ! - status = nf90_inq_varid(ncid_lw,'minor_gases_lower',varID) - status = nf90_get_var(ncid_lw,varID,minor_gases_lower) - ! - status = nf90_inq_varid(ncid_lw,'minor_gases_upper',varID) - status = nf90_get_var(ncid_lw,varID,minor_gases_upper) - ! - status = nf90_inq_varid(ncid_lw,'minor_limits_gpt_lower',varID) - status = nf90_get_var(ncid_lw,varID,minor_limits_gpt_lower) - ! - status = nf90_inq_varid(ncid_lw,'minor_limits_gpt_upper',varID) - status = nf90_get_var(ncid_lw,varID,minor_limits_gpt_upper) - ! - status = nf90_inq_varid(ncid_lw,'bnd_limits_gpt',varID) - status = nf90_get_var(ncid_lw,varID,band2gpt) - ! - status = nf90_inq_varid(ncid_lw,'key_species',varID) - status = nf90_get_var(ncid_lw,varID,key_species) - ! - status = nf90_inq_varid(ncid_lw,'bnd_limits_wavenumber',varID) - status = nf90_get_var(ncid_lw,varID,band_lims) - ! - status = nf90_inq_varid(ncid_lw,'press_ref',varID) - status = nf90_get_var(ncid_lw,varID,press_ref) - ! - status = nf90_inq_varid(ncid_lw,'temp_ref',varID) - status = nf90_get_var(ncid_lw,varID,temp_ref) - ! - status = nf90_inq_varid(ncid_lw,'absorption_coefficient_ref_P',varID) - status = nf90_get_var(ncid_lw,varID,temp_ref_p) - ! - status = nf90_inq_varid(ncid_lw,'absorption_coefficient_ref_T',varID) - status = nf90_get_var(ncid_lw,varID,temp_ref_t) - ! - status = nf90_inq_varid(ncid_lw,'press_ref_trop',varID) - status = nf90_get_var(ncid_lw,varID,press_ref_trop) - ! - status = nf90_inq_varid(ncid_lw,'kminor_lower',varID) - status = nf90_get_var(ncid_lw,varID,kminor_lower) - ! - status = nf90_inq_varid(ncid_lw,'kminor_upper',varID) - status = nf90_get_var(ncid_lw,varID,kminor_upper) - ! - status = nf90_inq_varid(ncid_lw,'vmr_ref',varID) - status = nf90_get_var(ncid_lw,varID,vmr_ref) - ! - status = nf90_inq_varid(ncid_lw,'kmajor',varID) - status = nf90_get_var(ncid_lw,varID,kmajor) - ! - status = nf90_inq_varid(ncid_lw,'kminor_start_lower',varID) - status = nf90_get_var(ncid_lw,varID,kminor_start_lower) - ! - status = nf90_inq_varid(ncid_lw,'kminor_start_upper',varID) - status = nf90_get_var(ncid_lw,varID,kminor_start_upper) - ! - status = nf90_inq_varid(ncid_lw,'totplnk',varID) - status = nf90_get_var(ncid_lw,varID,totplnk) - ! - status = nf90_inq_varid(ncid_lw,'plank_fraction',varID) - status = nf90_get_var(ncid_lw,varID,planck_frac) - - ! Logical fields are read in as integers and then converted to logicals. - status = nf90_inq_varid(ncid_lw,'minor_scales_with_density_lower',varID) - status = nf90_get_var(ncid_lw,varID,temp1) - minor_scales_with_density_lower(:) = .false. - where(temp1 .eq. 1) minor_scales_with_density_lower(:) = .true. - ! - status = nf90_inq_varid(ncid_lw,'minor_scales_with_density_upper',varID) - status = nf90_get_var(ncid_lw,varID,temp2) - minor_scales_with_density_upper(:) = .false. - where(temp2 .eq. 1) minor_scales_with_density_upper(:) = .true. - ! - status = nf90_inq_varid(ncid_lw,'scale_by_complement_lower',varID) - status = nf90_get_var(ncid_lw,varID,temp3) - scale_by_complement_lower(:) = .false. - where(temp3 .eq. 1) scale_by_complement_lower(:) = .true. - ! - status = nf90_inq_varid(ncid_lw,'scale_by_complement_upper',varID) - status = nf90_get_var(ncid_lw,varID,temp4) - scale_by_complement_upper(:) = .false. - where(temp4 .eq. 1) scale_by_complement_upper(:) = .true. - - ! Close - status = nf90_close(ncid_lw) - endif - endif - - ! Broadcast arrays to all processors -#ifdef MPI - call MPI_BCAST(minor_limits_gpt_upper, size(minor_limits_gpt_upper), MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(minor_limits_gpt_lower, size(minor_limits_gpt_lower), MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(kminor_start_upper, size(kminor_start_upper), MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(kminor_start_lower, size(kminor_start_lower), MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(key_species, size(key_species), MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(band2gpt, size(band2gpt), MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(band_lims, size(band_lims), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(press_ref, size(press_ref), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(temp_ref, size(temp_ref), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(kminor_lower, size(kminor_lower), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(kminor_upper, size(kminor_upper), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(scaling_gas_lower, size(scaling_gas_lower), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(scaling_gas_upper, size(scaling_gas_upper), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(vmr_ref, size(vmr_ref), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(kmajor, size(kmajor), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(temp_ref_p, 1, kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(temp_ref_t, 1, kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(press_ref_trop, 1, kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(totplnk, size(totplnk), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(planck_frac, size(planck_frac), kind_phys, mpiroot, mpicomm, ierr) - ! Character arrays - do ij=1,nabsorbers - call MPI_BCAST(gas_names(ij), 32, MPI_CHAR, mpiroot, mpicomm, ierr) - enddo - do ij=1,nminorabsorbers - call MPI_BCAST(gas_minor(ij), 32, MPI_CHAR, mpiroot, mpicomm, ierr) - call MPI_BCAST(identifier_minor(ij), 32, MPI_CHAR, mpiroot, mpicomm, ierr) - enddo - do ij=1,nminor_absorber_intervals_lower - call MPI_BCAST(minor_gases_lower(ij), 32, MPI_CHAR, mpiroot, mpicomm, ierr) - enddo - do ij=1,nminor_absorber_intervals_upper - call MPI_BCAST(minor_gases_upper(ij), 32, MPI_CHAR, mpiroot, mpicomm, ierr) - enddo - ! Logical arrays (First convert to integer-array, then broadcast) - ! - allocate(temp_log_array1(nminor_absorber_intervals_lower)) - where(minor_scales_with_density_lower) - temp_log_array1 = 1 - elsewhere - temp_log_array1 = 0 - end where - call MPI_BCAST(temp_log_array1, size(temp_log_array1), MPI_INTEGER, mpiroot, mpicomm, ierr) - ! - allocate(temp_log_array2(nminor_absorber_intervals_lower)) - where(scale_by_complement_lower) - temp_log_array2 = 1 - elsewhere - temp_log_array2 = 0 - end where - call MPI_BCAST(temp_log_array2, size(temp_log_array2), MPI_INTEGER, mpiroot, mpicomm, ierr) - ! - allocate(temp_log_array3(nminor_absorber_intervals_upper)) - where(minor_scales_with_density_upper) - temp_log_array3 = 1 - elsewhere - temp_log_array3 = 0 - end where - call MPI_BCAST(temp_log_array3, size(temp_log_array3), MPI_INTEGER, mpiroot, mpicomm, ierr) - ! - allocate(temp_log_array4(nminor_absorber_intervals_upper)) - where(scale_by_complement_upper) - temp_log_array4 = 1 - elsewhere - temp_log_array4 = 0 - end where - call MPI_BCAST(temp_log_array4, size(temp_log_array4), MPI_INTEGER, mpiroot, mpicomm, ierr) -#endif - - ! Initialize gas concentrations and gas optics class with data - do iGas=1,nGases - call check_error_msg('rrtmgp_lw_init',gas_concentrations%set_vmr(active_gases(iGas), 0._kind_phys)) - enddo - call check_error_msg('rrtmgp_lw_init',kdist_lw%load(gas_concentrations, gas_names, key_species, band2gpt, & - band_lims, press_ref, press_ref_trop, temp_ref, temp_ref_p, temp_ref_t, & - vmr_ref, kmajor, kminor_lower, kminor_upper, gas_minor,identifier_minor, & - minor_gases_lower, minor_gases_upper, minor_limits_gpt_lower, & - minor_limits_gpt_upper, minor_scales_with_density_lower, & - minor_scales_with_density_upper, scaling_gas_lower, & - scaling_gas_upper, scale_by_complement_lower, & - scale_by_complement_upper, kminor_start_lower, kminor_start_upper, & - totplnk, planck_frac, rayl_lower, rayl_upper)) - - ! Set initial permutation seed for McICA, initially set to number of G-points - ipsdlw0 = kdist_lw%get_ngpt() - - ! ####################################################################################### - ! If RRTMGP cloud-optics are requested, read tables and broadcast. - ! ####################################################################################### - ! Read dimensions for k-distribution fields (only on master processor(0)) - if (mpirank .eq. mpiroot) then - if(nf90_open(trim(kdist_cldy_file), NF90_WRITE, ncid_lw_clds) == NF90_NOERR) then - status = nf90_inq_dimid(ncid_lw_clds, 'nband', dimid) - status = nf90_inquire_dimension(ncid_lw_clds, dimid, len=nbandLWcldy) - status = nf90_inq_dimid(ncid_lw_clds, 'nrghice', dimid) - status = nf90_inquire_dimension(ncid_lw_clds, dimid, len=nrghice) - status = nf90_inq_dimid(ncid_lw_clds, 'nsize_liq', dimid) - status = nf90_inquire_dimension(ncid_lw_clds, dimid, len=nsize_liq) - status = nf90_inq_dimid(ncid_lw_clds, 'nsize_ice', dimid) - status = nf90_inquire_dimension(ncid_lw_clds, dimid, len=nsize_ice) - status = nf90_inq_dimid(ncid_lw_clds, 'nsizereg', dimid) - status = nf90_inquire_dimension(ncid_lw_clds, dimid, len=nsizereg) - status = nf90_inq_dimid(ncid_lw_clds, 'ncoeff_ext', dimid) - status = nf90_inquire_dimension(ncid_lw_clds, dimid, len=ncoeff_ext) - status = nf90_inq_dimid(ncid_lw_clds, 'ncoeff_ssa_g', dimid) - status = nf90_inquire_dimension(ncid_lw_clds, dimid, len=ncoeff_ssa_g) - status = nf90_inq_dimid(ncid_lw_clds, 'nbound', dimid) - status = nf90_inquire_dimension(ncid_lw_clds, dimid, len=nbound) - status = nf90_inq_dimid(ncid_lw_clds, 'pair', dimid) - status = nf90_inquire_dimension(ncid_lw_clds, dimid, len=npairsLWcldy) - status = nf90_close(ncid_lw_clds) - endif - endif - - ! Broadcast dimensions to all processors -#ifdef MPI - if (rrtmgp_lw_cld_phys .eq. 1 .or. rrtmgp_lw_cld_phys .eq. 2) then - call MPI_BCAST(nbandLWcldy, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(nrghice, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(nsize_liq, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(nsize_ice, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(nsizereg, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(ncoeff_ext, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(ncoeff_ssa_g, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(nbound, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(npairsLWcldy, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - endif -#endif - - if (rrtmgp_lw_cld_phys .eq. 1) then - allocate(lut_extliq(nsize_liq, nBandLWcldy)) - allocate(lut_ssaliq(nsize_liq, nBandLWcldy)) - allocate(lut_asyliq(nsize_liq, nBandLWcldy)) - allocate(lut_extice(nsize_ice, nBandLWcldy, nrghice)) - allocate(lut_ssaice(nsize_ice, nBandLWcldy, nrghice)) - allocate(lut_asyice(nsize_ice, nBandLWcldy, nrghice)) - allocate(band_lims_cldy(2, nBandLWcldy)) - endif - if (rrtmgp_lw_cld_phys .eq. 2) then - allocate(pade_extliq(nbandLWcldy, nsizereg, ncoeff_ext )) - allocate(pade_ssaliq(nbandLWcldy, nsizereg, ncoeff_ssa_g)) - allocate(pade_asyliq(nbandLWcldy, nsizereg, ncoeff_ssa_g)) - allocate(pade_extice(nbandLWcldy, nsizereg, ncoeff_ext, nrghice)) - allocate(pade_ssaice(nbandLWcldy, nsizereg, ncoeff_ssa_g, nrghice)) - allocate(pade_asyice(nbandLWcldy, nsizereg, ncoeff_ssa_g, nrghice)) - allocate(pade_sizereg_extliq(nbound)) - allocate(pade_sizereg_ssaliq(nbound)) - allocate(pade_sizereg_asyliq(nbound)) - allocate(pade_sizereg_extice(nbound)) - allocate(pade_sizereg_ssaice(nbound)) - allocate(pade_sizereg_asyice(nbound)) - allocate(band_lims_cldy(2,nbandLWcldy)) - endif - - ! On master processor, allocate space, read in fields, broadcast to all processors - if (mpirank .eq. mpiroot) then - ! - if (rrtmgp_lw_cld_phys .eq. 1) then - ! - if(nf90_open(trim(kdist_cldy_file), NF90_WRITE, ncid_lw_clds) == NF90_NOERR) then - status = nf90_inq_varid(ncid_lw_clds,'radliq_lwr',varID) - status = nf90_get_var(ncid_lw_clds,varID,radliq_lwr) - status = nf90_inq_varid(ncid_lw_clds,'radliq_upr',varID) - status = nf90_get_var(ncid_lw_clds,varID,radliq_upr) - status = nf90_inq_varid(ncid_lw_clds,'radliq_fac',varID) - status = nf90_get_var(ncid_lw_clds,varID,radliq_fac) - status = nf90_inq_varid(ncid_lw_clds,'radice_lwr',varID) - status = nf90_get_var(ncid_lw_clds,varID,radice_lwr) - status = nf90_inq_varid(ncid_lw_clds,'radice_upr',varID) - status = nf90_get_var(ncid_lw_clds,varID,radice_upr) - status = nf90_inq_varid(ncid_lw_clds,'radice_fac',varID) - status = nf90_get_var(ncid_lw_clds,varID,radice_fac) - status = nf90_inq_varid(ncid_lw_clds,'lut_extliq',varID) - status = nf90_get_var(ncid_lw_clds,varID,lut_extliq) - status = nf90_inq_varid(ncid_lw_clds,'lut_ssaliq',varID) - status = nf90_get_var(ncid_lw_clds,varID,lut_ssaliq) - status = nf90_inq_varid(ncid_lw_clds,'lut_asyliq',varID) - status = nf90_get_var(ncid_lw_clds,varID,lut_asyliq) - status = nf90_inq_varid(ncid_lw_clds,'lut_extice',varID) - status = nf90_get_var(ncid_lw_clds,varID,lut_extice) - status = nf90_inq_varid(ncid_lw_clds,'lut_ssaice',varID) - status = nf90_get_var(ncid_lw_clds,varID,lut_ssaice) - status = nf90_inq_varid(ncid_lw_clds,'lut_asyice',varID) - status = nf90_get_var(ncid_lw_clds,varID,lut_asyice) - status = nf90_inq_varid(ncid_lw_clds,'bnd_limits_wavenumber',varID) - status = nf90_get_var(ncid_lw_clds,varID,band_lims_cldy) - status = nf90_close(ncid_lw_clds) - endif - endif - ! - if (rrtmgp_lw_cld_phys .eq. 2) then - ! - if(nf90_open(trim(kdist_cldy_file), NF90_WRITE, ncid_lw_clds) == NF90_NOERR) then - status = nf90_inq_varid(ncid_lw_clds,'radliq_lwr',varID) - status = nf90_get_var(ncid_lw_clds,varID,radliq_lwr) - status = nf90_inq_varid(ncid_lw_clds,'radliq_upr',varID) - status = nf90_get_var(ncid_lw_clds,varID,radliq_upr) - status = nf90_inq_varid(ncid_lw_clds,'radliq_fac',varID) - status = nf90_get_var(ncid_lw_clds,varID,radliq_fac) - status = nf90_inq_varid(ncid_lw_clds,'radice_lwr',varID) - status = nf90_get_var(ncid_lw_clds,varID,radice_lwr) - status = nf90_inq_varid(ncid_lw_clds,'radice_upr',varID) - status = nf90_get_var(ncid_lw_clds,varID,radice_upr) - status = nf90_inq_varid(ncid_lw_clds,'radice_fac',varID) - status = nf90_get_var(ncid_lw_clds,varID,radice_fac) - status = nf90_inq_varid(ncid_lw_clds,'pade_extliq',varID) - status = nf90_get_var(ncid_lw_clds,varID,pade_extliq) - status = nf90_inq_varid(ncid_lw_clds,'pade_ssaliq',varID) - status = nf90_get_var(ncid_lw_clds,varID,pade_ssaliq) - status = nf90_inq_varid(ncid_lw_clds,'pade_asyliq',varID) - status = nf90_get_var(ncid_lw_clds,varID,pade_asyliq) - status = nf90_inq_varid(ncid_lw_clds,'pade_extice',varID) - status = nf90_get_var(ncid_lw_clds,varID,pade_extice) - status = nf90_inq_varid(ncid_lw_clds,'pade_ssaice',varID) - status = nf90_get_var(ncid_lw_clds,varID,pade_ssaice) - status = nf90_inq_varid(ncid_lw_clds,'pade_asyice',varID) - status = nf90_get_var(ncid_lw_clds,varID,pade_asyice) - status = nf90_inq_varid(ncid_lw_clds,'pade_sizreg_extliq',varID) - status = nf90_get_var(ncid_lw_clds,varID,pade_sizereg_extliq) - status = nf90_inq_varid(ncid_lw_clds,'pade_sizreg_ssaliq',varID) - status = nf90_get_var(ncid_lw_clds,varID,pade_sizereg_ssaliq) - status = nf90_inq_varid(ncid_lw_clds,'pade_sizreg_asyliq',varID) - status = nf90_get_var(ncid_lw_clds,varID,pade_sizereg_asyliq) - status = nf90_inq_varid(ncid_lw_clds,'pade_sizreg_extice',varID) - status = nf90_get_var(ncid_lw_clds,varID,pade_sizereg_extice) - status = nf90_inq_varid(ncid_lw_clds,'pade_sizreg_ssaice',varID) - status = nf90_get_var(ncid_lw_clds,varID,pade_sizereg_ssaice) - status = nf90_inq_varid(ncid_lw_clds,'pade_sizreg_asyice',varID) - status = nf90_get_var(ncid_lw_clds,varID,pade_sizereg_asyice) - status = nf90_inq_varid(ncid_lw_clds,'bnd_limits_wavenumber',varID) - status = nf90_get_var(ncid_lw_clds,varID,band_lims_cldy) - status = nf90_close(ncid_lw_clds) - endif - endif - endif - - ! Broadcast arrays to all processors -#ifdef MPI - if (rrtmgp_lw_cld_phys .eq. 1) then - call MPI_BCAST(radliq_lwr, size(radliq_lwr), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(radliq_upr, size(radliq_upr), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(radliq_fac, size(radliq_fac), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(radice_lwr, size(radice_lwr), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(radice_upr, size(radice_upr), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(radice_fac, size(radice_fac), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(lut_extliq, size(lut_extliq), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(lut_ssaliq, size(lut_ssaliq), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(lut_asyliq, size(lut_asyliq), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(lut_extice, size(lut_extice), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(lut_ssaice, size(lut_ssaice), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(lut_asyice, size(lut_asyice), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(band_lims_cldy), size(band_lims_cldy), kind_phys, mpiroot, mpicomm, ierr) - endif - if (rrtmgp_lw_cld_phys .eq. 2) then - call MPI_BCAST(pade_extliq, size(pade_extliq), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(pade_ssaliq, size(pade_ssaliq), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(pade_asyliq, size(pade_asyliq), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(pade_extice, size(pade_extice), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(pade_ssaice, size(pade_ssaice), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(pade_asyice, size(pade_asyice), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(pade_sizereg_extliq), size(pade_sizereg_extliq), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(pade_sizereg_ssaliq), size(pade_sizereg_ssaliq), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(pade_sizereg_asyliq), size(pade_sizereg_asyliq), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(pade_sizereg_extice), size(pade_sizereg_extice), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(pade_sizereg_ssaice), size(pade_sizereg_ssaice), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(pade_sizereg_asyice), size(pade_sizereg_asyice), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(band_lims_cldy), size(band_lims_cldy), kind_phys, mpiroot, mpicomm, ierr) - endif -#endif - - ! Load tables data for RRTGMP cloud-optics - if (rrtmgp_lw_cld_phys .eq. 1) then - call check_error_msg('rrtmgp_lw_init',kdist_cldy_lw%set_ice_roughness(nrghice)) - call check_error_msg('rrtmgp_lw_init',kdist_cldy_lw%load(band_lims_cldy, radliq_lwr, radliq_upr, & - radliq_fac, radice_lwr, radice_upr, radice_fac, lut_extliq, lut_ssaliq, & - lut_asyliq, lut_extice, lut_ssaice, lut_asyice)) - endif - if (rrtmgp_lw_cld_phys .eq. 2) then - call check_error_msg('rrtmgp_lw_init',kdist_cldy_lw%set_ice_roughness(nrghice)) - call check_error_msg('rrtmgp_lw_init',kdist_cldy_lw%load(band_lims_cldy, pade_extliq, & - pade_ssaliq, pade_asyliq, pade_extice, pade_ssaice, pade_asyice, & - pade_sizereg_extliq, pade_sizereg_ssaliq, pade_sizereg_asyliq, & - pade_sizereg_extice, pade_sizereg_ssaice, pade_sizereg_asyice)) + ! Load cloud optics + if (Model%rrtmgp_cld_optics .gt. 0) then + call lw_cloud_optics_init(Model, mpicomm, mpirank, mpiroot, lw_cloud_props, errmsg, errflg) endif end subroutine rrtmgp_lw_init @@ -669,7 +71,7 @@ end subroutine rrtmgp_lw_init !! | t_lay | air_temperature_at_layer_for_RRTMGP | air temperature layer | K | 2 | real | kind_phys | in | F | !! | skt | surface_ground_temperature_for_radiation | surface ground temperature for radiation | K | 1 | real | kind_phys | in | F | !! | sfc_emiss | surface_longwave_emissivity_in_each_band | surface lw emissivity in fraction in each LW band | frac | 2 | real | kind_phys | in | F | -!! | kdist_lw | K_distribution_file_for_RRTMGP_LW_scheme | DDT containing spectral information for RRTMGP LW radiation scheme | DDT | 0 | ty_gas_optics_rrtmgp | | in | F | +!! | lw_gas_props | coefficients_for_lw_gas_optics | DDT containing spectral information for RRTMGP LW radiation scheme | DDT | 0 | ty_gas_optics_rrtmgp | | in | F | !! | optical_propsLW_clds | longwave_optical_properties_for_cloudy_atmosphere | Fortran DDT containing RRTMGP optical properties | DDT | 0 | ty_optical_props_1scl | | in | F | !! | optical_propsLW_aerosol | longwave_optical_properties_for_aerosols | Fortran DDT containing RRTMGP optical properties | DDT | 0 | ty_optical_props_1scl | | in | F | !! | gas_concentrations | Gas_concentrations_for_RRTMGP_suite | DDT containing gas concentrations for RRTMGP radiation scheme | DDT | 0 | ty_gas_concs | | in | F | @@ -683,7 +85,7 @@ end subroutine rrtmgp_lw_init !! | errmsg | ccpp_error_message | error message for error handling in CCPP | none | 0 | character | len=* | out | F | !! | errflg | ccpp_error_flag | error flag for error handling in CCPP | flag | 0 | integer | | out | F | !! - subroutine rrtmgp_lw_run(Model, ncol, kdist_lw, p_lay, t_lay, p_lev, skt, & + subroutine rrtmgp_lw_run(Model, ncol, lw_gas_props, p_lay, t_lay, p_lev, skt, & sfc_emiss, gas_concentrations, optical_propsLW_clds, optical_propsLW_aerosol,& lslwr, fluxUP_allsky, fluxDOWN_allsky, fluxUP_clrsky, fluxDOWN_clrsky, hlw0, hlwb, errmsg, errflg) @@ -699,8 +101,8 @@ subroutine rrtmgp_lw_run(Model, ncol, kdist_lw, p_lay, t_lay, p_lev, skt, & real(kind_phys), dimension(ncol), intent(in) :: & skt ! Surface(skin) temperature (K) type(ty_gas_optics_rrtmgp),intent(in) :: & - kdist_lw ! DDT containing LW spectral information - real(kind_phys), dimension(kdist_lw%get_nband(),ncol) :: & + lw_gas_props ! DDT containing LW spectral information + real(kind_phys), dimension(lw_gas_props%get_nband(),ncol) :: & sfc_emiss ! Surface emissivity (1) type(ty_optical_props_1scl),intent(in) :: & optical_propsLW_clds, & ! RRTMGP DDT: longwave cloud radiative properties @@ -720,7 +122,7 @@ subroutine rrtmgp_lw_run(Model, ncol, kdist_lw, p_lay, t_lay, p_lev, skt, & fluxDOWN_clrsky ! All-sky flux (W/m2) ! Outputs (optional) - real(kind_phys), dimension(ncol,model%levs,kdist_lw%get_nband()), optional, intent(inout) :: & + real(kind_phys), dimension(ncol,model%levs,lw_gas_props%get_nband()), optional, intent(inout) :: & hlwb ! All-sky heating rate, by band (K/sec) real(kind_phys), dimension(ncol,model%levs), optional, intent(inout) :: & hlw0 ! Clear-sky heating rate (K/sec) @@ -731,7 +133,7 @@ subroutine rrtmgp_lw_run(Model, ncol, kdist_lw, p_lay, t_lay, p_lev, skt, & flux_clrsky ! Clear-sky flux (W/m2) real(kind_phys), dimension(ncol,model%levs+1),target :: & fluxLW_up_allsky, fluxLW_up_clrsky, fluxLW_dn_allsky, fluxLW_dn_clrsky - real(kind_phys), dimension(ncol,model%levs+1,kdist_lw%get_nband()),target :: & + real(kind_phys), dimension(ncol,model%levs+1,lw_gas_props%get_nband()),target :: & fluxLWBB_up_allsky, fluxLWBB_dn_allsky logical :: l_ClrSky_HR, l_AllSky_HR_byband integer :: k @@ -758,7 +160,7 @@ subroutine rrtmgp_lw_run(Model, ncol, kdist_lw, p_lay, t_lay, p_lev, skt, & ! Call RRTMGP LW scheme call check_error_msg('rrtmgp_lw_run',rte_lw( & - kdist_lw, & ! IN - spectral information + lw_gas_props, & ! IN - spectral information gas_concentrations, & ! IN - gas concentrations (vmr) p_lay, & ! IN - pressure at layer interfaces (Pa) t_lay, & ! IN - temperature at layer interfaes (K) @@ -778,14 +180,6 @@ end subroutine rrtmgp_lw_run subroutine rrtmgp_lw_finalize() end subroutine rrtmgp_lw_finalize - subroutine check_error_msg(routine_name, error_msg) - character(len=*), intent(in) :: & - error_msg, routine_name - - if(error_msg /= "") then - print*,"ERROR("//trim(routine_name)//"): " - print*,trim(error_msg) - return - end if - end subroutine check_error_msg + + end module rrtmgp_lw diff --git a/physics/rrtmgp_sw.F90 b/physics/rrtmgp_sw.F90 index 97d485f2f..3592a7b55 100644 --- a/physics/rrtmgp_sw.F90 +++ b/physics/rrtmgp_sw.F90 @@ -11,38 +11,27 @@ module rrtmgp_sw use mo_gas_concentrations, only: ty_gas_concs use mo_fluxes_byband, only: ty_fluxes_byband use module_radsw_parameters, only: cmpfsw_type - - ! Parameters - integer,parameter :: nGases = 6 - real(kind_phys),parameter :: epsilon=1.0e-6 - character(len=3),parameter, dimension(nGases) :: & - active_gases = (/ 'h2o', 'co2', 'o3 ', 'n2o', 'ch4', 'o2 '/) - integer :: nrghice, ipsdsw0 + use rrtmgp_aux, only: sw_gas_optics_init, sw_cloud_optics_init, check_error_msg, active_gases public rrtmgp_sw_init, rrtmgp_sw_run, rrtmgp_sw_finalize -contains +contains !! \section arg_table_rrtmgp_sw_init Argument Table -!! | local_name | standard_name | long_name | units | rank | type | kind | intent | optional | -!! |--------------------|-------------------------------------------------|---------------------------------------------------------------------------|-------|------|----------------------|-----------|--------|----------| -!! | Model | GFS_control_type_instance | Fortran DDT containing FV3-GFS model control parameters | DDT | 0 | GFS_control_type | | in | F | -!! | mpirank | mpi_rank | current MPI rank | index | 0 | integer | | in | F | -!! | mpiroot | mpi_root | master MPI rank | index | 0 | integer | | in | F | -!! | mpicomm | mpi_comm | MPI communicator | index | 0 | integer | | in | F | -!! | errmsg | ccpp_error_message | error message for error handling in CCPP | none | 0 | character | len=* | out | F | -!! | errflg | ccpp_error_flag | error flag for error handling in CCPP | flag | 0 | integer | | out | F | -!! | kdist_sw | K_distribution_file_for_RRTMGP_SW_scheme | DDT containing spectral information for RRTMGP SW radiation scheme | DDT | 0 | ty_gas_optics_rrtmgp | | inout | F | -!! | kdist_cldy_sw | K_distribution_file_for_cloudy_RRTMGP_SW_scheme | DDT containing spectral information for cloudy RRTMGP SW radiation scheme | DDT | 0 | ty_cloud_optics | | inout | F | +!! | local_name | standard_name | long_name | units | rank | type | kind | intent | optional | +!! |--------------------|----------------------------------|---------------------------------------------------------------------------|-------|------|----------------------|-----------|--------|----------| +!! | Model | GFS_control_type_instance | Fortran DDT containing FV3-GFS model control parameters | DDT | 0 | GFS_control_type | | in | F | +!! | mpirank | mpi_rank | current MPI rank | index | 0 | integer | | in | F | +!! | mpiroot | mpi_root | master MPI rank | index | 0 | integer | | in | F | +!! | mpicomm | mpi_comm | MPI communicator | index | 0 | integer | | in | F | +!! | errmsg | ccpp_error_message | error message for error handling in CCPP | none | 0 | character | len=* | out | F | +!! | errflg | ccpp_error_flag | error flag for error handling in CCPP | flag | 0 | integer | | out | F | +!! | sw_gas_props | coefficients_for_sw_gas_optics | DDT containing spectral information for RRTMGP SW radiation scheme | DDT | 0 | ty_gas_optics_rrtmgp | | inout | F | +!! | sw_cloud_props | coefficients_for_sw_cloud_optics | DDT containing spectral information for cloudy RRTMGP SW radiation scheme | DDT | 0 | ty_cloud_optics | | inout | F | !! ! ######################################################################################### - subroutine rrtmgp_sw_init(Model,mpicomm, mpirank, mpiroot, kdist_sw, kdist_cldy_sw, & + subroutine rrtmgp_sw_init(Model,mpicomm, mpirank, mpiroot, sw_gas_props, sw_cloud_props, & errmsg, errflg) - use netcdf - -#ifdef MPI - use mpi -#endif ! Inputs type(GFS_control_type), intent(in) :: & @@ -52,9 +41,9 @@ subroutine rrtmgp_sw_init(Model,mpicomm, mpirank, mpiroot, kdist_sw, kdist_cldy_ mpirank, & ! Current MPI rank mpiroot ! Master MPI rank type(ty_gas_optics_rrtmgp),intent(inout) :: & - kdist_sw + sw_gas_props type(ty_cloud_optics),intent(inout) :: & - kdist_cldy_sw + sw_cloud_props ! Outputs character(len=*), intent(out) :: & @@ -62,606 +51,13 @@ subroutine rrtmgp_sw_init(Model,mpicomm, mpirank, mpiroot, kdist_sw, kdist_cldy_ integer, intent(out) :: & errflg ! Error code - ! Fields from the K-distribution files - ! Variables that will be passed to gas_optics%load() - type(ty_gas_concs) :: & - gas_concentrations - integer, dimension(:), allocatable :: & - kminor_start_lower_sw, & ! used by RRTGMP gas optics - kminor_start_upper_sw ! used by RRTGMP gas optics - integer, dimension(:,:), allocatable :: & - band2gpt_sw, & ! used by RRTGMP gas optics - minor_limits_gpt_lower_sw, & ! used by RRTGMP gas optics - minor_limits_gpt_upper_sw ! used by RRTGMP gas optics - integer, dimension(:,:,:), allocatable :: & - key_species_sw ! used by RRTGMP gas optics - real(kind_phys) :: & - press_ref_trop_sw, & ! used by RRTGMP gas optics - temp_ref_p_sw, & ! used by RRTGMP gas optics - temp_ref_t_sw, & ! used by RRTGMP gas optics - radliq_lwr_sw, & ! used by RRTGMP cloud optics - radliq_upr_sw, & ! used by RRTGMP cloud optics - radliq_fac_sw, & ! used by RRTGMP cloud optics - radice_lwr_sw, & ! used by RRTGMP cloud optics - radice_upr_sw, & ! used by RRTGMP cloud optics - radice_fac_sw ! used by RRTGMP cloud optics - - real(kind_phys), dimension(:), allocatable :: & - press_ref_sw, & ! used by RRTGMP gas optics - temp_ref_sw, & ! used by RRTGMP gas optics - solar_source_sw, & ! used by RRTGMP gas optics - pade_sizereg_extliq_sw, & ! used by RRTGMP cloud optics - pade_sizereg_ssaliq_sw, & ! used by RRTGMP cloud optics - pade_sizereg_asyliq_sw, & ! used by RRTGMP cloud optics - pade_sizereg_extice_sw, & ! used by RRTGMP cloud optics - pade_sizereg_ssaice_sw, & ! used by RRTGMP cloud optics - pade_sizereg_asyice_sw ! used by RRTGMP cloud optics - real(kind_phys), dimension(:,:), allocatable :: & - band_lims_sw, & ! used by RRTGMP gas optics - lut_extliq_sw, & ! used by RRTGMP cloud optics - lut_ssaliq_sw, & ! used by RRTGMP cloud optics - lut_asyliq_sw, & ! used by RRTGMP cloud optics - band_lims_cldy_sw ! used by RRTGMP cloud optics - - real(kind_phys), dimension(:,:,:), allocatable :: & - vmr_ref_sw, & ! used by RRTGMP gas optics - kminor_lower_sw, & ! used by RRTGMP gas optics - kminor_upper_sw, & ! used by RRTGMP gas optics - rayl_lower_sw, & ! used by RRTGMP gas optics - rayl_upper_sw, & ! used by RRTGMP gas optics - lut_extice_sw, & ! used by RRTGMP cloud optics - lut_ssaice_sw, & ! used by RRTGMP cloud optics - lut_asyice_sw, & ! used by RRTGMP cloud optics - pade_extliq_sw, & ! used by RRTGMP cloud optics - pade_ssaliq_sw, & ! used by RRTGMP cloud optics - pade_asyliq_sw ! used by RRTGMP cloud optics - real(kind_phys), dimension(:,:,:,:), allocatable :: & - kmajor_sw, & ! used by RRTGMP gas optics - pade_extice_sw, & ! used by RRTGMP cloud optics - pade_ssaice_sw, & ! used by RRTGMP cloud optics - pade_asyice_sw ! used by RRTGMP cloud optics - character(len=32), dimension(:), allocatable :: & - gas_names_sw, & ! used by RRTGMP gas optics - gas_minor_sw, & ! used by RRTGMP gas optics - identifier_minor_sw, & ! used by RRTGMP gas optics - minor_gases_lower_sw, & ! used by RRTGMP gas optics - minor_gases_upper_sw, & ! used by RRTGMP gas optics - scaling_gas_lower_sw, & ! used by RRTGMP gas optics - scaling_gas_upper_sw ! used by RRTGMP gas optics - logical(wl), dimension(:), allocatable :: & - minor_scales_with_density_lower_sw, & ! used by RRTGMP gas optics - minor_scales_with_density_upper_sw, & ! used by RRTGMP gas optics - scale_by_complement_lower_sw, & ! used by RRTGMP gas optics - scale_by_complement_upper_sw ! used by RRTGMP gas optics - ! Dimensions (to be broadcast across all processors) - integer :: & - ntemps_sw, & ! used by RRTGMP gas optics - npress_sw, & ! used by RRTGMP gas optics - nabsorbers_sw, & ! used by RRTGMP gas optics - nextrabsorbers_sw, & ! used by RRTGMP gas optics - nminorabsorbers_sw, & ! used by RRTGMP gas optics - nmixingfracs_sw, & ! used by RRTGMP gas optics - nlayers_sw, & ! used by RRTGMP gas optics - nbnds_sw, & ! used by RRTGMP gas optics - ngpts_sw, & ! used by RRTGMP gas optics - npairs_sw, & ! used by RRTGMP gas optics - nminor_absorber_intervals_lower_sw, & ! used by RRTGMP gas optics - nminor_absorber_intervals_upper_sw, & ! used by RRTGMP gas optics - ncontributors_lower_sw, & ! used by RRTGMP gas optics - ncontributors_upper_sw, & ! used by RRTGMP gas optics - nbandSWcldy_sw, & ! used by RRTGMP cloud optics - nsize_liq_sw, & ! used by RRTGMP cloud optics - nsize_ice_sw, & ! used by RRTGMP cloud optics - nsizereg_sw, & ! used by RRTGMP cloud optics - ncoeff_ext_sw, & ! used by RRTGMP cloud optics - ncoeff_ssa_g_sw, & ! used by RRTGMP cloud optics - nbound_sw, & ! used by RRTGMP cloud optics - npairsSWcldy_sw ! used by RRTGMP cloud optics - - ! Local variables - integer :: status,ncid_sw,ncid_sw_clds,dimid,varID,ij,iGas - character(len=264) :: kdist_file, kdist_cldy_file - integer,dimension(:),allocatable :: temp1,temp2,temp3,temp4,temp_log_array1,& - temp_log_array2, temp_log_array3, temp_log_array4 - - ! Initialize - errmsg = '' - errflg = 0 - - ! How are we handling cloud-optics? - rrtmgp_sw_cld_phys = Model%rrtmgp_cld_phys + ! Load gas-optics + call sw_gas_optics_init(Model, mpicomm, mpirank, mpiroot, sw_gas_props, errmsg, errflg) - ! Filenames are set in the gfs_physics_nml (scm/src/GFS_typedefs.F90) - kdist_file = trim(Model%rrtmgp_root)//trim(Model%kdist_sw_file_gas) - kdist_cldy_file = trim(Model%rrtmgp_root)//trim(Model%kdist_sw_file_clouds) - - ! Read dimensions for k-distribution fields (only on master processor(0)) - if (mpirank .eq. mpiroot) then - if(nf90_open(trim(kdist_file), NF90_WRITE, ncid_sw) .eq. NF90_NOERR) then - status = nf90_inq_dimid(ncid_sw, 'temperature', dimid) - status = nf90_inquire_dimension(ncid_sw, dimid, len=ntemps_sw) - status = nf90_inq_dimid(ncid_sw, 'pressure', dimid) - status = nf90_inquire_dimension(ncid_sw, dimid, len=npress_sw) - status = nf90_inq_dimid(ncid_sw, 'absorber', dimid) - status = nf90_inquire_dimension(ncid_sw, dimid, len=nabsorbers_sw) - status = nf90_inq_dimid(ncid_sw, 'minor_absorber', dimid) - status = nf90_inquire_dimension(ncid_sw, dimid, len=nminorabsorbers_sw) - status = nf90_inq_dimid(ncid_sw, 'absorber_ext', dimid) - status = nf90_inquire_dimension(ncid_sw, dimid, len=nextrabsorbers_sw) - status = nf90_inq_dimid(ncid_sw, 'mixing_fraction', dimid) - status = nf90_inquire_dimension(ncid_sw, dimid, len=nmixingfracs_sw) - status = nf90_inq_dimid(ncid_sw, 'atmos_layer', dimid) - status = nf90_inquire_dimension(ncid_sw, dimid, len=nlayers_sw) - status = nf90_inq_dimid(ncid_sw, 'bnd', dimid) - status = nf90_inquire_dimension(ncid_sw, dimid, len=nbnds_sw) - status = nf90_inq_dimid(ncid_sw, 'gpt', dimid) - status = nf90_inquire_dimension(ncid_sw, dimid, len=ngpts_sw) - status = nf90_inq_dimid(ncid_sw, 'pair', dimid) - status = nf90_inquire_dimension(ncid_sw, dimid, len=npairs_sw) - status = nf90_inq_dimid(ncid_sw, 'contributors_lower', dimid) - status = nf90_inquire_dimension(ncid_sw, dimid, len=ncontributors_lower_sw) - status = nf90_inq_dimid(ncid_sw, 'contributors_upper', dimid) - status = nf90_inquire_dimension(ncid_sw, dimid, len=ncontributors_upper_sw) - status = nf90_inq_dimid(ncid_sw, 'minor_absorber_intervals_lower', dimid) - status = nf90_inquire_dimension(ncid_sw, dimid, len=nminor_absorber_intervals_lower_sw) - status = nf90_inq_dimid(ncid_sw, 'minor_absorber_intervals_upper', dimid) - status = nf90_inquire_dimension(ncid_sw, dimid, len=nminor_absorber_intervals_upper_sw) - status = nf90_close(ncid_sw) - endif + ! Load cloud optics + if (Model%rrtmgp_cld_optics .gt. 0) then + call sw_cloud_optics_init(Model, mpicomm, mpirank, mpiroot, sw_cloud_props, errmsg, errflg) endif - - ! Broadcast dimensions to all processors -#ifdef MPI - call MPI_BCAST(ntemps_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(npress_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(nabsorbers_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(nminorabsorbers_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(nextraabsorbers_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(nmixingfracs_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(nlayers_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(nbnds_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(ngpts_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(npairs_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(ncontributors_lower_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(ncontributors_upper_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(nminor_absorber_intervals_lower_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(nminor_absorber_intervals_upper_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) -#endif - - ! Allocate space for arrays - allocate(gas_names_sw(nabsorbers_sw)) - allocate(scaling_gas_lower_sw(nminor_absorber_intervals_lower_sw)) - allocate(scaling_gas_upper_sw(nminor_absorber_intervals_upper_sw)) - allocate(gas_minor_sw(nminorabsorbers_sw)) - allocate(identifier_minor_sw(nminorabsorbers_sw)) - allocate(minor_gases_lower_sw(nminor_absorber_intervals_lower_sw)) - allocate(minor_gases_upper_sw(nminor_absorber_intervals_upper_sw)) - allocate(minor_limits_gpt_lower_sw(npairs_sw,nminor_absorber_intervals_lower_sw)) - allocate(minor_limits_gpt_upper_sw(npairs_sw,nminor_absorber_intervals_upper_sw)) - allocate(band2gpt_sw(2,nbnds_sw)) - allocate(key_species_sw(2,nlayers_sw,nbnds_sw)) - allocate(band_lims_sw(2,nbnds_sw)) - allocate(press_ref_sw(npress_sw)) - allocate(temp_ref_sw(ntemps_sw)) - allocate(vmr_ref_sw(nlayers_sw, nextrabsorbers_sw, ntemps_sw)) - allocate(kminor_lower_sw(ncontributors_lower_sw, nmixingfracs_sw, ntemps_sw)) - allocate(kmajor_sw(ngpts_sw, nmixingfracs_sw, npress_sw+1, ntemps_sw)) - allocate(kminor_start_lower_sw(nminor_absorber_intervals_lower_sw)) - allocate(kminor_upper_sw(ncontributors_upper_sw, nmixingfracs_sw, ntemps_sw)) - allocate(kminor_start_upper_sw(nminor_absorber_intervals_upper_sw)) - allocate(minor_scales_with_density_lower_sw(nminor_absorber_intervals_lower_sw)) - allocate(minor_scales_with_density_upper_sw(nminor_absorber_intervals_upper_sw)) - allocate(scale_by_complement_lower_sw(nminor_absorber_intervals_lower_sw)) - allocate(scale_by_complement_upper_sw(nminor_absorber_intervals_upper_sw)) - allocate(rayl_upper_sw(ngpts_sw, nmixingfracs_sw, ntemps_sw)) - allocate(rayl_lower_sw(ngpts_sw, nmixingfracs_sw, ntemps_sw)) - allocate(solar_source_sw(ngpts_sw)) - allocate(temp1(nminor_absorber_intervals_lower_sw)) - allocate(temp2(nminor_absorber_intervals_upper_sw)) - allocate(temp3(nminor_absorber_intervals_lower_sw)) - allocate(temp4(nminor_absorber_intervals_upper_sw)) - - ! On master processor, read in fields, broadcast to all processors - if (mpirank .eq. mpiroot) then - ! Read in fields from file - if(nf90_open(trim(kdist_file), NF90_WRITE, ncid_sw) .eq. NF90_NOERR) then - status = nf90_inq_varid(ncid_sw,'gas_names',varID) - status = nf90_get_var(ncid_sw,varID,gas_names_sw) - ! - status = nf90_inq_varid(ncid_sw,'scaling_gas_lower',varID) - status = nf90_get_var(ncid_sw,varID,scaling_gas_lower_sw) - ! - status = nf90_inq_varid(ncid_sw,'scaling_gas_upper',varID) - status = nf90_get_var(ncid_sw,varID,scaling_gas_upper_sw) - ! - status = nf90_inq_varid(ncid_sw,'gas_minor',varID) - status = nf90_get_var(ncid_sw,varID,gas_minor_sw) - ! - status = nf90_inq_varid(ncid_sw,'identifier_minor',varID) - status = nf90_get_var(ncid_sw,varID,identifier_minor_sw) - ! - status = nf90_inq_varid(ncid_sw,'minor_gases_lower',varID) - status = nf90_get_var(ncid_sw,varID,minor_gases_lower_sw) - ! - status = nf90_inq_varid(ncid_sw,'minor_gases_upper',varID) - status = nf90_get_var(ncid_sw,varID,minor_gases_upper_sw) - ! - status = nf90_inq_varid(ncid_sw,'minor_limits_gpt_lower',varID) - status = nf90_get_var(ncid_sw,varID,minor_limits_gpt_lower_sw) - ! - status = nf90_inq_varid(ncid_sw,'minor_limits_gpt_upper',varID) - status = nf90_get_var(ncid_sw,varID,minor_limits_gpt_upper_sw) - ! - status = nf90_inq_varid(ncid_sw,'bnd_limits_gpt',varID) - status = nf90_get_var(ncid_sw,varID,band2gpt_sw) - ! - status = nf90_inq_varid(ncid_sw,'key_species',varID) - status = nf90_get_var(ncid_sw,varID,key_species_sw) - ! - status = nf90_inq_varid(ncid_sw,'bnd_limits_wavenumber',varID) - status = nf90_get_var(ncid_sw,varID,band_lims_sw) - ! - status = nf90_inq_varid(ncid_sw,'press_ref',varID) - status = nf90_get_var(ncid_sw,varID,press_ref_sw) - ! - status = nf90_inq_varid(ncid_sw,'temp_ref',varID) - status = nf90_get_var(ncid_sw,varID,temp_ref_sw) - ! - status = nf90_inq_varid(ncid_sw,'absorption_coefficient_ref_P',varID) - status = nf90_get_var(ncid_sw,varID,temp_ref_p_sw) - ! - status = nf90_inq_varid(ncid_sw,'absorption_coefficient_ref_T',varID) - status = nf90_get_var(ncid_sw,varID,temp_ref_t_sw) - ! - status = nf90_inq_varid(ncid_sw,'press_ref_trop',varID) - status = nf90_get_var(ncid_sw,varID,press_ref_trop_sw) - ! - status = nf90_inq_varid(ncid_sw,'kminor_lower',varID) - status = nf90_get_var(ncid_sw,varID,kminor_lower_sw) - ! - status = nf90_inq_varid(ncid_sw,'kminor_upper',varID) - status = nf90_get_var(ncid_sw,varID,kminor_upper_sw) - ! - status = nf90_inq_varid(ncid_sw,'vmr_ref',varID) - status = nf90_get_var(ncid_sw,varID,vmr_ref_sw) - ! - status = nf90_inq_varid(ncid_sw,'kmajor',varID) - status = nf90_get_var(ncid_sw,varID,kmajor_sw) - ! - status = nf90_inq_varid(ncid_sw,'kminor_start_lower',varID) - status = nf90_get_var(ncid_sw,varID,kminor_start_lower_sw) - ! - status = nf90_inq_varid(ncid_sw,'kminor_start_upper',varID) - status = nf90_get_var(ncid_sw,varID,kminor_start_upper_sw) - ! - status = nf90_inq_varid(ncid_sw,'solar_source',varID) - status = nf90_get_var(ncid_sw,varID,solar_source_sw) - ! - status = nf90_inq_varid(ncid_sw,'rayl_lower',varID) - status = nf90_get_var(ncid_sw,varID,rayl_lower_sw) - - status = nf90_inq_varid(ncid_sw,'rayl_upper',varID) - status = nf90_get_var(ncid_sw,varID,rayl_upper_sw) - - ! Logical fields are read in as integers and then converted to logicals. - status = nf90_inq_varid(ncid_sw,'minor_scales_with_density_lower',varID) - status = nf90_get_var(ncid_sw,varID,temp1) - minor_scales_with_density_lower_sw(:) = .false. - where(temp1 .eq. 1) minor_scales_with_density_lower_sw(:) = .true. - ! - status = nf90_inq_varid(ncid_sw,'minor_scales_with_density_upper',varID) - status = nf90_get_var(ncid_sw,varID,temp2) - minor_scales_with_density_upper_sw(:) = .false. - where(temp2 .eq. 1) minor_scales_with_density_upper_sw(:) = .true. - ! - status = nf90_inq_varid(ncid_sw,'scale_by_complement_lower',varID) - status = nf90_get_var(ncid_sw,varID,temp3) - scale_by_complement_lower_sw(:) = .false. - where(temp3 .eq. 1) scale_by_complement_lower_sw(:) = .true. - ! - status = nf90_inq_varid(ncid_sw,'scale_by_complement_upper',varID) - status = nf90_get_var(ncid_sw,varID,temp4) - scale_by_complement_upper_sw(:) = .false. - where(temp4 .eq. 1) scale_by_complement_upper_sw(:) = .true. - - ! Close - status = nf90_close(ncid_sw) - endif - endif - - ! Broadcast arrays to all processors -#ifdef MPI - call MPI_BCAST(minor_limits_gpt_upper_sw, size(minor_limits_gpt_upper_sw), MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(minor_limits_gpt_lower_sw, size(minor_limits_gpt_lower_sw), MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(kminor_start_upper_sw, size(kminor_start_upper_sw), MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(kminor_start_lower_sw, size(kminor_start_lower_sw), MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(key_species_sw, size(key_species_sw), MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(band2gpt_sw, size(band2gpt_sw), MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(band_lims_sw, size(band_lims_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(press_ref_sw, size(press_ref_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(temp_ref_sw, size(temp_ref_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(kminor_lower_sw, size(kminor_lower_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(kminor_upper_sw, size(kminor_upper_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(scaling_gas_lower_sw, size(scaling_gas_lower_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(scaling_gas_upper_sw, size(scaling_gas_upper_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(vmr_ref_sw, size(vmr_ref_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(kmajor_sw, size(kmajor_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(temp_ref_p_sw, 1, kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(temp_ref_t_sw, 1, kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(press_ref_trop_sw, 1, kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(solar_source_sw, size(solar_source_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(rayl_lower_sw, size(rayl_lower_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(rayl_upper_sw, size(rayl_upper_sw), kind_phys, mpiroot, mpicomm, ierr) - ! Character arrays - do ij=1,nabsorbers_sw - call MPI_BCAST(gas_names_sw(ij), 32, MPI_CHAR, mpiroot, mpicomm, ierr) - enddo - do ij=1,nminorabsorbers_sw - call MPI_BCAST(gas_minor_sw(ij), 32, MPI_CHAR, mpiroot, mpicomm, ierr) - call MPI_BCAST(identifier_minor_sw(ij), 32, MPI_CHAR, mpiroot, mpicomm, ierr) - enddo - do ij=1,nminor_absorber_intervals_lower_sw - call MPI_BCAST(minor_gases_lower_sw(ij), 32, MPI_CHAR, mpiroot, mpicomm, ierr) - enddo - do ij=1,nminor_absorber_intervals_upper_sw - call MPI_BCAST(minor_gases_upper_sw(ij), 32, MPI_CHAR, mpiroot, mpicomm, ierr) - enddo - ! Logical arrays (First convert to integer-array, then broadcast) - ! - allocate(temp_log_array1(nminor_absorber_intervals_lower_sw)) - where(minor_scales_with_density_lower_sw) - temp_log_array1 = 1 - elsewhere - temp_log_array1 = 0 - end where - call MPI_BCAST(temp_log_array1, size(temp_log_array1), MPI_INTEGER, mpiroot, mpicomm, ierr) - ! - allocate(temp_log_array2(nminor_absorber_intervals_lower_sw)) - where(scale_by_complement_lower_sw) - temp_log_array2 = 1 - elsewhere - temp_log_array2 = 0 - end where - call MPI_BCAST(temp_log_array2, size(temp_log_array2), MPI_INTEGER, mpiroot, mpicomm, ierr) - ! - allocate(temp_log_array3(nminor_absorber_intervals_upper_sw)) - where(minor_scales_with_density_upper_sw) - temp_log_array3 = 1 - elsewhere - temp_log_array3 = 0 - end where - call MPI_BCAST(temp_log_array3, size(temp_log_array3), MPI_INTEGER, mpiroot, mpicomm, ierr) - ! - allocate(temp_log_array4(nminor_absorber_intervals_upper_sw)) - where(scale_by_complement_upper_sw) - temp_log_array4 = 1 - elsewhere - temp_log_array4 = 0 - end where - call MPI_BCAST(temp_log_array4, size(temp_log_array4), MPI_INTEGER, mpiroot, mpicomm, ierr) -#endif - - ! Initialize gas concentrations and gas optics class with data - do iGas=1,nGases - call check_error_msg('rrtmgp_sw_init',gas_concentrations%set_vmr(active_gases(iGas), 0._kind_phys)) - enddo - call check_error_msg('rrtmgp_sw_init',kdist_sw%load(gas_concentrations, gas_names_sw, key_species_sw, band2gpt_sw, & - band_lims_sw, press_ref_sw, press_ref_trop_sw, temp_ref_sw, temp_ref_p_sw, temp_ref_t_sw, & - vmr_ref_sw, kmajor_sw, kminor_lower_sw, kminor_upper_sw, gas_minor_sw,identifier_minor_sw, & - minor_gases_lower_sw, minor_gases_upper_sw, minor_limits_gpt_lower_sw, & - minor_limits_gpt_upper_sw, minor_scales_with_density_lower_sw, & - minor_scales_with_density_upper_sw, scaling_gas_lower_sw, & - scaling_gas_upper_sw, scale_by_complement_lower_sw, & - scale_by_complement_upper_sw, kminor_start_lower_sw, kminor_start_upper_sw, & - solar_source_sw, rayl_lower_sw, rayl_upper_sw)) - - ! Set band index by g-point array - nBandsSW = kdist_sw%get_nband() - nGptsSW = kdist_sw%get_ngpt() - - ! Set initial permutation seed for McICA, initially set to number of G-points - ipsdsw0 = kdist_sw%get_ngpt() - - ! ####################################################################################### - ! If RRTMGP cloud-optics are requested, read tables and broadcast. - ! ####################################################################################### - ! Read dimensions for k-distribution fields (only on master processor(0)) - if (mpirank .eq. mpiroot) then - if(nf90_open(trim(kdist_cldy_file), NF90_WRITE, ncid_sw_clds) == NF90_NOERR) then - status = nf90_inq_dimid(ncid_sw_clds, 'nband', dimid) - status = nf90_inquire_dimension(ncid_sw_clds, dimid, len=nbandSWcldy_sw) - status = nf90_inq_dimid(ncid_sw_clds, 'nrghice', dimid) - status = nf90_inquire_dimension(ncid_sw_clds, dimid, len=nrghice) - status = nf90_inq_dimid(ncid_sw_clds, 'nsize_liq', dimid) - status = nf90_inquire_dimension(ncid_sw_clds, dimid, len=nsize_liq_sw) - status = nf90_inq_dimid(ncid_sw_clds, 'nsize_ice', dimid) - status = nf90_inquire_dimension(ncid_sw_clds, dimid, len=nsize_ice_sw) - status = nf90_inq_dimid(ncid_sw_clds, 'nsizereg', dimid) - status = nf90_inquire_dimension(ncid_sw_clds, dimid, len=nsizereg_sw) - status = nf90_inq_dimid(ncid_sw_clds, 'ncoeff_ext', dimid) - status = nf90_inquire_dimension(ncid_sw_clds, dimid, len=ncoeff_ext_sw) - status = nf90_inq_dimid(ncid_sw_clds, 'ncoeff_ssa_g', dimid) - status = nf90_inquire_dimension(ncid_sw_clds, dimid, len=ncoeff_ssa_g_sw) - status = nf90_inq_dimid(ncid_sw_clds, 'nbound', dimid) - status = nf90_inquire_dimension(ncid_sw_clds, dimid, len=nbound_sw) - status = nf90_inq_dimid(ncid_sw_clds, 'pair', dimid) - status = nf90_inquire_dimension(ncid_sw_clds, dimid, len=npairsSWcldy_sw) - status = nf90_close(ncid_sw_clds) - endif - endif - - ! Broadcast dimensions to all processors -#ifdef MPI - if (rrtmgp_sw_cld_phys .eq. 1 .or. rrtmgp_sw_cld_phys .eq. 2) then - call MPI_BCAST(nbandSWcldy_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(nrghice, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(nsize_liq_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(nsize_ice_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(nsizereg_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(ncoeff_ext_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(ncoeff_ssa_g_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(nbound_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - call MPI_BCAST(npairsSWcldy_sw, 1, MPI_INTEGER, mpiroot, mpicomm, ierr) - endif -#endif - - if (rrtmgp_sw_cld_phys .eq. 1) then - allocate(lut_extliq_sw(nsize_liq_sw, nBandSWcldy_sw)) - allocate(lut_ssaliq_sw(nsize_liq_sw, nBandSWcldy_sw)) - allocate(lut_asyliq_sw(nsize_liq_sw, nBandSWcldy_sw)) - allocate(lut_extice_sw(nsize_ice_sw, nBandSWcldy_sw, nrghice)) - allocate(lut_ssaice_sw(nsize_ice_sw, nBandSWcldy_sw, nrghice)) - allocate(lut_asyice_sw(nsize_ice_sw, nBandSWcldy_sw, nrghice)) - allocate(band_lims_cldy_sw(2, nBandSWcldy_sw)) - endif - if (rrtmgp_sw_cld_phys .eq. 2) then - allocate(pade_extliq_sw(nbandSWcldy_sw, nsizereg_sw, ncoeff_ext_sw )) - allocate(pade_ssaliq_sw(nbandSWcldy_sw, nsizereg_sw, ncoeff_ssa_g_sw)) - allocate(pade_asyliq_sw(nbandSWcldy_sw, nsizereg_sw, ncoeff_ssa_g_sw)) - allocate(pade_extice_sw(nbandSWcldy_sw, nsizereg_sw, ncoeff_ext_sw, nrghice)) - allocate(pade_ssaice_sw(nbandSWcldy_sw, nsizereg_sw, ncoeff_ssa_g_sw, nrghice)) - allocate(pade_asyice_sw(nbandSWcldy_sw, nsizereg_sw, ncoeff_ssa_g_sw, nrghice)) - allocate(pade_sizereg_extliq_sw(nbound_sw)) - allocate(pade_sizereg_ssaliq_sw(nbound_sw)) - allocate(pade_sizereg_asyliq_sw(nbound_sw)) - allocate(pade_sizereg_extice_sw(nbound_sw)) - allocate(pade_sizereg_ssaice_sw(nbound_sw)) - allocate(pade_sizereg_asyice_sw(nbound_sw)) - allocate(band_lims_cldy_sw(2,nbandSWcldy_sw)) - endif - - ! On master processor, allocate space, read in fields, broadcast to all processors - if (mpirank .eq. mpiroot) then - ! - if (rrtmgp_sw_cld_phys .eq. 1) then - ! - if(nf90_open(trim(kdist_cldy_file), NF90_WRITE, ncid_sw_clds) == NF90_NOERR) then - status = nf90_inq_varid(ncid_sw_clds,'radliq_lwr',varID) - status = nf90_get_var(ncid_sw_clds,varID,radliq_lwr_sw) - status = nf90_inq_varid(ncid_sw_clds,'radliq_upr',varID) - status = nf90_get_var(ncid_sw_clds,varID,radliq_upr_sw) - status = nf90_inq_varid(ncid_sw_clds,'radliq_fac',varID) - status = nf90_get_var(ncid_sw_clds,varID,radliq_fac_sw) - status = nf90_inq_varid(ncid_sw_clds,'radice_lwr',varID) - status = nf90_get_var(ncid_sw_clds,varID,radice_lwr_sw) - status = nf90_inq_varid(ncid_sw_clds,'radice_upr',varID) - status = nf90_get_var(ncid_sw_clds,varID,radice_upr_sw) - status = nf90_inq_varid(ncid_sw_clds,'radice_fac',varID) - status = nf90_get_var(ncid_sw_clds,varID,radice_fac_sw) - status = nf90_inq_varid(ncid_sw_clds,'lut_extliq',varID) - status = nf90_get_var(ncid_sw_clds,varID,lut_extliq_sw) - status = nf90_inq_varid(ncid_sw_clds,'lut_ssaliq',varID) - status = nf90_get_var(ncid_sw_clds,varID,lut_ssaliq_sw) - status = nf90_inq_varid(ncid_sw_clds,'lut_asyliq',varID) - status = nf90_get_var(ncid_sw_clds,varID,lut_asyliq_sw) - status = nf90_inq_varid(ncid_sw_clds,'lut_extice',varID) - status = nf90_get_var(ncid_sw_clds,varID,lut_extice_sw) - status = nf90_inq_varid(ncid_sw_clds,'lut_ssaice',varID) - status = nf90_get_var(ncid_sw_clds,varID,lut_ssaice_sw) - status = nf90_inq_varid(ncid_sw_clds,'lut_asyice',varID) - status = nf90_get_var(ncid_sw_clds,varID,lut_asyice_sw) - status = nf90_inq_varid(ncid_sw_clds,'bnd_limits_wavenumber',varID) - status = nf90_get_var(ncid_sw_clds,varID,band_lims_cldy_sw) - status = nf90_close(ncid_sw_clds) - endif - endif - ! - if (rrtmgp_sw_cld_phys .eq. 2) then - ! - if(nf90_open(trim(kdist_cldy_file), NF90_WRITE, ncid_sw_clds) == NF90_NOERR) then - status = nf90_inq_varid(ncid_sw_clds,'radliq_lwr',varID) - status = nf90_get_var(ncid_sw_clds,varID,radliq_lwr_sw) - status = nf90_inq_varid(ncid_sw_clds,'radliq_upr',varID) - status = nf90_get_var(ncid_sw_clds,varID,radliq_upr_sw) - status = nf90_inq_varid(ncid_sw_clds,'radliq_fac',varID) - status = nf90_get_var(ncid_sw_clds,varID,radliq_fac_sw) - status = nf90_inq_varid(ncid_sw_clds,'radice_lwr',varID) - status = nf90_get_var(ncid_sw_clds,varID,radice_lwr_sw) - status = nf90_inq_varid(ncid_sw_clds,'radice_upr',varID) - status = nf90_get_var(ncid_sw_clds,varID,radice_upr_sw) - status = nf90_inq_varid(ncid_sw_clds,'radice_fac',varID) - status = nf90_get_var(ncid_sw_clds,varID,radice_fac_sw) - status = nf90_inq_varid(ncid_sw_clds,'pade_extliq',varID) - status = nf90_get_var(ncid_sw_clds,varID,pade_extliq_sw) - status = nf90_inq_varid(ncid_sw_clds,'pade_ssaliq',varID) - status = nf90_get_var(ncid_sw_clds,varID,pade_ssaliq_sw) - status = nf90_inq_varid(ncid_sw_clds,'pade_asyliq',varID) - status = nf90_get_var(ncid_sw_clds,varID,pade_asyliq_sw) - status = nf90_inq_varid(ncid_sw_clds,'pade_extice',varID) - status = nf90_get_var(ncid_sw_clds,varID,pade_extice_sw) - status = nf90_inq_varid(ncid_sw_clds,'pade_ssaice',varID) - status = nf90_get_var(ncid_sw_clds,varID,pade_ssaice_sw) - status = nf90_inq_varid(ncid_sw_clds,'pade_asyice',varID) - status = nf90_get_var(ncid_sw_clds,varID,pade_asyice_sw) - status = nf90_inq_varid(ncid_sw_clds,'pade_sizreg_extliq',varID) - status = nf90_get_var(ncid_sw_clds,varID,pade_sizereg_extliq_sw) - status = nf90_inq_varid(ncid_sw_clds,'pade_sizreg_ssaliq',varID) - status = nf90_get_var(ncid_sw_clds,varID,pade_sizereg_ssaliq_sw) - status = nf90_inq_varid(ncid_sw_clds,'pade_sizreg_asyliq',varID) - status = nf90_get_var(ncid_sw_clds,varID,pade_sizereg_asyliq_sw) - status = nf90_inq_varid(ncid_sw_clds,'pade_sizreg_extice',varID) - status = nf90_get_var(ncid_sw_clds,varID,pade_sizereg_extice_sw) - status = nf90_inq_varid(ncid_sw_clds,'pade_sizreg_ssaice',varID) - status = nf90_get_var(ncid_sw_clds,varID,pade_sizereg_ssaice_sw) - status = nf90_inq_varid(ncid_sw_clds,'pade_sizreg_asyice',varID) - status = nf90_get_var(ncid_sw_clds,varID,pade_sizereg_asyice_sw) - status = nf90_inq_varid(ncid_sw_clds,'bnd_limits_wavenumber',varID) - status = nf90_get_var(ncid_sw_clds,varID,band_lims_cldy_sw) - status = nf90_close(ncid_sw_clds) - endif - endif - endif - - ! Broadcast arrays to all processors -#ifdef MPI - if (rrtmgp_sw_cld_phys .eq. 1) then - call MPI_BCAST(radliq_lwr_sw, size(radliq_lwr_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(radliq_upr_sw, size(radliq_upr_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(radliq_fac_sw, size(radliq_fac_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(radice_lwr_sw, size(radice_lwr_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(radice_upr_sw, size(radice_upr_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(radice_fac_sw, size(radice_fac_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(lut_extliq_sw, size(lut_extliq_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(lut_ssaliq_sw, size(lut_ssaliq_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(lut_asyliq_sw, size(lut_asyliq_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(lut_extice_sw, size(lut_extice_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(lut_ssaice_sw, size(lut_ssaice_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(lut_asyice_sw, size(lut_asyice_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(band_lims_cldy_sw), size(band_lims_cldy_sw), kind_phys, mpiroot, mpicomm, ierr) - endif - if (rrtmgp_sw_cld_phys .eq. 2) then - call MPI_BCAST(pade_extliq_sw, size(pade_extliq_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(pade_ssaliq_sw, size(pade_ssaliq_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(pade_asyliq_sw, size(pade_asyliq_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(pade_extice_sw, size(pade_extice_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(pade_ssaice_sw, size(pade_ssaice_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(pade_asyice_sw, size(pade_asyice_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(pade_sizereg_extliq_sw), size(pade_sizereg_extliq_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(pade_sizereg_ssaliq_sw), size(pade_sizereg_ssaliq_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(pade_sizereg_asyliq_sw), size(pade_sizereg_asyliq_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(pade_sizereg_extice_sw), size(pade_sizereg_extice_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(pade_sizereg_ssaice_sw), size(pade_sizereg_ssaice_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(pade_sizereg_asyice_sw), size(pade_sizereg_asyice_sw), kind_phys, mpiroot, mpicomm, ierr) - call MPI_BCAST(band_lims_cldy_sw), size(band_lims_cldy_sw), kind_phys, mpiroot, mpicomm, ierr) - endif -#endif - - ! Load tables data for RRTGMP cloud-optics - if (rrtmgp_sw_cld_phys .eq. 1) then - call check_error_msg('rrtmgp_sw_init',kdist_cldy_sw%set_ice_roughness(nrghice)) - call check_error_msg('rrtmgp_sw_init',kdist_cldy_sw%load(band_lims_cldy_sw, radliq_lwr_sw, & - radliq_upr_sw, radliq_fac_sw, radice_lwr_sw, radice_upr_sw, radice_fac_sw, & - lut_extliq_sw, lut_ssaliq_sw, lut_asyliq_sw, lut_extice_sw, lut_ssaice_sw, & - lut_asyice_sw)) - endif - if (rrtmgp_sw_cld_phys .eq. 2) then - call check_error_msg('rrtmgp_sw_init',kdist_cldy_sw%set_ice_roughness(nrghice)) - call check_error_msg('rrtmgp_sw_init', kdist_cldy_sw%load(band_lims_cldy_sw, pade_extliq_sw, & - pade_ssaliq_sw, pade_asyliq_sw, pade_extice_sw, pade_ssaice_sw, pade_asyice_sw, & - pade_sizereg_extliq_sw, pade_sizereg_ssaliq_sw, pade_sizereg_asyliq_sw, & - pade_sizereg_extice_sw, pade_sizereg_ssaice_sw, pade_sizereg_asyice_sw)) - endif - end subroutine rrtmgp_sw_init ! ######################################################################################### @@ -674,7 +70,7 @@ end subroutine rrtmgp_sw_init !! | p_lay | air_pressure_at_layer_for_RRTMGP_in_hPa | air pressure layer | hPa | 2 | real | kind_phys | in | F | !! | p_lev | air_pressure_at_interface_for_RRTMGP_in_hPa | air pressure level | hPa | 2 | real | kind_phys | in | F | !! | t_lay | air_temperature_at_layer_for_RRTMGP | air temperature layer | K | 2 | real | kind_phys | in | F | -!! | kdist_sw | K_distribution_file_for_RRTMGP_SW_scheme | DDT containing spectral information for RRTMGP SW radiation scheme | DDT | 0 | ty_gas_optics_rrtmgp | | in | F | +!! | sw_gas_props | coefficients_for_sw_gas_optics | DDT containing spectral information for RRTMGP SW radiation scheme | DDT | 0 | ty_gas_optics_rrtmgp | | in | F | !! | optical_props_clds | shortwave_optical_properties_for_cloudy_atmosphere | Fortran DDT containing RRTMGP optical properties | DDT | 0 | ty_optical_props_2str | | in | F | !! | optical_props_aerosol | shortwave_optical_properties_for_aerosols | Fortran DDT containing RRTMGP optical properties | DDT | 0 | ty_optical_props_2str | | in | F | !! | gas_concentrations | Gas_concentrations_for_RRTMGP_suite | DDT containing gas concentrations for RRTMGP radiation scheme | DDT | 0 | ty_gas_concs | | in | F | @@ -694,7 +90,7 @@ end subroutine rrtmgp_sw_init !! | errmsg | ccpp_error_message | error message for error handling in CCPP | none | 0 | character | len=* | out | F | !! | errflg | ccpp_error_flag | error flag for error handling in CCPP | flag | 0 | integer | | out | F | !! - subroutine rrtmgp_sw_run(Model, ncol, kdist_sw, p_lay, t_lay, p_lev, gas_concentrations, & + subroutine rrtmgp_sw_run(Model, ncol, sw_gas_props, p_lay, t_lay, p_lev, gas_concentrations, & optical_props_clds, optical_props_aerosol,& lsswr, sfcalb_nir_dir, sfcalb_nir_dif, cossza, nday, idxday, hsw0, hswb, scmpsw, & fluxUP_allsky, fluxDOWN_allsky, fluxUP_clrsky, fluxDOWN_clrsky, errmsg, errflg) @@ -712,8 +108,8 @@ subroutine rrtmgp_sw_run(Model, ncol, kdist_sw, p_lay, t_lay, p_lev, gas_concent real(kind_phys), dimension(ncol,Model%levs+1), intent(in) :: & p_lev ! Pressure @ model layer-interfaces (hPa) type(ty_gas_optics_rrtmgp),intent(in) :: & - kdist_sw ! DDT containing SW spectral information - real(kind_phys), dimension(kdist_sw%get_nband(),ncol), intent(in) :: & + sw_gas_props ! DDT containing SW spectral information + real(kind_phys), dimension(sw_gas_props%get_nband(),ncol), intent(in) :: & sfcalb_nir_dir, & ! Surface albedo direct (near-IR) (1) sfcalb_nir_dif ! Surface albedo diffuse (near-IR) (1) real(kind_phys), dimension(ncol), intent(in) :: & @@ -739,7 +135,7 @@ subroutine rrtmgp_sw_run(Model, ncol, kdist_sw, p_lay, t_lay, p_lev, gas_concent ! Inputs (optional) (NOTE. We only need the optional arguments to know what fluxes to output, HR's are computed later) real(kind_phys), dimension(ncol,Model%levs), optional, intent(inout) :: & hsw0 ! Clear-sky heating rate (K/sec) - real(kind_phys), dimension(ncol,Model%levs,kdist_sw%get_nband()), intent(inout), optional :: & + real(kind_phys), dimension(ncol,Model%levs,sw_gas_props%get_nband()), intent(inout), optional :: & hswb ! All-sky heating rate, by band (K/sec) ! Outputs (optional) type(cmpfsw_type), dimension(ncol), intent(inout),optional :: & @@ -757,7 +153,7 @@ subroutine rrtmgp_sw_run(Model, ncol, kdist_sw, p_lay, t_lay, p_lev, gas_concent flux_clrsky ! Clear-sky flux (W/m2) real(kind_phys), dimension(nday,Model%levs+1),target :: & fluxSW_up_allsky, fluxSW_up_clrsky, fluxSW_dn_allsky, fluxSW_dn_clrsky - real(kind_phys), dimension(nday,Model%levs+1,kdist_sw%get_nband()),target :: & + real(kind_phys), dimension(nday,Model%levs+1,sw_gas_props%get_nband()),target :: & fluxSWBB_up_allsky, fluxSWBB_dn_allsky real(kind_phys), dimension(ncol,Model%levs) :: vmrTemp logical :: l_ClrSky_HR=.false., l_AllSky_HR_byband=.false., l_scmpsw=.false. @@ -790,20 +186,20 @@ subroutine rrtmgp_sw_run(Model, ncol, kdist_sw, p_lay, t_lay, p_lev, gas_concent ! Subset the cloud and aerosol radiative properties over daylit points. ! Cloud optics [nDay,Model%levs,nBands] - call check_error_msg('rrtmgp_sw_run',optical_props_clds_daylit%alloc_2str(nday, Model%levs, kdist_sw)) + call check_error_msg('rrtmgp_sw_run',optical_props_clds_daylit%alloc_2str(nday, Model%levs, sw_gas_props)) optical_props_clds_daylit%tau = optical_props_clds%tau(idxday,:,:) optical_props_clds_daylit%ssa = optical_props_clds%ssa(idxday,:,:) optical_props_clds_daylit%g = optical_props_clds%g(idxday,:,:) ! Aerosol optics [nDay,Model%levs,nBands] - call check_error_msg('rrtmgp_sw_run',optical_props_aerosol_daylit%alloc_2str(nday, Model%levs, kdist_sw%get_band_lims_wavenumber())) + call check_error_msg('rrtmgp_sw_run',optical_props_aerosol_daylit%alloc_2str(nday, Model%levs, sw_gas_props%get_band_lims_wavenumber())) optical_props_aerosol_daylit%tau = optical_props_aerosol%tau(idxday,:,:) optical_props_aerosol_daylit%ssa = optical_props_aerosol%ssa(idxday,:,:) optical_props_aerosol_daylit%g = optical_props_aerosol%g(idxday,:,:) ! Similarly, subset the gas concentrations. - do iGas=1,nGases + do iGas=1,size(active_gases,1) call check_error_msg('rrtmgp_sw_run',gas_concentrations%get_vmr(trim(active_gases(iGas)),vmrTemp)) - call check_error_msg('rrtmgp_sw_run',gas_concentrations_daylit%set_vmr(active_gases(iGas),vmrTemp(idxday,:))) + call check_error_msg('rrtmgp_sw_run',gas_concentrations_daylit%set_vmr(trim(active_gases(iGas)),vmrTemp(idxday,:))) enddo ! Initialize RRTMGP DDT containing 2D(3D) fluxes @@ -819,7 +215,7 @@ subroutine rrtmgp_sw_run(Model, ncol, kdist_sw, p_lay, t_lay, p_lev, gas_concent ! Call RRTMGP SW scheme call check_error_msg('rrtmgp_sw_run',rte_sw( & - kdist_sw, & ! IN - spectral information + sw_gas_props, & ! IN - spectral information gas_concentrations_daylit, & ! IN - gas concentrations (vmr) p_lay(idxday,1:Model%levs), & ! IN - pressure at layer interfaces (Pa) t_lay(idxday,1:Model%levs), & ! IN - temperature at layer interfaes (K) @@ -841,14 +237,4 @@ end subroutine rrtmgp_sw_run subroutine rrtmgp_sw_finalize() end subroutine rrtmgp_sw_finalize - subroutine check_error_msg(routine_name, error_msg) - character(len=*), intent(in) :: & - error_msg, routine_name - - if(error_msg /= "") then - print*,"ERROR("//trim(routine_name)//"): " - print*,trim(error_msg) - return - end if - end subroutine check_error_msg end module rrtmgp_sw diff --git a/physics/rrtmgp_sw_pre.F90 b/physics/rrtmgp_sw_pre.F90 index 4f3fefa5f..1891cf2b9 100644 --- a/physics/rrtmgp_sw_pre.F90 +++ b/physics/rrtmgp_sw_pre.F90 @@ -27,7 +27,7 @@ end subroutine rrtmgp_sw_pre_init !! | idxday | daytime_points | daytime points | index | 1 | integer | | out | F | !! | tsfg | surface_ground_temperature_for_radiation | surface ground temperature for radiation | K | 1 | real | kind_phys | in | F | !! | tsfa | surface_air_temperature_for_radiation | lowest model layer air temperature for radiation | K | 1 | real | kind_phys | in | F | -!! | kdist_sw | K_distribution_file_for_RRTMGP_SW_scheme | DDT containing spectral information for RRTMGP SW radiation scheme | DDT | 0 | ty_gas_optics_rrtmgp | | in | F | +!! | sw_gas_props | coefficients_for_sw_gas_optics | DDT containing spectral information for RRTMGP SW radiation scheme | DDT | 0 | ty_gas_optics_rrtmgp | | in | F | !! | sfc_alb_nir_dir | surface_shortwave_albedo_near_infrared_direct_in_each_band | surface sw near-infrared direct albedo in each SW band | frac | 2 | real | kind_phys | out | F | !! | sfc_alb_nir_dif | surface_shortwave_albedo_near_infrared_diffuse_in_each_band | surface sw near-infrared diffuse albedo in each SW band | frac | 2 | real | kind_phys | out | F | !! | sfc_alb_uvvis_dir | surface_shortwave_albedo_uv_visible_direct_in_each_band | surface sw uv-visible direct albedo in each SW band | frac | 2 | real | kind_phys | out | F | @@ -36,13 +36,13 @@ end subroutine rrtmgp_sw_pre_init !! | errmsg | ccpp_error_message | error message for error handling in CCPP | none | 0 | character | len=* | out | F | !! | errflg | ccpp_error_flag | error flag for error handling in CCPP | flag | 0 | integer | | out | F | !! - subroutine rrtmgp_sw_pre_run (Model, Grid, Sfcprop, Radtend, im, kdist_sw, & + subroutine rrtmgp_sw_pre_run (Model, Grid, Sfcprop, Radtend, im, sw_gas_props, & nday, idxday, tsfg, tsfa, sfc_alb_nir_dir, sfc_alb_nir_dif, sfc_alb_uvvis_dir, & sfc_alb_uvvis_dif, alb1d, errmsg, errflg) ! Inputs type(ty_gas_optics_rrtmgp),intent(in) :: & - kdist_sw ! RRTMGP DDT containing spectral information for SW calculation + sw_gas_props ! RRTMGP DDT containing spectral information for SW calculation type(GFS_control_type), intent(in) :: Model type(GFS_radtend_type), intent(inout) :: Radtend type(GFS_sfcprop_type), intent(in) :: Sfcprop @@ -54,7 +54,7 @@ subroutine rrtmgp_sw_pre_run (Model, Grid, Sfcprop, Radtend, im, kdist_sw, & real(kind=kind_phys), dimension(size(Grid%xlon,1)), intent(in) :: alb1d ! Outputs - real(kind_phys),dimension(kdist_sw%get_nband(),IM),intent(out) :: & + real(kind_phys),dimension(sw_gas_props%get_nband(),IM),intent(out) :: & sfc_alb_nir_dir, & ! Shortwave surface albedo (nIR-direct) sfc_alb_nir_dif, & ! Shortwave surface albedo (nIR-diffuse) sfc_alb_uvvis_dir, & ! Shortwave surface albedo (uvvis-direct) @@ -100,7 +100,7 @@ subroutine rrtmgp_sw_pre_run (Model, Grid, Sfcprop, Radtend, im, kdist_sw, & endif ! Spread across all SW bands - do iBand=1,kdist_sw%get_nband() + do iBand=1,sw_gas_props%get_nband() sfc_alb_nir_dir(iBand,1:IM) = sfcalb(1:IM,1) sfc_alb_nir_dif(iBand,1:IM) = sfcalb(1:IM,2) sfc_alb_uvvis_dir(iBand,1:IM) = sfcalb(1:IM,3)