Ignore:
Timestamp:
Mar 19, 2024, 3:34:21 PM (2 months ago)
Author:
idelkadi
Message:

Ecrad update in LMDZ / Implementation of Ecrad double call in LMDZ

  • version 1.6.1 (commit 210d7911380f53a788c3cad73b3cf9b4e022ef87)
  • interface routines between lmdz and ecrad grouped in a new "lmdz" directory
  • double call method redesigned so as to go through the Ecrad initialization and configuration part only once for the entire simulation
  • clean-up in the read.F routine: delete unitules arguments
  • modification of default gas model in namelist (default: ECCKD)
File:
1 edited

Legend:

Unmodified
Added
Removed
  • LMDZ6/trunk/libf/phylmd/ecrad/radiation/radiation_mcica_sw.F90

    r4773 r4853  
    1818!   2017-10-23  R. Hogan  Renamed single-character variables
    1919
     20#include "ecrad_config.h"
     21
    2022module radiation_mcica_sw
    2123
     
    119121    ! Total cloud cover output from the cloud generator
    120122    real(jprb) :: total_cloud_cover
     123
     124    ! Temporary storage for more efficient summation
     125#ifdef DWD_REDUCTION_OPTIMIZATIONS
     126    real(jprb), dimension(nlev+1,3) :: sum_aux
     127#else
     128    real(jprb) :: sum_up, sum_dn_diff, sum_dn_dir
     129#endif
    121130
    122131    ! Number of g points
     
    175184       
    176185        ! Sum over g-points to compute and save clear-sky broadband
    177         ! fluxes
    178         flux%sw_up_clear(jcol,:) = sum(flux_up,1)
     186        ! fluxes. Note that the built-in "sum" function is very slow,
     187        ! and before being replaced by the alternatives below
     188        ! accounted for around 40% of the total cost of this routine.
     189#ifdef DWD_REDUCTION_OPTIMIZATIONS
     190        ! Optimized summation for the NEC architecture
     191        sum_aux(:,:) = 0.0_jprb
     192        do jg = 1,ng
     193          do jlev = 1,nlev+1
     194            sum_aux(jlev,1) = sum_aux(jlev,1) + flux_up(jg,jlev)
     195            sum_aux(jlev,2) = sum_aux(jlev,2) + flux_dn_direct(jg,jlev)
     196            sum_aux(jlev,3) = sum_aux(jlev,3) + flux_dn_diffuse(jg,jlev)
     197          end do
     198        end do
     199        flux%sw_up_clear(jcol,:) = sum_aux(:,1)
     200        flux%sw_dn_clear(jcol,:) = sum_aux(:,2) + sum_aux(:,3)
    179201        if (allocated(flux%sw_dn_direct_clear)) then
    180           flux%sw_dn_direct_clear(jcol,:) &
    181                &  = sum(flux_dn_direct,1)
    182           flux%sw_dn_clear(jcol,:) = sum(flux_dn_diffuse,1) &
    183                &  + flux%sw_dn_direct_clear(jcol,:)
    184         else
    185           flux%sw_dn_clear(jcol,:) = sum(flux_dn_diffuse,1) &
    186                &  + sum(flux_dn_direct,1)
     202          flux%sw_dn_direct_clear(jcol,:) = sum_aux(:,2)
    187203        end if
     204#else
     205        ! Optimized summation for the x86-64 architecture
     206        do jlev = 1,nlev+1
     207          sum_up      = 0.0_jprb
     208          sum_dn_diff = 0.0_jprb
     209          sum_dn_dir  = 0.0_jprb
     210          !$omp simd reduction(+:sum_up, sum_dn_diff, sum_dn_dir)
     211          do jg = 1,ng
     212            sum_up      = sum_up      + flux_up(jg,jlev)
     213            sum_dn_diff = sum_dn_diff + flux_dn_diffuse(jg,jlev)
     214            sum_dn_dir  = sum_dn_dir  + flux_dn_direct(jg,jlev)
     215          end do
     216          flux%sw_up_clear(jcol,jlev) = sum_up
     217          flux%sw_dn_clear(jcol,jlev) = sum_dn_diff + sum_dn_dir
     218          if (allocated(flux%sw_dn_direct_clear)) then
     219            flux%sw_dn_direct_clear(jcol,jlev) = sum_dn_dir
     220          end if
     221        end do
     222#endif
     223       
    188224        ! Store spectral downwelling fluxes at surface
    189         flux%sw_dn_diffuse_surf_clear_g(:,jcol) = flux_dn_diffuse(:,nlev+1)
    190         flux%sw_dn_direct_surf_clear_g(:,jcol)  = flux_dn_direct(:,nlev+1)
     225        do jg = 1,ng
     226          flux%sw_dn_diffuse_surf_clear_g(jg,jcol) = flux_dn_diffuse(jg,nlev+1)
     227          flux%sw_dn_direct_surf_clear_g(jg,jcol)  = flux_dn_direct(jg,nlev+1)
     228        end do
    191229
    192230        ! Do cloudy-sky calculation
     
    249287            else
    250288              ! Clear-sky layer: copy over clear-sky values
    251               reflectance(:,jlev) = ref_clear(:,jlev)
    252               transmittance(:,jlev) = trans_clear(:,jlev)
    253               ref_dir(:,jlev) = ref_dir_clear(:,jlev)
    254               trans_dir_diff(:,jlev) = trans_dir_diff_clear(:,jlev)
    255               trans_dir_dir(:,jlev) = trans_dir_dir_clear(:,jlev)
     289              do jg = 1,ng
     290                reflectance(jg,jlev) = ref_clear(jg,jlev)
     291                transmittance(jg,jlev) = trans_clear(jg,jlev)
     292                ref_dir(jg,jlev) = ref_dir_clear(jg,jlev)
     293                trans_dir_diff(jg,jlev) = trans_dir_diff_clear(jg,jlev)
     294                trans_dir_dir(jg,jlev) = trans_dir_dir_clear(jg,jlev)
     295              end do
    256296            end if
    257297          end do
     
    264304         
    265305          ! Store overcast broadband fluxes
    266           flux%sw_up(jcol,:) = sum(flux_up,1)
     306#ifdef DWD_REDUCTION_OPTIMIZATIONS
     307          sum_aux(:,:) = 0.0_jprb
     308          do jg = 1,ng
     309            do jlev = 1,nlev+1
     310              sum_aux(jlev,1) = sum_aux(jlev,1) + flux_up(jg,jlev)
     311              sum_aux(jlev,2) = sum_aux(jlev,2) + flux_dn_direct(jg,jlev)
     312              sum_aux(jlev,3) = sum_aux(jlev,3) + flux_dn_diffuse(jg,jlev)
     313            end do
     314          end do
     315          flux%sw_up(jcol,:) = sum_aux(:,1)
     316          flux%sw_dn(jcol,:) = sum_aux(:,2) + sum_aux(:,3)
    267317          if (allocated(flux%sw_dn_direct)) then
    268             flux%sw_dn_direct(jcol,:) = sum(flux_dn_direct,1)
    269             flux%sw_dn(jcol,:) = sum(flux_dn_diffuse,1) &
    270                  &  + flux%sw_dn_direct(jcol,:)
    271           else
    272             flux%sw_dn(jcol,:) = sum(flux_dn_diffuse,1) &
    273                  &  + sum(flux_dn_direct,1)
     318            flux%sw_dn_direct(jcol,:) = sum_aux(:,2)
    274319          end if
    275 
     320#else
     321          do jlev = 1,nlev+1
     322            sum_up      = 0.0_jprb
     323            sum_dn_diff = 0.0_jprb
     324            sum_dn_dir  = 0.0_jprb
     325            !$omp simd reduction(+:sum_up, sum_dn_diff, sum_dn_dir)
     326            do jg = 1,ng
     327              sum_up      = sum_up      + flux_up(jg,jlev)
     328              sum_dn_diff = sum_dn_diff + flux_dn_diffuse(jg,jlev)
     329              sum_dn_dir  = sum_dn_dir  + flux_dn_direct(jg,jlev)
     330            end do
     331            flux%sw_up(jcol,jlev) = sum_up
     332            flux%sw_dn(jcol,jlev) = sum_dn_diff + sum_dn_dir
     333            if (allocated(flux%sw_dn_direct)) then
     334              flux%sw_dn_direct(jcol,jlev) = sum_dn_dir
     335            end if
     336          end do
     337#endif
     338         
    276339          ! Cloudy flux profiles currently assume completely overcast
    277340          ! skies; perform weighted average with clear-sky profile
    278           flux%sw_up(jcol,:) =  total_cloud_cover *flux%sw_up(jcol,:) &
    279                &  + (1.0_jprb - total_cloud_cover)*flux%sw_up_clear(jcol,:)
    280           flux%sw_dn(jcol,:) =  total_cloud_cover *flux%sw_dn(jcol,:) &
    281                &  + (1.0_jprb - total_cloud_cover)*flux%sw_dn_clear(jcol,:)
    282           if (allocated(flux%sw_dn_direct)) then
    283             flux%sw_dn_direct(jcol,:) = total_cloud_cover *flux%sw_dn_direct(jcol,:) &
    284                  &  + (1.0_jprb - total_cloud_cover)*flux%sw_dn_direct_clear(jcol,:)
    285           end if
     341          do jlev = 1, nlev+1
     342            flux%sw_up(jcol,jlev) =  total_cloud_cover *flux%sw_up(jcol,jlev) &
     343                 &     + (1.0_jprb - total_cloud_cover)*flux%sw_up_clear(jcol,jlev)
     344            flux%sw_dn(jcol,jlev) =  total_cloud_cover *flux%sw_dn(jcol,jlev) &
     345                 &     + (1.0_jprb - total_cloud_cover)*flux%sw_dn_clear(jcol,jlev)
     346            if (allocated(flux%sw_dn_direct)) then
     347              flux%sw_dn_direct(jcol,jlev) = total_cloud_cover *flux%sw_dn_direct(jcol,jlev) &
     348                   &  + (1.0_jprb - total_cloud_cover)*flux%sw_dn_direct_clear(jcol,jlev)
     349            end if
     350          end do
    286351          ! Likewise for surface spectral fluxes
    287           flux%sw_dn_diffuse_surf_g(:,jcol) = flux_dn_diffuse(:,nlev+1)
    288           flux%sw_dn_direct_surf_g(:,jcol)  = flux_dn_direct(:,nlev+1)
    289           flux%sw_dn_diffuse_surf_g(:,jcol) = total_cloud_cover *flux%sw_dn_diffuse_surf_g(:,jcol) &
    290                &     + (1.0_jprb - total_cloud_cover)*flux%sw_dn_diffuse_surf_clear_g(:,jcol)
    291           flux%sw_dn_direct_surf_g(:,jcol) = total_cloud_cover *flux%sw_dn_direct_surf_g(:,jcol) &
    292                &     + (1.0_jprb - total_cloud_cover)*flux%sw_dn_direct_surf_clear_g(:,jcol)
    293          
     352          do jg = 1,ng
     353            flux%sw_dn_diffuse_surf_g(jg,jcol) = flux_dn_diffuse(jg,nlev+1)
     354            flux%sw_dn_direct_surf_g(jg,jcol)  = flux_dn_direct(jg,nlev+1)
     355            flux%sw_dn_diffuse_surf_g(jg,jcol) = total_cloud_cover *flux%sw_dn_diffuse_surf_g(jg,jcol) &
     356                 &                 + (1.0_jprb - total_cloud_cover)*flux%sw_dn_diffuse_surf_clear_g(jg,jcol)
     357            flux%sw_dn_direct_surf_g(jg,jcol)  = total_cloud_cover *flux%sw_dn_direct_surf_g(jg,jcol) &
     358                 &                 + (1.0_jprb - total_cloud_cover)*flux%sw_dn_direct_surf_clear_g(jg,jcol)
     359          end do
     360
    294361        else
    295362          ! No cloud in profile and clear-sky fluxes already
    296363          ! calculated: copy them over
    297           flux%sw_up(jcol,:) = flux%sw_up_clear(jcol,:)
    298           flux%sw_dn(jcol,:) = flux%sw_dn_clear(jcol,:)
    299           if (allocated(flux%sw_dn_direct)) then
    300             flux%sw_dn_direct(jcol,:) = flux%sw_dn_direct_clear(jcol,:)
    301           end if
    302           flux%sw_dn_diffuse_surf_g(:,jcol) = flux%sw_dn_diffuse_surf_clear_g(:,jcol)
    303           flux%sw_dn_direct_surf_g(:,jcol)  = flux%sw_dn_direct_surf_clear_g(:,jcol)
     364          do jlev = 1, nlev+1
     365            flux%sw_up(jcol,jlev) = flux%sw_up_clear(jcol,jlev)
     366            flux%sw_dn(jcol,jlev) = flux%sw_dn_clear(jcol,jlev)
     367            if (allocated(flux%sw_dn_direct)) then
     368              flux%sw_dn_direct(jcol,jlev) = flux%sw_dn_direct_clear(jcol,jlev)
     369            end if
     370          end do
     371          do jg = 1,ng
     372            flux%sw_dn_diffuse_surf_g(jg,jcol) = flux%sw_dn_diffuse_surf_clear_g(jg,jcol)
     373            flux%sw_dn_direct_surf_g(jg,jcol)  = flux%sw_dn_direct_surf_clear_g(jg,jcol)
     374          end do
    304375
    305376        end if ! Cloud is present in profile
     
    307378      else
    308379        ! Set fluxes to zero if sun is below the horizon
    309         flux%sw_up(jcol,:) = 0.0_jprb
    310         flux%sw_dn(jcol,:) = 0.0_jprb
    311         if (allocated(flux%sw_dn_direct)) then
    312           flux%sw_dn_direct(jcol,:) = 0.0_jprb
    313         end if
    314         flux%sw_up_clear(jcol,:) = 0.0_jprb
    315         flux%sw_dn_clear(jcol,:) = 0.0_jprb
    316         if (allocated(flux%sw_dn_direct_clear)) then
    317           flux%sw_dn_direct_clear(jcol,:) = 0.0_jprb
    318         end if
    319         flux%sw_dn_diffuse_surf_g(:,jcol) = 0.0_jprb
    320         flux%sw_dn_direct_surf_g(:,jcol)  = 0.0_jprb
    321         flux%sw_dn_diffuse_surf_clear_g(:,jcol) = 0.0_jprb
    322         flux%sw_dn_direct_surf_clear_g(:,jcol)  = 0.0_jprb
     380        do jlev = 1, nlev+1
     381          flux%sw_up(jcol,jlev) = 0.0_jprb
     382          flux%sw_dn(jcol,jlev) = 0.0_jprb
     383          if (allocated(flux%sw_dn_direct)) then
     384            flux%sw_dn_direct(jcol,jlev) = 0.0_jprb
     385          end if
     386          flux%sw_up_clear(jcol,jlev) = 0.0_jprb
     387          flux%sw_dn_clear(jcol,jlev) = 0.0_jprb
     388          if (allocated(flux%sw_dn_direct_clear)) then
     389            flux%sw_dn_direct_clear(jcol,jlev) = 0.0_jprb
     390          end if
     391        end do
     392        do jg = 1,ng
     393          flux%sw_dn_diffuse_surf_g(jg,jcol) = 0.0_jprb
     394          flux%sw_dn_direct_surf_g(jg,jcol)  = 0.0_jprb
     395          flux%sw_dn_diffuse_surf_clear_g(jg,jcol) = 0.0_jprb
     396          flux%sw_dn_direct_surf_clear_g(jg,jcol)  = 0.0_jprb
     397        end do
    323398      end if ! Sun above horizon
    324399
Note: See TracChangeset for help on using the changeset viewer.