source: palm/trunk/SOURCE/radiation_model_mod.f90 @ 3156

Last change on this file since 3156 was 3156, checked in by knoop, 7 years ago

Bugfix: replaced usage of the pt array with the surf%pt_surface array in radiation model

  • Property svn:keywords set to Id
File size: 402.2 KB
Line 
1!> @file radiation_model_mod.f90
2!------------------------------------------------------------------------------!
3! This file is part of the PALM model system.
4!
5! PALM is free software: you can redistribute it and/or modify it under the
6! terms of the GNU General Public License as published by the Free Software
7! Foundation, either version 3 of the License, or (at your option) any later
8! version.
9!
10! PALM is distributed in the hope that it will be useful, but WITHOUT ANY
11! WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12! A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13!
14! You should have received a copy of the GNU General Public License along with
15! PALM. If not, see <http://www.gnu.org/licenses/>.
16!
17! Copyright 2015-2018 Czech Technical University in Prague
18! Copyright 2015-2018 Institute of Computer Science of the
19!                     Czech Academy of Sciences, Prague
20! Copyright 1997-2018 Leibniz Universitaet Hannover
21!------------------------------------------------------------------------------!
22!
23! Current revisions:
24! ------------------
25!
26!
27! Former revisions:
28! -----------------
29! $Id: radiation_model_mod.f90 3156 2018-07-19 16:30:54Z knoop $
30! Bugfix: replaced usage of the pt array with the surf%pt_surface array
31!
32! 3137 2018-07-17 06:44:21Z maronga
33! String length for trace_names fixed
34!
35! 3127 2018-07-15 08:01:25Z maronga
36! A few pavement parameters updated.
37!
38! 3123 2018-07-12 16:21:53Z suehring
39! Correct working precision for INTEGER number
40!
41! 3122 2018-07-11 21:46:41Z maronga
42! Bugfix: maximum distance for raytracing was set to  -999 m by default,
43! effectively switching off all surface reflections when max_raytracing_dist
44! was not explicitly set in namelist
45!
46! 3117 2018-07-11 09:59:11Z maronga
47! Bugfix: water vapor was not transfered to RRTMG when cloud_physics = .F.
48! Bugfix: changed the calculation of RRTMG boundary conditions (Mohamed Salim)
49! Bugfix: dry residual atmosphere is replaced by standard RRTMG atmosphere
50!
51! 3116 2018-07-10 14:31:58Z suehring
52! Output of long/shortwave radiation at surface
53!
54! 3107 2018-07-06 15:55:51Z suehring
55! Bugfix, missing index for dz
56!
57! 3066 2018-06-12 08:55:55Z Giersch
58! Error message revised
59!
60! 3065 2018-06-12 07:03:02Z Giersch
61! dz was replaced by dz(1), error message concerning vertical stretching was
62! added 
63!
64! 3049 2018-05-29 13:52:36Z Giersch
65! Error messages revised
66!
67! 3045 2018-05-28 07:55:41Z Giersch
68! Error message revised
69!
70! 3026 2018-05-22 10:30:53Z schwenkel
71! Changed the name specific humidity to mixing ratio, since we are computing
72! mixing ratios.
73!
74! 3016 2018-05-09 10:53:37Z Giersch
75! Revised structure of reading svf data according to PALM coding standard:
76! svf_code_field/len and fsvf removed, error messages PA0493 and PA0494 added,
77! allocation status of output arrays checked.
78!
79! 3014 2018-05-09 08:42:38Z maronga
80! Introduced plant canopy height similar to urban canopy height to limit
81! the memory requirement to allocate lad.
82! Deactivated automatic setting of minimum raytracing distance.
83!
84! 3004 2018-04-27 12:33:25Z Giersch
85! Further allocation checks implemented (averaged data will be assigned to fill
86! values if no allocation happened so far)
87!
88! 2995 2018-04-19 12:13:16Z Giersch
89! IF-statement in radiation_init removed so that the calculation of radiative
90! fluxes at model start is done in any case, bugfix in
91! radiation_presimulate_solar_pos (end_time is the sum of end_time and the
92! spinup_time specified in the p3d_file ), list of variables/fields that have
93! to be written out or read in case of restarts has been extended
94!
95! 2977 2018-04-17 10:27:57Z kanani
96! Implement changes from branch radiation (r2948-2971) with minor modifications,
97! plus some formatting.
98! (moh.hefny):
99! - replaced plant_canopy by npcbl to check tree existence to avoid weird
100!   allocation of related arrays (after domain decomposition some domains
101!   contains no trees although plant_canopy (global parameter) is still TRUE).
102! - added a namelist parameter to force RTM settings
103! - enabled the option to switch radiation reflections off
104! - renamed surf_reflections to surface_reflections
105! - removed average_radiation flag from the namelist (now it is implicitly set
106!   in init_3d_model according to RTM)
107! - edited read and write sky view factors and CSF routines to account for
108!   the sub-domains which may not contain any of them
109!
110! 2967 2018-04-13 11:22:08Z raasch
111! bugfix: missing parallel cpp-directives added
112!
113! 2964 2018-04-12 16:04:03Z Giersch
114! Error message PA0491 has been introduced which could be previously found in
115! check_open. The variable numprocs_previous_run is only known in case of
116! initializing_actions == read_restart_data
117!
118! 2963 2018-04-12 14:47:44Z suehring
119! - Introduce index for vegetation/wall, pavement/green-wall and water/window
120!   surfaces, for clearer access of surface fraction, albedo, emissivity, etc. .
121! - Minor bugfix in initialization of albedo for window surfaces
122!
123! 2944 2018-04-03 16:20:18Z suehring
124! Fixed bad commit
125!
126! 2943 2018-04-03 16:17:10Z suehring
127! No read of nsurfl from SVF file since it is calculated in
128! radiation_interaction_init,
129! allocation of arrays in radiation_read_svf only if not yet allocated,
130! update of 2920 revision comment.
131!
132! 2932 2018-03-26 09:39:22Z maronga
133! renamed radiation_par to radiation_parameters
134!
135! 2930 2018-03-23 16:30:46Z suehring
136! Remove default surfaces from radiation model, does not make much sense to
137! apply radiation model without energy-balance solvers; Further, add check for
138! this.
139!
140! 2920 2018-03-22 11:22:01Z kanani
141! - Bugfix: Initialize pcbl array (=-1)
142! RTM version 2.0 (Jaroslav Resler, Pavel Krc, Mohamed Salim):
143! - new major version of radiation interactions
144! - substantially enhanced performance and scalability
145! - processing of direct and diffuse solar radiation separated from reflected
146!   radiation, removed virtual surfaces
147! - new type of sky discretization by azimuth and elevation angles
148! - diffuse radiation processed cumulatively using sky view factor
149! - used precalculated apparent solar positions for direct irradiance
150! - added new 2D raytracing process for processing whole vertical column at once
151!   to increase memory efficiency and decrease number of MPI RMA operations
152! - enabled limiting the number of view factors between surfaces by the distance
153!   and value
154! - fixing issues induced by transferring radiation interactions from
155!   urban_surface_mod to radiation_mod
156! - bugfixes and other minor enhancements
157!
158! 2906 2018-03-19 08:56:40Z Giersch
159! NAMELIST paramter read/write_svf_on_init have been removed, functions
160! check_open and close_file are used now for opening/closing files related to
161! svf data, adjusted unit number and error numbers
162!
163! 2894 2018-03-15 09:17:58Z Giersch
164! Calculations of the index range of the subdomain on file which overlaps with
165! the current subdomain are already done in read_restart_data_mod
166! radiation_read_restart_data was renamed to radiation_rrd_local and
167! radiation_last_actions was renamed to radiation_wrd_local, variable named
168! found has been introduced for checking if restart data was found, reading
169! of restart strings has been moved completely to read_restart_data_mod,
170! radiation_rrd_local is already inside the overlap loop programmed in
171! read_restart_data_mod, the marker *** end rad *** is not necessary anymore,
172! strings and their respective lengths are written out and read now in case of
173! restart runs to get rid of prescribed character lengths (Giersch)
174!
175! 2809 2018-02-15 09:55:58Z suehring
176! Bugfix for gfortran: Replace the function C_SIZEOF with STORAGE_SIZE
177!
178! 2753 2018-01-16 14:16:49Z suehring
179! Tile approach for spectral albedo implemented.
180!
181! 2746 2018-01-15 12:06:04Z suehring
182! Move flag plant canopy to modules
183!
184! 2724 2018-01-05 12:12:38Z maronga
185! Set default of average_radiation to .FALSE.
186!
187! 2723 2018-01-05 09:27:03Z maronga
188! Bugfix in calculation of rad_lw_out (clear-sky). First grid level was used
189! instead of the surface value
190!
191! 2718 2018-01-02 08:49:38Z maronga
192! Corrected "Former revisions" section
193!
194! 2707 2017-12-18 18:34:46Z suehring
195! Changes from last commit documented
196!
197! 2706 2017-12-18 18:33:49Z suehring
198! Bugfix, in average radiation case calculate exner function before using it.
199!
200! 2701 2017-12-15 15:40:50Z suehring
201! Changes from last commit documented
202!
203! 2698 2017-12-14 18:46:24Z suehring
204! Bugfix in get_topography_top_index
205!
206! 2696 2017-12-14 17:12:51Z kanani
207! - Change in file header (GPL part)
208! - Improved reading/writing of SVF from/to file (BM)
209! - Bugfixes concerning RRTMG as well as average_radiation options (M. Salim)
210! - Revised initialization of surface albedo and some minor bugfixes (MS)
211! - Update net radiation after running radiation interaction routine (MS)
212! - Revisions from M Salim included
213! - Adjustment to topography and surface structure (MS)
214! - Initialization of albedo and surface emissivity via input file (MS)
215! - albedo_pars extended (MS)
216!
217! 2604 2017-11-06 13:29:00Z schwenkel
218! bugfix for calculation of effective radius using morrison microphysics
219!
220! 2601 2017-11-02 16:22:46Z scharf
221! added emissivity to namelist
222!
223! 2575 2017-10-24 09:57:58Z maronga
224! Bugfix: calculation of shortwave and longwave albedos for RRTMG swapped
225!
226! 2547 2017-10-16 12:41:56Z schwenkel
227! extended by cloud_droplets option, minor bugfix and correct calculation of
228! cloud droplet number concentration
229!
230! 2544 2017-10-13 18:09:32Z maronga
231! Moved date and time quantitis to separate module date_and_time_mod
232!
233! 2512 2017-10-04 08:26:59Z raasch
234! upper bounds of cross section and 3d output changed from nx+1,ny+1 to nx,ny
235! no output of ghost layer data
236!
237! 2504 2017-09-27 10:36:13Z maronga
238! Updates pavement types and albedo parameters
239!
240! 2328 2017-08-03 12:34:22Z maronga
241! Emissivity can now be set individually for each pixel.
242! Albedo type can be inferred from land surface model.
243! Added default albedo type for bare soil
244!
245! 2318 2017-07-20 17:27:44Z suehring
246! Get topography top index via Function call
247!
248! 2317 2017-07-20 17:27:19Z suehring
249! Improved syntax layout
250!
251! 2298 2017-06-29 09:28:18Z raasch
252! type of write_binary changed from CHARACTER to LOGICAL
253!
254! 2296 2017-06-28 07:53:56Z maronga
255! Added output of rad_sw_out for radiation_scheme = 'constant'
256!
257! 2270 2017-06-09 12:18:47Z maronga
258! Numbering changed (2 timeseries removed)
259!
260! 2249 2017-06-06 13:58:01Z sward
261! Allow for RRTMG runs without humidity/cloud physics
262!
263! 2248 2017-06-06 13:52:54Z sward
264! Error no changed
265!
266! 2233 2017-05-30 18:08:54Z suehring
267!
268! 2232 2017-05-30 17:47:52Z suehring
269! Adjustments to new topography concept
270! Bugfix in read restart
271!
272! 2200 2017-04-11 11:37:51Z suehring
273! Bugfix in call of exchange_horiz_2d and read restart data
274!
275! 2163 2017-03-01 13:23:15Z schwenkel
276! Bugfix in radiation_check_data_output
277!
278! 2157 2017-02-22 15:10:35Z suehring
279! Bugfix in read_restart data
280!
281! 2011 2016-09-19 17:29:57Z kanani
282! Removed CALL of auxiliary SUBROUTINE get_usm_info,
283! flag urban_surface is now defined in module control_parameters.
284!
285! 2007 2016-08-24 15:47:17Z kanani
286! Added calculation of solar directional vector for new urban surface
287! model,
288! accounted for urban_surface model in radiation_check_parameters,
289! correction of comments for zenith angle.
290!
291! 2000 2016-08-20 18:09:15Z knoop
292! Forced header and separation lines into 80 columns
293!
294! 1976 2016-07-27 13:28:04Z maronga
295! Output of 2D/3D/masked data is now directly done within this module. The
296! radiation schemes have been simplified for better usability so that
297! rad_lw_in, rad_lw_out, rad_sw_in, and rad_sw_out are available independent of
298! the radiation code used.
299!
300! 1856 2016-04-13 12:56:17Z maronga
301! Bugfix: allocation of rad_lw_out for radiation_scheme = 'clear-sky'
302!
303! 1853 2016-04-11 09:00:35Z maronga
304! Added routine for radiation_scheme = constant.
305
306! 1849 2016-04-08 11:33:18Z hoffmann
307! Adapted for modularization of microphysics
308!
309! 1826 2016-04-07 12:01:39Z maronga
310! Further modularization.
311!
312! 1788 2016-03-10 11:01:04Z maronga
313! Added new albedo class for pavements / roads.
314!
315! 1783 2016-03-06 18:36:17Z raasch
316! palm-netcdf-module removed in order to avoid a circular module dependency,
317! netcdf-variables moved to netcdf-module, new routine netcdf_handle_error_rad
318! added
319!
320! 1757 2016-02-22 15:49:32Z maronga
321! Added parameter unscheduled_radiation_calls. Bugfix: interpolation of sounding
322! profiles for pressure and temperature above the LES domain.
323!
324! 1709 2015-11-04 14:47:01Z maronga
325! Bugfix: set initial value for rrtm_lwuflx_dt to zero, small formatting
326! corrections
327!
328! 1701 2015-11-02 07:43:04Z maronga
329! Bugfixes: wrong index for output of timeseries, setting of nz_snd_end
330!
331! 1691 2015-10-26 16:17:44Z maronga
332! Added option for spin-up runs without radiation (skip_time_do_radiation). Bugfix
333! in calculation of pressure profiles. Bugfix in calculation of trace gas profiles.
334! Added output of radiative heating rates.
335!
336! 1682 2015-10-07 23:56:08Z knoop
337! Code annotations made doxygen readable
338!
339! 1606 2015-06-29 10:43:37Z maronga
340! Added preprocessor directive __netcdf to allow for compiling without netCDF.
341! Note, however, that RRTMG cannot be used without netCDF.
342!
343! 1590 2015-05-08 13:56:27Z maronga
344! Bugfix: definition of character strings requires same length for all elements
345!
346! 1587 2015-05-04 14:19:01Z maronga
347! Added albedo class for snow
348!
349! 1585 2015-04-30 07:05:52Z maronga
350! Added support for RRTMG
351!
352! 1571 2015-03-12 16:12:49Z maronga
353! Added missing KIND attribute. Removed upper-case variable names
354!
355! 1551 2015-03-03 14:18:16Z maronga
356! Added support for data output. Various variables have been renamed. Added
357! interface for different radiation schemes (currently: clear-sky, constant, and
358! RRTM (not yet implemented).
359!
360! 1496 2014-12-02 17:25:50Z maronga
361! Initial revision
362!
363!
364! Description:
365! ------------
366!> Radiation models and interfaces
367!> @todo Replace dz(1) appropriatly to account for grid stretching
368!> @todo move variable definitions used in radiation_init only to the subroutine
369!>       as they are no longer required after initialization.
370!> @todo Output of full column vertical profiles used in RRTMG
371!> @todo Output of other rrtm arrays (such as volume mixing ratios)
372!> @todo Adapt for use with topography
373!> @todo Optimize radiation_tendency routines
374!>
375!> @note Many variables have a leading dummy dimension (0:0) in order to
376!>       match the assume-size shape expected by the RRTMG model.
377!------------------------------------------------------------------------------!
378 MODULE radiation_model_mod
379 
380    USE arrays_3d,                                                             &
381        ONLY:  dzw, hyp, nc, pt, q, ql, zu, zw
382
383    USE calc_mean_profile_mod,                                                 &
384        ONLY:  calc_mean_profile
385
386    USE cloud_parameters,                                                      &
387        ONLY:  cp, l_d_cp, l_v, r_d, rho_l
388
389    USE constants,                                                             &
390        ONLY:  pi
391
392    USE control_parameters,                                                    &
393        ONLY:  cloud_droplets, cloud_physics, coupling_char, dz, g,            &
394               humidity,                                                       &
395               initializing_actions, io_blocks, io_group,                      &
396               latitude, longitude, large_scale_forcing, lsf_surf,             &
397               message_string, microphysics_morrison, plant_canopy, pt_surface,&
398               rho_surface, surface_pressure, time_since_reference_point,      &
399               urban_surface, land_surface, end_time, spinup_time, dt_spinup
400
401    USE cpulog,                                                                &
402        ONLY:  cpu_log, log_point, log_point_s
403
404    USE grid_variables,                                                        &
405         ONLY:  ddx, ddy, dx, dy 
406
407    USE date_and_time_mod,                                                     &
408        ONLY:  calc_date_and_time, d_hours_day, d_seconds_hour, day_of_year,   &
409               d_seconds_year, day_of_year_init, time_utc_init, time_utc
410
411    USE indices,                                                               &
412        ONLY:  nnx, nny, nx, nxl, nxlg, nxr, nxrg, ny, nyn, nyng, nys, nysg,   &
413               nzb, nzt
414
415    USE, INTRINSIC :: iso_c_binding
416
417    USE kinds
418
419    USE microphysics_mod,                                                      &
420        ONLY:  na_init, nc_const, sigma_gc
421
422#if defined ( __netcdf )
423    USE NETCDF
424#endif
425
426    USE netcdf_data_input_mod,                                                 &
427        ONLY:  albedo_type_f, albedo_pars_f, building_type_f, pavement_type_f, &
428               vegetation_type_f, water_type_f
429
430    USE plant_canopy_model_mod,                                                &
431        ONLY:  lad_s, pc_heating_rate, pc_transpiration_rate
432
433    USE pegrid
434
435#if defined ( __rrtmg )
436    USE parrrsw,                                                               &
437        ONLY:  naerec, nbndsw
438
439    USE parrrtm,                                                               &
440        ONLY:  nbndlw
441
442    USE rrtmg_lw_init,                                                         &
443        ONLY:  rrtmg_lw_ini
444
445    USE rrtmg_sw_init,                                                         &
446        ONLY:  rrtmg_sw_ini
447
448    USE rrtmg_lw_rad,                                                          &
449        ONLY:  rrtmg_lw
450
451    USE rrtmg_sw_rad,                                                          &
452        ONLY:  rrtmg_sw
453#endif
454    USE statistics,                                                            &
455        ONLY:  hom
456
457    USE surface_mod,                                                           &
458        ONLY:  get_topography_top_index, get_topography_top_index_ji,          &
459               ind_pav_green, ind_veg_wall, ind_wat_win,                       &
460               surf_lsm_h, surf_lsm_v, surf_type, surf_usm_h, surf_usm_v
461
462    IMPLICIT NONE
463
464    CHARACTER(10) :: radiation_scheme = 'clear-sky' ! 'constant', 'clear-sky', or 'rrtmg'
465
466!
467!-- Predefined Land surface classes (albedo_type) after Briegleb (1992)
468    CHARACTER(37), DIMENSION(0:33), PARAMETER :: albedo_type_name = (/      &
469                                   'user defined                         ', & !  0
470                                   'ocean                                ', & !  1
471                                   'mixed farming, tall grassland        ', & !  2
472                                   'tall/medium grassland                ', & !  3
473                                   'evergreen shrubland                  ', & !  4
474                                   'short grassland/meadow/shrubland     ', & !  5
475                                   'evergreen needleleaf forest          ', & !  6
476                                   'mixed deciduous evergreen forest     ', & !  7
477                                   'deciduous forest                     ', & !  8
478                                   'tropical evergreen broadleaved forest', & !  9
479                                   'medium/tall grassland/woodland       ', & ! 10
480                                   'desert, sandy                        ', & ! 11
481                                   'desert, rocky                        ', & ! 12
482                                   'tundra                               ', & ! 13
483                                   'land ice                             ', & ! 14
484                                   'sea ice                              ', & ! 15
485                                   'snow                                 ', & ! 16
486                                   'bare soil                            ', & ! 17
487                                   'asphalt/concrete mix                 ', & ! 18
488                                   'asphalt (asphalt concrete)           ', & ! 19
489                                   'concrete (Portland concrete)         ', & ! 20
490                                   'sett                                 ', & ! 21
491                                   'paving stones                        ', & ! 22
492                                   'cobblestone                          ', & ! 23
493                                   'metal                                ', & ! 24
494                                   'wood                                 ', & ! 25
495                                   'gravel                               ', & ! 26
496                                   'fine gravel                          ', & ! 27
497                                   'pebblestone                          ', & ! 28
498                                   'woodchips                            ', & ! 29
499                                   'tartan (sports)                      ', & ! 30
500                                   'artifical turf (sports)              ', & ! 31
501                                   'clay (sports)                        ', & ! 32
502                                   'building (dummy)                     '  & ! 33
503                                                         /)
504
505    INTEGER(iwp) :: albedo_type  = 9999999, & !< Albedo surface type
506                    dots_rad     = 0          !< starting index for timeseries output
507
508    LOGICAL ::  unscheduled_radiation_calls = .TRUE., & !< flag parameter indicating whether additional calls of the radiation code are allowed
509                constant_albedo = .FALSE.,            & !< flag parameter indicating whether the albedo may change depending on zenith
510                force_radiation_call = .FALSE.,       & !< flag parameter for unscheduled radiation calls
511                lw_radiation = .TRUE.,                & !< flag parameter indicating whether longwave radiation shall be calculated
512                radiation = .FALSE.,                  & !< flag parameter indicating whether the radiation model is used
513                sun_up    = .TRUE.,                   & !< flag parameter indicating whether the sun is up or down
514                sw_radiation = .TRUE.,                & !< flag parameter indicating whether shortwave radiation shall be calculated
515                sun_direction = .FALSE.,              & !< flag parameter indicating whether solar direction shall be calculated
516                average_radiation = .FALSE.,          & !< flag to set the calculation of radiation averaging for the domain
517                radiation_interactions = .FALSE.,     & !< flag to activiate RTM (TRUE only if vertical urban/land surface and trees exist)
518                surface_reflections = .TRUE.,         & !< flag to switch the calculation of radiation interaction between surfaces.
519                                                        !< When it switched off, only the effect of buildings and trees shadow will
520                                                        !< will be considered. However fewer SVFs are expected.
521                radiation_interactions_on = .TRUE.      !< namelist flag to force RTM activiation regardless to vertical urban/land surface and trees
522
523
524    REAL(wp), PARAMETER :: sigma_sb       = 5.67037321E-8_wp,       & !< Stefan-Boltzmann constant
525                           solar_constant = 1368.0_wp                 !< solar constant at top of atmosphere
526
527    REAL(wp) :: albedo = 9999999.9_wp,           & !< NAMELIST alpha
528                albedo_lw_dif = 9999999.9_wp,    & !< NAMELIST aldif
529                albedo_lw_dir = 9999999.9_wp,    & !< NAMELIST aldir
530                albedo_sw_dif = 9999999.9_wp,    & !< NAMELIST asdif
531                albedo_sw_dir = 9999999.9_wp,    & !< NAMELIST asdir
532                decl_1,                          & !< declination coef. 1
533                decl_2,                          & !< declination coef. 2
534                decl_3,                          & !< declination coef. 3
535                dt_radiation = 0.0_wp,           & !< radiation model timestep
536                emissivity = 9999999.9_wp,       & !< NAMELIST surface emissivity
537                lon = 0.0_wp,                    & !< longitude in radians
538                lat = 0.0_wp,                    & !< latitude in radians
539                net_radiation = 0.0_wp,          & !< net radiation at surface
540                skip_time_do_radiation = 0.0_wp, & !< Radiation model is not called before this time
541                sky_trans,                       & !< sky transmissivity
542                time_radiation = 0.0_wp            !< time since last call of radiation code
543
544
545    REAL(wp), DIMENSION(0:0) ::  zenith,         & !< cosine of solar zenith angle
546                                 sun_dir_lat,    & !< solar directional vector in latitudes
547                                 sun_dir_lon       !< solar directional vector in longitudes
548
549    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  rad_net_av       !< average of net radiation (rad_net) at surface
550    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  rad_lw_in_xy_av  !< average of incoming longwave radiation at surface
551    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  rad_lw_out_xy_av !< average of outgoing longwave radiation at surface
552    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  rad_sw_in_xy_av  !< average of incoming shortwave radiation at surface
553    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  rad_sw_out_xy_av !< average of outgoing shortwave radiation at surface
554!
555!-- Land surface albedos for solar zenith angle of 60° after Briegleb (1992)     
556!-- (shortwave, longwave, broadband):   sw,      lw,      bb,
557    REAL(wp), DIMENSION(0:2,1:33), PARAMETER :: albedo_pars = RESHAPE( (/& 
558                                   0.06_wp, 0.06_wp, 0.06_wp,            & !  1
559                                   0.09_wp, 0.28_wp, 0.19_wp,            & !  2
560                                   0.11_wp, 0.33_wp, 0.23_wp,            & !  3
561                                   0.11_wp, 0.33_wp, 0.23_wp,            & !  4
562                                   0.14_wp, 0.34_wp, 0.25_wp,            & !  5
563                                   0.06_wp, 0.22_wp, 0.14_wp,            & !  6
564                                   0.06_wp, 0.27_wp, 0.17_wp,            & !  7
565                                   0.06_wp, 0.31_wp, 0.19_wp,            & !  8
566                                   0.06_wp, 0.22_wp, 0.14_wp,            & !  9
567                                   0.06_wp, 0.28_wp, 0.18_wp,            & ! 10
568                                   0.35_wp, 0.51_wp, 0.43_wp,            & ! 11
569                                   0.24_wp, 0.40_wp, 0.32_wp,            & ! 12
570                                   0.10_wp, 0.27_wp, 0.19_wp,            & ! 13
571                                   0.90_wp, 0.65_wp, 0.77_wp,            & ! 14
572                                   0.90_wp, 0.65_wp, 0.77_wp,            & ! 15
573                                   0.95_wp, 0.70_wp, 0.82_wp,            & ! 16
574                                   0.08_wp, 0.08_wp, 0.08_wp,            & ! 17
575                                   0.17_wp, 0.17_wp, 0.17_wp,            & ! 18
576                                   0.17_wp, 0.17_wp, 0.17_wp,            & ! 19
577                                   0.30_wp, 0.30_wp, 0.30_wp,            & ! 20
578                                   0.17_wp, 0.17_wp, 0.17_wp,            & ! 21
579                                   0.17_wp, 0.17_wp, 0.17_wp,            & ! 22
580                                   0.17_wp, 0.17_wp, 0.17_wp,            & ! 23
581                                   0.17_wp, 0.17_wp, 0.17_wp,            & ! 24
582                                   0.17_wp, 0.17_wp, 0.17_wp,            & ! 25
583                                   0.17_wp, 0.17_wp, 0.17_wp,            & ! 26
584                                   0.17_wp, 0.17_wp, 0.17_wp,            & ! 27
585                                   0.17_wp, 0.17_wp, 0.17_wp,            & ! 28
586                                   0.17_wp, 0.17_wp, 0.17_wp,            & ! 29
587                                   0.17_wp, 0.17_wp, 0.17_wp,            & ! 30
588                                   0.17_wp, 0.17_wp, 0.17_wp,            & ! 31
589                                   0.17_wp, 0.17_wp, 0.17_wp,            & ! 32
590                                   0.17_wp, 0.17_wp, 0.17_wp             & ! 33
591                                 /), (/ 3, 33 /) )
592
593    REAL(wp), DIMENSION(:,:,:), ALLOCATABLE, TARGET :: &
594                        rad_lw_cs_hr,                  & !< longwave clear sky radiation heating rate (K/s)
595                        rad_lw_cs_hr_av,               & !< average of rad_lw_cs_hr
596                        rad_lw_hr,                     & !< longwave radiation heating rate (K/s)
597                        rad_lw_hr_av,                  & !< average of rad_sw_hr
598                        rad_lw_in,                     & !< incoming longwave radiation (W/m2)
599                        rad_lw_in_av,                  & !< average of rad_lw_in
600                        rad_lw_out,                    & !< outgoing longwave radiation (W/m2)
601                        rad_lw_out_av,                 & !< average of rad_lw_out
602                        rad_sw_cs_hr,                  & !< shortwave clear sky radiation heating rate (K/s)
603                        rad_sw_cs_hr_av,               & !< average of rad_sw_cs_hr
604                        rad_sw_hr,                     & !< shortwave radiation heating rate (K/s)
605                        rad_sw_hr_av,                  & !< average of rad_sw_hr
606                        rad_sw_in,                     & !< incoming shortwave radiation (W/m2)
607                        rad_sw_in_av,                  & !< average of rad_sw_in
608                        rad_sw_out,                    & !< outgoing shortwave radiation (W/m2)
609                        rad_sw_out_av                    !< average of rad_sw_out
610
611
612!
613!-- Variables and parameters used in RRTMG only
614#if defined ( __rrtmg )
615    CHARACTER(LEN=12) :: rrtm_input_file = "RAD_SND_DATA" !< name of the NetCDF input file (sounding data)
616
617
618!
619!-- Flag parameters for RRTMGS (should not be changed)
620    INTEGER(iwp), PARAMETER :: rrtm_idrv     = 1, & !< flag for longwave upward flux calculation option (0,1)
621                               rrtm_inflglw  = 2, & !< flag for lw cloud optical properties (0,1,2)
622                               rrtm_iceflglw = 0, & !< flag for lw ice particle specifications (0,1,2,3)
623                               rrtm_liqflglw = 1, & !< flag for lw liquid droplet specifications
624                               rrtm_inflgsw  = 2, & !< flag for sw cloud optical properties (0,1,2)
625                               rrtm_iceflgsw = 0, & !< flag for sw ice particle specifications (0,1,2,3)
626                               rrtm_liqflgsw = 1    !< flag for sw liquid droplet specifications
627
628!
629!-- The following variables should be only changed with care, as this will
630!-- require further setting of some variables, which is currently not
631!-- implemented (aerosols, ice phase).
632    INTEGER(iwp) :: nzt_rad,           & !< upper vertical limit for radiation calculations
633                    rrtm_icld = 0,     & !< cloud flag (0: clear sky column, 1: cloudy column)
634                    rrtm_iaer = 0        !< aerosol option flag (0: no aerosol layers, for lw only: 6 (requires setting of rrtm_sw_ecaer), 10: one or more aerosol layers (not implemented)
635
636    INTEGER(iwp) :: nc_stat !< local variable for storin the result of netCDF calls for error message handling
637
638    LOGICAL :: snd_exists = .FALSE.      !< flag parameter to check whether a user-defined input files exists
639
640    REAL(wp), PARAMETER :: mol_mass_air_d_wv = 1.607793_wp !< molecular weight dry air / water vapor
641
642    REAL(wp), DIMENSION(:), ALLOCATABLE :: hyp_snd,     & !< hypostatic pressure from sounding data (hPa)
643                                           rrtm_tsfc,   & !< dummy array for storing surface temperature
644                                           t_snd          !< actual temperature from sounding data (hPa)
645
646    REAL(wp), DIMENSION(:,:), ALLOCATABLE :: rrtm_ccl4vmr,   & !< CCL4 volume mixing ratio (g/mol)
647                                             rrtm_cfc11vmr,  & !< CFC11 volume mixing ratio (g/mol)
648                                             rrtm_cfc12vmr,  & !< CFC12 volume mixing ratio (g/mol)
649                                             rrtm_cfc22vmr,  & !< CFC22 volume mixing ratio (g/mol)
650                                             rrtm_ch4vmr,    & !< CH4 volume mixing ratio
651                                             rrtm_cicewp,    & !< in-cloud ice water path (g/m²)
652                                             rrtm_cldfr,     & !< cloud fraction (0,1)
653                                             rrtm_cliqwp,    & !< in-cloud liquid water path (g/m²)
654                                             rrtm_co2vmr,    & !< CO2 volume mixing ratio (g/mol)
655                                             rrtm_emis,      & !< surface emissivity (0-1) 
656                                             rrtm_h2ovmr,    & !< H2O volume mixing ratio
657                                             rrtm_n2ovmr,    & !< N2O volume mixing ratio
658                                             rrtm_o2vmr,     & !< O2 volume mixing ratio
659                                             rrtm_o3vmr,     & !< O3 volume mixing ratio
660                                             rrtm_play,      & !< pressure layers (hPa, zu-grid)
661                                             rrtm_plev,      & !< pressure layers (hPa, zw-grid)
662                                             rrtm_reice,     & !< cloud ice effective radius (microns)
663                                             rrtm_reliq,     & !< cloud water drop effective radius (microns)
664                                             rrtm_tlay,      & !< actual temperature (K, zu-grid)
665                                             rrtm_tlev,      & !< actual temperature (K, zw-grid)
666                                             rrtm_lwdflx,    & !< RRTM output of incoming longwave radiation flux (W/m2)
667                                             rrtm_lwdflxc,   & !< RRTM output of outgoing clear sky longwave radiation flux (W/m2)
668                                             rrtm_lwuflx,    & !< RRTM output of outgoing longwave radiation flux (W/m2)
669                                             rrtm_lwuflxc,   & !< RRTM output of incoming clear sky longwave radiation flux (W/m2)
670                                             rrtm_lwuflx_dt, & !< RRTM output of incoming clear sky longwave radiation flux (W/m2)
671                                             rrtm_lwuflxc_dt,& !< RRTM output of outgoing clear sky longwave radiation flux (W/m2)
672                                             rrtm_lwhr,      & !< RRTM output of longwave radiation heating rate (K/d)
673                                             rrtm_lwhrc,     & !< RRTM output of incoming longwave clear sky radiation heating rate (K/d)
674                                             rrtm_swdflx,    & !< RRTM output of incoming shortwave radiation flux (W/m2)
675                                             rrtm_swdflxc,   & !< RRTM output of outgoing clear sky shortwave radiation flux (W/m2)
676                                             rrtm_swuflx,    & !< RRTM output of outgoing shortwave radiation flux (W/m2)
677                                             rrtm_swuflxc,   & !< RRTM output of incoming clear sky shortwave radiation flux (W/m2)
678                                             rrtm_swhr,      & !< RRTM output of shortwave radiation heating rate (K/d)
679                                             rrtm_swhrc        !< RRTM output of incoming shortwave clear sky radiation heating rate (K/d)
680
681
682    REAL(wp), DIMENSION(1) ::                rrtm_aldif,     & !< surface albedo for longwave diffuse radiation
683                                             rrtm_aldir,     & !< surface albedo for longwave direct radiation
684                                             rrtm_asdif,     & !< surface albedo for shortwave diffuse radiation
685                                             rrtm_asdir        !< surface albedo for shortwave direct radiation
686
687!
688!-- Definition of arrays that are currently not used for calling RRTMG (due to setting of flag parameters)
689    REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  rad_lw_cs_in,   & !< incoming clear sky longwave radiation (W/m2) (not used)
690                                                rad_lw_cs_out,  & !< outgoing clear sky longwave radiation (W/m2) (not used)
691                                                rad_sw_cs_in,   & !< incoming clear sky shortwave radiation (W/m2) (not used)
692                                                rad_sw_cs_out,  & !< outgoing clear sky shortwave radiation (W/m2) (not used)
693                                                rrtm_lw_tauaer, & !< lw aerosol optical depth
694                                                rrtm_lw_taucld, & !< lw in-cloud optical depth
695                                                rrtm_sw_taucld, & !< sw in-cloud optical depth
696                                                rrtm_sw_ssacld, & !< sw in-cloud single scattering albedo
697                                                rrtm_sw_asmcld, & !< sw in-cloud asymmetry parameter
698                                                rrtm_sw_fsfcld, & !< sw in-cloud forward scattering fraction
699                                                rrtm_sw_tauaer, & !< sw aerosol optical depth
700                                                rrtm_sw_ssaaer, & !< sw aerosol single scattering albedo
701                                                rrtm_sw_asmaer, & !< sw aerosol asymmetry parameter
702                                                rrtm_sw_ecaer     !< sw aerosol optical detph at 0.55 microns (rrtm_iaer = 6 only)
703
704#endif
705!
706!-- Parameters of urban and land surface models
707    INTEGER(iwp)                                   ::  nzu                                !< number of layers of urban surface (will be calculated)
708    INTEGER(iwp)                                   ::  nzp                                !< number of layers of plant canopy (will be calculated)
709    INTEGER(iwp)                                   ::  nzub,nzut                          !< bottom and top layer of urban surface (will be calculated)
710    INTEGER(iwp)                                   ::  nzpt                               !< top layer of plant canopy (will be calculated)
711!-- parameters of urban and land surface models
712    INTEGER(iwp), PARAMETER                        ::  nzut_free = 3                      !< number of free layers above top of of topography
713    INTEGER(iwp), PARAMETER                        ::  ndsvf = 2                          !< number of dimensions of real values in SVF
714    INTEGER(iwp), PARAMETER                        ::  idsvf = 2                          !< number of dimensions of integer values in SVF
715    INTEGER(iwp), PARAMETER                        ::  ndcsf = 2                          !< number of dimensions of real values in CSF
716    INTEGER(iwp), PARAMETER                        ::  idcsf = 2                          !< number of dimensions of integer values in CSF
717    INTEGER(iwp), PARAMETER                        ::  kdcsf = 4                          !< number of dimensions of integer values in CSF calculation array
718    INTEGER(iwp), PARAMETER                        ::  id = 1                             !< position of d-index in surfl and surf
719    INTEGER(iwp), PARAMETER                        ::  iz = 2                             !< position of k-index in surfl and surf
720    INTEGER(iwp), PARAMETER                        ::  iy = 3                             !< position of j-index in surfl and surf
721    INTEGER(iwp), PARAMETER                        ::  ix = 4                             !< position of i-index in surfl and surf
722
723    INTEGER(iwp), PARAMETER                        ::  nsurf_type = 16                    !< number of surf types incl. phys.(land+urban) & (atm.,sky,boundary) surfaces - 1
724
725    INTEGER(iwp), PARAMETER                        ::  iup_u    = 0                       !< 0 - index of urban upward surface (ground or roof)
726    INTEGER(iwp), PARAMETER                        ::  idown_u  = 1                       !< 1 - index of urban downward surface (overhanging)
727    INTEGER(iwp), PARAMETER                        ::  inorth_u = 2                       !< 2 - index of urban northward facing wall
728    INTEGER(iwp), PARAMETER                        ::  isouth_u = 3                       !< 3 - index of urban southward facing wall
729    INTEGER(iwp), PARAMETER                        ::  ieast_u  = 4                       !< 4 - index of urban eastward facing wall
730    INTEGER(iwp), PARAMETER                        ::  iwest_u  = 5                       !< 5 - index of urban westward facing wall
731
732    INTEGER(iwp), PARAMETER                        ::  iup_l    = 6                       !< 6 - index of land upward surface (ground or roof)
733    INTEGER(iwp), PARAMETER                        ::  inorth_l = 7                       !< 7 - index of land northward facing wall
734    INTEGER(iwp), PARAMETER                        ::  isouth_l = 8                       !< 8 - index of land southward facing wall
735    INTEGER(iwp), PARAMETER                        ::  ieast_l  = 9                       !< 9 - index of land eastward facing wall
736    INTEGER(iwp), PARAMETER                        ::  iwest_l  = 10                      !< 10- index of land westward facing wall
737
738    INTEGER(iwp), PARAMETER                        ::  iup_a    = 11                      !< 11- index of atm. cell ubward virtual surface
739    INTEGER(iwp), PARAMETER                        ::  idown_a  = 12                      !< 12- index of atm. cell downward virtual surface
740    INTEGER(iwp), PARAMETER                        ::  inorth_a = 13                      !< 13- index of atm. cell northward facing virtual surface
741    INTEGER(iwp), PARAMETER                        ::  isouth_a = 14                      !< 14- index of atm. cell southward facing virtual surface
742    INTEGER(iwp), PARAMETER                        ::  ieast_a  = 15                      !< 15- index of atm. cell eastward facing virtual surface
743    INTEGER(iwp), PARAMETER                        ::  iwest_a  = 16                      !< 16- index of atm. cell westward facing virtual surface
744
745    INTEGER(iwp), DIMENSION(0:nsurf_type), PARAMETER ::  idir = (/0, 0,0, 0,1,-1,0,0, 0,1,-1,0, 0,0, 0,1,-1/)   !< surface normal direction x indices
746    INTEGER(iwp), DIMENSION(0:nsurf_type), PARAMETER ::  jdir = (/0, 0,1,-1,0, 0,0,1,-1,0, 0,0, 0,1,-1,0, 0/)   !< surface normal direction y indices
747    INTEGER(iwp), DIMENSION(0:nsurf_type), PARAMETER ::  kdir = (/1,-1,0, 0,0, 0,1,0, 0,0, 0,1,-1,0, 0,0, 0/)   !< surface normal direction z indices
748                                                                                          !< parameter but set in the code
749
750
751!-- indices and sizes of urban and land surface models
752    INTEGER(iwp)                                   ::  startland        !< start index of block of land and roof surfaces
753    INTEGER(iwp)                                   ::  endland          !< end index of block of land and roof surfaces
754    INTEGER(iwp)                                   ::  nlands           !< number of land and roof surfaces in local processor
755    INTEGER(iwp)                                   ::  startwall        !< start index of block of wall surfaces
756    INTEGER(iwp)                                   ::  endwall          !< end index of block of wall surfaces
757    INTEGER(iwp)                                   ::  nwalls           !< number of wall surfaces in local processor
758
759!-- indices and sizes of urban and land surface models
760    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE      ::  surfl            !< coordinates of i-th local surface in local grid - surfl[:,k] = [d, z, y, x]
761    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE      ::  surf             !< coordinates of i-th surface in grid - surf[:,k] = [d, z, y, x]
762    INTEGER(iwp)                                   ::  nsurfl           !< number of all surfaces in local processor
763    INTEGER(iwp), DIMENSION(:), ALLOCATABLE        ::  nsurfs           !< array of number of all surfaces in individual processors
764    INTEGER(iwp)                                   ::  nsurf            !< global number of surfaces in index array of surfaces (nsurf = proc nsurfs)
765    INTEGER(iwp), DIMENSION(:), ALLOCATABLE        ::  surfstart        !< starts of blocks of surfaces for individual processors in array surf
766                                                                        !< respective block for particular processor is surfstart[iproc]+1 : surfstart[iproc+1]
767
768!-- block variables needed for calculation of the plant canopy model inside the urban surface model
769    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE      ::  pct              !< top layer of the plant canopy
770    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE      ::  pch              !< heights of the plant canopy
771    INTEGER(iwp)                                   ::  npcbl = 0        !< number of the plant canopy gridboxes in local processor
772    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE      ::  pcbl             !< k,j,i coordinates of l-th local plant canopy box pcbl[:,l] = [k, j, i]
773    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  pcbinsw          !< array of absorbed sw radiation for local plant canopy box
774    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  pcbinswdir       !< array of absorbed direct sw radiation for local plant canopy box
775    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  pcbinswdif       !< array of absorbed diffusion sw radiation for local plant canopy box
776    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  pcbinlw          !< array of absorbed lw radiation for local plant canopy box
777
778!-- configuration parameters (they can be setup in PALM config)
779    LOGICAL                                        ::  split_diffusion_radiation = .TRUE. !< split direct and diffusion dw radiation
780                                                                                          !< (.F. in case the radiation model already does it)   
781    LOGICAL                                        ::  rma_lad_raytrace = .FALSE.         !< use MPI RMA to access LAD for raytracing (instead of global array)
782    LOGICAL                                        ::  mrt_factors = .FALSE.              !< whether to generate MRT factor files during init
783    INTEGER(iwp)                                   ::  nrefsteps = 0                      !< number of reflection steps to perform
784    REAL(wp), PARAMETER                            ::  ext_coef = 0.6_wp                  !< extinction coefficient (a.k.a. alpha)
785    INTEGER(iwp), PARAMETER                        ::  rad_version_len = 10               !< length of identification string of rad version
786    CHARACTER(rad_version_len), PARAMETER          ::  rad_version = 'RAD v. 1.1'         !< identification of version of binary svf and restart files
787    INTEGER(iwp)                                   ::  raytrace_discrete_elevs = 40       !< number of discretization steps for elevation (nadir to zenith)
788    INTEGER(iwp)                                   ::  raytrace_discrete_azims = 80       !< number of discretization steps for azimuth (out of 360 degrees)
789    REAL(wp)                                       ::  max_raytracing_dist = -999.0_wp    !< maximum distance for raytracing (in metres)
790    REAL(wp)                                       ::  min_irrf_value = 1e-6_wp           !< minimum potential irradiance factor value for raytracing
791    REAL(wp), DIMENSION(1:30)                      ::  svfnorm_report_thresh = 1e21_wp    !< thresholds of SVF normalization values to report
792    INTEGER(iwp)                                   ::  svfnorm_report_num                 !< number of SVF normalization thresholds to report
793
794!-- radiation related arrays to be used in radiation_interaction routine
795    REAL(wp), DIMENSION(:,:), ALLOCATABLE          ::  rad_sw_in_dir    !< direct sw radiation
796    REAL(wp), DIMENSION(:,:), ALLOCATABLE          ::  rad_sw_in_diff   !< diffusion sw radiation
797    REAL(wp), DIMENSION(:,:), ALLOCATABLE          ::  rad_lw_in_diff   !< diffusion lw radiation
798
799!-- parameters required for RRTMG lower boundary condition
800    REAL(wp)                   :: albedo_urb      !< albedo value retuned to RRTMG boundary cond.
801    REAL(wp)                   :: emissivity_urb  !< emissivity value retuned to RRTMG boundary cond.
802    REAL(wp)                   :: t_rad_urb       !< temperature value retuned to RRTMG boundary cond.
803
804!-- type for calculation of svf
805    TYPE t_svf
806        INTEGER(iwp)                               :: isurflt           !<
807        INTEGER(iwp)                               :: isurfs            !<
808        REAL(wp)                                   :: rsvf              !<
809        REAL(wp)                                   :: rtransp           !<
810    END TYPE
811
812!-- type for calculation of csf
813    TYPE t_csf
814        INTEGER(iwp)                               :: ip                !<
815        INTEGER(iwp)                               :: itx               !<
816        INTEGER(iwp)                               :: ity               !<
817        INTEGER(iwp)                               :: itz               !<
818        INTEGER(iwp)                               :: isurfs            !<
819        REAL(wp)                                   :: rsvf              !<
820        REAL(wp)                                   :: rtransp           !<
821    END TYPE
822
823!-- arrays storing the values of USM
824    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE      ::  svfsurf          !< svfsurf[:,isvf] = index of source and target surface for svf[isvf]
825    REAL(wp), DIMENSION(:,:), ALLOCATABLE          ::  svf              !< array of shape view factors+direct irradiation factors for local surfaces
826    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfins          !< array of sw radiation falling to local surface after i-th reflection
827    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfinl          !< array of lw radiation for local surface after i-th reflection
828
829    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  skyvf            !< array of sky view factor for each local surface
830    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  skyvft           !< array of sky view factor including transparency for each local surface
831    REAL(wp), DIMENSION(:,:), ALLOCATABLE          ::  dsitrans         !< dsidir[isvfl,i] = path transmittance of i-th
832                                                                        !< direction of direct solar irradiance per target surface
833    REAL(wp), DIMENSION(:,:), ALLOCATABLE          ::  dsitransc        !< dtto per plant canopy box
834    REAL(wp), DIMENSION(:,:), ALLOCATABLE          ::  dsidir           !< dsidir[:,i] = unit vector of i-th
835                                                                        !< direction of direct solar irradiance
836    INTEGER(iwp)                                   ::  ndsidir          !< number of apparent solar directions used
837    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE      ::  dsidir_rev       !< dsidir_rev[ielev,iazim] = i for dsidir or -1 if not present
838
839    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfinsw         !< array of sw radiation falling to local surface including radiation from reflections
840    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfinlw         !< array of lw radiation falling to local surface including radiation from reflections
841    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfinswdir      !< array of direct sw radiation falling to local surface
842    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfinswdif      !< array of diffuse sw radiation from sky and model boundary falling to local surface
843    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfinlwdif      !< array of diffuse lw radiation from sky and model boundary falling to local surface
844   
845                                                                        !< Outward radiation is only valid for nonvirtual surfaces
846    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfoutsl        !< array of reflected sw radiation for local surface in i-th reflection
847    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfoutll        !< array of reflected + emitted lw radiation for local surface in i-th reflection
848    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfouts         !< array of reflected sw radiation for all surfaces in i-th reflection
849    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfoutl         !< array of reflected + emitted lw radiation for all surfaces in i-th reflection
850    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfoutsw        !< array of total sw radiation outgoing from nonvirtual surfaces surfaces after all reflection
851    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfoutlw        !< array of total lw radiation outgoing from nonvirtual surfaces surfaces after all reflection
852    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfhf           !< array of total radiation flux incoming to minus outgoing from local surface
853    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfemitlwl      !< array of emitted lw radiation for local surface used to calculate effective surface temperature for radiation model
854
855!-- block variables needed for calculation of the plant canopy model inside the urban surface model
856    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE      ::  csfsurf          !< csfsurf[:,icsf] = index of target surface and csf grid index for csf[icsf]
857    REAL(wp), DIMENSION(:,:), ALLOCATABLE          ::  csf              !< array of plant canopy sink fators + direct irradiation factors (transparency)
858    REAL(wp), DIMENSION(:,:,:), POINTER            ::  sub_lad          !< subset of lad_s within urban surface, transformed to plain Z coordinate
859    REAL(wp), DIMENSION(:), POINTER                ::  sub_lad_g        !< sub_lad globalized (used to avoid MPI RMA calls in raytracing)
860    REAL(wp)                                       ::  prototype_lad    !< prototype leaf area density for computing effective optical depth
861    INTEGER(iwp), DIMENSION(:), ALLOCATABLE        ::  nzterr, plantt   !< temporary global arrays for raytracing
862    INTEGER(iwp)                                   ::  plantt_max
863
864!-- arrays and variables for calculation of svf and csf
865    TYPE(t_svf), DIMENSION(:), POINTER             ::  asvf             !< pointer to growing svc array
866    TYPE(t_csf), DIMENSION(:), POINTER             ::  acsf             !< pointer to growing csf array
867    TYPE(t_svf), DIMENSION(:), ALLOCATABLE, TARGET ::  asvf1, asvf2     !< realizations of svf array
868    TYPE(t_csf), DIMENSION(:), ALLOCATABLE, TARGET ::  acsf1, acsf2     !< realizations of csf array
869    INTEGER(iwp)                                   ::  nsvfla           !< dimmension of array allocated for storage of svf in local processor
870    INTEGER(iwp)                                   ::  ncsfla           !< dimmension of array allocated for storage of csf in local processor
871    INTEGER(iwp)                                   ::  msvf, mcsf       !< mod for swapping the growing array
872    INTEGER(iwp), PARAMETER                        ::  gasize = 10000   !< initial size of growing arrays
873    REAL(wp)                                       ::  dist_max_svf = -9999.0 !< maximum distance to calculate the minimum svf to be considered. It is
874                                                                        !< used to avoid very small SVFs resulting from too far surfaces with mutual visibility
875    INTEGER(iwp)                                   ::  nsvfl            !< number of svf for local processor
876    INTEGER(iwp)                                   ::  ncsfl            !< no. of csf in local processor
877                                                                        !< needed only during calc_svf but must be here because it is
878                                                                        !< shared between subroutines calc_svf and raytrace
879    INTEGER(iwp), DIMENSION(:,:,:), ALLOCATABLE    ::  gridpcbl         !< index of local pcb[k,j,i]
880
881!-- temporary arrays for calculation of csf in raytracing
882    INTEGER(iwp)                                   ::  maxboxesg        !< max number of boxes ray can cross in the domain
883    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE      ::  boxes            !< coordinates of gridboxes being crossed by ray
884    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  crlens           !< array of crossing lengths of ray for particular grid boxes
885    INTEGER(iwp), DIMENSION(:), ALLOCATABLE        ::  lad_ip           !< array of numbers of process where lad is stored
886#if defined( __parallel )
887    INTEGER(kind=MPI_ADDRESS_KIND), &
888                  DIMENSION(:), ALLOCATABLE        ::  lad_disp         !< array of displaycements of lad in local array of proc lad_ip
889#endif
890    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  lad_s_ray        !< array of received lad_s for appropriate gridboxes crossed by ray
891    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE      ::  rt2_track
892    REAL(wp), DIMENSION(:,:), ALLOCATABLE          ::  rt2_track_lad
893    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  rt2_track_dist
894    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  rt2_dist
895
896
897
898!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
899!-- Energy balance variables
900!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
901!-- parameters of the land, roof and wall surfaces
902    REAL(wp), DIMENSION(:), ALLOCATABLE            :: albedo_surf        !< albedo of the surface
903    REAL(wp), DIMENSION(:), ALLOCATABLE            :: emiss_surf         !< emissivity of the wall surface
904
905
906    INTERFACE radiation_check_data_output
907       MODULE PROCEDURE radiation_check_data_output
908    END INTERFACE radiation_check_data_output
909
910    INTERFACE radiation_check_data_output_pr
911       MODULE PROCEDURE radiation_check_data_output_pr
912    END INTERFACE radiation_check_data_output_pr
913 
914    INTERFACE radiation_check_parameters
915       MODULE PROCEDURE radiation_check_parameters
916    END INTERFACE radiation_check_parameters
917 
918    INTERFACE radiation_clearsky
919       MODULE PROCEDURE radiation_clearsky
920    END INTERFACE radiation_clearsky
921 
922    INTERFACE radiation_constant
923       MODULE PROCEDURE radiation_constant
924    END INTERFACE radiation_constant
925 
926    INTERFACE radiation_control
927       MODULE PROCEDURE radiation_control
928    END INTERFACE radiation_control
929
930    INTERFACE radiation_3d_data_averaging
931       MODULE PROCEDURE radiation_3d_data_averaging
932    END INTERFACE radiation_3d_data_averaging
933
934    INTERFACE radiation_data_output_2d
935       MODULE PROCEDURE radiation_data_output_2d
936    END INTERFACE radiation_data_output_2d
937
938    INTERFACE radiation_data_output_3d
939       MODULE PROCEDURE radiation_data_output_3d
940    END INTERFACE radiation_data_output_3d
941
942    INTERFACE radiation_data_output_mask
943       MODULE PROCEDURE radiation_data_output_mask
944    END INTERFACE radiation_data_output_mask
945
946    INTERFACE radiation_define_netcdf_grid
947       MODULE PROCEDURE radiation_define_netcdf_grid
948    END INTERFACE radiation_define_netcdf_grid
949
950    INTERFACE radiation_header
951       MODULE PROCEDURE radiation_header
952    END INTERFACE radiation_header 
953 
954    INTERFACE radiation_init
955       MODULE PROCEDURE radiation_init
956    END INTERFACE radiation_init
957
958    INTERFACE radiation_parin
959       MODULE PROCEDURE radiation_parin
960    END INTERFACE radiation_parin
961   
962    INTERFACE radiation_rrtmg
963       MODULE PROCEDURE radiation_rrtmg
964    END INTERFACE radiation_rrtmg
965
966    INTERFACE radiation_tendency
967       MODULE PROCEDURE radiation_tendency
968       MODULE PROCEDURE radiation_tendency_ij
969    END INTERFACE radiation_tendency
970
971    INTERFACE radiation_rrd_local
972       MODULE PROCEDURE radiation_rrd_local
973    END INTERFACE radiation_rrd_local
974
975    INTERFACE radiation_wrd_local
976       MODULE PROCEDURE radiation_wrd_local
977    END INTERFACE radiation_wrd_local
978
979    INTERFACE radiation_interaction
980       MODULE PROCEDURE radiation_interaction
981    END INTERFACE radiation_interaction
982
983    INTERFACE radiation_interaction_init
984       MODULE PROCEDURE radiation_interaction_init
985    END INTERFACE radiation_interaction_init
986 
987    INTERFACE radiation_presimulate_solar_pos
988       MODULE PROCEDURE radiation_presimulate_solar_pos
989    END INTERFACE radiation_presimulate_solar_pos
990
991    INTERFACE radiation_radflux_gridbox
992       MODULE PROCEDURE radiation_radflux_gridbox
993    END INTERFACE radiation_radflux_gridbox
994
995    INTERFACE radiation_calc_svf
996       MODULE PROCEDURE radiation_calc_svf
997    END INTERFACE radiation_calc_svf
998
999    INTERFACE radiation_write_svf
1000       MODULE PROCEDURE radiation_write_svf
1001    END INTERFACE radiation_write_svf
1002
1003    INTERFACE radiation_read_svf
1004       MODULE PROCEDURE radiation_read_svf
1005    END INTERFACE radiation_read_svf
1006
1007
1008    SAVE
1009
1010    PRIVATE
1011
1012!
1013!-- Public functions / NEEDS SORTING
1014    PUBLIC radiation_check_data_output, radiation_check_data_output_pr,        &
1015           radiation_check_parameters, radiation_control,                      &
1016           radiation_header, radiation_init, radiation_parin,                  &
1017           radiation_3d_data_averaging, radiation_tendency,                    &
1018           radiation_data_output_2d, radiation_data_output_3d,                 &
1019           radiation_define_netcdf_grid, radiation_wrd_local,                  &
1020           radiation_rrd_local, radiation_data_output_mask,                    &
1021           radiation_radflux_gridbox, radiation_calc_svf, radiation_write_svf, &
1022           radiation_interaction, radiation_interaction_init,                  &
1023           radiation_read_svf, radiation_presimulate_solar_pos
1024           
1025
1026   
1027!
1028!-- Public variables and constants / NEEDS SORTING
1029    PUBLIC albedo, albedo_type, decl_1, decl_2, decl_3, dots_rad, dt_radiation,&
1030           emissivity, force_radiation_call,                                   &
1031           lat, lon, rad_net_av, radiation, radiation_scheme, rad_lw_in,       &
1032           rad_lw_in_av, rad_lw_out, rad_lw_out_av,                            &
1033           rad_lw_cs_hr, rad_lw_cs_hr_av, rad_lw_hr, rad_lw_hr_av, rad_sw_in,  &
1034           rad_sw_in_av, rad_sw_out, rad_sw_out_av, rad_sw_cs_hr,              &
1035           rad_sw_cs_hr_av, rad_sw_hr, rad_sw_hr_av, sigma_sb, solar_constant, &
1036           skip_time_do_radiation, time_radiation, unscheduled_radiation_calls,&
1037           zenith, calc_zenith, sun_direction, sun_dir_lat, sun_dir_lon,       &
1038           split_diffusion_radiation,                                          &
1039           nrefsteps, mrt_factors, dist_max_svf, nsvfl, svf,                   &
1040           svfsurf, surfinsw, surfinlw, surfins, surfinl, surfinswdir,         &
1041           surfinswdif, surfoutsw, surfoutlw, surfinlwdif, rad_sw_in_dir,      &
1042           rad_sw_in_diff, rad_lw_in_diff, surfouts, surfoutl, surfoutsl,      &
1043           surfoutll, idir, jdir, kdir, id, iz, iy, ix, nsurfs, surfstart,     &
1044           surf, surfl, nsurfl, pcbinswdir, pcbinswdif, pcbinsw, pcbinlw,      &
1045           iup_u, inorth_u, isouth_u, ieast_u, iwest_u,           &
1046           iup_l, inorth_l, isouth_l, ieast_l, iwest_l,                        &
1047           nsurf_type, nzub, nzut, nzu, pch, nsurf,                            &
1048           iup_a, idown_a, inorth_a, isouth_a, ieast_a, iwest_a,               &
1049           idsvf, ndsvf, idcsf, ndcsf, kdcsf, pct,                             &
1050           radiation_interactions, startwall, startland, endland, endwall,     &
1051           skyvf, skyvft, radiation_interactions_on, average_radiation
1052
1053#if defined ( __rrtmg )
1054    PUBLIC rrtm_aldif, rrtm_aldir, rrtm_asdif, rrtm_asdir
1055#endif
1056
1057 CONTAINS
1058
1059
1060!------------------------------------------------------------------------------!
1061! Description:
1062! ------------
1063!> This subroutine controls the calls of the radiation schemes
1064!------------------------------------------------------------------------------!
1065    SUBROUTINE radiation_control
1066 
1067 
1068       IMPLICIT NONE
1069
1070
1071       SELECT CASE ( TRIM( radiation_scheme ) )
1072
1073          CASE ( 'constant' )
1074             CALL radiation_constant
1075         
1076          CASE ( 'clear-sky' ) 
1077             CALL radiation_clearsky
1078       
1079          CASE ( 'rrtmg' )
1080             CALL radiation_rrtmg
1081
1082          CASE DEFAULT
1083
1084       END SELECT
1085
1086
1087    END SUBROUTINE radiation_control
1088
1089!------------------------------------------------------------------------------!
1090! Description:
1091! ------------
1092!> Check data output for radiation model
1093!------------------------------------------------------------------------------!
1094    SUBROUTINE radiation_check_data_output( var, unit, i, ilen, k )
1095 
1096 
1097       USE control_parameters,                                                 &
1098           ONLY: data_output, message_string
1099
1100       IMPLICIT NONE
1101
1102       CHARACTER (LEN=*) ::  unit     !<
1103       CHARACTER (LEN=*) ::  var      !<
1104
1105       INTEGER(iwp) :: i
1106       INTEGER(iwp) :: ilen
1107       INTEGER(iwp) :: k
1108
1109       SELECT CASE ( TRIM( var ) )
1110
1111         CASE ( 'rad_lw_cs_hr', 'rad_lw_hr', 'rad_sw_cs_hr', 'rad_sw_hr' )
1112             IF (  .NOT.  radiation  .OR.  radiation_scheme /= 'rrtmg' )  THEN
1113                message_string = '"output of "' // TRIM( var ) // '" requi' // &
1114                                 'res radiation = .TRUE. and ' //              &
1115                                 'radiation_scheme = "rrtmg"'
1116                CALL message( 'check_parameters', 'PA0406', 1, 2, 0, 6, 0 )
1117             ENDIF
1118             unit = 'K/h'     
1119
1120          CASE ( 'rad_net*', 'rrtm_aldif*', 'rrtm_aldir*', 'rrtm_asdif*',      &
1121                 'rrtm_asdir*', 'rad_lw_in*', 'rad_lw_out*', 'rad_sw_in*',     &
1122                 'rad_sw_out*')
1123             IF ( k == 0  .OR.  data_output(i)(ilen-2:ilen) /= '_xy' )  THEN
1124                message_string = 'illegal value for data_output: "' //         &
1125                                 TRIM( var ) // '" & only 2d-horizontal ' //   &
1126                                 'cross sections are allowed for this value'
1127                CALL message( 'check_parameters', 'PA0111', 1, 2, 0, 6, 0 )
1128             ENDIF
1129             IF (  .NOT.  radiation  .OR.  radiation_scheme /= "rrtmg" )  THEN
1130                IF ( TRIM( var ) == 'rrtm_aldif*'  .OR.                        &
1131                     TRIM( var ) == 'rrtm_aldir*'  .OR.                        &
1132                     TRIM( var ) == 'rrtm_asdif*'  .OR.                        &
1133                     TRIM( var ) == 'rrtm_asdir*'      )                       &
1134                THEN
1135                   message_string = 'output of "' // TRIM( var ) // '" require'&
1136                                    // 's radiation = .TRUE. and radiation_sch'&
1137                                    // 'eme = "rrtmg"'
1138                   CALL message( 'check_parameters', 'PA0409', 1, 2, 0, 6, 0 )
1139                ENDIF
1140             ENDIF
1141
1142             IF ( TRIM( var ) == 'rad_net*'      ) unit = 'W/m2'   
1143             IF ( TRIM( var ) == 'rad_lw_in*'    ) unit = 'W/m2'
1144             IF ( TRIM( var ) == 'rad_lw_out*'   ) unit = 'W/m2'
1145             IF ( TRIM( var ) == 'rad_sw_in*'    ) unit = 'W/m2'
1146             IF ( TRIM( var ) == 'rad_sw_out*'   ) unit = 'W/m2'
1147             IF ( TRIM( var ) == 'rrtm_aldif*'   ) unit = ''   
1148             IF ( TRIM( var ) == 'rrtm_aldir*'   ) unit = '' 
1149             IF ( TRIM( var ) == 'rrtm_asdif*'   ) unit = '' 
1150             IF ( TRIM( var ) == 'rrtm_asdir*'   ) unit = '' 
1151
1152          CASE DEFAULT
1153             unit = 'illegal'
1154
1155       END SELECT
1156
1157
1158    END SUBROUTINE radiation_check_data_output
1159
1160!------------------------------------------------------------------------------!
1161! Description:
1162! ------------
1163!> Check data output of profiles for radiation model
1164!------------------------------------------------------------------------------! 
1165    SUBROUTINE radiation_check_data_output_pr( variable, var_count, unit,      &
1166               dopr_unit )
1167 
1168       USE arrays_3d,                                                          &
1169           ONLY: zu
1170
1171       USE control_parameters,                                                 &
1172           ONLY: data_output_pr, message_string
1173
1174       USE indices
1175
1176       USE profil_parameter
1177
1178       USE statistics
1179
1180       IMPLICIT NONE
1181   
1182       CHARACTER (LEN=*) ::  unit      !<
1183       CHARACTER (LEN=*) ::  variable  !<
1184       CHARACTER (LEN=*) ::  dopr_unit !< local value of dopr_unit
1185 
1186       INTEGER(iwp) ::  user_pr_index !<
1187       INTEGER(iwp) ::  var_count     !<
1188
1189       SELECT CASE ( TRIM( variable ) )
1190       
1191         CASE ( 'rad_net' )
1192             IF ( (  .NOT.  radiation )  .OR.  radiation_scheme == 'constant' )&
1193             THEN
1194                message_string = 'data_output_pr = ' //                        &
1195                                 TRIM( data_output_pr(var_count) ) // ' is' // &
1196                                 'not available for radiation = .FALSE. or ' //&
1197                                 'radiation_scheme = "constant"'
1198                CALL message( 'check_parameters', 'PA0408', 1, 2, 0, 6, 0 )
1199             ELSE
1200                dopr_index(var_count) = 99
1201                dopr_unit  = 'W/m2'
1202                hom(:,2,99,:)  = SPREAD( zw, 2, statistic_regions+1 )
1203                unit = dopr_unit
1204             ENDIF
1205
1206          CASE ( 'rad_lw_in' )
1207             IF ( (  .NOT.  radiation)  .OR.  radiation_scheme == 'constant' ) &
1208             THEN
1209                message_string = 'data_output_pr = ' //                        &
1210                                 TRIM( data_output_pr(var_count) ) // ' is' // &
1211                                 'not available for radiation = .FALSE. or ' //&
1212                                 'radiation_scheme = "constant"'
1213                CALL message( 'check_parameters', 'PA0408', 1, 2, 0, 6, 0 )
1214             ELSE
1215                dopr_index(var_count) = 100
1216                dopr_unit  = 'W/m2'
1217                hom(:,2,100,:)  = SPREAD( zw, 2, statistic_regions+1 )
1218                unit = dopr_unit 
1219             ENDIF
1220
1221          CASE ( 'rad_lw_out' )
1222             IF ( (  .NOT. radiation )  .OR.  radiation_scheme == 'constant' ) &
1223             THEN
1224                message_string = 'data_output_pr = ' //                        &
1225                                 TRIM( data_output_pr(var_count) ) // ' is' // &
1226                                 'not available for radiation = .FALSE. or ' //&
1227                                 'radiation_scheme = "constant"'
1228                CALL message( 'check_parameters', 'PA0408', 1, 2, 0, 6, 0 )
1229             ELSE
1230                dopr_index(var_count) = 101
1231                dopr_unit  = 'W/m2'
1232                hom(:,2,101,:)  = SPREAD( zw, 2, statistic_regions+1 )
1233                unit = dopr_unit   
1234             ENDIF
1235
1236          CASE ( 'rad_sw_in' )
1237             IF ( (  .NOT. radiation )  .OR.  radiation_scheme == 'constant' ) &
1238             THEN
1239                message_string = 'data_output_pr = ' //                        &
1240                                 TRIM( data_output_pr(var_count) ) // ' is' // &
1241                                 'not available for radiation = .FALSE. or ' //&
1242                                 'radiation_scheme = "constant"'
1243                CALL message( 'check_parameters', 'PA0408', 1, 2, 0, 6, 0 )
1244             ELSE
1245                dopr_index(var_count) = 102
1246                dopr_unit  = 'W/m2'
1247                hom(:,2,102,:)  = SPREAD( zw, 2, statistic_regions+1 )
1248                unit = dopr_unit
1249             ENDIF
1250
1251          CASE ( 'rad_sw_out')
1252             IF ( (  .NOT.  radiation )  .OR.  radiation_scheme == 'constant' )&
1253             THEN
1254                message_string = 'data_output_pr = ' //                        &
1255                                 TRIM( data_output_pr(var_count) ) // ' is' // &
1256                                 'not available for radiation = .FALSE. or ' //&
1257                                 'radiation_scheme = "constant"'
1258                CALL message( 'check_parameters', 'PA0408', 1, 2, 0, 6, 0 )
1259             ELSE
1260                dopr_index(var_count) = 103
1261                dopr_unit  = 'W/m2'
1262                hom(:,2,103,:)  = SPREAD( zw, 2, statistic_regions+1 )
1263                unit = dopr_unit
1264             ENDIF
1265
1266          CASE ( 'rad_lw_cs_hr' )
1267             IF ( (  .NOT.  radiation )  .OR.  radiation_scheme /= 'rrtmg' )   &
1268             THEN
1269                message_string = 'data_output_pr = ' //                        &
1270                                 TRIM( data_output_pr(var_count) ) // ' is' // &
1271                                 'not available for radiation = .FALSE. or ' //&
1272                                 'radiation_scheme /= "rrtmg"'
1273                CALL message( 'check_parameters', 'PA0413', 1, 2, 0, 6, 0 )
1274             ELSE
1275                dopr_index(var_count) = 104
1276                dopr_unit  = 'K/h'
1277                hom(:,2,104,:)  = SPREAD( zu, 2, statistic_regions+1 )
1278                unit = dopr_unit
1279             ENDIF
1280
1281          CASE ( 'rad_lw_hr' )
1282             IF ( (  .NOT.  radiation )  .OR.  radiation_scheme /= 'rrtmg' )   &
1283             THEN
1284                message_string = 'data_output_pr = ' //                        &
1285                                 TRIM( data_output_pr(var_count) ) // ' is' // &
1286                                 'not available for radiation = .FALSE. or ' //&
1287                                 'radiation_scheme /= "rrtmg"'
1288                CALL message( 'check_parameters', 'PA0413', 1, 2, 0, 6, 0 )
1289             ELSE
1290                dopr_index(var_count) = 105
1291                dopr_unit  = 'K/h'
1292                hom(:,2,105,:)  = SPREAD( zu, 2, statistic_regions+1 )
1293                unit = dopr_unit
1294             ENDIF
1295
1296          CASE ( 'rad_sw_cs_hr' )
1297             IF ( (  .NOT.  radiation )  .OR.  radiation_scheme /= 'rrtmg' )   &
1298             THEN
1299                message_string = 'data_output_pr = ' //                        &
1300                                 TRIM( data_output_pr(var_count) ) // ' is' // &
1301                                 'not available for radiation = .FALSE. or ' //&
1302                                 'radiation_scheme /= "rrtmg"'
1303                CALL message( 'check_parameters', 'PA0413', 1, 2, 0, 6, 0 )
1304             ELSE
1305                dopr_index(var_count) = 106
1306                dopr_unit  = 'K/h'
1307                hom(:,2,106,:)  = SPREAD( zu, 2, statistic_regions+1 )
1308                unit = dopr_unit
1309             ENDIF
1310
1311          CASE ( 'rad_sw_hr' )
1312             IF ( (  .NOT.  radiation )  .OR.  radiation_scheme /= 'rrtmg' )   &
1313             THEN
1314                message_string = 'data_output_pr = ' //                        &
1315                                 TRIM( data_output_pr(var_count) ) // ' is' // &
1316                                 'not available for radiation = .FALSE. or ' //&
1317                                 'radiation_scheme /= "rrtmg"'
1318                CALL message( 'check_parameters', 'PA0413', 1, 2, 0, 6, 0 )
1319             ELSE
1320                dopr_index(var_count) = 107
1321                dopr_unit  = 'K/h'
1322                hom(:,2,107,:)  = SPREAD( zu, 2, statistic_regions+1 )
1323                unit = dopr_unit
1324             ENDIF
1325
1326
1327          CASE DEFAULT
1328             unit = 'illegal'
1329
1330       END SELECT
1331
1332
1333    END SUBROUTINE radiation_check_data_output_pr
1334 
1335 
1336!------------------------------------------------------------------------------!
1337! Description:
1338! ------------
1339!> Check parameters routine for radiation model
1340!------------------------------------------------------------------------------!
1341    SUBROUTINE radiation_check_parameters
1342
1343       USE control_parameters,                                                 &
1344           ONLY: land_surface, message_string, topography, urban_surface
1345
1346       USE netcdf_data_input_mod,                                              &
1347           ONLY:  input_pids_static                 
1348   
1349       IMPLICIT NONE
1350       
1351!
1352!--    In case no urban-surface or land-surface model is applied, usage of
1353!--    a radiation model make no sense.         
1354       IF ( .NOT. land_surface  .AND.  .NOT. urban_surface )  THEN
1355          message_string = 'Usage of radiation module is only allowed if ' //  &
1356                           'land-surface and/or urban-surface model is applied.'
1357          CALL message( 'check_parameters', 'PA0486', 1, 2, 0, 6, 0 )
1358       ENDIF
1359
1360       IF ( radiation_scheme /= 'constant'   .AND.                             &
1361            radiation_scheme /= 'clear-sky'  .AND.                             &
1362            radiation_scheme /= 'rrtmg' )  THEN
1363          message_string = 'unknown radiation_scheme = '//                     &
1364                           TRIM( radiation_scheme )
1365          CALL message( 'check_parameters', 'PA0405', 1, 2, 0, 6, 0 )
1366       ELSEIF ( radiation_scheme == 'rrtmg' )  THEN
1367#if ! defined ( __rrtmg )
1368          message_string = 'radiation_scheme = "rrtmg" requires ' //           & 
1369                           'compilation of PALM with pre-processor ' //        &
1370                           'directive -D__rrtmg'
1371          CALL message( 'check_parameters', 'PA0407', 1, 2, 0, 6, 0 )
1372#endif
1373#if defined ( __rrtmg ) && ! defined( __netcdf )
1374          message_string = 'radiation_scheme = "rrtmg" requires ' //           & 
1375                           'the use of NetCDF (preprocessor directive ' //     &
1376                           '-D__netcdf'
1377          CALL message( 'check_parameters', 'PA0412', 1, 2, 0, 6, 0 )
1378#endif
1379
1380       ENDIF
1381!
1382!--    Checks performed only if data is given via namelist only.
1383       IF ( .NOT. input_pids_static )  THEN
1384          IF ( albedo_type == 0  .AND.  albedo == 9999999.9_wp  .AND.          &
1385               radiation_scheme == 'clear-sky')  THEN
1386             message_string = 'radiation_scheme = "clear-sky" in combination'//& 
1387                              'with albedo_type = 0 requires setting of'//     &
1388                              'albedo /= 9999999.9'
1389             CALL message( 'check_parameters', 'PA0410', 1, 2, 0, 6, 0 )
1390          ENDIF
1391
1392          IF ( albedo_type == 0  .AND.  radiation_scheme == 'rrtmg'  .AND.     &
1393             ( albedo_lw_dif == 9999999.9_wp .OR. albedo_lw_dir == 9999999.9_wp&
1394          .OR. albedo_sw_dif == 9999999.9_wp .OR. albedo_sw_dir == 9999999.9_wp& 
1395             ) ) THEN
1396             message_string = 'radiation_scheme = "rrtmg" in combination' //   & 
1397                              'with albedo_type = 0 requires setting of ' //   &
1398                              'albedo_lw_dif /= 9999999.9' //                  &
1399                              'albedo_lw_dir /= 9999999.9' //                  &
1400                              'albedo_sw_dif /= 9999999.9 and' //              &
1401                              'albedo_sw_dir /= 9999999.9'
1402             CALL message( 'check_parameters', 'PA0411', 1, 2, 0, 6, 0 )
1403          ENDIF
1404       ENDIF
1405
1406!
1407!--    Incialize svf normalization reporting histogram
1408       svfnorm_report_num = 1
1409       DO WHILE ( svfnorm_report_thresh(svfnorm_report_num) < 1e20_wp          &
1410                   .AND. svfnorm_report_num <= 30 )
1411          svfnorm_report_num = svfnorm_report_num + 1
1412       ENDDO
1413       svfnorm_report_num = svfnorm_report_num - 1
1414
1415
1416 
1417    END SUBROUTINE radiation_check_parameters 
1418 
1419 
1420!------------------------------------------------------------------------------!
1421! Description:
1422! ------------
1423!> Initialization of the radiation model
1424!------------------------------------------------------------------------------!
1425    SUBROUTINE radiation_init
1426   
1427       IMPLICIT NONE
1428
1429       INTEGER(iwp) ::  i         !< running index x-direction
1430       INTEGER(iwp) ::  ind_type  !< running index for subgrid-surface tiles
1431       INTEGER(iwp) ::  ioff      !< offset in x between surface element reference grid point in atmosphere and actual surface
1432       INTEGER(iwp) ::  j         !< running index y-direction
1433       INTEGER(iwp) ::  joff      !< offset in y between surface element reference grid point in atmosphere and actual surface
1434       INTEGER(iwp) ::  l         !< running index for orientation of vertical surfaces
1435       INTEGER(iwp) ::  m         !< running index for surface elements 
1436
1437!
1438!--    Allocate array for storing the surface net radiation
1439       IF ( .NOT. ALLOCATED ( surf_lsm_h%rad_net )  .AND.                      &
1440                  surf_lsm_h%ns > 0  )   THEN
1441          ALLOCATE( surf_lsm_h%rad_net(1:surf_lsm_h%ns) )
1442          surf_lsm_h%rad_net = 0.0_wp 
1443       ENDIF
1444       IF ( .NOT. ALLOCATED ( surf_usm_h%rad_net )  .AND.                      &
1445                  surf_usm_h%ns > 0  )  THEN
1446          ALLOCATE( surf_usm_h%rad_net(1:surf_usm_h%ns) )
1447          surf_usm_h%rad_net = 0.0_wp 
1448       ENDIF
1449       DO  l = 0, 3
1450          IF ( .NOT. ALLOCATED ( surf_lsm_v(l)%rad_net )  .AND.                &
1451                     surf_lsm_v(l)%ns > 0  )  THEN
1452             ALLOCATE( surf_lsm_v(l)%rad_net(1:surf_lsm_v(l)%ns) )
1453             surf_lsm_v(l)%rad_net = 0.0_wp 
1454          ENDIF
1455          IF ( .NOT. ALLOCATED ( surf_usm_v(l)%rad_net )  .AND.                &
1456                     surf_usm_v(l)%ns > 0  )  THEN
1457             ALLOCATE( surf_usm_v(l)%rad_net(1:surf_usm_v(l)%ns) )
1458             surf_usm_v(l)%rad_net = 0.0_wp 
1459          ENDIF
1460       ENDDO
1461
1462
1463!
1464!--    Allocate array for storing the surface longwave (out) radiation change
1465       IF ( .NOT. ALLOCATED ( surf_lsm_h%rad_lw_out_change_0 )  .AND.          &
1466                  surf_lsm_h%ns > 0  )   THEN
1467          ALLOCATE( surf_lsm_h%rad_lw_out_change_0(1:surf_lsm_h%ns) )
1468          surf_lsm_h%rad_lw_out_change_0 = 0.0_wp 
1469       ENDIF
1470       IF ( .NOT. ALLOCATED ( surf_usm_h%rad_lw_out_change_0 )  .AND.          &
1471                  surf_usm_h%ns > 0  )  THEN
1472          ALLOCATE( surf_usm_h%rad_lw_out_change_0(1:surf_usm_h%ns) )
1473          surf_usm_h%rad_lw_out_change_0 = 0.0_wp 
1474       ENDIF
1475       DO  l = 0, 3
1476          IF ( .NOT. ALLOCATED ( surf_lsm_v(l)%rad_lw_out_change_0 )  .AND.    &
1477                     surf_lsm_v(l)%ns > 0  )  THEN
1478             ALLOCATE( surf_lsm_v(l)%rad_lw_out_change_0(1:surf_lsm_v(l)%ns) )
1479             surf_lsm_v(l)%rad_lw_out_change_0 = 0.0_wp 
1480          ENDIF
1481          IF ( .NOT. ALLOCATED ( surf_usm_v(l)%rad_lw_out_change_0 )  .AND.    &
1482                     surf_usm_v(l)%ns > 0  )  THEN
1483             ALLOCATE( surf_usm_v(l)%rad_lw_out_change_0(1:surf_usm_v(l)%ns) )
1484             surf_usm_v(l)%rad_lw_out_change_0 = 0.0_wp 
1485          ENDIF
1486       ENDDO
1487
1488!
1489!--    Allocate surface arrays for incoming/outgoing short/longwave radiation
1490       IF ( .NOT. ALLOCATED ( surf_lsm_h%rad_sw_in )  .AND.                    &
1491                  surf_lsm_h%ns > 0  )   THEN
1492          ALLOCATE( surf_lsm_h%rad_sw_in(1:surf_lsm_h%ns)  )
1493          ALLOCATE( surf_lsm_h%rad_sw_out(1:surf_lsm_h%ns) )
1494          ALLOCATE( surf_lsm_h%rad_lw_in(1:surf_lsm_h%ns)  )
1495          ALLOCATE( surf_lsm_h%rad_lw_out(1:surf_lsm_h%ns) )
1496          surf_lsm_h%rad_sw_in  = 0.0_wp 
1497          surf_lsm_h%rad_sw_out = 0.0_wp 
1498          surf_lsm_h%rad_lw_in  = 0.0_wp 
1499          surf_lsm_h%rad_lw_out = 0.0_wp 
1500       ENDIF
1501       IF ( .NOT. ALLOCATED ( surf_usm_h%rad_sw_in )  .AND.                    &
1502                  surf_usm_h%ns > 0  )  THEN
1503          ALLOCATE( surf_usm_h%rad_sw_in(1:surf_usm_h%ns)  )
1504          ALLOCATE( surf_usm_h%rad_sw_out(1:surf_usm_h%ns) )
1505          ALLOCATE( surf_usm_h%rad_lw_in(1:surf_usm_h%ns)  )
1506          ALLOCATE( surf_usm_h%rad_lw_out(1:surf_usm_h%ns) )
1507          surf_usm_h%rad_sw_in  = 0.0_wp 
1508          surf_usm_h%rad_sw_out = 0.0_wp 
1509          surf_usm_h%rad_lw_in  = 0.0_wp 
1510          surf_usm_h%rad_lw_out = 0.0_wp 
1511       ENDIF
1512       DO  l = 0, 3
1513          IF ( .NOT. ALLOCATED ( surf_lsm_v(l)%rad_sw_in )  .AND.              &
1514                     surf_lsm_v(l)%ns > 0  )  THEN
1515             ALLOCATE( surf_lsm_v(l)%rad_sw_in(1:surf_lsm_v(l)%ns)  )
1516             ALLOCATE( surf_lsm_v(l)%rad_sw_out(1:surf_lsm_v(l)%ns) )
1517             ALLOCATE( surf_lsm_v(l)%rad_lw_in(1:surf_lsm_v(l)%ns)  )
1518             ALLOCATE( surf_lsm_v(l)%rad_lw_out(1:surf_lsm_v(l)%ns) )
1519             surf_lsm_v(l)%rad_sw_in  = 0.0_wp 
1520             surf_lsm_v(l)%rad_sw_out = 0.0_wp 
1521             surf_lsm_v(l)%rad_lw_in  = 0.0_wp 
1522             surf_lsm_v(l)%rad_lw_out = 0.0_wp 
1523          ENDIF
1524          IF ( .NOT. ALLOCATED ( surf_usm_v(l)%rad_sw_in )  .AND.              &
1525                     surf_usm_v(l)%ns > 0  )  THEN
1526             ALLOCATE( surf_usm_v(l)%rad_sw_in(1:surf_usm_v(l)%ns)  )
1527             ALLOCATE( surf_usm_v(l)%rad_sw_out(1:surf_usm_v(l)%ns) )
1528             ALLOCATE( surf_usm_v(l)%rad_lw_in(1:surf_usm_v(l)%ns)  )
1529             ALLOCATE( surf_usm_v(l)%rad_lw_out(1:surf_usm_v(l)%ns) )
1530             surf_usm_v(l)%rad_sw_in  = 0.0_wp 
1531             surf_usm_v(l)%rad_sw_out = 0.0_wp 
1532             surf_usm_v(l)%rad_lw_in  = 0.0_wp 
1533             surf_usm_v(l)%rad_lw_out = 0.0_wp 
1534          ENDIF
1535       ENDDO
1536!
1537!--    Fix net radiation in case of radiation_scheme = 'constant'
1538       IF ( radiation_scheme == 'constant' )  THEN
1539          IF ( ALLOCATED( surf_lsm_h%rad_net ) )                               &
1540             surf_lsm_h%rad_net    = net_radiation
1541          IF ( ALLOCATED( surf_usm_h%rad_net ) )                               &
1542             surf_usm_h%rad_net    = net_radiation
1543!
1544!--       Todo: weight with inclination angle
1545          DO  l = 0, 3
1546             IF ( ALLOCATED( surf_lsm_v(l)%rad_net ) )                         &
1547                surf_lsm_v(l)%rad_net = net_radiation
1548             IF ( ALLOCATED( surf_usm_v(l)%rad_net ) )                         &
1549                surf_usm_v(l)%rad_net = net_radiation
1550          ENDDO
1551!          radiation = .FALSE.
1552!
1553!--    Calculate orbital constants
1554       ELSE
1555          decl_1 = SIN(23.45_wp * pi / 180.0_wp)
1556          decl_2 = 2.0_wp * pi / 365.0_wp
1557          decl_3 = decl_2 * 81.0_wp
1558          lat    = latitude * pi / 180.0_wp
1559          lon    = longitude * pi / 180.0_wp
1560       ENDIF
1561
1562       IF ( radiation_scheme == 'clear-sky'  .OR.                              &
1563            radiation_scheme == 'constant')  THEN
1564
1565
1566!
1567!--       Allocate arrays for incoming/outgoing short/longwave radiation
1568          IF ( .NOT. ALLOCATED ( rad_sw_in ) )  THEN
1569             ALLOCATE ( rad_sw_in(0:0,nysg:nyng,nxlg:nxrg) )
1570          ENDIF
1571          IF ( .NOT. ALLOCATED ( rad_sw_out ) )  THEN
1572             ALLOCATE ( rad_sw_out(0:0,nysg:nyng,nxlg:nxrg) )
1573          ENDIF
1574
1575          IF ( .NOT. ALLOCATED ( rad_lw_in ) )  THEN
1576             ALLOCATE ( rad_lw_in(0:0,nysg:nyng,nxlg:nxrg) )
1577          ENDIF
1578          IF ( .NOT. ALLOCATED ( rad_lw_out ) )  THEN
1579             ALLOCATE ( rad_lw_out(0:0,nysg:nyng,nxlg:nxrg) )
1580          ENDIF
1581
1582!
1583!--       Allocate average arrays for incoming/outgoing short/longwave radiation
1584          IF ( .NOT. ALLOCATED ( rad_sw_in_av ) )  THEN
1585             ALLOCATE ( rad_sw_in_av(0:0,nysg:nyng,nxlg:nxrg) )
1586          ENDIF
1587          IF ( .NOT. ALLOCATED ( rad_sw_out_av ) )  THEN
1588             ALLOCATE ( rad_sw_out_av(0:0,nysg:nyng,nxlg:nxrg) )
1589          ENDIF
1590
1591          IF ( .NOT. ALLOCATED ( rad_lw_in_av ) )  THEN
1592             ALLOCATE ( rad_lw_in_av(0:0,nysg:nyng,nxlg:nxrg) )
1593          ENDIF
1594          IF ( .NOT. ALLOCATED ( rad_lw_out_av ) )  THEN
1595             ALLOCATE ( rad_lw_out_av(0:0,nysg:nyng,nxlg:nxrg) )
1596          ENDIF
1597!
1598!--       Allocate arrays for broadband albedo, and level 1 initialization
1599!--       via namelist paramter, unless already allocated.
1600          IF ( .NOT. ALLOCATED(surf_lsm_h%albedo) )  THEN
1601             ALLOCATE( surf_lsm_h%albedo(0:2,1:surf_lsm_h%ns)     )
1602             surf_lsm_h%albedo    = albedo
1603          ENDIF
1604          IF ( .NOT. ALLOCATED(surf_usm_h%albedo) )  THEN
1605             ALLOCATE( surf_usm_h%albedo(0:2,1:surf_usm_h%ns)     )
1606             surf_usm_h%albedo    = albedo
1607          ENDIF
1608
1609          DO  l = 0, 3
1610             IF ( .NOT. ALLOCATED( surf_lsm_v(l)%albedo ) )  THEN
1611                ALLOCATE( surf_lsm_v(l)%albedo(0:2,1:surf_lsm_v(l)%ns) )
1612                surf_lsm_v(l)%albedo = albedo
1613             ENDIF
1614             IF ( .NOT. ALLOCATED( surf_usm_v(l)%albedo ) )  THEN
1615                ALLOCATE( surf_usm_v(l)%albedo(0:2,1:surf_usm_v(l)%ns) )
1616                surf_usm_v(l)%albedo = albedo
1617             ENDIF
1618          ENDDO
1619!
1620!--       Level 2 initialization of broadband albedo via given albedo_type.
1621!--       Only if albedo_type is non-zero
1622          DO  m = 1, surf_lsm_h%ns
1623             IF ( surf_lsm_h%albedo_type(ind_veg_wall,m) /= 0 )                &
1624                surf_lsm_h%albedo(ind_veg_wall,m) =                            &
1625                           albedo_pars(2,surf_lsm_h%albedo_type(ind_veg_wall,m))
1626             IF ( surf_lsm_h%albedo_type(ind_pav_green,m) /= 0 )               &
1627                surf_lsm_h%albedo(ind_pav_green,m) =                           &
1628                           albedo_pars(2,surf_lsm_h%albedo_type(ind_pav_green,m))
1629             IF ( surf_lsm_h%albedo_type(ind_wat_win,m) /= 0 )                 &
1630                surf_lsm_h%albedo(ind_wat_win,m) =                             &
1631                           albedo_pars(2,surf_lsm_h%albedo_type(ind_wat_win,m))
1632          ENDDO
1633          DO  m = 1, surf_usm_h%ns
1634             IF ( surf_usm_h%albedo_type(ind_veg_wall,m) /= 0 )                &
1635                surf_usm_h%albedo(ind_veg_wall,m) =                            &
1636                           albedo_pars(2,surf_usm_h%albedo_type(ind_veg_wall,m))
1637             IF ( surf_usm_h%albedo_type(ind_pav_green,m) /= 0 )               &
1638                surf_usm_h%albedo(ind_pav_green,m) =                           &
1639                           albedo_pars(2,surf_usm_h%albedo_type(ind_pav_green,m))
1640             IF ( surf_usm_h%albedo_type(ind_wat_win,m) /= 0 )                 &
1641                surf_usm_h%albedo(ind_wat_win,m) =                             &
1642                           albedo_pars(2,surf_usm_h%albedo_type(ind_wat_win,m))
1643          ENDDO
1644
1645          DO  l = 0, 3
1646             DO  m = 1, surf_lsm_v(l)%ns
1647                IF ( surf_lsm_v(l)%albedo_type(ind_veg_wall,m) /= 0 )          &
1648                   surf_lsm_v(l)%albedo(ind_veg_wall,m) =                      &
1649                        albedo_pars(2,surf_lsm_v(l)%albedo_type(ind_veg_wall,m))
1650                IF ( surf_lsm_v(l)%albedo_type(ind_pav_green,m) /= 0 )         &
1651                   surf_lsm_v(l)%albedo(ind_pav_green,m) =                     &
1652                        albedo_pars(2,surf_lsm_v(l)%albedo_type(ind_pav_green,m))
1653                IF ( surf_lsm_v(l)%albedo_type(ind_wat_win,m) /= 0 )           &
1654                   surf_lsm_v(l)%albedo(ind_wat_win,m) =                       &
1655                        albedo_pars(2,surf_lsm_v(l)%albedo_type(ind_wat_win,m))
1656             ENDDO
1657             DO  m = 1, surf_usm_v(l)%ns
1658                IF ( surf_usm_v(l)%albedo_type(ind_veg_wall,m) /= 0 )          &
1659                   surf_usm_v(l)%albedo(ind_veg_wall,m) =                      &
1660                        albedo_pars(2,surf_usm_v(l)%albedo_type(ind_veg_wall,m))
1661                IF ( surf_usm_v(l)%albedo_type(ind_pav_green,m) /= 0 )         &
1662                   surf_usm_v(l)%albedo(ind_pav_green,m) =                     &
1663                        albedo_pars(2,surf_usm_v(l)%albedo_type(ind_pav_green,m))
1664                IF ( surf_usm_v(l)%albedo_type(ind_wat_win,m) /= 0 )           &
1665                   surf_usm_v(l)%albedo(ind_wat_win,m) =                       &
1666                        albedo_pars(2,surf_usm_v(l)%albedo_type(ind_wat_win,m))
1667             ENDDO
1668          ENDDO
1669
1670!
1671!--       Level 3 initialization at grid points where albedo type is zero.
1672!--       This case, albedo is taken from file. In case of constant radiation
1673!--       or clear sky, only broadband albedo is given.
1674          IF ( albedo_pars_f%from_file )  THEN
1675!
1676!--          Horizontal surfaces
1677             DO  m = 1, surf_lsm_h%ns
1678                i = surf_lsm_h%i(m)
1679                j = surf_lsm_h%j(m)
1680                IF ( albedo_pars_f%pars_xy(0,j,i) /= albedo_pars_f%fill )  THEN
1681                   IF ( surf_lsm_h%albedo_type(ind_veg_wall,m) == 0 )          &
1682                      surf_lsm_h%albedo(ind_veg_wall,m) = albedo_pars_f%pars_xy(0,j,i)
1683                   IF ( surf_lsm_h%albedo_type(ind_pav_green,m) == 0 )         &
1684                      surf_lsm_h%albedo(ind_pav_green,m) = albedo_pars_f%pars_xy(0,j,i)
1685                   IF ( surf_lsm_h%albedo_type(ind_wat_win,m) == 0 )           &
1686                      surf_lsm_h%albedo(ind_wat_win,m) = albedo_pars_f%pars_xy(0,j,i)
1687                ENDIF
1688             ENDDO
1689             DO  m = 1, surf_usm_h%ns
1690                i = surf_usm_h%i(m)
1691                j = surf_usm_h%j(m)
1692                IF ( albedo_pars_f%pars_xy(0,j,i) /= albedo_pars_f%fill )  THEN
1693                   IF ( surf_usm_h%albedo_type(ind_veg_wall,m) == 0 )          &
1694                      surf_usm_h%albedo(ind_veg_wall,m) = albedo_pars_f%pars_xy(0,j,i)
1695                   IF ( surf_usm_h%albedo_type(ind_pav_green,m) == 0 )         &
1696                      surf_usm_h%albedo(ind_pav_green,m) = albedo_pars_f%pars_xy(0,j,i)
1697                   IF ( surf_usm_h%albedo_type(ind_wat_win,m) == 0 )           &
1698                      surf_usm_h%albedo(ind_wat_win,m) = albedo_pars_f%pars_xy(0,j,i)
1699                ENDIF
1700             ENDDO 
1701!
1702!--          Vertical surfaces           
1703             DO  l = 0, 3
1704
1705                ioff = surf_lsm_v(l)%ioff
1706                joff = surf_lsm_v(l)%joff
1707                DO  m = 1, surf_lsm_v(l)%ns
1708                   i = surf_lsm_v(l)%i(m) + ioff
1709                   j = surf_lsm_v(l)%j(m) + joff
1710                   IF ( albedo_pars_f%pars_xy(0,j,i) /= albedo_pars_f%fill )  THEN
1711                      IF ( surf_lsm_v(l)%albedo_type(ind_veg_wall,m) == 0 )    &
1712                         surf_lsm_v(l)%albedo(ind_veg_wall,m) = albedo_pars_f%pars_xy(0,j,i)
1713                      IF ( surf_lsm_v(l)%albedo_type(ind_pav_green,m) == 0 )   &
1714                         surf_lsm_v(l)%albedo(ind_pav_green,m) = albedo_pars_f%pars_xy(0,j,i)
1715                      IF ( surf_lsm_v(l)%albedo_type(ind_wat_win,m) == 0 )     &
1716                         surf_lsm_v(l)%albedo(ind_wat_win,m) = albedo_pars_f%pars_xy(0,j,i)
1717                   ENDIF
1718                ENDDO
1719
1720                ioff = surf_usm_v(l)%ioff
1721                joff = surf_usm_v(l)%joff
1722                DO  m = 1, surf_usm_h%ns
1723                   i = surf_usm_h%i(m) + joff
1724                   j = surf_usm_h%j(m) + joff
1725                   IF ( albedo_pars_f%pars_xy(0,j,i) /= albedo_pars_f%fill )  THEN
1726                      IF ( surf_usm_v(l)%albedo_type(ind_veg_wall,m) == 0 )    &
1727                         surf_usm_v(l)%albedo(ind_veg_wall,m) = albedo_pars_f%pars_xy(0,j,i)
1728                      IF ( surf_usm_v(l)%albedo_type(ind_pav_green,m) == 0 )   &
1729                         surf_usm_v(l)%albedo(ind_pav_green,m) = albedo_pars_f%pars_xy(0,j,i)
1730                      IF ( surf_usm_v(l)%albedo_type(ind_wat_win,m) == 0 )     &
1731                         surf_lsm_v(l)%albedo(ind_wat_win,m) = albedo_pars_f%pars_xy(0,j,i)
1732                   ENDIF
1733                ENDDO
1734             ENDDO
1735
1736          ENDIF 
1737!
1738!--    Initialization actions for RRTMG
1739       ELSEIF ( radiation_scheme == 'rrtmg' )  THEN
1740#if defined ( __rrtmg )
1741!
1742!--       Allocate albedos for short/longwave radiation, horizontal surfaces
1743!--       for wall/green/window (USM) or vegetation/pavement/water surfaces
1744!--       (LSM).
1745          ALLOCATE ( surf_lsm_h%aldif(0:2,1:surf_lsm_h%ns)       )
1746          ALLOCATE ( surf_lsm_h%aldir(0:2,1:surf_lsm_h%ns)       )
1747          ALLOCATE ( surf_lsm_h%asdif(0:2,1:surf_lsm_h%ns)       )
1748          ALLOCATE ( surf_lsm_h%asdir(0:2,1:surf_lsm_h%ns)       )
1749          ALLOCATE ( surf_lsm_h%rrtm_aldif(0:2,1:surf_lsm_h%ns)  )
1750          ALLOCATE ( surf_lsm_h%rrtm_aldir(0:2,1:surf_lsm_h%ns)  )
1751          ALLOCATE ( surf_lsm_h%rrtm_asdif(0:2,1:surf_lsm_h%ns)  )
1752          ALLOCATE ( surf_lsm_h%rrtm_asdir(0:2,1:surf_lsm_h%ns)  )
1753
1754          ALLOCATE ( surf_usm_h%aldif(0:2,1:surf_usm_h%ns)       )
1755          ALLOCATE ( surf_usm_h%aldir(0:2,1:surf_usm_h%ns)       )
1756          ALLOCATE ( surf_usm_h%asdif(0:2,1:surf_usm_h%ns)       )
1757          ALLOCATE ( surf_usm_h%asdir(0:2,1:surf_usm_h%ns)       )
1758          ALLOCATE ( surf_usm_h%rrtm_aldif(0:2,1:surf_usm_h%ns)  )
1759          ALLOCATE ( surf_usm_h%rrtm_aldir(0:2,1:surf_usm_h%ns)  )
1760          ALLOCATE ( surf_usm_h%rrtm_asdif(0:2,1:surf_usm_h%ns)  )
1761          ALLOCATE ( surf_usm_h%rrtm_asdir(0:2,1:surf_usm_h%ns)  )
1762
1763!
1764!--       Allocate broadband albedo (temporary for the current radiation
1765!--       implementations)
1766          IF ( .NOT. ALLOCATED(surf_lsm_h%albedo) )                            &
1767             ALLOCATE( surf_lsm_h%albedo(0:2,1:surf_lsm_h%ns)     )
1768          IF ( .NOT. ALLOCATED(surf_usm_h%albedo) )                            &
1769             ALLOCATE( surf_usm_h%albedo(0:2,1:surf_usm_h%ns)     )
1770
1771!
1772!--       Allocate albedos for short/longwave radiation, vertical surfaces
1773          DO  l = 0, 3
1774
1775             ALLOCATE ( surf_lsm_v(l)%aldif(0:2,1:surf_lsm_v(l)%ns)      )
1776             ALLOCATE ( surf_lsm_v(l)%aldir(0:2,1:surf_lsm_v(l)%ns)      )
1777             ALLOCATE ( surf_lsm_v(l)%asdif(0:2,1:surf_lsm_v(l)%ns)      )
1778             ALLOCATE ( surf_lsm_v(l)%asdir(0:2,1:surf_lsm_v(l)%ns)      )
1779
1780             ALLOCATE ( surf_lsm_v(l)%rrtm_aldif(0:2,1:surf_lsm_v(l)%ns) )
1781             ALLOCATE ( surf_lsm_v(l)%rrtm_aldir(0:2,1:surf_lsm_v(l)%ns) )
1782             ALLOCATE ( surf_lsm_v(l)%rrtm_asdif(0:2,1:surf_lsm_v(l)%ns) )
1783             ALLOCATE ( surf_lsm_v(l)%rrtm_asdir(0:2,1:surf_lsm_v(l)%ns) )
1784
1785             ALLOCATE ( surf_usm_v(l)%aldif(0:2,1:surf_usm_v(l)%ns)      )
1786             ALLOCATE ( surf_usm_v(l)%aldir(0:2,1:surf_usm_v(l)%ns)      )
1787             ALLOCATE ( surf_usm_v(l)%asdif(0:2,1:surf_usm_v(l)%ns)      )
1788             ALLOCATE ( surf_usm_v(l)%asdir(0:2,1:surf_usm_v(l)%ns)      )
1789
1790             ALLOCATE ( surf_usm_v(l)%rrtm_aldif(0:2,1:surf_usm_v(l)%ns) )
1791             ALLOCATE ( surf_usm_v(l)%rrtm_aldir(0:2,1:surf_usm_v(l)%ns) )
1792             ALLOCATE ( surf_usm_v(l)%rrtm_asdif(0:2,1:surf_usm_v(l)%ns) )
1793             ALLOCATE ( surf_usm_v(l)%rrtm_asdir(0:2,1:surf_usm_v(l)%ns) )
1794!
1795!--          Allocate broadband albedo (temporary for the current radiation
1796!--          implementations)
1797             IF ( .NOT. ALLOCATED( surf_lsm_v(l)%albedo ) )                    &
1798                ALLOCATE( surf_lsm_v(l)%albedo(0:2,1:surf_lsm_v(l)%ns) )
1799             IF ( .NOT. ALLOCATED( surf_usm_v(l)%albedo ) )                    &
1800                ALLOCATE( surf_usm_v(l)%albedo(0:2,1:surf_usm_v(l)%ns) )
1801
1802          ENDDO
1803!
1804!--       Level 1 initialization of spectral albedos via namelist
1805!--       paramters. Please note, this case all surface tiles are initialized
1806!--       the same.
1807          IF ( surf_lsm_h%ns > 0 )  THEN
1808             surf_lsm_h%aldif  = albedo_lw_dif
1809             surf_lsm_h%aldir  = albedo_lw_dir
1810             surf_lsm_h%asdif  = albedo_sw_dif
1811             surf_lsm_h%asdir  = albedo_sw_dir
1812             surf_lsm_h%albedo = albedo_sw_dif
1813          ENDIF
1814          IF ( surf_usm_h%ns > 0 )  THEN
1815             surf_usm_h%aldif  = albedo_lw_dif
1816             surf_usm_h%aldir  = albedo_lw_dir
1817             surf_usm_h%asdif  = albedo_sw_dif
1818             surf_usm_h%asdir  = albedo_sw_dir
1819             surf_usm_h%albedo = albedo_sw_dif
1820          ENDIF
1821
1822          DO  l = 0, 3
1823
1824             IF ( surf_lsm_v(l)%ns > 0 )  THEN
1825                surf_lsm_v(l)%aldif  = albedo_lw_dif
1826                surf_lsm_v(l)%aldir  = albedo_lw_dir
1827                surf_lsm_v(l)%asdif  = albedo_sw_dif
1828                surf_lsm_v(l)%asdir  = albedo_sw_dir
1829                surf_lsm_v(l)%albedo = albedo_sw_dif
1830             ENDIF
1831
1832             IF ( surf_usm_v(l)%ns > 0 )  THEN
1833                surf_usm_v(l)%aldif  = albedo_lw_dif
1834                surf_usm_v(l)%aldir  = albedo_lw_dir
1835                surf_usm_v(l)%asdif  = albedo_sw_dif
1836                surf_usm_v(l)%asdir  = albedo_sw_dir
1837                surf_usm_v(l)%albedo = albedo_sw_dif
1838             ENDIF
1839          ENDDO
1840
1841!
1842!--       Level 2 initialization of spectral albedos via albedo_type.
1843!--       Please note, for natural- and urban-type surfaces, a tile approach
1844!--       is applied so that the resulting albedo is calculated via the weighted
1845!--       average of respective surface fractions.
1846          DO  m = 1, surf_lsm_h%ns
1847!
1848!--          Spectral albedos for vegetation/pavement/water surfaces
1849             DO  ind_type = 0, 2
1850                IF ( surf_lsm_h%albedo_type(ind_type,m) /= 0 )  THEN
1851                   surf_lsm_h%aldif(ind_type,m) =                              &
1852                               albedo_pars(0,surf_lsm_h%albedo_type(ind_type,m))
1853                   surf_lsm_h%asdif(ind_type,m) =                              &
1854                               albedo_pars(1,surf_lsm_h%albedo_type(ind_type,m))
1855                   surf_lsm_h%aldir(ind_type,m) =                              &
1856                               albedo_pars(0,surf_lsm_h%albedo_type(ind_type,m))
1857                   surf_lsm_h%asdir(ind_type,m) =                              &
1858                               albedo_pars(1,surf_lsm_h%albedo_type(ind_type,m))
1859                   surf_lsm_h%albedo(ind_type,m) =                             &
1860                               albedo_pars(2,surf_lsm_h%albedo_type(ind_type,m))
1861                ENDIF
1862             ENDDO
1863
1864          ENDDO
1865
1866          DO  m = 1, surf_usm_h%ns
1867!
1868!--          Spectral albedos for wall/green/window surfaces
1869             DO  ind_type = 0, 2
1870                IF ( surf_usm_h%albedo_type(ind_type,m) /= 0 )  THEN
1871                   surf_usm_h%aldif(ind_type,m) =                              &
1872                               albedo_pars(0,surf_usm_h%albedo_type(ind_type,m))
1873                   surf_usm_h%asdif(ind_type,m) =                              &
1874                               albedo_pars(1,surf_usm_h%albedo_type(ind_type,m))
1875                   surf_usm_h%aldir(ind_type,m) =                              &
1876                               albedo_pars(0,surf_usm_h%albedo_type(ind_type,m))
1877                   surf_usm_h%asdir(ind_type,m) =                              &
1878                               albedo_pars(1,surf_usm_h%albedo_type(ind_type,m))
1879                   surf_usm_h%albedo(ind_type,m) =                             &
1880                               albedo_pars(2,surf_usm_h%albedo_type(ind_type,m))
1881                ENDIF
1882             ENDDO
1883
1884          ENDDO
1885
1886          DO l = 0, 3
1887
1888             DO  m = 1, surf_lsm_v(l)%ns
1889!
1890!--             Spectral albedos for vegetation/pavement/water surfaces
1891                DO  ind_type = 0, 2
1892                   IF ( surf_lsm_v(l)%albedo_type(ind_type,m) /= 0 )  THEN
1893                      surf_lsm_v(l)%aldif(ind_type,m) =                        &
1894                            albedo_pars(0,surf_lsm_v(l)%albedo_type(ind_type,m))
1895                      surf_lsm_v(l)%asdif(ind_type,m) =                        &
1896                            albedo_pars(1,surf_lsm_v(l)%albedo_type(ind_type,m))
1897                      surf_lsm_v(l)%aldir(ind_type,m) =                        &
1898                            albedo_pars(0,surf_lsm_v(l)%albedo_type(ind_type,m))
1899                      surf_lsm_v(l)%asdir(ind_type,m) =                        &
1900                            albedo_pars(1,surf_lsm_v(l)%albedo_type(ind_type,m))
1901                      surf_lsm_v(l)%albedo(ind_type,m) =                       &
1902                            albedo_pars(2,surf_lsm_v(l)%albedo_type(ind_type,m))
1903                   ENDIF
1904                ENDDO
1905             ENDDO
1906
1907             DO  m = 1, surf_usm_v(l)%ns
1908!
1909!--             Spectral albedos for wall/green/window surfaces
1910                DO  ind_type = 0, 2
1911                   IF ( surf_usm_v(l)%albedo_type(ind_type,m) /= 0 )  THEN
1912                      surf_usm_v(l)%aldif(ind_type,m) =                        &
1913                            albedo_pars(0,surf_usm_v(l)%albedo_type(ind_type,m))
1914                      surf_usm_v(l)%asdif(ind_type,m) =                        &
1915                            albedo_pars(1,surf_usm_v(l)%albedo_type(ind_type,m))
1916                      surf_usm_v(l)%aldir(ind_type,m) =                        &
1917                            albedo_pars(0,surf_usm_v(l)%albedo_type(ind_type,m))
1918                      surf_usm_v(l)%asdir(ind_type,m) =                        &
1919                            albedo_pars(1,surf_usm_v(l)%albedo_type(ind_type,m))
1920                      surf_usm_v(l)%albedo(ind_type,m) =                       &
1921                            albedo_pars(2,surf_usm_v(l)%albedo_type(ind_type,m))
1922                   ENDIF
1923                ENDDO
1924
1925             ENDDO
1926          ENDDO
1927!
1928!--       Level 3 initialization at grid points where albedo type is zero.
1929!--       This case, spectral albedos are taken from file if available
1930          IF ( albedo_pars_f%from_file )  THEN
1931!
1932!--          Horizontal
1933             DO  m = 1, surf_lsm_h%ns
1934                i = surf_lsm_h%i(m)
1935                j = surf_lsm_h%j(m)
1936!
1937!--             Spectral albedos for vegetation/pavement/water surfaces
1938                DO  ind_type = 0, 2
1939                   IF ( surf_lsm_h%albedo_type(ind_type,m) == 0 )  THEN
1940                      IF ( albedo_pars_f%pars_xy(1,j,i) /= albedo_pars_f%fill )&
1941                         surf_lsm_h%albedo(ind_type,m) =                       &
1942                                                albedo_pars_f%pars_xy(1,j,i)
1943                      IF ( albedo_pars_f%pars_xy(1,j,i) /= albedo_pars_f%fill )&
1944                         surf_lsm_h%aldir(ind_type,m) =                        &
1945                                                albedo_pars_f%pars_xy(1,j,i)
1946                      IF ( albedo_pars_f%pars_xy(2,j,i) /= albedo_pars_f%fill )&
1947                         surf_lsm_h%aldif(ind_type,m) =                        &
1948                                                albedo_pars_f%pars_xy(2,j,i)
1949                      IF ( albedo_pars_f%pars_xy(3,j,i) /= albedo_pars_f%fill )&
1950                         surf_lsm_h%asdir(ind_type,m) =                        &
1951                                                albedo_pars_f%pars_xy(3,j,i)
1952                      IF ( albedo_pars_f%pars_xy(4,j,i) /= albedo_pars_f%fill )&
1953                         surf_lsm_h%asdif(ind_type,m) =                        &
1954                                                albedo_pars_f%pars_xy(4,j,i)
1955                   ENDIF
1956                ENDDO
1957             ENDDO
1958
1959             DO  m = 1, surf_usm_h%ns
1960                i = surf_usm_h%i(m)
1961                j = surf_usm_h%j(m)
1962!
1963!--             Spectral albedos for wall/green/window surfaces
1964                DO  ind_type = 0, 2
1965                   IF ( surf_usm_h%albedo_type(ind_type,m) == 0 )  THEN
1966                      IF ( albedo_pars_f%pars_xy(1,j,i) /= albedo_pars_f%fill )&
1967                         surf_usm_h%albedo(ind_type,m) =                       &
1968                                                albedo_pars_f%pars_xy(1,j,i)
1969                      IF ( albedo_pars_f%pars_xy(1,j,i) /= albedo_pars_f%fill )&
1970                         surf_usm_h%aldir(ind_type,m) =                        &
1971                                                albedo_pars_f%pars_xy(1,j,i)
1972                      IF ( albedo_pars_f%pars_xy(2,j,i) /= albedo_pars_f%fill )&
1973                         surf_usm_h%aldif(ind_type,m) =                        &
1974                                                albedo_pars_f%pars_xy(2,j,i)
1975                      IF ( albedo_pars_f%pars_xy(3,j,i) /= albedo_pars_f%fill )&
1976                         surf_usm_h%asdir(ind_type,m) =                        &
1977                                                albedo_pars_f%pars_xy(3,j,i)
1978                      IF ( albedo_pars_f%pars_xy(4,j,i) /= albedo_pars_f%fill )&
1979                         surf_usm_h%asdif(ind_type,m) =                        &
1980                                                albedo_pars_f%pars_xy(4,j,i)
1981                   ENDIF
1982                ENDDO
1983
1984             ENDDO
1985!
1986!--          Vertical
1987             DO  l = 0, 3
1988                ioff = surf_lsm_v(l)%ioff
1989                joff = surf_lsm_v(l)%joff
1990
1991                DO  m = 1, surf_lsm_v(l)%ns
1992                   i = surf_lsm_v(l)%i(m)
1993                   j = surf_lsm_v(l)%j(m)
1994!
1995!--                Spectral albedos for vegetation/pavement/water surfaces
1996                   DO  ind_type = 0, 2
1997                      IF ( surf_lsm_v(l)%albedo_type(ind_type,m) == 0 )  THEN
1998                         IF ( albedo_pars_f%pars_xy(1,j+joff,i+ioff) /=        &
1999                              albedo_pars_f%fill )                             &
2000                            surf_lsm_v(l)%albedo(ind_type,m) =                 &
2001                                          albedo_pars_f%pars_xy(1,j+joff,i+ioff)
2002                         IF ( albedo_pars_f%pars_xy(1,j+joff,i+ioff) /=        &
2003                              albedo_pars_f%fill )                             &
2004                            surf_lsm_v(l)%aldir(ind_type,m) =                  &
2005                                          albedo_pars_f%pars_xy(1,j+joff,i+ioff)
2006                         IF ( albedo_pars_f%pars_xy(2,j+joff,i+ioff) /=        &
2007                              albedo_pars_f%fill )                             &
2008                            surf_lsm_v(l)%aldif(ind_type,m) =                  &
2009                                          albedo_pars_f%pars_xy(2,j+joff,i+ioff)
2010                         IF ( albedo_pars_f%pars_xy(3,j+joff,i+ioff) /=        &
2011                              albedo_pars_f%fill )                             &
2012                            surf_lsm_v(l)%asdir(ind_type,m) =                  &
2013                                          albedo_pars_f%pars_xy(3,j+joff,i+ioff)
2014                         IF ( albedo_pars_f%pars_xy(4,j+joff,i+ioff) /=        &
2015                              albedo_pars_f%fill )                             &
2016                            surf_lsm_v(l)%asdif(ind_type,m) =                  &
2017                                          albedo_pars_f%pars_xy(4,j+joff,i+ioff)
2018                      ENDIF
2019                   ENDDO
2020                ENDDO
2021
2022                ioff = surf_usm_v(l)%ioff
2023                joff = surf_usm_v(l)%joff
2024
2025                DO  m = 1, surf_usm_v(l)%ns
2026                   i = surf_usm_v(l)%i(m)
2027                   j = surf_usm_v(l)%j(m)
2028!
2029!--                Spectral albedos for wall/green/window surfaces
2030                   DO  ind_type = 0, 2
2031                      IF ( surf_usm_v(l)%albedo_type(ind_type,m) == 0 )  THEN
2032                         IF ( albedo_pars_f%pars_xy(1,j+joff,i+ioff) /=        &
2033                              albedo_pars_f%fill )                             &
2034                            surf_usm_v(l)%albedo(ind_type,m) =                 &
2035                                          albedo_pars_f%pars_xy(1,j+joff,i+ioff)
2036                         IF ( albedo_pars_f%pars_xy(1,j+joff,i+ioff) /=        &
2037                              albedo_pars_f%fill )                             &
2038                            surf_usm_v(l)%aldir(ind_type,m) =                  &
2039                                          albedo_pars_f%pars_xy(1,j+joff,i+ioff)
2040                         IF ( albedo_pars_f%pars_xy(2,j+joff,i+ioff) /=        &
2041                              albedo_pars_f%fill )                             &
2042                            surf_usm_v(l)%aldif(ind_type,m) =                  &
2043                                          albedo_pars_f%pars_xy(2,j+joff,i+ioff)
2044                         IF ( albedo_pars_f%pars_xy(3,j+joff,i+ioff) /=        &
2045                              albedo_pars_f%fill )                             &
2046                            surf_usm_v(l)%asdir(ind_type,m) =                  &
2047                                          albedo_pars_f%pars_xy(3,j+joff,i+ioff)
2048                         IF ( albedo_pars_f%pars_xy(4,j+joff,i+ioff) /=        &
2049                              albedo_pars_f%fill )                             &
2050                            surf_usm_v(l)%asdif(ind_type,m) =                  &
2051                                          albedo_pars_f%pars_xy(4,j+joff,i+ioff)
2052                      ENDIF
2053                   ENDDO
2054
2055                ENDDO
2056             ENDDO
2057
2058          ENDIF
2059
2060!
2061!--       Calculate initial values of current (cosine of) the zenith angle and
2062!--       whether the sun is up
2063          CALL calc_zenith     
2064!
2065!--       Calculate initial surface albedo for different surfaces
2066          IF ( .NOT. constant_albedo )  THEN
2067!
2068!--          Horizontally aligned natural and urban surfaces
2069             CALL calc_albedo( surf_lsm_h    )
2070             CALL calc_albedo( surf_usm_h    )
2071!
2072!--          Vertically aligned natural and urban surfaces
2073             DO  l = 0, 3
2074                CALL calc_albedo( surf_lsm_v(l) )
2075                CALL calc_albedo( surf_usm_v(l) )
2076             ENDDO
2077          ELSE
2078!
2079!--          Initialize sun-inclination independent spectral albedos
2080!--          Horizontal surfaces
2081             IF ( surf_lsm_h%ns > 0 )  THEN
2082                surf_lsm_h%rrtm_aldir = surf_lsm_h%aldir
2083                surf_lsm_h%rrtm_asdir = surf_lsm_h%asdir
2084                surf_lsm_h%rrtm_aldif = surf_lsm_h%aldif
2085                surf_lsm_h%rrtm_asdif = surf_lsm_h%asdif
2086             ENDIF
2087             IF ( surf_usm_h%ns > 0 )  THEN
2088                surf_usm_h%rrtm_aldir = surf_usm_h%aldir
2089                surf_usm_h%rrtm_asdir = surf_usm_h%asdir
2090                surf_usm_h%rrtm_aldif = surf_usm_h%aldif
2091                surf_usm_h%rrtm_asdif = surf_usm_h%asdif
2092             ENDIF
2093!
2094!--          Vertical surfaces
2095             DO  l = 0, 3
2096                IF ( surf_lsm_v(l)%ns > 0 )  THEN
2097                   surf_lsm_v(l)%rrtm_aldir = surf_lsm_v(l)%aldir
2098                   surf_lsm_v(l)%rrtm_asdir = surf_lsm_v(l)%asdir
2099                   surf_lsm_v(l)%rrtm_aldif = surf_lsm_v(l)%aldif
2100                   surf_lsm_v(l)%rrtm_asdif = surf_lsm_v(l)%asdif
2101                ENDIF
2102                IF ( surf_usm_v(l)%ns > 0 )  THEN
2103                   surf_usm_v(l)%rrtm_aldir = surf_usm_v(l)%aldir
2104                   surf_usm_v(l)%rrtm_asdir = surf_usm_v(l)%asdir
2105                   surf_usm_v(l)%rrtm_aldif = surf_usm_v(l)%aldif
2106                   surf_usm_v(l)%rrtm_asdif = surf_usm_v(l)%asdif
2107                ENDIF
2108             ENDDO
2109
2110          ENDIF
2111
2112!
2113!--       Allocate 3d arrays of radiative fluxes and heating rates
2114          IF ( .NOT. ALLOCATED ( rad_sw_in ) )  THEN
2115             ALLOCATE ( rad_sw_in(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2116             rad_sw_in = 0.0_wp
2117          ENDIF
2118
2119          IF ( .NOT. ALLOCATED ( rad_sw_in_av ) )  THEN
2120             ALLOCATE ( rad_sw_in_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2121          ENDIF
2122
2123          IF ( .NOT. ALLOCATED ( rad_sw_out ) )  THEN
2124             ALLOCATE ( rad_sw_out(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2125             rad_sw_out = 0.0_wp
2126          ENDIF
2127
2128          IF ( .NOT. ALLOCATED ( rad_sw_out_av ) )  THEN
2129             ALLOCATE ( rad_sw_out_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2130          ENDIF
2131
2132          IF ( .NOT. ALLOCATED ( rad_sw_hr ) )  THEN
2133             ALLOCATE ( rad_sw_hr(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2134             rad_sw_hr = 0.0_wp
2135          ENDIF
2136
2137          IF ( .NOT. ALLOCATED ( rad_sw_hr_av ) )  THEN
2138             ALLOCATE ( rad_sw_hr_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2139             rad_sw_hr_av = 0.0_wp
2140          ENDIF
2141
2142          IF ( .NOT. ALLOCATED ( rad_sw_cs_hr ) )  THEN
2143             ALLOCATE ( rad_sw_cs_hr(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2144             rad_sw_cs_hr = 0.0_wp
2145          ENDIF
2146
2147          IF ( .NOT. ALLOCATED ( rad_sw_cs_hr_av ) )  THEN
2148             ALLOCATE ( rad_sw_cs_hr_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2149             rad_sw_cs_hr_av = 0.0_wp
2150          ENDIF
2151
2152          IF ( .NOT. ALLOCATED ( rad_lw_in ) )  THEN
2153             ALLOCATE ( rad_lw_in(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2154             rad_lw_in     = 0.0_wp
2155          ENDIF
2156
2157          IF ( .NOT. ALLOCATED ( rad_lw_in_av ) )  THEN
2158             ALLOCATE ( rad_lw_in_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2159          ENDIF
2160
2161          IF ( .NOT. ALLOCATED ( rad_lw_out ) )  THEN
2162             ALLOCATE ( rad_lw_out(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2163            rad_lw_out    = 0.0_wp
2164          ENDIF
2165
2166          IF ( .NOT. ALLOCATED ( rad_lw_out_av ) )  THEN
2167             ALLOCATE ( rad_lw_out_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2168          ENDIF
2169
2170          IF ( .NOT. ALLOCATED ( rad_lw_hr ) )  THEN
2171             ALLOCATE ( rad_lw_hr(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2172             rad_lw_hr = 0.0_wp
2173          ENDIF
2174
2175          IF ( .NOT. ALLOCATED ( rad_lw_hr_av ) )  THEN
2176             ALLOCATE ( rad_lw_hr_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2177             rad_lw_hr_av = 0.0_wp
2178          ENDIF
2179
2180          IF ( .NOT. ALLOCATED ( rad_lw_cs_hr ) )  THEN
2181             ALLOCATE ( rad_lw_cs_hr(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2182             rad_lw_cs_hr = 0.0_wp
2183          ENDIF
2184
2185          IF ( .NOT. ALLOCATED ( rad_lw_cs_hr_av ) )  THEN
2186             ALLOCATE ( rad_lw_cs_hr_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2187             rad_lw_cs_hr_av = 0.0_wp
2188          ENDIF
2189
2190          ALLOCATE ( rad_sw_cs_in(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2191          ALLOCATE ( rad_sw_cs_out(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2192          rad_sw_cs_in  = 0.0_wp
2193          rad_sw_cs_out = 0.0_wp
2194
2195          ALLOCATE ( rad_lw_cs_in(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2196          ALLOCATE ( rad_lw_cs_out(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2197          rad_lw_cs_in  = 0.0_wp
2198          rad_lw_cs_out = 0.0_wp
2199
2200!
2201!--       Allocate 1-element array for surface temperature
2202!--       (RRTMG anticipates an array as passed argument).
2203          ALLOCATE ( rrtm_tsfc(1) )
2204!
2205!--       Allocate surface emissivity.
2206!--       Values will be given directly before calling rrtm_lw.
2207          ALLOCATE ( rrtm_emis(0:0,1:nbndlw+1) )
2208
2209!
2210!--       Initialize RRTMG
2211          IF ( lw_radiation )  CALL rrtmg_lw_ini ( cp )
2212          IF ( sw_radiation )  CALL rrtmg_sw_ini ( cp )
2213
2214!
2215!--       Set input files for RRTMG
2216          INQUIRE(FILE="RAD_SND_DATA", EXIST=snd_exists) 
2217          IF ( .NOT. snd_exists )  THEN
2218             rrtm_input_file = "rrtmg_lw.nc"
2219          ENDIF
2220
2221!
2222!--       Read vertical layers for RRTMG from sounding data
2223!--       The routine provides nzt_rad, hyp_snd(1:nzt_rad),
2224!--       t_snd(nzt+2:nzt_rad), rrtm_play(1:nzt_rad), rrtm_plev(1_nzt_rad+1),
2225!--       rrtm_tlay(nzt+2:nzt_rad), rrtm_tlev(nzt+2:nzt_rad+1)
2226          CALL read_sounding_data
2227
2228!
2229!--       Read trace gas profiles from file. This routine provides
2230!--       the rrtm_ arrays (1:nzt_rad+1)
2231          CALL read_trace_gas_data
2232#endif
2233       ENDIF
2234
2235!
2236!--    Perform user actions if required
2237       CALL user_init_radiation
2238
2239!
2240!--    Calculate radiative fluxes at model start
2241       SELECT CASE ( TRIM( radiation_scheme ) )
2242
2243          CASE ( 'rrtmg' )
2244             CALL radiation_rrtmg
2245
2246          CASE ( 'clear-sky' )
2247             CALL radiation_clearsky
2248
2249          CASE ( 'constant' )
2250             CALL radiation_constant
2251
2252          CASE DEFAULT
2253
2254       END SELECT
2255
2256       RETURN
2257
2258    END SUBROUTINE radiation_init
2259
2260
2261!------------------------------------------------------------------------------!
2262! Description:
2263! ------------
2264!> A simple clear sky radiation model
2265!------------------------------------------------------------------------------!
2266    SUBROUTINE radiation_clearsky
2267
2268
2269       IMPLICIT NONE
2270
2271       INTEGER(iwp) ::  l         !< running index for surface orientation
2272
2273       REAL(wp)     ::  exn       !< Exner functions at surface
2274       REAL(wp)     ::  exn1      !< Exner functions at first grid level or at urban layer top
2275       REAL(wp)     ::  pt1       !< potential temperature at first grid level or mean value at urban layer top
2276       REAL(wp)     ::  pt1_l     !< potential temperature at first grid level or mean value at urban layer top at local subdomain
2277       REAL(wp)     ::  ql1       !< liquid water mixing ratio at first grid level or mean value at urban layer top
2278       REAL(wp)     ::  ql1_l     !< liquid water mixing ratio at first grid level or mean value at urban layer top at local subdomain
2279
2280       TYPE(surf_type), POINTER ::  surf !< pointer on respective surface type, used to generalize routine   
2281
2282!
2283!--    Calculate current zenith angle
2284       CALL calc_zenith
2285
2286!
2287!--    Calculate sky transmissivity
2288       sky_trans = 0.6_wp + 0.2_wp * zenith(0)
2289
2290!
2291!--    Calculate value of the Exner function at model surface
2292       exn = (surface_pressure / 1000.0_wp )**0.286_wp
2293!
2294!--    In case averaged radiation is used, calculate mean temperature and
2295!--    liquid water mixing ratio at the urban-layer top.
2296       IF ( average_radiation ) THEN   
2297          pt1   = 0.0_wp
2298          IF ( cloud_physics )  ql1   = 0.0_wp
2299
2300          pt1_l = SUM( pt(nzut,nys:nyn,nxl:nxr) )
2301          IF ( cloud_physics )  ql1_l = SUM( ql(nzut,nys:nyn,nxl:nxr) )
2302
2303#if defined( __parallel )     
2304          IF ( collective_wait )  CALL MPI_BARRIER( comm2d, ierr )
2305          CALL MPI_ALLREDUCE( pt1_l, pt1, 1, MPI_REAL, MPI_SUM, comm2d, ierr )
2306          IF ( cloud_physics )                                                 &
2307             CALL MPI_ALLREDUCE( ql1_l, ql1, 1, MPI_REAL, MPI_SUM, comm2d, ierr )
2308#else
2309          pt1 = pt1_l 
2310          IF ( cloud_physics )  ql1 = ql1_l
2311#endif
2312 
2313          exn1 = ( hyp(nzut) / 100000.0_wp )**0.286_wp
2314          IF ( cloud_physics )  pt1 = pt1 + l_d_cp / exn1 * ql1
2315!
2316!--       Finally, divide by number of grid points
2317          pt1 = pt1 / REAL( ( nx + 1 ) * ( ny + 1 ), KIND=wp )
2318       ENDIF
2319!
2320!--    Call clear-sky calculation for each surface orientation.
2321!--    First, horizontal surfaces
2322       surf => surf_lsm_h
2323       CALL radiation_clearsky_surf
2324       surf => surf_usm_h
2325       CALL radiation_clearsky_surf
2326!
2327!--    Vertical surfaces
2328       DO  l = 0, 3
2329          surf => surf_lsm_v(l)
2330          CALL radiation_clearsky_surf
2331          surf => surf_usm_v(l)
2332          CALL radiation_clearsky_surf
2333       ENDDO
2334
2335       CONTAINS
2336
2337          SUBROUTINE radiation_clearsky_surf
2338
2339             IMPLICIT NONE
2340
2341             INTEGER(iwp) ::  i         !< index x-direction
2342             INTEGER(iwp) ::  j         !< index y-direction
2343             INTEGER(iwp) ::  k         !< index z-direction
2344             INTEGER(iwp) ::  m         !< running index for surface elements
2345
2346             IF ( surf%ns < 1 )  RETURN
2347
2348!
2349!--          Calculate radiation fluxes and net radiation (rad_net) assuming
2350!--          homogeneous urban radiation conditions.
2351             IF ( average_radiation ) THEN       
2352
2353                k = nzut
2354
2355                exn1 = ( hyp(k+1) / 100000.0_wp )**0.286_wp
2356
2357                surf%rad_sw_in  = solar_constant * sky_trans * zenith(0)
2358                surf%rad_sw_out = albedo_urb * surf%rad_sw_in
2359               
2360                surf%rad_lw_in  = 0.8_wp * sigma_sb * (pt1 * exn1)**4
2361
2362                surf%rad_lw_out = emissivity_urb * sigma_sb * (t_rad_urb)**4   &
2363                                    + (1.0_wp - emissivity_urb) * surf%rad_lw_in
2364
2365                surf%rad_net = surf%rad_sw_in - surf%rad_sw_out                &
2366                             + surf%rad_lw_in - surf%rad_lw_out
2367
2368                surf%rad_lw_out_change_0 = 3.0_wp * emissivity_urb * sigma_sb  &
2369                                           * (t_rad_urb)**3
2370
2371!
2372!--          Calculate radiation fluxes and net radiation (rad_net) for each surface
2373!--          element.
2374             ELSE
2375
2376                DO  m = 1, surf%ns
2377                   i = surf%i(m)
2378                   j = surf%j(m)
2379                   k = surf%k(m)
2380
2381                   exn1 = (hyp(k) / 100000.0_wp )**0.286_wp
2382
2383                   surf%rad_sw_in(m) = solar_constant * sky_trans * zenith(0)
2384
2385!
2386!--                Weighted average according to surface fraction.
2387!--                ATTENTION: when radiation interactions are switched on the
2388!--                calculated fluxes below are not actually used as they are
2389!--                overwritten in radiation_interaction.
2390                   surf%rad_sw_out(m) = ( surf%frac(ind_veg_wall,m)  *         &
2391                                          surf%albedo(ind_veg_wall,m)          &
2392                                        + surf%frac(ind_pav_green,m) *         &
2393                                          surf%albedo(ind_pav_green,m)         &
2394                                        + surf%frac(ind_wat_win,m)   *         &
2395                                          surf%albedo(ind_wat_win,m) )         &
2396                                        * surf%rad_sw_in(m)
2397
2398                   surf%rad_lw_out(m) = ( surf%frac(ind_veg_wall,m)  *         &
2399                                          surf%emissivity(ind_veg_wall,m)      &
2400                                        + surf%frac(ind_pav_green,m) *         &
2401                                          surf%emissivity(ind_pav_green,m)     &
2402                                        + surf%frac(ind_wat_win,m)   *         &
2403                                          surf%emissivity(ind_wat_win,m)       &
2404                                        )                                      &
2405                                        * sigma_sb                             &
2406                                        * ( surf%pt_surface(m) * exn )**4
2407
2408                   surf%rad_lw_out_change_0(m) =                               &
2409                                      ( surf%frac(ind_veg_wall,m)  *           &
2410                                        surf%emissivity(ind_veg_wall,m)        &
2411                                      + surf%frac(ind_pav_green,m) *           &
2412                                        surf%emissivity(ind_pav_green,m)       &
2413                                      + surf%frac(ind_wat_win,m)   *           &
2414                                        surf%emissivity(ind_wat_win,m)         &
2415                                      ) * 3.0_wp * sigma_sb                    &
2416                                      * ( surf%pt_surface(m) * exn )** 3
2417
2418
2419                   IF ( cloud_physics )  THEN
2420                      pt1 = pt(k,j,i) + l_d_cp / exn1 * ql(k,j,i)
2421                      surf%rad_lw_in(m)  = 0.8_wp * sigma_sb * (pt1 * exn1)**4
2422                   ELSE
2423                      surf%rad_lw_in(m)  = 0.8_wp * sigma_sb * (pt(k,j,i) * exn1)**4
2424                   ENDIF
2425
2426                   surf%rad_net(m) = surf%rad_sw_in(m) - surf%rad_sw_out(m)    &
2427                                   + surf%rad_lw_in(m) - surf%rad_lw_out(m)
2428
2429                ENDDO
2430
2431             ENDIF
2432
2433!
2434!--          Fill out values in radiation arrays
2435             DO  m = 1, surf%ns
2436                i = surf%i(m)
2437                j = surf%j(m)
2438                rad_sw_in(0,j,i) = surf%rad_sw_in(m)
2439                rad_sw_out(0,j,i) = surf%rad_sw_out(m)
2440                rad_lw_in(0,j,i) = surf%rad_lw_in(m)
2441                rad_lw_out(0,j,i) = surf%rad_lw_out(m)
2442             ENDDO
2443 
2444          END SUBROUTINE radiation_clearsky_surf
2445
2446    END SUBROUTINE radiation_clearsky
2447
2448
2449!------------------------------------------------------------------------------!
2450! Description:
2451! ------------
2452!> This scheme keeps the prescribed net radiation constant during the run
2453!------------------------------------------------------------------------------!
2454    SUBROUTINE radiation_constant
2455
2456
2457       IMPLICIT NONE
2458
2459       INTEGER(iwp) ::  l         !< running index for surface orientation
2460
2461       REAL(wp)     ::  exn       !< Exner functions at surface
2462       REAL(wp)     ::  exn1      !< Exner functions at first grid level
2463       REAL(wp)     ::  pt1       !< potential temperature at first grid level or mean value at urban layer top
2464       REAL(wp)     ::  pt1_l     !< potential temperature at first grid level or mean value at urban layer top at local subdomain
2465       REAL(wp)     ::  ql1       !< liquid water mixing ratio at first grid level or mean value at urban layer top
2466       REAL(wp)     ::  ql1_l     !< liquid water mixing ratio at first grid level or mean value at urban layer top at local subdomain
2467
2468       TYPE(surf_type), POINTER ::  surf !< pointer on respective surface type, used to generalize routine   
2469
2470!
2471!--    Calculate value of the Exner function
2472       exn = (surface_pressure / 1000.0_wp )**0.286_wp
2473!
2474!--    In case averaged radiation is used, calculate mean temperature and
2475!--    liquid water mixing ratio at the urban-layer top.
2476       IF ( average_radiation ) THEN   
2477          pt1   = 0.0_wp
2478          IF ( cloud_physics )  ql1   = 0.0_wp
2479
2480          pt1_l = SUM( pt(nzut,nys:nyn,nxl:nxr) )
2481          IF ( cloud_physics )  ql1_l = SUM( ql(nzut,nys:nyn,nxl:nxr) )
2482
2483#if defined( __parallel )     
2484          IF ( collective_wait )  CALL MPI_BARRIER( comm2d, ierr )
2485          CALL MPI_ALLREDUCE( pt1_l, pt1, 1, MPI_REAL, MPI_SUM, comm2d, ierr )
2486          IF ( cloud_physics )                                                 &
2487             CALL MPI_ALLREDUCE( ql1_l, ql1, 1, MPI_REAL, MPI_SUM, comm2d, ierr )
2488#else
2489          pt1 = pt1_l
2490          IF ( cloud_physics )  ql1 = ql1_l
2491#endif
2492          IF ( cloud_physics )  pt1 = pt1 + l_d_cp / exn1 * ql1
2493!
2494!--       Finally, divide by number of grid points
2495          pt1 = pt1 / REAL( ( nx + 1 ) * ( ny + 1 ), KIND=wp )
2496       ENDIF
2497
2498!
2499!--    First, horizontal surfaces
2500       surf => surf_lsm_h
2501       CALL radiation_constant_surf
2502       surf => surf_usm_h
2503       CALL radiation_constant_surf
2504!
2505!--    Vertical surfaces
2506       DO  l = 0, 3
2507          surf => surf_lsm_v(l)
2508          CALL radiation_constant_surf
2509          surf => surf_usm_v(l)
2510          CALL radiation_constant_surf
2511       ENDDO
2512
2513       CONTAINS
2514
2515          SUBROUTINE radiation_constant_surf
2516
2517             IMPLICIT NONE
2518
2519             INTEGER(iwp) ::  i         !< index x-direction
2520             INTEGER(iwp) ::  ioff      !< offset between surface element and adjacent grid point along x
2521             INTEGER(iwp) ::  j         !< index y-direction
2522             INTEGER(iwp) ::  joff      !< offset between surface element and adjacent grid point along y
2523             INTEGER(iwp) ::  k         !< index z-direction
2524             INTEGER(iwp) ::  koff      !< offset between surface element and adjacent grid point along z
2525             INTEGER(iwp) ::  m         !< running index for surface elements
2526
2527             IF ( surf%ns < 1 )  RETURN
2528
2529!--          Calculate homogenoeus urban radiation fluxes
2530             IF ( average_radiation ) THEN
2531
2532                ! set height above canopy
2533                k = nzut
2534
2535                surf%rad_net = net_radiation
2536! MS: Wyh k + 1 ?
2537                exn1 = (hyp(k+1) / 100000.0_wp )**0.286_wp
2538
2539                surf%rad_lw_in  = 0.8_wp * sigma_sb * (pt1 * exn1)**4
2540
2541                surf%rad_lw_out = emissivity_urb * sigma_sb * (t_rad_urb)**4   &
2542                                    + ( 10.0_wp - emissivity_urb )             & ! shouldn't be this a bulk value -- emissivity_urb?
2543                                    * surf%rad_lw_in
2544
2545                surf%rad_lw_out_change_0 = 3.0_wp * emissivity_urb * sigma_sb  &
2546                                           * t_rad_urb**3
2547
2548                surf%rad_sw_in = ( surf%rad_net - surf%rad_lw_in               &
2549                                     + surf%rad_lw_out )                       &
2550                                     / ( 1.0_wp - albedo_urb )
2551
2552                surf%rad_sw_out =  albedo_urb * surf%rad_sw_in
2553
2554!
2555!--          Calculate radiation fluxes for each surface element
2556             ELSE
2557!
2558!--             Determine index offset between surface element and adjacent
2559!--             atmospheric grid point
2560                ioff = surf%ioff
2561                joff = surf%joff
2562                koff = surf%koff
2563
2564!
2565!--             Prescribe net radiation and estimate the remaining radiative fluxes
2566                DO  m = 1, surf%ns
2567                   i = surf%i(m)
2568                   j = surf%j(m)
2569                   k = surf%k(m)
2570
2571                   surf%rad_net(m) = net_radiation
2572
2573                   exn1 = (hyp(k) / 100000.0_wp )**0.286_wp
2574
2575                   IF ( cloud_physics )  THEN
2576                      pt1 = pt(k,j,i) + l_d_cp / exn1 * ql(k,j,i)
2577                      surf%rad_lw_in(m)  = 0.8_wp * sigma_sb * (pt1 * exn1)**4
2578                   ELSE
2579                      surf%rad_lw_in(m)  = 0.8_wp * sigma_sb *                 &
2580                                             ( pt(k,j,i) * exn1 )**4
2581                   ENDIF
2582
2583!
2584!--                Weighted average according to surface fraction.
2585                   surf%rad_lw_out(m) = ( surf%frac(ind_veg_wall,m)  *         &
2586                                          surf%emissivity(ind_veg_wall,m)      &
2587                                        + surf%frac(ind_pav_green,m) *         &
2588                                          surf%emissivity(ind_pav_green,m)     &
2589                                        + surf%frac(ind_wat_win,m)   *         &
2590                                          surf%emissivity(ind_wat_win,m)       &
2591                                        )                                      &
2592                                      * sigma_sb                               &
2593                                      * ( surf%pt_surface(m) * exn )**4
2594
2595                   surf%rad_sw_in(m) = ( surf%rad_net(m) - surf%rad_lw_in(m)   &
2596                                       + surf%rad_lw_out(m) )                  &
2597                                       / ( 1.0_wp -                            &
2598                                          ( surf%frac(ind_veg_wall,m)  *       &
2599                                            surf%albedo(ind_veg_wall,m)        &
2600                                         +  surf%frac(ind_pav_green,m) *       &
2601                                            surf%albedo(ind_pav_green,m)       &
2602                                         +  surf%frac(ind_wat_win,m)   *       &
2603                                            surf%albedo(ind_wat_win,m) )       &
2604                                         )
2605
2606                   surf%rad_sw_out(m) = ( surf%frac(ind_veg_wall,m)  *         &
2607                                          surf%albedo(ind_veg_wall,m)          &
2608                                        + surf%frac(ind_pav_green,m) *         &
2609                                          surf%albedo(ind_pav_green,m)         &
2610                                        + surf%frac(ind_wat_win,m)   *         &
2611                                          surf%albedo(ind_wat_win,m) )         &
2612                                      * surf%rad_sw_in(m)
2613
2614                ENDDO
2615
2616             ENDIF
2617
2618!
2619!--          Fill out values in radiation arrays
2620             DO  m = 1, surf%ns
2621                i = surf%i(m)
2622                j = surf%j(m)
2623                rad_sw_in(0,j,i) = surf%rad_sw_in(m)
2624                rad_sw_out(0,j,i) = surf%rad_sw_out(m)
2625                rad_lw_in(0,j,i) = surf%rad_lw_in(m)
2626                rad_lw_out(0,j,i) = surf%rad_lw_out(m)
2627             ENDDO
2628
2629          END SUBROUTINE radiation_constant_surf
2630         
2631
2632    END SUBROUTINE radiation_constant
2633
2634!------------------------------------------------------------------------------!
2635! Description:
2636! ------------
2637!> Header output for radiation model
2638!------------------------------------------------------------------------------!
2639    SUBROUTINE radiation_header ( io )
2640
2641
2642       IMPLICIT NONE
2643 
2644       INTEGER(iwp), INTENT(IN) ::  io            !< Unit of the output file
2645   
2646
2647       
2648!
2649!--    Write radiation model header
2650       WRITE( io, 3 )
2651
2652       IF ( radiation_scheme == "constant" )  THEN
2653          WRITE( io, 4 ) net_radiation
2654       ELSEIF ( radiation_scheme == "clear-sky" )  THEN
2655          WRITE( io, 5 )
2656       ELSEIF ( radiation_scheme == "rrtmg" )  THEN
2657          WRITE( io, 6 )
2658          IF ( .NOT. lw_radiation )  WRITE( io, 10 )
2659          IF ( .NOT. sw_radiation )  WRITE( io, 11 )
2660       ENDIF
2661
2662       IF ( albedo_type_f%from_file  .OR.  vegetation_type_f%from_file  .OR.   &
2663            pavement_type_f%from_file  .OR.  water_type_f%from_file  .OR.      &
2664            building_type_f%from_file )  THEN
2665             WRITE( io, 13 )
2666       ELSE 
2667          IF ( albedo_type == 0 )  THEN
2668             WRITE( io, 7 ) albedo
2669          ELSE
2670             WRITE( io, 8 ) TRIM( albedo_type_name(albedo_type) )
2671          ENDIF
2672       ENDIF
2673       IF ( constant_albedo )  THEN
2674          WRITE( io, 9 )
2675       ENDIF
2676       
2677       WRITE( io, 12 ) dt_radiation
2678 
2679
2680 3 FORMAT (//' Radiation model information:'/                                  &
2681              ' ----------------------------'/)
2682 4 FORMAT ('    --> Using constant net radiation: net_radiation = ', F6.2,     &
2683           // 'W/m**2')
2684 5 FORMAT ('    --> Simple radiation scheme for clear sky is used (no clouds,',&
2685                   ' default)')
2686 6 FORMAT ('    --> RRTMG scheme is used')
2687 7 FORMAT (/'    User-specific surface albedo: albedo =', F6.3)
2688 8 FORMAT (/'    Albedo is set for land surface type: ', A)
2689 9 FORMAT (/'    --> Albedo is fixed during the run')
269010 FORMAT (/'    --> Longwave radiation is disabled')
269111 FORMAT (/'    --> Shortwave radiation is disabled.')
269212 FORMAT  ('    Timestep: dt_radiation = ', F6.2, '  s')
269313 FORMAT (/'    Albedo is set individually for each xy-location, according '  &
2694                 'to given surface type.')
2695
2696
2697    END SUBROUTINE radiation_header
2698   
2699
2700!------------------------------------------------------------------------------!
2701! Description:
2702! ------------
2703!> Parin for &radiation_parameters for radiation model
2704!------------------------------------------------------------------------------!
2705    SUBROUTINE radiation_parin
2706
2707
2708       IMPLICIT NONE
2709
2710       CHARACTER (LEN=80) ::  line  !< dummy string that contains the current line of the parameter file
2711       
2712       NAMELIST /radiation_par/   albedo, albedo_type, albedo_lw_dir,          &
2713                                  albedo_lw_dif, albedo_sw_dir, albedo_sw_dif, &
2714                                  constant_albedo, dt_radiation, emissivity,   &
2715                                  lw_radiation, net_radiation,                 &
2716                                  radiation_scheme, skip_time_do_radiation,    &
2717                                  sw_radiation, unscheduled_radiation_calls,   &
2718                                  split_diffusion_radiation,                   &
2719                                  max_raytracing_dist, min_irrf_value,         &
2720                                  nrefsteps, mrt_factors, rma_lad_raytrace,    &
2721                                  dist_max_svf,                                &
2722                                  surface_reflections, svfnorm_report_thresh,  &
2723                                  radiation_interactions_on
2724   
2725       NAMELIST /radiation_parameters/   albedo, albedo_type, albedo_lw_dir,   &
2726                                  albedo_lw_dif, albedo_sw_dir, albedo_sw_dif, &
2727                                  constant_albedo, dt_radiation, emissivity,   &
2728                                  lw_radiation, net_radiation,                 &
2729                                  radiation_scheme, skip_time_do_radiation,    &
2730                                  sw_radiation, unscheduled_radiation_calls,   &
2731                                  split_diffusion_radiation,                   &
2732                                  max_raytracing_dist, min_irrf_value,         &
2733                                  nrefsteps, mrt_factors, rma_lad_raytrace,    &
2734                                  dist_max_svf,                                &
2735                                  surface_reflections, svfnorm_report_thresh,  &
2736                                  radiation_interactions_on
2737   
2738       line = ' '
2739       
2740!
2741!--    Try to find radiation model namelist
2742       REWIND ( 11 )
2743       line = ' '
2744       DO   WHILE ( INDEX( line, '&radiation_parameters' ) == 0 )
2745          READ ( 11, '(A)', END=10 )  line
2746       ENDDO
2747       BACKSPACE ( 11 )
2748
2749!
2750!--    Read user-defined namelist
2751       READ ( 11, radiation_parameters )
2752
2753!
2754!--    Set flag that indicates that the radiation model is switched on
2755       radiation = .TRUE.
2756       
2757       GOTO 12
2758!
2759!--    Try to find old namelist
2760 10    REWIND ( 11 )
2761       line = ' '
2762       DO   WHILE ( INDEX( line, '&radiation_par' ) == 0 )
2763          READ ( 11, '(A)', END=12 )  line
2764       ENDDO
2765       BACKSPACE ( 11 )
2766
2767!
2768!--    Read user-defined namelist
2769       READ ( 11, radiation_par )
2770       
2771       message_string = 'namelist radiation_par is deprecated and will be ' // &
2772                     'removed in near future. Please use namelist ' //         &
2773                     'radiation_parameters instead'
2774       CALL message( 'radiation_parin', 'PA0487', 0, 1, 0, 6, 0 )
2775
2776       
2777!
2778!--    Set flag that indicates that the radiation model is switched on
2779       radiation = .TRUE.
2780
2781       IF ( .NOT.  radiation_interactions_on  .AND.  surface_reflections )  THEN
2782          message_string = 'surface_reflections is allowed only when '      // &
2783               'radiation_interactions_on is set to TRUE'
2784          CALL message( 'radiation_parin', 'PA0293',1, 2, 0, 6, 0 )
2785       ENDIF
2786
2787 12    CONTINUE
2788       
2789    END SUBROUTINE radiation_parin
2790
2791
2792!------------------------------------------------------------------------------!
2793! Description:
2794! ------------
2795!> Implementation of the RRTMG radiation_scheme
2796!------------------------------------------------------------------------------!
2797    SUBROUTINE radiation_rrtmg
2798
2799       USE indices,                                                            &
2800           ONLY:  nbgp
2801
2802       USE particle_attributes,                                                &
2803           ONLY:  grid_particles, number_of_particles, particles,              &
2804                  particle_advection_start, prt_count
2805
2806       IMPLICIT NONE
2807
2808#if defined ( __rrtmg )
2809
2810       INTEGER(iwp) ::  i, j, k, l, m, n !< loop indices
2811       INTEGER(iwp) ::  k_topo     !< topography top index
2812
2813       REAL(wp)     ::  nc_rad, &    !< number concentration of cloud droplets
2814                        s_r2,   &    !< weighted sum over all droplets with r^2
2815                        s_r3         !< weighted sum over all droplets with r^3
2816
2817       REAL(wp), DIMENSION(0:nzt+1) :: pt_av, q_av, ql_av
2818!
2819!--    Just dummy arguments
2820       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: rrtm_lw_taucld_dum,          &
2821                                                  rrtm_lw_tauaer_dum,          &
2822                                                  rrtm_sw_taucld_dum,          &
2823                                                  rrtm_sw_ssacld_dum,          &
2824                                                  rrtm_sw_asmcld_dum,          &
2825                                                  rrtm_sw_fsfcld_dum,          &
2826                                                  rrtm_sw_tauaer_dum,          &
2827                                                  rrtm_sw_ssaaer_dum,          &
2828                                                  rrtm_sw_asmaer_dum,          &
2829                                                  rrtm_sw_ecaer_dum
2830
2831!
2832!--    Calculate current (cosine of) zenith angle and whether the sun is up
2833       CALL calc_zenith     
2834!
2835!--    Calculate surface albedo. In case average radiation is applied,
2836!--    this is not required.
2837       IF ( .NOT. constant_albedo )  THEN
2838!
2839!--       Horizontally aligned default, natural and urban surfaces
2840          CALL calc_albedo( surf_lsm_h    )
2841          CALL calc_albedo( surf_usm_h    )
2842!
2843!--       Vertically aligned default, natural and urban surfaces
2844          DO  l = 0, 3
2845             CALL calc_albedo( surf_lsm_v(l) )
2846             CALL calc_albedo( surf_usm_v(l) )
2847          ENDDO
2848       ENDIF
2849
2850!
2851!--    Prepare input data for RRTMG
2852
2853!
2854!--    In case of large scale forcing with surface data, calculate new pressure
2855!--    profile. nzt_rad might be modified by these calls and all required arrays
2856!--    will then be re-allocated
2857       IF ( large_scale_forcing  .AND.  lsf_surf )  THEN
2858          CALL read_sounding_data
2859          CALL read_trace_gas_data
2860       ENDIF
2861
2862
2863       IF ( average_radiation ) THEN
2864
2865          rrtm_asdir(1)  = albedo_urb
2866          rrtm_asdif(1)  = albedo_urb
2867          rrtm_aldir(1)  = albedo_urb
2868          rrtm_aldif(1)  = albedo_urb
2869
2870          rrtm_emis = emissivity_urb
2871!
2872!--       Calculate mean pt profile. Actually, only one height level is required.
2873          CALL calc_mean_profile( pt, 4 )
2874          pt_av = hom(:, 1, 4, 0)
2875         
2876          IF ( humidity )  THEN
2877             CALL calc_mean_profile( q, 41 )
2878             q_av  = hom(:, 1, 41, 0)
2879          ENDIF
2880!
2881!--       Prepare profiles of temperature and H2O volume mixing ratio
2882          rrtm_tlev(0,nzb+1) = t_rad_urb
2883
2884          IF ( cloud_physics )  THEN
2885
2886             CALL calc_mean_profile( ql, 54 )
2887             ! average ql is now in hom(:, 1, 54, 0)
2888             ql_av = hom(:, 1, 54, 0)
2889             
2890             DO k = nzb+1, nzt+1
2891                rrtm_tlay(0,k) = pt_av(k) * ( (hyp(k) ) / 100000._wp       &
2892                                 )**.286_wp + l_d_cp * ql_av(k)
2893                rrtm_h2ovmr(0,k) = mol_mass_air_d_wv * (q_av(k) - ql_av(k))
2894             ENDDO
2895          ELSE
2896             DO k = nzb+1, nzt+1
2897                rrtm_tlay(0,k) = pt_av(k) * ( (hyp(k) ) / 100000._wp       &
2898                                 )**.286_wp
2899             ENDDO
2900
2901             IF ( humidity )  THEN
2902                DO k = nzb+1, nzt+1
2903                   rrtm_h2ovmr(0,k) = mol_mass_air_d_wv * q_av(k)
2904                ENDDO
2905             ELSE
2906                rrtm_h2ovmr(0,nzb+1:nzt+1) = 0.0_wp
2907             ENDIF
2908          ENDIF
2909
2910!
2911!--       Avoid temperature/humidity jumps at the top of the LES domain by
2912!--       linear interpolation from nzt+2 to nzt+7
2913          DO k = nzt+2, nzt+7
2914             rrtm_tlay(0,k) = rrtm_tlay(0,nzt+1)                            &
2915                           + ( rrtm_tlay(0,nzt+8) - rrtm_tlay(0,nzt+1) )    &
2916                           / ( rrtm_play(0,nzt+8) - rrtm_play(0,nzt+1) )    &
2917                           * ( rrtm_play(0,k) - rrtm_play(0,nzt+1) )
2918
2919             rrtm_h2ovmr(0,k) = rrtm_h2ovmr(0,nzt+1)                        &
2920                           + ( rrtm_h2ovmr(0,nzt+8) - rrtm_h2ovmr(0,nzt+1) )&
2921                           / ( rrtm_play(0,nzt+8)   - rrtm_play(0,nzt+1)   )&
2922                           * ( rrtm_play(0,k) - rrtm_play(0,nzt+1) )
2923
2924          ENDDO
2925
2926!--       Linear interpolate to zw grid
2927          DO k = nzb+2, nzt+8
2928             rrtm_tlev(0,k)   = rrtm_tlay(0,k-1) + (rrtm_tlay(0,k) -        &
2929                                rrtm_tlay(0,k-1))                           &
2930                                / ( rrtm_play(0,k) - rrtm_play(0,k-1) )     &
2931                                * ( rrtm_plev(0,k) - rrtm_play(0,k-1) )
2932          ENDDO
2933
2934
2935!
2936!--       Calculate liquid water path and cloud fraction for each column.
2937!--       Note that LWP is required in g/m² instead of kg/kg m.
2938          rrtm_cldfr  = 0.0_wp
2939          rrtm_reliq  = 0.0_wp
2940          rrtm_cliqwp = 0.0_wp
2941          rrtm_icld   = 0
2942
2943          IF ( cloud_physics )  THEN
2944             DO k = nzb+1, nzt+1
2945                rrtm_cliqwp(0,k) =  ql_av(k) * 1000._wp *                  &
2946                                    (rrtm_plev(0,k) - rrtm_plev(0,k+1))     &
2947                                    * 100._wp / g 
2948
2949                IF ( rrtm_cliqwp(0,k) > 0._wp )  THEN
2950                   rrtm_cldfr(0,k) = 1._wp
2951                   IF ( rrtm_icld == 0 )  rrtm_icld = 1
2952
2953!
2954!--                Calculate cloud droplet effective radius
2955                   IF ( cloud_physics )  THEN
2956                      rrtm_reliq(0,k) = 1.0E6_wp * ( 3._wp * ql_av(k)      &
2957                                        * rho_surface                       &
2958                                        / ( 4._wp * pi * nc_const * rho_l )&
2959                                        )**.33333333333333_wp              &
2960                                        * EXP( LOG( sigma_gc )**2 )
2961
2962                   ENDIF
2963
2964!
2965!--                Limit effective radius
2966                   IF ( rrtm_reliq(0,k) > 0.0_wp )  THEN
2967                      rrtm_reliq(0,k) = MAX(rrtm_reliq(0,k),2.5_wp)
2968                      rrtm_reliq(0,k) = MIN(rrtm_reliq(0,k),60.0_wp)
2969                   ENDIF
2970                ENDIF
2971             ENDDO
2972          ENDIF
2973
2974!
2975!--       Set surface temperature
2976          rrtm_tsfc = t_rad_urb
2977         
2978          IF ( lw_radiation )  THEN
2979             CALL rrtmg_lw( 1, nzt_rad      , rrtm_icld    , rrtm_idrv      ,&
2980             rrtm_play       , rrtm_plev    , rrtm_tlay    , rrtm_tlev      ,&
2981             rrtm_tsfc       , rrtm_h2ovmr  , rrtm_o3vmr   , rrtm_co2vmr    ,&
2982             rrtm_ch4vmr     , rrtm_n2ovmr  , rrtm_o2vmr   , rrtm_cfc11vmr  ,&
2983             rrtm_cfc12vmr   , rrtm_cfc22vmr, rrtm_ccl4vmr , rrtm_emis      ,&
2984             rrtm_inflglw    , rrtm_iceflglw, rrtm_liqflglw, rrtm_cldfr     ,&
2985             rrtm_lw_taucld  , rrtm_cicewp  , rrtm_cliqwp  , rrtm_reice     ,& 
2986             rrtm_reliq      , rrtm_lw_tauaer,                               &
2987             rrtm_lwuflx     , rrtm_lwdflx  , rrtm_lwhr  ,                   &
2988             rrtm_lwuflxc    , rrtm_lwdflxc , rrtm_lwhrc ,                   &
2989             rrtm_lwuflx_dt  ,  rrtm_lwuflxc_dt )
2990
2991!
2992!--          Save fluxes
2993             DO k = nzb, nzt+1
2994                rad_lw_in(k,:,:)  = rrtm_lwdflx(0,k)
2995                rad_lw_out(k,:,:) = rrtm_lwuflx(0,k)
2996             ENDDO
2997
2998!
2999!--          Save heating rates (convert from K/d to K/h)
3000             DO k = nzb+1, nzt+1
3001                rad_lw_hr(k,:,:)     = rrtm_lwhr(0,k)  * d_hours_day
3002                rad_lw_cs_hr(k,:,:)  = rrtm_lwhrc(0,k) * d_hours_day
3003             ENDDO
3004
3005!
3006!--          Save surface radiative fluxes and change in LW heating rate
3007!--          onto respective surface elements
3008!--          Horizontal surfaces
3009             IF ( surf_lsm_h%ns > 0 )  THEN
3010                surf_lsm_h%rad_lw_in           = rrtm_lwdflx(0,nzb)
3011                surf_lsm_h%rad_lw_out          = rrtm_lwuflx(0,nzb)
3012                surf_lsm_h%rad_lw_out_change_0 = rrtm_lwuflx_dt(0,nzb)
3013             ENDIF             
3014             IF ( surf_usm_h%ns > 0 )  THEN
3015                surf_usm_h%rad_lw_in           = rrtm_lwdflx(0,nzb)
3016                surf_usm_h%rad_lw_out          = rrtm_lwuflx(0,nzb)
3017                surf_usm_h%rad_lw_out_change_0 = rrtm_lwuflx_dt(0,nzb)
3018             ENDIF
3019!
3020!--          Vertical surfaces.
3021             DO  l = 0, 3
3022                IF ( surf_lsm_v(l)%ns > 0 )  THEN
3023                   surf_lsm_v(l)%rad_lw_in           = rrtm_lwdflx(0,nzb)
3024                   surf_lsm_v(l)%rad_lw_out          = rrtm_lwuflx(0,nzb)
3025                   surf_lsm_v(l)%rad_lw_out_change_0 = rrtm_lwuflx_dt(0,nzb)
3026                ENDIF
3027                IF ( surf_usm_v(l)%ns > 0 )  THEN
3028                   surf_usm_v(l)%rad_lw_in           = rrtm_lwdflx(0,nzb)
3029                   surf_usm_v(l)%rad_lw_out          = rrtm_lwuflx(0,nzb)
3030                   surf_usm_v(l)%rad_lw_out_change_0 = rrtm_lwuflx_dt(0,nzb)
3031                ENDIF
3032             ENDDO
3033
3034          ENDIF
3035
3036          IF ( sw_radiation .AND. sun_up )  THEN
3037             CALL rrtmg_sw( 1, nzt_rad      , rrtm_icld  , rrtm_iaer        ,&
3038             rrtm_play       , rrtm_plev    , rrtm_tlay  , rrtm_tlev        ,&
3039             rrtm_tsfc       , rrtm_h2ovmr  , rrtm_o3vmr , rrtm_co2vmr      ,&
3040             rrtm_ch4vmr     , rrtm_n2ovmr  , rrtm_o2vmr , rrtm_asdir       ,&
3041             rrtm_asdif      , rrtm_aldir   , rrtm_aldif , zenith,           &
3042             0.0_wp          , day_of_year  , solar_constant,   rrtm_inflgsw,&
3043             rrtm_iceflgsw   , rrtm_liqflgsw, rrtm_cldfr , rrtm_sw_taucld   ,&
3044             rrtm_sw_ssacld  , rrtm_sw_asmcld, rrtm_sw_fsfcld, rrtm_cicewp  ,&
3045             rrtm_cliqwp     , rrtm_reice   , rrtm_reliq , rrtm_sw_tauaer   ,&
3046             rrtm_sw_ssaaer  , rrtm_sw_asmaer  , rrtm_sw_ecaer ,             &
3047             rrtm_swuflx     , rrtm_swdflx  , rrtm_swhr  ,                   &
3048             rrtm_swuflxc    , rrtm_swdflxc , rrtm_swhrc )
3049 
3050!
3051!--          Save fluxes
3052             DO k = nzb, nzt+1
3053                rad_sw_in(k,:,:)  = rrtm_swdflx(0,k)
3054                rad_sw_out(k,:,:) = rrtm_swuflx(0,k)
3055             ENDDO
3056
3057!
3058!--          Save heating rates (convert from K/d to K/s)
3059             DO k = nzb+1, nzt+1
3060                rad_sw_hr(k,:,:)     = rrtm_swhr(0,k)  * d_hours_day
3061                rad_sw_cs_hr(k,:,:)  = rrtm_swhrc(0,k) * d_hours_day
3062             ENDDO
3063
3064!
3065!--          Save surface radiative fluxes onto respective surface elements
3066!--          Horizontal surfaces
3067             IF ( surf_lsm_h%ns > 0 )  THEN
3068                   surf_lsm_h%rad_sw_in     = rrtm_swdflx(0,nzb)
3069                   surf_lsm_h%rad_sw_out    = rrtm_swuflx(0,nzb)
3070             ENDIF
3071             IF ( surf_usm_h%ns > 0 )  THEN
3072                   surf_usm_h%rad_sw_in     = rrtm_swdflx(0,nzb)
3073                   surf_usm_h%rad_sw_out    = rrtm_swuflx(0,nzb)
3074             ENDIF
3075!
3076!--          Vertical surfaces. Fluxes are obtain at respective vertical
3077!--          level of the surface element
3078             DO  l = 0, 3
3079                IF ( surf_lsm_v(l)%ns > 0 )  THEN
3080                      surf_lsm_v(l)%rad_sw_in  = rrtm_swdflx(0,nzb)
3081                      surf_lsm_v(l)%rad_sw_out = rrtm_swuflx(0,nzb)
3082                ENDIF             
3083                IF ( surf_usm_v(l)%ns > 0 )  THEN
3084                      surf_usm_v(l)%rad_sw_in  = rrtm_swdflx(0,nzb)
3085                      surf_usm_v(l)%rad_sw_out = rrtm_swuflx(0,nzb)
3086                ENDIF       
3087             ENDDO
3088
3089          ENDIF
3090!
3091!--    RRTMG is called for each (j,i) grid point separately, starting at the
3092!--    highest topography level
3093       ELSE
3094!
3095!--       Loop over all grid points
3096          DO i = nxl, nxr
3097             DO j = nys, nyn
3098
3099!
3100!--             Prepare profiles of temperature and H2O volume mixing ratio
3101                DO  m = surf_lsm_h%start_index(j,i), surf_lsm_h%end_index(j,i)
3102                   rrtm_tlev(0,nzb+1) = surf_lsm_h%pt_surface(m) * &
3103                                    ( surface_pressure / 1000.0_wp )**0.286_wp
3104                ENDDO
3105                DO  m = surf_usm_h%start_index(j,i), surf_usm_h%end_index(j,i)
3106                   rrtm_tlev(0,nzb+1) = surf_usm_h%pt_surface(m) * &
3107                                    ( surface_pressure / 1000.0_wp )**0.286_wp
3108                ENDDO
3109
3110
3111                IF ( cloud_physics )  THEN
3112                   DO k = nzb+1, nzt+1
3113                      rrtm_tlay(0,k) = pt(k,j,i) * ( (hyp(k) ) / 100000.0_wp   &
3114                                       )**0.286_wp + l_d_cp * ql(k,j,i)
3115                      rrtm_h2ovmr(0,k) = mol_mass_air_d_wv * (q(k,j,i) - ql(k,j,i))
3116                   ENDDO
3117                ELSE
3118                   DO k = nzb+1, nzt+1
3119                      rrtm_tlay(0,k) = pt(k,j,i) * ( (hyp(k) ) / 100000.0_wp   &
3120                                       )**0.286_wp
3121                   ENDDO
3122
3123                   IF ( humidity )  THEN
3124                      DO k = nzb+1, nzt+1
3125                         rrtm_h2ovmr(0,k) =  mol_mass_air_d_wv * q(k,j,i)
3126                      ENDDO   
3127                   ELSE
3128                      rrtm_h2ovmr(0,nzb+1:nzt+1) = 0.0_wp
3129                   ENDIF
3130                ENDIF
3131
3132!
3133!--             Avoid temperature/humidity jumps at the top of the LES domain by
3134!--             linear interpolation from nzt+2 to nzt+7
3135                DO k = nzt+2, nzt+7
3136                   rrtm_tlay(0,k) = rrtm_tlay(0,nzt+1)                         &
3137                                 + ( rrtm_tlay(0,nzt+8) - rrtm_tlay(0,nzt+1) ) &
3138                                 / ( rrtm_play(0,nzt+8) - rrtm_play(0,nzt+1) ) &
3139                                 * ( rrtm_play(0,k)     - rrtm_play(0,nzt+1) )
3140
3141                   rrtm_h2ovmr(0,k) = rrtm_h2ovmr(0,nzt+1)                     &
3142                              + ( rrtm_h2ovmr(0,nzt+8) - rrtm_h2ovmr(0,nzt+1) )&
3143                              / ( rrtm_play(0,nzt+8)   - rrtm_play(0,nzt+1)   )&
3144                              * ( rrtm_play(0,k)       - rrtm_play(0,nzt+1) )
3145
3146                ENDDO
3147
3148!--             Linear interpolate to zw grid
3149                DO k = nzb+2, nzt+8
3150                   rrtm_tlev(0,k)   = rrtm_tlay(0,k-1) + (rrtm_tlay(0,k) -     &
3151                                      rrtm_tlay(0,k-1))                        &
3152                                      / ( rrtm_play(0,k) - rrtm_play(0,k-1) )  &
3153                                      * ( rrtm_plev(0,k) - rrtm_play(0,k-1) )
3154                ENDDO
3155
3156
3157!
3158!--             Calculate liquid water path and cloud fraction for each column.
3159!--             Note that LWP is required in g/m² instead of kg/kg m.
3160                rrtm_cldfr  = 0.0_wp
3161                rrtm_reliq  = 0.0_wp
3162                rrtm_cliqwp = 0.0_wp
3163                rrtm_icld   = 0
3164
3165                IF ( cloud_physics  .OR.  cloud_droplets )  THEN
3166                   DO k = nzb+1, nzt+1
3167                      rrtm_cliqwp(0,k) =  ql(k,j,i) * 1000.0_wp *              &
3168                                          (rrtm_plev(0,k) - rrtm_plev(0,k+1))  &
3169                                          * 100.0_wp / g 
3170
3171                      IF ( rrtm_cliqwp(0,k) > 0.0_wp )  THEN
3172                         rrtm_cldfr(0,k) = 1.0_wp
3173                         IF ( rrtm_icld == 0 )  rrtm_icld = 1
3174
3175!
3176!--                      Calculate cloud droplet effective radius
3177                         IF ( cloud_physics )  THEN
3178!
3179!--                         Calculete effective droplet radius. In case of using
3180!--                         cloud_scheme = 'morrison' and a non reasonable number
3181!--                         of cloud droplets the inital aerosol number 
3182!--                         concentration is considered.
3183                            IF ( microphysics_morrison )  THEN
3184                               IF ( nc(k,j,i) > 1.0E-20_wp )  THEN
3185                                  nc_rad = nc(k,j,i)
3186                               ELSE
3187                                  nc_rad = na_init
3188                               ENDIF
3189                            ELSE
3190                               nc_rad = nc_const
3191                            ENDIF 
3192
3193                            rrtm_reliq(0,k) = 1.0E6_wp * ( 3.0_wp * ql(k,j,i)     &
3194                                              * rho_surface                       &
3195                                              / ( 4.0_wp * pi * nc_rad * rho_l )  &
3196                                              )**0.33333333333333_wp              &
3197                                              * EXP( LOG( sigma_gc )**2 )
3198
3199                         ELSEIF ( cloud_droplets )  THEN
3200                            number_of_particles = prt_count(k,j,i)
3201
3202                            IF (number_of_particles <= 0)  CYCLE
3203                            particles => grid_particles(k,j,i)%particles(1:number_of_particles)
3204                            s_r2 = 0.0_wp
3205                            s_r3 = 0.0_wp
3206
3207                            DO  n = 1, number_of_particles
3208                               IF ( particles(n)%particle_mask )  THEN
3209                                  s_r2 = s_r2 + particles(n)%radius**2 *       &
3210                                         particles(n)%weight_factor
3211                                  s_r3 = s_r3 + particles(n)%radius**3 *       &
3212                                         particles(n)%weight_factor
3213                               ENDIF
3214                            ENDDO
3215
3216                            IF ( s_r2 > 0.0_wp )  rrtm_reliq(0,k) = s_r3 / s_r2
3217
3218                         ENDIF
3219
3220!
3221!--                      Limit effective radius
3222                         IF ( rrtm_reliq(0,k) > 0.0_wp )  THEN
3223                            rrtm_reliq(0,k) = MAX(rrtm_reliq(0,k),2.5_wp)
3224                            rrtm_reliq(0,k) = MIN(rrtm_reliq(0,k),60.0_wp)
3225                        ENDIF
3226                      ENDIF
3227                   ENDDO
3228                ENDIF
3229
3230!
3231!--             Write surface emissivity and surface temperature at current
3232!--             surface element on RRTMG-shaped array.
3233!--             Please note, as RRTMG is a single column model, surface attributes
3234!--             are only obtained from horizontally aligned surfaces (for
3235!--             simplicity). Taking surface attributes from horizontal and
3236!--             vertical walls would lead to multiple solutions. 
3237!--             Moreover, for natural- and urban-type surfaces, several surface
3238!--             classes can exist at a surface element next to each other.
3239!--             To obtain bulk parameters, apply a weighted average for these
3240!--             surfaces.
3241                DO  m = surf_lsm_h%start_index(j,i), surf_lsm_h%end_index(j,i)
3242                   rrtm_emis = surf_lsm_h%frac(ind_veg_wall,m)  *              &
3243                               surf_lsm_h%emissivity(ind_veg_wall,m)  +        &
3244                               surf_lsm_h%frac(ind_pav_green,m) *              &
3245                               surf_lsm_h%emissivity(ind_pav_green,m) +        & 
3246                               surf_lsm_h%frac(ind_wat_win,m)   *              &
3247                               surf_lsm_h%emissivity(ind_wat_win,m)
3248                   rrtm_tsfc = surf_lsm_h%pt_surface(m) *                      &
3249                                       (surface_pressure / 1000.0_wp )**0.286_wp
3250                ENDDO             
3251                DO  m = surf_usm_h%start_index(j,i), surf_usm_h%end_index(j,i)
3252                   rrtm_emis = surf_usm_h%frac(ind_veg_wall,m)  *              &
3253                               surf_usm_h%emissivity(ind_veg_wall,m)  +        &
3254                               surf_usm_h%frac(ind_pav_green,m) *              &
3255                               surf_usm_h%emissivity(ind_pav_green,m) +        & 
3256                               surf_usm_h%frac(ind_wat_win,m)   *              &
3257                               surf_usm_h%emissivity(ind_wat_win,m)
3258                   rrtm_tsfc = surf_usm_h%pt_surface(m) *                      &
3259                                       (surface_pressure / 1000.0_wp )**0.286_wp
3260                ENDDO
3261!
3262!--             Obtain topography top index (lower bound of RRTMG)
3263                k_topo = get_topography_top_index_ji( j, i, 's' )
3264
3265                IF ( lw_radiation )  THEN
3266!
3267!--                Due to technical reasons, copy optical depth to dummy arguments
3268!--                which are allocated on the exact size as the rrtmg_lw is called.
3269!--                As one dimesion is allocated with zero size, compiler complains
3270!--                that rank of the array does not match that of the
3271!--                assumed-shaped arguments in the RRTMG library. In order to
3272!--                avoid this, write to dummy arguments and give pass the entire
3273!--                dummy array. Seems to be the only existing work-around. 
3274                   ALLOCATE( rrtm_lw_taucld_dum(1:nbndlw+1,0:0,k_topo+1:nzt_rad+1) )
3275                   ALLOCATE( rrtm_lw_tauaer_dum(0:0,k_topo+1:nzt_rad+1,1:nbndlw+1) )
3276
3277                   rrtm_lw_taucld_dum =                                        &
3278                               rrtm_lw_taucld(1:nbndlw+1,0:0,k_topo+1:nzt_rad+1)
3279                   rrtm_lw_tauaer_dum =                                        &
3280                               rrtm_lw_tauaer(0:0,k_topo+1:nzt_rad+1,1:nbndlw+1)
3281
3282                   CALL rrtmg_lw( 1,                                           &                                       
3283                                  nzt_rad-k_topo,                              &
3284                                  rrtm_icld,                                   &
3285                                  rrtm_idrv,                                   &
3286                                  rrtm_play(:,k_topo+1:nzt_rad+1),             &
3287                                  rrtm_plev(:,k_topo+1:nzt_rad+2),             &
3288                                  rrtm_tlay(:,k_topo+1:nzt_rad+1),             &
3289                                  rrtm_tlev(:,k_topo+1:nzt_rad+2),             &
3290                                  rrtm_tsfc,                                   &
3291                                  rrtm_h2ovmr(:,k_topo+1:nzt_rad+1),           &
3292                                  rrtm_o3vmr(:,k_topo+1:nzt_rad+1),            &
3293                                  rrtm_co2vmr(:,k_topo+1:nzt_rad+1),           &
3294                                  rrtm_ch4vmr(:,k_topo+1:nzt_rad+1),           &
3295                                  rrtm_n2ovmr(:,k_topo+1:nzt_rad+1),           &
3296                                  rrtm_o2vmr(:,k_topo+1:nzt_rad+1),            &
3297                                  rrtm_cfc11vmr(:,k_topo+1:nzt_rad+1),         &
3298                                  rrtm_cfc12vmr(:,k_topo+1:nzt_rad+1),         &
3299                                  rrtm_cfc22vmr(:,k_topo+1:nzt_rad+1),         &
3300                                  rrtm_ccl4vmr(:,k_topo+1:nzt_rad+1),          &
3301                                  rrtm_emis,                                   &
3302                                  rrtm_inflglw,                                &
3303                                  rrtm_iceflglw,                               &
3304                                  rrtm_liqflglw,                               &
3305                                  rrtm_cldfr(:,k_topo+1:nzt_rad+1),            &
3306                                  rrtm_lw_taucld_dum,                          &
3307                                  rrtm_cicewp(:,k_topo+1:nzt_rad+1),           &
3308                                  rrtm_cliqwp(:,k_topo+1:nzt_rad+1),           &
3309                                  rrtm_reice(:,k_topo+1:nzt_rad+1),            & 
3310                                  rrtm_reliq(:,k_topo+1:nzt_rad+1),            &
3311                                  rrtm_lw_tauaer_dum,                          &
3312                                  rrtm_lwuflx(:,k_topo:nzt_rad+1),             &
3313                                  rrtm_lwdflx(:,k_topo:nzt_rad+1),             &
3314                                  rrtm_lwhr(:,k_topo+1:nzt_rad+1),             &
3315                                  rrtm_lwuflxc(:,k_topo:nzt_rad+1),            &
3316                                  rrtm_lwdflxc(:,k_topo:nzt_rad+1),            &
3317                                  rrtm_lwhrc(:,k_topo+1:nzt_rad+1),            &
3318                                  rrtm_lwuflx_dt(:,k_topo:nzt_rad+1),          &
3319                                  rrtm_lwuflxc_dt(:,k_topo:nzt_rad+1) )
3320
3321                   DEALLOCATE ( rrtm_lw_taucld_dum )
3322                   DEALLOCATE ( rrtm_lw_tauaer_dum )
3323!
3324!--                Save fluxes
3325                   DO k = k_topo, nzt+1
3326                      rad_lw_in(k,j,i)  = rrtm_lwdflx(0,k)
3327                      rad_lw_out(k,j,i) = rrtm_lwuflx(0,k)
3328                   ENDDO
3329
3330!
3331!--                Save heating rates (convert from K/d to K/h)
3332                   DO k = k_topo+1, nzt+1
3333                      rad_lw_hr(k,j,i)     = rrtm_lwhr(0,k)  * d_hours_day
3334                      rad_lw_cs_hr(k,j,i)  = rrtm_lwhrc(0,k) * d_hours_day
3335                   ENDDO
3336
3337!
3338!--                Save surface radiative fluxes and change in LW heating rate
3339!--                onto respective surface elements
3340!--                Horizontal surfaces
3341                   DO  m = surf_lsm_h%start_index(j,i),                        &
3342                           surf_lsm_h%end_index(j,i)
3343                      surf_lsm_h%rad_lw_in(m)           = rrtm_lwdflx(0,k_topo)
3344                      surf_lsm_h%rad_lw_out(m)          = rrtm_lwuflx(0,k_topo)
3345                      surf_lsm_h%rad_lw_out_change_0(m) = rrtm_lwuflx_dt(0,k_topo)
3346                   ENDDO             
3347                   DO  m = surf_usm_h%start_index(j,i),                        &
3348                           surf_usm_h%end_index(j,i)
3349                      surf_usm_h%rad_lw_in(m)           = rrtm_lwdflx(0,k_topo)
3350                      surf_usm_h%rad_lw_out(m)          = rrtm_lwuflx(0,k_topo)
3351                      surf_usm_h%rad_lw_out_change_0(m) = rrtm_lwuflx_dt(0,k_topo)
3352                   ENDDO 
3353!
3354!--                Vertical surfaces. Fluxes are obtain at vertical level of the
3355!--                respective surface element
3356                   DO  l = 0, 3
3357                      DO  m = surf_lsm_v(l)%start_index(j,i),                  &
3358                              surf_lsm_v(l)%end_index(j,i)
3359                         k                                    = surf_lsm_v(l)%k(m)
3360                         surf_lsm_v(l)%rad_lw_in(m)           = rrtm_lwdflx(0,k)
3361                         surf_lsm_v(l)%rad_lw_out(m)          = rrtm_lwuflx(0,k)
3362                         surf_lsm_v(l)%rad_lw_out_change_0(m) = rrtm_lwuflx_dt(0,k)
3363                      ENDDO             
3364                      DO  m = surf_usm_v(l)%start_index(j,i),                  &
3365                              surf_usm_v(l)%end_index(j,i)
3366                         k                                    = surf_usm_v(l)%k(m)
3367                         surf_usm_v(l)%rad_lw_in(m)           = rrtm_lwdflx(0,k)
3368                         surf_usm_v(l)%rad_lw_out(m)          = rrtm_lwuflx(0,k)
3369                         surf_usm_v(l)%rad_lw_out_change_0(m) = rrtm_lwuflx_dt(0,k)
3370                      ENDDO 
3371                   ENDDO
3372
3373                ENDIF
3374
3375                IF ( sw_radiation .AND. sun_up )  THEN
3376!
3377!--                Get albedo for direct/diffusive long/shortwave radiation at
3378!--                current (y,x)-location from surface variables.
3379!--                Only obtain it from horizontal surfaces, as RRTMG is a single
3380!--                column model
3381!--                (Please note, only one loop will entered, controlled by
3382!--                start-end index.)
3383                   DO  m = surf_lsm_h%start_index(j,i),                        &
3384                           surf_lsm_h%end_index(j,i)
3385                      rrtm_asdir(1)  = SUM( surf_lsm_h%frac(:,m) *             &
3386                                            surf_lsm_h%rrtm_asdir(:,m) )
3387                      rrtm_asdif(1)  = SUM( surf_lsm_h%frac(:,m) *             &
3388                                            surf_lsm_h%rrtm_asdif(:,m) )
3389                      rrtm_aldir(1)  = SUM( surf_lsm_h%frac(:,m) *             &
3390                                            surf_lsm_h%rrtm_aldir(:,m) )
3391                      rrtm_aldif(1)  = SUM( surf_lsm_h%frac(:,m) *             &
3392                                            surf_lsm_h%rrtm_aldif(:,m) )
3393                   ENDDO             
3394                   DO  m = surf_usm_h%start_index(j,i),                        &
3395                           surf_usm_h%end_index(j,i)
3396                      rrtm_asdir(1)  = SUM( surf_usm_h%frac(:,m) *             &
3397                                            surf_usm_h%rrtm_asdir(:,m) )
3398                      rrtm_asdif(1)  = SUM( surf_usm_h%frac(:,m) *             &
3399                                            surf_usm_h%rrtm_asdif(:,m) )
3400                      rrtm_aldir(1)  = SUM( surf_usm_h%frac(:,m) *             &
3401                                            surf_usm_h%rrtm_aldir(:,m) )
3402                      rrtm_aldif(1)  = SUM( surf_usm_h%frac(:,m) *             &
3403                                            surf_usm_h%rrtm_aldif(:,m) )
3404                   ENDDO
3405!
3406!--                Due to technical reasons, copy optical depths and other
3407!--                to dummy arguments which are allocated on the exact size as the
3408!--                rrtmg_sw is called.
3409!--                As one dimesion is allocated with zero size, compiler complains
3410!--                that rank of the array does not match that of the
3411!--                assumed-shaped arguments in the RRTMG library. In order to
3412!--                avoid this, write to dummy arguments and give pass the entire
3413!--                dummy array. Seems to be the only existing work-around. 
3414                   ALLOCATE( rrtm_sw_taucld_dum(1:nbndsw+1,0:0,k_topo+1:nzt_rad+1) )
3415                   ALLOCATE( rrtm_sw_ssacld_dum(1:nbndsw+1,0:0,k_topo+1:nzt_rad+1) )
3416                   ALLOCATE( rrtm_sw_asmcld_dum(1:nbndsw+1,0:0,k_topo+1:nzt_rad+1) )
3417                   ALLOCATE( rrtm_sw_fsfcld_dum(1:nbndsw+1,0:0,k_topo+1:nzt_rad+1) )
3418                   ALLOCATE( rrtm_sw_tauaer_dum(0:0,k_topo+1:nzt_rad+1,1:nbndsw+1) )
3419                   ALLOCATE( rrtm_sw_ssaaer_dum(0:0,k_topo+1:nzt_rad+1,1:nbndsw+1) )
3420                   ALLOCATE( rrtm_sw_asmaer_dum(0:0,k_topo+1:nzt_rad+1,1:nbndsw+1) )
3421                   ALLOCATE( rrtm_sw_ecaer_dum(0:0,k_topo+1:nzt_rad+1,1:naerec+1)  )
3422     
3423                   rrtm_sw_taucld_dum = rrtm_sw_taucld(1:nbndsw+1,0:0,k_topo+1:nzt_rad+1)
3424                   rrtm_sw_ssacld_dum = rrtm_sw_ssacld(1:nbndsw+1,0:0,k_topo+1:nzt_rad+1)
3425                   rrtm_sw_asmcld_dum = rrtm_sw_asmcld(1:nbndsw+1,0:0,k_topo+1:nzt_rad+1)
3426                   rrtm_sw_fsfcld_dum = rrtm_sw_fsfcld(1:nbndsw+1,0:0,k_topo+1:nzt_rad+1)
3427                   rrtm_sw_tauaer_dum = rrtm_sw_tauaer(0:0,k_topo+1:nzt_rad+1,1:nbndsw+1)
3428                   rrtm_sw_ssaaer_dum = rrtm_sw_ssaaer(0:0,k_topo+1:nzt_rad+1,1:nbndsw+1)
3429                   rrtm_sw_asmaer_dum = rrtm_sw_asmaer(0:0,k_topo+1:nzt_rad+1,1:nbndsw+1)
3430                   rrtm_sw_ecaer_dum  = rrtm_sw_ecaer(0:0,k_topo+1:nzt_rad+1,1:naerec+1)
3431
3432                   CALL rrtmg_sw( 1,                                           &
3433                                  nzt_rad-k_topo,                              &
3434                                  rrtm_icld,                                   &
3435                                  rrtm_iaer,                                   &
3436                                  rrtm_play(:,k_topo+1:nzt_rad+1),             &
3437                                  rrtm_plev(:,k_topo+1:nzt_rad+2),             &
3438                                  rrtm_tlay(:,k_topo+1:nzt_rad+1),             &
3439                                  rrtm_tlev(:,k_topo+1:nzt_rad+2),             &
3440                                  rrtm_tsfc,                                   &
3441                                  rrtm_h2ovmr(:,k_topo+1:nzt_rad+1),           &                               
3442                                  rrtm_o3vmr(:,k_topo+1:nzt_rad+1),            &       
3443                                  rrtm_co2vmr(:,k_topo+1:nzt_rad+1),           &
3444                                  rrtm_ch4vmr(:,k_topo+1:nzt_rad+1),           &
3445                                  rrtm_n2ovmr(:,k_topo+1:nzt_rad+1),           &
3446                                  rrtm_o2vmr(:,k_topo+1:nzt_rad+1),            &
3447                                  rrtm_asdir,                                  & 
3448                                  rrtm_asdif,                                  &
3449                                  rrtm_aldir,                                  &
3450                                  rrtm_aldif,                                  &
3451                                  zenith,                                      &
3452                                  0.0_wp,                                      &
3453                                  day_of_year,                                 &
3454                                  solar_constant,                              &
3455                                  rrtm_inflgsw,                                &
3456                                  rrtm_iceflgsw,                               &
3457                                  rrtm_liqflgsw,                               &
3458                                  rrtm_cldfr(:,k_topo+1:nzt_rad+1),            &
3459                                  rrtm_sw_taucld_dum,                          &
3460                                  rrtm_sw_ssacld_dum,                          &
3461                                  rrtm_sw_asmcld_dum,                          &
3462                                  rrtm_sw_fsfcld_dum,                          &
3463                                  rrtm_cicewp(:,k_topo+1:nzt_rad+1),           &
3464                                  rrtm_cliqwp(:,k_topo+1:nzt_rad+1),           &
3465                                  rrtm_reice(:,k_topo+1:nzt_rad+1),            &
3466                                  rrtm_reliq(:,k_topo+1:nzt_rad+1),            &
3467                                  rrtm_sw_tauaer_dum,                          &
3468                                  rrtm_sw_ssaaer_dum,                          &
3469                                  rrtm_sw_asmaer_dum,                          &
3470                                  rrtm_sw_ecaer_dum,                           &
3471                                  rrtm_swuflx(:,k_topo:nzt_rad+1),             & 
3472                                  rrtm_swdflx(:,k_topo:nzt_rad+1),             & 
3473                                  rrtm_swhr(:,k_topo+1:nzt_rad+1),             & 
3474                                  rrtm_swuflxc(:,k_topo:nzt_rad+1),            & 
3475                                  rrtm_swdflxc(:,k_topo:nzt_rad+1),            &
3476                                  rrtm_swhrc(:,k_topo+1:nzt_rad+1) )
3477
3478                   DEALLOCATE( rrtm_sw_taucld_dum )
3479                   DEALLOCATE( rrtm_sw_ssacld_dum )
3480                   DEALLOCATE( rrtm_sw_asmcld_dum )
3481                   DEALLOCATE( rrtm_sw_fsfcld_dum )
3482                   DEALLOCATE( rrtm_sw_tauaer_dum )
3483                   DEALLOCATE( rrtm_sw_ssaaer_dum )
3484                   DEALLOCATE( rrtm_sw_asmaer_dum )
3485                   DEALLOCATE( rrtm_sw_ecaer_dum )
3486!
3487!--                Save fluxes
3488                   DO k = nzb, nzt+1
3489                      rad_sw_in(k,j,i)  = rrtm_swdflx(0,k)
3490                      rad_sw_out(k,j,i) = rrtm_swuflx(0,k)
3491                   ENDDO
3492!
3493!--                Save heating rates (convert from K/d to K/s)
3494                   DO k = nzb+1, nzt+1
3495                      rad_sw_hr(k,j,i)     = rrtm_swhr(0,k)  * d_hours_day
3496                      rad_sw_cs_hr(k,j,i)  = rrtm_swhrc(0,k) * d_hours_day
3497                   ENDDO
3498
3499!
3500!--                Save surface radiative fluxes onto respective surface elements
3501!--                Horizontal surfaces
3502                   DO  m = surf_lsm_h%start_index(j,i),                        &
3503                           surf_lsm_h%end_index(j,i)
3504                      surf_lsm_h%rad_sw_in(m)     = rrtm_swdflx(0,k_topo)
3505                      surf_lsm_h%rad_sw_out(m)    = rrtm_swuflx(0,k_topo)
3506                   ENDDO             
3507                   DO  m = surf_usm_h%start_index(j,i),                        &
3508                           surf_usm_h%end_index(j,i)
3509                      surf_usm_h%rad_sw_in(m)     = rrtm_swdflx(0,k_topo)
3510                      surf_usm_h%rad_sw_out(m)    = rrtm_swuflx(0,k_topo)
3511                   ENDDO 
3512!
3513!--                Vertical surfaces. Fluxes are obtain at respective vertical
3514!--                level of the surface element
3515                   DO  l = 0, 3
3516                      DO  m = surf_lsm_v(l)%start_index(j,i),                  &
3517                              surf_lsm_v(l)%end_index(j,i)
3518                         k                           = surf_lsm_v(l)%k(m)
3519                         surf_lsm_v(l)%rad_sw_in(m)  = rrtm_swdflx(0,k)
3520                         surf_lsm_v(l)%rad_sw_out(m) = rrtm_swuflx(0,k)
3521                      ENDDO             
3522                      DO  m = surf_usm_v(l)%start_index(j,i),                  &
3523                              surf_usm_v(l)%end_index(j,i)
3524                         k                           = surf_usm_v(l)%k(m)
3525                         surf_usm_v(l)%rad_sw_in(m)  = rrtm_swdflx(0,k)
3526                         surf_usm_v(l)%rad_sw_out(m) = rrtm_swuflx(0,k)
3527                      ENDDO 
3528                   ENDDO
3529
3530                ENDIF
3531
3532             ENDDO
3533          ENDDO
3534
3535       ENDIF
3536!
3537!--    Finally, calculate surface net radiation for surface elements.
3538!--    First, for horizontal surfaces   
3539       DO  m = 1, surf_lsm_h%ns
3540          surf_lsm_h%rad_net(m) = surf_lsm_h%rad_sw_in(m)                      &
3541                                - surf_lsm_h%rad_sw_out(m)                     &
3542                                + surf_lsm_h%rad_lw_in(m)                      &
3543                                - surf_lsm_h%rad_lw_out(m)
3544       ENDDO
3545       DO  m = 1, surf_usm_h%ns
3546          surf_usm_h%rad_net(m) = surf_usm_h%rad_sw_in(m)                      &
3547                                - surf_usm_h%rad_sw_out(m)                     &
3548                                + surf_usm_h%rad_lw_in(m)                      &
3549                                - surf_usm_h%rad_lw_out(m)
3550       ENDDO
3551!
3552!--    Vertical surfaces.
3553!--    Todo: weight with azimuth and zenith angle according to their orientation!
3554       DO  l = 0, 3     
3555          DO  m = 1, surf_lsm_v(l)%ns
3556             surf_lsm_v(l)%rad_net(m) = surf_lsm_v(l)%rad_sw_in(m)             &
3557                                      - surf_lsm_v(l)%rad_sw_out(m)            &
3558                                      + surf_lsm_v(l)%rad_lw_in(m)             &
3559                                      - surf_lsm_v(l)%rad_lw_out(m)
3560          ENDDO
3561          DO  m = 1, surf_usm_v(l)%ns
3562             surf_usm_v(l)%rad_net(m) = surf_usm_v(l)%rad_sw_in(m)             &
3563                                      - surf_usm_v(l)%rad_sw_out(m)            &
3564                                      + surf_usm_v(l)%rad_lw_in(m)             &
3565                                      - surf_usm_v(l)%rad_lw_out(m)
3566          ENDDO
3567       ENDDO
3568
3569
3570       CALL exchange_horiz( rad_lw_in,  nbgp )
3571       CALL exchange_horiz( rad_lw_out, nbgp )
3572       CALL exchange_horiz( rad_lw_hr,    nbgp )
3573       CALL exchange_horiz( rad_lw_cs_hr, nbgp )
3574
3575       CALL exchange_horiz( rad_sw_in,  nbgp )
3576       CALL exchange_horiz( rad_sw_out, nbgp ) 
3577       CALL exchange_horiz( rad_sw_hr,    nbgp )
3578       CALL exchange_horiz( rad_sw_cs_hr, nbgp )
3579
3580#endif
3581
3582    END SUBROUTINE radiation_rrtmg
3583
3584
3585!------------------------------------------------------------------------------!
3586! Description:
3587! ------------
3588!> Calculate the cosine of the zenith angle (variable is called zenith)
3589!------------------------------------------------------------------------------!
3590    SUBROUTINE calc_zenith
3591
3592       IMPLICIT NONE
3593
3594       REAL(wp) ::  declination,  & !< solar declination angle
3595                    hour_angle      !< solar hour angle
3596!
3597!--    Calculate current day and time based on the initial values and simulation
3598!--    time
3599       CALL calc_date_and_time
3600
3601!
3602!--    Calculate solar declination and hour angle   
3603       declination = ASIN( decl_1 * SIN(decl_2 * REAL(day_of_year, KIND=wp) - decl_3) )
3604       hour_angle  = 2.0_wp * pi * (time_utc / 86400.0_wp) + lon - pi
3605
3606!
3607!--    Calculate cosine of solar zenith angle
3608       zenith(0) = SIN(lat) * SIN(declination) + COS(lat) * COS(declination)   &
3609                                            * COS(hour_angle)
3610       zenith(0) = MAX(0.0_wp,zenith(0))
3611
3612!
3613!--    Calculate solar directional vector
3614       IF ( sun_direction )  THEN
3615
3616!
3617!--       Direction in longitudes equals to sin(solar_azimuth) * sin(zenith)
3618          sun_dir_lon(0) = -SIN(hour_angle) * COS(declination)
3619
3620!
3621!--       Direction in latitues equals to cos(solar_azimuth) * sin(zenith)
3622          sun_dir_lat(0) = SIN(declination) * COS(lat) - COS(hour_angle) &
3623                              * COS(declination) * SIN(lat)
3624       ENDIF
3625
3626!
3627!--    Check if the sun is up (otheriwse shortwave calculations can be skipped)
3628       IF ( zenith(0) > 0.0_wp )  THEN
3629          sun_up = .TRUE.
3630       ELSE
3631          sun_up = .FALSE.
3632       END IF
3633
3634    END SUBROUTINE calc_zenith
3635
3636#if defined ( __rrtmg ) && defined ( __netcdf )
3637!------------------------------------------------------------------------------!
3638! Description:
3639! ------------
3640!> Calculates surface albedo components based on Briegleb (1992) and
3641!> Briegleb et al. (1986)
3642!------------------------------------------------------------------------------!
3643    SUBROUTINE calc_albedo( surf )
3644
3645        IMPLICIT NONE
3646
3647        INTEGER(iwp)    ::  ind_type !< running index surface tiles
3648        INTEGER(iwp)    ::  m        !< running index surface elements
3649
3650        TYPE(surf_type) ::  surf !< treated surfaces
3651
3652        IF ( sun_up  .AND.  .NOT. average_radiation )  THEN
3653
3654           DO  m = 1, surf%ns
3655!
3656!--           Loop over surface elements
3657              DO  ind_type = 0, SIZE( surf%albedo_type, 1 ) - 1
3658           
3659!
3660!--              Ocean
3661                 IF ( surf%albedo_type(ind_type,m) == 1 )  THEN
3662                    surf%rrtm_aldir(ind_type,m) = 0.026_wp /                    &
3663                                                ( zenith(0)**1.7_wp + 0.065_wp )&
3664                                     + 0.15_wp * ( zenith(0) - 0.1_wp )         &
3665                                               * ( zenith(0) - 0.5_wp )         &
3666                                               * ( zenith(0) - 1.0_wp )
3667                    surf%rrtm_asdir(ind_type,m) = surf%rrtm_aldir(ind_type,m)
3668!
3669!--              Snow
3670                 ELSEIF ( surf%albedo_type(ind_type,m) == 16 )  THEN
3671                    IF ( zenith(0) < 0.5_wp )  THEN
3672                       surf%rrtm_aldir(ind_type,m) =                           &
3673                                 0.5_wp * ( 1.0_wp - surf%aldif(ind_type,m) )  &
3674                                        * ( 3.0_wp / ( 1.0_wp + 4.0_wp         &
3675                                        * zenith(0) ) ) - 1.0_wp
3676                       surf%rrtm_asdir(ind_type,m) =                           &
3677                                 0.5_wp * ( 1.0_wp - surf%asdif(ind_type,m) )  &
3678                                        * ( 3.0_wp / ( 1.0_wp + 4.0_wp         &
3679                                        * zenith(0) ) ) - 1.0_wp
3680
3681                       surf%rrtm_aldir(ind_type,m) =                           &
3682                                       MIN(0.98_wp, surf%rrtm_aldir(ind_type,m))
3683                       surf%rrtm_asdir(ind_type,m) =                           &
3684                                       MIN(0.98_wp, surf%rrtm_asdir(ind_type,m))
3685                    ELSE
3686                       surf%rrtm_aldir(ind_type,m) = surf%aldif(ind_type,m)
3687                       surf%rrtm_asdir(ind_type,m) = surf%asdif(ind_type,m)
3688                    ENDIF
3689!
3690!--              Sea ice
3691                 ELSEIF ( surf%albedo_type(ind_type,m) == 15 )  THEN
3692                    surf%rrtm_aldir(ind_type,m) = surf%aldif(ind_type,m)
3693                    surf%rrtm_asdir(ind_type,m) = surf%asdif(ind_type,m)
3694
3695!
3696!--              Asphalt
3697                 ELSEIF ( surf%albedo_type(ind_type,m) == 17 )  THEN
3698                    surf%rrtm_aldir(ind_type,m) = surf%aldif(ind_type,m)
3699                    surf%rrtm_asdir(ind_type,m) = surf%asdif(ind_type,m)
3700
3701
3702!
3703!--              Bare soil
3704                 ELSEIF ( surf%albedo_type(ind_type,m) == 18 )  THEN
3705                    surf%rrtm_aldir(ind_type,m) = surf%aldif(ind_type,m)
3706                    surf%rrtm_asdir(ind_type,m) = surf%asdif(ind_type,m)
3707
3708!
3709!--              Land surfaces
3710                 ELSE
3711                    SELECT CASE ( surf%albedo_type(ind_type,m) )
3712
3713!
3714!--                    Surface types with strong zenith dependence
3715                       CASE ( 1, 2, 3, 4, 11, 12, 13 )
3716                          surf%rrtm_aldir(ind_type,m) =                        &
3717                                surf%aldif(ind_type,m) * 1.4_wp /              &
3718                                           ( 1.0_wp + 0.8_wp * zenith(0) )
3719                          surf%rrtm_asdir(ind_type,m) =                        &
3720                                surf%asdif(ind_type,m) * 1.4_wp /              &
3721                                           ( 1.0_wp + 0.8_wp * zenith(0) )
3722!
3723!--                    Surface types with weak zenith dependence
3724                       CASE ( 5, 6, 7, 8, 9, 10, 14 )
3725                          surf%rrtm_aldir(ind_type,m) =                        &
3726                                surf%aldif(ind_type,m) * 1.1_wp /              &
3727                                           ( 1.0_wp + 0.2_wp * zenith(0) )
3728                          surf%rrtm_asdir(ind_type,m) =                        &
3729                                surf%asdif(ind_type,m) * 1.1_wp /              &
3730                                           ( 1.0_wp + 0.2_wp * zenith(0) )
3731
3732                       CASE DEFAULT
3733
3734                    END SELECT
3735                 ENDIF
3736!
3737!--              Diffusive albedo is taken from Table 2
3738                 surf%rrtm_aldif(ind_type,m) = surf%aldif(ind_type,m)
3739                 surf%rrtm_asdif(ind_type,m) = surf%asdif(ind_type,m)
3740              ENDDO
3741           ENDDO
3742!
3743!--     Set albedo in case of average radiation
3744        ELSEIF ( sun_up  .AND.  average_radiation )  THEN
3745           surf%rrtm_asdir = albedo_urb
3746           surf%rrtm_asdif = albedo_urb
3747           surf%rrtm_aldir = albedo_urb
3748           surf%rrtm_aldif = albedo_urb 
3749!
3750!--     Darkness
3751        ELSE
3752           surf%rrtm_aldir = 0.0_wp
3753           surf%rrtm_asdir = 0.0_wp
3754           surf%rrtm_aldif = 0.0_wp
3755           surf%rrtm_asdif = 0.0_wp
3756        ENDIF
3757
3758    END SUBROUTINE calc_albedo
3759
3760!------------------------------------------------------------------------------!
3761! Description:
3762! ------------
3763!> Read sounding data (pressure and temperature) from RADIATION_DATA.
3764!------------------------------------------------------------------------------!
3765    SUBROUTINE read_sounding_data
3766
3767       IMPLICIT NONE
3768
3769       INTEGER(iwp) :: id,           & !< NetCDF id of input file
3770                       id_dim_zrad,  & !< pressure level id in the NetCDF file
3771                       id_var,       & !< NetCDF variable id
3772                       k,            & !< loop index
3773                       nz_snd,       & !< number of vertical levels in the sounding data
3774                       nz_snd_start, & !< start vertical index for sounding data to be used
3775                       nz_snd_end      !< end vertical index for souding data to be used
3776
3777       REAL(wp) :: t_surface           !< actual surface temperature
3778
3779       REAL(wp), DIMENSION(:), ALLOCATABLE ::  hyp_snd_tmp, & !< temporary hydrostatic pressure profile (sounding)
3780                                               t_snd_tmp      !< temporary temperature profile (sounding)
3781
3782!
3783!--    In case of updates, deallocate arrays first (sufficient to check one
3784!--    array as the others are automatically allocated). This is required
3785!--    because nzt_rad might change during the update
3786       IF ( ALLOCATED ( hyp_snd ) )  THEN
3787          DEALLOCATE( hyp_snd )
3788          DEALLOCATE( t_snd )
3789          DEALLOCATE ( rrtm_play )
3790          DEALLOCATE ( rrtm_plev )
3791          DEALLOCATE ( rrtm_tlay )
3792          DEALLOCATE ( rrtm_tlev )
3793
3794          DEALLOCATE ( rrtm_cicewp )
3795          DEALLOCATE ( rrtm_cldfr )
3796          DEALLOCATE ( rrtm_cliqwp )
3797          DEALLOCATE ( rrtm_reice )
3798          DEALLOCATE ( rrtm_reliq )
3799          DEALLOCATE ( rrtm_lw_taucld )
3800          DEALLOCATE ( rrtm_lw_tauaer )
3801
3802          DEALLOCATE ( rrtm_lwdflx  )
3803          DEALLOCATE ( rrtm_lwdflxc )
3804          DEALLOCATE ( rrtm_lwuflx  )
3805          DEALLOCATE ( rrtm_lwuflxc )
3806          DEALLOCATE ( rrtm_lwuflx_dt )
3807          DEALLOCATE ( rrtm_lwuflxc_dt )
3808          DEALLOCATE ( rrtm_lwhr  )
3809          DEALLOCATE ( rrtm_lwhrc )
3810
3811          DEALLOCATE ( rrtm_sw_taucld )
3812          DEALLOCATE ( rrtm_sw_ssacld )
3813          DEALLOCATE ( rrtm_sw_asmcld )
3814          DEALLOCATE ( rrtm_sw_fsfcld )
3815          DEALLOCATE ( rrtm_sw_tauaer )
3816          DEALLOCATE ( rrtm_sw_ssaaer )
3817          DEALLOCATE ( rrtm_sw_asmaer ) 
3818          DEALLOCATE ( rrtm_sw_ecaer )   
3819 
3820          DEALLOCATE ( rrtm_swdflx  )
3821          DEALLOCATE ( rrtm_swdflxc )
3822          DEALLOCATE ( rrtm_swuflx  )
3823          DEALLOCATE ( rrtm_swuflxc )
3824          DEALLOCATE ( rrtm_swhr  )
3825          DEALLOCATE ( rrtm_swhrc )
3826
3827       ENDIF
3828
3829!
3830!--    Open file for reading
3831       nc_stat = NF90_OPEN( rrtm_input_file, NF90_NOWRITE, id )
3832       CALL netcdf_handle_error_rad( 'read_sounding_data', 549 )
3833
3834!
3835!--    Inquire dimension of z axis and save in nz_snd
3836       nc_stat = NF90_INQ_DIMID( id, "Pressure", id_dim_zrad )
3837       nc_stat = NF90_INQUIRE_DIMENSION( id, id_dim_zrad, len = nz_snd )
3838       CALL netcdf_handle_error_rad( 'read_sounding_data', 551 )
3839
3840!
3841! !--    Allocate temporary array for storing pressure data
3842       ALLOCATE( hyp_snd_tmp(1:nz_snd) )
3843       hyp_snd_tmp = 0.0_wp
3844
3845
3846!--    Read pressure from file
3847       nc_stat = NF90_INQ_VARID( id, "Pressure", id_var )
3848       nc_stat = NF90_GET_VAR( id, id_var, hyp_snd_tmp(:), start = (/1/),      &
3849                               count = (/nz_snd/) )
3850       CALL netcdf_handle_error_rad( 'read_sounding_data', 552 )
3851
3852!
3853!--    Allocate temporary array for storing temperature data
3854       ALLOCATE( t_snd_tmp(1:nz_snd) )
3855       t_snd_tmp = 0.0_wp
3856
3857!
3858!--    Read temperature from file
3859       nc_stat = NF90_INQ_VARID( id, "ReferenceTemperature", id_var )
3860       nc_stat = NF90_GET_VAR( id, id_var, t_snd_tmp(:), start = (/1/),        &
3861                               count = (/nz_snd/) )
3862       CALL netcdf_handle_error_rad( 'read_sounding_data', 553 )
3863
3864!
3865!--    Calculate start of sounding data
3866       nz_snd_start = nz_snd + 1
3867       nz_snd_end   = nz_snd + 1
3868
3869!
3870!--    Start filling vertical dimension at 10hPa above the model domain (hyp is
3871!--    in Pa, hyp_snd in hPa).
3872       DO  k = 1, nz_snd
3873          IF ( hyp_snd_tmp(k) < ( hyp(nzt+1) - 1000.0_wp) * 0.01_wp )  THEN
3874             nz_snd_start = k
3875             EXIT
3876          END IF
3877       END DO
3878
3879       IF ( nz_snd_start <= nz_snd )  THEN
3880          nz_snd_end = nz_snd
3881       END IF
3882
3883
3884!
3885!--    Calculate of total grid points for RRTMG calculations
3886       nzt_rad = nzt + nz_snd_end - nz_snd_start + 1
3887
3888!
3889!--    Save data above LES domain in hyp_snd, t_snd
3890       ALLOCATE( hyp_snd(nzb+1:nzt_rad) )
3891       ALLOCATE( t_snd(nzb+1:nzt_rad)   )
3892       hyp_snd = 0.0_wp
3893       t_snd = 0.0_wp
3894
3895       hyp_snd(nzt+2:nzt_rad) = hyp_snd_tmp(nz_snd_start+1:nz_snd_end)
3896       t_snd(nzt+2:nzt_rad)   = t_snd_tmp(nz_snd_start+1:nz_snd_end)
3897
3898       nc_stat = NF90_CLOSE( id )
3899
3900!
3901!--    Calculate pressure levels on zu and zw grid. Sounding data is added at
3902!--    top of the LES domain. This routine does not consider horizontal or
3903!--    vertical variability of pressure and temperature
3904       ALLOCATE ( rrtm_play(0:0,nzb+1:nzt_rad+1)   )
3905       ALLOCATE ( rrtm_plev(0:0,nzb+1:nzt_rad+2)   )
3906
3907       t_surface = pt_surface * ( surface_pressure / 1000.0_wp )**0.286_wp
3908       DO k = nzb+1, nzt+1
3909          rrtm_play(0,k) = hyp(k) * 0.01_wp
3910          rrtm_plev(0,k) = surface_pressure * ( (t_surface - g/cp * zw(k-1)) / &
3911                         t_surface )**(1.0_wp/0.286_wp)
3912       ENDDO
3913
3914       DO k = nzt+2, nzt_rad
3915          rrtm_play(0,k) = hyp_snd(k)
3916          rrtm_plev(0,k) = 0.5_wp * ( rrtm_play(0,k) + rrtm_play(0,k-1) )
3917       ENDDO
3918       rrtm_plev(0,nzt_rad+1) = MAX( 0.5 * hyp_snd(nzt_rad),                   &
3919                                   1.5 * hyp_snd(nzt_rad)                      &
3920                                 - 0.5 * hyp_snd(nzt_rad-1) )
3921       rrtm_plev(0,nzt_rad+2)  = MIN( 1.0E-4_wp,                               &
3922                                      0.25_wp * rrtm_plev(0,nzt_rad+1) )
3923
3924       rrtm_play(0,nzt_rad+1) = 0.5 * rrtm_plev(0,nzt_rad+1)
3925
3926!
3927!--    Calculate temperature/humidity levels at top of the LES domain.
3928!--    Currently, the temperature is taken from sounding data (might lead to a
3929!--    temperature jump at interface. To do: Humidity is currently not
3930!--    calculated above the LES domain.
3931       ALLOCATE ( rrtm_tlay(0:0,nzb+1:nzt_rad+1)   )
3932       ALLOCATE ( rrtm_tlev(0:0,nzb+1:nzt_rad+2)   )
3933
3934       DO k = nzt+8, nzt_rad
3935          rrtm_tlay(0,k)   = t_snd(k)
3936       ENDDO
3937       rrtm_tlay(0,nzt_rad+1) = 2.0_wp * rrtm_tlay(0,nzt_rad)                  &
3938                                - rrtm_tlay(0,nzt_rad-1)
3939       DO k = nzt+9, nzt_rad+1
3940          rrtm_tlev(0,k)   = rrtm_tlay(0,k-1) + (rrtm_tlay(0,k)                &
3941                             - rrtm_tlay(0,k-1))                               &
3942                             / ( rrtm_play(0,k) - rrtm_play(0,k-1) )           &
3943                             * ( rrtm_plev(0,k) - rrtm_play(0,k-1) )
3944       ENDDO
3945
3946       rrtm_tlev(0,nzt_rad+2)   = 2.0_wp * rrtm_tlay(0,nzt_rad+1)              &
3947                                  - rrtm_tlev(0,nzt_rad)
3948!
3949!--    Allocate remaining RRTMG arrays
3950       ALLOCATE ( rrtm_cicewp(0:0,nzb+1:nzt_rad+1) )
3951       ALLOCATE ( rrtm_cldfr(0:0,nzb+1:nzt_rad+1) )
3952       ALLOCATE ( rrtm_cliqwp(0:0,nzb+1:nzt_rad+1) )
3953       ALLOCATE ( rrtm_reice(0:0,nzb+1:nzt_rad+1) )
3954       ALLOCATE ( rrtm_reliq(0:0,nzb+1:nzt_rad+1) )
3955       ALLOCATE ( rrtm_lw_taucld(1:nbndlw+1,0:0,nzb+1:nzt_rad+1) )
3956       ALLOCATE ( rrtm_lw_tauaer(0:0,nzb+1:nzt_rad+1,1:nbndlw+1) )
3957       ALLOCATE ( rrtm_sw_taucld(1:nbndsw+1,0:0,nzb+1:nzt_rad+1) )
3958       ALLOCATE ( rrtm_sw_ssacld(1:nbndsw+1,0:0,nzb+1:nzt_rad+1) )
3959       ALLOCATE ( rrtm_sw_asmcld(1:nbndsw+1,0:0,nzb+1:nzt_rad+1) )
3960       ALLOCATE ( rrtm_sw_fsfcld(1:nbndsw+1,0:0,nzb+1:nzt_rad+1) )
3961       ALLOCATE ( rrtm_sw_tauaer(0:0,nzb+1:nzt_rad+1,1:nbndsw+1) )
3962       ALLOCATE ( rrtm_sw_ssaaer(0:0,nzb+1:nzt_rad+1,1:nbndsw+1) )
3963       ALLOCATE ( rrtm_sw_asmaer(0:0,nzb+1:nzt_rad+1,1:nbndsw+1) ) 
3964       ALLOCATE ( rrtm_sw_ecaer(0:0,nzb+1:nzt_rad+1,1:naerec+1) )   
3965
3966!
3967!--    The ice phase is currently not considered in PALM
3968       rrtm_cicewp = 0.0_wp
3969       rrtm_reice  = 0.0_wp
3970
3971!
3972!--    Set other parameters (move to NAMELIST parameters in the future)
3973       rrtm_lw_tauaer = 0.0_wp
3974       rrtm_lw_taucld = 0.0_wp
3975       rrtm_sw_taucld = 0.0_wp
3976       rrtm_sw_ssacld = 0.0_wp
3977       rrtm_sw_asmcld = 0.0_wp
3978       rrtm_sw_fsfcld = 0.0_wp
3979       rrtm_sw_tauaer = 0.0_wp
3980       rrtm_sw_ssaaer = 0.0_wp
3981       rrtm_sw_asmaer = 0.0_wp
3982       rrtm_sw_ecaer  = 0.0_wp
3983
3984
3985       ALLOCATE ( rrtm_swdflx(0:0,nzb:nzt_rad+1)  )
3986       ALLOCATE ( rrtm_swuflx(0:0,nzb:nzt_rad+1)  )
3987       ALLOCATE ( rrtm_swhr(0:0,nzb+1:nzt_rad+1)  )
3988       ALLOCATE ( rrtm_swuflxc(0:0,nzb:nzt_rad+1) )
3989       ALLOCATE ( rrtm_swdflxc(0:0,nzb:nzt_rad+1) )
3990       ALLOCATE ( rrtm_swhrc(0:0,nzb+1:nzt_rad+1) )
3991
3992       rrtm_swdflx  = 0.0_wp
3993       rrtm_swuflx  = 0.0_wp
3994       rrtm_swhr    = 0.0_wp 
3995       rrtm_swuflxc = 0.0_wp
3996       rrtm_swdflxc = 0.0_wp
3997       rrtm_swhrc   = 0.0_wp
3998
3999       ALLOCATE ( rrtm_lwdflx(0:0,nzb:nzt_rad+1)  )
4000       ALLOCATE ( rrtm_lwuflx(0:0,nzb:nzt_rad+1)  )
4001       ALLOCATE ( rrtm_lwhr(0:0,nzb+1:nzt_rad+1)  )
4002       ALLOCATE ( rrtm_lwuflxc(0:0,nzb:nzt_rad+1) )
4003       ALLOCATE ( rrtm_lwdflxc(0:0,nzb:nzt_rad+1) )
4004       ALLOCATE ( rrtm_lwhrc(0:0,nzb+1:nzt_rad+1) )
4005
4006       rrtm_lwdflx  = 0.0_wp
4007       rrtm_lwuflx  = 0.0_wp
4008       rrtm_lwhr    = 0.0_wp 
4009       rrtm_lwuflxc = 0.0_wp
4010       rrtm_lwdflxc = 0.0_wp
4011       rrtm_lwhrc   = 0.0_wp
4012
4013       ALLOCATE ( rrtm_lwuflx_dt(0:0,nzb:nzt_rad+1) )
4014       ALLOCATE ( rrtm_lwuflxc_dt(0:0,nzb:nzt_rad+1) )
4015
4016       rrtm_lwuflx_dt = 0.0_wp
4017       rrtm_lwuflxc_dt = 0.0_wp
4018
4019    END SUBROUTINE read_sounding_data
4020
4021
4022!------------------------------------------------------------------------------!
4023! Description:
4024! ------------
4025!> Read trace gas data from file
4026!------------------------------------------------------------------------------!
4027    SUBROUTINE read_trace_gas_data
4028
4029       USE rrsw_ncpar
4030
4031       IMPLICIT NONE
4032
4033       INTEGER(iwp), PARAMETER :: num_trace_gases = 10 !< number of trace gases (absorbers)
4034
4035       CHARACTER(LEN=5), DIMENSION(num_trace_gases), PARAMETER ::              & !< trace gas names
4036           trace_names = (/'O3   ', 'CO2  ', 'CH4  ', 'N2O  ', 'O2   ',        &
4037                           'CFC11', 'CFC12', 'CFC22', 'CCL4 ', 'H2O  '/)
4038
4039       INTEGER(iwp) :: id,     & !< NetCDF id
4040                       k,      & !< loop index
4041                       m,      & !< loop index
4042                       n,      & !< loop index
4043                       nabs,   & !< number of absorbers
4044                       np,     & !< number of pressure levels
4045                       id_abs, & !< NetCDF id of the respective absorber
4046                       id_dim, & !< NetCDF id of asborber's dimension
4047                       id_var    !< NetCDf id ot the absorber
4048
4049       REAL(wp) :: p_mls_l, p_mls_u, p_wgt_l, p_wgt_u, p_mls_m
4050
4051
4052       REAL(wp), DIMENSION(:), ALLOCATABLE   ::  p_mls,          & !< pressure levels for the absorbers
4053                                                 rrtm_play_tmp,  & !< temporary array for pressure zu-levels
4054                                                 rrtm_plev_tmp,  & !< temporary array for pressure zw-levels
4055                                                 trace_path_tmp    !< temporary array for storing trace gas path data
4056
4057       REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  trace_mls,      & !< array for storing the absorber amounts
4058                                                 trace_mls_path, & !< array for storing trace gas path data
4059                                                 trace_mls_tmp     !< temporary array for storing trace gas data
4060
4061
4062!
4063!--    In case of updates, deallocate arrays first (sufficient to check one
4064!--    array as the others are automatically allocated)
4065       IF ( ALLOCATED ( rrtm_o3vmr ) )  THEN
4066          DEALLOCATE ( rrtm_o3vmr  )
4067          DEALLOCATE ( rrtm_co2vmr )
4068          DEALLOCATE ( rrtm_ch4vmr )
4069          DEALLOCATE ( rrtm_n2ovmr )
4070          DEALLOCATE ( rrtm_o2vmr  )
4071          DEALLOCATE ( rrtm_cfc11vmr )
4072          DEALLOCATE ( rrtm_cfc12vmr )
4073          DEALLOCATE ( rrtm_cfc22vmr )
4074          DEALLOCATE ( rrtm_ccl4vmr  )
4075          DEALLOCATE ( rrtm_h2ovmr  )     
4076       ENDIF
4077
4078!
4079!--    Allocate trace gas profiles
4080       ALLOCATE ( rrtm_o3vmr(0:0,1:nzt_rad+1)  )
4081       ALLOCATE ( rrtm_co2vmr(0:0,1:nzt_rad+1) )
4082       ALLOCATE ( rrtm_ch4vmr(0:0,1:nzt_rad+1) )
4083       ALLOCATE ( rrtm_n2ovmr(0:0,1:nzt_rad+1) )
4084       ALLOCATE ( rrtm_o2vmr(0:0,1:nzt_rad+1)  )
4085       ALLOCATE ( rrtm_cfc11vmr(0:0,1:nzt_rad+1) )
4086       ALLOCATE ( rrtm_cfc12vmr(0:0,1:nzt_rad+1) )
4087       ALLOCATE ( rrtm_cfc22vmr(0:0,1:nzt_rad+1) )
4088       ALLOCATE ( rrtm_ccl4vmr(0:0,1:nzt_rad+1)  )
4089       ALLOCATE ( rrtm_h2ovmr(0:0,1:nzt_rad+1)  )
4090
4091!
4092!--    Open file for reading
4093       nc_stat = NF90_OPEN( rrtm_input_file, NF90_NOWRITE, id )
4094       CALL netcdf_handle_error_rad( 'read_trace_gas_data', 549 )
4095!
4096!--    Inquire dimension ids and dimensions
4097       nc_stat = NF90_INQ_DIMID( id, "Pressure", id_dim )
4098       CALL netcdf_handle_error_rad( 'read_trace_gas_data', 550 )
4099       nc_stat = NF90_INQUIRE_DIMENSION( id, id_dim, len = np) 
4100       CALL netcdf_handle_error_rad( 'read_trace_gas_data', 550 )
4101
4102       nc_stat = NF90_INQ_DIMID( id, "Absorber", id_dim )
4103       CALL netcdf_handle_error_rad( 'read_trace_gas_data', 550 )
4104       nc_stat = NF90_INQUIRE_DIMENSION( id, id_dim, len = nabs ) 
4105       CALL netcdf_handle_error_rad( 'read_trace_gas_data', 550 )
4106   
4107
4108!
4109!--    Allocate pressure, and trace gas arrays     
4110       ALLOCATE( p_mls(1:np) )
4111       ALLOCATE( trace_mls(1:num_trace_gases,1:np) ) 
4112       ALLOCATE( trace_mls_tmp(1:nabs,1:np) ) 
4113
4114
4115       nc_stat = NF90_INQ_VARID( id, "Pressure", id_var )
4116       CALL netcdf_handle_error_rad( 'read_trace_gas_data', 550 )
4117       nc_stat = NF90_GET_VAR( id, id_var, p_mls )
4118       CALL netcdf_handle_error_rad( 'read_trace_gas_data', 550 )
4119
4120       nc_stat = NF90_INQ_VARID( id, "AbsorberAmountMLS", id_var )
4121       CALL netcdf_handle_error_rad( 'read_trace_gas_data', 550 )
4122       nc_stat = NF90_GET_VAR( id, id_var, trace_mls_tmp )
4123       CALL netcdf_handle_error_rad( 'read_trace_gas_data', 550 )
4124
4125
4126!
4127!--    Write absorber amounts (mls) to trace_mls
4128       DO n = 1, num_trace_gases
4129          CALL getAbsorberIndex( TRIM( trace_names(n) ), id_abs )
4130
4131          trace_mls(n,1:np) = trace_mls_tmp(id_abs,1:np)
4132
4133!
4134!--       Replace missing values by zero
4135          WHERE ( trace_mls(n,:) > 2.0_wp ) 
4136             trace_mls(n,:) = 0.0_wp
4137          END WHERE
4138       END DO
4139
4140       DEALLOCATE ( trace_mls_tmp )
4141
4142       nc_stat = NF90_CLOSE( id )
4143       CALL netcdf_handle_error_rad( 'read_trace_gas_data', 551 )
4144
4145!
4146!--    Add extra pressure level for calculations of the trace gas paths
4147       ALLOCATE ( rrtm_play_tmp(1:nzt_rad+1) )
4148       ALLOCATE ( rrtm_plev_tmp(1:nzt_rad+2) )
4149
4150       rrtm_play_tmp(1:nzt_rad)   = rrtm_play(0,1:nzt_rad) 
4151       rrtm_plev_tmp(1:nzt_rad+1) = rrtm_plev(0,1:nzt_rad+1)
4152       rrtm_play_tmp(nzt_rad+1)   = rrtm_plev(0,nzt_rad+1) * 0.5_wp
4153       rrtm_plev_tmp(nzt_rad+2)   = MIN( 1.0E-4_wp, 0.25_wp                    &
4154                                         * rrtm_plev(0,nzt_rad+1) )
4155 
4156!
4157!--    Calculate trace gas path (zero at surface) with interpolation to the
4158!--    sounding levels
4159       ALLOCATE ( trace_mls_path(1:nzt_rad+2,1:num_trace_gases) )
4160
4161       trace_mls_path(nzb+1,:) = 0.0_wp
4162       
4163       DO k = nzb+2, nzt_rad+2
4164          DO m = 1, num_trace_gases
4165             trace_mls_path(k,m) = trace_mls_path(k-1,m)
4166
4167!
4168!--          When the pressure level is higher than the trace gas pressure
4169!--          level, assume that
4170             IF ( rrtm_plev_tmp(k-1) > p_mls(1) )  THEN             
4171               
4172                trace_mls_path(k,m) = trace_mls_path(k,m) + trace_mls(m,1)     &
4173                                      * ( rrtm_plev_tmp(k-1)                   &
4174                                          - MAX( p_mls(1), rrtm_plev_tmp(k) )  &
4175                                        ) / g
4176             ENDIF
4177
4178!
4179!--          Integrate for each sounding level from the contributing p_mls
4180!--          levels
4181             DO n = 2, np
4182!
4183!--             Limit p_mls so that it is within the model level
4184                p_mls_u = MIN( rrtm_plev_tmp(k-1),                             &
4185                          MAX( rrtm_plev_tmp(k), p_mls(n) ) )
4186                p_mls_l = MIN( rrtm_plev_tmp(k-1),                             &
4187                          MAX( rrtm_plev_tmp(k), p_mls(n-1) ) )
4188
4189                IF ( p_mls_l > p_mls_u )  THEN
4190
4191!
4192!--                Calculate weights for interpolation
4193                   p_mls_m = 0.5_wp * (p_mls_l + p_mls_u)
4194                   p_wgt_u = (p_mls(n-1) - p_mls_m) / (p_mls(n-1) - p_mls(n))
4195                   p_wgt_l = (p_mls_m - p_mls(n))   / (p_mls(n-1) - p_mls(n))
4196
4197!
4198!--                Add level to trace gas path
4199                   trace_mls_path(k,m) = trace_mls_path(k,m)                   &
4200                                         +  ( p_wgt_u * trace_mls(m,n)         &
4201                                            + p_wgt_l * trace_mls(m,n-1) )     &
4202                                         * (p_mls_l - p_mls_u) / g
4203                ENDIF
4204             ENDDO
4205
4206             IF ( rrtm_plev_tmp(k) < p_mls(np) )  THEN
4207                trace_mls_path(k,m) = trace_mls_path(k,m) + trace_mls(m,np)    &
4208                                      * ( MIN( rrtm_plev_tmp(k-1), p_mls(np) ) &
4209                                          - rrtm_plev_tmp(k)                   &
4210                                        ) / g 
4211             ENDIF 
4212          ENDDO
4213       ENDDO
4214
4215
4216!
4217!--    Prepare trace gas path profiles
4218       ALLOCATE ( trace_path_tmp(1:nzt_rad+1) )
4219
4220       DO m = 1, num_trace_gases
4221
4222          trace_path_tmp(1:nzt_rad+1) = ( trace_mls_path(2:nzt_rad+2,m)        &
4223                                       - trace_mls_path(1:nzt_rad+1,m) ) * g   &
4224                                       / ( rrtm_plev_tmp(1:nzt_rad+1)          &
4225                                       - rrtm_plev_tmp(2:nzt_rad+2) )
4226
4227!
4228!--       Save trace gas paths to the respective arrays
4229          SELECT CASE ( TRIM( trace_names(m) ) )
4230
4231             CASE ( 'O3' )
4232
4233                rrtm_o3vmr(0,:) = trace_path_tmp(:)
4234
4235             CASE ( 'CO2' )
4236
4237                rrtm_co2vmr(0,:) = trace_path_tmp(:)
4238
4239             CASE ( 'CH4' )
4240
4241                rrtm_ch4vmr(0,:) = trace_path_tmp(:)
4242
4243             CASE ( 'N2O' )
4244
4245                rrtm_n2ovmr(0,:) = trace_path_tmp(:)
4246
4247             CASE ( 'O2' )
4248
4249                rrtm_o2vmr(0,:) = trace_path_tmp(:)
4250
4251             CASE ( 'CFC11' )
4252
4253                rrtm_cfc11vmr(0,:) = trace_path_tmp(:)
4254
4255             CASE ( 'CFC12' )
4256
4257                rrtm_cfc12vmr(0,:) = trace_path_tmp(:)
4258
4259             CASE ( 'CFC22' )
4260
4261                rrtm_cfc22vmr(0,:) = trace_path_tmp(:)
4262
4263             CASE ( 'CCL4' )
4264
4265                rrtm_ccl4vmr(0,:) = trace_path_tmp(:)
4266
4267             CASE ( 'H2O' )
4268
4269                rrtm_h2ovmr(0,:) = trace_path_tmp(:)
4270               
4271             CASE DEFAULT
4272
4273          END SELECT
4274
4275       ENDDO
4276
4277       DEALLOCATE ( trace_path_tmp )
4278       DEALLOCATE ( trace_mls_path )
4279       DEALLOCATE ( rrtm_play_tmp )
4280       DEALLOCATE ( rrtm_plev_tmp )
4281       DEALLOCATE ( trace_mls )
4282       DEALLOCATE ( p_mls )
4283
4284    END SUBROUTINE read_trace_gas_data
4285
4286
4287    SUBROUTINE netcdf_handle_error_rad( routine_name, errno )
4288
4289       USE control_parameters,                                                 &
4290           ONLY:  message_string
4291
4292       USE NETCDF
4293
4294       USE pegrid
4295
4296       IMPLICIT NONE
4297
4298       CHARACTER(LEN=6) ::  message_identifier
4299       CHARACTER(LEN=*) ::  routine_name
4300
4301       INTEGER(iwp) ::  errno
4302
4303       IF ( nc_stat /= NF90_NOERR )  THEN
4304
4305          WRITE( message_identifier, '(''NC'',I4.4)' )  errno
4306          message_string = TRIM( NF90_STRERROR( nc_stat ) )
4307
4308          CALL message( routine_name, message_identifier, 2, 2, 0, 6, 1 )
4309
4310       ENDIF
4311
4312    END SUBROUTINE netcdf_handle_error_rad
4313#endif
4314
4315
4316!------------------------------------------------------------------------------!
4317! Description:
4318! ------------
4319!> Calculate temperature tendency due to radiative cooling/heating.
4320!> Cache-optimized version.
4321!------------------------------------------------------------------------------!
4322 SUBROUTINE radiation_tendency_ij ( i, j, tend )
4323
4324    USE cloud_parameters,                                                      &
4325        ONLY:  pt_d_t
4326
4327    IMPLICIT NONE
4328
4329    INTEGER(iwp) :: i, j, k !< loop indices
4330
4331    REAL(wp), DIMENSION(nzb:nzt+1,nysg:nyng,nxlg:nxrg) :: tend !< pt tendency term
4332
4333    IF ( radiation_scheme == 'rrtmg' )  THEN
4334#if defined  ( __rrtmg )
4335!
4336!--    Calculate tendency based on heating rate
4337       DO k = nzb+1, nzt+1
4338          tend(k,j,i) = tend(k,j,i) + (rad_lw_hr(k,j,i) + rad_sw_hr(k,j,i))    &
4339                                         * pt_d_t(k) * d_seconds_hour
4340       ENDDO
4341#endif
4342    ENDIF
4343
4344    END SUBROUTINE radiation_tendency_ij
4345
4346
4347!------------------------------------------------------------------------------!
4348! Description:
4349! ------------
4350!> Calculate temperature tendency due to radiative cooling/heating.
4351!> Vector-optimized version
4352!------------------------------------------------------------------------------!
4353 SUBROUTINE radiation_tendency ( tend )
4354
4355    USE cloud_parameters,                                                      &
4356        ONLY:  pt_d_t
4357
4358    USE indices,                                                               &
4359        ONLY:  nxl, nxr, nyn, nys
4360
4361    IMPLICIT NONE
4362
4363    INTEGER(iwp) :: i, j, k !< loop indices
4364
4365    REAL(wp), DIMENSION(nzb:nzt+1,nysg:nyng,nxlg:nxrg) :: tend !< pt tendency term
4366
4367    IF ( radiation_scheme == 'rrtmg' )  THEN
4368#if defined  ( __rrtmg )
4369!
4370!--    Calculate tendency based on heating rate
4371       DO  i = nxl, nxr
4372          DO  j = nys, nyn
4373             DO k = nzb+1, nzt+1
4374                tend(k,j,i) = tend(k,j,i) + ( rad_lw_hr(k,j,i)                 &
4375                                          +  rad_sw_hr(k,j,i) ) * pt_d_t(k)    &
4376                                          * d_seconds_hour
4377             ENDDO
4378          ENDDO
4379       ENDDO
4380#endif
4381    ENDIF
4382
4383
4384 END SUBROUTINE radiation_tendency
4385
4386!------------------------------------------------------------------------------!
4387! Description:
4388! ------------
4389!> This subroutine calculates interaction of the solar radiation
4390!> with urban and land surfaces and updates all surface heatfluxes.
4391!> It calculates also the required parameters for RRTMG lower BC.
4392!>
4393!> For more info. see Resler et al. 2017
4394!>
4395!> The new version 2.0 was radically rewriten, the discretization scheme
4396!> has been changed. This new version significantly improves effectivity
4397!> of the paralelization and the scalability of the model.
4398!------------------------------------------------------------------------------!
4399
4400 SUBROUTINE radiation_interaction
4401
4402     IMPLICIT NONE
4403
4404     INTEGER(iwp)                      :: i, j, k, kk, is, js, d, ku, refstep, m, mm, l, ll
4405     INTEGER(iwp)                      :: nzubl, nzutl, isurf, isurfsrc, isvf, icsf, ipcgb
4406     INTEGER(iwp)                      :: isd                !< solar direction number
4407     REAL(wp), DIMENSION(3,3)          :: mrot               !< grid rotation matrix (zyx)
4408     REAL(wp), DIMENSION(3,0:nsurf_type):: vnorm             !< face direction normal vectors (zyx)
4409     REAL(wp), DIMENSION(3)            :: sunorig            !< grid rotated solar direction unit vector (zyx)
4410     REAL(wp), DIMENSION(3)            :: sunorig_grid       !< grid squashed solar direction unit vector (zyx)
4411     REAL(wp), DIMENSION(0:nsurf_type) :: costheta           !< direct irradiance factor of solar angle
4412     REAL(wp), DIMENSION(nzub:nzut)    :: pchf_prep          !< precalculated factor for canopy temperature tendency
4413     REAL(wp), DIMENSION(nzub:nzut)    :: pctf_prep          !< precalculated factor for canopy transpiration tendency
4414     REAL(wp), PARAMETER               :: alpha = 0._wp      !< grid rotation (TODO: add to namelist or remove)
4415     REAL(wp)                          :: pc_box_area, pc_abs_frac, pc_abs_eff
4416     INTEGER(iwp)                      :: pc_box_dimshift    !< transform for best accuracy
4417     INTEGER(iwp), DIMENSION(0:3)      :: reorder = (/ 1, 0, 3, 2 /)
4418     REAL(wp), DIMENSION(0:nsurf_type) :: facearea
4419     REAL(wp)                          :: pabsswl  = 0.0_wp  !< total absorbed SW radiation energy in local processor (W)
4420     REAL(wp)                          :: pabssw   = 0.0_wp  !< total absorbed SW radiation energy in all processors (W)
4421     REAL(wp)                          :: pabslwl  = 0.0_wp  !< total absorbed LW radiation energy in local processor (W)
4422     REAL(wp)                          :: pabslw   = 0.0_wp  !< total absorbed LW radiation energy in all processors (W)
4423     REAL(wp)                          :: pemitlwl = 0.0_wp  !< total emitted LW radiation energy in all processors (W)
4424     REAL(wp)                          :: pemitlw  = 0.0_wp  !< total emitted LW radiation energy in all processors (W)
4425     REAL(wp)                          :: pinswl   = 0.0_wp  !< total received SW radiation energy in local processor (W)
4426     REAL(wp)                          :: pinsw    = 0.0_wp  !< total received SW radiation energy in all processor (W)
4427     REAL(wp)                          :: pinlwl   = 0.0_wp  !< total received LW radiation energy in local processor (W)
4428     REAL(wp)                          :: pinlw    = 0.0_wp  !< total received LW radiation energy in all processor (W)
4429     REAL(wp)                          :: emiss_sum_surfl    !< sum of emissisivity of surfaces in local processor
4430     REAL(wp)                          :: emiss_sum_surf     !< sum of emissisivity of surfaces in all processor
4431     REAL(wp)                          :: area_surfl         !< total area of surfaces in local processor
4432     REAL(wp)                          :: area_surf          !< total area of surfaces in all processor
4433     REAL(wp)                          :: area_horl          !< total horizontal area of domain in local processor
4434     REAL(wp)                          :: area_hor           !< total horizontal area of domain in all processor
4435
4436
4437
4438#if ! defined( __nopointer )
4439     IF ( plant_canopy )  THEN
4440         pchf_prep(:) = r_d * (hyp(nzub:nzut) / 100000.0_wp)**0.286_wp &
4441                     / (cp * hyp(nzub:nzut) * dx*dy*dz(1)) !< equals to 1 / (rho * c_p * Vbox * T)
4442         pctf_prep(:) = r_d * (hyp(nzub:nzut) / 100000.0_wp)**0.286_wp &
4443                     / (l_v * hyp(nzub:nzut) * dx*dy*dz(1))
4444     ENDIF
4445#endif
4446     sun_direction = .TRUE.
4447     CALL calc_zenith  !< required also for diffusion radiation
4448
4449!--     prepare rotated normal vectors and irradiance factor
4450     vnorm(1,:) = kdir(:)
4451     vnorm(2,:) = jdir(:)
4452     vnorm(3,:) = idir(:)
4453     mrot(1, :) = (/ 1._wp,  0._wp,      0._wp      /)
4454     mrot(2, :) = (/ 0._wp,  COS(alpha), SIN(alpha) /)
4455     mrot(3, :) = (/ 0._wp, -SIN(alpha), COS(alpha) /)
4456     sunorig = (/ zenith(0), sun_dir_lat, sun_dir_lon /)
4457     sunorig = MATMUL(mrot, sunorig)
4458     DO d = 0, nsurf_type
4459         costheta(d) = DOT_PRODUCT(sunorig, vnorm(:,d))
4460     ENDDO
4461
4462     IF ( zenith(0) > 0 )  THEN
4463!--         now we will "squash" the sunorig vector by grid box size in
4464!--         each dimension, so that this new direction vector will allow us
4465!--         to traverse the ray path within grid coordinates directly
4466         sunorig_grid = (/ sunorig(1)/dz(1), sunorig(2)/dy, sunorig(3)/dx /)
4467!--         sunorig_grid = sunorig_grid / norm2(sunorig_grid)
4468         sunorig_grid = sunorig_grid / SQRT(SUM(sunorig_grid**2))
4469
4470         IF ( npcbl > 0 )  THEN
4471!--            precompute effective box depth with prototype Leaf Area Density
4472            pc_box_dimshift = MAXLOC(ABS(sunorig), 1) - 1
4473            CALL box_absorb(CSHIFT((/dz(1),dy,dx/), pc_box_dimshift),      &
4474                                60, prototype_lad,                          &
4475                                CSHIFT(ABS(sunorig), pc_box_dimshift),      &
4476                                pc_box_area, pc_abs_frac)
4477            pc_box_area = pc_box_area * ABS(sunorig(pc_box_dimshift+1) / sunorig(1))
4478            pc_abs_eff = LOG(1._wp - pc_abs_frac) / prototype_lad
4479         ENDIF
4480     ENDIF
4481
4482!--     split diffusion and direct part of the solar downward radiation
4483!--     comming from radiation model and store it in 2D arrays
4484!--     rad_sw_in_diff, rad_sw_in_dir and rad_lw_in_diff
4485     IF ( split_diffusion_radiation )  THEN
4486         CALL calc_diffusion_radiation
4487     ELSE
4488         rad_sw_in_diff = 0.0_wp
4489         rad_sw_in_dir(:,:)  = rad_sw_in(0,:,:)
4490         rad_lw_in_diff(:,:) = rad_lw_in(0,:,:)
4491     ENDIF
4492
4493!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4494!--     First pass: direct + diffuse irradiance + thermal
4495!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4496     surfinswdir   = 0._wp !nsurfl
4497     surfins       = 0._wp !nsurfl
4498     surfinl       = 0._wp !nsurfl
4499     surfoutsl(:)  = 0.0_wp !start-end
4500     surfoutll(:)  = 0.0_wp !start-end
4501
4502!--  Set up thermal radiation from surfaces
4503!--  emiss_surf is defined only for surfaces for which energy balance is calculated
4504!--  Workaround: reorder surface data type back on 1D array including all surfaces,
4505!--  which implies to reorder horizontal and vertical surfaces
4506!
4507!--  Horizontal walls
4508     mm = 1
4509     DO  i = nxl, nxr
4510        DO  j = nys, nyn
4511!--           urban
4512           DO  m = surf_usm_h%start_index(j,i), surf_usm_h%end_index(j,i)
4513              surfoutll(mm) = SUM ( surf_usm_h%frac(:,m) *                  &
4514                                    surf_usm_h%emissivity(:,m) )            &
4515                                  * sigma_sb                                &
4516                                  * surf_usm_h%pt_surface(m)**4
4517              albedo_surf(mm) = SUM ( surf_usm_h%frac(:,m) *                &
4518                                      surf_usm_h%albedo(:,m) )
4519              emiss_surf(mm)  = SUM ( surf_usm_h%frac(:,m) *                &
4520                                      surf_usm_h%emissivity(:,m) )
4521              mm = mm + 1
4522           ENDDO
4523!--           land
4524           DO  m = surf_lsm_h%start_index(j,i), surf_lsm_h%end_index(j,i)
4525              surfoutll(mm) = SUM ( surf_lsm_h%frac(:,m) *                  &
4526                                    surf_lsm_h%emissivity(:,m) )            &
4527                                  * sigma_sb                                &
4528                                  * surf_lsm_h%pt_surface(m)**4
4529              albedo_surf(mm) = SUM ( surf_lsm_h%frac(:,m) *                &
4530                                      surf_lsm_h%albedo(:,m) )
4531              emiss_surf(mm)  = SUM ( surf_lsm_h%frac(:,m) *                &
4532                                      surf_lsm_h%emissivity(:,m) )
4533              mm = mm + 1
4534           ENDDO
4535        ENDDO
4536     ENDDO
4537!
4538!--     Vertical walls
4539     DO  i = nxl, nxr
4540        DO  j = nys, nyn
4541           DO  ll = 0, 3
4542              l = reorder(ll)
4543!--              urban
4544              DO  m = surf_usm_v(l)%start_index(j,i),                       &
4545                      surf_usm_v(l)%end_index(j,i)
4546                 surfoutll(mm) = SUM ( surf_usm_v(l)%frac(:,m) *            &
4547                                       surf_usm_v(l)%emissivity(:,m) )      &
4548                                  * sigma_sb                                &
4549                                  * surf_usm_v(l)%pt_surface(m)**4
4550                 albedo_surf(mm) = SUM ( surf_usm_v(l)%frac(:,m) *          &
4551                                         surf_usm_v(l)%albedo(:,m) )
4552                 emiss_surf(mm)  = SUM ( surf_usm_v(l)%frac(:,m) *          &
4553                                         surf_usm_v(l)%emissivity(:,m) )
4554                 mm = mm + 1
4555              ENDDO
4556!--              land
4557              DO  m = surf_lsm_v(l)%start_index(j,i),                       &
4558                      surf_lsm_v(l)%end_index(j,i)
4559                 surfoutll(mm) = SUM ( surf_lsm_v(l)%frac(:,m) *            &
4560                                       surf_lsm_v(l)%emissivity(:,m) )      &
4561                                  * sigma_sb                                &
4562                                  * surf_lsm_v(l)%pt_surface(m)**4
4563                 albedo_surf(mm) = SUM ( surf_lsm_v(l)%frac(:,m) *          &
4564                                         surf_lsm_v(l)%albedo(:,m) )
4565                 emiss_surf(mm)  = SUM ( surf_lsm_v(l)%frac(:,m) *          &
4566                                         surf_lsm_v(l)%emissivity(:,m) )
4567                 mm = mm + 1
4568              ENDDO
4569           ENDDO
4570        ENDDO
4571     ENDDO
4572
4573#if defined( __parallel )
4574!--     might be optimized and gather only values relevant for current processor
4575     CALL MPI_AllGatherv(surfoutll, nsurfl, MPI_REAL, &
4576                         surfoutl, nsurfs, surfstart, MPI_REAL, comm2d, ierr) !nsurf global
4577#else
4578     surfoutl(:) = surfoutll(:) !nsurf global
4579#endif
4580
4581     IF ( surface_reflections)  THEN
4582        DO  isvf = 1, nsvfl
4583           isurf = svfsurf(1, isvf)
4584           k     = surfl(iz, isurf)
4585           j     = surfl(iy, isurf)
4586           i     = surfl(ix, isurf)
4587           isurfsrc = svfsurf(2, isvf)
4588!
4589!--        For surface-to-surface factors we calculate thermal radiation in 1st pass
4590           surfinl(isurf) = surfinl(isurf) + svf(1,isvf) * surfoutl(isurfsrc)
4591        ENDDO
4592     ENDIF
4593
4594     !-- diffuse radiation using sky view factor, TODO: homogeneous rad_*w_in_diff because now it depends on no. of processors
4595     surfinswdif(:) = rad_sw_in_diff(nyn,nxl) * skyvft(:)
4596     surfinlwdif(:) = rad_lw_in_diff(nyn,nxl) * skyvf(:)
4597
4598     !-- direct radiation
4599     IF ( zenith(0) > 0 )  THEN
4600        !--Identify solar direction vector (discretized number) 1)
4601        !--
4602        j = FLOOR(ACOS(zenith(0)) / pi * raytrace_discrete_elevs)
4603        i = MODULO(NINT(ATAN2(sun_dir_lon(0), sun_dir_lat(0))               &
4604                        / (2._wp*pi) * raytrace_discrete_azims-.5_wp, iwp), &
4605                   raytrace_discrete_azims)
4606        isd = dsidir_rev(j, i)
4607        DO isurf = 1, nsurfl
4608           surfinswdir(isurf) = rad_sw_in_dir(nyn,nxl) * costheta(surfl(id, isurf)) * dsitrans(isurf, isd) / zenith(0)
4609        ENDDO
4610     ENDIF
4611
4612     IF ( npcbl > 0 )  THEN
4613
4614         pcbinswdir(:) = 0._wp
4615         pcbinswdif(:) = 0._wp
4616         pcbinlw(:) = 0._wp  !< will stay always 0 since we don't absorb lw anymore
4617!
4618!--         pcsf first pass
4619         DO icsf = 1, ncsfl
4620             ipcgb = csfsurf(1, icsf)
4621             i = pcbl(ix,ipcgb)
4622             j = pcbl(iy,ipcgb)
4623             k = pcbl(iz,ipcgb)
4624             isurfsrc = csfsurf(2, icsf)
4625
4626             IF ( isurfsrc == -1 )  THEN
4627!--                 Diffuse rad from sky.
4628                 pcbinswdif(ipcgb) = csf(1,icsf) * csf(2,icsf) * rad_sw_in_diff(j,i)
4629
4630                 !--Direct rad
4631                 IF ( zenith(0) > 0 )  THEN
4632                    !--Estimate directed box absorption
4633                    pc_abs_frac = 1._wp - exp(pc_abs_eff * lad_s(k,j,i))
4634
4635                    !--isd has already been established, see 1)
4636                    pcbinswdir(ipcgb) = rad_sw_in_dir(j, i) * pc_box_area &
4637                                        * pc_abs_frac * dsitransc(ipcgb, isd)
4638                 ENDIF
4639
4640                 EXIT ! only isurfsrc=-1 is processed here
4641             ENDIF
4642         ENDDO
4643
4644         pcbinsw(:) = pcbinswdir(:) + pcbinswdif(:)
4645     ENDIF
4646     surfins = surfinswdir + surfinswdif
4647     surfinl = surfinl + surfinlwdif
4648     surfinsw = surfins
4649     surfinlw = surfinl
4650     surfoutsw = 0.0_wp
4651     surfoutlw = surfoutll
4652     surfemitlwl = surfoutll
4653!        surfhf = surfinsw + surfinlw - surfoutsw - surfoutlw
4654
4655     IF ( .NOT.  surface_reflections )  THEN
4656!
4657!--     Set nrefsteps to 0 to disable reflections       
4658        nrefsteps = 0
4659        surfoutsl = albedo_surf * surfins
4660        surfoutll = (1._wp - emiss_surf) * surfinl
4661        surfoutsw = surfoutsw + surfoutsl
4662        surfoutlw = surfoutlw + surfoutll
4663     ENDIF
4664
4665!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4666!--     Next passes - reflections
4667!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4668     DO refstep = 1, nrefsteps
4669
4670         surfoutsl = albedo_surf * surfins
4671!--         for non-transparent surfaces, longwave albedo is 1 - emissivity
4672         surfoutll = (1._wp - emiss_surf) * surfinl
4673
4674#if defined( __parallel )
4675         CALL MPI_AllGatherv(surfoutsl, nsurfl, MPI_REAL, &
4676             surfouts, nsurfs, surfstart, MPI_REAL, comm2d, ierr)
4677         CALL MPI_AllGatherv(surfoutll, nsurfl, MPI_REAL, &
4678             surfoutl, nsurfs, surfstart, MPI_REAL, comm2d, ierr)
4679#else
4680         surfouts = surfoutsl
4681         surfoutl = surfoutll
4682#endif
4683
4684!--         reset for next pass input
4685         surfins = 0._wp
4686         surfinl = 0._wp
4687
4688!--         reflected radiation
4689         DO isvf = 1, nsvfl
4690             isurf = svfsurf(1, isvf)
4691             isurfsrc = svfsurf(2, isvf)
4692             surfins(isurf) = surfins(isurf) + svf(1,isvf) * svf(2,isvf) * surfouts(isurfsrc)
4693             surfinl(isurf) = surfinl(isurf) + svf(1,isvf) * surfoutl(isurfsrc)
4694         ENDDO
4695
4696!--         radiation absorbed by plant canopy
4697         DO icsf = 1, ncsfl
4698             ipcgb = csfsurf(1, icsf)
4699             isurfsrc = csfsurf(2, icsf)
4700             IF ( isurfsrc == -1 )  CYCLE ! sky->face only in 1st pass, not here
4701
4702             pcbinsw(ipcgb) = pcbinsw(ipcgb) + csf(1,icsf) * csf(2,icsf) * surfouts(isurfsrc)
4703         ENDDO
4704
4705         surfinsw = surfinsw  + surfins
4706         surfinlw = surfinlw  + surfinl
4707         surfoutsw = surfoutsw + surfoutsl
4708         surfoutlw = surfoutlw + surfoutll
4709!            surfhf = surfinsw + surfinlw - surfoutsw - surfoutlw
4710
4711     ENDDO
4712
4713!--  push heat flux absorbed by plant canopy to respective 3D arrays
4714     IF ( npcbl > 0 )  THEN
4715         pc_heating_rate(:,:,:) = 0.0_wp
4716         pc_transpiration_rate(:,:,:) = 0.0_wp
4717         DO ipcgb = 1, npcbl
4718                 
4719             j = pcbl(iy, ipcgb)
4720             i = pcbl(ix, ipcgb)
4721             k = pcbl(iz, ipcgb)
4722!
4723!--             Following expression equals former kk = k - nzb_s_inner(j,i)
4724             kk = k - get_topography_top_index_ji( j, i, 's' )  !- lad arrays are defined flat
4725             pc_heating_rate(kk, j, i) = (pcbinsw(ipcgb) + pcbinlw(ipcgb)) &
4726                 * pchf_prep(k) * pt(k, j, i) !-- = dT/dt
4727
4728!             pc_transpiration_rate(kk,j,i) = 0.75_wp* (pcbinsw(ipcgb) + pcbinlw(ipcgb)) &
4729!                 * pctf_prep(k) * pt(k, j, i) !-- = dq/dt
4730
4731         ENDDO
4732     ENDIF
4733!
4734!--     Transfer radiation arrays required for energy balance to the respective data types
4735     DO  i = 1, nsurfl
4736        m  = surfl(5,i)
4737!
4738!--     (1) Urban surfaces
4739!--     upward-facing
4740        IF ( surfl(1,i) == iup_u )  THEN
4741           surf_usm_h%rad_sw_in(m)  = surfinsw(i)
4742           surf_usm_h%rad_sw_out(m) = surfoutsw(i)
4743           surf_usm_h%rad_lw_in(m)  = surfinlw(i)
4744           surf_usm_h%rad_lw_out(m) = surfoutlw(i)
4745           surf_usm_h%rad_net(m)    = surfinsw(i) - surfoutsw(i) +          &
4746                                      surfinlw(i) - surfoutlw(i)
4747!
4748!--     northward-facding
4749        ELSEIF ( surfl(1,i) == inorth_u )  THEN
4750           surf_usm_v(0)%rad_sw_in(m)  = surfinsw(i)
4751           surf_usm_v(0)%rad_sw_out(m) = surfoutsw(i)
4752           surf_usm_v(0)%rad_lw_in(m)  = surfinlw(i)
4753           surf_usm_v(0)%rad_lw_out(m) = surfoutlw(i)
4754           surf_usm_v(0)%rad_net(m)    = surfinsw(i) - surfoutsw(i) +       &
4755                                         surfinlw(i) - surfoutlw(i)
4756!
4757!--     southward-facding
4758        ELSEIF ( surfl(1,i) == isouth_u )  THEN
4759           surf_usm_v(1)%rad_sw_in(m)  = surfinsw(i)
4760           surf_usm_v(1)%rad_sw_out(m) = surfoutsw(i)
4761           surf_usm_v(1)%rad_lw_in(m)  = surfinlw(i)
4762           surf_usm_v(1)%rad_lw_out(m) = surfoutlw(i)
4763           surf_usm_v(1)%rad_net(m)    = surfinsw(i) - surfoutsw(i) +       &
4764                                         surfinlw(i) - surfoutlw(i)
4765!
4766!--     eastward-facing
4767        ELSEIF ( surfl(1,i) == ieast_u )  THEN
4768           surf_usm_v(2)%rad_sw_in(m)  = surfinsw(i)
4769           surf_usm_v(2)%rad_sw_out(m) = surfoutsw(i)
4770           surf_usm_v(2)%rad_lw_in(m)  = surfinlw(i)
4771           surf_usm_v(2)%rad_lw_out(m) = surfoutlw(i)
4772           surf_usm_v(2)%rad_net(m)    = surfinsw(i) - surfoutsw(i) +       &
4773                                         surfinlw(i) - surfoutlw(i)
4774!
4775!--     westward-facding
4776        ELSEIF ( surfl(1,i) == iwest_u )  THEN
4777           surf_usm_v(3)%rad_sw_in(m)  = surfinsw(i)
4778           surf_usm_v(3)%rad_sw_out(m) = surfoutsw(i)
4779           surf_usm_v(3)%rad_lw_in(m)  = surfinlw(i)
4780           surf_usm_v(3)%rad_lw_out(m) = surfoutlw(i)
4781           surf_usm_v(3)%rad_net(m)    = surfinsw(i) - surfoutsw(i) +       &
4782                                         surfinlw(i) - surfoutlw(i)
4783!
4784!--     (2) land surfaces
4785!--     upward-facing
4786        ELSEIF ( surfl(1,i) == iup_l )  THEN
4787           surf_lsm_h%rad_sw_in(m)  = surfinsw(i)
4788           surf_lsm_h%rad_sw_out(m) = surfoutsw(i)
4789           surf_lsm_h%rad_lw_in(m)  = surfinlw(i)
4790           surf_lsm_h%rad_lw_out(m) = surfoutlw(i)
4791           surf_lsm_h%rad_net(m)    = surfinsw(i) - surfoutsw(i) +          &
4792                                      surfinlw(i) - surfoutlw(i)
4793!
4794!--     northward-facding
4795        ELSEIF ( surfl(1,i) == inorth_l )  THEN
4796           surf_lsm_v(0)%rad_sw_in(m)  = surfinsw(i)
4797           surf_lsm_v(0)%rad_sw_out(m) = surfoutsw(i)
4798           surf_lsm_v(0)%rad_lw_in(m)  = surfinlw(i)
4799           surf_lsm_v(0)%rad_lw_out(m) = surfoutlw(i)
4800           surf_lsm_v(0)%rad_net(m)    = surfinsw(i) - surfoutsw(i) +       &
4801                                         surfinlw(i) - surfoutlw(i)
4802!
4803!--     southward-facding
4804        ELSEIF ( surfl(1,i) == isouth_l )  THEN
4805           surf_lsm_v(1)%rad_sw_in(m)  = surfinsw(i)
4806           surf_lsm_v(1)%rad_sw_out(m) = surfoutsw(i)
4807           surf_lsm_v(1)%rad_lw_in(m)  = surfinlw(i)
4808           surf_lsm_v(1)%rad_lw_out(m) = surfoutlw(i)
4809           surf_lsm_v(1)%rad_net(m)    = surfinsw(i) - surfoutsw(i) +       &
4810                                         surfinlw(i) - surfoutlw(i)
4811!
4812!--     eastward-facing
4813        ELSEIF ( surfl(1,i) == ieast_l )  THEN
4814           surf_lsm_v(2)%rad_sw_in(m)  = surfinsw(i)
4815           surf_lsm_v(2)%rad_sw_out(m) = surfoutsw(i)
4816           surf_lsm_v(2)%rad_lw_in(m)  = surfinlw(i)
4817           surf_lsm_v(2)%rad_lw_out(m) = surfoutlw(i)
4818           surf_lsm_v(2)%rad_net(m)    = surfinsw(i) - surfoutsw(i) +       &
4819                                         surfinlw(i) - surfoutlw(i)
4820!
4821!--     westward-facing
4822        ELSEIF ( surfl(1,i) == iwest_l )  THEN
4823           surf_lsm_v(3)%rad_sw_in(m)  = surfinsw(i)
4824           surf_lsm_v(3)%rad_sw_out(m) = surfoutsw(i)
4825           surf_lsm_v(3)%rad_lw_in(m)  = surfinlw(i)
4826           surf_lsm_v(3)%rad_lw_out(m) = surfoutlw(i)
4827           surf_lsm_v(3)%rad_net(m)    = surfinsw(i) - surfoutsw(i) +       &
4828                                         surfinlw(i) - surfoutlw(i)
4829        ENDIF
4830
4831     ENDDO
4832
4833     DO  m = 1, surf_usm_h%ns
4834        surf_usm_h%surfhf(m) = surf_usm_h%rad_sw_in(m)  +                   &
4835                               surf_usm_h%rad_lw_in(m)  -                   &
4836                               surf_usm_h%rad_sw_out(m) -                   &
4837                               surf_usm_h%rad_lw_out(m)
4838     ENDDO
4839     DO  m = 1, surf_lsm_h%ns
4840        surf_lsm_h%surfhf(m) = surf_lsm_h%rad_sw_in(m)  +                   &
4841                               surf_lsm_h%rad_lw_in(m)  -                   &
4842                               surf_lsm_h%rad_sw_out(m) -                   &
4843                               surf_lsm_h%rad_lw_out(m)
4844     ENDDO
4845
4846     DO  l = 0, 3
4847!--     urban
4848        DO  m = 1, surf_usm_v(l)%ns
4849           surf_usm_v(l)%surfhf(m) = surf_usm_v(l)%rad_sw_in(m)  +          &
4850                                     surf_usm_v(l)%rad_lw_in(m)  -          &
4851                                     surf_usm_v(l)%rad_sw_out(m) -          &
4852                                     surf_usm_v(l)%rad_lw_out(m)
4853        ENDDO
4854!--     land
4855        DO  m = 1, surf_lsm_v(l)%ns
4856           surf_lsm_v(l)%surfhf(m) = surf_lsm_v(l)%rad_sw_in(m)  +          &
4857                                     surf_lsm_v(l)%rad_lw_in(m)  -          &
4858                                     surf_lsm_v(l)%rad_sw_out(m) -          &
4859                                     surf_lsm_v(l)%rad_lw_out(m)
4860
4861        ENDDO
4862     ENDDO
4863!
4864!--  Calculate the average temperature, albedo, and emissivity for urban/land
4865!--  domain when using average_radiation in the respective radiation model
4866
4867!--  Precalculate face areas for all face directions using normal vector
4868     DO d = 0, nsurf_type
4869        facearea(d) = 1._wp
4870        IF ( idir(d) == 0 ) facearea(d) = facearea(d) * dx
4871        IF ( jdir(d) == 0 ) facearea(d) = facearea(d) * dy
4872        IF ( kdir(d) == 0 ) facearea(d) = facearea(d) * dz(1)
4873     ENDDO
4874!--  calculate horizontal area
4875! !!! ATTENTION!!! uniform grid is assumed here
4876     area_hor = (nx+1) * (ny+1) * dx * dy
4877!
4878!--  absorbed/received SW & LW and emitted LW energy of all physical
4879!--  surfaces (land and urban) in local processor
4880     pinswl = 0._wp
4881     pinlwl = 0._wp
4882     pabsswl = 0._wp
4883     pabslwl = 0._wp
4884     pemitlwl = 0._wp
4885     emiss_sum_surfl = 0._wp
4886     area_surfl = 0._wp
4887     DO  i = 1, nsurfl
4888        d = surfl(id, i)
4889!--  received SW & LW
4890        pinswl = pinswl + (surfinswdir(i) + surfinswdif(i)) * facearea(d)
4891        pinlwl = pinlwl + surfinlwdif(i) * facearea(d)
4892!--   absorbed SW & LW
4893        pabsswl = pabsswl + (1._wp - albedo_surf(i)) *                   &
4894                                                surfinsw(i) * facearea(d)
4895        pabslwl = pabslwl + emiss_surf(i) * surfinlw(i) * facearea(d)
4896!--   emitted LW
4897        pemitlwl = pemitlwl + surfemitlwl(i) * facearea(d)
4898!--   emissivity and area sum
4899        emiss_sum_surfl = emiss_sum_surfl + emiss_surf(i) * facearea(d)
4900        area_surfl = area_surfl + facearea(d)
4901     END DO
4902!
4903!--  add the absorbed SW energy by plant canopy
4904     IF ( npcbl > 0 )  THEN
4905        pabsswl = pabsswl + SUM(pcbinsw)
4906        pabslwl = pabslwl + SUM(pcbinlw)
4907        pinswl = pinswl + SUM(pcbinswdir) + SUM(pcbinswdif)
4908     ENDIF
4909!
4910!--  gather all rad flux energy in all processors
4911#if defined( __parallel )
4912     CALL MPI_ALLREDUCE( pinswl, pinsw, 1, MPI_REAL, MPI_SUM, comm2d, ierr)
4913     CALL MPI_ALLREDUCE( pinlwl, pinlw, 1, MPI_REAL, MPI_SUM, comm2d, ierr)
4914     CALL MPI_ALLREDUCE( pabsswl, pabssw, 1, MPI_REAL, MPI_SUM, comm2d, ierr )
4915     CALL MPI_ALLREDUCE( pabslwl, pabslw, 1, MPI_REAL, MPI_SUM, comm2d, ierr )
4916     CALL MPI_ALLREDUCE( pemitlwl, pemitlw, 1, MPI_REAL, MPI_SUM, comm2d, ierr )
4917     CALL MPI_ALLREDUCE( emiss_sum_surfl, emiss_sum_surf, 1, MPI_REAL, MPI_SUM, comm2d, ierr )
4918     CALL MPI_ALLREDUCE( area_surfl, area_surf, 1, MPI_REAL, MPI_SUM, comm2d, ierr )
4919#else
4920     pinsw = pinswl
4921     pinlw = pinlwl
4922     pabssw = pabsswl
4923     pabslw = pabslwl
4924     pemitlw = pemitlwl
4925     emiss_sum_surf = emiss_sum_surfl
4926     area_surf = area_surfl
4927#endif
4928
4929!--  (1) albedo
4930     IF ( pinsw /= 0.0_wp )  &
4931          albedo_urb = (pinsw - pabssw) / pinsw
4932!--  (2) average emmsivity
4933     IF ( area_surf /= 0.0_wp ) &
4934          emissivity_urb = emiss_sum_surf / area_surf
4935!--  (3) temperature
4936     t_rad_urb = ( (pemitlw - pabslw + emissivity_urb*pinlw) / &
4937          (emissivity_urb*sigma_sb * area_hor) )**0.25_wp
4938     
4939    CONTAINS
4940
4941!------------------------------------------------------------------------------!
4942!> Calculates radiation absorbed by box with given size and LAD.
4943!>
4944!> Simulates resol**2 rays (by equally spacing a bounding horizontal square
4945!> conatining all possible rays that would cross the box) and calculates
4946!> average transparency per ray. Returns fraction of absorbed radiation flux
4947!> and area for which this fraction is effective.
4948!------------------------------------------------------------------------------!
4949    PURE SUBROUTINE box_absorb(boxsize, resol, dens, uvec, area, absorb)
4950       IMPLICIT NONE
4951
4952       REAL(wp), DIMENSION(3), INTENT(in) :: &
4953            boxsize, &      !< z, y, x size of box in m
4954            uvec            !< z, y, x unit vector of incoming flux
4955       INTEGER(iwp), INTENT(in) :: &
4956            resol           !< No. of rays in x and y dimensions
4957       REAL(wp), INTENT(in) :: &
4958            dens            !< box density (e.g. Leaf Area Density)
4959       REAL(wp), INTENT(out) :: &
4960            area, &         !< horizontal area for flux absorbtion
4961            absorb          !< fraction of absorbed flux
4962       REAL(wp) :: &
4963            xshift, yshift, &
4964            xmin, xmax, ymin, ymax, &
4965            xorig, yorig, &
4966            dx1, dy1, dz1, dx2, dy2, dz2, &
4967            crdist, &
4968            transp
4969       INTEGER(iwp) :: &
4970            i, j
4971
4972       xshift = uvec(3) / uvec(1) * boxsize(1)
4973       xmin = min(0._wp, -xshift)
4974       xmax = boxsize(3) + max(0._wp, -xshift)
4975       yshift = uvec(2) / uvec(1) * boxsize(1)
4976       ymin = min(0._wp, -yshift)
4977       ymax = boxsize(2) + max(0._wp, -yshift)
4978
4979       transp = 0._wp
4980       DO i = 1, resol
4981          xorig = xmin + (xmax-xmin) * (i-.5_wp) / resol
4982          DO j = 1, resol
4983             yorig = ymin + (ymax-ymin) * (j-.5_wp) / resol
4984
4985             dz1 = 0._wp
4986             dz2 = boxsize(1)/uvec(1)
4987
4988             IF ( uvec(2) > 0._wp )  THEN
4989                dy1 = -yorig             / uvec(2) !< crossing with y=0
4990                dy2 = (boxsize(2)-yorig) / uvec(2) !< crossing with y=boxsize(2)
4991             ELSE !uvec(2)==0
4992                dy1 = -huge(1._wp)
4993                dy2 = huge(1._wp)
4994             ENDIF
4995
4996             IF ( uvec(3) > 0._wp )  THEN
4997                dx1 = -xorig             / uvec(3) !< crossing with x=0
4998                dx2 = (boxsize(3)-xorig) / uvec(3) !< crossing with x=boxsize(3)
4999             ELSE !uvec(3)==0
5000                dx1 = -huge(1._wp)
5001                dx2 = huge(1._wp)
5002             ENDIF
5003
5004             crdist = max(0._wp, (min(dz2, dy2, dx2) - max(dz1, dy1, dx1)))
5005             transp = transp + exp(-ext_coef * dens * crdist)
5006          ENDDO
5007       ENDDO
5008       transp = transp / resol**2
5009       area = (boxsize(3)+xshift)*(boxsize(2)+yshift)
5010       absorb = 1._wp - transp
5011
5012    END SUBROUTINE box_absorb
5013
5014!------------------------------------------------------------------------------!
5015! Description:
5016! ------------
5017!> This subroutine splits direct and diffusion dw radiation
5018!> It sould not be called in case the radiation model already does it
5019!> It follows <CITATION>
5020!------------------------------------------------------------------------------!
5021    SUBROUTINE calc_diffusion_radiation 
5022   
5023        REAL(wp), PARAMETER                          :: lowest_solarUp = 0.1_wp  !< limit the sun elevation to protect stability of the calculation
5024        INTEGER(iwp)                                 :: i, j
5025        REAL(wp)                                     ::  year_angle              !< angle
5026        REAL(wp)                                     ::  etr                     !< extraterestrial radiation
5027        REAL(wp)                                     ::  corrected_solarUp       !< corrected solar up radiation
5028        REAL(wp)                                     ::  horizontalETR           !< horizontal extraterestrial radiation
5029        REAL(wp)                                     ::  clearnessIndex          !< clearness index
5030        REAL(wp)                                     ::  diff_frac               !< diffusion fraction of the radiation
5031
5032       
5033!--     Calculate current day and time based on the initial values and simulation time
5034        year_angle = ( (day_of_year_init * 86400) + time_utc_init              &
5035                        + time_since_reference_point )  * d_seconds_year       &
5036                        * 2.0_wp * pi
5037       
5038        etr = solar_constant * (1.00011_wp +                                   &
5039                          0.034221_wp * cos(year_angle) +                      &
5040                          0.001280_wp * sin(year_angle) +                      &
5041                          0.000719_wp * cos(2.0_wp * year_angle) +             &
5042                          0.000077_wp * sin(2.0_wp * year_angle))
5043       
5044!--   
5045!--     Under a very low angle, we keep extraterestrial radiation at
5046!--     the last small value, therefore the clearness index will be pushed
5047!--     towards 0 while keeping full continuity.
5048!--   
5049        IF ( zenith(0) <= lowest_solarUp )  THEN
5050            corrected_solarUp = lowest_solarUp
5051        ELSE
5052            corrected_solarUp = zenith(0)
5053        ENDIF
5054       
5055        horizontalETR = etr * corrected_solarUp
5056       
5057        DO i = nxl, nxr
5058            DO j = nys, nyn
5059                clearnessIndex = rad_sw_in(0,j,i) / horizontalETR
5060                diff_frac = 1.0_wp / (1.0_wp + exp(-5.0033_wp + 8.6025_wp * clearnessIndex))
5061                rad_sw_in_diff(j,i) = rad_sw_in(0,j,i) * diff_frac
5062                rad_sw_in_dir(j,i)  = rad_sw_in(0,j,i) * (1.0_wp - diff_frac)
5063                rad_lw_in_diff(j,i) = rad_lw_in(0,j,i)
5064            ENDDO
5065        ENDDO
5066       
5067    END SUBROUTINE calc_diffusion_radiation
5068
5069
5070 END SUBROUTINE radiation_interaction
5071   
5072!------------------------------------------------------------------------------!
5073! Description:
5074! ------------
5075!> This subroutine initializes structures needed for radiative transfer
5076!> model. This model calculates transformation processes of the
5077!> radiation inside urban and land canopy layer. The module includes also
5078!> the interaction of the radiation with the resolved plant canopy.
5079!>
5080!> For more info. see Resler et al. 2017
5081!>
5082!> The new version 2.0 was radically rewriten, the discretization scheme
5083!> has been changed. This new version significantly improves effectivity
5084!> of the paralelization and the scalability of the model.
5085!>
5086!------------------------------------------------------------------------------!
5087    SUBROUTINE radiation_interaction_init
5088
5089       USE control_parameters,                                                 &
5090           ONLY:  dz_stretch_level_start
5091           
5092       USE netcdf_data_input_mod,                                              &
5093           ONLY:  leaf_area_density_f
5094
5095       USE plant_canopy_model_mod,                                             &
5096           ONLY:  pch_index, pc_heating_rate, lad_s
5097
5098       IMPLICIT NONE
5099
5100       INTEGER(iwp) :: i, j, k, d, l, ir, jr, ids, m
5101       INTEGER(iwp) :: k_topo     !< vertical index indicating topography top for given (j,i)
5102       INTEGER(iwp) :: k_topo2    !< vertical index indicating topography top for given (j,i)
5103       INTEGER(iwp) :: nzptl, nzubl, nzutl, isurf, ipcgb
5104       INTEGER(iwp) :: procid
5105       REAL(wp)     :: mrl
5106
5107
5108       !INTEGER(iwp), DIMENSION(1:4,inorth_b:iwest_b)  ::  ijdb                               !< start and end of the local domain border coordinates (set in code)
5109       !LOGICAL, DIMENSION(inorth_b:iwest_b)           ::  isborder                           !< is PE on the border of the domain in four corresponding directions
5110
5111!
5112!--    Find nzub, nzut, nzu via wall_flag_0 array (nzb_s_inner will be
5113!--    removed later). The following contruct finds the lowest / largest index
5114!--    for any upward-facing wall (see bit 12).
5115       nzubl = MINVAL( get_topography_top_index( 's' ) )
5116       nzutl = MAXVAL( get_topography_top_index( 's' ) )
5117
5118       nzubl = MAX( nzubl, nzb )
5119
5120       IF ( plant_canopy )  THEN
5121!--        allocate needed arrays
5122           ALLOCATE( pct(nys:nyn,nxl:nxr) )
5123           ALLOCATE( pch(nys:nyn,nxl:nxr) )
5124
5125!--        calculate plant canopy height
5126           npcbl = 0
5127           pct   = 0
5128           pch   = 0
5129           DO i = nxl, nxr
5130               DO j = nys, nyn
5131!
5132!--                Find topography top index
5133                   k_topo = get_topography_top_index_ji( j, i, 's' )
5134
5135                   DO k = nzt+1, 0, -1
5136                       IF ( lad_s(k,j,i) /= 0.0_wp )  THEN
5137!--                        we are at the top of the pcs
5138                           pct(j,i) = k + k_topo
5139                           pch(j,i) = k
5140                           npcbl = npcbl + pch(j,i)
5141                           EXIT
5142                       ENDIF
5143                   ENDDO
5144               ENDDO
5145           ENDDO
5146
5147           nzutl = MAX( nzutl, MAXVAL( pct ) )
5148           nzptl = MAXVAL( pct )
5149!--        code of plant canopy model uses parameter pch_index
5150!--        we need to setup it here to right value
5151!--        (pch_index, lad_s and other arrays in PCM are defined flat)
5152           pch_index = MERGE( leaf_area_density_f%nz - 1, MAXVAL( pch ),       &
5153                              leaf_area_density_f%from_file )
5154
5155           prototype_lad = MAXVAL( lad_s ) * .9_wp  !< better be *1.0 if lad is either 0 or maxval(lad) everywhere
5156           IF ( prototype_lad <= 0._wp ) prototype_lad = .3_wp
5157           !WRITE(message_string, '(a,f6.3)') 'Precomputing effective box optical ' &
5158           !    // 'depth using prototype leaf area density = ', prototype_lad
5159           !CALL message('usm_init_urban_surface', 'PA0520', 0, 0, -1, 6, 0)
5160       ENDIF
5161
5162       nzutl = MIN( nzutl + nzut_free, nzt )
5163
5164#if defined( __parallel )
5165       CALL MPI_AllReduce(nzubl, nzub, 1, MPI_INTEGER, MPI_MIN, comm2d, ierr )
5166       CALL MPI_AllReduce(nzutl, nzut, 1, MPI_INTEGER, MPI_MAX, comm2d, ierr )
5167       CALL MPI_AllReduce(nzptl, nzpt, 1, MPI_INTEGER, MPI_MAX, comm2d, ierr )
5168#else
5169       nzub = nzubl
5170       nzut = nzutl
5171       nzpt = nzptl
5172#endif
5173!
5174!--    Stretching (non-uniform grid spacing) is not considered in the radiation
5175!--    model. Therefore, vertical stretching has to be applied above the area
5176!--    where the parts of the radiation model which assume constant grid spacing
5177!--    are active. ABS (...) is required because the default value of
5178!--    dz_stretch_level_start is -9999999.9_wp (negative).
5179       IF ( ABS( dz_stretch_level_start(1) ) <= zw(nzut) ) THEN
5180          WRITE( message_string, * ) 'The lowest level where vertical ',       &
5181                                     'stretching is applied have to be ',      &
5182                                     'greater than ', zw(nzut)
5183          CALL message( 'radiation_interaction_init', 'PA0496', 1, 2, 0, 6, 0 )
5184       ENDIF 
5185!
5186!--    global number of urban and plant layers
5187       nzu = nzut - nzub + 1
5188       nzp = nzpt - nzub + 1
5189!
5190!--    check max_raytracing_dist relative to urban surface layer height
5191       mrl = 2.0_wp * nzu * dz(1)
5192       IF ( max_raytracing_dist == -999.0_wp ) THEN
5193          max_raytracing_dist = mrl
5194       ENDIF
5195!        IF ( max_raytracing_dist <= mrl ) THEN
5196!           IF ( max_raytracing_dist /= -999.0_wp ) THEN
5197! !--          max_raytracing_dist too low
5198!              WRITE(message_string, '(a,f6.1)') 'Max_raytracing_dist too low, ' &
5199!                    // 'override to value ', mrl
5200!              CALL message('radiation_interaction_init', 'PA0521', 0, 0, -1, 6, 0)
5201!           ENDIF
5202!           max_raytracing_dist = mrl
5203!        ENDIF
5204!
5205!--    allocate urban surfaces grid
5206!--    calc number of surfaces in local proc
5207       CALL location_message( '    calculation of indices for surfaces', .TRUE. )
5208       nsurfl = 0
5209!
5210!--    Number of horizontal surfaces including land- and roof surfaces in both USM and LSM. Note that
5211!--    All horizontal surface elements are already counted in surface_mod.
5212       startland = 1
5213       nsurfl    = surf_usm_h%ns + surf_lsm_h%ns
5214       endland   = nsurfl
5215       nlands    = endland - startland + 1
5216
5217!
5218!--    Number of vertical surfaces in both USM and LSM. Note that all vertical surface elements are
5219!--    already counted in surface_mod.
5220       startwall = nsurfl+1
5221       DO  i = 0,3
5222          nsurfl = nsurfl + surf_usm_v(i)%ns + surf_lsm_v(i)%ns
5223       ENDDO
5224       endwall = nsurfl
5225       nwalls  = endwall - startwall + 1
5226
5227!--    fill gridpcbl and pcbl
5228       IF ( npcbl > 0 )  THEN
5229           ALLOCATE( pcbl(iz:ix, 1:npcbl) )
5230           ALLOCATE( gridpcbl(nzub:nzpt,nys:nyn,nxl:nxr) )
5231           pcbl = -1
5232           gridpcbl(:,:,:) = 0
5233           ipcgb = 0
5234           DO i = nxl, nxr
5235               DO j = nys, nyn
5236!
5237!--                Find topography top index
5238                   k_topo = get_topography_top_index_ji( j, i, 's' )
5239
5240                   DO k = k_topo + 1, pct(j,i)
5241                       ipcgb = ipcgb + 1
5242                       gridpcbl(k,j,i) = ipcgb
5243                       pcbl(:,ipcgb) = (/ k, j, i /)
5244                   ENDDO
5245               ENDDO
5246           ENDDO
5247           ALLOCATE( pcbinsw( 1:npcbl ) )
5248           ALLOCATE( pcbinswdir( 1:npcbl ) )
5249           ALLOCATE( pcbinswdif( 1:npcbl ) )
5250           ALLOCATE( pcbinlw( 1:npcbl ) )
5251       ENDIF
5252
5253!--    fill surfl (the ordering of local surfaces given by the following
5254!--    cycles must not be altered, certain file input routines may depend
5255!--    on it)
5256       ALLOCATE(surfl(5,nsurfl))  ! is it mecessary to allocate it with (5,nsurfl)?
5257       isurf = 0
5258
5259!--    add horizontal surface elements (land and urban surfaces)
5260!--    TODO: add urban overhanging surfaces (idown_u)
5261       DO i = nxl, nxr
5262           DO j = nys, nyn
5263              DO  m = surf_usm_h%start_index(j,i), surf_usm_h%end_index(j,i)
5264                 k = surf_usm_h%k(m)
5265
5266                 isurf = isurf + 1
5267                 surfl(:,isurf) = (/iup_u,k,j,i,m/)
5268              ENDDO
5269
5270              DO  m = surf_lsm_h%start_index(j,i), surf_lsm_h%end_index(j,i)
5271                 k = surf_lsm_h%k(m)
5272
5273                 isurf = isurf + 1
5274                 surfl(:,isurf) = (/iup_l,k,j,i,m/)
5275              ENDDO
5276
5277           ENDDO
5278       ENDDO
5279
5280!--    add vertical surface elements (land and urban surfaces)
5281!--    TODO: remove the hard coding of l = 0 to l = idirection
5282       DO i = nxl, nxr
5283           DO j = nys, nyn
5284              l = 0
5285              DO  m = surf_usm_v(l)%start_index(j,i), surf_usm_v(l)%end_index(j,i)
5286                 k = surf_usm_v(l)%k(m)
5287
5288                 isurf          = isurf + 1
5289                 surfl(:,isurf) = (/inorth_u,k,j,i,m/)
5290              ENDDO
5291              DO  m = surf_lsm_v(l)%start_index(j,i), surf_lsm_v(l)%end_index(j,i)
5292                 k = surf_lsm_v(l)%k(m)
5293
5294                 isurf          = isurf + 1
5295                 surfl(:,isurf) = (/inorth_l,k,j,i,m/)
5296              ENDDO
5297
5298              l = 1
5299              DO  m = surf_usm_v(l)%start_index(j,i), surf_usm_v(l)%end_index(j,i)
5300                 k = surf_usm_v(l)%k(m)
5301
5302                 isurf          = isurf + 1
5303                 surfl(:,isurf) = (/isouth_u,k,j,i,m/)
5304              ENDDO
5305              DO  m = surf_lsm_v(l)%start_index(j,i), surf_lsm_v(l)%end_index(j,i)
5306                 k = surf_lsm_v(l)%k(m)
5307
5308                 isurf          = isurf + 1
5309                 surfl(:,isurf) = (/isouth_l,k,j,i,m/)
5310              ENDDO
5311
5312              l = 2
5313              DO  m = surf_usm_v(l)%start_index(j,i), surf_usm_v(l)%end_index(j,i)
5314                 k = surf_usm_v(l)%k(m)
5315
5316                 isurf          = isurf + 1
5317                 surfl(:,isurf) = (/ieast_u,k,j,i,m/)
5318              ENDDO
5319              DO  m = surf_lsm_v(l)%start_index(j,i), surf_lsm_v(l)%end_index(j,i)
5320                 k = surf_lsm_v(l)%k(m)
5321
5322                 isurf          = isurf + 1
5323                 surfl(:,isurf) = (/ieast_l,k,j,i,m/)
5324              ENDDO
5325
5326              l = 3
5327              DO  m = surf_usm_v(l)%start_index(j,i), surf_usm_v(l)%end_index(j,i)
5328                 k = surf_usm_v(l)%k(m)
5329
5330                 isurf          = isurf + 1
5331                 surfl(:,isurf) = (/iwest_u,k,j,i,m/)
5332              ENDDO
5333              DO  m = surf_lsm_v(l)%start_index(j,i), surf_lsm_v(l)%end_index(j,i)
5334                 k = surf_lsm_v(l)%k(m)
5335
5336                 isurf          = isurf + 1
5337                 surfl(:,isurf) = (/iwest_l,k,j,i,m/)
5338              ENDDO
5339           ENDDO
5340       ENDDO
5341
5342!
5343!--    broadband albedo of the land, roof and wall surface
5344!--    for domain border and sky set artifically to 1.0
5345!--    what allows us to calculate heat flux leaving over
5346!--    side and top borders of the domain
5347       ALLOCATE ( albedo_surf(nsurfl) )
5348       albedo_surf = 1.0_wp
5349!
5350!--    Also allocate further array for emissivity with identical order of
5351!--    surface elements as radiation arrays.
5352       ALLOCATE ( emiss_surf(nsurfl)  )
5353
5354
5355!
5356!--    global array surf of indices of surfaces and displacement index array surfstart
5357       ALLOCATE(nsurfs(0:numprocs-1))
5358
5359#if defined( __parallel )
5360       CALL MPI_Allgather(nsurfl,1,MPI_INTEGER,nsurfs,1,MPI_INTEGER,comm2d,ierr)
5361#else
5362       nsurfs(0) = nsurfl
5363#endif
5364       ALLOCATE(surfstart(0:numprocs))
5365       k = 0
5366       DO i=0,numprocs-1
5367           surfstart(i) = k
5368           k = k+nsurfs(i)
5369       ENDDO
5370       surfstart(numprocs) = k
5371       nsurf = k
5372       ALLOCATE(surf(5,nsurf))
5373
5374#if defined( __parallel )
5375       CALL MPI_AllGatherv(surfl, nsurfl*5, MPI_INTEGER, surf, nsurfs*5, &
5376           surfstart(0:numprocs-1)*5, MPI_INTEGER, comm2d, ierr)
5377#else
5378       surf = surfl
5379#endif
5380
5381!--
5382!--    allocation of the arrays for direct and diffusion radiation
5383       CALL location_message( '    allocation of radiation arrays', .TRUE. )
5384!--    rad_sw_in, rad_lw_in are computed in radiation model,
5385!--    splitting of direct and diffusion part is done
5386!--    in calc_diffusion_radiation for now
5387
5388       ALLOCATE( rad_sw_in_dir(nysg:nyng,nxlg:nxrg) )
5389       ALLOCATE( rad_sw_in_diff(nysg:nyng,nxlg:nxrg) )
5390       ALLOCATE( rad_lw_in_diff(nysg:nyng,nxlg:nxrg) )
5391       rad_sw_in_dir  = 0.0_wp
5392       rad_sw_in_diff = 0.0_wp
5393       rad_lw_in_diff = 0.0_wp
5394
5395!--    allocate radiation arrays
5396       ALLOCATE( surfins(nsurfl) )
5397       ALLOCATE( surfinl(nsurfl) )
5398       ALLOCATE( surfinsw(nsurfl) )
5399       ALLOCATE( surfinlw(nsurfl) )
5400       ALLOCATE( surfinswdir(nsurfl) )
5401       ALLOCATE( surfinswdif(nsurfl) )
5402       ALLOCATE( surfinlwdif(nsurfl) )
5403       ALLOCATE( surfoutsl(nsurfl) )
5404       ALLOCATE( surfoutll(nsurfl) )
5405       ALLOCATE( surfoutsw(nsurfl) )
5406       ALLOCATE( surfoutlw(nsurfl) )
5407       ALLOCATE( surfouts(nsurf) )
5408       ALLOCATE( surfoutl(nsurf) )
5409       ALLOCATE( skyvf(nsurfl) )
5410       ALLOCATE( skyvft(nsurfl) )
5411       ALLOCATE( surfemitlwl(nsurfl) )
5412
5413!
5414!--    In case of average_radiation, aggregated surface albedo and emissivity,
5415!--    also set initial value for t_rad_urb.
5416!--    For now set an arbitrary initial value.
5417       IF ( average_radiation )  THEN
5418          albedo_urb = 0.1_wp
5419          emissivity_urb = 0.9_wp
5420          t_rad_urb = pt_surface
5421       ENDIF
5422
5423    END SUBROUTINE radiation_interaction_init
5424
5425!------------------------------------------------------------------------------!
5426! Description:
5427! ------------
5428!> Calculates shape view factors (SVF), plant sink canopy factors (PCSF),
5429!> sky-view factors, discretized path for direct solar radiation, MRT factors
5430!> and other preprocessed data needed for radiation_interaction.
5431!------------------------------------------------------------------------------!
5432    SUBROUTINE radiation_calc_svf
5433   
5434        IMPLICIT NONE
5435       
5436        INTEGER(iwp)                                  :: i, j, k, l, d, ip, jp
5437        INTEGER(iwp)                                  :: isvf, ksvf, icsf, kcsf, npcsfl, isvf_surflt, imrtt, imrtf, ipcgb
5438        INTEGER(iwp)                                  :: sd, td, ioln, iproc
5439        INTEGER(iwp)                                  :: iaz, izn      !< azimuth, zenith counters
5440        INTEGER(iwp)                                  :: naz, nzn      !< azimuth, zenith num of steps
5441        REAL(wp)                                      :: az0, zn0      !< starting azimuth/zenith
5442        REAL(wp)                                      :: azs, zns      !< azimuth/zenith cycle step
5443        REAL(wp)                                      :: az1, az2      !< relative azimuth of section borders
5444        REAL(wp)                                      :: azmid         !< ray (center) azimuth
5445        REAL(wp)                                      :: horizon       !< computed horizon height (tangent of elevation)
5446        REAL(wp)                                      :: azen          !< zenith angle
5447        REAL(wp), DIMENSION(:), ALLOCATABLE           :: zdirs         !< directions in z (tangent of elevation)
5448        REAL(wp), DIMENSION(:), ALLOCATABLE           :: zbdry         !< zenith angle boundaries
5449        REAL(wp), DIMENSION(:), ALLOCATABLE           :: vffrac        !< view factor fractions for individual rays
5450        REAL(wp), DIMENSION(:), ALLOCATABLE           :: ztransp       !< array of transparency in z steps
5451        REAL(wp),     DIMENSION(0:nsurf_type)         :: facearea
5452        INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE     :: nzterrl
5453        REAL(wp),     DIMENSION(:,:), ALLOCATABLE     :: csflt, pcsflt
5454        INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE     :: kcsflt,kpcsflt
5455        INTEGER(iwp), DIMENSION(:), ALLOCATABLE       :: icsflt,dcsflt,ipcsflt,dpcsflt
5456        REAL(wp), DIMENSION(3)                        :: uv
5457        LOGICAL                                       :: visible
5458        REAL(wp), DIMENSION(3)                        :: sa, ta          !< real coordinates z,y,x of source and target
5459        REAL(wp)                                      :: transparency, rirrf, sqdist, svfsum
5460        INTEGER(iwp)                                  :: isurflt, isurfs, isurflt_prev
5461        INTEGER(iwp)                                  :: itx, ity, itz
5462        INTEGER(idp)                                  :: ray_skip_maxdist, ray_skip_minval !< skipped raytracing counts
5463        INTEGER(iwp)                                  :: max_track_len !< maximum 2d track length
5464        CHARACTER(len=7)                              :: pid_char = ''
5465        INTEGER(iwp)                                  :: win_lad, minfo
5466        REAL(wp), DIMENSION(:,:,:), POINTER           :: lad_s_rma       !< fortran pointer, but lower bounds are 1
5467        TYPE(c_ptr)                                   :: lad_s_rma_p     !< allocated c pointer
5468#if defined( __parallel )
5469        INTEGER(kind=MPI_ADDRESS_KIND)                :: size_lad_rma
5470#endif
5471!   
5472        INTEGER(iwp), DIMENSION(0:svfnorm_report_num) :: svfnorm_counts
5473        CHARACTER(200)                                :: msg
5474
5475!--     calculation of the SVF
5476        CALL location_message( '    calculation of SVF and CSF', .TRUE. )
5477!         CALL radiation_write_debug_log('Start calculation of SVF and CSF')
5478
5479!--     precalculate face areas for different face directions using normal vector
5480        DO d = 0, nsurf_type
5481            facearea(d) = 1._wp
5482            IF ( idir(d) == 0 ) facearea(d) = facearea(d) * dx
5483            IF ( jdir(d) == 0 ) facearea(d) = facearea(d) * dy
5484            IF ( kdir(d) == 0 ) facearea(d) = facearea(d) * dz(1)
5485        ENDDO
5486
5487!--     initialize variables and temporary arrays for calculation of svf and csf
5488        nsvfl  = 0
5489        ncsfl  = 0
5490        nsvfla = gasize
5491        msvf   = 1
5492        ALLOCATE( asvf1(nsvfla) )
5493        asvf => asvf1
5494        IF ( plant_canopy )  THEN
5495            ncsfla = gasize
5496            mcsf   = 1
5497            ALLOCATE( acsf1(ncsfla) )
5498            acsf => acsf1
5499        ENDIF
5500        ray_skip_maxdist = 0
5501        ray_skip_minval = 0
5502       
5503!--     initialize temporary terrain and plant canopy height arrays (global 2D array!)
5504        ALLOCATE( nzterr(0:(nx+1)*(ny+1)-1) )
5505#if defined( __parallel )
5506        ALLOCATE( nzterrl(nys:nyn,nxl:nxr) )
5507        nzterrl = get_topography_top_index( 's' )
5508        CALL MPI_AllGather( nzterrl, nnx*nny, MPI_INTEGER, &
5509                            nzterr, nnx*nny, MPI_INTEGER, comm2d, ierr )
5510        DEALLOCATE(nzterrl)
5511#else
5512        nzterr = RESHAPE( get_topography_top_index( 's' ), (/(nx+1)*(ny+1)/) )
5513#endif
5514        IF ( plant_canopy )  THEN
5515            ALLOCATE( plantt(0:(nx+1)*(ny+1)-1) )
5516            maxboxesg = nx + ny + nzp + 1
5517            max_track_len = nx + ny + 1
5518!--         temporary arrays storing values for csf calculation during raytracing
5519            ALLOCATE( boxes(3, maxboxesg) )
5520            ALLOCATE( crlens(maxboxesg) )
5521
5522#if defined( __parallel )
5523            CALL MPI_AllGather( pct, nnx*nny, MPI_INTEGER, &
5524                                plantt, nnx*nny, MPI_INTEGER, comm2d, ierr )
5525           
5526!--         temporary arrays storing values for csf calculation during raytracing
5527            ALLOCATE( lad_ip(maxboxesg) )
5528            ALLOCATE( lad_disp(maxboxesg) )
5529
5530            IF ( rma_lad_raytrace )  THEN
5531                ALLOCATE( lad_s_ray(maxboxesg) )
5532               
5533                ! set conditions for RMA communication
5534                CALL MPI_Info_create(minfo, ierr)
5535                CALL MPI_Info_set(minfo, 'accumulate_ordering', '', ierr)
5536                CALL MPI_Info_set(minfo, 'accumulate_ops', 'same_op', ierr)
5537                CALL MPI_Info_set(minfo, 'same_size', 'true', ierr)
5538                CALL MPI_Info_set(minfo, 'same_disp_unit', 'true', ierr)
5539
5540!--             Allocate and initialize the MPI RMA window
5541!--             must be in accordance with allocation of lad_s in plant_canopy_model
5542!--             optimization of memory should be done
5543!--             Argument X of function STORAGE_SIZE(X) needs arbitrary REAL(wp) value, set to 1.0_wp for now
5544                size_lad_rma = STORAGE_SIZE(1.0_wp)/8*nnx*nny*nzp
5545                CALL MPI_Win_allocate(size_lad_rma, STORAGE_SIZE(1.0_wp)/8, minfo, comm2d, &
5546                                        lad_s_rma_p, win_lad, ierr)
5547                CALL c_f_pointer(lad_s_rma_p, lad_s_rma, (/ nzp, nny, nnx /))
5548                sub_lad(nzub:, nys:, nxl:) => lad_s_rma(:,:,:)
5549            ELSE
5550                ALLOCATE(sub_lad(nzub:nzpt, nys:nyn, nxl:nxr))
5551            ENDIF
5552#else
5553            plantt = RESHAPE( pct(nys:nyn,nxl:nxr), (/(nx+1)*(ny+1)/) )
5554            ALLOCATE(sub_lad(nzub:nzpt, nys:nyn, nxl:nxr))
5555#endif
5556            plantt_max = MAXVAL(plantt)
5557            ALLOCATE( rt2_track(2, max_track_len), rt2_track_lad(nzub:plantt_max, max_track_len), &
5558                      rt2_track_dist(0:max_track_len), rt2_dist(plantt_max-nzub+2) )
5559
5560            sub_lad(:,:,:) = 0._wp
5561            DO i = nxl, nxr
5562                DO j = nys, nyn
5563                    k = get_topography_top_index_ji( j, i, 's' )
5564
5565                    sub_lad(k:nzpt, j, i) = lad_s(0:nzpt-k, j, i)
5566                ENDDO
5567            ENDDO
5568
5569#if defined( __parallel )
5570            IF ( rma_lad_raytrace )  THEN
5571                CALL MPI_Info_free(minfo, ierr)
5572                CALL MPI_Win_lock_all(0, win_lad, ierr)
5573            ELSE
5574                ALLOCATE( sub_lad_g(0:(nx+1)*(ny+1)*nzp-1) )
5575                CALL MPI_AllGather( sub_lad, nnx*nny*nzp, MPI_REAL, &
5576                                    sub_lad_g, nnx*nny*nzp, MPI_REAL, comm2d, ierr )
5577            ENDIF
5578#endif
5579        ENDIF
5580
5581        IF ( mrt_factors )  THEN
5582            OPEN(153, file='MRT_TARGETS', access='SEQUENTIAL', &
5583                    action='READ', status='OLD', form='FORMATTED', err=524)
5584            OPEN(154, file='MRT_FACTORS'//myid_char, access='DIRECT', recl=(5*4+2*8), &
5585                    action='WRITE', status='REPLACE', form='UNFORMATTED', err=525)
5586            imrtf = 1
5587            DO
5588                READ(153, *, end=526, err=524) imrtt, i, j, k
5589                IF ( i < nxl  .OR.  i > nxr &
5590                     .OR.  j < nys  .OR.  j > nyn ) CYCLE
5591                ta = (/ REAL(k), REAL(j), REAL(i) /)
5592
5593                DO isurfs = 1, nsurf
5594                    IF ( .NOT.  surface_facing(i, j, k, -1, &
5595                        surf(ix, isurfs), surf(iy, isurfs), &
5596                        surf(iz, isurfs), surf(id, isurfs)) )  THEN
5597                        CYCLE
5598                    ENDIF
5599                     
5600                    sd = surf(id, isurfs)
5601                    sa = (/ REAL(surf(iz, isurfs), wp) - 0.5_wp * kdir(sd), &
5602                            REAL(surf(iy, isurfs), wp) - 0.5_wp * jdir(sd), &
5603                            REAL(surf(ix, isurfs), wp) - 0.5_wp * idir(sd) /)
5604
5605!--                 unit vector source -> target
5606                    uv = (/ (ta(1)-sa(1))*dz(1), (ta(2)-sa(2))*dy, (ta(3)-sa(3))*dx /)
5607                    sqdist = SUM(uv(:)**2)
5608                    uv = uv / SQRT(sqdist)
5609
5610!--                 irradiance factor - see svf. Here we consider that target face is always normal,
5611!--                 i.e. the second dot product equals 1
5612                    rirrf = dot_product((/ kdir(sd), jdir(sd), idir(sd) /), uv) &
5613                        / (pi * sqdist) * facearea(sd)
5614
5615!--                 raytrace while not creating any canopy sink factors
5616                    CALL raytrace(sa, ta, isurfs, rirrf, 1._wp, .FALSE., &
5617                            visible, transparency, win_lad)
5618                    IF ( .NOT.  visible ) CYCLE
5619
5620                    !rsvf = rirrf * transparency
5621                    WRITE(154, rec=imrtf, err=525) INT(imrtt, kind=4), &
5622                        INT(surf(id, isurfs), kind=4), &
5623                        INT(surf(iz, isurfs), kind=4), &
5624                        INT(surf(iy, isurfs), kind=4), &
5625                        INT(surf(ix, isurfs), kind=4), &
5626                        REAL(rirrf, kind=8), REAL(transparency, kind=8)
5627                    imrtf = imrtf + 1
5628
5629                ENDDO !< isurfs
5630            ENDDO !< MRT_TARGETS record
5631
5632524         message_string = 'error reading file MRT_TARGETS'
5633            CALL message( 'radiation_calc_svf', 'PA0524', 1, 2, 0, 6, 0 )
5634
5635525         message_string = 'error writing file MRT_FACTORS'//myid_char
5636            CALL message( 'radiation_calc_svf', 'PA0525', 1, 2, 0, 6, 0 )
5637
5638526         CLOSE(153)
5639            CLOSE(154)
5640        ENDIF  !< mrt_factors
5641       
5642        !--Directions opposite to face normals are not even calculated,
5643        !--they must be preset to 0
5644        !--
5645        dsitrans(:,:) = 0._wp
5646       
5647        DO isurflt = 1, nsurfl
5648!--         determine face centers
5649            td = surfl(id, isurflt)
5650            ta = (/ REAL(surfl(iz, isurflt), wp) - 0.5_wp * kdir(td),  &
5651                      REAL(surfl(iy, isurflt), wp) - 0.5_wp * jdir(td),  &
5652                      REAL(surfl(ix, isurflt), wp) - 0.5_wp * idir(td)  /)
5653
5654            !--Calculate sky view factor and raytrace DSI paths
5655            skyvf(isurflt) = 0._wp
5656            skyvft(isurflt) = 0._wp
5657
5658            !--Select a proper half-sphere for 2D raytracing
5659            SELECT CASE ( td )
5660               CASE ( iup_u, iup_l )
5661                  az0 = 0._wp
5662                  naz = raytrace_discrete_azims
5663                  azs = 2._wp * pi / REAL(naz, wp)
5664                  zn0 = 0._wp
5665                  nzn = raytrace_discrete_elevs / 2
5666                  zns = pi / 2._wp / REAL(nzn, wp)
5667               CASE ( isouth_u, isouth_l )
5668                  az0 = pi / 2._wp
5669                  naz = raytrace_discrete_azims / 2
5670                  azs = pi / REAL(naz, wp)
5671                  zn0 = 0._wp
5672                  nzn = raytrace_discrete_elevs
5673                  zns = pi / REAL(nzn, wp)
5674               CASE ( inorth_u, inorth_l )
5675                  az0 = - pi / 2._wp
5676                  naz = raytrace_discrete_azims / 2
5677                  azs = pi / REAL(naz, wp)
5678                  zn0 = 0._wp
5679                  nzn = raytrace_discrete_elevs
5680                  zns = pi / REAL(nzn, wp)
5681               CASE ( iwest_u, iwest_l )
5682                  az0 = pi
5683                  naz = raytrace_discrete_azims / 2
5684                  azs = pi / REAL(naz, wp)
5685                  zn0 = 0._wp
5686                  nzn = raytrace_discrete_elevs
5687                  zns = pi / REAL(nzn, wp)
5688               CASE ( ieast_u, ieast_l )
5689                  az0 = 0._wp
5690                  naz = raytrace_discrete_azims / 2
5691                  azs = pi / REAL(naz, wp)
5692                  zn0 = 0._wp
5693                  nzn = raytrace_discrete_elevs
5694                  zns = pi / REAL(nzn, wp)
5695               CASE DEFAULT
5696                  WRITE(message_string, *) 'ERROR: the surface type ', td,     &
5697                                           ' is not supported for calculating',&
5698                                           ' SVF'
5699                  CALL message( 'radiation_calc_svf', 'PA0488', 1, 2, 0, 6, 0 )
5700            END SELECT
5701
5702            ALLOCATE ( zdirs(1:nzn), zbdry(0:nzn), vffrac(1:nzn), ztransp(1:nzn) )
5703            zdirs(:) = (/( TAN(pi/2 - (zn0+(REAL(izn,wp)-.5_wp)*zns)), izn=1, nzn )/)
5704            zbdry(:) = (/( zn0+REAL(izn,wp)*zns, izn=0, nzn )/)
5705            IF ( td == iup_u  .OR.  td == iup_l )  THEN
5706               !-- For horizontal target, vf fractions are constant per azimuth
5707               vffrac(:) = (COS(2 * zbdry(0:nzn-1)) - COS(2 * zbdry(1:nzn))) / 2._wp / REAL(naz, wp)
5708               !--sum of vffrac for all iaz equals 1, verified
5709            ENDIF
5710
5711            !--Calculate sky-view factor and direct solar visibility using 2D raytracing
5712            DO iaz = 1, naz
5713               azmid = az0 + (REAL(iaz, wp) - .5_wp) * azs
5714               IF ( td /= iup_u  .AND.  td /= iup_l )  THEN
5715                  az2 = REAL(iaz, wp) * azs - pi/2._wp
5716                  az1 = az2 - azs
5717                  !TODO precalculate after 1st line
5718                  vffrac(:) = (SIN(az2) - SIN(az1))                           &
5719                              * (zbdry(1:nzn) - zbdry(0:nzn-1)                &
5720                                 + SIN(zbdry(0:nzn-1))*COS(zbdry(0:nzn-1))    &
5721                                 - SIN(zbdry(1:nzn))*COS(zbdry(1:nzn)))       &
5722                              / (2._wp * pi)
5723                  !--sum of vffrac for all iaz equals 1, verified
5724               ENDIF
5725               CALL raytrace_2d(ta, (/ COS(azmid), SIN(azmid) /), zdirs,      &
5726                                    surfstart(myid) + isurflt, facearea(td),  &
5727                                    vffrac, .TRUE., .FALSE., win_lad, horizon,&
5728                                    ztransp) !FIXME unit vect in grid units + zdirs
5729
5730               azen = pi/2 - ATAN(horizon)
5731               IF ( td == iup_u  .OR.  td == iup_l )  THEN
5732                  azen = MIN(azen, pi/2) !only above horizontal direction
5733                  skyvf(isurflt) = skyvf(isurflt) + (1._wp - COS(2*azen)) /   &
5734                     (2._wp * raytrace_discrete_azims)
5735               ELSE
5736                  skyvf(isurflt) = skyvf(isurflt) + (SIN(az2) - SIN(az1)) *   &
5737                              (azen - SIN(azen)*COS(azen)) / (2._wp*pi)
5738               ENDIF
5739               skyvft(isurflt) = skyvft(isurflt) + SUM(ztransp(:) * vffrac(:))
5740 
5741               !--Save direct solar transparency
5742               j = MODULO(NINT(azmid/                                          &
5743                               (2._wp*pi)*raytrace_discrete_azims-.5_wp, iwp), &
5744                          raytrace_discrete_azims)
5745
5746               DO k = 1, raytrace_discrete_elevs/2
5747                  i = dsidir_rev(k-1, j)
5748                  IF ( i /= -1 )  dsitrans(isurflt, i) = ztransp(k)
5749               ENDDO
5750            ENDDO
5751
5752            DEALLOCATE ( zdirs, zbdry, vffrac, ztransp )
5753!
5754!--         Following calculations only required for surface_reflections
5755            IF ( surface_reflections )  THEN
5756
5757               DO  isurfs = 1, nsurf
5758                  IF ( .NOT.  surface_facing(surfl(ix, isurflt), surfl(iy, isurflt), &
5759                     surfl(iz, isurflt), surfl(id, isurflt), &
5760                     surf(ix, isurfs), surf(iy, isurfs), &
5761                     surf(iz, isurfs), surf(id, isurfs)) )  THEN
5762                     CYCLE
5763                  ENDIF
5764                 
5765                  sd = surf(id, isurfs)
5766                  sa = (/ REAL(surf(iz, isurfs), wp) - 0.5_wp * kdir(sd),  &
5767                          REAL(surf(iy, isurfs), wp) - 0.5_wp * jdir(sd),  &
5768                          REAL(surf(ix, isurfs), wp) - 0.5_wp * idir(sd)  /)
5769
5770!--               unit vector source -> target
5771                  uv = (/ (ta(1)-sa(1))*dz(1), (ta(2)-sa(2))*dy, (ta(3)-sa(3))*dx /)
5772                  sqdist = SUM(uv(:)**2)
5773                  uv = uv / SQRT(sqdist)
5774
5775!--               reject raytracing above max distance
5776                  IF ( SQRT(sqdist) > max_raytracing_dist ) THEN
5777                     ray_skip_maxdist = ray_skip_maxdist + 1
5778                     CYCLE
5779                  ENDIF
5780                 
5781!--               irradiance factor (our unshaded shape view factor) = view factor per differential target area * source area
5782                  rirrf = dot_product((/ kdir(sd), jdir(sd), idir(sd) /), uv) & ! cosine of source normal and direction
5783                      * dot_product((/ kdir(td), jdir(td), idir(td) /), -uv) &  ! cosine of target normal and reverse direction
5784                      / (pi * sqdist) & ! square of distance between centers
5785                      * facearea(sd)
5786
5787!--               reject raytracing for potentially too small view factor values
5788                  IF ( rirrf < min_irrf_value ) THEN
5789                      ray_skip_minval = ray_skip_minval + 1
5790                      CYCLE
5791                  ENDIF
5792
5793!--               raytrace + process plant canopy sinks within
5794                  CALL raytrace(sa, ta, isurfs, rirrf, facearea(td), .TRUE., &
5795                                visible, transparency, win_lad)
5796
5797                  IF ( .NOT.  visible ) CYCLE
5798                 ! rsvf = rirrf * transparency
5799
5800!--               write to the svf array
5801                  nsvfl = nsvfl + 1
5802!--               check dimmension of asvf array and enlarge it if needed
5803                  IF ( nsvfla < nsvfl )  THEN
5804                     k = nsvfla * 2
5805                     IF ( msvf == 0 )  THEN
5806                        msvf = 1
5807                        ALLOCATE( asvf1(k) )
5808                        asvf => asvf1
5809                        asvf1(1:nsvfla) = asvf2
5810                        DEALLOCATE( asvf2 )
5811                     ELSE
5812                        msvf = 0
5813                        ALLOCATE( asvf2(k) )
5814                        asvf => asvf2
5815                        asvf2(1:nsvfla) = asvf1
5816                        DEALLOCATE( asvf1 )
5817                     ENDIF
5818
5819!                      WRITE(msg,'(A,3I12)') 'Grow asvf:',nsvfl,nsvfla,k
5820!                      CALL radiation_write_debug_log( msg )
5821                     
5822                     nsvfla = k
5823                  ENDIF
5824!--               write svf values into the array
5825                  asvf(nsvfl)%isurflt = isurflt
5826                  asvf(nsvfl)%isurfs = isurfs
5827                  asvf(nsvfl)%rsvf = rirrf !we postopne multiplication by transparency
5828                  asvf(nsvfl)%rtransp = transparency !a.k.a. Direct Irradiance Factor
5829               ENDDO
5830            ENDIF
5831        ENDDO
5832
5833        !--Raytrace to canopy boxes to fill dsitransc TODO optimize
5834        !--
5835        dsitransc(:,:) = -999._wp !FIXME
5836        az0 = 0._wp
5837        naz = raytrace_discrete_azims
5838        azs = 2._wp * pi / REAL(naz, wp)
5839        zn0 = 0._wp
5840        nzn = raytrace_discrete_elevs / 2
5841        zns = pi / 2._wp / REAL(nzn, wp)
5842        ALLOCATE ( zdirs(1:nzn), vffrac(1:nzn), ztransp(1:nzn) )
5843        zdirs(:) = (/( TAN(pi/2 - (zn0+(REAL(izn,wp)-.5_wp)*zns)), izn=1, nzn )/)
5844        vffrac(:) = 0._wp
5845
5846        DO ipcgb = 1, npcbl
5847           ta = (/ REAL(pcbl(iz, ipcgb), wp),  &
5848                   REAL(pcbl(iy, ipcgb), wp),  &
5849                   REAL(pcbl(ix, ipcgb), wp) /)
5850           !--Calculate sky-view factor and direct solar visibility using 2D raytracing
5851           DO iaz = 1, naz
5852              azmid = az0 + (REAL(iaz, wp) - .5_wp) * azs
5853              CALL raytrace_2d(ta, (/ COS(azmid), SIN(azmid) /), zdirs,     &
5854                                   -999, -999._wp, vffrac, .FALSE., .TRUE., &
5855                                   win_lad, horizon, ztransp) !FIXME unit vect in grid units + zdirs
5856
5857              !--Save direct solar transparency
5858              j = MODULO(NINT(azmid/                                         &
5859                             (2._wp*pi)*raytrace_discrete_azims-.5_wp, iwp), &
5860                         raytrace_discrete_azims)
5861              DO k = 1, raytrace_discrete_elevs/2
5862                 i = dsidir_rev(k-1, j)
5863                 IF ( i /= -1 )  dsitransc(ipcgb, i) = ztransp(k)
5864              ENDDO
5865           ENDDO
5866        ENDDO
5867        DEALLOCATE ( zdirs, vffrac, ztransp )
5868
5869!         CALL radiation_write_debug_log( 'End of calculation SVF' )
5870!         WRITE(msg, *) 'Raytracing skipped for maximum distance of ', &
5871!             max_raytracing_dist, ' m on ', ray_skip_maxdist, ' pairs.'
5872!         CALL radiation_write_debug_log( msg )
5873!         WRITE(msg, *) 'Raytracing skipped for minimum potential value of ', &
5874!             min_irrf_value , ' on ', ray_skip_minval, ' pairs.'
5875!         CALL radiation_write_debug_log( msg )
5876
5877        CALL location_message( '    waiting for completion of SVF and CSF calculation in all processes', .TRUE. )
5878!--     deallocate temporary global arrays
5879        DEALLOCATE(nzterr)
5880       
5881        IF ( plant_canopy )  THEN
5882!--         finalize mpi_rma communication and deallocate temporary arrays
5883#if defined( __parallel )
5884            IF ( rma_lad_raytrace )  THEN
5885                CALL MPI_Win_flush_all(win_lad, ierr)
5886!--             unlock MPI window
5887                CALL MPI_Win_unlock_all(win_lad, ierr)
5888!--             free MPI window
5889                CALL MPI_Win_free(win_lad, ierr)
5890               
5891!--             deallocate temporary arrays storing values for csf calculation during raytracing
5892                DEALLOCATE( lad_s_ray )
5893!--             sub_lad is the pointer to lad_s_rma in case of rma_lad_raytrace
5894!--             and must not be deallocated here
5895            ELSE
5896                DEALLOCATE(sub_lad)
5897                DEALLOCATE(sub_lad_g)
5898            ENDIF
5899#else
5900            DEALLOCATE(sub_lad)
5901#endif
5902            DEALLOCATE( boxes )
5903            DEALLOCATE( crlens )
5904            DEALLOCATE( plantt )
5905            DEALLOCATE( rt2_track, rt2_track_lad, rt2_track_dist, rt2_dist )
5906        ENDIF
5907
5908        CALL location_message( '    calculation of the complete SVF array', .TRUE. )
5909
5910!         CALL radiation_write_debug_log( 'Start SVF sort' )
5911!--     sort svf ( a version of quicksort )
5912        CALL quicksort_svf(asvf,1,nsvfl)
5913
5914        !< load svf from the structure array to plain arrays
5915!         CALL radiation_write_debug_log( 'Load svf from the structure array to plain arrays' )
5916        ALLOCATE( svf(ndsvf,nsvfl) )
5917        ALLOCATE( svfsurf(idsvf,nsvfl) )
5918        svfnorm_counts(:) = 0._wp
5919        isurflt_prev = -1
5920        ksvf = 1
5921        svfsum = 0._wp
5922        DO isvf = 1, nsvfl
5923!--         normalize svf per target face
5924            IF ( asvf(ksvf)%isurflt /= isurflt_prev )  THEN
5925                IF ( isurflt_prev /= -1  .AND.  svfsum /= 0._wp )  THEN
5926                    !< update histogram of logged svf normalization values
5927                    i = searchsorted(svfnorm_report_thresh, svfsum / (1._wp-skyvf(isurflt_prev)))
5928                    svfnorm_counts(i) = svfnorm_counts(i) + 1
5929
5930                    svf(1, isvf_surflt:isvf-1) = svf(1, isvf_surflt:isvf-1) / svfsum * (1._wp-skyvf(isurflt_prev))
5931                ENDIF
5932                isurflt_prev = asvf(ksvf)%isurflt
5933                isvf_surflt = isvf
5934                svfsum = asvf(ksvf)%rsvf !?? / asvf(ksvf)%rtransp
5935            ELSE
5936                svfsum = svfsum + asvf(ksvf)%rsvf !?? / asvf(ksvf)%rtransp
5937            ENDIF
5938
5939            svf(:, isvf) = (/ asvf(ksvf)%rsvf, asvf(ksvf)%rtransp /)
5940            svfsurf(:, isvf) = (/ asvf(ksvf)%isurflt, asvf(ksvf)%isurfs /)
5941
5942!--         next element
5943            ksvf = ksvf + 1
5944        ENDDO
5945
5946        IF ( isurflt_prev /= -1  .AND.  svfsum /= 0._wp )  THEN
5947            i = searchsorted(svfnorm_report_thresh, svfsum / (1._wp-skyvf(isurflt_prev)))
5948            svfnorm_counts(i) = svfnorm_counts(i) + 1
5949
5950            svf(1, isvf_surflt:nsvfl) = svf(1, isvf_surflt:nsvfl) / svfsum * (1._wp-skyvf(isurflt_prev))
5951        ENDIF
5952        !TODO we should be able to deallocate skyvf, from now on we only need skyvft
5953
5954!--     deallocate temporary asvf array
5955!--     DEALLOCATE(asvf) - ifort has a problem with deallocation of allocatable target
5956!--     via pointing pointer - we need to test original targets
5957        IF ( ALLOCATED(asvf1) )  THEN
5958            DEALLOCATE(asvf1)
5959        ENDIF
5960        IF ( ALLOCATED(asvf2) )  THEN
5961            DEALLOCATE(asvf2)
5962        ENDIF
5963
5964        npcsfl = 0
5965        IF ( plant_canopy )  THEN
5966
5967            CALL location_message( '    calculation of the complete CSF array', .TRUE. )
5968!             CALL radiation_write_debug_log( 'Calculation of the complete CSF array' )
5969!--         sort and merge csf for the last time, keeping the array size to minimum
5970            CALL merge_and_grow_csf(-1)
5971           
5972!--         aggregate csb among processors
5973!--         allocate necessary arrays
5974            ALLOCATE( csflt(ndcsf,max(ncsfl,ndcsf)) )
5975            ALLOCATE( kcsflt(kdcsf,max(ncsfl,kdcsf)) )
5976            ALLOCATE( icsflt(0:numprocs-1) )
5977            ALLOCATE( dcsflt(0:numprocs-1) )
5978            ALLOCATE( ipcsflt(0:numprocs-1) )
5979            ALLOCATE( dpcsflt(0:numprocs-1) )
5980           
5981!--         fill out arrays of csf values and
5982!--         arrays of number of elements and displacements
5983!--         for particular precessors
5984            icsflt = 0
5985            dcsflt = 0
5986            ip = -1
5987            j = -1
5988            d = 0
5989            DO kcsf = 1, ncsfl
5990                j = j+1
5991                IF ( acsf(kcsf)%ip /= ip )  THEN
5992!--                 new block of the processor
5993!--                 number of elements of previous block
5994                    IF ( ip>=0) icsflt(ip) = j
5995                    d = d+j
5996!--                 blank blocks
5997                    DO jp = ip+1, acsf(kcsf)%ip-1
5998!--                     number of elements is zero, displacement is equal to previous
5999                        icsflt(jp) = 0
6000                        dcsflt(jp) = d
6001                    ENDDO
6002!--                 the actual block
6003                    ip = acsf(kcsf)%ip
6004                    dcsflt(ip) = d
6005                    j = 0
6006                ENDIF
6007!--             fill out real values of rsvf, rtransp
6008                csflt(1,kcsf) = acsf(kcsf)%rsvf
6009                csflt(2,kcsf) = acsf(kcsf)%rtransp
6010!--             fill out integer values of itz,ity,itx,isurfs
6011                kcsflt(1,kcsf) = acsf(kcsf)%itz
6012                kcsflt(2,kcsf) = acsf(kcsf)%ity
6013                kcsflt(3,kcsf) = acsf(kcsf)%itx
6014                kcsflt(4,kcsf) = acsf(kcsf)%isurfs
6015            ENDDO
6016!--         last blank blocks at the end of array
6017            j = j+1
6018            IF ( ip>=0 ) icsflt(ip) = j
6019            d = d+j
6020            DO jp = ip+1, numprocs-1
6021!--             number of elements is zero, displacement is equal to previous
6022                icsflt(jp) = 0
6023                dcsflt(jp) = d
6024            ENDDO
6025           
6026!--         deallocate temporary acsf array
6027!--         DEALLOCATE(acsf) - ifort has a problem with deallocation of allocatable target
6028!--         via pointing pointer - we need to test original targets
6029            IF ( ALLOCATED(acsf1) )  THEN
6030                DEALLOCATE(acsf1)
6031            ENDIF
6032            IF ( ALLOCATED(acsf2) )  THEN
6033                DEALLOCATE(acsf2)
6034            ENDIF
6035                   
6036#if defined( __parallel )
6037!--         scatter and gather the number of elements to and from all processor
6038!--         and calculate displacements
6039!             CALL radiation_write_debug_log( 'Scatter and gather the number of elements to and from all processor' )
6040            CALL MPI_AlltoAll(icsflt,1,MPI_INTEGER,ipcsflt,1,MPI_INTEGER,comm2d, ierr)
6041           
6042            npcsfl = SUM(ipcsflt)
6043            d = 0
6044            DO i = 0, numprocs-1
6045                dpcsflt(i) = d
6046                d = d + ipcsflt(i)
6047            ENDDO
6048
6049!--         exchange csf fields between processors
6050!             CALL radiation_write_debug_log( 'Exchange csf fields between processors' )
6051            ALLOCATE( pcsflt(ndcsf,max(npcsfl,ndcsf)) )
6052            ALLOCATE( kpcsflt(kdcsf,max(npcsfl,kdcsf)) )
6053            CALL MPI_AlltoAllv(csflt, ndcsf*icsflt, ndcsf*dcsflt, MPI_REAL, &
6054                pcsflt, ndcsf*ipcsflt, ndcsf*dpcsflt, MPI_REAL, comm2d, ierr)
6055            CALL MPI_AlltoAllv(kcsflt, kdcsf*icsflt, kdcsf*dcsflt, MPI_INTEGER, &
6056                kpcsflt, kdcsf*ipcsflt, kdcsf*dpcsflt, MPI_INTEGER, comm2d, ierr)
6057           
6058#else
6059            npcsfl = ncsfl
6060            ALLOCATE( pcsflt(ndcsf,max(npcsfl,ndcsf)) )
6061            ALLOCATE( kpcsflt(kdcsf,max(npcsfl,kdcsf)) )
6062            pcsflt = csflt
6063            kpcsflt = kcsflt
6064#endif
6065
6066!--         deallocate temporary arrays
6067            DEALLOCATE( csflt )
6068            DEALLOCATE( kcsflt )
6069            DEALLOCATE( icsflt )
6070            DEALLOCATE( dcsflt )
6071            DEALLOCATE( ipcsflt )
6072            DEALLOCATE( dpcsflt )
6073
6074!--         sort csf ( a version of quicksort )
6075!             CALL radiation_write_debug_log( 'Sort csf' )
6076            CALL quicksort_csf2(kpcsflt, pcsflt, 1, npcsfl)
6077
6078!--         aggregate canopy sink factor records with identical box & source
6079!--         againg across all values from all processors
6080!             CALL radiation_write_debug_log( 'Aggregate canopy sink factor records with identical box' )
6081
6082            IF ( npcsfl > 0 )  THEN
6083                icsf = 1 !< reading index
6084                kcsf = 1 !< writing index
6085                DO while (icsf < npcsfl)
6086!--                 here kpcsf(kcsf) already has values from kpcsf(icsf)
6087                    IF ( kpcsflt(3,icsf) == kpcsflt(3,icsf+1)  .AND.  &
6088                         kpcsflt(2,icsf) == kpcsflt(2,icsf+1)  .AND.  &
6089                         kpcsflt(1,icsf) == kpcsflt(1,icsf+1)  .AND.  &
6090                         kpcsflt(4,icsf) == kpcsflt(4,icsf+1) )  THEN
6091!--                     We could simply take either first or second rtransp, both are valid. As a very simple heuristic about which ray
6092!--                     probably passes nearer the center of the target box, we choose DIF from the entry with greater CSF, since that
6093!--                     might mean that the traced beam passes longer through the canopy box.
6094                        IF ( pcsflt(1,kcsf) < pcsflt(1,icsf+1) )  THEN
6095                            pcsflt(2,kcsf) = pcsflt(2,icsf+1)
6096                        ENDIF
6097                        pcsflt(1,kcsf) = pcsflt(1,kcsf) + pcsflt(1,icsf+1)
6098
6099!--                     advance reading index, keep writing index
6100                        icsf = icsf + 1
6101                    ELSE
6102!--                     not identical, just advance and copy
6103                        icsf = icsf + 1
6104                        kcsf = kcsf + 1
6105                        kpcsflt(:,kcsf) = kpcsflt(:,icsf)
6106                        pcsflt(:,kcsf) = pcsflt(:,icsf)
6107                    ENDIF
6108                ENDDO
6109!--             last written item is now also the last item in valid part of array
6110                npcsfl = kcsf
6111            ENDIF
6112
6113            ncsfl = npcsfl
6114            IF ( ncsfl > 0 )  THEN
6115                ALLOCATE( csf(ndcsf,ncsfl) )
6116                ALLOCATE( csfsurf(idcsf,ncsfl) )
6117                DO icsf = 1, ncsfl
6118                    csf(:,icsf) = pcsflt(:,icsf)
6119                    csfsurf(1,icsf) =  gridpcbl(kpcsflt(1,icsf),kpcsflt(2,icsf),kpcsflt(3,icsf))
6120                    csfsurf(2,icsf) =  kpcsflt(4,icsf)
6121                ENDDO
6122            ENDIF
6123           
6124!--         deallocation of temporary arrays
6125            DEALLOCATE( pcsflt )
6126            DEALLOCATE( kpcsflt )
6127!             CALL radiation_write_debug_log( 'End of aggregate csf' )
6128           
6129        ENDIF
6130
6131#if defined( __parallel )
6132        CALL MPI_BARRIER( comm2d, ierr )
6133#endif
6134!         CALL radiation_write_debug_log( 'End of radiation_calc_svf (after mpi_barrier)' )
6135
6136        RETURN
6137       
6138301     WRITE( message_string, * )  &
6139            'I/O error when processing shape view factors / ',  &
6140            'plant canopy sink factors / direct irradiance factors.'
6141        CALL message( 'init_urban_surface', 'PA0502', 2, 2, 0, 6, 0 )
6142       
6143    END SUBROUTINE radiation_calc_svf
6144
6145   
6146!------------------------------------------------------------------------------!
6147! Description:
6148! ------------
6149!> Raytracing for detecting obstacles and calculating compound canopy sink
6150!> factors. (A simple obstacle detection would only need to process faces in
6151!> 3 dimensions without any ordering.)
6152!> Assumtions:
6153!> -----------
6154!> 1. The ray always originates from a face midpoint (only one coordinate equals
6155!>    *.5, i.e. wall) and doesn't travel parallel to the surface (that would mean
6156!>    shape factor=0). Therefore, the ray may never travel exactly along a face
6157!>    or an edge.
6158!> 2. From grid bottom to urban surface top the grid has to be *equidistant*
6159!>    within each of the dimensions, including vertical (but the resolution
6160!>    doesn't need to be the same in all three dimensions).
6161!------------------------------------------------------------------------------!
6162    SUBROUTINE raytrace(src, targ, isrc, rirrf, atarg, create_csf, visible, transparency, win_lad)
6163        IMPLICIT NONE
6164
6165        REAL(wp), DIMENSION(3), INTENT(in)     :: src, targ    !< real coordinates z,y,x
6166        INTEGER(iwp), INTENT(in)               :: isrc         !< index of source face for csf
6167        REAL(wp), INTENT(in)                   :: rirrf        !< irradiance factor for csf
6168        REAL(wp), INTENT(in)                   :: atarg        !< target surface area for csf
6169        LOGICAL, INTENT(in)                    :: create_csf   !< whether to generate new CSFs during raytracing
6170        LOGICAL, INTENT(out)                   :: visible
6171        REAL(wp), INTENT(out)                  :: transparency !< along whole path
6172        INTEGER(iwp), INTENT(in)               :: win_lad
6173        INTEGER(iwp)                           :: i, j, k, d
6174        INTEGER(iwp)                           :: seldim       !< dimension to be incremented
6175        INTEGER(iwp)                           :: ncsb         !< no of written plant canopy sinkboxes
6176        INTEGER(iwp)                           :: maxboxes     !< max no of gridboxes visited
6177        REAL(wp)                               :: distance     !< euclidean along path
6178        REAL(wp)                               :: crlen        !< length of gridbox crossing
6179        REAL(wp)                               :: lastdist     !< beginning of current crossing
6180        REAL(wp)                               :: nextdist     !< end of current crossing
6181        REAL(wp)                               :: realdist     !< distance in meters per unit distance
6182        REAL(wp)                               :: crmid        !< midpoint of crossing
6183        REAL(wp)                               :: cursink      !< sink factor for current canopy box
6184        REAL(wp), DIMENSION(3)                 :: delta        !< path vector
6185        REAL(wp), DIMENSION(3)                 :: uvect        !< unit vector
6186        REAL(wp), DIMENSION(3)                 :: dimnextdist  !< distance for each dimension increments
6187        INTEGER(iwp), DIMENSION(3)             :: box          !< gridbox being crossed
6188        INTEGER(iwp), DIMENSION(3)             :: dimnext      !< next dimension increments along path
6189        INTEGER(iwp), DIMENSION(3)             :: dimdelta     !< dimension direction = +- 1
6190        INTEGER(iwp)                           :: px, py       !< number of processors in x and y dir before
6191                                                               !< the processor in the question
6192        INTEGER(iwp)                           :: ip           !< number of processor where gridbox reside
6193        INTEGER(iwp)                           :: ig           !< 1D index of gridbox in global 2D array
6194        REAL(wp)                               :: lad_s_target !< recieved lad_s of particular grid box
6195        REAL(wp), PARAMETER                    :: grow_factor = 1.5_wp !< factor of expansion of grow arrays
6196
6197!
6198!--     Maximum number of gridboxes visited equals to maximum number of boundaries crossed in each dimension plus one. That's also
6199!--     the maximum number of plant canopy boxes written. We grow the acsf array accordingly using exponential factor.
6200        maxboxes = SUM(ABS(NINT(targ, iwp) - NINT(src, iwp))) + 1
6201        IF ( plant_canopy  .AND.  ncsfl + maxboxes > ncsfla )  THEN
6202!--         use this code for growing by fixed exponential increments (equivalent to case where ncsfl always increases by 1)
6203!--         k = CEILING(grow_factor ** real(CEILING(log(real(ncsfl + maxboxes, kind=wp)) &
6204!--                                                / log(grow_factor)), kind=wp))
6205!--         or use this code to simply always keep some extra space after growing
6206            k = CEILING(REAL(ncsfl + maxboxes, kind=wp) * grow_factor)
6207
6208            CALL merge_and_grow_csf(k)
6209        ENDIF
6210       
6211        transparency = 1._wp
6212        ncsb = 0
6213
6214        delta(:) = targ(:) - src(:)
6215        distance = SQRT(SUM(delta(:)**2))
6216        IF ( distance == 0._wp )  THEN
6217            visible = .TRUE.
6218            RETURN
6219        ENDIF
6220        uvect(:) = delta(:) / distance
6221        realdist = SQRT(SUM( (uvect(:)*(/dz(1),dy,dx/))**2 ))
6222
6223        lastdist = 0._wp
6224
6225!--     Since all face coordinates have values *.5 and we'd like to use
6226!--     integers, all these have .5 added
6227        DO d = 1, 3
6228            IF ( uvect(d) == 0._wp )  THEN
6229                dimnext(d) = 999999999
6230                dimdelta(d) = 999999999
6231                dimnextdist(d) = 1.0E20_wp
6232            ELSE IF ( uvect(d) > 0._wp )  THEN
6233                dimnext(d) = CEILING(src(d) + .5_wp)
6234                dimdelta(d) = 1
6235                dimnextdist(d) = (dimnext(d) - .5_wp - src(d)) / uvect(d)
6236            ELSE
6237                dimnext(d) = FLOOR(src(d) + .5_wp)
6238                dimdelta(d) = -1
6239                dimnextdist(d) = (dimnext(d) - .5_wp - src(d)) / uvect(d)
6240            ENDIF
6241        ENDDO
6242
6243        DO
6244!--         along what dimension will the next wall crossing be?
6245            seldim = minloc(dimnextdist, 1)
6246            nextdist = dimnextdist(seldim)
6247            IF ( nextdist > distance ) nextdist = distance
6248
6249            crlen = nextdist - lastdist
6250            IF ( crlen > .001_wp )  THEN
6251                crmid = (lastdist + nextdist) * .5_wp
6252                box = NINT(src(:) + uvect(:) * crmid, iwp)
6253
6254!--             calculate index of the grid with global indices (box(2),box(3))
6255!--             in the array nzterr and plantt and id of the coresponding processor
6256                px = box(3)/nnx
6257                py = box(2)/nny
6258                ip = px*pdims(2)+py
6259                ig = ip*nnx*nny + (box(3)-px*nnx)*nny + box(2)-py*nny
6260                IF ( box(1) <= nzterr(ig) )  THEN
6261                    visible = .FALSE.
6262                    RETURN
6263                ENDIF
6264
6265                IF ( plant_canopy )  THEN
6266                    IF ( box(1) <= plantt(ig) )  THEN
6267                        ncsb = ncsb + 1
6268                        boxes(:,ncsb) = box
6269                        crlens(ncsb) = crlen
6270#if defined( __parallel )
6271                        lad_ip(ncsb) = ip
6272                        lad_disp(ncsb) = (box(3)-px*nnx)*(nny*nzp) + (box(2)-py*nny)*nzp + box(1)-nzub
6273#endif
6274                    ENDIF
6275                ENDIF
6276            ENDIF
6277
6278            IF ( nextdist >= distance ) EXIT
6279            lastdist = nextdist
6280            dimnext(seldim) = dimnext(seldim) + dimdelta(seldim)
6281            dimnextdist(seldim) = (dimnext(seldim) - .5_wp - src(seldim)) / uvect(seldim)
6282        ENDDO
6283       
6284        IF ( plant_canopy )  THEN
6285#if defined( __parallel )
6286            IF ( rma_lad_raytrace )  THEN
6287!--             send requests for lad_s to appropriate processor
6288                CALL cpu_log( log_point_s(77), 'rad_init_rma', 'start' )
6289                DO i = 1, ncsb
6290                    CALL MPI_Get(lad_s_ray(i), 1, MPI_REAL, lad_ip(i), lad_disp(i), &
6291                                 1, MPI_REAL, win_lad, ierr)
6292                    IF ( ierr /= 0 )  THEN
6293                        WRITE(message_string, *) 'MPI error ', ierr, ' at MPI_Get'
6294                        CALL message( 'raytrace', 'PA0519', 1, 2, 0, 6, 0 )
6295                    ENDIF
6296                ENDDO
6297               
6298!--             wait for all pending local requests complete
6299                CALL MPI_Win_flush_local_all(win_lad, ierr)
6300                IF ( ierr /= 0 )  THEN
6301                    WRITE(message_string, *) 'MPI error ', ierr, ' at MPI_Win_flush_local_all'
6302                    CALL message( 'raytrace', 'PA0519', 1, 2, 0, 6, 0 )
6303                ENDIF
6304                CALL cpu_log( log_point_s(77), 'rad_init_rma', 'stop' )
6305               
6306            ENDIF
6307#endif
6308
6309!--         calculate csf and transparency
6310            DO i = 1, ncsb
6311#if defined( __parallel )
6312                IF ( rma_lad_raytrace )  THEN
6313                    lad_s_target = lad_s_ray(i)
6314                ELSE
6315                    lad_s_target = sub_lad_g(lad_ip(i)*nnx*nny*nzp + lad_disp(i))
6316                ENDIF
6317#else
6318                lad_s_target = sub_lad(boxes(1,i),boxes(2,i),boxes(3,i))
6319#endif
6320                cursink = 1._wp - exp(-ext_coef * lad_s_target * crlens(i)*realdist)
6321
6322                IF ( create_csf )  THEN
6323!--                 write svf values into the array
6324                    ncsfl = ncsfl + 1
6325                    acsf(ncsfl)%ip = lad_ip(i)
6326                    acsf(ncsfl)%itx = boxes(3,i)
6327                    acsf(ncsfl)%ity = boxes(2,i)
6328                    acsf(ncsfl)%itz = boxes(1,i)
6329                    acsf(ncsfl)%isurfs = isrc
6330                    acsf(ncsfl)%rsvf = REAL(cursink*rirrf*atarg, wp) !-- we postpone multiplication by transparency
6331                    acsf(ncsfl)%rtransp = REAL(transparency, wp)
6332                ENDIF  !< create_csf
6333
6334                transparency = transparency * (1._wp - cursink)
6335               
6336            ENDDO
6337        ENDIF
6338       
6339        visible = .TRUE.
6340
6341    END SUBROUTINE raytrace
6342   
6343 
6344!------------------------------------------------------------------------------!
6345! Description:
6346! ------------
6347!> A new, more efficient version of ray tracing algorithm that processes a whole
6348!> arc instead of a single ray.
6349!>
6350!> In all comments, horizon means tangent of horizon angle, i.e.
6351!> vertical_delta / horizontal_distance
6352!------------------------------------------------------------------------------!
6353   SUBROUTINE raytrace_2d(origin, yxdir, zdirs, iorig, aorig, vffrac, &
6354                              create_csf, skip_1st_pcb, win_lad, horizon, &
6355                              transparency)
6356      IMPLICIT NONE
6357
6358      REAL(wp), DIMENSION(3), INTENT(IN)     ::  origin        !< z,y,x coordinates of ray origin
6359      REAL(wp), DIMENSION(2), INTENT(IN)     ::  yxdir         !< y,x *unit* vector of ray direction (in grid units)
6360      REAL(wp), DIMENSION(:), INTENT(IN)     ::  zdirs         !< list of z directions to raytrace (z/hdist, in grid)
6361      INTEGER(iwp), INTENT(in)               ::  iorig         !< index of origin face for csf
6362      REAL(wp), INTENT(in)                   ::  aorig         !< origin face area for csf
6363      REAL(wp), DIMENSION(LBOUND(zdirs, 1):UBOUND(zdirs, 1)), INTENT(in) ::  vffrac !<
6364                                                               !< view factor fractions of each ray for csf
6365      LOGICAL, INTENT(in)                    ::  create_csf    !< whether to generate new CSFs during raytracing
6366      LOGICAL, INTENT(in)                    ::  skip_1st_pcb  !< whether to skip first plant canopy box during raytracing
6367      INTEGER(iwp), INTENT(in)               ::  win_lad       !< leaf area density MPI window
6368      REAL(wp), INTENT(OUT)                  ::  horizon       !< highest horizon found after raytracing (z/hdist)
6369      REAL(wp), DIMENSION(LBOUND(zdirs, 1):UBOUND(zdirs, 1)), INTENT(OUT) ::  transparency !<
6370                                                                !< transparencies of zdirs paths
6371      !--INTEGER(iwp), DIMENSION(3, LBOUND(zdirs, 1):UBOUND(zdirs, 1)), INTENT(OUT) :: itarget !<
6372                                                                !< (z,y,x) coordinates of target faces for zdirs
6373      INTEGER(iwp)                           ::  i, k, l, d
6374      INTEGER(iwp)                           ::  seldim       !< dimension to be incremented
6375      REAL(wp), DIMENSION(2)                 ::  yxorigin     !< horizontal copy of origin (y,x)
6376      REAL(wp)                               ::  distance     !< euclidean along path
6377      REAL(wp)                               ::  lastdist     !< beginning of current crossing
6378      REAL(wp)                               ::  nextdist     !< end of current crossing
6379      REAL(wp)                               ::  crmid        !< midpoint of crossing
6380      REAL(wp)                               ::  horz_entry   !< horizon at entry to column
6381      REAL(wp)                               ::  horz_exit    !< horizon at exit from column
6382      REAL(wp)                               ::  bdydim       !< boundary for current dimension
6383      REAL(wp), DIMENSION(2)                 ::  crossdist    !< distances to boundary for dimensions
6384      REAL(wp), DIMENSION(2)                 ::  dimnextdist  !< distance for each dimension increments
6385      INTEGER(iwp), DIMENSION(2)             ::  column       !< grid column being crossed
6386      INTEGER(iwp), DIMENSION(2)             ::  dimnext      !< next dimension increments along path
6387      INTEGER(iwp), DIMENSION(2)             ::  dimdelta     !< dimension direction = +- 1
6388      INTEGER(iwp)                           ::  px, py       !< number of processors in x and y dir before
6389                                                              !< the processor in the question
6390      INTEGER(iwp)                           ::  ip           !< number of processor where gridbox reside
6391      INTEGER(iwp)                           ::  ig           !< 1D index of gridbox in global 2D array
6392      INTEGER(iwp)                           ::  wcount       !< RMA window item count
6393      INTEGER(iwp)                           ::  maxboxes     !< max no of CSF created
6394      INTEGER(iwp)                           ::  nly          !< maximum  plant canopy height
6395      INTEGER(iwp)                           ::  ntrack
6396      REAL(wp)                               ::  zbottom, ztop !< urban surface boundary in real numbers
6397      REAL(wp)                               ::  zorig        !< z coordinate of ray column entry
6398      REAL(wp)                               ::  zexit        !< z coordinate of ray column exit
6399      REAL(wp)                               ::  qdist        !< ratio of real distance to z coord difference
6400      REAL(wp)                               ::  dxxyy        !< square of real horizontal distance
6401      REAL(wp)                               ::  curtrans     !< transparency of current PC box crossing
6402      INTEGER(iwp)                           ::  zb0
6403      INTEGER(iwp)                           ::  zb1
6404      INTEGER(iwp)                           ::  nz
6405      INTEGER(iwp)                           ::  iz
6406      INTEGER(iwp)                           ::  zsgn
6407      REAL(wp), PARAMETER                    ::  grow_factor = 1.5_wp !< factor of expansion of grow arrays
6408
6409#if defined( __parallel )
6410      INTEGER(MPI_ADDRESS_KIND)              ::  wdisp        !< RMA window displacement
6411#endif
6412     
6413      yxorigin(:) = origin(2:3)
6414      transparency(:) = 1._wp !-- Pre-set the all rays to transparent before reducing
6415      horizon = -HUGE(1._wp)
6416
6417      !--Determine distance to boundary (in 2D xy)
6418      IF ( yxdir(1) > 0._wp )  THEN
6419         bdydim = ny + .5_wp !< north global boundary
6420         crossdist(1) = (bdydim - yxorigin(1)) / yxdir(1)
6421      ELSEIF ( yxdir(1) == 0._wp )  THEN
6422         crossdist(1) = HUGE(1._wp)
6423      ELSE
6424          bdydim = -.5_wp !< south global boundary
6425          crossdist(1) = (bdydim - yxorigin(1)) / yxdir(1)
6426      ENDIF
6427
6428      IF ( yxdir(2) >= 0._wp )  THEN
6429          bdydim = nx + .5_wp !< east global boundary
6430          crossdist(2) = (bdydim - yxorigin(2)) / yxdir(2)
6431      ELSEIF ( yxdir(2) == 0._wp )  THEN
6432         crossdist(2) = HUGE(1._wp)
6433      ELSE
6434          bdydim = -.5_wp !< west global boundary
6435          crossdist(2) = (bdydim - yxorigin(2)) / yxdir(2)
6436      ENDIF
6437      distance = minval(crossdist, 1)
6438
6439      IF ( plant_canopy )  THEN
6440         rt2_track_dist(0) = 0._wp
6441         rt2_track_lad(:,:) = 0._wp
6442         nly = plantt_max - nzub + 1
6443      ENDIF
6444
6445      lastdist = 0._wp
6446
6447!--   Since all face coordinates have values *.5 and we'd like to use
6448!--   integers, all these have .5 added
6449      DO d = 1, 2
6450          IF ( yxdir(d) == 0._wp )  THEN
6451              dimnext(d) = HUGE(1_iwp)
6452              dimdelta(d) = HUGE(1_iwp)
6453              dimnextdist(d) = HUGE(1._wp)
6454          ELSE IF ( yxdir(d) > 0._wp )  THEN
6455              dimnext(d) = FLOOR(yxorigin(d) + .5_wp) + 1
6456              dimdelta(d) = 1
6457              dimnextdist(d) = (dimnext(d) - .5_wp - yxorigin(d)) / yxdir(d)
6458          ELSE
6459              dimnext(d) = CEILING(yxorigin(d) + .5_wp) - 1
6460              dimdelta(d) = -1
6461              dimnextdist(d) = (dimnext(d) - .5_wp - yxorigin(d)) / yxdir(d)
6462          ENDIF
6463      ENDDO
6464
6465      ntrack = 0
6466      DO
6467!--      along what dimension will the next wall crossing be?
6468         seldim = minloc(dimnextdist, 1)
6469         nextdist = dimnextdist(seldim)
6470         IF ( nextdist > distance ) nextdist = distance
6471
6472         IF ( nextdist > lastdist )  THEN
6473            ntrack = ntrack + 1
6474            crmid = (lastdist + nextdist) * .5_wp
6475            column = NINT(yxorigin(:) + yxdir(:) * crmid, iwp)
6476
6477!--         calculate index of the grid with global indices (column(1),column(2))
6478!--         in the array nzterr and plantt and id of the coresponding processor
6479            px = column(2)/nnx
6480            py = column(1)/nny
6481            ip = px*pdims(2)+py
6482            ig = ip*nnx*nny + (column(2)-px*nnx)*nny + column(1)-py*nny
6483
6484            IF ( lastdist == 0._wp )  THEN
6485               horz_entry = -HUGE(1._wp)
6486            ELSE
6487               horz_entry = (nzterr(ig) - origin(1)) / lastdist
6488            ENDIF
6489            horz_exit = (nzterr(ig) - origin(1)) / nextdist
6490            horizon = MAX(horizon, horz_entry, horz_exit)
6491
6492            IF ( plant_canopy )  THEN
6493               rt2_track(:, ntrack) = column(:)
6494               rt2_track_dist(ntrack) = nextdist
6495            ENDIF
6496         ENDIF
6497
6498         IF ( nextdist >= distance )  EXIT
6499         lastdist = nextdist
6500         dimnext(seldim) = dimnext(seldim) + dimdelta(seldim)
6501         dimnextdist(seldim) = (dimnext(seldim) - .5_wp - yxorigin(seldim)) / yxdir(seldim)
6502      ENDDO
6503
6504      IF ( plant_canopy )  THEN
6505         !--Request LAD WHERE applicable
6506         !--
6507#if defined( __parallel )
6508         IF ( rma_lad_raytrace )  THEN
6509!--         send requests for lad_s to appropriate processor
6510            !CALL cpu_log( log_point_s(77), 'usm_init_rma', 'start' )
6511            DO i = 1, ntrack
6512               px = rt2_track(2,i)/nnx
6513               py = rt2_track(1,i)/nny
6514               ip = px*pdims(2)+py
6515               ig = ip*nnx*nny + (rt2_track(2,i)-px*nnx)*nny + rt2_track(1,i)-py*nny
6516               IF ( plantt(ig) <= nzterr(ig) )  CYCLE
6517               wdisp = (rt2_track(2,i)-px*nnx)*(nny*nzp) + (rt2_track(1,i)-py*nny)*nzp + nzterr(ig)+1-nzub
6518               wcount = plantt(ig)-nzterr(ig)
6519               ! TODO send request ASAP - even during raytracing
6520               CALL MPI_Get(rt2_track_lad(nzterr(ig)+1:plantt(ig), i), wcount, MPI_REAL, ip,    &
6521                            wdisp, wcount, MPI_REAL, win_lad, ierr)
6522               IF ( ierr /= 0 )  THEN
6523                  WRITE(message_string, *) 'MPI error ', ierr, ' at MPI_Get'
6524                  CALL message( 'raytrace_2d', 'PA0526', 1, 2, 0, 6, 0 )
6525               ENDIF
6526            ENDDO
6527
6528!--         wait for all pending local requests complete
6529            ! TODO WAIT selectively for each column later when needed
6530            CALL MPI_Win_flush_local_all(win_lad, ierr)
6531            IF ( ierr /= 0 )  THEN
6532               WRITE(message_string, *) 'MPI error ', ierr, ' at MPI_Win_flush_local_all'
6533               CALL message( 'raytrace', 'PA0527', 1, 2, 0, 6, 0 )
6534            ENDIF
6535            !CALL cpu_log( log_point_s(77), 'usm_init_rma', 'stop' )
6536         ELSE ! rma_lad_raytrace
6537            DO i = 1, ntrack
6538               px = rt2_track(2,i)/nnx
6539               py = rt2_track(1,i)/nny
6540               ip = px*pdims(2)+py
6541               ig = ip*nnx*nny*nzp + (rt2_track(2,i)-px*nnx)*(nny*nzp) + (rt2_track(1,i)-py*nny)*nzp
6542               rt2_track_lad(nzub:plantt_max, i) = sub_lad_g(ig:ig+nly-1)
6543            ENDDO
6544         ENDIF
6545#else
6546         DO i = 1, ntrack
6547            rt2_track_lad(nzub:plantt_max, i) = sub_lad(rt2_track(1,i), rt2_track(2,i), nzub:plantt_max)
6548         ENDDO
6549#endif
6550
6551         !--Skip the PCB around origin if requested
6552         !--
6553         IF ( skip_1st_pcb )  THEN
6554            rt2_track_lad(NINT(origin(1), iwp), 1) = 0._wp
6555         ENDIF
6556
6557         !--Assert that we have space allocated for CSFs
6558         !--
6559         maxboxes = (ntrack + MAX(origin(1) - nzub, nzpt - origin(1))) * SIZE(zdirs, 1)
6560         IF ( ncsfl + maxboxes > ncsfla )  THEN
6561!--         use this code for growing by fixed exponential increments (equivalent to case where ncsfl always increases by 1)
6562!--         k = CEILING(grow_factor ** real(CEILING(log(real(ncsfl + maxboxes, kind=wp)) &
6563!--                                                / log(grow_factor)), kind=wp))
6564!--         or use this code to simply always keep some extra space after growing
6565            k = CEILING(REAL(ncsfl + maxboxes, kind=wp) * grow_factor)
6566            CALL merge_and_grow_csf(k)
6567         ENDIF
6568
6569         !--Calculate transparencies and store new CSFs
6570         !--
6571         zbottom = REAL(nzub, wp) - .5_wp
6572         ztop = REAL(plantt_max, wp) + .5_wp
6573
6574         !--Reverse direction of radiation (face->sky), only when create_csf
6575         !--
6576         IF ( create_csf )  THEN
6577            DO i = 1, ntrack ! for each column
6578               dxxyy = ((dy*yxdir(1))**2 + (dx*yxdir(2))**2) * (rt2_track_dist(i)-rt2_track_dist(i-1))**2
6579               px = rt2_track(2,i)/nnx
6580               py = rt2_track(1,i)/nny
6581               ip = px*pdims(2)+py
6582
6583               DO k = LBOUND(zdirs, 1), UBOUND(zdirs, 1) ! for each ray
6584                  IF ( zdirs(k) <= horizon )  THEN
6585                     CYCLE
6586                  ENDIF
6587
6588                  zorig = REAL(origin(1), wp) + zdirs(k) * rt2_track_dist(i-1)
6589                  IF ( zorig <= zbottom .OR. zorig >= ztop )  CYCLE
6590
6591                  zsgn = INT(SIGN(1._wp, zdirs(k)), iwp)
6592                  rt2_dist(1) = 0._wp
6593                  IF ( zdirs(k) == 0._wp )  THEN ! ray is exactly horizontal
6594                     nz = 2
6595                     rt2_dist(nz) = SQRT(dxxyy)
6596                     iz = NINT(zorig, iwp)
6597                  ELSE
6598                     zexit = MIN(MAX(REAL(origin(1), wp) + zdirs(k) * rt2_track_dist(i), zbottom), ztop)
6599
6600                     zb0 = FLOOR(  zorig * zsgn - .5_wp) + 1  ! because it must be greater than orig
6601                     zb1 = CEILING(zexit * zsgn - .5_wp) - 1  ! because it must be smaller than exit
6602                     nz = MAX(zb1 - zb0 + 3, 2)
6603                     rt2_dist(nz) = SQRT(((zexit-zorig)*dz(1))**2 + dxxyy)
6604                     qdist = rt2_dist(nz) / (zexit-zorig)
6605                     rt2_dist(2:nz-1) = (/( ((REAL(l, wp) + .5_wp) * zsgn - zorig) * qdist , l = zb0, zb1 )/)
6606                     iz = zb0 * zsgn
6607                  ENDIF
6608
6609                  DO l = 2, nz
6610                     IF ( rt2_track_lad(iz, i) > 0._wp )  THEN
6611                        curtrans = exp(-ext_coef * rt2_track_lad(iz, i) * (rt2_dist(l)-rt2_dist(l-1)))
6612
6613                        ncsfl = ncsfl + 1
6614                        acsf(ncsfl)%ip = ip
6615                        acsf(ncsfl)%itx = rt2_track(2,i)
6616                        acsf(ncsfl)%ity = rt2_track(1,i)
6617                        acsf(ncsfl)%itz = iz
6618                        acsf(ncsfl)%isurfs = iorig
6619                        acsf(ncsfl)%rsvf = REAL((1._wp - curtrans)*aorig*vffrac(k), wp) ! we postpone multiplication by transparency
6620                        acsf(ncsfl)%rtransp = REAL(transparency(k), wp)
6621
6622                        transparency(k) = transparency(k) * curtrans
6623                     ENDIF
6624                     iz = iz + zsgn
6625                  ENDDO ! l = 1, nz - 1
6626               ENDDO ! k = LBOUND(zdirs, 1), UBOUND(zdirs, 1)
6627            ENDDO ! i = 1, ntrack
6628
6629            transparency(:) = 1._wp !-- Reset all rays to transparent
6630         ENDIF
6631
6632         !-- Forward direction of radiation (sky->face), always
6633         !--
6634         DO i = ntrack, 1, -1 ! for each column backwards
6635            dxxyy = ((dy*yxdir(1))**2 + (dx*yxdir(2))**2) * (rt2_track_dist(i)-rt2_track_dist(i-1))**2
6636            px = rt2_track(2,i)/nnx
6637            py = rt2_track(1,i)/nny
6638            ip = px*pdims(2)+py
6639
6640            DO k = LBOUND(zdirs, 1), UBOUND(zdirs, 1) ! for each ray
6641               IF ( zdirs(k) <= horizon )  THEN
6642                  transparency(k) = 0._wp
6643                  CYCLE
6644               ENDIF
6645
6646               zexit = REAL(origin(1), wp) + zdirs(k) * rt2_track_dist(i-1)
6647               IF ( zexit <= zbottom .OR. zexit >= ztop )  CYCLE
6648
6649               zsgn = -INT(SIGN(1._wp, zdirs(k)), iwp)
6650               rt2_dist(1) = 0._wp
6651               IF ( zdirs(k) == 0._wp )  THEN ! ray is exactly horizontal
6652                  nz = 2
6653                  rt2_dist(nz) = SQRT(dxxyy)
6654                  iz = NINT(zexit, iwp)
6655               ELSE
6656                  zorig = MIN(MAX(REAL(origin(1), wp) + zdirs(k) * rt2_track_dist(i), zbottom), ztop)
6657
6658                  zb0 = FLOOR(  zorig * zsgn - .5_wp) + 1  ! because it must be greater than orig
6659                  zb1 = CEILING(zexit * zsgn - .5_wp) - 1  ! because it must be smaller than exit
6660                  nz = MAX(zb1 - zb0 + 3, 2)
6661                  rt2_dist(nz) = SQRT(((zexit-zorig)*dz(1))**2 + dxxyy)
6662                  qdist = rt2_dist(nz) / (zexit-zorig)
6663                  rt2_dist(2:nz-1) = (/( ((REAL(l, wp) + .5_wp) * zsgn - zorig) * qdist , l = zb0, zb1 )/)
6664                  iz = zb0 * zsgn
6665               ENDIF
6666
6667               DO l = 2, nz
6668                  IF ( rt2_track_lad(iz, i) > 0._wp )  THEN
6669                     curtrans = exp(-ext_coef * rt2_track_lad(iz, i) * (rt2_dist(l)-rt2_dist(l-1)))
6670
6671                     IF ( create_csf )  THEN
6672                        ncsfl = ncsfl + 1
6673                        acsf(ncsfl)%ip = ip
6674                        acsf(ncsfl)%itx = rt2_track(2,i)
6675                        acsf(ncsfl)%ity = rt2_track(1,i)
6676                        acsf(ncsfl)%itz = iz
6677                        acsf(ncsfl)%isurfs = -1 ! a special ID indicating sky
6678                        acsf(ncsfl)%rsvf = REAL((1._wp - curtrans)*aorig*vffrac(k), wp) ! we postpone multiplication by transparency
6679                        acsf(ncsfl)%rtransp = REAL(transparency(k), wp)
6680                     ENDIF  !< create_csf
6681
6682                     transparency(k) = transparency(k) * curtrans
6683                  ENDIF
6684                  iz = iz + zsgn
6685               ENDDO ! l = 1, nz - 1
6686            ENDDO ! k = LBOUND(zdirs, 1), UBOUND(zdirs, 1)
6687         ENDDO ! i = 1, ntrack
6688
6689      ELSE ! not plant_canopy
6690         DO k = UBOUND(zdirs, 1), LBOUND(zdirs, 1), -1 ! TODO make more generic
6691            IF ( zdirs(k) > horizon )  EXIT
6692            transparency(k) = 0._wp
6693         ENDDO
6694      ENDIF
6695
6696   END SUBROUTINE raytrace_2d
6697 
6698
6699!------------------------------------------------------------------------------!
6700!
6701! Description:
6702! ------------
6703!> Calculates apparent solar positions for all timesteps and stores discretized
6704!> positions.
6705!------------------------------------------------------------------------------!
6706   SUBROUTINE radiation_presimulate_solar_pos
6707      IMPLICIT NONE
6708
6709      INTEGER(iwp)                              ::  it, i, j
6710      REAL(wp)                                  ::  tsrp_prev
6711      REAL(wp), DIMENSION(:,:), ALLOCATABLE     ::  dsidir_tmp       !< dsidir_tmp[:,i] = unit vector of i-th
6712                                                                     !< appreant solar direction
6713
6714      ALLOCATE ( dsidir_rev(0:raytrace_discrete_elevs/2-1,                 &
6715                            0:raytrace_discrete_azims-1) )
6716      dsidir_rev(:,:) = -1
6717      ALLOCATE ( dsidir_tmp(3,                                             &
6718                     raytrace_discrete_elevs/2*raytrace_discrete_azims) )
6719      ndsidir = 0
6720
6721!
6722!--   We will artificialy update time_since_reference_point and return to
6723!--   true value later
6724      tsrp_prev = time_since_reference_point
6725      sun_direction = .TRUE.
6726
6727!
6728!--   Process spinup time if configured
6729      IF ( spinup_time > 0._wp )  THEN
6730         DO  it = 0, CEILING(spinup_time / dt_spinup)
6731            time_since_reference_point = -spinup_time + REAL(it, wp) * dt_spinup
6732            CALL simulate_pos
6733         ENDDO
6734      ENDIF
6735!
6736!--   Process simulation time
6737      DO  it = 0, CEILING(( end_time - spinup_time ) / dt_radiation)
6738         time_since_reference_point = REAL(it, wp) * dt_radiation
6739         CALL simulate_pos
6740      ENDDO
6741
6742      time_since_reference_point = tsrp_prev
6743
6744!--   Allocate global vars which depend on ndsidir
6745      ALLOCATE ( dsidir ( 3, ndsidir ) )
6746      dsidir(:,:) = dsidir_tmp(:, 1:ndsidir)
6747      DEALLOCATE ( dsidir_tmp )
6748
6749      ALLOCATE ( dsitrans(nsurfl, ndsidir) )
6750      ALLOCATE ( dsitransc(npcbl, ndsidir) )
6751
6752      WRITE ( message_string, * ) 'Precalculated', ndsidir, ' solar positions', &
6753                                  'from', it, ' timesteps.'
6754      CALL message( 'radiation_presimulate_solar_pos', 'UI0013', 0, 0, 0, 6, 0 )
6755
6756      CONTAINS
6757
6758      !------------------------------------------------------------------------!
6759      ! Description:
6760      ! ------------
6761      !> Simuates a single position
6762      !------------------------------------------------------------------------!
6763      SUBROUTINE simulate_pos
6764         IMPLICIT NONE
6765!
6766!--      Update apparent solar position based on modified t_s_r_p
6767         CALL calc_zenith
6768         IF ( zenith(0) > 0 )  THEN
6769!--         
6770!--         Identify solar direction vector (discretized number) 1)
6771            i = MODULO(NINT(ATAN2(sun_dir_lon(0), sun_dir_lat(0))               &
6772                            / (2._wp*pi) * raytrace_discrete_azims-.5_wp, iwp), &
6773                       raytrace_discrete_azims)
6774            j = FLOOR(ACOS(zenith(0)) / pi * raytrace_discrete_elevs)
6775            IF ( dsidir_rev(j, i) == -1 )  THEN
6776               ndsidir = ndsidir + 1
6777               dsidir_tmp(:, ndsidir) =                                              &
6778                     (/ COS((REAL(j,wp)+.5_wp) * pi      / raytrace_discrete_elevs), &
6779                        SIN((REAL(j,wp)+.5_wp) * pi      / raytrace_discrete_elevs)  &
6780                      * COS((REAL(i,wp)+.5_wp) * 2_wp*pi / raytrace_discrete_azims), &
6781                        SIN((REAL(j,wp)+.5_wp) * pi      / raytrace_discrete_elevs)  &
6782                      * SIN((REAL(i,wp)+.5_wp) * 2_wp*pi / raytrace_discrete_azims) /)
6783               dsidir_rev(j, i) = ndsidir
6784            ENDIF
6785         ENDIF
6786      END SUBROUTINE simulate_pos
6787
6788   END SUBROUTINE radiation_presimulate_solar_pos
6789
6790
6791
6792!------------------------------------------------------------------------------!
6793! Description:
6794! ------------
6795!> Determines whether two faces are oriented towards each other. Since the
6796!> surfaces follow the gird box surfaces, it checks first whether the two surfaces
6797!> are directed in the same direction, then it checks if the two surfaces are
6798!> located in confronted direction but facing away from each other, e.g. <--| |-->
6799!------------------------------------------------------------------------------!
6800    PURE LOGICAL FUNCTION surface_facing(x, y, z, d, x2, y2, z2, d2)
6801        IMPLICIT NONE
6802        INTEGER(iwp),   INTENT(in)  :: x, y, z, d, x2, y2, z2, d2
6803     
6804        surface_facing = .FALSE.
6805
6806!-- first check: are the two surfaces directed in the same direction
6807        IF ( (d==iup_u  .OR.  d==iup_l  .OR.  d==iup_a )                             &
6808             .AND. (d2==iup_u  .OR. d2==iup_l) ) RETURN
6809        IF ( (d==isouth_u  .OR.  d==isouth_l  .OR.  d==isouth_a ) &
6810             .AND.  (d2==isouth_u  .OR.  d2==isouth_l) ) RETURN
6811        IF ( (d==inorth_u  .OR.  d==inorth_l  .OR.  d==inorth_a ) &
6812             .AND.  (d2==inorth_u  .OR.  d2==inorth_l) ) RETURN
6813        IF ( (d==iwest_u  .OR.  d==iwest_l  .OR.  d==iwest_a )     &
6814             .AND.  (d2==iwest_u  .OR.  d2==iwest_l ) ) RETURN
6815        IF ( (d==ieast_u  .OR.  d==ieast_l  .OR.  d==ieast_a )     &
6816             .AND.  (d2==ieast_u  .OR.  d2==ieast_l ) ) RETURN
6817
6818!-- second check: are surfaces facing away from each other
6819        SELECT CASE (d)
6820            CASE (iup_u, iup_l, iup_a)              !< upward facing surfaces
6821                IF ( z2 < z ) RETURN
6822            CASE (idown_a)                          !< downward facing surfaces
6823                IF ( z2 > z ) RETURN
6824            CASE (isouth_u, isouth_l, isouth_a)     !< southward facing surfaces
6825                IF ( y2 > y ) RETURN
6826            CASE (inorth_u, inorth_l, inorth_a)     !< northward facing surfaces
6827                IF ( y2 < y ) RETURN
6828            CASE (iwest_u, iwest_l, iwest_a)        !< westward facing surfaces
6829                IF ( x2 > x ) RETURN
6830            CASE (ieast_u, ieast_l, ieast_a)        !< eastward facing surfaces
6831                IF ( x2 < x ) RETURN
6832        END SELECT
6833
6834        SELECT CASE (d2)
6835            CASE (iup_u)                            !< ground, roof
6836                IF ( z < z2 ) RETURN
6837            CASE (isouth_u, isouth_l)               !< south facing
6838                IF ( y > y2 ) RETURN
6839            CASE (inorth_u, inorth_l)               !< north facing
6840                IF ( y < y2 ) RETURN
6841            CASE (iwest_u, iwest_l)                 !< west facing
6842                IF ( x > x2 ) RETURN
6843            CASE (ieast_u, ieast_l)                 !< east facing
6844                IF ( x < x2 ) RETURN
6845            CASE (-1)
6846                CONTINUE
6847        END SELECT
6848
6849        surface_facing = .TRUE.
6850       
6851    END FUNCTION surface_facing
6852
6853
6854!------------------------------------------------------------------------------!
6855!
6856! Description:
6857! ------------
6858!> Soubroutine reads svf and svfsurf data from saved file
6859!> SVF means sky view factors and CSF means canopy sink factors
6860!------------------------------------------------------------------------------!
6861    SUBROUTINE radiation_read_svf
6862
6863       IMPLICIT NONE
6864       
6865       CHARACTER(rad_version_len)   :: rad_version_field
6866       
6867       INTEGER(iwp)                 :: i
6868       INTEGER(iwp)                 :: ndsidir_from_file = 0
6869       INTEGER(iwp)                 :: npcbl_from_file = 0
6870       INTEGER(iwp)                 :: nsurfl_from_file = 0
6871       
6872       DO  i = 0, io_blocks-1
6873          IF ( i == io_group )  THEN
6874
6875!
6876!--          numprocs_previous_run is only known in case of reading restart
6877!--          data. If a new initial run which reads svf data is started the
6878!--          following query will be skipped
6879             IF ( initializing_actions == 'read_restart_data' ) THEN
6880
6881                IF ( numprocs_previous_run /= numprocs ) THEN
6882                   WRITE( message_string, * ) 'A different number of ',        &
6883                                              'processors between the run ',   &
6884                                              'that has written the svf data ',&
6885                                              'and the one that will read it ',&
6886                                              'is not allowed' 
6887                   CALL message( 'check_open', 'PA0491', 1, 2, 0, 6, 0 )
6888                ENDIF
6889
6890             ENDIF
6891             
6892!
6893!--          Open binary file
6894             CALL check_open( 88 )
6895
6896!
6897!--          read and check version
6898             READ ( 88 ) rad_version_field
6899             IF ( TRIM(rad_version_field) /= TRIM(rad_version) )  THEN
6900                 WRITE( message_string, * ) 'Version of binary SVF file "',    &
6901                             TRIM(rad_version_field), '" does not match ',     &
6902                             'the version of model "', TRIM(rad_version), '"'
6903                 CALL message( 'radiation_read_svf', 'PA0482', 1, 2, 0, 6, 0 )
6904             ENDIF
6905             
6906!
6907!--          read nsvfl, ncsfl, nsurfl
6908             READ ( 88 ) nsvfl, ncsfl, nsurfl_from_file, npcbl_from_file,      &
6909                         ndsidir_from_file
6910             
6911             IF ( nsvfl < 0  .OR.  ncsfl < 0 )  THEN
6912                 WRITE( message_string, * ) 'Wrong number of SVF or CSF'
6913                 CALL message( 'radiation_read_svf', 'PA0483', 1, 2, 0, 6, 0 )
6914             ELSE
6915                 WRITE(message_string,*) '    Number of SVF, CSF, and nsurfl ',&
6916                                         'to read', nsvfl, ncsfl,              &
6917                                         nsurfl_from_file
6918                 CALL location_message( message_string, .TRUE. )
6919             ENDIF
6920             
6921             IF ( nsurfl_from_file /= nsurfl )  THEN
6922                 WRITE( message_string, * ) 'nsurfl from SVF file does not ',  &
6923                                            'match calculated nsurfl from ',   &
6924                                            'radiation_interaction_init'
6925                 CALL message( 'radiation_read_svf', 'PA0490', 1, 2, 0, 6, 0 )
6926             ENDIF
6927             
6928             IF ( npcbl_from_file /= npcbl )  THEN
6929                 WRITE( message_string, * ) 'npcbl from SVF file does not ',   &
6930                                            'match calculated npcbl from ',    &
6931                                            'radiation_interaction_init'
6932                 CALL message( 'radiation_read_svf', 'PA0493', 1, 2, 0, 6, 0 )
6933             ENDIF
6934             
6935             IF ( ndsidir_from_file /= ndsidir )  THEN
6936                 WRITE( message_string, * ) 'ndsidir from SVF file does not ', &
6937                                            'match calculated ndsidir from ',  &
6938                                            'radiation_presimulate_solar_pos'
6939                 CALL message( 'radiation_read_svf', 'PA0494', 1, 2, 0, 6, 0 )
6940             ENDIF
6941             
6942!
6943!--          Arrays skyvf, skyvft, dsitrans and dsitransc are allready
6944!--          allocated in radiation_interaction_init and
6945!--          radiation_presimulate_solar_pos
6946             IF ( nsurfl > 0 )  THEN
6947                READ(88) skyvf
6948                READ(88) skyvft
6949                READ(88) dsitrans 
6950             ENDIF
6951             
6952             IF ( plant_canopy  .AND.  npcbl > 0 ) THEN
6953                READ ( 88 )  dsitransc
6954             ENDIF
6955             
6956!
6957!--          The allocation of svf, svfsurf, csf and csfsurf happens in routine
6958!--          radiation_calc_svf which is not called if the program enters
6959!--          radiation_read_svf. Therefore these arrays has to allocate in the
6960!--          following
6961             IF ( nsvfl > 0 )  THEN
6962                ALLOCATE( svf(ndsvf,nsvfl) )
6963                ALLOCATE( svfsurf(idsvf,nsvfl) )
6964                READ(88) svf
6965                READ(88) svfsurf
6966             ENDIF
6967
6968             IF ( plant_canopy  .AND.  ncsfl > 0 )  THEN
6969                ALLOCATE( csf(ndcsf,ncsfl) )
6970                ALLOCATE( csfsurf(idcsf,ncsfl) )
6971                READ(88) csf
6972                READ(88) csfsurf
6973             ENDIF
6974             
6975!
6976!--          Close binary file                 
6977             CALL close_file( 88 )
6978               
6979          ENDIF
6980#if defined( __parallel )
6981          CALL MPI_BARRIER( comm2d, ierr )
6982#endif
6983       ENDDO
6984
6985    END SUBROUTINE radiation_read_svf
6986
6987
6988!------------------------------------------------------------------------------!
6989!
6990! Description:
6991! ------------
6992!> Subroutine stores svf, svfsurf, csf and csfsurf data to a file.
6993!------------------------------------------------------------------------------!
6994    SUBROUTINE radiation_write_svf
6995
6996       IMPLICIT NONE
6997       
6998       INTEGER(iwp)        :: i
6999
7000       DO  i = 0, io_blocks-1
7001          IF ( i == io_group )  THEN
7002!
7003!--          Open binary file
7004             CALL check_open( 89 )
7005
7006             WRITE ( 89 )  rad_version
7007             WRITE ( 89 )  nsvfl, ncsfl, nsurfl, npcbl, ndsidir
7008             IF ( nsurfl > 0 ) THEN
7009                WRITE ( 89 )  skyvf
7010                WRITE ( 89 )  skyvft
7011                WRITE ( 89 )  dsitrans
7012             ENDIF
7013             IF ( npcbl > 0 ) THEN
7014                WRITE ( 89 )  dsitransc
7015             ENDIF
7016             IF ( nsvfl > 0 ) THEN
7017                WRITE ( 89 )  svf
7018                WRITE ( 89 )  svfsurf
7019             ENDIF
7020             IF ( plant_canopy  .AND.  ncsfl > 0 )  THEN
7021                 WRITE ( 89 )  csf
7022                 WRITE ( 89 )  csfsurf
7023             ENDIF
7024
7025!
7026!--          Close binary file                 
7027             CALL close_file( 89 )
7028
7029          ENDIF
7030#if defined( __parallel )
7031          CALL MPI_BARRIER( comm2d, ierr )
7032#endif
7033       ENDDO
7034    END SUBROUTINE radiation_write_svf
7035
7036!------------------------------------------------------------------------------!
7037!
7038! Description:
7039! ------------
7040!> Block of auxiliary subroutines:
7041!> 1. quicksort and corresponding comparison
7042!> 2. merge_and_grow_csf for implementation of "dynamical growing"
7043!>    array for csf
7044!------------------------------------------------------------------------------!
7045    PURE FUNCTION svf_lt(svf1,svf2) result (res)
7046      TYPE (t_svf), INTENT(in) :: svf1,svf2
7047      LOGICAL                  :: res
7048      IF ( svf1%isurflt < svf2%isurflt  .OR.    &
7049          (svf1%isurflt == svf2%isurflt  .AND.  svf1%isurfs < svf2%isurfs) )  THEN
7050          res = .TRUE.
7051      ELSE
7052          res = .FALSE.
7053      ENDIF
7054    END FUNCTION svf_lt
7055   
7056 
7057!-- quicksort.f -*-f90-*-
7058!-- Author: t-nissie, adaptation J.Resler
7059!-- License: GPLv3
7060!-- Gist: https://gist.github.com/t-nissie/479f0f16966925fa29ea
7061    RECURSIVE SUBROUTINE quicksort_svf(svfl, first, last)
7062        IMPLICIT NONE
7063        TYPE(t_svf), DIMENSION(:), INTENT(INOUT)  :: svfl
7064        INTEGER(iwp), INTENT(IN)                  :: first, last
7065        TYPE(t_svf)                               :: x, t
7066        INTEGER(iwp)                              :: i, j
7067
7068        IF ( first>=last ) RETURN
7069        x = svfl( (first+last) / 2 )
7070        i = first
7071        j = last
7072        DO
7073            DO while ( svf_lt(svfl(i),x) )
7074               i=i+1
7075            ENDDO
7076            DO while ( svf_lt(x,svfl(j)) )
7077                j=j-1
7078            ENDDO
7079            IF ( i >= j ) EXIT
7080            t = svfl(i);  svfl(i) = svfl(j);  svfl(j) = t
7081            i=i+1
7082            j=j-1
7083        ENDDO
7084        IF ( first < i-1 ) CALL quicksort_svf(svfl, first, i-1)
7085        IF ( j+1 < last )  CALL quicksort_svf(svfl, j+1, last)
7086    END SUBROUTINE quicksort_svf
7087
7088   
7089    PURE FUNCTION csf_lt(csf1,csf2) result (res)
7090      TYPE (t_csf), INTENT(in) :: csf1,csf2
7091      LOGICAL                  :: res
7092      IF ( csf1%ip < csf2%ip  .OR.    &
7093           (csf1%ip == csf2%ip  .AND.  csf1%itx < csf2%itx)  .OR.  &
7094           (csf1%ip == csf2%ip  .AND.  csf1%itx == csf2%itx  .AND.  csf1%ity < csf2%ity)  .OR.  &
7095           (csf1%ip == csf2%ip  .AND.  csf1%itx == csf2%itx  .AND.  csf1%ity == csf2%ity  .AND.   &
7096            csf1%itz < csf2%itz)  .OR.  &
7097           (csf1%ip == csf2%ip  .AND.  csf1%itx == csf2%itx  .AND.  csf1%ity == csf2%ity  .AND.   &
7098            csf1%itz == csf2%itz  .AND.  csf1%isurfs < csf2%isurfs) )  THEN
7099          res = .TRUE.
7100      ELSE
7101          res = .FALSE.
7102      ENDIF
7103    END FUNCTION csf_lt
7104
7105
7106!-- quicksort.f -*-f90-*-
7107!-- Author: t-nissie, adaptation J.Resler
7108!-- License: GPLv3
7109!-- Gist: https://gist.github.com/t-nissie/479f0f16966925fa29ea
7110    RECURSIVE SUBROUTINE quicksort_csf(csfl, first, last)
7111        IMPLICIT NONE
7112        TYPE(t_csf), DIMENSION(:), INTENT(INOUT)  :: csfl
7113        INTEGER(iwp), INTENT(IN)                  :: first, last
7114        TYPE(t_csf)                               :: x, t
7115        INTEGER(iwp)                              :: i, j
7116
7117        IF ( first>=last ) RETURN
7118        x = csfl( (first+last)/2 )
7119        i = first
7120        j = last
7121        DO
7122            DO while ( csf_lt(csfl(i),x) )
7123                i=i+1
7124            ENDDO
7125            DO while ( csf_lt(x,csfl(j)) )
7126                j=j-1
7127            ENDDO
7128            IF ( i >= j ) EXIT
7129            t = csfl(i);  csfl(i) = csfl(j);  csfl(j) = t
7130            i=i+1
7131            j=j-1
7132        ENDDO
7133        IF ( first < i-1 ) CALL quicksort_csf(csfl, first, i-1)
7134        IF ( j+1 < last )  CALL quicksort_csf(csfl, j+1, last)
7135    END SUBROUTINE quicksort_csf
7136
7137   
7138    SUBROUTINE merge_and_grow_csf(newsize)
7139        INTEGER(iwp), INTENT(in)                :: newsize  !< new array size after grow, must be >= ncsfl
7140                                                            !< or -1 to shrink to minimum
7141        INTEGER(iwp)                            :: iread, iwrite
7142        TYPE(t_csf), DIMENSION(:), POINTER      :: acsfnew
7143        CHARACTER(100)                          :: msg
7144
7145        IF ( newsize == -1 )  THEN
7146!--         merge in-place
7147            acsfnew => acsf
7148        ELSE
7149!--         allocate new array
7150            IF ( mcsf == 0 )  THEN
7151                ALLOCATE( acsf1(newsize) )
7152                acsfnew => acsf1
7153            ELSE
7154                ALLOCATE( acsf2(newsize) )
7155                acsfnew => acsf2
7156            ENDIF
7157        ENDIF
7158
7159        IF ( ncsfl >= 1 )  THEN
7160!--         sort csf in place (quicksort)
7161            CALL quicksort_csf(acsf,1,ncsfl)
7162
7163!--         while moving to a new array, aggregate canopy sink factor records with identical box & source
7164            acsfnew(1) = acsf(1)
7165            iwrite = 1
7166            DO iread = 2, ncsfl
7167!--             here acsf(kcsf) already has values from acsf(icsf)
7168                IF ( acsfnew(iwrite)%itx == acsf(iread)%itx &
7169                         .AND.  acsfnew(iwrite)%ity == acsf(iread)%ity &
7170                         .AND.  acsfnew(iwrite)%itz == acsf(iread)%itz &
7171                         .AND.  acsfnew(iwrite)%isurfs == acsf(iread)%isurfs )  THEN
7172!--                 We could simply take either first or second rtransp, both are valid. As a very simple heuristic about which ray
7173!--                 probably passes nearer the center of the target box, we choose DIF from the entry with greater CSF, since that
7174!--                 might mean that the traced beam passes longer through the canopy box.
7175                    IF ( acsfnew(iwrite)%rsvf < acsf(iread)%rsvf )  THEN
7176                        acsfnew(iwrite)%rtransp = acsf(iread)%rtransp
7177                    ENDIF
7178                    acsfnew(iwrite)%rsvf = acsfnew(iwrite)%rsvf + acsf(iread)%rsvf
7179!--                 advance reading index, keep writing index
7180                ELSE
7181!--                 not identical, just advance and copy
7182                    iwrite = iwrite + 1
7183                    acsfnew(iwrite) = acsf(iread)
7184                ENDIF
7185            ENDDO
7186            ncsfl = iwrite
7187        ENDIF
7188
7189        IF ( newsize == -1 )  THEN
7190!--         allocate new array and copy shrinked data
7191            IF ( mcsf == 0 )  THEN
7192                ALLOCATE( acsf1(ncsfl) )
7193                acsf1(1:ncsfl) = acsf2(1:ncsfl)
7194            ELSE
7195                ALLOCATE( acsf2(ncsfl) )
7196                acsf2(1:ncsfl) = acsf1(1:ncsfl)
7197            ENDIF
7198        ENDIF
7199
7200!--     deallocate old array
7201        IF ( mcsf == 0 )  THEN
7202            mcsf = 1
7203            acsf => acsf1
7204            DEALLOCATE( acsf2 )
7205        ELSE
7206            mcsf = 0
7207            acsf => acsf2
7208            DEALLOCATE( acsf1 )
7209        ENDIF
7210        ncsfla = newsize
7211
7212!         WRITE(msg,'(A,2I12)') 'Grow acsf2:',ncsfl,ncsfla
7213!         CALL radiation_write_debug_log( msg )
7214
7215    END SUBROUTINE merge_and_grow_csf
7216
7217   
7218!-- quicksort.f -*-f90-*-
7219!-- Author: t-nissie, adaptation J.Resler
7220!-- License: GPLv3
7221!-- Gist: https://gist.github.com/t-nissie/479f0f16966925fa29ea
7222    RECURSIVE SUBROUTINE quicksort_csf2(kpcsflt, pcsflt, first, last)
7223        IMPLICIT NONE
7224        INTEGER(iwp), DIMENSION(:,:), INTENT(INOUT)  :: kpcsflt
7225        REAL(wp), DIMENSION(:,:), INTENT(INOUT)      :: pcsflt
7226        INTEGER(iwp), INTENT(IN)                     :: first, last
7227        REAL(wp), DIMENSION(ndcsf)                   :: t2
7228        INTEGER(iwp), DIMENSION(kdcsf)               :: x, t1
7229        INTEGER(iwp)                                 :: i, j
7230
7231        IF ( first>=last ) RETURN
7232        x = kpcsflt(:, (first+last)/2 )
7233        i = first
7234        j = last
7235        DO
7236            DO while ( csf_lt2(kpcsflt(:,i),x) )
7237                i=i+1
7238            ENDDO
7239            DO while ( csf_lt2(x,kpcsflt(:,j)) )
7240                j=j-1
7241            ENDDO
7242            IF ( i >= j ) EXIT
7243            t1 = kpcsflt(:,i);  kpcsflt(:,i) = kpcsflt(:,j);  kpcsflt(:,j) = t1
7244            t2 = pcsflt(:,i);  pcsflt(:,i) = pcsflt(:,j);  pcsflt(:,j) = t2
7245            i=i+1
7246            j=j-1
7247        ENDDO
7248        IF ( first < i-1 ) CALL quicksort_csf2(kpcsflt, pcsflt, first, i-1)
7249        IF ( j+1 < last )  CALL quicksort_csf2(kpcsflt, pcsflt, j+1, last)
7250    END SUBROUTINE quicksort_csf2
7251   
7252
7253    PURE FUNCTION csf_lt2(item1, item2) result(res)
7254        INTEGER(iwp), DIMENSION(kdcsf), INTENT(in)  :: item1, item2
7255        LOGICAL                                     :: res
7256        res = ( (item1(3) < item2(3))                                                        &
7257             .OR.  (item1(3) == item2(3)  .AND.  item1(2) < item2(2))                            &
7258             .OR.  (item1(3) == item2(3)  .AND.  item1(2) == item2(2)  .AND.  item1(1) < item2(1)) &
7259             .OR.  (item1(3) == item2(3)  .AND.  item1(2) == item2(2)  .AND.  item1(1) == item2(1) &
7260                 .AND.  item1(4) < item2(4)) )
7261    END FUNCTION csf_lt2
7262
7263    PURE FUNCTION searchsorted(athresh, val) result(ind)
7264        REAL(wp), DIMENSION(:), INTENT(IN)  :: athresh
7265        REAL(wp), INTENT(IN)                :: val
7266        INTEGER(iwp)                        :: ind
7267        INTEGER(iwp)                        :: i
7268
7269        DO i = LBOUND(athresh, 1), UBOUND(athresh, 1)
7270            IF ( val < athresh(i) ) THEN
7271                ind = i - 1
7272                RETURN
7273            ENDIF
7274        ENDDO
7275        ind = UBOUND(athresh, 1)
7276    END FUNCTION searchsorted
7277
7278!------------------------------------------------------------------------------!
7279! Description:
7280! ------------
7281!
7282!> radiation_radflux_gridbox subroutine gives the sw and lw radiation fluxes at the
7283!> faces of a gridbox defined at i,j,k and located in the urban layer.
7284!> The total sw and the diffuse sw radiation as well as the lw radiation fluxes at
7285!> the gridbox 6 faces are stored in sw_gridbox, swd_gridbox, and lw_gridbox arrays,
7286!> respectively, in the following order:
7287!>  up_face, down_face, north_face, south_face, east_face, west_face
7288!>
7289!> The subroutine reports also how successful was the search process via the parameter
7290!> i_feedback as follow:
7291!> - i_feedback =  1 : successful
7292!> - i_feedback = -1 : unsuccessful; the requisted point is outside the urban domain
7293!> - i_feedback =  0 : uncomplete; some gridbox faces fluxes are missing
7294!>
7295!>
7296!> It is called outside from usm_urban_surface_mod whenever the radiation fluxes
7297!> are needed.
7298!>
7299!> TODO:
7300!>    - Compare performance when using some combination of the Fortran intrinsic
7301!>      functions, e.g. MINLOC, MAXLOC, ALL, ANY and COUNT functions, which search
7302!>      surfl array for elements meeting user-specified criterion, i.e. i,j,k
7303!>    - Report non-found or incomplete radiation fluxes arrays , if any, at the
7304!>      gridbox faces in an error message form
7305!>
7306!------------------------------------------------------------------------------!
7307    SUBROUTINE radiation_radflux_gridbox(i,j,k,sw_gridbox,swd_gridbox,lw_gridbox,i_feedback)
7308       
7309        IMPLICIT NONE
7310
7311        INTEGER(iwp),                 INTENT(in)  :: i,j,k                 !< gridbox indices at which fluxes are required
7312        INTEGER(iwp)                              :: ii,jj,kk,d            !< surface indices and type
7313        INTEGER(iwp)                              :: l                     !< surface id
7314        REAL(wp)    , DIMENSION(1:6), INTENT(out) :: sw_gridbox,lw_gridbox !< total sw and lw radiation fluxes of 6 faces of a gridbox, w/m2
7315        REAL(wp)    , DIMENSION(1:6), INTENT(out) :: swd_gridbox           !< diffuse sw radiation from sky and model boundary of 6 faces of a gridbox, w/m2
7316        INTEGER(iwp),                 INTENT(out) :: i_feedback            !< feedback to report how the search was successful
7317
7318
7319!-- initialize variables
7320        i_feedback  = -999999
7321        sw_gridbox  = -999999.9_wp
7322        lw_gridbox  = -999999.9_wp
7323        swd_gridbox = -999999.9_wp
7324       
7325!-- check the requisted grid indices
7326        IF ( k < nzb   .OR.  k > nzut  .OR.   &
7327             j < nysg  .OR.  j > nyng  .OR.   &
7328             i < nxlg  .OR.  i > nxrg         &
7329             ) THEN
7330           i_feedback = -1
7331           RETURN
7332        ENDIF
7333
7334!-- search for the required grid and formulate the fluxes at the 6 gridbox faces
7335        DO l = 1, nsurfl
7336            ii = surfl(ix,l)
7337            jj = surfl(iy,l)
7338            kk = surfl(iz,l)
7339
7340            IF ( ii == i  .AND.  jj == j  .AND.  kk == k ) THEN
7341               d = surfl(id,l)
7342
7343               SELECT CASE ( d )
7344
7345               CASE (iup_u,iup_l,iup_a)                    !- gridbox up_facing face
7346                  sw_gridbox(1) = surfinsw(l)
7347                  lw_gridbox(1) = surfinlw(l)
7348                  swd_gridbox(1) = surfinswdif(l)
7349
7350               CASE (idown_a)                         !- gridbox down_facing face
7351                  sw_gridbox(2) = surfinsw(l)
7352                  lw_gridbox(2) = surfinlw(l)
7353                  swd_gridbox(2) = surfinswdif(l)
7354
7355               CASE (inorth_u,inorth_l,inorth_a)  !- gridbox north_facing face
7356                  sw_gridbox(3) = surfinsw(l)
7357                  lw_gridbox(3) = surfinlw(l)
7358                  swd_gridbox(3) = surfinswdif(l)
7359
7360               CASE (isouth_u,isouth_l,isouth_a)  !- gridbox south_facing face
7361                  sw_gridbox(4) = surfinsw(l)
7362                  lw_gridbox(4) = surfinlw(l)
7363                  swd_gridbox(4) = surfinswdif(l)
7364
7365               CASE (ieast_u,ieast_l,ieast_a)      !- gridbox east_facing face
7366                  sw_gridbox(5) = surfinsw(l)
7367                  lw_gridbox(5) = surfinlw(l)
7368                  swd_gridbox(5) = surfinswdif(l)
7369
7370               CASE (iwest_u,iwest_l,iwest_a)      !- gridbox west_facing face
7371                  sw_gridbox(6) = surfinsw(l)
7372                  lw_gridbox(6) = surfinlw(l)
7373                  swd_gridbox(6) = surfinswdif(l)
7374
7375               END SELECT
7376
7377            ENDIF
7378
7379        IF ( ALL( sw_gridbox(:)  /= -999999.9_wp )  ) EXIT
7380        ENDDO
7381
7382!-- check the completeness of the fluxes at all gidbox faces       
7383!-- TODO: report non-found or incomplete rad fluxes arrays in an error message form
7384        IF ( ANY( sw_gridbox(:)  <= -999999.9_wp )  .OR.   &
7385             ANY( swd_gridbox(:) <= -999999.9_wp )  .OR.   &
7386             ANY( lw_gridbox(:)  <= -999999.9_wp ) ) THEN
7387           i_feedback = 0
7388        ELSE
7389           i_feedback = 1
7390        ENDIF
7391       
7392        RETURN
7393       
7394    END SUBROUTINE radiation_radflux_gridbox
7395
7396!------------------------------------------------------------------------------!
7397!
7398! Description:
7399! ------------
7400!> Subroutine for averaging 3D data
7401!------------------------------------------------------------------------------!
7402SUBROUTINE radiation_3d_data_averaging( mode, variable )
7403 
7404
7405    USE control_parameters
7406
7407    USE indices
7408
7409    USE kinds
7410
7411    IMPLICIT NONE
7412
7413    CHARACTER (LEN=*) ::  mode    !<
7414    CHARACTER (LEN=*) :: variable !<
7415
7416    INTEGER(iwp) ::  i !<
7417    INTEGER(iwp) ::  j !<
7418    INTEGER(iwp) ::  k !<
7419    INTEGER(iwp) ::  m !< index of current surface element
7420
7421    IF ( mode == 'allocate' )  THEN
7422
7423       SELECT CASE ( TRIM( variable ) )
7424
7425             CASE ( 'rad_net*' )
7426                IF ( .NOT. ALLOCATED( rad_net_av ) )  THEN
7427                   ALLOCATE( rad_net_av(nysg:nyng,nxlg:nxrg) )
7428                ENDIF
7429                rad_net_av = 0.0_wp
7430             
7431             CASE ( 'rad_lw_in*' )
7432                IF ( .NOT. ALLOCATED( rad_lw_in_xy_av ) )  THEN
7433                   ALLOCATE( rad_lw_in_xy_av(nysg:nyng,nxlg:nxrg) )
7434                ENDIF
7435                rad_lw_in_xy_av = 0.0_wp
7436               
7437             CASE ( 'rad_lw_out*' )
7438                IF ( .NOT. ALLOCATED( rad_lw_out_xy_av ) )  THEN
7439                   ALLOCATE( rad_lw_out_xy_av(nysg:nyng,nxlg:nxrg) )
7440                ENDIF
7441                rad_lw_out_xy_av = 0.0_wp
7442               
7443             CASE ( 'rad_sw_in*' )
7444                IF ( .NOT. ALLOCATED( rad_sw_in_xy_av ) )  THEN
7445                   ALLOCATE( rad_sw_in_xy_av(nysg:nyng,nxlg:nxrg) )
7446                ENDIF
7447                rad_sw_in_xy_av = 0.0_wp
7448               
7449             CASE ( 'rad_sw_out*' )
7450                IF ( .NOT. ALLOCATED( rad_sw_out_xy_av ) )  THEN
7451                   ALLOCATE( rad_sw_out_xy_av(nysg:nyng,nxlg:nxrg) )
7452                ENDIF
7453                rad_sw_out_xy_av = 0.0_wp               
7454
7455             CASE ( 'rad_lw_in' )
7456                IF ( .NOT. ALLOCATED( rad_lw_in_av ) )  THEN
7457                   ALLOCATE( rad_lw_in_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
7458                ENDIF
7459                rad_lw_in_av = 0.0_wp
7460
7461             CASE ( 'rad_lw_out' )
7462                IF ( .NOT. ALLOCATED( rad_lw_out_av ) )  THEN
7463                   ALLOCATE( rad_lw_in_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
7464                ENDIF
7465                rad_lw_out_av = 0.0_wp
7466
7467             CASE ( 'rad_lw_cs_hr' )
7468                IF ( .NOT. ALLOCATED( rad_lw_cs_hr_av ) )  THEN
7469                   ALLOCATE( rad_lw_cs_hr_av(nzb+1:nzt+1,nysg:nyng,nxlg:nxrg) )
7470                ENDIF
7471                rad_lw_cs_hr_av = 0.0_wp
7472
7473             CASE ( 'rad_lw_hr' )
7474                IF ( .NOT. ALLOCATED( rad_lw_hr_av ) )  THEN
7475                   ALLOCATE( rad_lw_hr_av(nzb+1:nzt+1,nysg:nyng,nxlg:nxrg) )
7476                ENDIF
7477                rad_lw_hr_av = 0.0_wp
7478
7479             CASE ( 'rad_sw_in' )
7480                IF ( .NOT. ALLOCATED( rad_sw_in_av ) )  THEN
7481                   ALLOCATE( rad_sw_in_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
7482                ENDIF
7483                rad_sw_in_av = 0.0_wp
7484
7485             CASE ( 'rad_sw_out' )
7486                IF ( .NOT. ALLOCATED( rad_sw_out_av ) )  THEN
7487                   ALLOCATE( rad_sw_out_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
7488                ENDIF
7489                rad_sw_out_av = 0.0_wp
7490
7491             CASE ( 'rad_sw_cs_hr' )
7492                IF ( .NOT. ALLOCATED( rad_sw_cs_hr_av ) )  THEN
7493                   ALLOCATE( rad_sw_cs_hr_av(nzb+1:nzt+1,nysg:nyng,nxlg:nxrg) )
7494                ENDIF
7495                rad_sw_cs_hr_av = 0.0_wp
7496
7497             CASE ( 'rad_sw_hr' )
7498                IF ( .NOT. ALLOCATED( rad_sw_hr_av ) )  THEN
7499                   ALLOCATE( rad_sw_hr_av(nzb+1:nzt+1,nysg:nyng,nxlg:nxrg) )
7500                ENDIF
7501                rad_sw_hr_av = 0.0_wp
7502
7503          CASE DEFAULT
7504             CONTINUE
7505
7506       END SELECT
7507
7508    ELSEIF ( mode == 'sum' )  THEN
7509
7510       SELECT CASE ( TRIM( variable ) )
7511
7512          CASE ( 'rad_net*' )
7513             IF ( ALLOCATED( rad_net_av ) ) THEN
7514                DO  i = nxl, nxr
7515                   DO  j = nys, nyn
7516                      DO m = surf_lsm_h%start_index(j,i),                      &
7517                             surf_lsm_h%end_index(j,i)
7518                         rad_net_av(j,i) = rad_net_av(j,i) +                   &
7519                                           surf_lsm_h%rad_net(m)
7520                      ENDDO
7521                      DO m = surf_usm_h%start_index(j,i),                      &
7522                             surf_usm_h%end_index(j,i)
7523                         rad_net_av(j,i) = rad_net_av(j,i) +                   &
7524                                           surf_usm_h%rad_net(m)
7525                      ENDDO
7526                   ENDDO
7527                ENDDO
7528             ENDIF
7529
7530          CASE ( 'rad_lw_in*' )
7531             IF ( ALLOCATED( rad_lw_in_xy_av ) ) THEN
7532                DO  i = nxl, nxr
7533                   DO  j = nys, nyn
7534                      DO m = surf_lsm_h%start_index(j,i),                      &
7535                             surf_lsm_h%end_index(j,i)
7536                         rad_lw_in_xy_av(j,i) = rad_lw_in_xy_av(j,i) +         &
7537                                                surf_lsm_h%rad_lw_in(m)
7538                      ENDDO
7539                      DO m = surf_usm_h%start_index(j,i),                      &
7540                             surf_usm_h%end_index(j,i)
7541                         rad_lw_in_xy_av(j,i) = rad_lw_in_xy_av(j,i) +         &
7542                                                surf_usm_h%rad_lw_in(m)
7543                      ENDDO
7544                   ENDDO
7545                ENDDO
7546             ENDIF
7547             
7548          CASE ( 'rad_lw_out*' )
7549             IF ( ALLOCATED( rad_lw_out_xy_av ) ) THEN
7550                DO  i = nxl, nxr
7551                   DO  j = nys, nyn
7552                      DO m = surf_lsm_h%start_index(j,i),                      &
7553                             surf_lsm_h%end_index(j,i)
7554                         rad_lw_out_xy_av(j,i) = rad_lw_out_xy_av(j,i) +       &
7555                                                   surf_lsm_h%rad_lw_out(m)
7556                      ENDDO
7557                      DO m = surf_usm_h%start_index(j,i),                      &
7558                             surf_usm_h%end_index(j,i)
7559                         rad_lw_out_xy_av(j,i) = rad_lw_out_xy_av(j,i) +       &
7560                                                  surf_usm_h%rad_lw_out(m)
7561                      ENDDO
7562                   ENDDO
7563                ENDDO
7564             ENDIF
7565             
7566          CASE ( 'rad_sw_in*' )
7567             IF ( ALLOCATED( rad_sw_in_xy_av ) ) THEN
7568                DO  i = nxl, nxr
7569                   DO  j = nys, nyn
7570                      DO m = surf_lsm_h%start_index(j,i),                      &
7571                             surf_lsm_h%end_index(j,i)
7572                         rad_sw_in_xy_av(j,i) = rad_sw_in_xy_av(j,i) +         &
7573                                                  surf_lsm_h%rad_sw_in(m)
7574                      ENDDO
7575                      DO m = surf_usm_h%start_index(j,i),                      &
7576                             surf_usm_h%end_index(j,i)
7577                         rad_sw_in_xy_av(j,i) = rad_sw_in_xy_av(j,i) +         &
7578                                                surf_usm_h%rad_sw_in(m)
7579                      ENDDO
7580                   ENDDO
7581                ENDDO
7582             ENDIF
7583             
7584          CASE ( 'rad_sw_out*' )
7585             IF ( ALLOCATED( rad_sw_out_xy_av ) ) THEN
7586                DO  i = nxl, nxr
7587                   DO  j = nys, nyn
7588                      DO m = surf_lsm_h%start_index(j,i),                      &
7589                             surf_lsm_h%end_index(j,i)
7590                         rad_sw_out_xy_av(j,i) = rad_sw_out_xy_av(j,i) +       &
7591                                                   surf_lsm_h%rad_sw_out(m)
7592                      ENDDO
7593                      DO m = surf_usm_h%start_index(j,i),                      &
7594                             surf_usm_h%end_index(j,i)
7595                         rad_sw_out_xy_av(j,i) = rad_sw_out_xy_av(j,i) +       &
7596                                                   surf_usm_h%rad_sw_out(m)
7597                      ENDDO
7598                   ENDDO
7599                ENDDO
7600             ENDIF
7601             
7602          CASE ( 'rad_lw_in' )
7603             IF ( ALLOCATED( rad_lw_in_av ) ) THEN
7604                DO  i = nxlg, nxrg
7605                   DO  j = nysg, nyng
7606                      DO  k = nzb, nzt+1
7607                         rad_lw_in_av(k,j,i) = rad_lw_in_av(k,j,i)             &
7608                                               + rad_lw_in(k,j,i)
7609                      ENDDO
7610                   ENDDO
7611                ENDDO
7612             ENDIF
7613
7614          CASE ( 'rad_lw_out' )
7615             IF ( ALLOCATED( rad_lw_out_av ) ) THEN
7616                DO  i = nxlg, nxrg
7617                   DO  j = nysg, nyng
7618                      DO  k = nzb, nzt+1
7619                         rad_lw_out_av(k,j,i) = rad_lw_out_av(k,j,i)           &
7620                                                + rad_lw_out(k,j,i)
7621                      ENDDO
7622                   ENDDO
7623                ENDDO
7624             ENDIF
7625
7626          CASE ( 'rad_lw_cs_hr' )
7627             IF ( ALLOCATED( rad_lw_cs_hr_av ) ) THEN
7628                DO  i = nxlg, nxrg
7629                   DO  j = nysg, nyng
7630                      DO  k = nzb, nzt+1
7631                         rad_lw_cs_hr_av(k,j,i) = rad_lw_cs_hr_av(k,j,i)       &
7632                                                  + rad_lw_cs_hr(k,j,i)
7633                      ENDDO
7634                   ENDDO
7635                ENDDO
7636             ENDIF
7637
7638          CASE ( 'rad_lw_hr' )
7639             IF ( ALLOCATED( rad_lw_hr_av ) ) THEN
7640                DO  i = nxlg, nxrg
7641                   DO  j = nysg, nyng
7642                      DO  k = nzb, nzt+1
7643                         rad_lw_hr_av(k,j,i) = rad_lw_hr_av(k,j,i)             &
7644                                               + rad_lw_hr(k,j,i)
7645                      ENDDO
7646                   ENDDO
7647                ENDDO
7648             ENDIF
7649
7650          CASE ( 'rad_sw_in' )
7651             IF ( ALLOCATED( rad_sw_in_av ) ) THEN
7652                DO  i = nxlg, nxrg
7653                   DO  j = nysg, nyng
7654                      DO  k = nzb, nzt+1
7655                         rad_sw_in_av(k,j,i) = rad_sw_in_av(k,j,i)             &
7656                                               + rad_sw_in(k,j,i)
7657                      ENDDO
7658                   ENDDO
7659                ENDDO
7660             ENDIF
7661
7662          CASE ( 'rad_sw_out' )
7663             IF ( ALLOCATED( rad_sw_out_av ) ) THEN
7664                DO  i = nxlg, nxrg
7665                   DO  j = nysg, nyng
7666                      DO  k = nzb, nzt+1
7667                         rad_sw_out_av(k,j,i) = rad_sw_out_av(k,j,i)           &
7668                                                + rad_sw_out(k,j,i)
7669                      ENDDO
7670                   ENDDO
7671                ENDDO
7672             ENDIF
7673
7674          CASE ( 'rad_sw_cs_hr' )
7675             IF ( ALLOCATED( rad_sw_cs_hr_av ) ) THEN
7676                DO  i = nxlg, nxrg
7677                   DO  j = nysg, nyng
7678                      DO  k = nzb, nzt+1
7679                         rad_sw_cs_hr_av(k,j,i) = rad_sw_cs_hr_av(k,j,i)       &
7680                                                  + rad_sw_cs_hr(k,j,i)
7681                      ENDDO
7682                   ENDDO
7683                ENDDO
7684             ENDIF
7685
7686          CASE ( 'rad_sw_hr' )
7687             IF ( ALLOCATED( rad_sw_hr_av ) ) THEN
7688                DO  i = nxlg, nxrg
7689                   DO  j = nysg, nyng
7690                      DO  k = nzb, nzt+1
7691                         rad_sw_hr_av(k,j,i) = rad_sw_hr_av(k,j,i)             &
7692                                               + rad_sw_hr(k,j,i)
7693                      ENDDO
7694                   ENDDO
7695                ENDDO
7696             ENDIF
7697
7698          CASE DEFAULT
7699             CONTINUE
7700
7701       END SELECT
7702
7703    ELSEIF ( mode == 'average' )  THEN
7704
7705       SELECT CASE ( TRIM( variable ) )
7706
7707         CASE ( 'rad_net*' )
7708             IF ( ALLOCATED( rad_net_av ) ) THEN
7709                DO  i = nxlg, nxrg
7710                   DO  j = nysg, nyng
7711                      rad_net_av(j,i) = rad_net_av(j,i)                        &
7712                                        / REAL( average_count_3d, KIND=wp )
7713                   ENDDO
7714                ENDDO
7715             ENDIF
7716             
7717          CASE ( 'rad_lw_in*' )
7718             IF ( ALLOCATED( rad_lw_in_xy_av ) ) THEN
7719                DO  i = nxlg, nxrg
7720                   DO  j = nysg, nyng
7721                      rad_lw_in_xy_av(j,i) = rad_lw_in_xy_av(j,i)              &
7722                                        / REAL( average_count_3d, KIND=wp )
7723                   ENDDO
7724                ENDDO
7725             ENDIF
7726             
7727          CASE ( 'rad_lw_out*' )
7728             IF ( ALLOCATED( rad_lw_out_xy_av ) ) THEN
7729                DO  i = nxlg, nxrg
7730                   DO  j = nysg, nyng
7731                      rad_lw_out_xy_av(j,i) = rad_lw_out_xy_av(j,i)            &
7732                                        / REAL( average_count_3d, KIND=wp )
7733                   ENDDO
7734                ENDDO
7735             ENDIF
7736             
7737          CASE ( 'rad_sw_in*' )
7738             IF ( ALLOCATED( rad_sw_in_xy_av ) ) THEN
7739                DO  i = nxlg, nxrg
7740                   DO  j = nysg, nyng
7741                      rad_sw_in_xy_av(j,i) = rad_sw_in_xy_av(j,i)              &
7742                                        / REAL( average_count_3d, KIND=wp )
7743                   ENDDO
7744                ENDDO
7745             ENDIF
7746             
7747          CASE ( 'rad_sw_out*' )
7748             IF ( ALLOCATED( rad_sw_out_xy_av ) ) THEN
7749                DO  i = nxlg, nxrg
7750                   DO  j = nysg, nyng
7751                      rad_sw_out_xy_av(j,i) = rad_sw_out_xy_av(j,i)             &
7752                                        / REAL( average_count_3d, KIND=wp )
7753                   ENDDO
7754                ENDDO
7755             ENDIF
7756
7757          CASE ( 'rad_lw_in' )
7758             IF ( ALLOCATED( rad_lw_in_av ) ) THEN
7759                DO  i = nxlg, nxrg
7760                   DO  j = nysg, nyng
7761                      DO  k = nzb, nzt+1
7762                         rad_lw_in_av(k,j,i) = rad_lw_in_av(k,j,i)             &
7763                                               / REAL( average_count_3d, KIND=wp )
7764                      ENDDO
7765                   ENDDO
7766                ENDDO
7767             ENDIF
7768
7769          CASE ( 'rad_lw_out' )
7770             IF ( ALLOCATED( rad_lw_out_av ) ) THEN
7771                DO  i = nxlg, nxrg
7772                   DO  j = nysg, nyng
7773                      DO  k = nzb, nzt+1
7774                         rad_lw_out_av(k,j,i) = rad_lw_out_av(k,j,i)           &
7775                                                / REAL( average_count_3d, KIND=wp )
7776                      ENDDO
7777                   ENDDO
7778                ENDDO
7779             ENDIF
7780
7781          CASE ( 'rad_lw_cs_hr' )
7782             IF ( ALLOCATED( rad_lw_cs_hr_av ) ) THEN
7783                DO  i = nxlg, nxrg
7784                   DO  j = nysg, nyng
7785                      DO  k = nzb, nzt+1
7786                         rad_lw_cs_hr_av(k,j,i) = rad_lw_cs_hr_av(k,j,i)       &
7787                                                / REAL( average_count_3d, KIND=wp )
7788                      ENDDO
7789                   ENDDO
7790                ENDDO
7791             ENDIF
7792
7793          CASE ( 'rad_lw_hr' )
7794             IF ( ALLOCATED( rad_lw_hr_av ) ) THEN
7795                DO  i = nxlg, nxrg
7796                   DO  j = nysg, nyng
7797                      DO  k = nzb, nzt+1
7798                         rad_lw_hr_av(k,j,i) = rad_lw_hr_av(k,j,i)             &
7799                                               / REAL( average_count_3d, KIND=wp )
7800                      ENDDO
7801                   ENDDO
7802                ENDDO
7803             ENDIF
7804
7805          CASE ( 'rad_sw_in' )
7806             IF ( ALLOCATED( rad_sw_in_av ) ) THEN
7807                DO  i = nxlg, nxrg
7808                   DO  j = nysg, nyng
7809                      DO  k = nzb, nzt+1
7810                         rad_sw_in_av(k,j,i) = rad_sw_in_av(k,j,i)             &
7811                                               / REAL( average_count_3d, KIND=wp )
7812                      ENDDO
7813                   ENDDO
7814                ENDDO
7815             ENDIF
7816
7817          CASE ( 'rad_sw_out' )
7818             IF ( ALLOCATED( rad_sw_out_av ) ) THEN
7819                DO  i = nxlg, nxrg
7820                   DO  j = nysg, nyng
7821                      DO  k = nzb, nzt+1
7822                         rad_sw_out_av(k,j,i) = rad_sw_out_av(k,j,i)           &
7823                                                / REAL( average_count_3d, KIND=wp )
7824                      ENDDO
7825                   ENDDO
7826                ENDDO
7827             ENDIF
7828
7829          CASE ( 'rad_sw_cs_hr' )
7830             IF ( ALLOCATED( rad_sw_cs_hr_av ) ) THEN
7831                DO  i = nxlg, nxrg
7832                   DO  j = nysg, nyng
7833                      DO  k = nzb, nzt+1
7834                         rad_sw_cs_hr_av(k,j,i) = rad_sw_cs_hr_av(k,j,i)       &
7835                                                / REAL( average_count_3d, KIND=wp )
7836                      ENDDO
7837                   ENDDO
7838                ENDDO
7839             ENDIF
7840
7841          CASE ( 'rad_sw_hr' )
7842             IF ( ALLOCATED( rad_sw_hr_av ) ) THEN
7843                DO  i = nxlg, nxrg
7844                   DO  j = nysg, nyng
7845                      DO  k = nzb, nzt+1
7846                         rad_sw_hr_av(k,j,i) = rad_sw_hr_av(k,j,i)             &
7847                                               / REAL( average_count_3d, KIND=wp )
7848                      ENDDO
7849                   ENDDO
7850                ENDDO
7851             ENDIF
7852
7853       END SELECT
7854
7855    ENDIF
7856
7857END SUBROUTINE radiation_3d_data_averaging
7858
7859
7860!------------------------------------------------------------------------------!
7861!
7862! Description:
7863! ------------
7864!> Subroutine defining appropriate grid for netcdf variables.
7865!> It is called out from subroutine netcdf.
7866!------------------------------------------------------------------------------!
7867SUBROUTINE radiation_define_netcdf_grid( var, found, grid_x, grid_y, grid_z )
7868   
7869    IMPLICIT NONE
7870
7871    CHARACTER (LEN=*), INTENT(IN)  ::  var         !<
7872    LOGICAL, INTENT(OUT)           ::  found       !<
7873    CHARACTER (LEN=*), INTENT(OUT) ::  grid_x      !<
7874    CHARACTER (LEN=*), INTENT(OUT) ::  grid_y      !<
7875    CHARACTER (LEN=*), INTENT(OUT) ::  grid_z      !<
7876
7877    found  = .TRUE.
7878
7879
7880!
7881!-- Check for the grid
7882    SELECT CASE ( TRIM( var ) )
7883
7884       CASE ( 'rad_lw_cs_hr', 'rad_lw_hr', 'rad_sw_cs_hr', 'rad_sw_hr',        &
7885              'rad_lw_cs_hr_xy', 'rad_lw_hr_xy', 'rad_sw_cs_hr_xy',            &
7886              'rad_sw_hr_xy', 'rad_lw_cs_hr_xz', 'rad_lw_hr_xz',               &
7887              'rad_sw_cs_hr_xz', 'rad_sw_hr_xz', 'rad_lw_cs_hr_yz',            &
7888              'rad_lw_hr_yz', 'rad_sw_cs_hr_yz', 'rad_sw_hr_yz' )
7889          grid_x = 'x'
7890          grid_y = 'y'
7891          grid_z = 'zu'
7892
7893       CASE ( 'rad_lw_in', 'rad_lw_out', 'rad_sw_in', 'rad_sw_out',            &
7894              'rad_lw_in_xy', 'rad_lw_out_xy', 'rad_sw_in_xy','rad_sw_out_xy', &
7895              'rad_lw_in_xz', 'rad_lw_out_xz', 'rad_sw_in_xz','rad_sw_out_xz', &
7896              'rad_lw_in_yz', 'rad_lw_out_yz', 'rad_sw_in_yz','rad_sw_out_yz' )
7897          grid_x = 'x'
7898          grid_y = 'y'
7899          grid_z = 'zw'
7900
7901
7902       CASE DEFAULT
7903          found  = .FALSE.
7904          grid_x = 'none'
7905          grid_y = 'none'
7906          grid_z = 'none'
7907
7908        END SELECT
7909
7910    END SUBROUTINE radiation_define_netcdf_grid
7911
7912!------------------------------------------------------------------------------!
7913!
7914! Description:
7915! ------------
7916!> Subroutine defining 3D output variables
7917!------------------------------------------------------------------------------!
7918 SUBROUTINE radiation_data_output_2d( av, variable, found, grid, mode,         &
7919                                      local_pf, two_d, nzb_do, nzt_do )
7920 
7921    USE indices
7922
7923    USE kinds
7924
7925
7926    IMPLICIT NONE
7927
7928    CHARACTER (LEN=*) ::  grid     !<
7929    CHARACTER (LEN=*) ::  mode     !<
7930    CHARACTER (LEN=*) ::  variable !<
7931
7932    INTEGER(iwp) ::  av !<
7933    INTEGER(iwp) ::  i  !<
7934    INTEGER(iwp) ::  j  !<
7935    INTEGER(iwp) ::  k  !<
7936    INTEGER(iwp) ::  m  !< index of surface element at grid point (j,i)
7937    INTEGER(iwp) ::  nzb_do   !<
7938    INTEGER(iwp) ::  nzt_do   !<
7939
7940    LOGICAL      ::  found !<
7941    LOGICAL      ::  two_d !< flag parameter that indicates 2D variables (horizontal cross sections)
7942
7943    REAL(wp) ::  fill_value = -999.0_wp    !< value for the _FillValue attribute
7944
7945    REAL(wp), DIMENSION(nxl:nxr,nys:nyn,nzb_do:nzt_do) ::  local_pf !<
7946
7947    found = .TRUE.
7948
7949    SELECT CASE ( TRIM( variable ) )
7950
7951       CASE ( 'rad_net*_xy' )        ! 2d-array
7952          IF ( av == 0 ) THEN
7953             DO  i = nxl, nxr
7954                DO  j = nys, nyn
7955!
7956!--                Obtain rad_net from its respective surface type
7957!--                Natural-type surfaces
7958                   DO  m = surf_lsm_h%start_index(j,i),                        &
7959                           surf_lsm_h%end_index(j,i) 
7960                      local_pf(i,j,nzb+1) = surf_lsm_h%rad_net(m)
7961                   ENDDO
7962!
7963!--                Urban-type surfaces
7964                   DO  m = surf_usm_h%start_index(j,i),                        &
7965                           surf_usm_h%end_index(j,i) 
7966                      local_pf(i,j,nzb+1) = surf_usm_h%rad_net(m)
7967                   ENDDO
7968                ENDDO
7969             ENDDO
7970          ELSE
7971             IF ( .NOT. ALLOCATED( rad_net_av ) ) THEN
7972                ALLOCATE( rad_net_av(nysg:nyng,nxlg:nxrg) )
7973                rad_net_av = REAL( fill_value, KIND = wp )
7974             ENDIF
7975             DO  i = nxl, nxr
7976                DO  j = nys, nyn 
7977                   local_pf(i,j,nzb+1) = rad_net_av(j,i)
7978                ENDDO
7979             ENDDO
7980          ENDIF
7981          two_d = .TRUE.
7982          grid = 'zu1'
7983         
7984       CASE ( 'rad_lw_in*_xy' )        ! 2d-array
7985          IF ( av == 0 ) THEN
7986             DO  i = nxl, nxr
7987                DO  j = nys, nyn
7988!
7989!--                Obtain rad_net from its respective surface type
7990!--                Natural-type surfaces
7991                   DO  m = surf_lsm_h%start_index(j,i),                        &
7992                           surf_lsm_h%end_index(j,i) 
7993                      local_pf(i,j,nzb+1) = surf_lsm_h%rad_lw_in(m)
7994                   ENDDO
7995!
7996!--                Urban-type surfaces
7997                   DO  m = surf_usm_h%start_index(j,i),                        &
7998                           surf_usm_h%end_index(j,i) 
7999                      local_pf(i,j,nzb+1) = surf_usm_h%rad_lw_in(m)
8000                   ENDDO
8001                ENDDO
8002             ENDDO
8003          ELSE
8004             IF ( .NOT. ALLOCATED( rad_lw_in_xy_av ) ) THEN
8005                ALLOCATE( rad_lw_in_xy_av(nysg:nyng,nxlg:nxrg) )
8006                rad_lw_in_xy_av = REAL( fill_value, KIND = wp )
8007             ENDIF
8008             DO  i = nxl, nxr
8009                DO  j = nys, nyn 
8010                   local_pf(i,j,nzb+1) = rad_lw_in_xy_av(j,i)
8011                ENDDO
8012             ENDDO
8013          ENDIF
8014          two_d = .TRUE.
8015          grid = 'zu1'
8016         
8017       CASE ( 'rad_lw_out*_xy' )        ! 2d-array
8018          IF ( av == 0 ) THEN
8019             DO  i = nxl, nxr
8020                DO  j = nys, nyn
8021!
8022!--                Obtain rad_net from its respective surface type
8023!--                Natural-type surfaces
8024                   DO  m = surf_lsm_h%start_index(j,i),                        &
8025                           surf_lsm_h%end_index(j,i) 
8026                      local_pf(i,j,nzb+1) = surf_lsm_h%rad_lw_out(m)
8027                   ENDDO
8028!
8029!--                Urban-type surfaces
8030                   DO  m = surf_usm_h%start_index(j,i),                        &
8031                           surf_usm_h%end_index(j,i) 
8032                      local_pf(i,j,nzb+1) = surf_usm_h%rad_lw_out(m)
8033                   ENDDO
8034                ENDDO
8035             ENDDO
8036          ELSE
8037             IF ( .NOT. ALLOCATED( rad_lw_out_xy_av ) ) THEN
8038                ALLOCATE( rad_lw_out_xy_av(nysg:nyng,nxlg:nxrg) )
8039                rad_lw_out_xy_av = REAL( fill_value, KIND = wp )
8040             ENDIF
8041             DO  i = nxl, nxr
8042                DO  j = nys, nyn 
8043                   local_pf(i,j,nzb+1) = rad_lw_out_xy_av(j,i)
8044                ENDDO
8045             ENDDO
8046          ENDIF
8047          two_d = .TRUE.
8048          grid = 'zu1'
8049         
8050       CASE ( 'rad_sw_in*_xy' )        ! 2d-array
8051          IF ( av == 0 ) THEN
8052             DO  i = nxl, nxr
8053                DO  j = nys, nyn
8054!
8055!--                Obtain rad_net from its respective surface type
8056!--                Natural-type surfaces
8057                   DO  m = surf_lsm_h%start_index(j,i),                        &
8058                           surf_lsm_h%end_index(j,i) 
8059                      local_pf(i,j,nzb+1) = surf_lsm_h%rad_sw_in(m)
8060                   ENDDO
8061!
8062!--                Urban-type surfaces
8063                   DO  m = surf_usm_h%start_index(j,i),                        &
8064                           surf_usm_h%end_index(j,i) 
8065                      local_pf(i,j,nzb+1) = surf_usm_h%rad_sw_in(m)
8066                   ENDDO
8067                ENDDO
8068             ENDDO
8069          ELSE
8070             IF ( .NOT. ALLOCATED( rad_sw_in_xy_av ) ) THEN
8071                ALLOCATE( rad_sw_in_xy_av(nysg:nyng,nxlg:nxrg) )
8072                rad_sw_in_xy_av = REAL( fill_value, KIND = wp )
8073             ENDIF
8074             DO  i = nxl, nxr
8075                DO  j = nys, nyn 
8076                   local_pf(i,j,nzb+1) = rad_sw_in_xy_av(j,i)
8077                ENDDO
8078             ENDDO
8079          ENDIF
8080          two_d = .TRUE.
8081          grid = 'zu1'
8082         
8083       CASE ( 'rad_sw_out*_xy' )        ! 2d-array
8084          IF ( av == 0 ) THEN
8085             DO  i = nxl, nxr
8086                DO  j = nys, nyn
8087!
8088!--                Obtain rad_net from its respective surface type
8089!--                Natural-type surfaces
8090                   DO  m = surf_lsm_h%start_index(j,i),                        &
8091                           surf_lsm_h%end_index(j,i) 
8092                      local_pf(i,j,nzb+1) = surf_lsm_h%rad_sw_out(m)
8093                   ENDDO
8094!
8095!--                Urban-type surfaces
8096                   DO  m = surf_usm_h%start_index(j,i),                        &
8097                           surf_usm_h%end_index(j,i) 
8098                      local_pf(i,j,nzb+1) = surf_usm_h%rad_sw_out(m)
8099                   ENDDO
8100                ENDDO
8101             ENDDO
8102          ELSE
8103             IF ( .NOT. ALLOCATED( rad_sw_out_xy_av ) ) THEN
8104                ALLOCATE( rad_sw_out_xy_av(nysg:nyng,nxlg:nxrg) )
8105                rad_sw_out_xy_av = REAL( fill_value, KIND = wp )
8106             ENDIF
8107             DO  i = nxl, nxr
8108                DO  j = nys, nyn 
8109                   local_pf(i,j,nzb+1) = rad_sw_out_xy_av(j,i)
8110                ENDDO
8111             ENDDO
8112          ENDIF
8113          two_d = .TRUE.
8114          grid = 'zu1'         
8115         
8116       CASE ( 'rad_lw_in_xy', 'rad_lw_in_xz', 'rad_lw_in_yz' )
8117          IF ( av == 0 ) THEN
8118             DO  i = nxl, nxr
8119                DO  j = nys, nyn
8120                   DO  k = nzb_do, nzt_do
8121                      local_pf(i,j,k) = rad_lw_in(k,j,i)
8122                   ENDDO
8123                ENDDO
8124             ENDDO
8125          ELSE
8126            IF ( .NOT. ALLOCATED( rad_lw_in_av ) ) THEN
8127               ALLOCATE( rad_lw_in_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
8128               rad_lw_in_av = REAL( fill_value, KIND = wp )
8129            ENDIF
8130             DO  i = nxl, nxr
8131                DO  j = nys, nyn 
8132                   DO  k = nzb_do, nzt_do
8133                      local_pf(i,j,k) = rad_lw_in_av(k,j,i)
8134                   ENDDO
8135                ENDDO
8136             ENDDO
8137          ENDIF
8138          IF ( mode == 'xy' )  grid = 'zu'
8139
8140       CASE ( 'rad_lw_out_xy', 'rad_lw_out_xz', 'rad_lw_out_yz' )
8141          IF ( av == 0 ) THEN
8142             DO  i = nxl, nxr
8143                DO  j = nys, nyn
8144                   DO  k = nzb_do, nzt_do
8145                      local_pf(i,j,k) = rad_lw_out(k,j,i)
8146                   ENDDO
8147                ENDDO
8148             ENDDO
8149          ELSE
8150            IF ( .NOT. ALLOCATED( rad_lw_out_av ) ) THEN
8151               ALLOCATE( rad_lw_out_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
8152               rad_lw_out_av = REAL( fill_value, KIND = wp )
8153            ENDIF
8154             DO  i = nxl, nxr
8155                DO  j = nys, nyn 
8156                   DO  k = nzb_do, nzt_do
8157                      local_pf(i,j,k) = rad_lw_out_av(k,j,i)
8158                   ENDDO
8159                ENDDO
8160             ENDDO
8161          ENDIF   
8162          IF ( mode == 'xy' )  grid = 'zu'
8163
8164       CASE ( 'rad_lw_cs_hr_xy', 'rad_lw_cs_hr_xz', 'rad_lw_cs_hr_yz' )
8165          IF ( av == 0 ) THEN
8166             DO  i = nxl, nxr
8167                DO  j = nys, nyn
8168                   DO  k = nzb_do, nzt_do
8169                      local_pf(i,j,k) = rad_lw_cs_hr(k,j,i)
8170                   ENDDO
8171                ENDDO
8172             ENDDO
8173          ELSE
8174            IF ( .NOT. ALLOCATED( rad_lw_cs_hr_av ) ) THEN
8175               ALLOCATE( rad_lw_cs_hr_av(nzb+1:nzt+1,nysg:nyng,nxlg:nxrg) )
8176               rad_lw_cs_hr_av = REAL( fill_value, KIND = wp )
8177            ENDIF
8178             DO  i = nxl, nxr
8179                DO  j = nys, nyn 
8180                   DO  k = nzb_do, nzt_do
8181                      local_pf(i,j,k) = rad_lw_cs_hr_av(k,j,i)
8182                   ENDDO
8183                ENDDO
8184             ENDDO
8185          ENDIF
8186          IF ( mode == 'xy' )  grid = 'zw'
8187
8188       CASE ( 'rad_lw_hr_xy', 'rad_lw_hr_xz', 'rad_lw_hr_yz' )
8189          IF ( av == 0 ) THEN
8190             DO  i = nxl, nxr
8191                DO  j = nys, nyn
8192                   DO  k = nzb_do, nzt_do
8193                      local_pf(i,j,k) = rad_lw_hr(k,j,i)
8194                   ENDDO
8195                ENDDO
8196             ENDDO
8197          ELSE
8198            IF ( .NOT. ALLOCATED( rad_lw_hr_av ) ) THEN
8199               ALLOCATE( rad_lw_hr_av(nzb+1:nzt+1,nysg:nyng,nxlg:nxrg) )
8200               rad_lw_hr_av= REAL( fill_value, KIND = wp )
8201            ENDIF
8202             DO  i = nxl, nxr
8203                DO  j = nys, nyn 
8204                   DO  k = nzb_do, nzt_do
8205                      local_pf(i,j,k) = rad_lw_hr_av(k,j,i)
8206                   ENDDO
8207                ENDDO
8208             ENDDO
8209          ENDIF
8210          IF ( mode == 'xy' )  grid = 'zw'
8211
8212       CASE ( 'rad_sw_in_xy', 'rad_sw_in_xz', 'rad_sw_in_yz' )
8213          IF ( av == 0 ) THEN
8214             DO  i = nxl, nxr
8215                DO  j = nys, nyn
8216                   DO  k = nzb_do, nzt_do
8217                      local_pf(i,j,k) = rad_sw_in(k,j,i)
8218                   ENDDO
8219                ENDDO
8220             ENDDO
8221          ELSE
8222            IF ( .NOT. ALLOCATED( rad_sw_in_av ) ) THEN
8223               ALLOCATE( rad_sw_in_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
8224               rad_sw_in_av = REAL( fill_value, KIND = wp )
8225            ENDIF
8226             DO  i = nxl, nxr
8227                DO  j = nys, nyn 
8228                   DO  k = nzb_do, nzt_do
8229                      local_pf(i,j,k) = rad_sw_in_av(k,j,i)
8230                   ENDDO
8231                ENDDO
8232             ENDDO
8233          ENDIF
8234          IF ( mode == 'xy' )  grid = 'zu'
8235
8236       CASE ( 'rad_sw_out_xy', 'rad_sw_out_xz', 'rad_sw_out_yz' )
8237          IF ( av == 0 ) THEN
8238             DO  i = nxl, nxr
8239                DO  j = nys, nyn
8240                   DO  k = nzb_do, nzt_do
8241                      local_pf(i,j,k) = rad_sw_out(k,j,i)
8242                   ENDDO
8243                ENDDO
8244             ENDDO
8245          ELSE
8246            IF ( .NOT. ALLOCATED( rad_sw_out_av ) ) THEN
8247               ALLOCATE( rad_sw_out_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
8248               rad_sw_out_av = REAL( fill_value, KIND = wp )
8249            ENDIF
8250             DO  i = nxl, nxr
8251                DO  j = nys, nyn 
8252                   DO  k = nzb, nzt+1
8253                      local_pf(i,j,k) = rad_sw_out_av(k,j,i)
8254                   ENDDO
8255                ENDDO
8256             ENDDO
8257          ENDIF
8258          IF ( mode == 'xy' )  grid = 'zu'
8259
8260       CASE ( 'rad_sw_cs_hr_xy', 'rad_sw_cs_hr_xz', 'rad_sw_cs_hr_yz' )
8261          IF ( av == 0 ) THEN
8262             DO  i = nxl, nxr
8263                DO  j = nys, nyn
8264                   DO  k = nzb_do, nzt_do
8265                      local_pf(i,j,k) = rad_sw_cs_hr(k,j,i)
8266                   ENDDO
8267                ENDDO
8268             ENDDO
8269          ELSE
8270            IF ( .NOT. ALLOCATED( rad_sw_cs_hr_av ) ) THEN
8271               ALLOCATE( rad_sw_cs_hr_av(nzb+1:nzt+1,nysg:nyng,nxlg:nxrg) )
8272               rad_sw_cs_hr_av = REAL( fill_value, KIND = wp )
8273            ENDIF
8274             DO  i = nxl, nxr
8275                DO  j = nys, nyn 
8276                   DO  k = nzb_do, nzt_do
8277                      local_pf(i,j,k) = rad_sw_cs_hr_av(k,j,i)
8278                   ENDDO
8279                ENDDO
8280             ENDDO
8281          ENDIF
8282          IF ( mode == 'xy' )  grid = 'zw'
8283
8284       CASE ( 'rad_sw_hr_xy', 'rad_sw_hr_xz', 'rad_sw_hr_yz' )
8285          IF ( av == 0 ) THEN
8286             DO  i = nxl, nxr
8287                DO  j = nys, nyn
8288                   DO  k = nzb_do, nzt_do
8289                      local_pf(i,j,k) = rad_sw_hr(k,j,i)
8290                   ENDDO
8291                ENDDO
8292             ENDDO
8293          ELSE
8294            IF ( .NOT. ALLOCATED( rad_sw_hr_av ) ) THEN
8295               ALLOCATE( rad_sw_hr_av(nzb+1:nzt+1,nysg:nyng,nxlg:nxrg) )
8296               rad_sw_hr_av = REAL( fill_value, KIND = wp )
8297            ENDIF
8298             DO  i = nxl, nxr
8299                DO  j = nys, nyn 
8300                   DO  k = nzb_do, nzt_do
8301                      local_pf(i,j,k) = rad_sw_hr_av(k,j,i)
8302                   ENDDO
8303                ENDDO
8304             ENDDO
8305          ENDIF
8306          IF ( mode == 'xy' )  grid = 'zw'
8307
8308       CASE DEFAULT
8309          found = .FALSE.
8310          grid  = 'none'
8311
8312    END SELECT
8313 
8314 END SUBROUTINE radiation_data_output_2d
8315
8316
8317!------------------------------------------------------------------------------!
8318!
8319! Description:
8320! ------------
8321!> Subroutine defining 3D output variables
8322!------------------------------------------------------------------------------!
8323 SUBROUTINE radiation_data_output_3d( av, variable, found, local_pf, nzb_do, nzt_do )
8324 
8325
8326    USE indices
8327
8328    USE kinds
8329
8330
8331    IMPLICIT NONE
8332
8333    CHARACTER (LEN=*) ::  variable !<
8334
8335    INTEGER(iwp) ::  av    !<
8336    INTEGER(iwp) ::  i     !<
8337    INTEGER(iwp) ::  j     !<
8338    INTEGER(iwp) ::  k     !<
8339    INTEGER(iwp) ::  nzb_do   !<
8340    INTEGER(iwp) ::  nzt_do   !<
8341
8342    LOGICAL      ::  found !<
8343
8344    REAL(wp) ::  fill_value = -999.0_wp    !< value for the _FillValue attribute
8345
8346    REAL(sp), DIMENSION(nxl:nxr,nys:nyn,nzb_do:nzt_do) ::  local_pf !<
8347
8348
8349    found = .TRUE.
8350
8351
8352    SELECT CASE ( TRIM( variable ) )
8353
8354      CASE ( 'rad_sw_in' )
8355         IF ( av == 0 )  THEN
8356            DO  i = nxl, nxr
8357               DO  j = nys, nyn
8358                  DO  k = nzb_do, nzt_do
8359                     local_pf(i,j,k) = rad_sw_in(k,j,i)
8360                  ENDDO
8361               ENDDO
8362            ENDDO
8363         ELSE
8364            IF ( .NOT. ALLOCATED( rad_sw_in_av ) ) THEN
8365               ALLOCATE( rad_sw_in_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
8366               rad_sw_in_av = REAL( fill_value, KIND = wp )
8367            ENDIF
8368            DO  i = nxl, nxr
8369               DO  j = nys, nyn
8370                  DO  k = nzb_do, nzt_do
8371                     local_pf(i,j,k) = rad_sw_in_av(k,j,i)
8372                  ENDDO
8373               ENDDO
8374            ENDDO
8375         ENDIF
8376
8377      CASE ( 'rad_sw_out' )
8378         IF ( av == 0 )  THEN
8379            DO  i = nxl, nxr
8380               DO  j = nys, nyn
8381                  DO  k = nzb_do, nzt_do
8382                     local_pf(i,j,k) = rad_sw_out(k,j,i)
8383                  ENDDO
8384               ENDDO
8385            ENDDO
8386         ELSE
8387            IF ( .NOT. ALLOCATED( rad_sw_out_av ) ) THEN
8388               ALLOCATE( rad_sw_out_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
8389               rad_sw_out_av = REAL( fill_value, KIND = wp )
8390            ENDIF
8391            DO  i = nxl, nxr
8392               DO  j = nys, nyn
8393                  DO  k = nzb_do, nzt_do
8394                     local_pf(i,j,k) = rad_sw_out_av(k,j,i)
8395                  ENDDO
8396               ENDDO
8397            ENDDO
8398         ENDIF
8399
8400      CASE ( 'rad_sw_cs_hr' )
8401         IF ( av == 0 )  THEN
8402            DO  i = nxl, nxr
8403               DO  j = nys, nyn
8404                  DO  k = nzb_do, nzt_do
8405                     local_pf(i,j,k) = rad_sw_cs_hr(k,j,i)
8406                  ENDDO
8407               ENDDO
8408            ENDDO
8409         ELSE
8410            IF ( .NOT. ALLOCATED( rad_sw_cs_hr_av ) ) THEN
8411               ALLOCATE( rad_sw_cs_hr_av(nzb+1:nzt+1,nysg:nyng,nxlg:nxrg) )
8412               rad_sw_cs_hr_av = REAL( fill_value, KIND = wp )
8413            ENDIF
8414            DO  i = nxl, nxr
8415               DO  j = nys, nyn
8416                  DO  k = nzb_do, nzt_do
8417                     local_pf(i,j,k) = rad_sw_cs_hr_av(k,j,i)
8418                  ENDDO
8419               ENDDO
8420            ENDDO
8421         ENDIF
8422
8423      CASE ( 'rad_sw_hr' )
8424         IF ( av == 0 )  THEN
8425            DO  i = nxl, nxr
8426               DO  j = nys, nyn
8427                  DO  k = nzb_do, nzt_do
8428                     local_pf(i,j,k) = rad_sw_hr(k,j,i)
8429                  ENDDO
8430               ENDDO
8431            ENDDO
8432         ELSE
8433            IF ( .NOT. ALLOCATED( rad_sw_hr_av ) ) THEN
8434               ALLOCATE( rad_sw_hr_av(nzb+1:nzt+1,nysg:nyng,nxlg:nxrg) )
8435               rad_sw_hr_av = REAL( fill_value, KIND = wp )
8436            ENDIF
8437            DO  i = nxl, nxr
8438               DO  j = nys, nyn
8439                  DO  k = nzb_do, nzt_do
8440                     local_pf(i,j,k) = rad_sw_hr_av(k,j,i)
8441                  ENDDO
8442               ENDDO
8443            ENDDO
8444         ENDIF
8445
8446      CASE ( 'rad_lw_in' )
8447         IF ( av == 0 )  THEN
8448            DO  i = nxl, nxr
8449               DO  j = nys, nyn
8450                  DO  k = nzb_do, nzt_do
8451                     local_pf(i,j,k) = rad_lw_in(k,j,i)
8452                  ENDDO
8453               ENDDO
8454            ENDDO
8455         ELSE
8456            IF ( .NOT. ALLOCATED( rad_lw_in_av ) ) THEN
8457               ALLOCATE( rad_lw_in_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
8458               rad_lw_in_av = REAL( fill_value, KIND = wp )
8459            ENDIF
8460            DO  i = nxl, nxr
8461               DO  j = nys, nyn
8462                  DO  k = nzb_do, nzt_do
8463                     local_pf(i,j,k) = rad_lw_in_av(k,j,i)
8464                  ENDDO
8465               ENDDO
8466            ENDDO
8467         ENDIF
8468
8469      CASE ( 'rad_lw_out' )
8470         IF ( av == 0 )  THEN
8471            DO  i = nxl, nxr
8472               DO  j = nys, nyn
8473                  DO  k = nzb_do, nzt_do
8474                     local_pf(i,j,k) = rad_lw_out(k,j,i)
8475                  ENDDO
8476               ENDDO
8477            ENDDO
8478         ELSE
8479            IF ( .NOT. ALLOCATED( rad_lw_out_av ) ) THEN
8480               ALLOCATE( rad_lw_out_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
8481               rad_lw_out_av = REAL( fill_value, KIND = wp )
8482            ENDIF
8483            DO  i = nxl, nxr
8484               DO  j = nys, nyn
8485                  DO  k = nzb_do, nzt_do
8486                     local_pf(i,j,k) = rad_lw_out_av(k,j,i)
8487                  ENDDO
8488               ENDDO
8489            ENDDO
8490         ENDIF
8491
8492      CASE ( 'rad_lw_cs_hr' )
8493         IF ( av == 0 )  THEN
8494            DO  i = nxl, nxr
8495               DO  j = nys, nyn
8496                  DO  k = nzb_do, nzt_do
8497                     local_pf(i,j,k) = rad_lw_cs_hr(k,j,i)
8498                  ENDDO
8499               ENDDO
8500            ENDDO
8501         ELSE
8502            IF ( .NOT. ALLOCATED( rad_lw_cs_hr_av ) ) THEN
8503               ALLOCATE( rad_lw_cs_hr_av(nzb+1:nzt+1,nysg:nyng,nxlg:nxrg) )
8504               rad_lw_cs_hr_av = REAL( fill_value, KIND = wp )
8505            ENDIF
8506            DO  i = nxl, nxr
8507               DO  j = nys, nyn
8508                  DO  k = nzb_do, nzt_do
8509                     local_pf(i,j,k) = rad_lw_cs_hr_av(k,j,i)
8510                  ENDDO
8511               ENDDO
8512            ENDDO
8513         ENDIF
8514
8515      CASE ( 'rad_lw_hr' )
8516         IF ( av == 0 )  THEN
8517            DO  i = nxl, nxr
8518               DO  j = nys, nyn
8519                  DO  k = nzb_do, nzt_do
8520                     local_pf(i,j,k) = rad_lw_hr(k,j,i)
8521                  ENDDO
8522               ENDDO
8523            ENDDO
8524         ELSE
8525            IF ( .NOT. ALLOCATED( rad_lw_hr_av ) ) THEN
8526               ALLOCATE( rad_lw_hr_av(nzb+1:nzt+1,nysg:nyng,nxlg:nxrg) )
8527              rad_lw_hr_av = REAL( fill_value, KIND = wp )
8528            ENDIF
8529            DO  i = nxl, nxr
8530               DO  j = nys, nyn
8531                  DO  k = nzb_do, nzt_do
8532                     local_pf(i,j,k) = rad_lw_hr_av(k,j,i)
8533                  ENDDO
8534               ENDDO
8535            ENDDO
8536         ENDIF
8537
8538       CASE DEFAULT
8539          found = .FALSE.
8540
8541    END SELECT
8542
8543
8544 END SUBROUTINE radiation_data_output_3d
8545
8546!------------------------------------------------------------------------------!
8547!
8548! Description:
8549! ------------
8550!> Subroutine defining masked data output
8551!------------------------------------------------------------------------------!
8552 SUBROUTINE radiation_data_output_mask( av, variable, found, local_pf )
8553 
8554    USE control_parameters
8555       
8556    USE indices
8557   
8558    USE kinds
8559   
8560
8561    IMPLICIT NONE
8562
8563    CHARACTER (LEN=*) ::  variable   !<
8564
8565    INTEGER(iwp) ::  av   !<
8566    INTEGER(iwp) ::  i    !<
8567    INTEGER(iwp) ::  j    !<
8568    INTEGER(iwp) ::  k    !<
8569
8570    LOGICAL ::  found     !<
8571
8572    REAL(wp),                                                                  &
8573       DIMENSION(mask_size_l(mid,1),mask_size_l(mid,2),mask_size_l(mid,3)) ::  &
8574          local_pf   !<
8575
8576
8577    found = .TRUE.
8578
8579    SELECT CASE ( TRIM( variable ) )
8580
8581
8582       CASE ( 'rad_lw_in' )
8583          IF ( av == 0 )  THEN
8584             DO  i = 1, mask_size_l(mid,1)
8585                DO  j = 1, mask_size_l(mid,2)
8586                   DO  k = 1, mask_size_l(mid,3)
8587                       local_pf(i,j,k) = rad_lw_in(mask_k(mid,k),              &
8588                                            mask_j(mid,j),mask_i(mid,i))
8589                    ENDDO
8590                 ENDDO
8591              ENDDO
8592          ELSE
8593             DO  i = 1, mask_size_l(mid,1)
8594                DO  j = 1, mask_size_l(mid,2)
8595                   DO  k = 1, mask_size_l(mid,3)
8596                       local_pf(i,j,k) = rad_lw_in_av(mask_k(mid,k),           &
8597                                               mask_j(mid,j),mask_i(mid,i))
8598                   ENDDO
8599                ENDDO
8600             ENDDO
8601          ENDIF
8602
8603       CASE ( 'rad_lw_out' )
8604          IF ( av == 0 )  THEN
8605             DO  i = 1, mask_size_l(mid,1)
8606                DO  j = 1, mask_size_l(mid,2)
8607                   DO  k = 1, mask_size_l(mid,3)
8608                       local_pf(i,j,k) = rad_lw_out(mask_k(mid,k),             &
8609                                            mask_j(mid,j),mask_i(mid,i))
8610                    ENDDO
8611                 ENDDO
8612              ENDDO
8613          ELSE
8614             DO  i = 1, mask_size_l(mid,1)
8615                DO  j = 1, mask_size_l(mid,2)
8616                   DO  k = 1, mask_size_l(mid,3)
8617                       local_pf(i,j,k) = rad_lw_out_av(mask_k(mid,k),          &
8618                                               mask_j(mid,j),mask_i(mid,i))
8619                   ENDDO
8620                ENDDO
8621             ENDDO
8622          ENDIF
8623
8624       CASE ( 'rad_lw_cs_hr' )
8625          IF ( av == 0 )  THEN
8626             DO  i = 1, mask_size_l(mid,1)
8627                DO  j = 1, mask_size_l(mid,2)
8628                   DO  k = 1, mask_size_l(mid,3)
8629                       local_pf(i,j,k) = rad_lw_cs_hr(mask_k(mid,k),           &
8630                                            mask_j(mid,j),mask_i(mid,i))
8631                    ENDDO
8632                 ENDDO
8633              ENDDO
8634          ELSE
8635             DO  i = 1, mask_size_l(mid,1)
8636                DO  j = 1, mask_size_l(mid,2)
8637                   DO  k = 1, mask_size_l(mid,3)
8638                       local_pf(i,j,k) = rad_lw_cs_hr_av(mask_k(mid,k),        &
8639                                               mask_j(mid,j),mask_i(mid,i))
8640                   ENDDO
8641                ENDDO
8642             ENDDO
8643          ENDIF
8644
8645       CASE ( 'rad_lw_hr' )
8646          IF ( av == 0 )  THEN
8647             DO  i = 1, mask_size_l(mid,1)
8648                DO  j = 1, mask_size_l(mid,2)
8649                   DO  k = 1, mask_size_l(mid,3)
8650                       local_pf(i,j,k) = rad_lw_hr(mask_k(mid,k),              &
8651                                            mask_j(mid,j),mask_i(mid,i))
8652                    ENDDO
8653                 ENDDO
8654              ENDDO
8655          ELSE
8656             DO  i = 1, mask_size_l(mid,1)
8657                DO  j = 1, mask_size_l(mid,2)
8658                   DO  k = 1, mask_size_l(mid,3)
8659                       local_pf(i,j,k) = rad_lw_hr_av(mask_k(mid,k),           &
8660                                               mask_j(mid,j),mask_i(mid,i))
8661                   ENDDO
8662                ENDDO
8663             ENDDO
8664          ENDIF
8665
8666       CASE ( 'rad_sw_in' )
8667          IF ( av == 0 )  THEN
8668             DO  i = 1, mask_size_l(mid,1)
8669                DO  j = 1, mask_size_l(mid,2)
8670                   DO  k = 1, mask_size_l(mid,3)
8671                       local_pf(i,j,k) = rad_sw_in(mask_k(mid,k),              &
8672                                            mask_j(mid,j),mask_i(mid,i))
8673                    ENDDO
8674                 ENDDO
8675              ENDDO
8676          ELSE
8677             DO  i = 1, mask_size_l(mid,1)
8678                DO  j = 1, mask_size_l(mid,2)
8679                   DO  k = 1, mask_size_l(mid,3)
8680                       local_pf(i,j,k) = rad_sw_in_av(mask_k(mid,k),           &
8681                                               mask_j(mid,j),mask_i(mid,i))
8682                   ENDDO
8683                ENDDO
8684             ENDDO
8685          ENDIF
8686
8687       CASE ( 'rad_sw_out' )
8688          IF ( av == 0 )  THEN
8689             DO  i = 1, mask_size_l(mid,1)
8690                DO  j = 1, mask_size_l(mid,2)
8691                   DO  k = 1, mask_size_l(mid,3)
8692                       local_pf(i,j,k) = rad_sw_out(mask_k(mid,k),             &
8693                                            mask_j(mid,j),mask_i(mid,i))
8694                    ENDDO
8695                 ENDDO
8696              ENDDO
8697          ELSE
8698             DO  i = 1, mask_size_l(mid,1)
8699                DO  j = 1, mask_size_l(mid,2)
8700                   DO  k = 1, mask_size_l(mid,3)
8701                       local_pf(i,j,k) = rad_sw_out_av(mask_k(mid,k),          &
8702                                               mask_j(mid,j),mask_i(mid,i))
8703                   ENDDO
8704                ENDDO
8705             ENDDO
8706          ENDIF
8707
8708       CASE ( 'rad_sw_cs_hr' )
8709          IF ( av == 0 )  THEN
8710             DO  i = 1, mask_size_l(mid,1)
8711                DO  j = 1, mask_size_l(mid,2)
8712                   DO  k = 1, mask_size_l(mid,3)
8713                       local_pf(i,j,k) = rad_sw_cs_hr(mask_k(mid,k),           &
8714                                            mask_j(mid,j),mask_i(mid,i))
8715                    ENDDO
8716                 ENDDO
8717              ENDDO
8718          ELSE
8719             DO  i = 1, mask_size_l(mid,1)
8720                DO  j = 1, mask_size_l(mid,2)
8721                   DO  k = 1, mask_size_l(mid,3)
8722                       local_pf(i,j,k) = rad_sw_cs_hr_av(mask_k(mid,k),        &
8723                                               mask_j(mid,j),mask_i(mid,i))
8724                   ENDDO
8725                ENDDO
8726             ENDDO
8727          ENDIF
8728
8729       CASE ( 'rad_sw_hr' )
8730          IF ( av == 0 )  THEN
8731             DO  i = 1, mask_size_l(mid,1)
8732                DO  j = 1, mask_size_l(mid,2)
8733                   DO  k = 1, mask_size_l(mid,3)
8734                       local_pf(i,j,k) = rad_sw_hr(mask_k(mid,k),              &
8735                                            mask_j(mid,j),mask_i(mid,i))
8736                    ENDDO
8737                 ENDDO
8738              ENDDO
8739          ELSE
8740             DO  i = 1, mask_size_l(mid,1)
8741                DO  j = 1, mask_size_l(mid,2)
8742                   DO  k = 1, mask_size_l(mid,3)
8743                       local_pf(i,j,k) = rad_sw_hr_av(mask_k(mid,k),           &
8744                                               mask_j(mid,j),mask_i(mid,i))
8745                   ENDDO
8746                ENDDO
8747             ENDDO
8748          ENDIF
8749
8750       CASE DEFAULT
8751          found = .FALSE.
8752
8753    END SELECT
8754
8755
8756 END SUBROUTINE radiation_data_output_mask
8757
8758
8759!------------------------------------------------------------------------------!
8760! Description:
8761! ------------
8762!> Subroutine writes local (subdomain) restart data
8763!------------------------------------------------------------------------------!
8764 SUBROUTINE radiation_wrd_local
8765
8766
8767    IMPLICIT NONE
8768
8769
8770    IF ( ALLOCATED( rad_net_av ) )  THEN
8771       CALL wrd_write_string( 'rad_net_av' )
8772       WRITE ( 14 )  rad_net_av
8773    ENDIF
8774   
8775    IF ( ALLOCATED( rad_lw_in_xy_av ) )  THEN
8776       CALL wrd_write_string( 'rad_lw_in_xy_av' )
8777       WRITE ( 14 )  rad_lw_in_xy_av
8778    ENDIF
8779   
8780    IF ( ALLOCATED( rad_lw_out_xy_av ) )  THEN
8781       CALL wrd_write_string( 'rad_lw_out_xy_av' )
8782       WRITE ( 14 )  rad_lw_out_xy_av
8783    ENDIF
8784   
8785    IF ( ALLOCATED( rad_sw_in_xy_av ) )  THEN
8786       CALL wrd_write_string( 'rad_sw_in_xy_av' )
8787       WRITE ( 14 )  rad_sw_in_xy_av
8788    ENDIF
8789   
8790    IF ( ALLOCATED( rad_sw_out_xy_av ) )  THEN
8791       CALL wrd_write_string( 'rad_sw_out_xy_av' )
8792       WRITE ( 14 )  rad_sw_out_xy_av
8793    ENDIF
8794
8795    IF ( ALLOCATED( rad_lw_in ) )  THEN
8796       CALL wrd_write_string( 'rad_lw_in' )
8797       WRITE ( 14 )  rad_lw_in
8798    ENDIF
8799
8800    IF ( ALLOCATED( rad_lw_in_av ) )  THEN
8801       CALL wrd_write_string( 'rad_lw_in_av' )
8802       WRITE ( 14 )  rad_lw_in_av
8803    ENDIF
8804
8805    IF ( ALLOCATED( rad_lw_out ) )  THEN
8806       CALL wrd_write_string( 'rad_lw_out' )
8807       WRITE ( 14 )  rad_lw_out
8808    ENDIF
8809
8810    IF ( ALLOCATED( rad_lw_out_av) )  THEN
8811       CALL wrd_write_string( 'rad_lw_out_av' )
8812       WRITE ( 14 )  rad_lw_out_av
8813    ENDIF
8814
8815    IF ( ALLOCATED( rad_lw_cs_hr) )  THEN
8816       CALL wrd_write_string( 'rad_lw_cs_hr' )
8817       WRITE ( 14 )  rad_lw_cs_hr
8818    ENDIF
8819
8820    IF ( ALLOCATED( rad_lw_cs_hr_av) )  THEN
8821       CALL wrd_write_string( 'rad_lw_cs_hr_av' )
8822       WRITE ( 14 )  rad_lw_cs_hr_av
8823    ENDIF
8824
8825    IF ( ALLOCATED( rad_lw_hr) )  THEN
8826       CALL wrd_write_string( 'rad_lw_hr' )
8827       WRITE ( 14 )  rad_lw_hr
8828    ENDIF
8829
8830    IF ( ALLOCATED( rad_lw_hr_av) )  THEN
8831       CALL wrd_write_string( 'rad_lw_hr_av' )
8832       WRITE ( 14 )  rad_lw_hr_av
8833    ENDIF
8834
8835    IF ( ALLOCATED( rad_sw_in) )  THEN
8836       CALL wrd_write_string( 'rad_sw_in' )
8837       WRITE ( 14 )  rad_sw_in
8838    ENDIF
8839
8840    IF ( ALLOCATED( rad_sw_in_av) )  THEN
8841       CALL wrd_write_string( 'rad_sw_in_av' )
8842       WRITE ( 14 )  rad_sw_in_av
8843    ENDIF
8844
8845    IF ( ALLOCATED( rad_sw_out) )  THEN
8846       CALL wrd_write_string( 'rad_sw_out' )
8847       WRITE ( 14 )  rad_sw_out
8848    ENDIF
8849
8850    IF ( ALLOCATED( rad_sw_out_av) )  THEN
8851       CALL wrd_write_string( 'rad_sw_out_av' )
8852       WRITE ( 14 )  rad_sw_out_av
8853    ENDIF
8854
8855    IF ( ALLOCATED( rad_sw_cs_hr) )  THEN
8856       CALL wrd_write_string( 'rad_sw_cs_hr' )
8857       WRITE ( 14 )  rad_sw_cs_hr
8858    ENDIF
8859
8860    IF ( ALLOCATED( rad_sw_cs_hr_av) )  THEN
8861       CALL wrd_write_string( 'rad_sw_cs_hr_av' )
8862       WRITE ( 14 )  rad_sw_cs_hr_av
8863    ENDIF
8864
8865    IF ( ALLOCATED( rad_sw_hr) )  THEN
8866       CALL wrd_write_string( 'rad_sw_hr' )
8867       WRITE ( 14 )  rad_sw_hr
8868    ENDIF
8869
8870    IF ( ALLOCATED( rad_sw_hr_av) )  THEN
8871       CALL wrd_write_string( 'rad_sw_hr_av' )
8872       WRITE ( 14 )  rad_sw_hr_av
8873    ENDIF
8874
8875
8876 END SUBROUTINE radiation_wrd_local
8877
8878!------------------------------------------------------------------------------!
8879! Description:
8880! ------------
8881!> Subroutine reads local (subdomain) restart data
8882!------------------------------------------------------------------------------!
8883 SUBROUTINE radiation_rrd_local( i, k, nxlf, nxlc, nxl_on_file, nxrf, nxrc,    &
8884                                nxr_on_file, nynf, nync, nyn_on_file, nysf,    &
8885                                nysc, nys_on_file, tmp_2d, tmp_3d, found )
8886 
8887
8888    USE control_parameters
8889       
8890    USE indices
8891   
8892    USE kinds
8893   
8894    USE pegrid
8895
8896
8897    IMPLICIT NONE
8898
8899    INTEGER(iwp) ::  i               !<
8900    INTEGER(iwp) ::  k               !<
8901    INTEGER(iwp) ::  nxlc            !<
8902    INTEGER(iwp) ::  nxlf            !<
8903    INTEGER(iwp) ::  nxl_on_file     !<
8904    INTEGER(iwp) ::  nxrc            !<
8905    INTEGER(iwp) ::  nxrf            !<
8906    INTEGER(iwp) ::  nxr_on_file     !<
8907    INTEGER(iwp) ::  nync            !<
8908    INTEGER(iwp) ::  nynf            !<
8909    INTEGER(iwp) ::  nyn_on_file     !<
8910    INTEGER(iwp) ::  nysc            !<
8911    INTEGER(iwp) ::  nysf            !<
8912    INTEGER(iwp) ::  nys_on_file     !<
8913
8914    LOGICAL, INTENT(OUT)  :: found
8915
8916    REAL(wp), DIMENSION(nys_on_file-nbgp:nyn_on_file+nbgp,nxl_on_file-nbgp:nxr_on_file+nbgp) :: tmp_2d   !<
8917
8918    REAL(wp), DIMENSION(nzb:nzt+1,nys_on_file-nbgp:nyn_on_file+nbgp,nxl_on_file-nbgp:nxr_on_file+nbgp) :: tmp_3d   !<
8919
8920    REAL(wp), DIMENSION(0:0,nys_on_file-nbgp:nyn_on_file+nbgp,nxl_on_file-nbgp:nxr_on_file+nbgp) :: tmp_3d2   !<
8921
8922
8923    found = .TRUE.
8924
8925
8926    SELECT CASE ( restart_string(1:length) )
8927
8928       CASE ( 'rad_net_av' )
8929          IF ( .NOT. ALLOCATED( rad_net_av ) )  THEN
8930             ALLOCATE( rad_net_av(nysg:nyng,nxlg:nxrg) )
8931          ENDIF 
8932          IF ( k == 1 )  READ ( 13 )  tmp_2d
8933          rad_net_av(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  =           &
8934                        tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
8935                       
8936       CASE ( 'rad_lw_in_xy_av' )
8937          IF ( .NOT. ALLOCATED( rad_lw_in_xy_av ) )  THEN
8938             ALLOCATE( rad_lw_in_xy_av(nysg:nyng,nxlg:nxrg) )
8939          ENDIF 
8940          IF ( k == 1 )  READ ( 13 )  tmp_2d
8941          rad_lw_in_xy_av(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  =      &
8942                        tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
8943                       
8944       CASE ( 'rad_lw_out_xy_av' )
8945          IF ( .NOT. ALLOCATED( rad_lw_out_xy_av ) )  THEN
8946             ALLOCATE( rad_lw_out_xy_av(nysg:nyng,nxlg:nxrg) )
8947          ENDIF 
8948          IF ( k == 1 )  READ ( 13 )  tmp_2d
8949          rad_lw_out_xy_av(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  =     &
8950                        tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
8951                       
8952       CASE ( 'rad_sw_in_xy_av' )
8953          IF ( .NOT. ALLOCATED( rad_sw_in_xy_av ) )  THEN
8954             ALLOCATE( rad_sw_in_xy_av(nysg:nyng,nxlg:nxrg) )
8955          ENDIF 
8956          IF ( k == 1 )  READ ( 13 )  tmp_2d
8957          rad_sw_in_xy_av(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  =      &
8958                        tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
8959                       
8960       CASE ( 'rad_sw_out_xy_av' )
8961          IF ( .NOT. ALLOCATED( rad_sw_out_xy_av ) )  THEN
8962             ALLOCATE( rad_sw_out_xy_av(nysg:nyng,nxlg:nxrg) )
8963          ENDIF 
8964          IF ( k == 1 )  READ ( 13 )  tmp_2d
8965          rad_sw_out_xy_av(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  =     &
8966                        tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
8967                       
8968       CASE ( 'rad_lw_in' )
8969          IF ( .NOT. ALLOCATED( rad_lw_in ) )  THEN
8970             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
8971                  radiation_scheme == 'constant')  THEN
8972                ALLOCATE( rad_lw_in(0:0,nysg:nyng,nxlg:nxrg) )
8973             ELSE
8974                ALLOCATE( rad_lw_in(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
8975             ENDIF
8976          ENDIF 
8977          IF ( k == 1 )  THEN
8978             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
8979                  radiation_scheme == 'constant')  THEN
8980                READ ( 13 )  tmp_3d2
8981                rad_lw_in(0:0,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =   &
8982                   tmp_3d2(0:0,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
8983             ELSE
8984                READ ( 13 )  tmp_3d
8985                rad_lw_in(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =     &
8986                    tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
8987             ENDIF
8988          ENDIF
8989
8990       CASE ( 'rad_lw_in_av' )
8991          IF ( .NOT. ALLOCATED( rad_lw_in_av ) )  THEN
8992             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
8993                  radiation_scheme == 'constant')  THEN
8994                ALLOCATE( rad_lw_in_av(0:0,nysg:nyng,nxlg:nxrg) )
8995             ELSE
8996                ALLOCATE( rad_lw_in_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
8997             ENDIF
8998          ENDIF 
8999          IF ( k == 1 )  THEN
9000             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
9001                  radiation_scheme == 'constant')  THEN
9002                READ ( 13 )  tmp_3d2
9003                rad_lw_in_av(0:0,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =&
9004                    tmp_3d2(0:0,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
9005             ELSE
9006                READ ( 13 )  tmp_3d
9007                rad_lw_in_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =  &
9008                    tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
9009             ENDIF
9010          ENDIF
9011
9012       CASE ( 'rad_lw_out' )
9013          IF ( .NOT. ALLOCATED( rad_lw_out ) )  THEN
9014             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
9015                  radiation_scheme == 'constant')  THEN
9016                ALLOCATE( rad_lw_out(0:0,nysg:nyng,nxlg:nxrg) )
9017             ELSE
9018                ALLOCATE( rad_lw_out(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
9019             ENDIF
9020          ENDIF 
9021          IF ( k == 1 )  THEN
9022             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
9023                  radiation_scheme == 'constant')  THEN
9024                READ ( 13 )  tmp_3d2
9025                rad_lw_out(0:0,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =  &
9026                    tmp_3d2(0:0,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
9027             ELSE
9028                READ ( 13 )  tmp_3d
9029                rad_lw_out(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =    &
9030                    tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
9031             ENDIF
9032          ENDIF
9033
9034       CASE ( 'rad_lw_out_av' )
9035          IF ( .NOT. ALLOCATED( rad_lw_out_av ) )  THEN
9036             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
9037                  radiation_scheme == 'constant')  THEN
9038                ALLOCATE( rad_lw_out_av(0:0,nysg:nyng,nxlg:nxrg) )
9039             ELSE
9040                ALLOCATE( rad_lw_out_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
9041             ENDIF
9042          ENDIF 
9043          IF ( k == 1 )  THEN
9044             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
9045                  radiation_scheme == 'constant')  THEN
9046                READ ( 13 )  tmp_3d2
9047                rad_lw_out_av(0:0,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) &
9048                   = tmp_3d2(0:0,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
9049             ELSE
9050                READ ( 13 )  tmp_3d
9051                rad_lw_out_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) = &
9052                    tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
9053             ENDIF
9054          ENDIF
9055
9056       CASE ( 'rad_lw_cs_hr' )
9057          IF ( .NOT. ALLOCATED( rad_lw_cs_hr ) )  THEN
9058             ALLOCATE( rad_lw_cs_hr(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
9059          ENDIF
9060          IF ( k == 1 )  READ ( 13 )  tmp_3d
9061          rad_lw_cs_hr(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =        &
9062                  tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
9063
9064       CASE ( 'rad_lw_cs_hr_av' )
9065          IF ( .NOT. ALLOCATED( rad_lw_cs_hr_av ) )  THEN
9066             ALLOCATE( rad_lw_cs_hr_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
9067          ENDIF
9068          IF ( k == 1 )  READ ( 13 )  tmp_3d
9069          rad_lw_cs_hr_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =     &
9070                  tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
9071
9072       CASE ( 'rad_lw_hr' )
9073          IF ( .NOT. ALLOCATED( rad_lw_hr ) )  THEN
9074             ALLOCATE( rad_lw_hr(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
9075          ENDIF
9076          IF ( k == 1 )  READ ( 13 )  tmp_3d
9077          rad_lw_hr(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =           &
9078                  tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
9079
9080       CASE ( 'rad_lw_hr_av' )
9081          IF ( .NOT. ALLOCATED( rad_lw_hr_av ) )  THEN
9082             ALLOCATE( rad_lw_hr_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
9083          ENDIF
9084          IF ( k == 1 )  READ ( 13 )  tmp_3d
9085          rad_lw_hr_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =        &
9086                  tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
9087
9088       CASE ( 'rad_sw_in' )
9089          IF ( .NOT. ALLOCATED( rad_sw_in ) )  THEN
9090             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
9091                  radiation_scheme == 'constant')  THEN
9092                ALLOCATE( rad_sw_in(0:0,nysg:nyng,nxlg:nxrg) )
9093             ELSE
9094                ALLOCATE( rad_sw_in(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
9095             ENDIF
9096          ENDIF 
9097          IF ( k == 1 )  THEN
9098             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
9099                  radiation_scheme == 'constant')  THEN
9100                READ ( 13 )  tmp_3d2
9101                rad_sw_in(0:0,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =   &
9102                    tmp_3d2(0:0,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
9103             ELSE
9104                READ ( 13 )  tmp_3d
9105                rad_sw_in(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =     &
9106                    tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
9107             ENDIF
9108          ENDIF
9109
9110       CASE ( 'rad_sw_in_av' )
9111          IF ( .NOT. ALLOCATED( rad_sw_in_av ) )  THEN
9112             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
9113                  radiation_scheme == 'constant')  THEN
9114                ALLOCATE( rad_sw_in_av(0:0,nysg:nyng,nxlg:nxrg) )
9115             ELSE
9116                ALLOCATE( rad_sw_in_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
9117             ENDIF
9118          ENDIF 
9119          IF ( k == 1 )  THEN
9120             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
9121                  radiation_scheme == 'constant')  THEN
9122                READ ( 13 )  tmp_3d2
9123                rad_sw_in_av(0:0,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =&
9124                    tmp_3d2(0:0,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
9125             ELSE
9126                READ ( 13 )  tmp_3d
9127                rad_sw_in_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =  &
9128                    tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
9129             ENDIF
9130          ENDIF
9131
9132       CASE ( 'rad_sw_out' )
9133          IF ( .NOT. ALLOCATED( rad_sw_out ) )  THEN
9134             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
9135                  radiation_scheme == 'constant')  THEN
9136                ALLOCATE( rad_sw_out(0:0,nysg:nyng,nxlg:nxrg) )
9137             ELSE
9138                ALLOCATE( rad_sw_out(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
9139             ENDIF
9140          ENDIF 
9141          IF ( k == 1 )  THEN
9142             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
9143                  radiation_scheme == 'constant')  THEN
9144                READ ( 13 )  tmp_3d2
9145                rad_sw_out(0:0,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =  &
9146                    tmp_3d2(0:0,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
9147             ELSE
9148                READ ( 13 )  tmp_3d
9149                rad_sw_out(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =    &
9150                    tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
9151             ENDIF
9152          ENDIF
9153
9154       CASE ( 'rad_sw_out_av' )
9155          IF ( .NOT. ALLOCATED( rad_sw_out_av ) )  THEN
9156             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
9157                  radiation_scheme == 'constant')  THEN
9158                ALLOCATE( rad_sw_out_av(0:0,nysg:nyng,nxlg:nxrg) )
9159             ELSE
9160                ALLOCATE( rad_sw_out_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
9161             ENDIF
9162          ENDIF 
9163          IF ( k == 1 )  THEN
9164             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
9165                  radiation_scheme == 'constant')  THEN
9166                READ ( 13 )  tmp_3d2
9167                rad_sw_out_av(0:0,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) &
9168                   = tmp_3d2(0:0,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
9169             ELSE
9170                READ ( 13 )  tmp_3d
9171                rad_sw_out_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) = &
9172                    tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
9173             ENDIF
9174          ENDIF
9175
9176       CASE ( 'rad_sw_cs_hr' )
9177          IF ( .NOT. ALLOCATED( rad_sw_cs_hr ) )  THEN
9178             ALLOCATE( rad_sw_cs_hr(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
9179          ENDIF
9180          IF ( k == 1 )  READ ( 13 )  tmp_3d
9181          rad_sw_cs_hr(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =        &
9182                  tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
9183
9184       CASE ( 'rad_sw_cs_hr_av' )
9185          IF ( .NOT. ALLOCATED( rad_sw_cs_hr_av ) )  THEN
9186             ALLOCATE( rad_sw_cs_hr_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
9187          ENDIF
9188          IF ( k == 1 )  READ ( 13 )  tmp_3d
9189          rad_sw_cs_hr_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =     &
9190                  tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
9191
9192       CASE ( 'rad_sw_hr' )
9193          IF ( .NOT. ALLOCATED( rad_sw_hr ) )  THEN
9194             ALLOCATE( rad_sw_hr(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
9195          ENDIF
9196          IF ( k == 1 )  READ ( 13 )  tmp_3d
9197          rad_sw_hr(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =           &
9198                  tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
9199
9200       CASE ( 'rad_sw_hr_av' )
9201          IF ( .NOT. ALLOCATED( rad_sw_hr_av ) )  THEN
9202             ALLOCATE( rad_sw_hr_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
9203          ENDIF
9204          IF ( k == 1 )  READ ( 13 )  tmp_3d
9205          rad_lw_hr_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =        &
9206                  tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
9207
9208       CASE DEFAULT
9209
9210          found = .FALSE.
9211
9212    END SELECT
9213
9214 END SUBROUTINE radiation_rrd_local
9215
9216!------------------------------------------------------------------------------!
9217! Description:
9218! ------------
9219!> Subroutine writes debug information
9220!------------------------------------------------------------------------------!
9221 SUBROUTINE radiation_write_debug_log ( message )
9222    !> it writes debug log with time stamp
9223    CHARACTER(*)  :: message
9224    CHARACTER(15) :: dtc
9225    CHARACTER(8)  :: date
9226    CHARACTER(10) :: time
9227    CHARACTER(5)  :: zone
9228    CALL date_and_time(date, time, zone)
9229    dtc = date(7:8)//','//time(1:2)//':'//time(3:4)//':'//time(5:10)
9230    WRITE(9,'(2A)') dtc, TRIM(message)
9231    FLUSH(9)
9232 END SUBROUTINE radiation_write_debug_log
9233
9234 END MODULE radiation_model_mod
Note: See TracBrowser for help on using the repository browser.