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

Last change on this file since 3351 was 3351, checked in by suehring, 7 years ago

Do not overwrite values of albedo in radiation_init in case albedo has been already initialized in the urban-surface model via ASCII input

  • Property svn:keywords set to Id
File size: 448.8 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 Institute of Computer Science of the
18!                     Czech Academy of Sciences, Prague
19! Copyright 2015-2018 Czech Technical University in 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 3351 2018-10-15 18:40:42Z suehring $
30! Do not overwrite values of spectral and broadband albedo during initialization
31! if they are already initialized in the urban-surface model via ASCII input.
32!
33! 3337 2018-10-12 15:17:09Z kanani
34! - New RTM version 2.9: (Pavel Krc, Jaroslav Resler, ICS, Prague)
35!   added calculation of the MRT inside the RTM module
36!   MRT fluxes are consequently used in the new biometeorology module
37!   for calculation of biological indices (MRT, PET)
38!   Fixes of v. 2.5 and SVN trunk:
39!    - proper initialization of rad_net_l
40!    - make arrays nsurfs and surfstart TARGET to prevent some MPI problems
41!    - initialization of arrays used in MPI one-sided operation as 1-D arrays
42!      to prevent problems with some MPI/compiler combinations
43!    - fix indexing of target displacement in subroutine request_itarget to
44!      consider nzub
45!    - fix LAD dimmension range in PCB calculation
46!    - check ierr in all MPI calls
47!    - use proper per-gridbox sky and diffuse irradiance
48!    - fix shading for reflected irradiance
49!    - clear away the residuals of "atmospheric surfaces" implementation
50!    - fix rounding bug in raytrace_2d introduced in SVN trunk
51! - New RTM version 2.5: (Pavel Krc, Jaroslav Resler, ICS, Prague)
52!   can use angular discretization for all SVF
53!   (i.e. reflected and emitted radiation in addition to direct and diffuse),
54!   allowing for much better scaling wih high resoltion and/or complex terrain
55! - Unite array grow factors
56! - Fix slightly shifted terrain height in raytrace_2d
57! - Use more efficient MPI_Win_allocate for reverse gridsurf index
58! - Fix random MPI RMA bugs on Intel compilers
59! - Fix approx. double plant canopy sink values for reflected radiation
60! - Fix mostly missing plant canopy sinks for direct radiation
61! - Fix discretization errors for plant canopy sink in diffuse radiation
62! - Fix rounding errors in raytrace_2d
63!
64! 3274 2018-09-24 15:42:55Z knoop
65! Modularization of all bulk cloud physics code components
66!
67! 3272 2018-09-24 10:16:32Z suehring
68! - split direct and diffusion shortwave radiation using RRTMG rather than using
69!   calc_diffusion_radiation, in case of RRTMG
70! - removed the namelist variable split_diffusion_radiation. Now splitting depends
71!   on the choise of radiation radiation scheme
72! - removed calculating the rdiation flux for surfaces at the radiation scheme
73!   in case of using RTM since it will be calculated anyway in the radiation
74!   interaction routine.
75! - set SW radiation flux for surfaces to zero at night in case of no RTM is used
76! - precalculate the unit vector yxdir of ray direction to avoid the temporarly
77!   array allocation during the subroutine call
78! - fixed a bug in calculating the max number of boxes ray can cross in the domain
79!
80! 3264 2018-09-20 13:54:11Z moh.hefny
81! Bugfix in raytrace_2d calls
82!
83! 3248 2018-09-14 09:42:06Z sward
84! Minor formating changes
85!
86! 3246 2018-09-13 15:14:50Z sward
87! Added error handling for input namelist via parin_fail_message
88!
89! 3241 2018-09-12 15:02:00Z raasch
90! unused variables removed or commented
91!
92! 3233 2018-09-07 13:21:24Z schwenkel
93! Adapted for the use of cloud_droplets
94!
95! 3230 2018-09-05 09:29:05Z schwenkel
96! Bugfix in radiation_constant_surf: changed (10.0 - emissivity_urb) to
97! (1.0 - emissivity_urb)
98!
99! 3226 2018-08-31 12:27:09Z suehring
100! Bugfixes in calculation of sky-view factors and canopy-sink factors.
101!
102! 3186 2018-07-30 17:07:14Z suehring
103! Remove print statement
104!
105! 3180 2018-07-27 11:00:56Z suehring
106! Revise concept for calculation of effective radiative temperature and mapping
107! of radiative heating
108!
109! 3175 2018-07-26 14:07:38Z suehring
110! Bugfix for commit 3172
111!
112! 3173 2018-07-26 12:55:23Z suehring
113! Revise output of surface radiation quantities in case of overhanging
114! structures
115!
116! 3172 2018-07-26 12:06:06Z suehring
117! Bugfixes:
118!  - temporal work-around for calculation of effective radiative surface
119!    temperature
120!  - prevent positive solar radiation during nighttime
121!
122! 3170 2018-07-25 15:19:37Z suehring
123! Bugfix, map signle-column radiation forcing profiles on top of any topography
124!
125! 3156 2018-07-19 16:30:54Z knoop
126! Bugfix: replaced usage of the pt array with the surf%pt_surface array
127!
128! 3137 2018-07-17 06:44:21Z maronga
129! String length for trace_names fixed
130!
131! 3127 2018-07-15 08:01:25Z maronga
132! A few pavement parameters updated.
133!
134! 3123 2018-07-12 16:21:53Z suehring
135! Correct working precision for INTEGER number
136!
137! 3122 2018-07-11 21:46:41Z maronga
138! Bugfix: maximum distance for raytracing was set to  -999 m by default,
139! effectively switching off all surface reflections when max_raytracing_dist
140! was not explicitly set in namelist
141!
142! 3117 2018-07-11 09:59:11Z maronga
143! Bugfix: water vapor was not transfered to RRTMG when bulk_cloud_model = .F.
144! Bugfix: changed the calculation of RRTMG boundary conditions (Mohamed Salim)
145! Bugfix: dry residual atmosphere is replaced by standard RRTMG atmosphere
146!
147! 3116 2018-07-10 14:31:58Z suehring
148! Output of long/shortwave radiation at surface
149!
150! 3107 2018-07-06 15:55:51Z suehring
151! Bugfix, missing index for dz
152!
153! 3066 2018-06-12 08:55:55Z Giersch
154! Error message revised
155!
156! 3065 2018-06-12 07:03:02Z Giersch
157! dz was replaced by dz(1), error message concerning vertical stretching was
158! added 
159!
160! 3049 2018-05-29 13:52:36Z Giersch
161! Error messages revised
162!
163! 3045 2018-05-28 07:55:41Z Giersch
164! Error message revised
165!
166! 3026 2018-05-22 10:30:53Z schwenkel
167! Changed the name specific humidity to mixing ratio, since we are computing
168! mixing ratios.
169!
170! 3016 2018-05-09 10:53:37Z Giersch
171! Revised structure of reading svf data according to PALM coding standard:
172! svf_code_field/len and fsvf removed, error messages PA0493 and PA0494 added,
173! allocation status of output arrays checked.
174!
175! 3014 2018-05-09 08:42:38Z maronga
176! Introduced plant canopy height similar to urban canopy height to limit
177! the memory requirement to allocate lad.
178! Deactivated automatic setting of minimum raytracing distance.
179!
180! 3004 2018-04-27 12:33:25Z Giersch
181! Further allocation checks implemented (averaged data will be assigned to fill
182! values if no allocation happened so far)
183!
184! 2995 2018-04-19 12:13:16Z Giersch
185! IF-statement in radiation_init removed so that the calculation of radiative
186! fluxes at model start is done in any case, bugfix in
187! radiation_presimulate_solar_pos (end_time is the sum of end_time and the
188! spinup_time specified in the p3d_file ), list of variables/fields that have
189! to be written out or read in case of restarts has been extended
190!
191! 2977 2018-04-17 10:27:57Z kanani
192! Implement changes from branch radiation (r2948-2971) with minor modifications,
193! plus some formatting.
194! (moh.hefny):
195! - replaced plant_canopy by npcbl to check tree existence to avoid weird
196!   allocation of related arrays (after domain decomposition some domains
197!   contains no trees although plant_canopy (global parameter) is still TRUE).
198! - added a namelist parameter to force RTM settings
199! - enabled the option to switch radiation reflections off
200! - renamed surf_reflections to surface_reflections
201! - removed average_radiation flag from the namelist (now it is implicitly set
202!   in init_3d_model according to RTM)
203! - edited read and write sky view factors and CSF routines to account for
204!   the sub-domains which may not contain any of them
205!
206! 2967 2018-04-13 11:22:08Z raasch
207! bugfix: missing parallel cpp-directives added
208!
209! 2964 2018-04-12 16:04:03Z Giersch
210! Error message PA0491 has been introduced which could be previously found in
211! check_open. The variable numprocs_previous_run is only known in case of
212! initializing_actions == read_restart_data
213!
214! 2963 2018-04-12 14:47:44Z suehring
215! - Introduce index for vegetation/wall, pavement/green-wall and water/window
216!   surfaces, for clearer access of surface fraction, albedo, emissivity, etc. .
217! - Minor bugfix in initialization of albedo for window surfaces
218!
219! 2944 2018-04-03 16:20:18Z suehring
220! Fixed bad commit
221!
222! 2943 2018-04-03 16:17:10Z suehring
223! No read of nsurfl from SVF file since it is calculated in
224! radiation_interaction_init,
225! allocation of arrays in radiation_read_svf only if not yet allocated,
226! update of 2920 revision comment.
227!
228! 2932 2018-03-26 09:39:22Z maronga
229! renamed radiation_par to radiation_parameters
230!
231! 2930 2018-03-23 16:30:46Z suehring
232! Remove default surfaces from radiation model, does not make much sense to
233! apply radiation model without energy-balance solvers; Further, add check for
234! this.
235!
236! 2920 2018-03-22 11:22:01Z kanani
237! - Bugfix: Initialize pcbl array (=-1)
238! RTM version 2.0 (Jaroslav Resler, Pavel Krc, Mohamed Salim):
239! - new major version of radiation interactions
240! - substantially enhanced performance and scalability
241! - processing of direct and diffuse solar radiation separated from reflected
242!   radiation, removed virtual surfaces
243! - new type of sky discretization by azimuth and elevation angles
244! - diffuse radiation processed cumulatively using sky view factor
245! - used precalculated apparent solar positions for direct irradiance
246! - added new 2D raytracing process for processing whole vertical column at once
247!   to increase memory efficiency and decrease number of MPI RMA operations
248! - enabled limiting the number of view factors between surfaces by the distance
249!   and value
250! - fixing issues induced by transferring radiation interactions from
251!   urban_surface_mod to radiation_mod
252! - bugfixes and other minor enhancements
253!
254! 2906 2018-03-19 08:56:40Z Giersch
255! NAMELIST paramter read/write_svf_on_init have been removed, functions
256! check_open and close_file are used now for opening/closing files related to
257! svf data, adjusted unit number and error numbers
258!
259! 2894 2018-03-15 09:17:58Z Giersch
260! Calculations of the index range of the subdomain on file which overlaps with
261! the current subdomain are already done in read_restart_data_mod
262! radiation_read_restart_data was renamed to radiation_rrd_local and
263! radiation_last_actions was renamed to radiation_wrd_local, variable named
264! found has been introduced for checking if restart data was found, reading
265! of restart strings has been moved completely to read_restart_data_mod,
266! radiation_rrd_local is already inside the overlap loop programmed in
267! read_restart_data_mod, the marker *** end rad *** is not necessary anymore,
268! strings and their respective lengths are written out and read now in case of
269! restart runs to get rid of prescribed character lengths (Giersch)
270!
271! 2809 2018-02-15 09:55:58Z suehring
272! Bugfix for gfortran: Replace the function C_SIZEOF with STORAGE_SIZE
273!
274! 2753 2018-01-16 14:16:49Z suehring
275! Tile approach for spectral albedo implemented.
276!
277! 2746 2018-01-15 12:06:04Z suehring
278! Move flag plant canopy to modules
279!
280! 2724 2018-01-05 12:12:38Z maronga
281! Set default of average_radiation to .FALSE.
282!
283! 2723 2018-01-05 09:27:03Z maronga
284! Bugfix in calculation of rad_lw_out (clear-sky). First grid level was used
285! instead of the surface value
286!
287! 2718 2018-01-02 08:49:38Z maronga
288! Corrected "Former revisions" section
289!
290! 2707 2017-12-18 18:34:46Z suehring
291! Changes from last commit documented
292!
293! 2706 2017-12-18 18:33:49Z suehring
294! Bugfix, in average radiation case calculate exner function before using it.
295!
296! 2701 2017-12-15 15:40:50Z suehring
297! Changes from last commit documented
298!
299! 2698 2017-12-14 18:46:24Z suehring
300! Bugfix in get_topography_top_index
301!
302! 2696 2017-12-14 17:12:51Z kanani
303! - Change in file header (GPL part)
304! - Improved reading/writing of SVF from/to file (BM)
305! - Bugfixes concerning RRTMG as well as average_radiation options (M. Salim)
306! - Revised initialization of surface albedo and some minor bugfixes (MS)
307! - Update net radiation after running radiation interaction routine (MS)
308! - Revisions from M Salim included
309! - Adjustment to topography and surface structure (MS)
310! - Initialization of albedo and surface emissivity via input file (MS)
311! - albedo_pars extended (MS)
312!
313! 2604 2017-11-06 13:29:00Z schwenkel
314! bugfix for calculation of effective radius using morrison microphysics
315!
316! 2601 2017-11-02 16:22:46Z scharf
317! added emissivity to namelist
318!
319! 2575 2017-10-24 09:57:58Z maronga
320! Bugfix: calculation of shortwave and longwave albedos for RRTMG swapped
321!
322! 2547 2017-10-16 12:41:56Z schwenkel
323! extended by cloud_droplets option, minor bugfix and correct calculation of
324! cloud droplet number concentration
325!
326! 2544 2017-10-13 18:09:32Z maronga
327! Moved date and time quantitis to separate module date_and_time_mod
328!
329! 2512 2017-10-04 08:26:59Z raasch
330! upper bounds of cross section and 3d output changed from nx+1,ny+1 to nx,ny
331! no output of ghost layer data
332!
333! 2504 2017-09-27 10:36:13Z maronga
334! Updates pavement types and albedo parameters
335!
336! 2328 2017-08-03 12:34:22Z maronga
337! Emissivity can now be set individually for each pixel.
338! Albedo type can be inferred from land surface model.
339! Added default albedo type for bare soil
340!
341! 2318 2017-07-20 17:27:44Z suehring
342! Get topography top index via Function call
343!
344! 2317 2017-07-20 17:27:19Z suehring
345! Improved syntax layout
346!
347! 2298 2017-06-29 09:28:18Z raasch
348! type of write_binary changed from CHARACTER to LOGICAL
349!
350! 2296 2017-06-28 07:53:56Z maronga
351! Added output of rad_sw_out for radiation_scheme = 'constant'
352!
353! 2270 2017-06-09 12:18:47Z maronga
354! Numbering changed (2 timeseries removed)
355!
356! 2249 2017-06-06 13:58:01Z sward
357! Allow for RRTMG runs without humidity/cloud physics
358!
359! 2248 2017-06-06 13:52:54Z sward
360! Error no changed
361!
362! 2233 2017-05-30 18:08:54Z suehring
363!
364! 2232 2017-05-30 17:47:52Z suehring
365! Adjustments to new topography concept
366! Bugfix in read restart
367!
368! 2200 2017-04-11 11:37:51Z suehring
369! Bugfix in call of exchange_horiz_2d and read restart data
370!
371! 2163 2017-03-01 13:23:15Z schwenkel
372! Bugfix in radiation_check_data_output
373!
374! 2157 2017-02-22 15:10:35Z suehring
375! Bugfix in read_restart data
376!
377! 2011 2016-09-19 17:29:57Z kanani
378! Removed CALL of auxiliary SUBROUTINE get_usm_info,
379! flag urban_surface is now defined in module control_parameters.
380!
381! 2007 2016-08-24 15:47:17Z kanani
382! Added calculation of solar directional vector for new urban surface
383! model,
384! accounted for urban_surface model in radiation_check_parameters,
385! correction of comments for zenith angle.
386!
387! 2000 2016-08-20 18:09:15Z knoop
388! Forced header and separation lines into 80 columns
389!
390! 1976 2016-07-27 13:28:04Z maronga
391! Output of 2D/3D/masked data is now directly done within this module. The
392! radiation schemes have been simplified for better usability so that
393! rad_lw_in, rad_lw_out, rad_sw_in, and rad_sw_out are available independent of
394! the radiation code used.
395!
396! 1856 2016-04-13 12:56:17Z maronga
397! Bugfix: allocation of rad_lw_out for radiation_scheme = 'clear-sky'
398!
399! 1853 2016-04-11 09:00:35Z maronga
400! Added routine for radiation_scheme = constant.
401
402! 1849 2016-04-08 11:33:18Z hoffmann
403! Adapted for modularization of microphysics
404!
405! 1826 2016-04-07 12:01:39Z maronga
406! Further modularization.
407!
408! 1788 2016-03-10 11:01:04Z maronga
409! Added new albedo class for pavements / roads.
410!
411! 1783 2016-03-06 18:36:17Z raasch
412! palm-netcdf-module removed in order to avoid a circular module dependency,
413! netcdf-variables moved to netcdf-module, new routine netcdf_handle_error_rad
414! added
415!
416! 1757 2016-02-22 15:49:32Z maronga
417! Added parameter unscheduled_radiation_calls. Bugfix: interpolation of sounding
418! profiles for pressure and temperature above the LES domain.
419!
420! 1709 2015-11-04 14:47:01Z maronga
421! Bugfix: set initial value for rrtm_lwuflx_dt to zero, small formatting
422! corrections
423!
424! 1701 2015-11-02 07:43:04Z maronga
425! Bugfixes: wrong index for output of timeseries, setting of nz_snd_end
426!
427! 1691 2015-10-26 16:17:44Z maronga
428! Added option for spin-up runs without radiation (skip_time_do_radiation). Bugfix
429! in calculation of pressure profiles. Bugfix in calculation of trace gas profiles.
430! Added output of radiative heating rates.
431!
432! 1682 2015-10-07 23:56:08Z knoop
433! Code annotations made doxygen readable
434!
435! 1606 2015-06-29 10:43:37Z maronga
436! Added preprocessor directive __netcdf to allow for compiling without netCDF.
437! Note, however, that RRTMG cannot be used without netCDF.
438!
439! 1590 2015-05-08 13:56:27Z maronga
440! Bugfix: definition of character strings requires same length for all elements
441!
442! 1587 2015-05-04 14:19:01Z maronga
443! Added albedo class for snow
444!
445! 1585 2015-04-30 07:05:52Z maronga
446! Added support for RRTMG
447!
448! 1571 2015-03-12 16:12:49Z maronga
449! Added missing KIND attribute. Removed upper-case variable names
450!
451! 1551 2015-03-03 14:18:16Z maronga
452! Added support for data output. Various variables have been renamed. Added
453! interface for different radiation schemes (currently: clear-sky, constant, and
454! RRTM (not yet implemented).
455!
456! 1496 2014-12-02 17:25:50Z maronga
457! Initial revision
458!
459!
460! Description:
461! ------------
462!> Radiation models and interfaces
463!> @todo Replace dz(1) appropriatly to account for grid stretching
464!> @todo move variable definitions used in radiation_init only to the subroutine
465!>       as they are no longer required after initialization.
466!> @todo Output of full column vertical profiles used in RRTMG
467!> @todo Output of other rrtm arrays (such as volume mixing ratios)
468!> @todo Check for mis-used NINT() calls in raytrace_2d
469!>       RESULT: Original was correct (carefully verified formula), the change
470!>               to INT broke raytracing      -- P. Krc
471!> @todo Optimize radiation_tendency routines
472!>
473!> @note Many variables have a leading dummy dimension (0:0) in order to
474!>       match the assume-size shape expected by the RRTMG model.
475!------------------------------------------------------------------------------!
476 MODULE radiation_model_mod
477 
478    USE arrays_3d,                                                             &
479        ONLY:  dzw, hyp, nc, pt, p, q, ql, u, v, w, zu, zw, exner, d_exner
480
481    USE basic_constants_and_equations_mod,                                     &
482        ONLY:  c_p, g, lv_d_cp, l_v, pi, r_d, rho_l, solar_constant,           &
483               barometric_formula
484
485    USE calc_mean_profile_mod,                                                 &
486        ONLY:  calc_mean_profile
487
488    USE control_parameters,                                                    &
489        ONLY:  cloud_droplets, coupling_char, dz,                              &
490               humidity,                                                       &
491               initializing_actions, io_blocks, io_group,                      &
492               latitude, longitude, large_scale_forcing, lsf_surf,             &
493               message_string, plant_canopy, pt_surface,&
494               rho_surface, surface_pressure, time_since_reference_point,      &
495               urban_surface, land_surface, end_time, spinup_time, dt_spinup
496
497    USE cpulog,                                                                &
498        ONLY:  cpu_log, log_point, log_point_s
499
500    USE grid_variables,                                                        &
501         ONLY:  ddx, ddy, dx, dy 
502
503    USE date_and_time_mod,                                                     &
504        ONLY:  calc_date_and_time, d_hours_day, d_seconds_hour, day_of_year,   &
505               d_seconds_year, day_of_year_init, time_utc_init, time_utc
506
507    USE indices,                                                               &
508        ONLY:  nnx, nny, nx, nxl, nxlg, nxr, nxrg, ny, nyn, nyng, nys, nysg,   &
509               nzb, nzt
510
511    USE, INTRINSIC :: iso_c_binding
512
513    USE kinds
514
515    USE bulk_cloud_model_mod,                                                  &
516        ONLY:  bulk_cloud_model, microphysics_morrison, na_init, nc_const, sigma_gc
517
518#if defined ( __netcdf )
519    USE NETCDF
520#endif
521
522    USE netcdf_data_input_mod,                                                 &
523        ONLY:  albedo_type_f, albedo_pars_f, building_type_f, pavement_type_f, &
524               vegetation_type_f, water_type_f
525
526    USE plant_canopy_model_mod,                                                &
527        ONLY:  lad_s, pc_heating_rate, pc_transpiration_rate
528
529    USE pegrid
530
531#if defined ( __rrtmg )
532    USE parrrsw,                                                               &
533        ONLY:  naerec, nbndsw
534
535    USE parrrtm,                                                               &
536        ONLY:  nbndlw
537
538    USE rrtmg_lw_init,                                                         &
539        ONLY:  rrtmg_lw_ini
540
541    USE rrtmg_sw_init,                                                         &
542        ONLY:  rrtmg_sw_ini
543
544    USE rrtmg_lw_rad,                                                          &
545        ONLY:  rrtmg_lw
546
547    USE rrtmg_sw_rad,                                                          &
548        ONLY:  rrtmg_sw
549#endif
550    USE statistics,                                                            &
551        ONLY:  hom
552
553    USE surface_mod,                                                           &
554        ONLY:  get_topography_top_index, get_topography_top_index_ji,          &
555               ind_pav_green, ind_veg_wall, ind_wat_win,                       &
556               surf_lsm_h, surf_lsm_v, surf_type, surf_usm_h, surf_usm_v
557
558    IMPLICIT NONE
559
560    CHARACTER(10) :: radiation_scheme = 'clear-sky' ! 'constant', 'clear-sky', or 'rrtmg'
561
562!
563!-- Predefined Land surface classes (albedo_type) after Briegleb (1992)
564    CHARACTER(37), DIMENSION(0:33), PARAMETER :: albedo_type_name = (/      &
565                                   'user defined                         ', & !  0
566                                   'ocean                                ', & !  1
567                                   'mixed farming, tall grassland        ', & !  2
568                                   'tall/medium grassland                ', & !  3
569                                   'evergreen shrubland                  ', & !  4
570                                   'short grassland/meadow/shrubland     ', & !  5
571                                   'evergreen needleleaf forest          ', & !  6
572                                   'mixed deciduous evergreen forest     ', & !  7
573                                   'deciduous forest                     ', & !  8
574                                   'tropical evergreen broadleaved forest', & !  9
575                                   'medium/tall grassland/woodland       ', & ! 10
576                                   'desert, sandy                        ', & ! 11
577                                   'desert, rocky                        ', & ! 12
578                                   'tundra                               ', & ! 13
579                                   'land ice                             ', & ! 14
580                                   'sea ice                              ', & ! 15
581                                   'snow                                 ', & ! 16
582                                   'bare soil                            ', & ! 17
583                                   'asphalt/concrete mix                 ', & ! 18
584                                   'asphalt (asphalt concrete)           ', & ! 19
585                                   'concrete (Portland concrete)         ', & ! 20
586                                   'sett                                 ', & ! 21
587                                   'paving stones                        ', & ! 22
588                                   'cobblestone                          ', & ! 23
589                                   'metal                                ', & ! 24
590                                   'wood                                 ', & ! 25
591                                   'gravel                               ', & ! 26
592                                   'fine gravel                          ', & ! 27
593                                   'pebblestone                          ', & ! 28
594                                   'woodchips                            ', & ! 29
595                                   'tartan (sports)                      ', & ! 30
596                                   'artifical turf (sports)              ', & ! 31
597                                   'clay (sports)                        ', & ! 32
598                                   'building (dummy)                     '  & ! 33
599                                                         /)
600
601    REAL(wp), PARAMETER :: sigma_sb       = 5.67037321E-8_wp !< Stefan-Boltzmann constant
602
603    INTEGER(iwp) :: albedo_type  = 9999999, & !< Albedo surface type
604                    dots_rad     = 0          !< starting index for timeseries output
605
606    LOGICAL ::  unscheduled_radiation_calls = .TRUE., & !< flag parameter indicating whether additional calls of the radiation code are allowed
607                constant_albedo = .FALSE.,            & !< flag parameter indicating whether the albedo may change depending on zenith
608                force_radiation_call = .FALSE.,       & !< flag parameter for unscheduled radiation calls
609                lw_radiation = .TRUE.,                & !< flag parameter indicating whether longwave radiation shall be calculated
610                radiation = .FALSE.,                  & !< flag parameter indicating whether the radiation model is used
611                sun_up    = .TRUE.,                   & !< flag parameter indicating whether the sun is up or down
612                sw_radiation = .TRUE.,                & !< flag parameter indicating whether shortwave radiation shall be calculated
613                sun_direction = .FALSE.,              & !< flag parameter indicating whether solar direction shall be calculated
614                average_radiation = .FALSE.,          & !< flag to set the calculation of radiation averaging for the domain
615                radiation_interactions = .FALSE.,     & !< flag to activiate RTM (TRUE only if vertical urban/land surface and trees exist)
616                surface_reflections = .TRUE.,         & !< flag to switch the calculation of radiation interaction between surfaces.
617                                                        !< When it switched off, only the effect of buildings and trees shadow will
618                                                        !< will be considered. However fewer SVFs are expected.
619                radiation_interactions_on = .TRUE.      !< namelist flag to force RTM activiation regardless to vertical urban/land surface and trees
620
621    REAL(wp) :: albedo = 9999999.9_wp,           & !< NAMELIST alpha
622                albedo_lw_dif = 9999999.9_wp,    & !< NAMELIST aldif
623                albedo_lw_dir = 9999999.9_wp,    & !< NAMELIST aldir
624                albedo_sw_dif = 9999999.9_wp,    & !< NAMELIST asdif
625                albedo_sw_dir = 9999999.9_wp,    & !< NAMELIST asdir
626                decl_1,                          & !< declination coef. 1
627                decl_2,                          & !< declination coef. 2
628                decl_3,                          & !< declination coef. 3
629                dt_radiation = 0.0_wp,           & !< radiation model timestep
630                emissivity = 9999999.9_wp,       & !< NAMELIST surface emissivity
631                lon = 0.0_wp,                    & !< longitude in radians
632                lat = 0.0_wp,                    & !< latitude in radians
633                net_radiation = 0.0_wp,          & !< net radiation at surface
634                skip_time_do_radiation = 0.0_wp, & !< Radiation model is not called before this time
635                sky_trans,                       & !< sky transmissivity
636                time_radiation = 0.0_wp            !< time since last call of radiation code
637
638
639    REAL(wp), DIMENSION(0:0) ::  zenith,         & !< cosine of solar zenith angle
640                                 sun_dir_lat,    & !< solar directional vector in latitudes
641                                 sun_dir_lon       !< solar directional vector in longitudes
642
643    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  rad_net_av       !< average of net radiation (rad_net) at surface
644    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  rad_lw_in_xy_av  !< average of incoming longwave radiation at surface
645    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  rad_lw_out_xy_av !< average of outgoing longwave radiation at surface
646    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  rad_sw_in_xy_av  !< average of incoming shortwave radiation at surface
647    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  rad_sw_out_xy_av !< average of outgoing shortwave radiation at surface
648!
649!-- Land surface albedos for solar zenith angle of 60° after Briegleb (1992)     
650!-- (shortwave, longwave, broadband):   sw,      lw,      bb,
651    REAL(wp), DIMENSION(0:2,1:33), PARAMETER :: albedo_pars = RESHAPE( (/& 
652                                   0.06_wp, 0.06_wp, 0.06_wp,            & !  1
653                                   0.09_wp, 0.28_wp, 0.19_wp,            & !  2
654                                   0.11_wp, 0.33_wp, 0.23_wp,            & !  3
655                                   0.11_wp, 0.33_wp, 0.23_wp,            & !  4
656                                   0.14_wp, 0.34_wp, 0.25_wp,            & !  5
657                                   0.06_wp, 0.22_wp, 0.14_wp,            & !  6
658                                   0.06_wp, 0.27_wp, 0.17_wp,            & !  7
659                                   0.06_wp, 0.31_wp, 0.19_wp,            & !  8
660                                   0.06_wp, 0.22_wp, 0.14_wp,            & !  9
661                                   0.06_wp, 0.28_wp, 0.18_wp,            & ! 10
662                                   0.35_wp, 0.51_wp, 0.43_wp,            & ! 11
663                                   0.24_wp, 0.40_wp, 0.32_wp,            & ! 12
664                                   0.10_wp, 0.27_wp, 0.19_wp,            & ! 13
665                                   0.90_wp, 0.65_wp, 0.77_wp,            & ! 14
666                                   0.90_wp, 0.65_wp, 0.77_wp,            & ! 15
667                                   0.95_wp, 0.70_wp, 0.82_wp,            & ! 16
668                                   0.08_wp, 0.08_wp, 0.08_wp,            & ! 17
669                                   0.17_wp, 0.17_wp, 0.17_wp,            & ! 18
670                                   0.17_wp, 0.17_wp, 0.17_wp,            & ! 19
671                                   0.30_wp, 0.30_wp, 0.30_wp,            & ! 20
672                                   0.17_wp, 0.17_wp, 0.17_wp,            & ! 21
673                                   0.17_wp, 0.17_wp, 0.17_wp,            & ! 22
674                                   0.17_wp, 0.17_wp, 0.17_wp,            & ! 23
675                                   0.17_wp, 0.17_wp, 0.17_wp,            & ! 24
676                                   0.17_wp, 0.17_wp, 0.17_wp,            & ! 25
677                                   0.17_wp, 0.17_wp, 0.17_wp,            & ! 26
678                                   0.17_wp, 0.17_wp, 0.17_wp,            & ! 27
679                                   0.17_wp, 0.17_wp, 0.17_wp,            & ! 28
680                                   0.17_wp, 0.17_wp, 0.17_wp,            & ! 29
681                                   0.17_wp, 0.17_wp, 0.17_wp,            & ! 30
682                                   0.17_wp, 0.17_wp, 0.17_wp,            & ! 31
683                                   0.17_wp, 0.17_wp, 0.17_wp,            & ! 32
684                                   0.17_wp, 0.17_wp, 0.17_wp             & ! 33
685                                 /), (/ 3, 33 /) )
686
687    REAL(wp), DIMENSION(:,:,:), ALLOCATABLE, TARGET :: &
688                        rad_lw_cs_hr,                  & !< longwave clear sky radiation heating rate (K/s)
689                        rad_lw_cs_hr_av,               & !< average of rad_lw_cs_hr
690                        rad_lw_hr,                     & !< longwave radiation heating rate (K/s)
691                        rad_lw_hr_av,                  & !< average of rad_sw_hr
692                        rad_lw_in,                     & !< incoming longwave radiation (W/m2)
693                        rad_lw_in_av,                  & !< average of rad_lw_in
694                        rad_lw_out,                    & !< outgoing longwave radiation (W/m2)
695                        rad_lw_out_av,                 & !< average of rad_lw_out
696                        rad_sw_cs_hr,                  & !< shortwave clear sky radiation heating rate (K/s)
697                        rad_sw_cs_hr_av,               & !< average of rad_sw_cs_hr
698                        rad_sw_hr,                     & !< shortwave radiation heating rate (K/s)
699                        rad_sw_hr_av,                  & !< average of rad_sw_hr
700                        rad_sw_in,                     & !< incoming shortwave radiation (W/m2)
701                        rad_sw_in_av,                  & !< average of rad_sw_in
702                        rad_sw_out,                    & !< outgoing shortwave radiation (W/m2)
703                        rad_sw_out_av                    !< average of rad_sw_out
704
705
706!
707!-- Variables and parameters used in RRTMG only
708#if defined ( __rrtmg )
709    CHARACTER(LEN=12) :: rrtm_input_file = "RAD_SND_DATA" !< name of the NetCDF input file (sounding data)
710
711
712!
713!-- Flag parameters for RRTMGS (should not be changed)
714    INTEGER(iwp), PARAMETER :: rrtm_idrv     = 1, & !< flag for longwave upward flux calculation option (0,1)
715                               rrtm_inflglw  = 2, & !< flag for lw cloud optical properties (0,1,2)
716                               rrtm_iceflglw = 0, & !< flag for lw ice particle specifications (0,1,2,3)
717                               rrtm_liqflglw = 1, & !< flag for lw liquid droplet specifications
718                               rrtm_inflgsw  = 2, & !< flag for sw cloud optical properties (0,1,2)
719                               rrtm_iceflgsw = 0, & !< flag for sw ice particle specifications (0,1,2,3)
720                               rrtm_liqflgsw = 1    !< flag for sw liquid droplet specifications
721
722!
723!-- The following variables should be only changed with care, as this will
724!-- require further setting of some variables, which is currently not
725!-- implemented (aerosols, ice phase).
726    INTEGER(iwp) :: nzt_rad,           & !< upper vertical limit for radiation calculations
727                    rrtm_icld = 0,     & !< cloud flag (0: clear sky column, 1: cloudy column)
728                    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)
729
730    INTEGER(iwp) :: nc_stat !< local variable for storin the result of netCDF calls for error message handling
731
732    LOGICAL :: snd_exists = .FALSE.      !< flag parameter to check whether a user-defined input files exists
733
734    REAL(wp), PARAMETER :: mol_mass_air_d_wv = 1.607793_wp !< molecular weight dry air / water vapor
735
736    REAL(wp), DIMENSION(:), ALLOCATABLE :: hyp_snd,     & !< hypostatic pressure from sounding data (hPa)
737                                           rrtm_tsfc,   & !< dummy array for storing surface temperature
738                                           t_snd          !< actual temperature from sounding data (hPa)
739
740    REAL(wp), DIMENSION(:,:), ALLOCATABLE :: rrtm_ccl4vmr,   & !< CCL4 volume mixing ratio (g/mol)
741                                             rrtm_cfc11vmr,  & !< CFC11 volume mixing ratio (g/mol)
742                                             rrtm_cfc12vmr,  & !< CFC12 volume mixing ratio (g/mol)
743                                             rrtm_cfc22vmr,  & !< CFC22 volume mixing ratio (g/mol)
744                                             rrtm_ch4vmr,    & !< CH4 volume mixing ratio
745                                             rrtm_cicewp,    & !< in-cloud ice water path (g/m²)
746                                             rrtm_cldfr,     & !< cloud fraction (0,1)
747                                             rrtm_cliqwp,    & !< in-cloud liquid water path (g/m²)
748                                             rrtm_co2vmr,    & !< CO2 volume mixing ratio (g/mol)
749                                             rrtm_emis,      & !< surface emissivity (0-1) 
750                                             rrtm_h2ovmr,    & !< H2O volume mixing ratio
751                                             rrtm_n2ovmr,    & !< N2O volume mixing ratio
752                                             rrtm_o2vmr,     & !< O2 volume mixing ratio
753                                             rrtm_o3vmr,     & !< O3 volume mixing ratio
754                                             rrtm_play,      & !< pressure layers (hPa, zu-grid)
755                                             rrtm_plev,      & !< pressure layers (hPa, zw-grid)
756                                             rrtm_reice,     & !< cloud ice effective radius (microns)
757                                             rrtm_reliq,     & !< cloud water drop effective radius (microns)
758                                             rrtm_tlay,      & !< actual temperature (K, zu-grid)
759                                             rrtm_tlev,      & !< actual temperature (K, zw-grid)
760                                             rrtm_lwdflx,    & !< RRTM output of incoming longwave radiation flux (W/m2)
761                                             rrtm_lwdflxc,   & !< RRTM output of outgoing clear sky longwave radiation flux (W/m2)
762                                             rrtm_lwuflx,    & !< RRTM output of outgoing longwave radiation flux (W/m2)
763                                             rrtm_lwuflxc,   & !< RRTM output of incoming clear sky longwave radiation flux (W/m2)
764                                             rrtm_lwuflx_dt, & !< RRTM output of incoming clear sky longwave radiation flux (W/m2)
765                                             rrtm_lwuflxc_dt,& !< RRTM output of outgoing clear sky longwave radiation flux (W/m2)
766                                             rrtm_lwhr,      & !< RRTM output of longwave radiation heating rate (K/d)
767                                             rrtm_lwhrc,     & !< RRTM output of incoming longwave clear sky radiation heating rate (K/d)
768                                             rrtm_swdflx,    & !< RRTM output of incoming shortwave radiation flux (W/m2)
769                                             rrtm_swdflxc,   & !< RRTM output of outgoing clear sky shortwave radiation flux (W/m2)
770                                             rrtm_swuflx,    & !< RRTM output of outgoing shortwave radiation flux (W/m2)
771                                             rrtm_swuflxc,   & !< RRTM output of incoming clear sky shortwave radiation flux (W/m2)
772                                             rrtm_swhr,      & !< RRTM output of shortwave radiation heating rate (K/d)
773                                             rrtm_swhrc,     & !< RRTM output of incoming shortwave clear sky radiation heating rate (K/d)
774                                             rrtm_dirdflux,  & !< RRTM output of incoming direct shortwave (W/m)
775                                             rrtm_difdflux     !< RRTM output of incoming diffuse shortwave (W/m)
776
777    REAL(wp), DIMENSION(1) ::                rrtm_aldif,     & !< surface albedo for longwave diffuse radiation
778                                             rrtm_aldir,     & !< surface albedo for longwave direct radiation
779                                             rrtm_asdif,     & !< surface albedo for shortwave diffuse radiation
780                                             rrtm_asdir        !< surface albedo for shortwave direct radiation
781
782!
783!-- Definition of arrays that are currently not used for calling RRTMG (due to setting of flag parameters)
784    REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  rad_lw_cs_in,   & !< incoming clear sky longwave radiation (W/m2) (not used)
785                                                rad_lw_cs_out,  & !< outgoing clear sky longwave radiation (W/m2) (not used)
786                                                rad_sw_cs_in,   & !< incoming clear sky shortwave radiation (W/m2) (not used)
787                                                rad_sw_cs_out,  & !< outgoing clear sky shortwave radiation (W/m2) (not used)
788                                                rrtm_lw_tauaer, & !< lw aerosol optical depth
789                                                rrtm_lw_taucld, & !< lw in-cloud optical depth
790                                                rrtm_sw_taucld, & !< sw in-cloud optical depth
791                                                rrtm_sw_ssacld, & !< sw in-cloud single scattering albedo
792                                                rrtm_sw_asmcld, & !< sw in-cloud asymmetry parameter
793                                                rrtm_sw_fsfcld, & !< sw in-cloud forward scattering fraction
794                                                rrtm_sw_tauaer, & !< sw aerosol optical depth
795                                                rrtm_sw_ssaaer, & !< sw aerosol single scattering albedo
796                                                rrtm_sw_asmaer, & !< sw aerosol asymmetry parameter
797                                                rrtm_sw_ecaer     !< sw aerosol optical detph at 0.55 microns (rrtm_iaer = 6 only)
798
799#endif
800!
801!-- Parameters of urban and land surface models
802    INTEGER(iwp)                                   ::  nzu                                !< number of layers of urban surface (will be calculated)
803    INTEGER(iwp)                                   ::  nzp                                !< number of layers of plant canopy (will be calculated)
804    INTEGER(iwp)                                   ::  nzub,nzut                          !< bottom and top layer of urban surface (will be calculated)
805    INTEGER(iwp)                                   ::  nzpt                               !< top layer of plant canopy (will be calculated)
806!-- parameters of urban and land surface models
807    INTEGER(iwp), PARAMETER                        ::  nzut_free = 3                      !< number of free layers above top of of topography
808    INTEGER(iwp), PARAMETER                        ::  ndsvf = 2                          !< number of dimensions of real values in SVF
809    INTEGER(iwp), PARAMETER                        ::  idsvf = 2                          !< number of dimensions of integer values in SVF
810    INTEGER(iwp), PARAMETER                        ::  ndcsf = 1                          !< number of dimensions of real values in CSF
811    INTEGER(iwp), PARAMETER                        ::  idcsf = 2                          !< number of dimensions of integer values in CSF
812    INTEGER(iwp), PARAMETER                        ::  kdcsf = 4                          !< number of dimensions of integer values in CSF calculation array
813    INTEGER(iwp), PARAMETER                        ::  id = 1                             !< position of d-index in surfl and surf
814    INTEGER(iwp), PARAMETER                        ::  iz = 2                             !< position of k-index in surfl and surf
815    INTEGER(iwp), PARAMETER                        ::  iy = 3                             !< position of j-index in surfl and surf
816    INTEGER(iwp), PARAMETER                        ::  ix = 4                             !< position of i-index in surfl and surf
817
818    INTEGER(iwp), PARAMETER                        ::  nsurf_type = 10                    !< number of surf types incl. phys.(land+urban) & (atm.,sky,boundary) surfaces - 1
819
820    INTEGER(iwp), PARAMETER                        ::  iup_u    = 0                       !< 0 - index of urban upward surface (ground or roof)
821    INTEGER(iwp), PARAMETER                        ::  idown_u  = 1                       !< 1 - index of urban downward surface (overhanging)
822    INTEGER(iwp), PARAMETER                        ::  inorth_u = 2                       !< 2 - index of urban northward facing wall
823    INTEGER(iwp), PARAMETER                        ::  isouth_u = 3                       !< 3 - index of urban southward facing wall
824    INTEGER(iwp), PARAMETER                        ::  ieast_u  = 4                       !< 4 - index of urban eastward facing wall
825    INTEGER(iwp), PARAMETER                        ::  iwest_u  = 5                       !< 5 - index of urban westward facing wall
826
827    INTEGER(iwp), PARAMETER                        ::  iup_l    = 6                       !< 6 - index of land upward surface (ground or roof)
828    INTEGER(iwp), PARAMETER                        ::  inorth_l = 7                       !< 7 - index of land northward facing wall
829    INTEGER(iwp), PARAMETER                        ::  isouth_l = 8                       !< 8 - index of land southward facing wall
830    INTEGER(iwp), PARAMETER                        ::  ieast_l  = 9                       !< 9 - index of land eastward facing wall
831    INTEGER(iwp), PARAMETER                        ::  iwest_l  = 10                      !< 10- index of land westward facing wall
832
833    INTEGER(iwp), DIMENSION(0:nsurf_type), PARAMETER ::  idir = (/0, 0,0, 0,1,-1,0,0, 0,1,-1/)   !< surface normal direction x indices
834    INTEGER(iwp), DIMENSION(0:nsurf_type), PARAMETER ::  jdir = (/0, 0,1,-1,0, 0,0,1,-1,0, 0/)   !< surface normal direction y indices
835    INTEGER(iwp), DIMENSION(0:nsurf_type), PARAMETER ::  kdir = (/1,-1,0, 0,0, 0,1,0, 0,0, 0/)   !< surface normal direction z indices
836                                                                                          !< parameter but set in the code
837
838
839!-- indices and sizes of urban and land surface models
840    INTEGER(iwp)                                   ::  startland        !< start index of block of land and roof surfaces
841    INTEGER(iwp)                                   ::  endland          !< end index of block of land and roof surfaces
842    INTEGER(iwp)                                   ::  nlands           !< number of land and roof surfaces in local processor
843    INTEGER(iwp)                                   ::  startwall        !< start index of block of wall surfaces
844    INTEGER(iwp)                                   ::  endwall          !< end index of block of wall surfaces
845    INTEGER(iwp)                                   ::  nwalls           !< number of wall surfaces in local processor
846
847!-- indices and sizes of urban and land surface models
848    INTEGER(iwp), DIMENSION(:), ALLOCATABLE,TARGET ::  surfl_l          !< coordinates of i-th local surface in local grid - surfl[:,k] = [d, z, y, x]
849    INTEGER(iwp), DIMENSION(:), ALLOCATABLE,TARGET ::  surf_l           !< coordinates of i-th surface in grid - surf[:,k] = [d, z, y, x]
850    INTEGER(iwp), DIMENSION(:,:), POINTER          ::  surfl            !< coordinates of i-th local surface in local grid - surfl[:,k] = [d, z, y, x]
851    INTEGER(iwp), DIMENSION(:,:), POINTER          ::  surf             !< coordinates of i-th surface in grid - surf[:,k] = [d, z, y, x]
852    INTEGER(iwp)                                   ::  nsurfl           !< number of all surfaces in local processor
853    INTEGER(iwp), DIMENSION(:), ALLOCATABLE,TARGET ::  nsurfs           !< array of number of all surfaces in individual processors
854    INTEGER(iwp)                                   ::  nsurf            !< global number of surfaces in index array of surfaces (nsurf = proc nsurfs)
855    INTEGER(iwp), DIMENSION(:), ALLOCATABLE,TARGET ::  surfstart        !< starts of blocks of surfaces for individual processors in array surf (indexed from 1)
856                                                                        !< respective block for particular processor is surfstart[iproc+1]+1 : surfstart[iproc+1]+nsurfs[iproc+1]
857
858!-- block variables needed for calculation of the plant canopy model inside the urban surface model
859    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE      ::  pct              !< top layer of the plant canopy
860    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE      ::  pch              !< heights of the plant canopy
861    INTEGER(iwp)                                   ::  npcbl = 0        !< number of the plant canopy gridboxes in local processor
862    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE      ::  pcbl             !< k,j,i coordinates of l-th local plant canopy box pcbl[:,l] = [k, j, i]
863    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  pcbinsw          !< array of absorbed sw radiation for local plant canopy box
864    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  pcbinswdir       !< array of absorbed direct sw radiation for local plant canopy box
865    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  pcbinswdif       !< array of absorbed diffusion sw radiation for local plant canopy box
866    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  pcbinlw          !< array of absorbed lw radiation for local plant canopy box
867
868!-- configuration parameters (they can be setup in PALM config)
869    LOGICAL                                        ::  raytrace_mpi_rma = .TRUE.          !< use MPI RMA to access LAD and gridsurf from remote processes during raytracing
870    LOGICAL                                        ::  read_svf_on_init = .FALSE.         !< flag parameter indicating wheather SVFs will be read from a file at initialization
871    LOGICAL                                        ::  write_svf_on_init = .FALSE.        !< flag parameter indicating wheather SVFs will be written out to a file
872    LOGICAL                                        ::  rad_angular_discretization = .TRUE.!< whether to use fixed resolution discretization of view factors for
873                                                                                          !< reflected radiation (as opposed to all mutually visible pairs)
874    INTEGER(iwp)                                   ::  mrt_nlevels = 0                    !< number of vertical boxes above surface for which to calculate MRT
875    LOGICAL                                        ::  mrt_skip_roof = .TRUE.             !< do not calculate MRT above roof surfaces
876    LOGICAL                                        ::  mrt_include_sw = .TRUE.            !< should MRT calculation include SW radiation as well?
877    INTEGER(iwp)                                   ::  nrefsteps = 0                      !< number of reflection steps to perform
878    REAL(wp), PARAMETER                            ::  ext_coef = 0.6_wp                  !< extinction coefficient (a.k.a. alpha)
879    INTEGER(iwp), PARAMETER                        ::  rad_version_len = 10               !< length of identification string of rad version
880    CHARACTER(rad_version_len), PARAMETER          ::  rad_version = 'RAD v. 1.1'         !< identification of version of binary svf and restart files
881    INTEGER(iwp)                                   ::  raytrace_discrete_elevs = 40       !< number of discretization steps for elevation (nadir to zenith)
882    INTEGER(iwp)                                   ::  raytrace_discrete_azims = 80       !< number of discretization steps for azimuth (out of 360 degrees)
883    REAL(wp)                                       ::  max_raytracing_dist = -999.0_wp    !< maximum distance for raytracing (in metres)
884    REAL(wp)                                       ::  min_irrf_value = 1e-6_wp           !< minimum potential irradiance factor value for raytracing
885    REAL(wp), DIMENSION(1:30)                      ::  svfnorm_report_thresh = 1e21_wp    !< thresholds of SVF normalization values to report
886    INTEGER(iwp)                                   ::  svfnorm_report_num                 !< number of SVF normalization thresholds to report
887
888!-- radiation related arrays to be used in radiation_interaction routine
889    REAL(wp), DIMENSION(:,:), ALLOCATABLE          ::  rad_sw_in_dir    !< direct sw radiation
890    REAL(wp), DIMENSION(:,:), ALLOCATABLE          ::  rad_sw_in_diff   !< diffusion sw radiation
891    REAL(wp), DIMENSION(:,:), ALLOCATABLE          ::  rad_lw_in_diff   !< diffusion lw radiation
892
893!-- parameters required for RRTMG lower boundary condition
894    REAL(wp)                   :: albedo_urb      !< albedo value retuned to RRTMG boundary cond.
895    REAL(wp)                   :: emissivity_urb  !< emissivity value retuned to RRTMG boundary cond.
896    REAL(wp)                   :: t_rad_urb       !< temperature value retuned to RRTMG boundary cond.
897
898!-- type for calculation of svf
899    TYPE t_svf
900        INTEGER(iwp)                               :: isurflt           !<
901        INTEGER(iwp)                               :: isurfs            !<
902        REAL(wp)                                   :: rsvf              !<
903        REAL(wp)                                   :: rtransp           !<
904    END TYPE
905
906!-- type for calculation of csf
907    TYPE t_csf
908        INTEGER(iwp)                               :: ip                !<
909        INTEGER(iwp)                               :: itx               !<
910        INTEGER(iwp)                               :: ity               !<
911        INTEGER(iwp)                               :: itz               !<
912        INTEGER(iwp)                               :: isurfs            !<
913        REAL(wp)                                   :: rsvf              !<
914    END TYPE
915
916!-- arrays storing the values of USM
917    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE      ::  svfsurf          !< svfsurf[:,isvf] = index of target and source surface for svf[isvf]
918    REAL(wp), DIMENSION(:,:), ALLOCATABLE          ::  svf              !< array of shape view factors+direct irradiation factors for local surfaces
919    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfins          !< array of sw radiation falling to local surface after i-th reflection
920    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfinl          !< array of lw radiation for local surface after i-th reflection
921
922    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  skyvf            !< array of sky view factor for each local surface
923    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  skyvft           !< array of sky view factor including transparency for each local surface
924    REAL(wp), DIMENSION(:,:), ALLOCATABLE          ::  dsitrans         !< dsidir[isvfl,i] = path transmittance of i-th
925                                                                        !< direction of direct solar irradiance per target surface
926    REAL(wp), DIMENSION(:,:), ALLOCATABLE          ::  dsitransc        !< dtto per plant canopy box
927    REAL(wp), DIMENSION(:,:), ALLOCATABLE          ::  dsidir           !< dsidir[:,i] = unit vector of i-th
928                                                                        !< direction of direct solar irradiance
929    INTEGER(iwp)                                   ::  ndsidir          !< number of apparent solar directions used
930    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE      ::  dsidir_rev       !< dsidir_rev[ielev,iazim] = i for dsidir or -1 if not present
931
932    INTEGER(iwp)                                   ::  nmrtbl           !< No. of local grid boxes for which MRT is calculated
933    INTEGER(iwp)                                   ::  nmrtf            !< number of MRT factors for local processor
934    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE      ::  mrtbl            !< coordinates of i-th local MRT box - surfl[:,i] = [z, y, x]
935    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE      ::  mrtfsurf         !< mrtfsurf[:,imrtf] = index of target MRT box and source surface for mrtf[imrtf]
936    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  mrtf             !< array of MRT factors for each local MRT box
937    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  mrtft            !< array of MRT factors including transparency for each local MRT box
938    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  mrtsky           !< array of sky view factor for each local MRT box
939    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  mrtskyt          !< array of sky view factor including transparency for each local MRT box
940    REAL(wp), DIMENSION(:,:), ALLOCATABLE          ::  mrtdsit          !< array of direct solar transparencies for each local MRT box
941    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  mrtinsw          !< mean SW radiant flux for each MRT box
942    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  mrtinlw          !< mean LW radiant flux for each MRT box
943    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  mrt              !< mean radiant temperature for each MRT box
944    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  mrtinsw_av       !< time average mean SW radiant flux for each MRT box
945    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  mrtinlw_av       !< time average mean LW radiant flux for each MRT box
946    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  mrt_av           !< time average mean radiant temperature for each MRT box
947
948    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfinsw         !< array of sw radiation falling to local surface including radiation from reflections
949    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfinlw         !< array of lw radiation falling to local surface including radiation from reflections
950    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfinswdir      !< array of direct sw radiation falling to local surface
951    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfinswdif      !< array of diffuse sw radiation from sky and model boundary falling to local surface
952    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfinlwdif      !< array of diffuse lw radiation from sky and model boundary falling to local surface
953   
954                                                                        !< Outward radiation is only valid for nonvirtual surfaces
955    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfoutsl        !< array of reflected sw radiation for local surface in i-th reflection
956    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfoutll        !< array of reflected + emitted lw radiation for local surface in i-th reflection
957    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfouts         !< array of reflected sw radiation for all surfaces in i-th reflection
958    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfoutl         !< array of reflected + emitted lw radiation for all surfaces in i-th reflection
959    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfoutsw        !< array of total sw radiation outgoing from nonvirtual surfaces surfaces after all reflection
960    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfoutlw        !< array of total lw radiation outgoing from nonvirtual surfaces surfaces after all reflection
961    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfemitlwl      !< array of emitted lw radiation for local surface used to calculate effective surface temperature for radiation model
962
963!-- block variables needed for calculation of the plant canopy model inside the urban surface model
964    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE      ::  csfsurf          !< csfsurf[:,icsf] = index of target surface and csf grid index for csf[icsf]
965    REAL(wp), DIMENSION(:,:), ALLOCATABLE          ::  csf              !< array of plant canopy sink fators + direct irradiation factors (transparency)
966    REAL(wp), DIMENSION(:,:,:), POINTER            ::  sub_lad          !< subset of lad_s within urban surface, transformed to plain Z coordinate
967    REAL(wp), DIMENSION(:), POINTER                ::  sub_lad_g        !< sub_lad globalized (used to avoid MPI RMA calls in raytracing)
968    REAL(wp)                                       ::  prototype_lad    !< prototype leaf area density for computing effective optical depth
969    INTEGER(iwp), DIMENSION(:), ALLOCATABLE        ::  nzterr, plantt   !< temporary global arrays for raytracing
970    INTEGER(iwp)                                   ::  plantt_max
971
972!-- arrays and variables for calculation of svf and csf
973    TYPE(t_svf), DIMENSION(:), POINTER             ::  asvf             !< pointer to growing svc array
974    TYPE(t_csf), DIMENSION(:), POINTER             ::  acsf             !< pointer to growing csf array
975    TYPE(t_svf), DIMENSION(:), POINTER             ::  amrtf            !< pointer to growing mrtf array
976    TYPE(t_svf), DIMENSION(:), ALLOCATABLE, TARGET ::  asvf1, asvf2     !< realizations of svf array
977    TYPE(t_csf), DIMENSION(:), ALLOCATABLE, TARGET ::  acsf1, acsf2     !< realizations of csf array
978    TYPE(t_svf), DIMENSION(:), ALLOCATABLE, TARGET ::  amrtf1, amrtf2   !< realizations of mftf array
979    INTEGER(iwp)                                   ::  nsvfla           !< dimmension of array allocated for storage of svf in local processor
980    INTEGER(iwp)                                   ::  ncsfla           !< dimmension of array allocated for storage of csf in local processor
981    INTEGER(iwp)                                   ::  nmrtfa           !< dimmension of array allocated for storage of mrt
982    INTEGER(iwp)                                   ::  msvf, mcsf, mmrtf!< mod for swapping the growing array
983    INTEGER(iwp), PARAMETER                        ::  gasize = 100000  !< initial size of growing arrays
984    REAL(wp), PARAMETER                            ::  grow_factor = 1.4_wp !< growth factor of growing arrays
985    REAL(wp)                                       ::  dist_max_svf = -9999.0 !< maximum distance to calculate the minimum svf to be considered. It is
986                                                                        !< used to avoid very small SVFs resulting from too far surfaces with mutual visibility
987    INTEGER(iwp)                                   ::  nsvfl            !< number of svf for local processor
988    INTEGER(iwp)                                   ::  ncsfl            !< no. of csf in local processor
989                                                                        !< needed only during calc_svf but must be here because it is
990                                                                        !< shared between subroutines calc_svf and raytrace
991    INTEGER(iwp), DIMENSION(:,:,:,:), POINTER      ::  gridsurf         !< reverse index of local surfl[d,k,j,i] (for case rad_angular_discretization)
992    INTEGER(iwp), DIMENSION(:,:,:), ALLOCATABLE    ::  gridpcbl         !< reverse index of local pcbl[k,j,i]
993    INTEGER(iwp), PARAMETER                        ::  nsurf_type_u = 6 !< number of urban surf types (used in gridsurf)
994
995!-- temporary arrays for calculation of csf in raytracing
996    INTEGER(iwp)                                   ::  maxboxesg        !< max number of boxes ray can cross in the domain
997    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE      ::  boxes            !< coordinates of gridboxes being crossed by ray
998    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  crlens           !< array of crossing lengths of ray for particular grid boxes
999    INTEGER(iwp), DIMENSION(:), ALLOCATABLE        ::  lad_ip           !< array of numbers of process where lad is stored
1000#if defined( __parallel )
1001    INTEGER(kind=MPI_ADDRESS_KIND), &
1002                  DIMENSION(:), ALLOCATABLE        ::  lad_disp         !< array of displaycements of lad in local array of proc lad_ip
1003    INTEGER(iwp)                                   ::  win_lad          !< MPI RMA window for leaf area density
1004    INTEGER(iwp)                                   ::  win_gridsurf     !< MPI RMA window for reverse grid surface index
1005#endif
1006    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  lad_s_ray        !< array of received lad_s for appropriate gridboxes crossed by ray
1007    INTEGER(iwp), DIMENSION(:), ALLOCATABLE        ::  target_surfl
1008    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE      ::  rt2_track
1009    REAL(wp), DIMENSION(:,:), ALLOCATABLE          ::  rt2_track_lad
1010    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  rt2_track_dist
1011    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  rt2_dist
1012
1013
1014
1015!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1016!-- Energy balance variables
1017!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1018!-- parameters of the land, roof and wall surfaces
1019    REAL(wp), DIMENSION(:), ALLOCATABLE            :: albedo_surf        !< albedo of the surface
1020    REAL(wp), DIMENSION(:), ALLOCATABLE            :: emiss_surf         !< emissivity of the wall surface
1021
1022
1023    INTERFACE radiation_check_data_output
1024       MODULE PROCEDURE radiation_check_data_output
1025    END INTERFACE radiation_check_data_output
1026
1027    INTERFACE radiation_check_data_output_pr
1028       MODULE PROCEDURE radiation_check_data_output_pr
1029    END INTERFACE radiation_check_data_output_pr
1030 
1031    INTERFACE radiation_check_parameters
1032       MODULE PROCEDURE radiation_check_parameters
1033    END INTERFACE radiation_check_parameters
1034 
1035    INTERFACE radiation_clearsky
1036       MODULE PROCEDURE radiation_clearsky
1037    END INTERFACE radiation_clearsky
1038 
1039    INTERFACE radiation_constant
1040       MODULE PROCEDURE radiation_constant
1041    END INTERFACE radiation_constant
1042 
1043    INTERFACE radiation_control
1044       MODULE PROCEDURE radiation_control
1045    END INTERFACE radiation_control
1046
1047    INTERFACE radiation_3d_data_averaging
1048       MODULE PROCEDURE radiation_3d_data_averaging
1049    END INTERFACE radiation_3d_data_averaging
1050
1051    INTERFACE radiation_data_output_2d
1052       MODULE PROCEDURE radiation_data_output_2d
1053    END INTERFACE radiation_data_output_2d
1054
1055    INTERFACE radiation_data_output_3d
1056       MODULE PROCEDURE radiation_data_output_3d
1057    END INTERFACE radiation_data_output_3d
1058
1059    INTERFACE radiation_data_output_mask
1060       MODULE PROCEDURE radiation_data_output_mask
1061    END INTERFACE radiation_data_output_mask
1062
1063    INTERFACE radiation_define_netcdf_grid
1064       MODULE PROCEDURE radiation_define_netcdf_grid
1065    END INTERFACE radiation_define_netcdf_grid
1066
1067    INTERFACE radiation_header
1068       MODULE PROCEDURE radiation_header
1069    END INTERFACE radiation_header 
1070 
1071    INTERFACE radiation_init
1072       MODULE PROCEDURE radiation_init
1073    END INTERFACE radiation_init
1074
1075    INTERFACE radiation_parin
1076       MODULE PROCEDURE radiation_parin
1077    END INTERFACE radiation_parin
1078   
1079    INTERFACE radiation_rrtmg
1080       MODULE PROCEDURE radiation_rrtmg
1081    END INTERFACE radiation_rrtmg
1082
1083    INTERFACE radiation_tendency
1084       MODULE PROCEDURE radiation_tendency
1085       MODULE PROCEDURE radiation_tendency_ij
1086    END INTERFACE radiation_tendency
1087
1088    INTERFACE radiation_rrd_local
1089       MODULE PROCEDURE radiation_rrd_local
1090    END INTERFACE radiation_rrd_local
1091
1092    INTERFACE radiation_wrd_local
1093       MODULE PROCEDURE radiation_wrd_local
1094    END INTERFACE radiation_wrd_local
1095
1096    INTERFACE radiation_interaction
1097       MODULE PROCEDURE radiation_interaction
1098    END INTERFACE radiation_interaction
1099
1100    INTERFACE radiation_interaction_init
1101       MODULE PROCEDURE radiation_interaction_init
1102    END INTERFACE radiation_interaction_init
1103 
1104    INTERFACE radiation_presimulate_solar_pos
1105       MODULE PROCEDURE radiation_presimulate_solar_pos
1106    END INTERFACE radiation_presimulate_solar_pos
1107
1108    INTERFACE radiation_radflux_gridbox
1109       MODULE PROCEDURE radiation_radflux_gridbox
1110    END INTERFACE radiation_radflux_gridbox
1111
1112    INTERFACE radiation_calc_svf
1113       MODULE PROCEDURE radiation_calc_svf
1114    END INTERFACE radiation_calc_svf
1115
1116    INTERFACE radiation_write_svf
1117       MODULE PROCEDURE radiation_write_svf
1118    END INTERFACE radiation_write_svf
1119
1120    INTERFACE radiation_read_svf
1121       MODULE PROCEDURE radiation_read_svf
1122    END INTERFACE radiation_read_svf
1123
1124
1125    SAVE
1126
1127    PRIVATE
1128
1129!
1130!-- Public functions / NEEDS SORTING
1131    PUBLIC radiation_check_data_output, radiation_check_data_output_pr,        &
1132           radiation_check_parameters, radiation_control,                      &
1133           radiation_header, radiation_init, radiation_parin,                  &
1134           radiation_3d_data_averaging, radiation_tendency,                    &
1135           radiation_data_output_2d, radiation_data_output_3d,                 &
1136           radiation_define_netcdf_grid, radiation_wrd_local,                  &
1137           radiation_rrd_local, radiation_data_output_mask,                    &
1138           radiation_radflux_gridbox, radiation_calc_svf, radiation_write_svf, &
1139           radiation_interaction, radiation_interaction_init,                  &
1140           radiation_read_svf, radiation_presimulate_solar_pos
1141           
1142
1143   
1144!
1145!-- Public variables and constants / NEEDS SORTING
1146    PUBLIC albedo, albedo_type, decl_1, decl_2, decl_3, dots_rad, dt_radiation,&
1147           emissivity, force_radiation_call, lat, lon,                         &
1148           mrt_include_sw, mrt_nlevels, mrtbl, mrtinsw, mrtinlw, nmrtbl,       &
1149           rad_net_av, radiation, radiation_scheme, rad_lw_in,                 &
1150           rad_lw_in_av, rad_lw_out, rad_lw_out_av,                            &
1151           rad_lw_cs_hr, rad_lw_cs_hr_av, rad_lw_hr, rad_lw_hr_av, rad_sw_in,  &
1152           rad_sw_in_av, rad_sw_out, rad_sw_out_av, rad_sw_cs_hr,              &
1153           rad_sw_cs_hr_av, rad_sw_hr, rad_sw_hr_av, sigma_sb, solar_constant, &
1154           skip_time_do_radiation, time_radiation, unscheduled_radiation_calls,&
1155           zenith, calc_zenith, sun_direction, sun_dir_lat, sun_dir_lon,       &
1156           write_svf_on_init, read_svf_on_init,                                &
1157           nrefsteps, dist_max_svf, nsvfl, svf,                                &
1158           svfsurf, surfinsw, surfinlw, surfins, surfinl, surfinswdir,         &
1159           surfinswdif, surfoutsw, surfoutlw, surfinlwdif, rad_sw_in_dir,      &
1160           rad_sw_in_diff, rad_lw_in_diff, surfouts, surfoutl, surfoutsl,      &
1161           surfoutll, idir, jdir, kdir, id, iz, iy, ix,                        &
1162           surf, surfl, nsurfl, pcbinswdir, pcbinswdif, pcbinsw, pcbinlw,      &
1163           iup_u, inorth_u, isouth_u, ieast_u, iwest_u,                        &
1164           iup_l, inorth_l, isouth_l, ieast_l, iwest_l,                        &
1165           nsurf_type, nzub, nzut, nzpt, nzu, pch, nsurf,                      &
1166           idsvf, ndsvf, idcsf, ndcsf, kdcsf, pct,                             &
1167           radiation_interactions, startwall, startland, endland, endwall,     &
1168           skyvf, skyvft, radiation_interactions_on, average_radiation, npcbl, &
1169           pcbl
1170
1171#if defined ( __rrtmg )
1172    PUBLIC rrtm_aldif, rrtm_aldir, rrtm_asdif, rrtm_asdir
1173#endif
1174
1175 CONTAINS
1176
1177
1178!------------------------------------------------------------------------------!
1179! Description:
1180! ------------
1181!> This subroutine controls the calls of the radiation schemes
1182!------------------------------------------------------------------------------!
1183    SUBROUTINE radiation_control
1184 
1185 
1186       IMPLICIT NONE
1187
1188
1189       SELECT CASE ( TRIM( radiation_scheme ) )
1190
1191          CASE ( 'constant' )
1192             CALL radiation_constant
1193         
1194          CASE ( 'clear-sky' ) 
1195             CALL radiation_clearsky
1196       
1197          CASE ( 'rrtmg' )
1198             CALL radiation_rrtmg
1199
1200          CASE DEFAULT
1201
1202       END SELECT
1203
1204
1205    END SUBROUTINE radiation_control
1206
1207!------------------------------------------------------------------------------!
1208! Description:
1209! ------------
1210!> Check data output for radiation model
1211!------------------------------------------------------------------------------!
1212    SUBROUTINE radiation_check_data_output( var, unit, i, ilen, k )
1213 
1214 
1215       USE control_parameters,                                                 &
1216           ONLY: data_output, message_string
1217
1218       IMPLICIT NONE
1219
1220       CHARACTER (LEN=*) ::  unit     !<
1221       CHARACTER (LEN=*) ::  var      !<
1222
1223       INTEGER(iwp) :: i
1224       INTEGER(iwp) :: ilen
1225       INTEGER(iwp) :: k
1226
1227       SELECT CASE ( TRIM( var ) )
1228
1229          CASE ( 'rad_lw_cs_hr', 'rad_lw_hr', 'rad_sw_cs_hr', 'rad_sw_hr', 'rad_sw_in' )
1230             IF (  .NOT.  radiation  .OR.  radiation_scheme /= 'rrtmg' )  THEN
1231                message_string = '"output of "' // TRIM( var ) // '" requi' // &
1232                                 'res radiation = .TRUE. and ' //              &
1233                                 'radiation_scheme = "rrtmg"'
1234                CALL message( 'check_parameters', 'PA0406', 1, 2, 0, 6, 0 )
1235             ENDIF
1236             unit = 'K/h'     
1237
1238          CASE ( 'rad_net*', 'rrtm_aldif*', 'rrtm_aldir*', 'rrtm_asdif*',      &
1239                 'rrtm_asdir*', 'rad_lw_in*', 'rad_lw_out*', 'rad_sw_in*',     &
1240                 'rad_sw_out*')
1241             IF ( k == 0  .OR.  data_output(i)(ilen-2:ilen) /= '_xy' )  THEN
1242                message_string = 'illegal value for data_output: "' //         &
1243                                 TRIM( var ) // '" & only 2d-horizontal ' //   &
1244                                 'cross sections are allowed for this value'
1245                CALL message( 'check_parameters', 'PA0111', 1, 2, 0, 6, 0 )
1246             ENDIF
1247             IF (  .NOT.  radiation  .OR.  radiation_scheme /= "rrtmg" )  THEN
1248                IF ( TRIM( var ) == 'rrtm_aldif*'  .OR.                        &
1249                     TRIM( var ) == 'rrtm_aldir*'  .OR.                        &
1250                     TRIM( var ) == 'rrtm_asdif*'  .OR.                        &
1251                     TRIM( var ) == 'rrtm_asdir*'      )                       &
1252                THEN
1253                   message_string = 'output of "' // TRIM( var ) // '" require'&
1254                                    // 's radiation = .TRUE. and radiation_sch'&
1255                                    // 'eme = "rrtmg"'
1256                   CALL message( 'check_parameters', 'PA0409', 1, 2, 0, 6, 0 )
1257                ENDIF
1258             ENDIF
1259
1260             IF ( TRIM( var ) == 'rad_net*'      ) unit = 'W/m2'   
1261             IF ( TRIM( var ) == 'rad_lw_in*'    ) unit = 'W/m2'
1262             IF ( TRIM( var ) == 'rad_lw_out*'   ) unit = 'W/m2'
1263             IF ( TRIM( var ) == 'rad_sw_in*'    ) unit = 'W/m2'
1264             IF ( TRIM( var ) == 'rad_sw_out*'   ) unit = 'W/m2'
1265             IF ( TRIM( var ) == 'rad_sw_in'     ) unit = 'W/m2'
1266             IF ( TRIM( var ) == 'rrtm_aldif*'   ) unit = ''   
1267             IF ( TRIM( var ) == 'rrtm_aldir*'   ) unit = '' 
1268             IF ( TRIM( var ) == 'rrtm_asdif*'   ) unit = '' 
1269             IF ( TRIM( var ) == 'rrtm_asdir*'   ) unit = '' 
1270
1271          CASE ( 'rad_mrt', 'rad_mrt_sw', 'rad_mrt_lw'  )
1272             IF ( .NOT.  radiation ) THEN
1273                message_string = 'output of "' // TRIM( var ) // '" require'&
1274                                 // 's radiation = .TRUE.'
1275                CALL message( 'check_parameters', 'PA0509', 1, 2, 0, 6, 0 )
1276             ENDIF
1277             IF ( mrt_nlevels == 0 ) THEN
1278                message_string = 'output of "' // TRIM( var ) // '" require'&
1279                                 // 's mrt_nlevels > 0'
1280                CALL message( 'check_parameters', 'PA0510', 1, 2, 0, 6, 0 )
1281             ENDIF
1282             IF ( TRIM( var ) == 'rad_mrt_sw'  .AND.  .NOT. mrt_include_sw ) THEN
1283                message_string = 'output of "' // TRIM( var ) // '" require'&
1284                                 // 's rad_mrt_sw = .TRUE.'
1285                CALL message( 'check_parameters', 'PA0511', 1, 2, 0, 6, 0 )
1286             ENDIF
1287             IF ( TRIM( var ) == 'rad_mrt' ) THEN
1288                unit = 'K'
1289             ELSE
1290                unit = 'W m-2'
1291             ENDIF
1292
1293          CASE DEFAULT
1294             unit = 'illegal'
1295
1296       END SELECT
1297
1298
1299    END SUBROUTINE radiation_check_data_output
1300
1301!------------------------------------------------------------------------------!
1302! Description:
1303! ------------
1304!> Check data output of profiles for radiation model
1305!------------------------------------------------------------------------------! 
1306    SUBROUTINE radiation_check_data_output_pr( variable, var_count, unit,      &
1307               dopr_unit )
1308 
1309       USE arrays_3d,                                                          &
1310           ONLY: zu
1311
1312       USE control_parameters,                                                 &
1313           ONLY: data_output_pr, message_string
1314
1315       USE indices
1316
1317       USE profil_parameter
1318
1319       USE statistics
1320
1321       IMPLICIT NONE
1322   
1323       CHARACTER (LEN=*) ::  unit      !<
1324       CHARACTER (LEN=*) ::  variable  !<
1325       CHARACTER (LEN=*) ::  dopr_unit !< local value of dopr_unit
1326 
1327       INTEGER(iwp) ::  var_count     !<
1328
1329       SELECT CASE ( TRIM( variable ) )
1330       
1331         CASE ( 'rad_net' )
1332             IF ( (  .NOT.  radiation )  .OR.  radiation_scheme == 'constant' )&
1333             THEN
1334                message_string = 'data_output_pr = ' //                        &
1335                                 TRIM( data_output_pr(var_count) ) // ' is' // &
1336                                 'not available for radiation = .FALSE. or ' //&
1337                                 'radiation_scheme = "constant"'
1338                CALL message( 'check_parameters', 'PA0408', 1, 2, 0, 6, 0 )
1339             ELSE
1340                dopr_index(var_count) = 99
1341                dopr_unit  = 'W/m2'
1342                hom(:,2,99,:)  = SPREAD( zw, 2, statistic_regions+1 )
1343                unit = dopr_unit
1344             ENDIF
1345
1346          CASE ( 'rad_lw_in' )
1347             IF ( (  .NOT.  radiation)  .OR.  radiation_scheme == 'constant' ) &
1348             THEN
1349                message_string = 'data_output_pr = ' //                        &
1350                                 TRIM( data_output_pr(var_count) ) // ' is' // &
1351                                 'not available for radiation = .FALSE. or ' //&
1352                                 'radiation_scheme = "constant"'
1353                CALL message( 'check_parameters', 'PA0408', 1, 2, 0, 6, 0 )
1354             ELSE
1355                dopr_index(var_count) = 100
1356                dopr_unit  = 'W/m2'
1357                hom(:,2,100,:)  = SPREAD( zw, 2, statistic_regions+1 )
1358                unit = dopr_unit 
1359             ENDIF
1360
1361          CASE ( 'rad_lw_out' )
1362             IF ( (  .NOT. radiation )  .OR.  radiation_scheme == 'constant' ) &
1363             THEN
1364                message_string = 'data_output_pr = ' //                        &
1365                                 TRIM( data_output_pr(var_count) ) // ' is' // &
1366                                 'not available for radiation = .FALSE. or ' //&
1367                                 'radiation_scheme = "constant"'
1368                CALL message( 'check_parameters', 'PA0408', 1, 2, 0, 6, 0 )
1369             ELSE
1370                dopr_index(var_count) = 101
1371                dopr_unit  = 'W/m2'
1372                hom(:,2,101,:)  = SPREAD( zw, 2, statistic_regions+1 )
1373                unit = dopr_unit   
1374             ENDIF
1375
1376          CASE ( 'rad_sw_in' )
1377             IF ( (  .NOT. radiation )  .OR.  radiation_scheme == 'constant' ) &
1378             THEN
1379                message_string = 'data_output_pr = ' //                        &
1380                                 TRIM( data_output_pr(var_count) ) // ' is' // &
1381                                 'not available for radiation = .FALSE. or ' //&
1382                                 'radiation_scheme = "constant"'
1383                CALL message( 'check_parameters', 'PA0408', 1, 2, 0, 6, 0 )
1384             ELSE
1385                dopr_index(var_count) = 102
1386                dopr_unit  = 'W/m2'
1387                hom(:,2,102,:)  = SPREAD( zw, 2, statistic_regions+1 )
1388                unit = dopr_unit
1389             ENDIF
1390
1391          CASE ( 'rad_sw_out')
1392             IF ( (  .NOT.  radiation )  .OR.  radiation_scheme == 'constant' )&
1393             THEN
1394                message_string = 'data_output_pr = ' //                        &
1395                                 TRIM( data_output_pr(var_count) ) // ' is' // &
1396                                 'not available for radiation = .FALSE. or ' //&
1397                                 'radiation_scheme = "constant"'
1398                CALL message( 'check_parameters', 'PA0408', 1, 2, 0, 6, 0 )
1399             ELSE
1400                dopr_index(var_count) = 103
1401                dopr_unit  = 'W/m2'
1402                hom(:,2,103,:)  = SPREAD( zw, 2, statistic_regions+1 )
1403                unit = dopr_unit
1404             ENDIF
1405
1406          CASE ( 'rad_lw_cs_hr' )
1407             IF ( (  .NOT.  radiation )  .OR.  radiation_scheme /= 'rrtmg' )   &
1408             THEN
1409                message_string = 'data_output_pr = ' //                        &
1410                                 TRIM( data_output_pr(var_count) ) // ' is' // &
1411                                 'not available for radiation = .FALSE. or ' //&
1412                                 'radiation_scheme /= "rrtmg"'
1413                CALL message( 'check_parameters', 'PA0413', 1, 2, 0, 6, 0 )
1414             ELSE
1415                dopr_index(var_count) = 104
1416                dopr_unit  = 'K/h'
1417                hom(:,2,104,:)  = SPREAD( zu, 2, statistic_regions+1 )
1418                unit = dopr_unit
1419             ENDIF
1420
1421          CASE ( 'rad_lw_hr' )
1422             IF ( (  .NOT.  radiation )  .OR.  radiation_scheme /= 'rrtmg' )   &
1423             THEN
1424                message_string = 'data_output_pr = ' //                        &
1425                                 TRIM( data_output_pr(var_count) ) // ' is' // &
1426                                 'not available for radiation = .FALSE. or ' //&
1427                                 'radiation_scheme /= "rrtmg"'
1428                CALL message( 'check_parameters', 'PA0413', 1, 2, 0, 6, 0 )
1429             ELSE
1430                dopr_index(var_count) = 105
1431                dopr_unit  = 'K/h'
1432                hom(:,2,105,:)  = SPREAD( zu, 2, statistic_regions+1 )
1433                unit = dopr_unit
1434             ENDIF
1435
1436          CASE ( 'rad_sw_cs_hr' )
1437             IF ( (  .NOT.  radiation )  .OR.  radiation_scheme /= 'rrtmg' )   &
1438             THEN
1439                message_string = 'data_output_pr = ' //                        &
1440                                 TRIM( data_output_pr(var_count) ) // ' is' // &
1441                                 'not available for radiation = .FALSE. or ' //&
1442                                 'radiation_scheme /= "rrtmg"'
1443                CALL message( 'check_parameters', 'PA0413', 1, 2, 0, 6, 0 )
1444             ELSE
1445                dopr_index(var_count) = 106
1446                dopr_unit  = 'K/h'
1447                hom(:,2,106,:)  = SPREAD( zu, 2, statistic_regions+1 )
1448                unit = dopr_unit
1449             ENDIF
1450
1451          CASE ( 'rad_sw_hr' )
1452             IF ( (  .NOT.  radiation )  .OR.  radiation_scheme /= 'rrtmg' )   &
1453             THEN
1454                message_string = 'data_output_pr = ' //                        &
1455                                 TRIM( data_output_pr(var_count) ) // ' is' // &
1456                                 'not available for radiation = .FALSE. or ' //&
1457                                 'radiation_scheme /= "rrtmg"'
1458                CALL message( 'check_parameters', 'PA0413', 1, 2, 0, 6, 0 )
1459             ELSE
1460                dopr_index(var_count) = 107
1461                dopr_unit  = 'K/h'
1462                hom(:,2,107,:)  = SPREAD( zu, 2, statistic_regions+1 )
1463                unit = dopr_unit
1464             ENDIF
1465
1466
1467          CASE DEFAULT
1468             unit = 'illegal'
1469
1470       END SELECT
1471
1472
1473    END SUBROUTINE radiation_check_data_output_pr
1474 
1475 
1476!------------------------------------------------------------------------------!
1477! Description:
1478! ------------
1479!> Check parameters routine for radiation model
1480!------------------------------------------------------------------------------!
1481    SUBROUTINE radiation_check_parameters
1482
1483       USE control_parameters,                                                 &
1484           ONLY: land_surface, message_string, urban_surface
1485
1486       USE netcdf_data_input_mod,                                              &
1487           ONLY:  input_pids_static                 
1488   
1489       IMPLICIT NONE
1490       
1491!
1492!--    In case no urban-surface or land-surface model is applied, usage of
1493!--    a radiation model make no sense.         
1494       IF ( .NOT. land_surface  .AND.  .NOT. urban_surface )  THEN
1495          message_string = 'Usage of radiation module is only allowed if ' //  &
1496                           'land-surface and/or urban-surface model is applied.'
1497          CALL message( 'check_parameters', 'PA0486', 1, 2, 0, 6, 0 )
1498       ENDIF
1499
1500       IF ( radiation_scheme /= 'constant'   .AND.                             &
1501            radiation_scheme /= 'clear-sky'  .AND.                             &
1502            radiation_scheme /= 'rrtmg' )  THEN
1503          message_string = 'unknown radiation_scheme = '//                     &
1504                           TRIM( radiation_scheme )
1505          CALL message( 'check_parameters', 'PA0405', 1, 2, 0, 6, 0 )
1506       ELSEIF ( radiation_scheme == 'rrtmg' )  THEN
1507#if ! defined ( __rrtmg )
1508          message_string = 'radiation_scheme = "rrtmg" requires ' //           & 
1509                           'compilation of PALM with pre-processor ' //        &
1510                           'directive -D__rrtmg'
1511          CALL message( 'check_parameters', 'PA0407', 1, 2, 0, 6, 0 )
1512#endif
1513#if defined ( __rrtmg ) && ! defined( __netcdf )
1514          message_string = 'radiation_scheme = "rrtmg" requires ' //           & 
1515                           'the use of NetCDF (preprocessor directive ' //     &
1516                           '-D__netcdf'
1517          CALL message( 'check_parameters', 'PA0412', 1, 2, 0, 6, 0 )
1518#endif
1519
1520       ENDIF
1521!
1522!--    Checks performed only if data is given via namelist only.
1523       IF ( .NOT. input_pids_static )  THEN
1524          IF ( albedo_type == 0  .AND.  albedo == 9999999.9_wp  .AND.          &
1525               radiation_scheme == 'clear-sky')  THEN
1526             message_string = 'radiation_scheme = "clear-sky" in combination'//& 
1527                              'with albedo_type = 0 requires setting of'//     &
1528                              'albedo /= 9999999.9'
1529             CALL message( 'check_parameters', 'PA0410', 1, 2, 0, 6, 0 )
1530          ENDIF
1531
1532          IF ( albedo_type == 0  .AND.  radiation_scheme == 'rrtmg'  .AND.     &
1533             ( albedo_lw_dif == 9999999.9_wp .OR. albedo_lw_dir == 9999999.9_wp&
1534          .OR. albedo_sw_dif == 9999999.9_wp .OR. albedo_sw_dir == 9999999.9_wp& 
1535             ) ) THEN
1536             message_string = 'radiation_scheme = "rrtmg" in combination' //   & 
1537                              'with albedo_type = 0 requires setting of ' //   &
1538                              'albedo_lw_dif /= 9999999.9' //                  &
1539                              'albedo_lw_dir /= 9999999.9' //                  &
1540                              'albedo_sw_dif /= 9999999.9 and' //              &
1541                              'albedo_sw_dir /= 9999999.9'
1542             CALL message( 'check_parameters', 'PA0411', 1, 2, 0, 6, 0 )
1543          ENDIF
1544       ENDIF
1545!
1546!--    Parallel rad_angular_discretization without raytrace_mpi_rma is not implemented
1547#if defined( __parallel )     
1548       IF ( rad_angular_discretization  .AND.  .NOT. raytrace_mpi_rma )  THEN
1549          message_string = 'rad_angular_discretization can only be used ' //  &
1550                           'together with raytrace_mpi_rma or when ' //  &
1551                           'no parallelization is applied.'
1552          CALL message( 'check_parameters', 'PA0486', 1, 2, 0, 6, 0 )
1553       ENDIF
1554#endif
1555
1556       IF ( cloud_droplets  .AND.   radiation_scheme == 'rrtmg'  .AND.         &
1557            average_radiation ) THEN
1558          message_string = 'average_radiation = .T. with radiation_scheme'//   & 
1559                           '= "rrtmg" in combination cloud_droplets = .T.'//   &
1560                           'is not implementd'
1561          CALL message( 'check_parameters', 'PA0560', 1, 2, 0, 6, 0 )
1562       ENDIF
1563
1564!
1565!--    Incialize svf normalization reporting histogram
1566       svfnorm_report_num = 1
1567       DO WHILE ( svfnorm_report_thresh(svfnorm_report_num) < 1e20_wp          &
1568                   .AND. svfnorm_report_num <= 30 )
1569          svfnorm_report_num = svfnorm_report_num + 1
1570       ENDDO
1571       svfnorm_report_num = svfnorm_report_num - 1
1572
1573
1574 
1575    END SUBROUTINE radiation_check_parameters 
1576 
1577 
1578!------------------------------------------------------------------------------!
1579! Description:
1580! ------------
1581!> Initialization of the radiation model
1582!------------------------------------------------------------------------------!
1583    SUBROUTINE radiation_init
1584   
1585       IMPLICIT NONE
1586
1587       INTEGER(iwp) ::  i         !< running index x-direction
1588       INTEGER(iwp) ::  ioff      !< offset in x between surface element reference grid point in atmosphere and actual surface
1589       INTEGER(iwp) ::  j         !< running index y-direction
1590       INTEGER(iwp) ::  joff      !< offset in y between surface element reference grid point in atmosphere and actual surface
1591       INTEGER(iwp) ::  l         !< running index for orientation of vertical surfaces
1592       INTEGER(iwp) ::  m         !< running index for surface elements
1593#if defined( __rrtmg )
1594       INTEGER(iwp) ::  ind_type  !< running index for subgrid-surface tiles
1595#endif
1596
1597!
1598!--    Allocate array for storing the surface net radiation
1599       IF ( .NOT. ALLOCATED ( surf_lsm_h%rad_net )  .AND.                      &
1600                  surf_lsm_h%ns > 0  )   THEN
1601          ALLOCATE( surf_lsm_h%rad_net(1:surf_lsm_h%ns) )
1602          surf_lsm_h%rad_net = 0.0_wp 
1603       ENDIF
1604       IF ( .NOT. ALLOCATED ( surf_usm_h%rad_net )  .AND.                      &
1605                  surf_usm_h%ns > 0  )  THEN
1606          ALLOCATE( surf_usm_h%rad_net(1:surf_usm_h%ns) )
1607          surf_usm_h%rad_net = 0.0_wp 
1608       ENDIF
1609       DO  l = 0, 3
1610          IF ( .NOT. ALLOCATED ( surf_lsm_v(l)%rad_net )  .AND.                &
1611                     surf_lsm_v(l)%ns > 0  )  THEN
1612             ALLOCATE( surf_lsm_v(l)%rad_net(1:surf_lsm_v(l)%ns) )
1613             surf_lsm_v(l)%rad_net = 0.0_wp 
1614          ENDIF
1615          IF ( .NOT. ALLOCATED ( surf_usm_v(l)%rad_net )  .AND.                &
1616                     surf_usm_v(l)%ns > 0  )  THEN
1617             ALLOCATE( surf_usm_v(l)%rad_net(1:surf_usm_v(l)%ns) )
1618             surf_usm_v(l)%rad_net = 0.0_wp 
1619          ENDIF
1620       ENDDO
1621
1622
1623!
1624!--    Allocate array for storing the surface longwave (out) radiation change
1625       IF ( .NOT. ALLOCATED ( surf_lsm_h%rad_lw_out_change_0 )  .AND.          &
1626                  surf_lsm_h%ns > 0  )   THEN
1627          ALLOCATE( surf_lsm_h%rad_lw_out_change_0(1:surf_lsm_h%ns) )
1628          surf_lsm_h%rad_lw_out_change_0 = 0.0_wp 
1629       ENDIF
1630       IF ( .NOT. ALLOCATED ( surf_usm_h%rad_lw_out_change_0 )  .AND.          &
1631                  surf_usm_h%ns > 0  )  THEN
1632          ALLOCATE( surf_usm_h%rad_lw_out_change_0(1:surf_usm_h%ns) )
1633          surf_usm_h%rad_lw_out_change_0 = 0.0_wp 
1634       ENDIF
1635       DO  l = 0, 3
1636          IF ( .NOT. ALLOCATED ( surf_lsm_v(l)%rad_lw_out_change_0 )  .AND.    &
1637                     surf_lsm_v(l)%ns > 0  )  THEN
1638             ALLOCATE( surf_lsm_v(l)%rad_lw_out_change_0(1:surf_lsm_v(l)%ns) )
1639             surf_lsm_v(l)%rad_lw_out_change_0 = 0.0_wp 
1640          ENDIF
1641          IF ( .NOT. ALLOCATED ( surf_usm_v(l)%rad_lw_out_change_0 )  .AND.    &
1642                     surf_usm_v(l)%ns > 0  )  THEN
1643             ALLOCATE( surf_usm_v(l)%rad_lw_out_change_0(1:surf_usm_v(l)%ns) )
1644             surf_usm_v(l)%rad_lw_out_change_0 = 0.0_wp 
1645          ENDIF
1646       ENDDO
1647
1648!
1649!--    Allocate surface arrays for incoming/outgoing short/longwave radiation
1650       IF ( .NOT. ALLOCATED ( surf_lsm_h%rad_sw_in )  .AND.                    &
1651                  surf_lsm_h%ns > 0  )   THEN
1652          ALLOCATE( surf_lsm_h%rad_sw_in(1:surf_lsm_h%ns)  )
1653          ALLOCATE( surf_lsm_h%rad_sw_out(1:surf_lsm_h%ns) )
1654          ALLOCATE( surf_lsm_h%rad_lw_in(1:surf_lsm_h%ns)  )
1655          ALLOCATE( surf_lsm_h%rad_lw_out(1:surf_lsm_h%ns) )
1656          surf_lsm_h%rad_sw_in  = 0.0_wp 
1657          surf_lsm_h%rad_sw_out = 0.0_wp 
1658          surf_lsm_h%rad_lw_in  = 0.0_wp 
1659          surf_lsm_h%rad_lw_out = 0.0_wp 
1660       ENDIF
1661       IF ( .NOT. ALLOCATED ( surf_usm_h%rad_sw_in )  .AND.                    &
1662                  surf_usm_h%ns > 0  )  THEN
1663          ALLOCATE( surf_usm_h%rad_sw_in(1:surf_usm_h%ns)  )
1664          ALLOCATE( surf_usm_h%rad_sw_out(1:surf_usm_h%ns) )
1665          ALLOCATE( surf_usm_h%rad_lw_in(1:surf_usm_h%ns)  )
1666          ALLOCATE( surf_usm_h%rad_lw_out(1:surf_usm_h%ns) )
1667          surf_usm_h%rad_sw_in  = 0.0_wp 
1668          surf_usm_h%rad_sw_out = 0.0_wp 
1669          surf_usm_h%rad_lw_in  = 0.0_wp 
1670          surf_usm_h%rad_lw_out = 0.0_wp 
1671       ENDIF
1672       DO  l = 0, 3
1673          IF ( .NOT. ALLOCATED ( surf_lsm_v(l)%rad_sw_in )  .AND.              &
1674                     surf_lsm_v(l)%ns > 0  )  THEN
1675             ALLOCATE( surf_lsm_v(l)%rad_sw_in(1:surf_lsm_v(l)%ns)  )
1676             ALLOCATE( surf_lsm_v(l)%rad_sw_out(1:surf_lsm_v(l)%ns) )
1677             ALLOCATE( surf_lsm_v(l)%rad_lw_in(1:surf_lsm_v(l)%ns)  )
1678             ALLOCATE( surf_lsm_v(l)%rad_lw_out(1:surf_lsm_v(l)%ns) )
1679             surf_lsm_v(l)%rad_sw_in  = 0.0_wp 
1680             surf_lsm_v(l)%rad_sw_out = 0.0_wp 
1681             surf_lsm_v(l)%rad_lw_in  = 0.0_wp 
1682             surf_lsm_v(l)%rad_lw_out = 0.0_wp 
1683          ENDIF
1684          IF ( .NOT. ALLOCATED ( surf_usm_v(l)%rad_sw_in )  .AND.              &
1685                     surf_usm_v(l)%ns > 0  )  THEN
1686             ALLOCATE( surf_usm_v(l)%rad_sw_in(1:surf_usm_v(l)%ns)  )
1687             ALLOCATE( surf_usm_v(l)%rad_sw_out(1:surf_usm_v(l)%ns) )
1688             ALLOCATE( surf_usm_v(l)%rad_lw_in(1:surf_usm_v(l)%ns)  )
1689             ALLOCATE( surf_usm_v(l)%rad_lw_out(1:surf_usm_v(l)%ns) )
1690             surf_usm_v(l)%rad_sw_in  = 0.0_wp 
1691             surf_usm_v(l)%rad_sw_out = 0.0_wp 
1692             surf_usm_v(l)%rad_lw_in  = 0.0_wp 
1693             surf_usm_v(l)%rad_lw_out = 0.0_wp 
1694          ENDIF
1695       ENDDO
1696!
1697!--    Fix net radiation in case of radiation_scheme = 'constant'
1698       IF ( radiation_scheme == 'constant' )  THEN
1699          IF ( ALLOCATED( surf_lsm_h%rad_net ) )                               &
1700             surf_lsm_h%rad_net    = net_radiation
1701          IF ( ALLOCATED( surf_usm_h%rad_net ) )                               &
1702             surf_usm_h%rad_net    = net_radiation
1703!
1704!--       Todo: weight with inclination angle
1705          DO  l = 0, 3
1706             IF ( ALLOCATED( surf_lsm_v(l)%rad_net ) )                         &
1707                surf_lsm_v(l)%rad_net = net_radiation
1708             IF ( ALLOCATED( surf_usm_v(l)%rad_net ) )                         &
1709                surf_usm_v(l)%rad_net = net_radiation
1710          ENDDO
1711!          radiation = .FALSE.
1712!
1713!--    Calculate orbital constants
1714       ELSE
1715          decl_1 = SIN(23.45_wp * pi / 180.0_wp)
1716          decl_2 = 2.0_wp * pi / 365.0_wp
1717          decl_3 = decl_2 * 81.0_wp
1718          lat    = latitude * pi / 180.0_wp
1719          lon    = longitude * pi / 180.0_wp
1720       ENDIF
1721
1722       IF ( radiation_scheme == 'clear-sky'  .OR.                              &
1723            radiation_scheme == 'constant')  THEN
1724
1725
1726!
1727!--       Allocate arrays for incoming/outgoing short/longwave radiation
1728          IF ( .NOT. ALLOCATED ( rad_sw_in ) )  THEN
1729             ALLOCATE ( rad_sw_in(0:0,nysg:nyng,nxlg:nxrg) )
1730          ENDIF
1731          IF ( .NOT. ALLOCATED ( rad_sw_out ) )  THEN
1732             ALLOCATE ( rad_sw_out(0:0,nysg:nyng,nxlg:nxrg) )
1733          ENDIF
1734
1735          IF ( .NOT. ALLOCATED ( rad_lw_in ) )  THEN
1736             ALLOCATE ( rad_lw_in(0:0,nysg:nyng,nxlg:nxrg) )
1737          ENDIF
1738          IF ( .NOT. ALLOCATED ( rad_lw_out ) )  THEN
1739             ALLOCATE ( rad_lw_out(0:0,nysg:nyng,nxlg:nxrg) )
1740          ENDIF
1741
1742!
1743!--       Allocate average arrays for incoming/outgoing short/longwave radiation
1744          IF ( .NOT. ALLOCATED ( rad_sw_in_av ) )  THEN
1745             ALLOCATE ( rad_sw_in_av(0:0,nysg:nyng,nxlg:nxrg) )
1746          ENDIF
1747          IF ( .NOT. ALLOCATED ( rad_sw_out_av ) )  THEN
1748             ALLOCATE ( rad_sw_out_av(0:0,nysg:nyng,nxlg:nxrg) )
1749          ENDIF
1750
1751          IF ( .NOT. ALLOCATED ( rad_lw_in_av ) )  THEN
1752             ALLOCATE ( rad_lw_in_av(0:0,nysg:nyng,nxlg:nxrg) )
1753          ENDIF
1754          IF ( .NOT. ALLOCATED ( rad_lw_out_av ) )  THEN
1755             ALLOCATE ( rad_lw_out_av(0:0,nysg:nyng,nxlg:nxrg) )
1756          ENDIF
1757!
1758!--       Allocate arrays for broadband albedo, and level 1 initialization
1759!--       via namelist paramter, unless not already allocated.
1760          IF ( .NOT. ALLOCATED(surf_lsm_h%albedo) )  THEN
1761             ALLOCATE( surf_lsm_h%albedo(0:2,1:surf_lsm_h%ns)     )
1762             surf_lsm_h%albedo    = albedo
1763          ENDIF
1764          IF ( .NOT. ALLOCATED(surf_usm_h%albedo) )  THEN
1765             ALLOCATE( surf_usm_h%albedo(0:2,1:surf_usm_h%ns)     )
1766             surf_usm_h%albedo    = albedo
1767          ENDIF
1768
1769          DO  l = 0, 3
1770             IF ( .NOT. ALLOCATED( surf_lsm_v(l)%albedo ) )  THEN
1771                ALLOCATE( surf_lsm_v(l)%albedo(0:2,1:surf_lsm_v(l)%ns) )
1772                surf_lsm_v(l)%albedo = albedo
1773             ENDIF
1774             IF ( .NOT. ALLOCATED( surf_usm_v(l)%albedo ) )  THEN
1775                ALLOCATE( surf_usm_v(l)%albedo(0:2,1:surf_usm_v(l)%ns) )
1776                surf_usm_v(l)%albedo = albedo
1777             ENDIF
1778          ENDDO
1779!
1780!--       Level 2 initialization of broadband albedo via given albedo_type.
1781!--       Only if albedo_type is non-zero. In case of urban surface and
1782!--       input data is read from ASCII file, albedo_type will be zero, so that
1783!--       albedo won't be overwritten.
1784          DO  m = 1, surf_lsm_h%ns
1785             IF ( surf_lsm_h%albedo_type(ind_veg_wall,m) /= 0 )                &
1786                surf_lsm_h%albedo(ind_veg_wall,m) =                            &
1787                           albedo_pars(2,surf_lsm_h%albedo_type(ind_veg_wall,m))
1788             IF ( surf_lsm_h%albedo_type(ind_pav_green,m) /= 0 )               &
1789                surf_lsm_h%albedo(ind_pav_green,m) =                           &
1790                           albedo_pars(2,surf_lsm_h%albedo_type(ind_pav_green,m))
1791             IF ( surf_lsm_h%albedo_type(ind_wat_win,m) /= 0 )                 &
1792                surf_lsm_h%albedo(ind_wat_win,m) =                             &
1793                           albedo_pars(2,surf_lsm_h%albedo_type(ind_wat_win,m))
1794          ENDDO
1795          DO  m = 1, surf_usm_h%ns
1796             IF ( surf_usm_h%albedo_type(ind_veg_wall,m) /= 0 )                &
1797                surf_usm_h%albedo(ind_veg_wall,m) =                            &
1798                           albedo_pars(2,surf_usm_h%albedo_type(ind_veg_wall,m))
1799             IF ( surf_usm_h%albedo_type(ind_pav_green,m) /= 0 )               &
1800                surf_usm_h%albedo(ind_pav_green,m) =                           &
1801                           albedo_pars(2,surf_usm_h%albedo_type(ind_pav_green,m))
1802             IF ( surf_usm_h%albedo_type(ind_wat_win,m) /= 0 )                 &
1803                surf_usm_h%albedo(ind_wat_win,m) =                             &
1804                           albedo_pars(2,surf_usm_h%albedo_type(ind_wat_win,m))
1805          ENDDO
1806
1807          DO  l = 0, 3
1808             DO  m = 1, surf_lsm_v(l)%ns
1809                IF ( surf_lsm_v(l)%albedo_type(ind_veg_wall,m) /= 0 )          &
1810                   surf_lsm_v(l)%albedo(ind_veg_wall,m) =                      &
1811                        albedo_pars(2,surf_lsm_v(l)%albedo_type(ind_veg_wall,m))
1812                IF ( surf_lsm_v(l)%albedo_type(ind_pav_green,m) /= 0 )         &
1813                   surf_lsm_v(l)%albedo(ind_pav_green,m) =                     &
1814                        albedo_pars(2,surf_lsm_v(l)%albedo_type(ind_pav_green,m))
1815                IF ( surf_lsm_v(l)%albedo_type(ind_wat_win,m) /= 0 )           &
1816                   surf_lsm_v(l)%albedo(ind_wat_win,m) =                       &
1817                        albedo_pars(2,surf_lsm_v(l)%albedo_type(ind_wat_win,m))
1818             ENDDO
1819             DO  m = 1, surf_usm_v(l)%ns
1820                IF ( surf_usm_v(l)%albedo_type(ind_veg_wall,m) /= 0 )          &
1821                   surf_usm_v(l)%albedo(ind_veg_wall,m) =                      &
1822                        albedo_pars(2,surf_usm_v(l)%albedo_type(ind_veg_wall,m))
1823                IF ( surf_usm_v(l)%albedo_type(ind_pav_green,m) /= 0 )         &
1824                   surf_usm_v(l)%albedo(ind_pav_green,m) =                     &
1825                        albedo_pars(2,surf_usm_v(l)%albedo_type(ind_pav_green,m))
1826                IF ( surf_usm_v(l)%albedo_type(ind_wat_win,m) /= 0 )           &
1827                   surf_usm_v(l)%albedo(ind_wat_win,m) =                       &
1828                        albedo_pars(2,surf_usm_v(l)%albedo_type(ind_wat_win,m))
1829             ENDDO
1830          ENDDO
1831
1832!
1833!--       Level 3 initialization at grid points where albedo type is zero.
1834!--       This case, albedo is taken from file. In case of constant radiation
1835!--       or clear sky, only broadband albedo is given.
1836          IF ( albedo_pars_f%from_file )  THEN
1837!
1838!--          Horizontal surfaces
1839             DO  m = 1, surf_lsm_h%ns
1840                i = surf_lsm_h%i(m)
1841                j = surf_lsm_h%j(m)
1842                IF ( albedo_pars_f%pars_xy(0,j,i) /= albedo_pars_f%fill )  THEN
1843                   IF ( surf_lsm_h%albedo_type(ind_veg_wall,m) == 0 )          &
1844                      surf_lsm_h%albedo(ind_veg_wall,m) = albedo_pars_f%pars_xy(0,j,i)
1845                   IF ( surf_lsm_h%albedo_type(ind_pav_green,m) == 0 )         &
1846                      surf_lsm_h%albedo(ind_pav_green,m) = albedo_pars_f%pars_xy(0,j,i)
1847                   IF ( surf_lsm_h%albedo_type(ind_wat_win,m) == 0 )           &
1848                      surf_lsm_h%albedo(ind_wat_win,m) = albedo_pars_f%pars_xy(0,j,i)
1849                ENDIF
1850             ENDDO
1851             DO  m = 1, surf_usm_h%ns
1852                i = surf_usm_h%i(m)
1853                j = surf_usm_h%j(m)
1854                IF ( albedo_pars_f%pars_xy(0,j,i) /= albedo_pars_f%fill )  THEN
1855                   IF ( surf_usm_h%albedo_type(ind_veg_wall,m) == 0 )          &
1856                      surf_usm_h%albedo(ind_veg_wall,m) = albedo_pars_f%pars_xy(0,j,i)
1857                   IF ( surf_usm_h%albedo_type(ind_pav_green,m) == 0 )         &
1858                      surf_usm_h%albedo(ind_pav_green,m) = albedo_pars_f%pars_xy(0,j,i)
1859                   IF ( surf_usm_h%albedo_type(ind_wat_win,m) == 0 )           &
1860                      surf_usm_h%albedo(ind_wat_win,m) = albedo_pars_f%pars_xy(0,j,i)
1861                ENDIF
1862             ENDDO 
1863!
1864!--          Vertical surfaces           
1865             DO  l = 0, 3
1866
1867                ioff = surf_lsm_v(l)%ioff
1868                joff = surf_lsm_v(l)%joff
1869                DO  m = 1, surf_lsm_v(l)%ns
1870                   i = surf_lsm_v(l)%i(m) + ioff
1871                   j = surf_lsm_v(l)%j(m) + joff
1872                   IF ( albedo_pars_f%pars_xy(0,j,i) /= albedo_pars_f%fill )  THEN
1873                      IF ( surf_lsm_v(l)%albedo_type(ind_veg_wall,m) == 0 )    &
1874                         surf_lsm_v(l)%albedo(ind_veg_wall,m) = albedo_pars_f%pars_xy(0,j,i)
1875                      IF ( surf_lsm_v(l)%albedo_type(ind_pav_green,m) == 0 )   &
1876                         surf_lsm_v(l)%albedo(ind_pav_green,m) = albedo_pars_f%pars_xy(0,j,i)
1877                      IF ( surf_lsm_v(l)%albedo_type(ind_wat_win,m) == 0 )     &
1878                         surf_lsm_v(l)%albedo(ind_wat_win,m) = albedo_pars_f%pars_xy(0,j,i)
1879                   ENDIF
1880                ENDDO
1881
1882                ioff = surf_usm_v(l)%ioff
1883                joff = surf_usm_v(l)%joff
1884                DO  m = 1, surf_usm_h%ns
1885                   i = surf_usm_h%i(m) + joff
1886                   j = surf_usm_h%j(m) + joff
1887                   IF ( albedo_pars_f%pars_xy(0,j,i) /= albedo_pars_f%fill )  THEN
1888                      IF ( surf_usm_v(l)%albedo_type(ind_veg_wall,m) == 0 )    &
1889                         surf_usm_v(l)%albedo(ind_veg_wall,m) = albedo_pars_f%pars_xy(0,j,i)
1890                      IF ( surf_usm_v(l)%albedo_type(ind_pav_green,m) == 0 )   &
1891                         surf_usm_v(l)%albedo(ind_pav_green,m) = albedo_pars_f%pars_xy(0,j,i)
1892                      IF ( surf_usm_v(l)%albedo_type(ind_wat_win,m) == 0 )     &
1893                         surf_lsm_v(l)%albedo(ind_wat_win,m) = albedo_pars_f%pars_xy(0,j,i)
1894                   ENDIF
1895                ENDDO
1896             ENDDO
1897
1898          ENDIF 
1899!
1900!--    Initialization actions for RRTMG
1901       ELSEIF ( radiation_scheme == 'rrtmg' )  THEN
1902#if defined ( __rrtmg )
1903!
1904!--       Allocate albedos for short/longwave radiation, horizontal surfaces
1905!--       for wall/green/window (USM) or vegetation/pavement/water surfaces
1906!--       (LSM).
1907          ALLOCATE ( surf_lsm_h%aldif(0:2,1:surf_lsm_h%ns)       )
1908          ALLOCATE ( surf_lsm_h%aldir(0:2,1:surf_lsm_h%ns)       )
1909          ALLOCATE ( surf_lsm_h%asdif(0:2,1:surf_lsm_h%ns)       )
1910          ALLOCATE ( surf_lsm_h%asdir(0:2,1:surf_lsm_h%ns)       )
1911          ALLOCATE ( surf_lsm_h%rrtm_aldif(0:2,1:surf_lsm_h%ns)  )
1912          ALLOCATE ( surf_lsm_h%rrtm_aldir(0:2,1:surf_lsm_h%ns)  )
1913          ALLOCATE ( surf_lsm_h%rrtm_asdif(0:2,1:surf_lsm_h%ns)  )
1914          ALLOCATE ( surf_lsm_h%rrtm_asdir(0:2,1:surf_lsm_h%ns)  )
1915
1916          ALLOCATE ( surf_usm_h%aldif(0:2,1:surf_usm_h%ns)       )
1917          ALLOCATE ( surf_usm_h%aldir(0:2,1:surf_usm_h%ns)       )
1918          ALLOCATE ( surf_usm_h%asdif(0:2,1:surf_usm_h%ns)       )
1919          ALLOCATE ( surf_usm_h%asdir(0:2,1:surf_usm_h%ns)       )
1920          ALLOCATE ( surf_usm_h%rrtm_aldif(0:2,1:surf_usm_h%ns)  )
1921          ALLOCATE ( surf_usm_h%rrtm_aldir(0:2,1:surf_usm_h%ns)  )
1922          ALLOCATE ( surf_usm_h%rrtm_asdif(0:2,1:surf_usm_h%ns)  )
1923          ALLOCATE ( surf_usm_h%rrtm_asdir(0:2,1:surf_usm_h%ns)  )
1924
1925!
1926!--       Allocate broadband albedo (temporary for the current radiation
1927!--       implementations)
1928          IF ( .NOT. ALLOCATED(surf_lsm_h%albedo) )                            &
1929             ALLOCATE( surf_lsm_h%albedo(0:2,1:surf_lsm_h%ns)     )
1930          IF ( .NOT. ALLOCATED(surf_usm_h%albedo) )                            &
1931             ALLOCATE( surf_usm_h%albedo(0:2,1:surf_usm_h%ns)     )
1932
1933!
1934!--       Allocate albedos for short/longwave radiation, vertical surfaces
1935          DO  l = 0, 3
1936
1937             ALLOCATE ( surf_lsm_v(l)%aldif(0:2,1:surf_lsm_v(l)%ns)      )
1938             ALLOCATE ( surf_lsm_v(l)%aldir(0:2,1:surf_lsm_v(l)%ns)      )
1939             ALLOCATE ( surf_lsm_v(l)%asdif(0:2,1:surf_lsm_v(l)%ns)      )
1940             ALLOCATE ( surf_lsm_v(l)%asdir(0:2,1:surf_lsm_v(l)%ns)      )
1941
1942             ALLOCATE ( surf_lsm_v(l)%rrtm_aldif(0:2,1:surf_lsm_v(l)%ns) )
1943             ALLOCATE ( surf_lsm_v(l)%rrtm_aldir(0:2,1:surf_lsm_v(l)%ns) )
1944             ALLOCATE ( surf_lsm_v(l)%rrtm_asdif(0:2,1:surf_lsm_v(l)%ns) )
1945             ALLOCATE ( surf_lsm_v(l)%rrtm_asdir(0:2,1:surf_lsm_v(l)%ns) )
1946
1947             ALLOCATE ( surf_usm_v(l)%aldif(0:2,1:surf_usm_v(l)%ns)      )
1948             ALLOCATE ( surf_usm_v(l)%aldir(0:2,1:surf_usm_v(l)%ns)      )
1949             ALLOCATE ( surf_usm_v(l)%asdif(0:2,1:surf_usm_v(l)%ns)      )
1950             ALLOCATE ( surf_usm_v(l)%asdir(0:2,1:surf_usm_v(l)%ns)      )
1951
1952             ALLOCATE ( surf_usm_v(l)%rrtm_aldif(0:2,1:surf_usm_v(l)%ns) )
1953             ALLOCATE ( surf_usm_v(l)%rrtm_aldir(0:2,1:surf_usm_v(l)%ns) )
1954             ALLOCATE ( surf_usm_v(l)%rrtm_asdif(0:2,1:surf_usm_v(l)%ns) )
1955             ALLOCATE ( surf_usm_v(l)%rrtm_asdir(0:2,1:surf_usm_v(l)%ns) )
1956!
1957!--          Allocate broadband albedo (temporary for the current radiation
1958!--          implementations)
1959             IF ( .NOT. ALLOCATED( surf_lsm_v(l)%albedo ) )                    &
1960                ALLOCATE( surf_lsm_v(l)%albedo(0:2,1:surf_lsm_v(l)%ns) )
1961             IF ( .NOT. ALLOCATED( surf_usm_v(l)%albedo ) )                    &
1962                ALLOCATE( surf_usm_v(l)%albedo(0:2,1:surf_usm_v(l)%ns) )
1963
1964          ENDDO
1965!
1966!--       Level 1 initialization of spectral albedos via namelist
1967!--       paramters. Please note, this case all surface tiles are initialized
1968!--       the same.
1969          IF ( surf_lsm_h%ns > 0 )  THEN
1970             surf_lsm_h%aldif  = albedo_lw_dif
1971             surf_lsm_h%aldir  = albedo_lw_dir
1972             surf_lsm_h%asdif  = albedo_sw_dif
1973             surf_lsm_h%asdir  = albedo_sw_dir
1974             surf_lsm_h%albedo = albedo_sw_dif
1975          ENDIF
1976          IF ( surf_usm_h%ns > 0 )  THEN
1977             IF ( surf_usm_h%albedo_from_ascii )  THEN
1978                surf_usm_h%aldif  = surf_usm_h%albedo
1979                surf_usm_h%aldir  = surf_usm_h%albedo
1980                surf_usm_h%asdif  = surf_usm_h%albedo
1981                surf_usm_h%asdir  = surf_usm_h%albedo
1982             ELSE
1983                surf_usm_h%aldif  = albedo_lw_dif
1984                surf_usm_h%aldir  = albedo_lw_dir
1985                surf_usm_h%asdif  = albedo_sw_dif
1986                surf_usm_h%asdir  = albedo_sw_dir
1987                surf_usm_h%albedo = albedo_sw_dif
1988             ENDIF
1989          ENDIF
1990
1991          DO  l = 0, 3
1992
1993             IF ( surf_lsm_v(l)%ns > 0 )  THEN
1994                surf_lsm_v(l)%aldif  = albedo_lw_dif
1995                surf_lsm_v(l)%aldir  = albedo_lw_dir
1996                surf_lsm_v(l)%asdif  = albedo_sw_dif
1997                surf_lsm_v(l)%asdir  = albedo_sw_dir
1998                surf_lsm_v(l)%albedo = albedo_sw_dif
1999             ENDIF
2000
2001             IF ( surf_usm_v(l)%ns > 0 )  THEN
2002                IF ( surf_usm_v(l)%albedo_from_ascii )  THEN
2003                   surf_usm_v(l)%aldif  = surf_usm_v(l)%albedo
2004                   surf_usm_v(l)%aldir  = surf_usm_v(l)%albedo
2005                   surf_usm_v(l)%asdif  = surf_usm_v(l)%albedo
2006                   surf_usm_v(l)%asdir  = surf_usm_v(l)%albedo
2007                ELSE
2008                   surf_usm_v(l)%aldif  = albedo_lw_dif
2009                   surf_usm_v(l)%aldir  = albedo_lw_dir
2010                   surf_usm_v(l)%asdif  = albedo_sw_dif
2011                   surf_usm_v(l)%asdir  = albedo_sw_dir
2012                ENDIF
2013             ENDIF
2014          ENDDO
2015
2016!
2017!--       Level 2 initialization of spectral albedos via albedo_type.
2018!--       Please note, for natural- and urban-type surfaces, a tile approach
2019!--       is applied so that the resulting albedo is calculated via the weighted
2020!--       average of respective surface fractions.
2021          DO  m = 1, surf_lsm_h%ns
2022!
2023!--          Spectral albedos for vegetation/pavement/water surfaces
2024             DO  ind_type = 0, 2
2025                IF ( surf_lsm_h%albedo_type(ind_type,m) /= 0 )  THEN
2026                   surf_lsm_h%aldif(ind_type,m) =                              &
2027                               albedo_pars(0,surf_lsm_h%albedo_type(ind_type,m))
2028                   surf_lsm_h%asdif(ind_type,m) =                              &
2029                               albedo_pars(1,surf_lsm_h%albedo_type(ind_type,m))
2030                   surf_lsm_h%aldir(ind_type,m) =                              &
2031                               albedo_pars(0,surf_lsm_h%albedo_type(ind_type,m))
2032                   surf_lsm_h%asdir(ind_type,m) =                              &
2033                               albedo_pars(1,surf_lsm_h%albedo_type(ind_type,m))
2034                   surf_lsm_h%albedo(ind_type,m) =                             &
2035                               albedo_pars(2,surf_lsm_h%albedo_type(ind_type,m))
2036                ENDIF
2037             ENDDO
2038
2039          ENDDO
2040!
2041!--       For urban surface only if albedo has not been already initialized
2042!--       in the urban-surface model via the ASCII file.
2043          IF ( .NOT. surf_usm_h%albedo_from_ascii )  THEN
2044             DO  m = 1, surf_usm_h%ns
2045!
2046!--             Spectral albedos for wall/green/window surfaces
2047                DO  ind_type = 0, 2
2048                   IF ( surf_usm_h%albedo_type(ind_type,m) /= 0 )  THEN
2049                      surf_usm_h%aldif(ind_type,m) =                           &
2050                               albedo_pars(0,surf_usm_h%albedo_type(ind_type,m))
2051                      surf_usm_h%asdif(ind_type,m) =                           &
2052                               albedo_pars(1,surf_usm_h%albedo_type(ind_type,m))
2053                      surf_usm_h%aldir(ind_type,m) =                           &
2054                               albedo_pars(0,surf_usm_h%albedo_type(ind_type,m))
2055                      surf_usm_h%asdir(ind_type,m) =                           &
2056                               albedo_pars(1,surf_usm_h%albedo_type(ind_type,m))
2057                      surf_usm_h%albedo(ind_type,m) =                          &
2058                               albedo_pars(2,surf_usm_h%albedo_type(ind_type,m))
2059                   ENDIF
2060                ENDDO
2061
2062             ENDDO
2063          ENDIF
2064
2065          DO l = 0, 3
2066
2067             DO  m = 1, surf_lsm_v(l)%ns
2068!
2069!--             Spectral albedos for vegetation/pavement/water surfaces
2070                DO  ind_type = 0, 2
2071                   IF ( surf_lsm_v(l)%albedo_type(ind_type,m) /= 0 )  THEN
2072                      surf_lsm_v(l)%aldif(ind_type,m) =                        &
2073                            albedo_pars(0,surf_lsm_v(l)%albedo_type(ind_type,m))
2074                      surf_lsm_v(l)%asdif(ind_type,m) =                        &
2075                            albedo_pars(1,surf_lsm_v(l)%albedo_type(ind_type,m))
2076                      surf_lsm_v(l)%aldir(ind_type,m) =                        &
2077                            albedo_pars(0,surf_lsm_v(l)%albedo_type(ind_type,m))
2078                      surf_lsm_v(l)%asdir(ind_type,m) =                        &
2079                            albedo_pars(1,surf_lsm_v(l)%albedo_type(ind_type,m))
2080                      surf_lsm_v(l)%albedo(ind_type,m) =                       &
2081                            albedo_pars(2,surf_lsm_v(l)%albedo_type(ind_type,m))
2082                   ENDIF
2083                ENDDO
2084             ENDDO
2085!
2086!--          For urban surface only if albedo has not been already initialized
2087!--          in the urban-surface model via the ASCII file.
2088             IF ( .NOT. surf_usm_v(l)%albedo_from_ascii )  THEN
2089                DO  m = 1, surf_usm_v(l)%ns
2090!
2091!--                Spectral albedos for wall/green/window surfaces
2092                   DO  ind_type = 0, 2
2093                      IF ( surf_usm_v(l)%albedo_type(ind_type,m) /= 0 )  THEN
2094                         surf_usm_v(l)%aldif(ind_type,m) =                     &
2095                            albedo_pars(0,surf_usm_v(l)%albedo_type(ind_type,m))
2096                         surf_usm_v(l)%asdif(ind_type,m) =                     &
2097                            albedo_pars(1,surf_usm_v(l)%albedo_type(ind_type,m))
2098                         surf_usm_v(l)%aldir(ind_type,m) =                     &
2099                            albedo_pars(0,surf_usm_v(l)%albedo_type(ind_type,m))
2100                         surf_usm_v(l)%asdir(ind_type,m) =                     &
2101                            albedo_pars(1,surf_usm_v(l)%albedo_type(ind_type,m))
2102                         surf_usm_v(l)%albedo(ind_type,m) =                    &
2103                            albedo_pars(2,surf_usm_v(l)%albedo_type(ind_type,m))
2104                      ENDIF
2105                   ENDDO
2106
2107                ENDDO
2108             ENDIF
2109          ENDDO
2110!
2111!--       Level 3 initialization at grid points where albedo type is zero.
2112!--       This case, spectral albedos are taken from file if available
2113          IF ( albedo_pars_f%from_file )  THEN
2114!
2115!--          Horizontal
2116             DO  m = 1, surf_lsm_h%ns
2117                i = surf_lsm_h%i(m)
2118                j = surf_lsm_h%j(m)
2119!
2120!--             Spectral albedos for vegetation/pavement/water surfaces
2121                DO  ind_type = 0, 2
2122                   IF ( surf_lsm_h%albedo_type(ind_type,m) == 0 )  THEN
2123                      IF ( albedo_pars_f%pars_xy(1,j,i) /= albedo_pars_f%fill )&
2124                         surf_lsm_h%albedo(ind_type,m) =                       &
2125                                                albedo_pars_f%pars_xy(1,j,i)
2126                      IF ( albedo_pars_f%pars_xy(1,j,i) /= albedo_pars_f%fill )&
2127                         surf_lsm_h%aldir(ind_type,m) =                        &
2128                                                albedo_pars_f%pars_xy(1,j,i)
2129                      IF ( albedo_pars_f%pars_xy(2,j,i) /= albedo_pars_f%fill )&
2130                         surf_lsm_h%aldif(ind_type,m) =                        &
2131                                                albedo_pars_f%pars_xy(2,j,i)
2132                      IF ( albedo_pars_f%pars_xy(3,j,i) /= albedo_pars_f%fill )&
2133                         surf_lsm_h%asdir(ind_type,m) =                        &
2134                                                albedo_pars_f%pars_xy(3,j,i)
2135                      IF ( albedo_pars_f%pars_xy(4,j,i) /= albedo_pars_f%fill )&
2136                         surf_lsm_h%asdif(ind_type,m) =                        &
2137                                                albedo_pars_f%pars_xy(4,j,i)
2138                   ENDIF
2139                ENDDO
2140             ENDDO
2141!
2142!--          For urban surface only if albedo has not been already initialized
2143!--          in the urban-surface model via the ASCII file.
2144             IF ( .NOT. surf_usm_h%albedo_from_ascii )  THEN
2145                DO  m = 1, surf_usm_h%ns
2146                   i = surf_usm_h%i(m)
2147                   j = surf_usm_h%j(m)
2148!
2149!--                Spectral albedos for wall/green/window surfaces
2150                   DO  ind_type = 0, 2
2151                      IF ( surf_usm_h%albedo_type(ind_type,m) == 0 )  THEN
2152                         IF ( albedo_pars_f%pars_xy(1,j,i) /= albedo_pars_f%fill )&
2153                            surf_usm_h%albedo(ind_type,m) =                       &
2154                                                albedo_pars_f%pars_xy(1,j,i)
2155                         IF ( albedo_pars_f%pars_xy(1,j,i) /= albedo_pars_f%fill )&
2156                            surf_usm_h%aldir(ind_type,m) =                        &
2157                                                albedo_pars_f%pars_xy(1,j,i)
2158                         IF ( albedo_pars_f%pars_xy(2,j,i) /= albedo_pars_f%fill )&
2159                            surf_usm_h%aldif(ind_type,m) =                        &
2160                                                albedo_pars_f%pars_xy(2,j,i)
2161                         IF ( albedo_pars_f%pars_xy(3,j,i) /= albedo_pars_f%fill )&
2162                            surf_usm_h%asdir(ind_type,m) =                        &
2163                                                albedo_pars_f%pars_xy(3,j,i)
2164                         IF ( albedo_pars_f%pars_xy(4,j,i) /= albedo_pars_f%fill )&
2165                            surf_usm_h%asdif(ind_type,m) =                        &
2166                                                albedo_pars_f%pars_xy(4,j,i)
2167                      ENDIF
2168                   ENDDO
2169
2170                ENDDO
2171             ENDIF
2172!
2173!--          Vertical
2174             DO  l = 0, 3
2175                ioff = surf_lsm_v(l)%ioff
2176                joff = surf_lsm_v(l)%joff
2177
2178                DO  m = 1, surf_lsm_v(l)%ns
2179                   i = surf_lsm_v(l)%i(m)
2180                   j = surf_lsm_v(l)%j(m)
2181!
2182!--                Spectral albedos for vegetation/pavement/water surfaces
2183                   DO  ind_type = 0, 2
2184                      IF ( surf_lsm_v(l)%albedo_type(ind_type,m) == 0 )  THEN
2185                         IF ( albedo_pars_f%pars_xy(1,j+joff,i+ioff) /=        &
2186                              albedo_pars_f%fill )                             &
2187                            surf_lsm_v(l)%albedo(ind_type,m) =                 &
2188                                          albedo_pars_f%pars_xy(1,j+joff,i+ioff)
2189                         IF ( albedo_pars_f%pars_xy(1,j+joff,i+ioff) /=        &
2190                              albedo_pars_f%fill )                             &
2191                            surf_lsm_v(l)%aldir(ind_type,m) =                  &
2192                                          albedo_pars_f%pars_xy(1,j+joff,i+ioff)
2193                         IF ( albedo_pars_f%pars_xy(2,j+joff,i+ioff) /=        &
2194                              albedo_pars_f%fill )                             &
2195                            surf_lsm_v(l)%aldif(ind_type,m) =                  &
2196                                          albedo_pars_f%pars_xy(2,j+joff,i+ioff)
2197                         IF ( albedo_pars_f%pars_xy(3,j+joff,i+ioff) /=        &
2198                              albedo_pars_f%fill )                             &
2199                            surf_lsm_v(l)%asdir(ind_type,m) =                  &
2200                                          albedo_pars_f%pars_xy(3,j+joff,i+ioff)
2201                         IF ( albedo_pars_f%pars_xy(4,j+joff,i+ioff) /=        &
2202                              albedo_pars_f%fill )                             &
2203                            surf_lsm_v(l)%asdif(ind_type,m) =                  &
2204                                          albedo_pars_f%pars_xy(4,j+joff,i+ioff)
2205                      ENDIF
2206                   ENDDO
2207                ENDDO
2208!
2209!--             For urban surface only if albedo has not been already initialized
2210!--             in the urban-surface model via the ASCII file.
2211                IF ( .NOT. surf_usm_v(l)%albedo_from_ascii )  THEN
2212                   ioff = surf_usm_v(l)%ioff
2213                   joff = surf_usm_v(l)%joff
2214
2215                   DO  m = 1, surf_usm_v(l)%ns
2216                      i = surf_usm_v(l)%i(m)
2217                      j = surf_usm_v(l)%j(m)
2218!
2219!--                   Spectral albedos for wall/green/window surfaces
2220                      DO  ind_type = 0, 2
2221                         IF ( surf_usm_v(l)%albedo_type(ind_type,m) == 0 )  THEN
2222                            IF ( albedo_pars_f%pars_xy(1,j+joff,i+ioff) /=        &
2223                                 albedo_pars_f%fill )                             &
2224                               surf_usm_v(l)%albedo(ind_type,m) =                 &
2225                                             albedo_pars_f%pars_xy(1,j+joff,i+ioff)
2226                            IF ( albedo_pars_f%pars_xy(1,j+joff,i+ioff) /=        &
2227                                 albedo_pars_f%fill )                             &
2228                               surf_usm_v(l)%aldir(ind_type,m) =                  &
2229                                             albedo_pars_f%pars_xy(1,j+joff,i+ioff)
2230                            IF ( albedo_pars_f%pars_xy(2,j+joff,i+ioff) /=        &
2231                                 albedo_pars_f%fill )                             &
2232                               surf_usm_v(l)%aldif(ind_type,m) =                  &
2233                                             albedo_pars_f%pars_xy(2,j+joff,i+ioff)
2234                            IF ( albedo_pars_f%pars_xy(3,j+joff,i+ioff) /=        &
2235                                 albedo_pars_f%fill )                             &
2236                               surf_usm_v(l)%asdir(ind_type,m) =                  &
2237                                             albedo_pars_f%pars_xy(3,j+joff,i+ioff)
2238                            IF ( albedo_pars_f%pars_xy(4,j+joff,i+ioff) /=        &
2239                                 albedo_pars_f%fill )                             &
2240                               surf_usm_v(l)%asdif(ind_type,m) =                  &
2241                                             albedo_pars_f%pars_xy(4,j+joff,i+ioff)
2242                         ENDIF
2243                      ENDDO
2244
2245                   ENDDO
2246                ENDIF
2247             ENDDO
2248
2249          ENDIF
2250
2251!
2252!--       Calculate initial values of current (cosine of) the zenith angle and
2253!--       whether the sun is up
2254          CALL calc_zenith     
2255!
2256!--       Calculate initial surface albedo for different surfaces
2257          IF ( .NOT. constant_albedo )  THEN
2258!
2259!--          Horizontally aligned natural and urban surfaces
2260             CALL calc_albedo( surf_lsm_h    )
2261             CALL calc_albedo( surf_usm_h    )
2262!
2263!--          Vertically aligned natural and urban surfaces
2264             DO  l = 0, 3
2265                CALL calc_albedo( surf_lsm_v(l) )
2266                CALL calc_albedo( surf_usm_v(l) )
2267             ENDDO
2268          ELSE
2269!
2270!--          Initialize sun-inclination independent spectral albedos
2271!--          Horizontal surfaces
2272             IF ( surf_lsm_h%ns > 0 )  THEN
2273                surf_lsm_h%rrtm_aldir = surf_lsm_h%aldir
2274                surf_lsm_h%rrtm_asdir = surf_lsm_h%asdir
2275                surf_lsm_h%rrtm_aldif = surf_lsm_h%aldif
2276                surf_lsm_h%rrtm_asdif = surf_lsm_h%asdif
2277             ENDIF
2278             IF ( surf_usm_h%ns > 0 )  THEN
2279                surf_usm_h%rrtm_aldir = surf_usm_h%aldir
2280                surf_usm_h%rrtm_asdir = surf_usm_h%asdir
2281                surf_usm_h%rrtm_aldif = surf_usm_h%aldif
2282                surf_usm_h%rrtm_asdif = surf_usm_h%asdif
2283             ENDIF
2284!
2285!--          Vertical surfaces
2286             DO  l = 0, 3
2287                IF ( surf_lsm_v(l)%ns > 0 )  THEN
2288                   surf_lsm_v(l)%rrtm_aldir = surf_lsm_v(l)%aldir
2289                   surf_lsm_v(l)%rrtm_asdir = surf_lsm_v(l)%asdir
2290                   surf_lsm_v(l)%rrtm_aldif = surf_lsm_v(l)%aldif
2291                   surf_lsm_v(l)%rrtm_asdif = surf_lsm_v(l)%asdif
2292                ENDIF
2293                IF ( surf_usm_v(l)%ns > 0 )  THEN
2294                   surf_usm_v(l)%rrtm_aldir = surf_usm_v(l)%aldir
2295                   surf_usm_v(l)%rrtm_asdir = surf_usm_v(l)%asdir
2296                   surf_usm_v(l)%rrtm_aldif = surf_usm_v(l)%aldif
2297                   surf_usm_v(l)%rrtm_asdif = surf_usm_v(l)%asdif
2298                ENDIF
2299             ENDDO
2300
2301          ENDIF
2302
2303!
2304!--       Allocate 3d arrays of radiative fluxes and heating rates
2305          IF ( .NOT. ALLOCATED ( rad_sw_in ) )  THEN
2306             ALLOCATE ( rad_sw_in(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2307             rad_sw_in = 0.0_wp
2308          ENDIF
2309
2310          IF ( .NOT. ALLOCATED ( rad_sw_in_av ) )  THEN
2311             ALLOCATE ( rad_sw_in_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2312          ENDIF
2313
2314          IF ( .NOT. ALLOCATED ( rad_sw_out ) )  THEN
2315             ALLOCATE ( rad_sw_out(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2316             rad_sw_out = 0.0_wp
2317          ENDIF
2318
2319          IF ( .NOT. ALLOCATED ( rad_sw_out_av ) )  THEN
2320             ALLOCATE ( rad_sw_out_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2321          ENDIF
2322
2323          IF ( .NOT. ALLOCATED ( rad_sw_hr ) )  THEN
2324             ALLOCATE ( rad_sw_hr(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2325             rad_sw_hr = 0.0_wp
2326          ENDIF
2327
2328          IF ( .NOT. ALLOCATED ( rad_sw_hr_av ) )  THEN
2329             ALLOCATE ( rad_sw_hr_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2330             rad_sw_hr_av = 0.0_wp
2331          ENDIF
2332
2333          IF ( .NOT. ALLOCATED ( rad_sw_cs_hr ) )  THEN
2334             ALLOCATE ( rad_sw_cs_hr(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2335             rad_sw_cs_hr = 0.0_wp
2336          ENDIF
2337
2338          IF ( .NOT. ALLOCATED ( rad_sw_cs_hr_av ) )  THEN
2339             ALLOCATE ( rad_sw_cs_hr_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2340             rad_sw_cs_hr_av = 0.0_wp
2341          ENDIF
2342
2343          IF ( .NOT. ALLOCATED ( rad_lw_in ) )  THEN
2344             ALLOCATE ( rad_lw_in(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2345             rad_lw_in     = 0.0_wp
2346          ENDIF
2347
2348          IF ( .NOT. ALLOCATED ( rad_lw_in_av ) )  THEN
2349             ALLOCATE ( rad_lw_in_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2350          ENDIF
2351
2352          IF ( .NOT. ALLOCATED ( rad_lw_out ) )  THEN
2353             ALLOCATE ( rad_lw_out(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2354            rad_lw_out    = 0.0_wp
2355          ENDIF
2356
2357          IF ( .NOT. ALLOCATED ( rad_lw_out_av ) )  THEN
2358             ALLOCATE ( rad_lw_out_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2359          ENDIF
2360
2361          IF ( .NOT. ALLOCATED ( rad_lw_hr ) )  THEN
2362             ALLOCATE ( rad_lw_hr(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2363             rad_lw_hr = 0.0_wp
2364          ENDIF
2365
2366          IF ( .NOT. ALLOCATED ( rad_lw_hr_av ) )  THEN
2367             ALLOCATE ( rad_lw_hr_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2368             rad_lw_hr_av = 0.0_wp
2369          ENDIF
2370
2371          IF ( .NOT. ALLOCATED ( rad_lw_cs_hr ) )  THEN
2372             ALLOCATE ( rad_lw_cs_hr(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2373             rad_lw_cs_hr = 0.0_wp
2374          ENDIF
2375
2376          IF ( .NOT. ALLOCATED ( rad_lw_cs_hr_av ) )  THEN
2377             ALLOCATE ( rad_lw_cs_hr_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2378             rad_lw_cs_hr_av = 0.0_wp
2379          ENDIF
2380
2381          ALLOCATE ( rad_sw_cs_in(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2382          ALLOCATE ( rad_sw_cs_out(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2383          rad_sw_cs_in  = 0.0_wp
2384          rad_sw_cs_out = 0.0_wp
2385
2386          ALLOCATE ( rad_lw_cs_in(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2387          ALLOCATE ( rad_lw_cs_out(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
2388          rad_lw_cs_in  = 0.0_wp
2389          rad_lw_cs_out = 0.0_wp
2390
2391!
2392!--       Allocate 1-element array for surface temperature
2393!--       (RRTMG anticipates an array as passed argument).
2394          ALLOCATE ( rrtm_tsfc(1) )
2395!
2396!--       Allocate surface emissivity.
2397!--       Values will be given directly before calling rrtm_lw.
2398          ALLOCATE ( rrtm_emis(0:0,1:nbndlw+1) )
2399
2400!
2401!--       Initialize RRTMG
2402          IF ( lw_radiation )  CALL rrtmg_lw_ini ( c_p )
2403          IF ( sw_radiation )  CALL rrtmg_sw_ini ( c_p )
2404
2405!
2406!--       Set input files for RRTMG
2407          INQUIRE(FILE="RAD_SND_DATA", EXIST=snd_exists) 
2408          IF ( .NOT. snd_exists )  THEN
2409             rrtm_input_file = "rrtmg_lw.nc"
2410          ENDIF
2411
2412!
2413!--       Read vertical layers for RRTMG from sounding data
2414!--       The routine provides nzt_rad, hyp_snd(1:nzt_rad),
2415!--       t_snd(nzt+2:nzt_rad), rrtm_play(1:nzt_rad), rrtm_plev(1_nzt_rad+1),
2416!--       rrtm_tlay(nzt+2:nzt_rad), rrtm_tlev(nzt+2:nzt_rad+1)
2417          CALL read_sounding_data
2418
2419!
2420!--       Read trace gas profiles from file. This routine provides
2421!--       the rrtm_ arrays (1:nzt_rad+1)
2422          CALL read_trace_gas_data
2423#endif
2424       ENDIF
2425
2426!
2427!--    Perform user actions if required
2428       CALL user_init_radiation
2429
2430!
2431!--    Calculate radiative fluxes at model start
2432       SELECT CASE ( TRIM( radiation_scheme ) )
2433
2434          CASE ( 'rrtmg' )
2435             CALL radiation_rrtmg
2436
2437          CASE ( 'clear-sky' )
2438             CALL radiation_clearsky
2439
2440          CASE ( 'constant' )
2441             CALL radiation_constant
2442
2443          CASE DEFAULT
2444
2445       END SELECT
2446
2447       RETURN
2448
2449    END SUBROUTINE radiation_init
2450
2451
2452!------------------------------------------------------------------------------!
2453! Description:
2454! ------------
2455!> A simple clear sky radiation model
2456!------------------------------------------------------------------------------!
2457    SUBROUTINE radiation_clearsky
2458
2459
2460       IMPLICIT NONE
2461
2462       INTEGER(iwp) ::  l         !< running index for surface orientation
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 current zenith angle
2472       CALL calc_zenith
2473
2474!
2475!--    Calculate sky transmissivity
2476       sky_trans = 0.6_wp + 0.2_wp * zenith(0)
2477
2478!
2479!--    Calculate value of the Exner function at model surface
2480!
2481!--    In case averaged radiation is used, calculate mean temperature and
2482!--    liquid water mixing ratio at the urban-layer top.
2483       IF ( average_radiation ) THEN
2484          pt1   = 0.0_wp
2485          IF ( bulk_cloud_model  .OR.  cloud_droplets )  ql1   = 0.0_wp
2486
2487          pt1_l = SUM( pt(nzut,nys:nyn,nxl:nxr) )
2488          IF ( bulk_cloud_model  .OR.  cloud_droplets  )  ql1_l = SUM( ql(nzut,nys:nyn,nxl:nxr) )
2489
2490#if defined( __parallel )     
2491          IF ( collective_wait )  CALL MPI_BARRIER( comm2d, ierr )
2492          CALL MPI_ALLREDUCE( pt1_l, pt1, 1, MPI_REAL, MPI_SUM, comm2d, ierr )
2493          IF ( ierr /= 0 ) THEN
2494              WRITE(9,*) 'Error MPI_AllReduce1:', ierr, pt1_l, pt1
2495              FLUSH(9)
2496          ENDIF
2497
2498          IF ( bulk_cloud_model  .OR.  cloud_droplets ) THEN
2499              CALL MPI_ALLREDUCE( ql1_l, ql1, 1, MPI_REAL, MPI_SUM, comm2d, ierr )
2500              IF ( ierr /= 0 ) THEN
2501                  WRITE(9,*) 'Error MPI_AllReduce2:', ierr, ql1_l, ql1
2502                  FLUSH(9)
2503              ENDIF
2504          ENDIF
2505#else
2506          pt1 = pt1_l 
2507          IF ( bulk_cloud_model  .OR.  cloud_droplets )  ql1 = ql1_l
2508#endif
2509
2510          IF ( bulk_cloud_model  .OR.  cloud_droplets  )  pt1 = pt1 + lv_d_cp / exner(nzut) * ql1
2511!
2512!--       Finally, divide by number of grid points
2513          pt1 = pt1 / REAL( ( nx + 1 ) * ( ny + 1 ), KIND=wp )
2514       ENDIF
2515!
2516!--    Call clear-sky calculation for each surface orientation.
2517!--    First, horizontal surfaces
2518       surf => surf_lsm_h
2519       CALL radiation_clearsky_surf
2520       surf => surf_usm_h
2521       CALL radiation_clearsky_surf
2522!
2523!--    Vertical surfaces
2524       DO  l = 0, 3
2525          surf => surf_lsm_v(l)
2526          CALL radiation_clearsky_surf
2527          surf => surf_usm_v(l)
2528          CALL radiation_clearsky_surf
2529       ENDDO
2530
2531       CONTAINS
2532
2533          SUBROUTINE radiation_clearsky_surf
2534
2535             IMPLICIT NONE
2536
2537             INTEGER(iwp) ::  i         !< index x-direction
2538             INTEGER(iwp) ::  j         !< index y-direction
2539             INTEGER(iwp) ::  k         !< index z-direction
2540             INTEGER(iwp) ::  m         !< running index for surface elements
2541
2542             IF ( surf%ns < 1 )  RETURN
2543
2544!
2545!--          Calculate radiation fluxes and net radiation (rad_net) assuming
2546!--          homogeneous urban radiation conditions.
2547             IF ( average_radiation ) THEN       
2548
2549                k = nzut
2550
2551                surf%rad_sw_in  = solar_constant * sky_trans * zenith(0)
2552                surf%rad_sw_out = albedo_urb * surf%rad_sw_in
2553               
2554                surf%rad_lw_in  = 0.8_wp * sigma_sb * (pt1 * exner(k+1))**4
2555
2556                surf%rad_lw_out = emissivity_urb * sigma_sb * (t_rad_urb)**4   &
2557                                    + (1.0_wp - emissivity_urb) * surf%rad_lw_in
2558
2559                surf%rad_net = surf%rad_sw_in - surf%rad_sw_out                &
2560                             + surf%rad_lw_in - surf%rad_lw_out
2561
2562                surf%rad_lw_out_change_0 = 3.0_wp * emissivity_urb * sigma_sb  &
2563                                           * (t_rad_urb)**3
2564
2565!
2566!--          Calculate radiation fluxes and net radiation (rad_net) for each surface
2567!--          element.
2568             ELSE
2569
2570                DO  m = 1, surf%ns
2571                   i = surf%i(m)
2572                   j = surf%j(m)
2573                   k = surf%k(m)
2574
2575                   surf%rad_sw_in(m) = solar_constant * sky_trans * zenith(0)
2576
2577!
2578!--                Weighted average according to surface fraction.
2579!--                ATTENTION: when radiation interactions are switched on the
2580!--                calculated fluxes below are not actually used as they are
2581!--                overwritten in radiation_interaction.
2582                   surf%rad_sw_out(m) = ( surf%frac(ind_veg_wall,m)  *         &
2583                                          surf%albedo(ind_veg_wall,m)          &
2584                                        + surf%frac(ind_pav_green,m) *         &
2585                                          surf%albedo(ind_pav_green,m)         &
2586                                        + surf%frac(ind_wat_win,m)   *         &
2587                                          surf%albedo(ind_wat_win,m) )         &
2588                                        * surf%rad_sw_in(m)
2589
2590                   surf%rad_lw_out(m) = ( surf%frac(ind_veg_wall,m)  *         &
2591                                          surf%emissivity(ind_veg_wall,m)      &
2592                                        + surf%frac(ind_pav_green,m) *         &
2593                                          surf%emissivity(ind_pav_green,m)     &
2594                                        + surf%frac(ind_wat_win,m)   *         &
2595                                          surf%emissivity(ind_wat_win,m)       &
2596                                        )                                      &
2597                                        * sigma_sb                             &
2598                                        * ( surf%pt_surface(m) * exner(nzb) )**4
2599
2600                   surf%rad_lw_out_change_0(m) =                               &
2601                                      ( surf%frac(ind_veg_wall,m)  *           &
2602                                        surf%emissivity(ind_veg_wall,m)        &
2603                                      + surf%frac(ind_pav_green,m) *           &
2604                                        surf%emissivity(ind_pav_green,m)       &
2605                                      + surf%frac(ind_wat_win,m)   *           &
2606                                        surf%emissivity(ind_wat_win,m)         &
2607                                      ) * 3.0_wp * sigma_sb                    &
2608                                      * ( surf%pt_surface(m) * exner(nzb) )** 3
2609
2610
2611                   IF ( bulk_cloud_model  .OR.  cloud_droplets  )  THEN
2612                      pt1 = pt(k,j,i) + lv_d_cp / exner(k) * ql(k,j,i)
2613                      surf%rad_lw_in(m)  = 0.8_wp * sigma_sb * (pt1 * exner(k))**4
2614                   ELSE
2615                      surf%rad_lw_in(m)  = 0.8_wp * sigma_sb * (pt(k,j,i) * exner(k))**4
2616                   ENDIF
2617
2618                   surf%rad_net(m) = surf%rad_sw_in(m) - surf%rad_sw_out(m)    &
2619                                   + surf%rad_lw_in(m) - surf%rad_lw_out(m)
2620
2621                ENDDO
2622
2623             ENDIF
2624
2625!
2626!--          Fill out values in radiation arrays
2627             DO  m = 1, surf%ns
2628                i = surf%i(m)
2629                j = surf%j(m)
2630                rad_sw_in(0,j,i) = surf%rad_sw_in(m)
2631                rad_sw_out(0,j,i) = surf%rad_sw_out(m)
2632                rad_lw_in(0,j,i) = surf%rad_lw_in(m)
2633                rad_lw_out(0,j,i) = surf%rad_lw_out(m)
2634             ENDDO
2635 
2636          END SUBROUTINE radiation_clearsky_surf
2637
2638    END SUBROUTINE radiation_clearsky
2639
2640
2641!------------------------------------------------------------------------------!
2642! Description:
2643! ------------
2644!> This scheme keeps the prescribed net radiation constant during the run
2645!------------------------------------------------------------------------------!
2646    SUBROUTINE radiation_constant
2647
2648
2649       IMPLICIT NONE
2650
2651       INTEGER(iwp) ::  l         !< running index for surface orientation
2652
2653       REAL(wp)     ::  pt1       !< potential temperature at first grid level or mean value at urban layer top
2654       REAL(wp)     ::  pt1_l     !< potential temperature at first grid level or mean value at urban layer top at local subdomain
2655       REAL(wp)     ::  ql1       !< liquid water mixing ratio at first grid level or mean value at urban layer top
2656       REAL(wp)     ::  ql1_l     !< liquid water mixing ratio at first grid level or mean value at urban layer top at local subdomain
2657
2658       TYPE(surf_type), POINTER ::  surf !< pointer on respective surface type, used to generalize routine
2659
2660!
2661!--    In case averaged radiation is used, calculate mean temperature and
2662!--    liquid water mixing ratio at the urban-layer top.
2663       IF ( average_radiation ) THEN   
2664          pt1   = 0.0_wp
2665          IF ( bulk_cloud_model  .OR.  cloud_droplets )  ql1   = 0.0_wp
2666
2667          pt1_l = SUM( pt(nzut,nys:nyn,nxl:nxr) )
2668          IF ( bulk_cloud_model  .OR.  cloud_droplets )  ql1_l = SUM( ql(nzut,nys:nyn,nxl:nxr) )
2669
2670#if defined( __parallel )     
2671          IF ( collective_wait )  CALL MPI_BARRIER( comm2d, ierr )
2672          CALL MPI_ALLREDUCE( pt1_l, pt1, 1, MPI_REAL, MPI_SUM, comm2d, ierr )
2673          IF ( ierr /= 0 ) THEN
2674              WRITE(9,*) 'Error MPI_AllReduce3:', ierr, pt1_l, pt1
2675              FLUSH(9)
2676          ENDIF
2677          IF ( bulk_cloud_model  .OR.  cloud_droplets )  THEN
2678             CALL MPI_ALLREDUCE( ql1_l, ql1, 1, MPI_REAL, MPI_SUM, comm2d, ierr )
2679             IF ( ierr /= 0 ) THEN
2680                 WRITE(9,*) 'Error MPI_AllReduce4:', ierr, ql1_l, ql1
2681                 FLUSH(9)
2682             ENDIF
2683          ENDIF
2684#else
2685          pt1 = pt1_l
2686          IF ( bulk_cloud_model  .OR.  cloud_droplets )  ql1 = ql1_l
2687#endif
2688          IF ( bulk_cloud_model  .OR.  cloud_droplets )  pt1 = pt1 + lv_d_cp / exner(nzut+1) * ql1
2689!
2690!--       Finally, divide by number of grid points
2691          pt1 = pt1 / REAL( ( nx + 1 ) * ( ny + 1 ), KIND=wp )
2692       ENDIF
2693
2694!
2695!--    First, horizontal surfaces
2696       surf => surf_lsm_h
2697       CALL radiation_constant_surf
2698       surf => surf_usm_h
2699       CALL radiation_constant_surf
2700!
2701!--    Vertical surfaces
2702       DO  l = 0, 3
2703          surf => surf_lsm_v(l)
2704          CALL radiation_constant_surf
2705          surf => surf_usm_v(l)
2706          CALL radiation_constant_surf
2707       ENDDO
2708
2709       CONTAINS
2710
2711          SUBROUTINE radiation_constant_surf
2712
2713             IMPLICIT NONE
2714
2715             INTEGER(iwp) ::  i         !< index x-direction
2716             INTEGER(iwp) ::  ioff      !< offset between surface element and adjacent grid point along x
2717             INTEGER(iwp) ::  j         !< index y-direction
2718             INTEGER(iwp) ::  joff      !< offset between surface element and adjacent grid point along y
2719             INTEGER(iwp) ::  k         !< index z-direction
2720             INTEGER(iwp) ::  koff      !< offset between surface element and adjacent grid point along z
2721             INTEGER(iwp) ::  m         !< running index for surface elements
2722
2723             IF ( surf%ns < 1 )  RETURN
2724
2725!--          Calculate homogenoeus urban radiation fluxes
2726             IF ( average_radiation ) THEN
2727
2728                surf%rad_net = net_radiation
2729
2730                surf%rad_lw_in  = 0.8_wp * sigma_sb * (pt1 * exner(nzut+1))**4
2731
2732                surf%rad_lw_out = emissivity_urb * sigma_sb * (t_rad_urb)**4   &
2733                                    + ( 1.0_wp - emissivity_urb )             & ! shouldn't be this a bulk value -- emissivity_urb?
2734                                    * surf%rad_lw_in
2735
2736                surf%rad_lw_out_change_0 = 3.0_wp * emissivity_urb * sigma_sb  &
2737                                           * t_rad_urb**3
2738
2739                surf%rad_sw_in = ( surf%rad_net - surf%rad_lw_in               &
2740                                     + surf%rad_lw_out )                       &
2741                                     / ( 1.0_wp - albedo_urb )
2742
2743                surf%rad_sw_out =  albedo_urb * surf%rad_sw_in
2744
2745!
2746!--          Calculate radiation fluxes for each surface element
2747             ELSE
2748!
2749!--             Determine index offset between surface element and adjacent
2750!--             atmospheric grid point
2751                ioff = surf%ioff
2752                joff = surf%joff
2753                koff = surf%koff
2754
2755!
2756!--             Prescribe net radiation and estimate the remaining radiative fluxes
2757                DO  m = 1, surf%ns
2758                   i = surf%i(m)
2759                   j = surf%j(m)
2760                   k = surf%k(m)
2761
2762                   surf%rad_net(m) = net_radiation
2763
2764                   IF ( bulk_cloud_model  .OR.  cloud_droplets )  THEN
2765                      pt1 = pt(k,j,i) + lv_d_cp / exner(k) * ql(k,j,i)
2766                      surf%rad_lw_in(m)  = 0.8_wp * sigma_sb * (pt1 * exner(k))**4
2767                   ELSE
2768                      surf%rad_lw_in(m)  = 0.8_wp * sigma_sb *                 &
2769                                             ( pt(k,j,i) * exner(k) )**4
2770                   ENDIF
2771
2772!
2773!--                Weighted average according to surface fraction.
2774                   surf%rad_lw_out(m) = ( surf%frac(ind_veg_wall,m)  *         &
2775                                          surf%emissivity(ind_veg_wall,m)      &
2776                                        + surf%frac(ind_pav_green,m) *         &
2777                                          surf%emissivity(ind_pav_green,m)     &
2778                                        + surf%frac(ind_wat_win,m)   *         &
2779                                          surf%emissivity(ind_wat_win,m)       &
2780                                        )                                      &
2781                                      * sigma_sb                               &
2782                                      * ( surf%pt_surface(m) * exner(nzb) )**4
2783
2784                   surf%rad_sw_in(m) = ( surf%rad_net(m) - surf%rad_lw_in(m)   &
2785                                       + surf%rad_lw_out(m) )                  &
2786                                       / ( 1.0_wp -                            &
2787                                          ( surf%frac(ind_veg_wall,m)  *       &
2788                                            surf%albedo(ind_veg_wall,m)        &
2789                                         +  surf%frac(ind_pav_green,m) *       &
2790                                            surf%albedo(ind_pav_green,m)       &
2791                                         +  surf%frac(ind_wat_win,m)   *       &
2792                                            surf%albedo(ind_wat_win,m) )       &
2793                                         )
2794
2795                   surf%rad_sw_out(m) = ( surf%frac(ind_veg_wall,m)  *         &
2796                                          surf%albedo(ind_veg_wall,m)          &
2797                                        + surf%frac(ind_pav_green,m) *         &
2798                                          surf%albedo(ind_pav_green,m)         &
2799                                        + surf%frac(ind_wat_win,m)   *         &
2800                                          surf%albedo(ind_wat_win,m) )         &
2801                                      * surf%rad_sw_in(m)
2802
2803                ENDDO
2804
2805             ENDIF
2806
2807!
2808!--          Fill out values in radiation arrays
2809             DO  m = 1, surf%ns
2810                i = surf%i(m)
2811                j = surf%j(m)
2812                rad_sw_in(0,j,i) = surf%rad_sw_in(m)
2813                rad_sw_out(0,j,i) = surf%rad_sw_out(m)
2814                rad_lw_in(0,j,i) = surf%rad_lw_in(m)
2815                rad_lw_out(0,j,i) = surf%rad_lw_out(m)
2816             ENDDO
2817
2818          END SUBROUTINE radiation_constant_surf
2819         
2820
2821    END SUBROUTINE radiation_constant
2822
2823!------------------------------------------------------------------------------!
2824! Description:
2825! ------------
2826!> Header output for radiation model
2827!------------------------------------------------------------------------------!
2828    SUBROUTINE radiation_header ( io )
2829
2830
2831       IMPLICIT NONE
2832 
2833       INTEGER(iwp), INTENT(IN) ::  io            !< Unit of the output file
2834   
2835
2836       
2837!
2838!--    Write radiation model header
2839       WRITE( io, 3 )
2840
2841       IF ( radiation_scheme == "constant" )  THEN
2842          WRITE( io, 4 ) net_radiation
2843       ELSEIF ( radiation_scheme == "clear-sky" )  THEN
2844          WRITE( io, 5 )
2845       ELSEIF ( radiation_scheme == "rrtmg" )  THEN
2846          WRITE( io, 6 )
2847          IF ( .NOT. lw_radiation )  WRITE( io, 10 )
2848          IF ( .NOT. sw_radiation )  WRITE( io, 11 )
2849       ENDIF
2850
2851       IF ( albedo_type_f%from_file  .OR.  vegetation_type_f%from_file  .OR.   &
2852            pavement_type_f%from_file  .OR.  water_type_f%from_file  .OR.      &
2853            building_type_f%from_file )  THEN
2854             WRITE( io, 13 )
2855       ELSE 
2856          IF ( albedo_type == 0 )  THEN
2857             WRITE( io, 7 ) albedo
2858          ELSE
2859             WRITE( io, 8 ) TRIM( albedo_type_name(albedo_type) )
2860          ENDIF
2861       ENDIF
2862       IF ( constant_albedo )  THEN
2863          WRITE( io, 9 )
2864       ENDIF
2865       
2866       WRITE( io, 12 ) dt_radiation
2867 
2868
2869 3 FORMAT (//' Radiation model information:'/                                  &
2870              ' ----------------------------'/)
2871 4 FORMAT ('    --> Using constant net radiation: net_radiation = ', F6.2,     &
2872           // 'W/m**2')
2873 5 FORMAT ('    --> Simple radiation scheme for clear sky is used (no clouds,',&
2874                   ' default)')
2875 6 FORMAT ('    --> RRTMG scheme is used')
2876 7 FORMAT (/'    User-specific surface albedo: albedo =', F6.3)
2877 8 FORMAT (/'    Albedo is set for land surface type: ', A)
2878 9 FORMAT (/'    --> Albedo is fixed during the run')
287910 FORMAT (/'    --> Longwave radiation is disabled')
288011 FORMAT (/'    --> Shortwave radiation is disabled.')
288112 FORMAT  ('    Timestep: dt_radiation = ', F6.2, '  s')
288213 FORMAT (/'    Albedo is set individually for each xy-location, according ', &
2883                 'to given surface type.')
2884
2885
2886    END SUBROUTINE radiation_header
2887   
2888
2889!------------------------------------------------------------------------------!
2890! Description:
2891! ------------
2892!> Parin for &radiation_parameters for radiation model
2893!------------------------------------------------------------------------------!
2894    SUBROUTINE radiation_parin
2895
2896
2897       IMPLICIT NONE
2898
2899       CHARACTER (LEN=80) ::  line  !< dummy string that contains the current line of the parameter file
2900       
2901       NAMELIST /radiation_par/   albedo, albedo_type, albedo_lw_dir,          &
2902                                  albedo_lw_dif, albedo_sw_dir, albedo_sw_dif, &
2903                                  constant_albedo, dt_radiation, emissivity,   &
2904                                  lw_radiation, mrt_nlevels, mrt_skip_roof,    &
2905                                  mrt_include_sw,  net_radiation,              &
2906                                  radiation_scheme, skip_time_do_radiation,    &
2907                                  sw_radiation, unscheduled_radiation_calls,   &
2908                                  read_svf_on_init, write_svf_on_init,         &
2909                                  max_raytracing_dist, min_irrf_value,         &
2910                                  nrefsteps, raytrace_mpi_rma,                 &
2911                                  dist_max_svf,                                &
2912                                  surface_reflections, svfnorm_report_thresh,  &
2913                                  radiation_interactions_on,                   &
2914                                  rad_angular_discretization,                  &
2915                                  raytrace_discrete_azims,                     &
2916                                  raytrace_discrete_elevs
2917   
2918       NAMELIST /radiation_parameters/   albedo, albedo_type, albedo_lw_dir,   &
2919                                  albedo_lw_dif, albedo_sw_dir, albedo_sw_dif, &
2920                                  constant_albedo, dt_radiation, emissivity,   &
2921                                  lw_radiation, mrt_nlevels, mrt_skip_roof,    &
2922                                  mrt_include_sw,  net_radiation,              &
2923                                  radiation_scheme, skip_time_do_radiation,    &
2924                                  sw_radiation, unscheduled_radiation_calls,   &
2925                                  max_raytracing_dist, min_irrf_value,         &
2926                                  nrefsteps, raytrace_mpi_rma,                 &
2927                                  dist_max_svf,                                &
2928                                  surface_reflections, svfnorm_report_thresh,  &
2929                                  radiation_interactions_on,                   &
2930                                  rad_angular_discretization,                  &
2931                                  raytrace_discrete_azims,                     &
2932                                  raytrace_discrete_elevs
2933   
2934       line = ' '
2935       
2936!
2937!--    Try to find radiation model namelist
2938       REWIND ( 11 )
2939       line = ' '
2940       DO WHILE ( INDEX( line, '&radiation_parameters' ) == 0 )
2941          READ ( 11, '(A)', END=12 )  line
2942       ENDDO
2943       BACKSPACE ( 11 )
2944
2945!
2946!--    Read user-defined namelist
2947       READ ( 11, radiation_parameters, ERR = 10 )
2948
2949!
2950!--    Set flag that indicates that the radiation model is switched on
2951       radiation = .TRUE.
2952
2953       GOTO 14
2954
2955 10    BACKSPACE( 11 )
2956       READ( 11 , '(A)') line
2957       CALL parin_fail_message( 'radiation_parameters', line )
2958!
2959!--    Try to find old namelist
2960 12    REWIND ( 11 )
2961       line = ' '
2962       DO WHILE ( INDEX( line, '&radiation_par' ) == 0 )
2963          READ ( 11, '(A)', END=14 )  line
2964       ENDDO
2965       BACKSPACE ( 11 )
2966
2967!
2968!--    Read user-defined namelist
2969       READ ( 11, radiation_par, ERR = 13, END = 14 )
2970
2971       message_string = 'namelist radiation_par is deprecated and will be ' // &
2972                     'removed in near future. Please use namelist ' //         &
2973                     'radiation_parameters instead'
2974       CALL message( 'radiation_parin', 'PA0487', 0, 1, 0, 6, 0 )
2975
2976!
2977!--    Set flag that indicates that the radiation model is switched on
2978       radiation = .TRUE.
2979
2980       IF ( .NOT.  radiation_interactions_on  .AND.  surface_reflections )  THEN
2981          message_string = 'surface_reflections is allowed only when '      // &
2982               'radiation_interactions_on is set to TRUE'
2983          CALL message( 'radiation_parin', 'PA0293',1, 2, 0, 6, 0 )
2984       ENDIF
2985
2986       GOTO 14
2987
2988 13    BACKSPACE( 11 )
2989       READ( 11 , '(A)') line
2990       CALL parin_fail_message( 'radiation_par', line )
2991
2992 14    CONTINUE
2993       
2994    END SUBROUTINE radiation_parin
2995
2996
2997!------------------------------------------------------------------------------!
2998! Description:
2999! ------------
3000!> Implementation of the RRTMG radiation_scheme
3001!------------------------------------------------------------------------------!
3002    SUBROUTINE radiation_rrtmg
3003
3004#if defined ( __rrtmg )
3005       USE indices,                                                            &
3006           ONLY:  nbgp
3007
3008       USE particle_attributes,                                                &
3009           ONLY:  grid_particles, number_of_particles, particles,              &
3010                  particle_advection_start, prt_count
3011
3012       IMPLICIT NONE
3013
3014
3015       INTEGER(iwp) ::  i, j, k, l, m, n !< loop indices
3016       INTEGER(iwp) ::  k_topo     !< topography top index
3017
3018       REAL(wp)     ::  nc_rad, &    !< number concentration of cloud droplets
3019                        s_r2,   &    !< weighted sum over all droplets with r^2
3020                        s_r3         !< weighted sum over all droplets with r^3
3021
3022       REAL(wp), DIMENSION(0:nzt+1) :: pt_av, q_av, ql_av
3023!
3024!--    Just dummy arguments
3025       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: rrtm_lw_taucld_dum,          &
3026                                                  rrtm_lw_tauaer_dum,          &
3027                                                  rrtm_sw_taucld_dum,          &
3028                                                  rrtm_sw_ssacld_dum,          &
3029                                                  rrtm_sw_asmcld_dum,          &
3030                                                  rrtm_sw_fsfcld_dum,          &
3031                                                  rrtm_sw_tauaer_dum,          &
3032                                                  rrtm_sw_ssaaer_dum,          &
3033                                                  rrtm_sw_asmaer_dum,          &
3034                                                  rrtm_sw_ecaer_dum
3035
3036!
3037!--    Calculate current (cosine of) zenith angle and whether the sun is up
3038       CALL calc_zenith     
3039!
3040!--    Calculate surface albedo. In case average radiation is applied,
3041!--    this is not required.
3042       IF ( .NOT. constant_albedo )  THEN
3043!
3044!--       Horizontally aligned default, natural and urban surfaces
3045          CALL calc_albedo( surf_lsm_h    )
3046          CALL calc_albedo( surf_usm_h    )
3047!
3048!--       Vertically aligned default, natural and urban surfaces
3049          DO  l = 0, 3
3050             CALL calc_albedo( surf_lsm_v(l) )
3051             CALL calc_albedo( surf_usm_v(l) )
3052          ENDDO
3053       ENDIF
3054
3055!
3056!--    Prepare input data for RRTMG
3057
3058!
3059!--    In case of large scale forcing with surface data, calculate new pressure
3060!--    profile. nzt_rad might be modified by these calls and all required arrays
3061!--    will then be re-allocated
3062       IF ( large_scale_forcing  .AND.  lsf_surf )  THEN
3063          CALL read_sounding_data
3064          CALL read_trace_gas_data
3065       ENDIF
3066
3067
3068       IF ( average_radiation ) THEN
3069
3070          rrtm_asdir(1)  = albedo_urb
3071          rrtm_asdif(1)  = albedo_urb
3072          rrtm_aldir(1)  = albedo_urb
3073          rrtm_aldif(1)  = albedo_urb
3074
3075          rrtm_emis = emissivity_urb
3076!
3077!--       Calculate mean pt profile. Actually, only one height level is required.
3078          CALL calc_mean_profile( pt, 4 )
3079          pt_av = hom(:, 1, 4, 0)
3080         
3081          IF ( humidity )  THEN
3082             CALL calc_mean_profile( q, 41 )
3083             q_av  = hom(:, 1, 41, 0)
3084          ENDIF
3085!
3086!--       Prepare profiles of temperature and H2O volume mixing ratio
3087          rrtm_tlev(0,nzb+1) = t_rad_urb
3088
3089          IF ( bulk_cloud_model )  THEN
3090
3091             CALL calc_mean_profile( ql, 54 )
3092             ! average ql is now in hom(:, 1, 54, 0)
3093             ql_av = hom(:, 1, 54, 0)
3094             
3095             DO k = nzb+1, nzt+1
3096                rrtm_tlay(0,k) = pt_av(k) * ( (hyp(k) ) / 100000._wp       &
3097                                 )**.286_wp + lv_d_cp * ql_av(k)
3098                rrtm_h2ovmr(0,k) = mol_mass_air_d_wv * (q_av(k) - ql_av(k))
3099             ENDDO
3100          ELSE
3101             DO k = nzb+1, nzt+1
3102                rrtm_tlay(0,k) = pt_av(k) * ( (hyp(k) ) / 100000._wp       &
3103                                 )**.286_wp
3104             ENDDO
3105
3106             IF ( humidity )  THEN
3107                DO k = nzb+1, nzt+1
3108                   rrtm_h2ovmr(0,k) = mol_mass_air_d_wv * q_av(k)
3109                ENDDO
3110             ELSE
3111                rrtm_h2ovmr(0,nzb+1:nzt+1) = 0.0_wp
3112             ENDIF
3113          ENDIF
3114
3115!
3116!--       Avoid temperature/humidity jumps at the top of the LES domain by
3117!--       linear interpolation from nzt+2 to nzt+7
3118          DO k = nzt+2, nzt+7
3119             rrtm_tlay(0,k) = rrtm_tlay(0,nzt+1)                            &
3120                           + ( rrtm_tlay(0,nzt+8) - rrtm_tlay(0,nzt+1) )    &
3121                           / ( rrtm_play(0,nzt+8) - rrtm_play(0,nzt+1) )    &
3122                           * ( rrtm_play(0,k) - rrtm_play(0,nzt+1) )
3123
3124             rrtm_h2ovmr(0,k) = rrtm_h2ovmr(0,nzt+1)                        &
3125                           + ( rrtm_h2ovmr(0,nzt+8) - rrtm_h2ovmr(0,nzt+1) )&
3126                           / ( rrtm_play(0,nzt+8)   - rrtm_play(0,nzt+1)   )&
3127                           * ( rrtm_play(0,k) - rrtm_play(0,nzt+1) )
3128
3129          ENDDO
3130
3131!--       Linear interpolate to zw grid
3132          DO k = nzb+2, nzt+8
3133             rrtm_tlev(0,k)   = rrtm_tlay(0,k-1) + (rrtm_tlay(0,k) -        &
3134                                rrtm_tlay(0,k-1))                           &
3135                                / ( rrtm_play(0,k) - rrtm_play(0,k-1) )     &
3136                                * ( rrtm_plev(0,k) - rrtm_play(0,k-1) )
3137          ENDDO
3138
3139
3140!
3141!--       Calculate liquid water path and cloud fraction for each column.
3142!--       Note that LWP is required in g/m² instead of kg/kg m.
3143          rrtm_cldfr  = 0.0_wp
3144          rrtm_reliq  = 0.0_wp
3145          rrtm_cliqwp = 0.0_wp
3146          rrtm_icld   = 0
3147
3148          IF ( bulk_cloud_model )  THEN
3149             DO k = nzb+1, nzt+1
3150                rrtm_cliqwp(0,k) =  ql_av(k) * 1000._wp *                   &
3151                                    (rrtm_plev(0,k) - rrtm_plev(0,k+1))     &
3152                                    * 100._wp / g 
3153
3154                IF ( rrtm_cliqwp(0,k) > 0._wp )  THEN
3155                   rrtm_cldfr(0,k) = 1._wp
3156                   IF ( rrtm_icld == 0 )  rrtm_icld = 1
3157
3158!
3159!--                Calculate cloud droplet effective radius
3160                   rrtm_reliq(0,k) = 1.0E6_wp * ( 3.0_wp * ql_av(k)         &
3161                                     * rho_surface                          &
3162                                     / ( 4.0_wp * pi * nc_const * rho_l )   &
3163                                     )**0.33333333333333_wp                 &
3164                                     * EXP( LOG( sigma_gc )**2 )
3165!
3166!--                Limit effective radius
3167                   IF ( rrtm_reliq(0,k) > 0.0_wp )  THEN
3168                      rrtm_reliq(0,k) = MAX(rrtm_reliq(0,k),2.5_wp)
3169                      rrtm_reliq(0,k) = MIN(rrtm_reliq(0,k),60.0_wp)
3170                   ENDIF
3171                ENDIF
3172             ENDDO
3173          ENDIF
3174
3175!
3176!--       Set surface temperature
3177          rrtm_tsfc = t_rad_urb
3178         
3179          IF ( lw_radiation )  THEN       
3180         
3181             CALL rrtmg_lw( 1, nzt_rad      , rrtm_icld    , rrtm_idrv      ,&
3182             rrtm_play       , rrtm_plev    , rrtm_tlay    , rrtm_tlev      ,&
3183             rrtm_tsfc       , rrtm_h2ovmr  , rrtm_o3vmr   , rrtm_co2vmr    ,&
3184             rrtm_ch4vmr     , rrtm_n2ovmr  , rrtm_o2vmr   , rrtm_cfc11vmr  ,&
3185             rrtm_cfc12vmr   , rrtm_cfc22vmr, rrtm_ccl4vmr , rrtm_emis      ,&
3186             rrtm_inflglw    , rrtm_iceflglw, rrtm_liqflglw, rrtm_cldfr     ,&
3187             rrtm_lw_taucld  , rrtm_cicewp  , rrtm_cliqwp  , rrtm_reice     ,& 
3188             rrtm_reliq      , rrtm_lw_tauaer,                               &
3189             rrtm_lwuflx     , rrtm_lwdflx  , rrtm_lwhr  ,                   &
3190             rrtm_lwuflxc    , rrtm_lwdflxc , rrtm_lwhrc ,                   &
3191             rrtm_lwuflx_dt  ,  rrtm_lwuflxc_dt )
3192
3193!
3194!--          Save fluxes
3195             DO k = nzb, nzt+1
3196                rad_lw_in(k,:,:)  = rrtm_lwdflx(0,k)
3197                rad_lw_out(k,:,:) = rrtm_lwuflx(0,k)
3198             ENDDO
3199             rad_lw_in_diff(:,:) = rad_lw_in(0,:,:)
3200!
3201!--          Save heating rates (convert from K/d to K/h).
3202!--          Further, even though an aggregated radiation is computed, map
3203!--          signle-column profiles on top of any topography, in order to
3204!--          obtain correct near surface radiation heating/cooling rates.
3205             DO  i = nxl, nxr
3206                DO  j = nys, nyn
3207                   k_topo = get_topography_top_index_ji( j, i, 's' )
3208                   DO k = k_topo+1, nzt+1
3209                      rad_lw_hr(k,j,i)     = rrtm_lwhr(0,k-k_topo)  * d_hours_day
3210                      rad_lw_cs_hr(k,j,i)  = rrtm_lwhrc(0,k-k_topo) * d_hours_day
3211                   ENDDO
3212                ENDDO
3213             ENDDO
3214
3215          ENDIF
3216
3217          IF ( sw_radiation .AND. sun_up )  THEN
3218             CALL rrtmg_sw( 1, nzt_rad      , rrtm_icld     , rrtm_iaer      ,&
3219             rrtm_play      , rrtm_plev     , rrtm_tlay     , rrtm_tlev      ,&
3220             rrtm_tsfc      , rrtm_h2ovmr   , rrtm_o3vmr    , rrtm_co2vmr    ,&
3221             rrtm_ch4vmr    , rrtm_n2ovmr   , rrtm_o2vmr    , rrtm_asdir     ,&
3222             rrtm_asdif     , rrtm_aldir    , rrtm_aldif    , zenith         ,&
3223             0.0_wp         , day_of_year   , solar_constant, rrtm_inflgsw   ,&
3224             rrtm_iceflgsw  , rrtm_liqflgsw , rrtm_cldfr    , rrtm_sw_taucld ,&
3225             rrtm_sw_ssacld , rrtm_sw_asmcld, rrtm_sw_fsfcld, rrtm_cicewp    ,&
3226             rrtm_cliqwp    , rrtm_reice    , rrtm_reliq    , rrtm_sw_tauaer ,&
3227             rrtm_sw_ssaaer , rrtm_sw_asmaer, rrtm_sw_ecaer , rrtm_swuflx    ,&
3228             rrtm_swdflx    , rrtm_swhr     , rrtm_swuflxc  , rrtm_swdflxc   ,&
3229             rrtm_swhrc     , rrtm_dirdflux , rrtm_difdflux )
3230 
3231!
3232!--          Save fluxes:
3233!--          - whole domain
3234             DO k = nzb, nzt+1
3235                rad_sw_in(k,:,:)  = rrtm_swdflx(0,k)
3236                rad_sw_out(k,:,:) = rrtm_swuflx(0,k)
3237             ENDDO
3238!--          - direct and diffuse SW at urban-surface-layer (required by RTM)
3239             rad_sw_in_dir(:,:) = rrtm_dirdflux(0,nzb)
3240             rad_sw_in_diff(:,:) = rrtm_difdflux(0,nzb)
3241
3242!
3243!--          Save heating rates (convert from K/d to K/s)
3244             DO k = nzb+1, nzt+1
3245                rad_sw_hr(k,:,:)     = rrtm_swhr(0,k)  * d_hours_day
3246                rad_sw_cs_hr(k,:,:)  = rrtm_swhrc(0,k) * d_hours_day
3247             ENDDO
3248!
3249!--       Solar radiation is zero during night
3250          ELSE
3251             rad_sw_in  = 0.0_wp
3252             rad_sw_out = 0.0_wp
3253             rad_sw_in_dir(:,:) = 0.0_wp
3254             rad_sw_in_diff(:,:) = 0.0_wp
3255          ENDIF
3256!
3257!--    RRTMG is called for each (j,i) grid point separately, starting at the
3258!--    highest topography level. Here no RTM is used since average_radiation is false
3259       ELSE
3260!
3261!--       Loop over all grid points
3262          DO i = nxl, nxr
3263             DO j = nys, nyn
3264
3265!
3266!--             Prepare profiles of temperature and H2O volume mixing ratio
3267                DO  m = surf_lsm_h%start_index(j,i), surf_lsm_h%end_index(j,i)
3268                   rrtm_tlev(0,nzb+1) = surf_lsm_h%pt_surface(m) * exner(nzb)
3269                ENDDO
3270                DO  m = surf_usm_h%start_index(j,i), surf_usm_h%end_index(j,i)
3271                   rrtm_tlev(0,nzb+1) = surf_usm_h%pt_surface(m) * exner(nzb)
3272                ENDDO
3273
3274
3275                IF ( bulk_cloud_model )  THEN
3276                   DO k = nzb+1, nzt+1
3277                      rrtm_tlay(0,k) = pt(k,j,i) * exner(k)                    &
3278                                        + lv_d_cp * ql(k,j,i)
3279                      rrtm_h2ovmr(0,k) = mol_mass_air_d_wv * (q(k,j,i) - ql(k,j,i))
3280                   ENDDO
3281                ELSEIF ( cloud_droplets )  THEN
3282                   DO k = nzb+1, nzt+1
3283                      rrtm_tlay(0,k) = pt(k,j,i) * exner(k)                     &
3284                                        + lv_d_cp * ql(k,j,i)
3285                      rrtm_h2ovmr(0,k) = mol_mass_air_d_wv * q(k,j,i) 
3286                   ENDDO
3287                ELSE
3288                   DO k = nzb+1, nzt+1
3289                      rrtm_tlay(0,k) = pt(k,j,i) * exner(k)
3290                   ENDDO
3291
3292                   IF ( humidity )  THEN
3293                      DO k = nzb+1, nzt+1
3294                         rrtm_h2ovmr(0,k) =  mol_mass_air_d_wv * q(k,j,i)
3295                      ENDDO   
3296                   ELSE
3297                      rrtm_h2ovmr(0,nzb+1:nzt+1) = 0.0_wp
3298                   ENDIF
3299                ENDIF
3300
3301!
3302!--             Avoid temperature/humidity jumps at the top of the LES domain by
3303!--             linear interpolation from nzt+2 to nzt+7
3304                DO k = nzt+2, nzt+7
3305                   rrtm_tlay(0,k) = rrtm_tlay(0,nzt+1)                         &
3306                                 + ( rrtm_tlay(0,nzt+8) - rrtm_tlay(0,nzt+1) ) &
3307                                 / ( rrtm_play(0,nzt+8) - rrtm_play(0,nzt+1) ) &
3308                                 * ( rrtm_play(0,k)     - rrtm_play(0,nzt+1) )
3309
3310                   rrtm_h2ovmr(0,k) = rrtm_h2ovmr(0,nzt+1)                     &
3311                              + ( rrtm_h2ovmr(0,nzt+8) - rrtm_h2ovmr(0,nzt+1) )&
3312                              / ( rrtm_play(0,nzt+8)   - rrtm_play(0,nzt+1)   )&
3313                              * ( rrtm_play(0,k)       - rrtm_play(0,nzt+1) )
3314
3315                ENDDO
3316
3317!--             Linear interpolate to zw grid
3318                DO k = nzb+2, nzt+8
3319                   rrtm_tlev(0,k)   = rrtm_tlay(0,k-1) + (rrtm_tlay(0,k) -     &
3320                                      rrtm_tlay(0,k-1))                        &
3321                                      / ( rrtm_play(0,k) - rrtm_play(0,k-1) )  &
3322                                      * ( rrtm_plev(0,k) - rrtm_play(0,k-1) )
3323                ENDDO
3324
3325
3326!
3327!--             Calculate liquid water path and cloud fraction for each column.
3328!--             Note that LWP is required in g/m² instead of kg/kg m.
3329                rrtm_cldfr  = 0.0_wp
3330                rrtm_reliq  = 0.0_wp
3331                rrtm_cliqwp = 0.0_wp
3332                rrtm_icld   = 0
3333
3334                IF ( bulk_cloud_model  .OR.  cloud_droplets )  THEN
3335                   DO k = nzb+1, nzt+1
3336                      rrtm_cliqwp(0,k) =  ql(k,j,i) * 1000.0_wp *              &
3337                                          (rrtm_plev(0,k) - rrtm_plev(0,k+1))  &
3338                                          * 100.0_wp / g 
3339
3340                      IF ( rrtm_cliqwp(0,k) > 0.0_wp )  THEN
3341                         rrtm_cldfr(0,k) = 1.0_wp
3342                         IF ( rrtm_icld == 0 )  rrtm_icld = 1
3343
3344!
3345!--                      Calculate cloud droplet effective radius
3346                         IF ( bulk_cloud_model )  THEN
3347!
3348!--                         Calculete effective droplet radius. In case of using
3349!--                         cloud_scheme = 'morrison' and a non reasonable number
3350!--                         of cloud droplets the inital aerosol number 
3351!--                         concentration is considered.
3352                            IF ( microphysics_morrison )  THEN
3353                               IF ( nc(k,j,i) > 1.0E-20_wp )  THEN
3354                                  nc_rad = nc(k,j,i)
3355                               ELSE
3356                                  nc_rad = na_init
3357                               ENDIF
3358                            ELSE
3359                               nc_rad = nc_const
3360                            ENDIF 
3361
3362                            rrtm_reliq(0,k) = 1.0E6_wp * ( 3.0_wp * ql(k,j,i)     &
3363                                              * rho_surface                       &
3364                                              / ( 4.0_wp * pi * nc_rad * rho_l )  &
3365                                              )**0.33333333333333_wp              &
3366                                              * EXP( LOG( sigma_gc )**2 )
3367
3368                         ELSEIF ( cloud_droplets )  THEN
3369                            number_of_particles = prt_count(k,j,i)
3370
3371                            IF (number_of_particles <= 0)  CYCLE
3372                            particles => grid_particles(k,j,i)%particles(1:number_of_particles)
3373                            s_r2 = 0.0_wp
3374                            s_r3 = 0.0_wp
3375
3376                            DO  n = 1, number_of_particles
3377                               IF ( particles(n)%particle_mask )  THEN
3378                                  s_r2 = s_r2 + particles(n)%radius**2 *       &
3379                                         particles(n)%weight_factor
3380                                  s_r3 = s_r3 + particles(n)%radius**3 *       &
3381                                         particles(n)%weight_factor
3382                               ENDIF
3383                            ENDDO
3384
3385                            IF ( s_r2 > 0.0_wp )  rrtm_reliq(0,k) = s_r3 / s_r2
3386
3387                         ENDIF
3388
3389!
3390!--                      Limit effective radius
3391                         IF ( rrtm_reliq(0,k) > 0.0_wp )  THEN
3392                            rrtm_reliq(0,k) = MAX(rrtm_reliq(0,k),2.5_wp)
3393                            rrtm_reliq(0,k) = MIN(rrtm_reliq(0,k),60.0_wp)
3394                        ENDIF
3395                      ENDIF
3396                   ENDDO
3397                ENDIF
3398
3399!
3400!--             Write surface emissivity and surface temperature at current
3401!--             surface element on RRTMG-shaped array.
3402!--             Please note, as RRTMG is a single column model, surface attributes
3403!--             are only obtained from horizontally aligned surfaces (for
3404!--             simplicity). Taking surface attributes from horizontal and
3405!--             vertical walls would lead to multiple solutions. 
3406!--             Moreover, for natural- and urban-type surfaces, several surface
3407!--             classes can exist at a surface element next to each other.
3408!--             To obtain bulk parameters, apply a weighted average for these
3409!--             surfaces.
3410                DO  m = surf_lsm_h%start_index(j,i), surf_lsm_h%end_index(j,i)
3411                   rrtm_emis = surf_lsm_h%frac(ind_veg_wall,m)  *              &
3412                               surf_lsm_h%emissivity(ind_veg_wall,m)  +        &
3413                               surf_lsm_h%frac(ind_pav_green,m) *              &
3414                               surf_lsm_h%emissivity(ind_pav_green,m) +        & 
3415                               surf_lsm_h%frac(ind_wat_win,m)   *              &
3416                               surf_lsm_h%emissivity(ind_wat_win,m)
3417                   rrtm_tsfc = surf_lsm_h%pt_surface(m) * exner(nzb)
3418                ENDDO             
3419                DO  m = surf_usm_h%start_index(j,i), surf_usm_h%end_index(j,i)
3420                   rrtm_emis = surf_usm_h%frac(ind_veg_wall,m)  *              &
3421                               surf_usm_h%emissivity(ind_veg_wall,m)  +        &
3422                               surf_usm_h%frac(ind_pav_green,m) *              &
3423                               surf_usm_h%emissivity(ind_pav_green,m) +        & 
3424                               surf_usm_h%frac(ind_wat_win,m)   *              &
3425                               surf_usm_h%emissivity(ind_wat_win,m)
3426                   rrtm_tsfc = surf_usm_h%pt_surface(m) * exner(nzb)
3427                ENDDO
3428!
3429!--             Obtain topography top index (lower bound of RRTMG)
3430                k_topo = get_topography_top_index_ji( j, i, 's' )
3431
3432                IF ( lw_radiation )  THEN
3433!
3434!--                Due to technical reasons, copy optical depth to dummy arguments
3435!--                which are allocated on the exact size as the rrtmg_lw is called.
3436!--                As one dimesion is allocated with zero size, compiler complains
3437!--                that rank of the array does not match that of the
3438!--                assumed-shaped arguments in the RRTMG library. In order to
3439!--                avoid this, write to dummy arguments and give pass the entire
3440!--                dummy array. Seems to be the only existing work-around. 
3441                   ALLOCATE( rrtm_lw_taucld_dum(1:nbndlw+1,0:0,k_topo+1:nzt_rad+1) )
3442                   ALLOCATE( rrtm_lw_tauaer_dum(0:0,k_topo+1:nzt_rad+1,1:nbndlw+1) )
3443
3444                   rrtm_lw_taucld_dum =                                        &
3445                               rrtm_lw_taucld(1:nbndlw+1,0:0,k_topo+1:nzt_rad+1)
3446                   rrtm_lw_tauaer_dum =                                        &
3447                               rrtm_lw_tauaer(0:0,k_topo+1:nzt_rad+1,1:nbndlw+1)
3448
3449                   CALL rrtmg_lw( 1,                                           &                                       
3450                                  nzt_rad-k_topo,                              &
3451                                  rrtm_icld,                                   &
3452                                  rrtm_idrv,                                   &
3453                                  rrtm_play(:,k_topo+1:nzt_rad+1),             &
3454                                  rrtm_plev(:,k_topo+1:nzt_rad+2),             &
3455                                  rrtm_tlay(:,k_topo+1:nzt_rad+1),             &
3456                                  rrtm_tlev(:,k_topo+1:nzt_rad+2),             &
3457                                  rrtm_tsfc,                                   &
3458                                  rrtm_h2ovmr(:,k_topo+1:nzt_rad+1),           &
3459                                  rrtm_o3vmr(:,k_topo+1:nzt_rad+1),            &
3460                                  rrtm_co2vmr(:,k_topo+1:nzt_rad+1),           &
3461                                  rrtm_ch4vmr(:,k_topo+1:nzt_rad+1),           &
3462                                  rrtm_n2ovmr(:,k_topo+1:nzt_rad+1),           &
3463                                  rrtm_o2vmr(:,k_topo+1:nzt_rad+1),            &
3464                                  rrtm_cfc11vmr(:,k_topo+1:nzt_rad+1),         &
3465                                  rrtm_cfc12vmr(:,k_topo+1:nzt_rad+1),         &
3466                                  rrtm_cfc22vmr(:,k_topo+1:nzt_rad+1),         &
3467                                  rrtm_ccl4vmr(:,k_topo+1:nzt_rad+1),          &
3468                                  rrtm_emis,                                   &
3469                                  rrtm_inflglw,                                &
3470                                  rrtm_iceflglw,                               &
3471                                  rrtm_liqflglw,                               &
3472                                  rrtm_cldfr(:,k_topo+1:nzt_rad+1),            &
3473                                  rrtm_lw_taucld_dum,                          &
3474                                  rrtm_cicewp(:,k_topo+1:nzt_rad+1),           &
3475                                  rrtm_cliqwp(:,k_topo+1:nzt_rad+1),           &
3476                                  rrtm_reice(:,k_topo+1:nzt_rad+1),            & 
3477                                  rrtm_reliq(:,k_topo+1:nzt_rad+1),            &
3478                                  rrtm_lw_tauaer_dum,                          &
3479                                  rrtm_lwuflx(:,k_topo:nzt_rad+1),             &
3480                                  rrtm_lwdflx(:,k_topo:nzt_rad+1),             &
3481                                  rrtm_lwhr(:,k_topo+1:nzt_rad+1),             &
3482                                  rrtm_lwuflxc(:,k_topo:nzt_rad+1),            &
3483                                  rrtm_lwdflxc(:,k_topo:nzt_rad+1),            &
3484                                  rrtm_lwhrc(:,k_topo+1:nzt_rad+1),            &
3485                                  rrtm_lwuflx_dt(:,k_topo:nzt_rad+1),          &
3486                                  rrtm_lwuflxc_dt(:,k_topo:nzt_rad+1) )
3487
3488                   DEALLOCATE ( rrtm_lw_taucld_dum )
3489                   DEALLOCATE ( rrtm_lw_tauaer_dum )
3490!
3491!--                Save fluxes
3492                   DO k = k_topo, nzt+1
3493                      rad_lw_in(k,j,i)  = rrtm_lwdflx(0,k)
3494                      rad_lw_out(k,j,i) = rrtm_lwuflx(0,k)
3495                   ENDDO
3496
3497!
3498!--                Save heating rates (convert from K/d to K/h)
3499                   DO k = k_topo+1, nzt+1
3500                      rad_lw_hr(k,j,i)     = rrtm_lwhr(0,k-k_topo)  * d_hours_day
3501                      rad_lw_cs_hr(k,j,i)  = rrtm_lwhrc(0,k-k_topo) * d_hours_day
3502                   ENDDO
3503
3504!
3505!--                Save surface radiative fluxes and change in LW heating rate
3506!--                onto respective surface elements
3507!--                Horizontal surfaces
3508                   DO  m = surf_lsm_h%start_index(j,i),                        &
3509                           surf_lsm_h%end_index(j,i)
3510                      surf_lsm_h%rad_lw_in(m)           = rrtm_lwdflx(0,k_topo)
3511                      surf_lsm_h%rad_lw_out(m)          = rrtm_lwuflx(0,k_topo)
3512                      surf_lsm_h%rad_lw_out_change_0(m) = rrtm_lwuflx_dt(0,k_topo)
3513                   ENDDO             
3514                   DO  m = surf_usm_h%start_index(j,i),                        &
3515                           surf_usm_h%end_index(j,i)
3516                      surf_usm_h%rad_lw_in(m)           = rrtm_lwdflx(0,k_topo)
3517                      surf_usm_h%rad_lw_out(m)          = rrtm_lwuflx(0,k_topo)
3518                      surf_usm_h%rad_lw_out_change_0(m) = rrtm_lwuflx_dt(0,k_topo)
3519                   ENDDO 
3520!
3521!--                Vertical surfaces. Fluxes are obtain at vertical level of the
3522!--                respective surface element
3523                   DO  l = 0, 3
3524                      DO  m = surf_lsm_v(l)%start_index(j,i),                  &
3525                              surf_lsm_v(l)%end_index(j,i)
3526                         k                                    = surf_lsm_v(l)%k(m)
3527                         surf_lsm_v(l)%rad_lw_in(m)           = rrtm_lwdflx(0,k)
3528                         surf_lsm_v(l)%rad_lw_out(m)          = rrtm_lwuflx(0,k)
3529                         surf_lsm_v(l)%rad_lw_out_change_0(m) = rrtm_lwuflx_dt(0,k)
3530                      ENDDO             
3531                      DO  m = surf_usm_v(l)%start_index(j,i),                  &
3532                              surf_usm_v(l)%end_index(j,i)
3533                         k                                    = surf_usm_v(l)%k(m)
3534                         surf_usm_v(l)%rad_lw_in(m)           = rrtm_lwdflx(0,k)
3535                         surf_usm_v(l)%rad_lw_out(m)          = rrtm_lwuflx(0,k)
3536                         surf_usm_v(l)%rad_lw_out_change_0(m) = rrtm_lwuflx_dt(0,k)
3537                      ENDDO 
3538                   ENDDO
3539
3540                ENDIF
3541
3542                IF ( sw_radiation .AND. sun_up )  THEN
3543!
3544!--                Get albedo for direct/diffusive long/shortwave radiation at
3545!--                current (y,x)-location from surface variables.
3546!--                Only obtain it from horizontal surfaces, as RRTMG is a single
3547!--                column model
3548!--                (Please note, only one loop will entered, controlled by
3549!--                start-end index.)
3550                   DO  m = surf_lsm_h%start_index(j,i),                        &
3551                           surf_lsm_h%end_index(j,i)
3552                      rrtm_asdir(1)  = SUM( surf_lsm_h%frac(:,m) *             &
3553                                            surf_lsm_h%rrtm_asdir(:,m) )
3554                      rrtm_asdif(1)  = SUM( surf_lsm_h%frac(:,m) *             &
3555                                            surf_lsm_h%rrtm_asdif(:,m) )
3556                      rrtm_aldir(1)  = SUM( surf_lsm_h%frac(:,m) *             &
3557                                            surf_lsm_h%rrtm_aldir(:,m) )
3558                      rrtm_aldif(1)  = SUM( surf_lsm_h%frac(:,m) *             &
3559                                            surf_lsm_h%rrtm_aldif(:,m) )
3560                   ENDDO             
3561                   DO  m = surf_usm_h%start_index(j,i),                        &
3562                           surf_usm_h%end_index(j,i)
3563                      rrtm_asdir(1)  = SUM( surf_usm_h%frac(:,m) *             &
3564                                            surf_usm_h%rrtm_asdir(:,m) )
3565                      rrtm_asdif(1)  = SUM( surf_usm_h%frac(:,m) *             &
3566                                            surf_usm_h%rrtm_asdif(:,m) )
3567                      rrtm_aldir(1)  = SUM( surf_usm_h%frac(:,m) *             &
3568                                            surf_usm_h%rrtm_aldir(:,m) )
3569                      rrtm_aldif(1)  = SUM( surf_usm_h%frac(:,m) *             &
3570                                            surf_usm_h%rrtm_aldif(:,m) )
3571                   ENDDO
3572!
3573!--                Due to technical reasons, copy optical depths and other
3574!--                to dummy arguments which are allocated on the exact size as the
3575!--                rrtmg_sw is called.
3576!--                As one dimesion is allocated with zero size, compiler complains
3577!--                that rank of the array does not match that of the
3578!--                assumed-shaped arguments in the RRTMG library. In order to
3579!--                avoid this, write to dummy arguments and give pass the entire
3580!--                dummy array. Seems to be the only existing work-around. 
3581                   ALLOCATE( rrtm_sw_taucld_dum(1:nbndsw+1,0:0,k_topo+1:nzt_rad+1) )
3582                   ALLOCATE( rrtm_sw_ssacld_dum(1:nbndsw+1,0:0,k_topo+1:nzt_rad+1) )
3583                   ALLOCATE( rrtm_sw_asmcld_dum(1:nbndsw+1,0:0,k_topo+1:nzt_rad+1) )
3584                   ALLOCATE( rrtm_sw_fsfcld_dum(1:nbndsw+1,0:0,k_topo+1:nzt_rad+1) )
3585                   ALLOCATE( rrtm_sw_tauaer_dum(0:0,k_topo+1:nzt_rad+1,1:nbndsw+1) )
3586                   ALLOCATE( rrtm_sw_ssaaer_dum(0:0,k_topo+1:nzt_rad+1,1:nbndsw+1) )
3587                   ALLOCATE( rrtm_sw_asmaer_dum(0:0,k_topo+1:nzt_rad+1,1:nbndsw+1) )
3588                   ALLOCATE( rrtm_sw_ecaer_dum(0:0,k_topo+1:nzt_rad+1,1:naerec+1)  )
3589     
3590                   rrtm_sw_taucld_dum = rrtm_sw_taucld(1:nbndsw+1,0:0,k_topo+1:nzt_rad+1)
3591                   rrtm_sw_ssacld_dum = rrtm_sw_ssacld(1:nbndsw+1,0:0,k_topo+1:nzt_rad+1)
3592                   rrtm_sw_asmcld_dum = rrtm_sw_asmcld(1:nbndsw+1,0:0,k_topo+1:nzt_rad+1)
3593                   rrtm_sw_fsfcld_dum = rrtm_sw_fsfcld(1:nbndsw+1,0:0,k_topo+1:nzt_rad+1)
3594                   rrtm_sw_tauaer_dum = rrtm_sw_tauaer(0:0,k_topo+1:nzt_rad+1,1:nbndsw+1)
3595                   rrtm_sw_ssaaer_dum = rrtm_sw_ssaaer(0:0,k_topo+1:nzt_rad+1,1:nbndsw+1)
3596                   rrtm_sw_asmaer_dum = rrtm_sw_asmaer(0:0,k_topo+1:nzt_rad+1,1:nbndsw+1)
3597                   rrtm_sw_ecaer_dum  = rrtm_sw_ecaer(0:0,k_topo+1:nzt_rad+1,1:naerec+1)
3598
3599                   CALL rrtmg_sw( 1,                                           &
3600                                  nzt_rad-k_topo,                              &
3601                                  rrtm_icld,                                   &
3602                                  rrtm_iaer,                                   &
3603                                  rrtm_play(:,k_topo+1:nzt_rad+1),             &
3604                                  rrtm_plev(:,k_topo+1:nzt_rad+2),             &
3605                                  rrtm_tlay(:,k_topo+1:nzt_rad+1),             &
3606                                  rrtm_tlev(:,k_topo+1:nzt_rad+2),             &
3607                                  rrtm_tsfc,                                   &
3608                                  rrtm_h2ovmr(:,k_topo+1:nzt_rad+1),           &                               
3609                                  rrtm_o3vmr(:,k_topo+1:nzt_rad+1),            &       
3610                                  rrtm_co2vmr(:,k_topo+1:nzt_rad+1),           &
3611                                  rrtm_ch4vmr(:,k_topo+1:nzt_rad+1),           &
3612                                  rrtm_n2ovmr(:,k_topo+1:nzt_rad+1),           &
3613                                  rrtm_o2vmr(:,k_topo+1:nzt_rad+1),            &
3614                                  rrtm_asdir,                                  & 
3615                                  rrtm_asdif,                                  &
3616                                  rrtm_aldir,                                  &
3617                                  rrtm_aldif,                                  &
3618                                  zenith,                                      &
3619                                  0.0_wp,                                      &
3620                                  day_of_year,                                 &
3621                                  solar_constant,                              &
3622                                  rrtm_inflgsw,                                &
3623                                  rrtm_iceflgsw,                               &
3624                                  rrtm_liqflgsw,                               &
3625                                  rrtm_cldfr(:,k_topo+1:nzt_rad+1),            &
3626                                  rrtm_sw_taucld_dum,                          &
3627                                  rrtm_sw_ssacld_dum,                          &
3628                                  rrtm_sw_asmcld_dum,                          &
3629                                  rrtm_sw_fsfcld_dum,                          &
3630                                  rrtm_cicewp(:,k_topo+1:nzt_rad+1),           &
3631                                  rrtm_cliqwp(:,k_topo+1:nzt_rad+1),           &
3632                                  rrtm_reice(:,k_topo+1:nzt_rad+1),            &
3633                                  rrtm_reliq(:,k_topo+1:nzt_rad+1),            &
3634                                  rrtm_sw_tauaer_dum,                          &
3635                                  rrtm_sw_ssaaer_dum,                          &
3636                                  rrtm_sw_asmaer_dum,                          &
3637                                  rrtm_sw_ecaer_dum,                           &
3638                                  rrtm_swuflx(:,k_topo:nzt_rad+1),             & 
3639                                  rrtm_swdflx(:,k_topo:nzt_rad+1),             & 
3640                                  rrtm_swhr(:,k_topo+1:nzt_rad+1),             & 
3641                                  rrtm_swuflxc(:,k_topo:nzt_rad+1),            & 
3642                                  rrtm_swdflxc(:,k_topo:nzt_rad+1),            &
3643                                  rrtm_swhrc(:,k_topo+1:nzt_rad+1),            &
3644                                  rrtm_dirdflux(:,k_topo:nzt_rad+1),           &
3645                                  rrtm_difdflux(:,k_topo:nzt_rad+1) )
3646
3647                   DEALLOCATE( rrtm_sw_taucld_dum )
3648                   DEALLOCATE( rrtm_sw_ssacld_dum )
3649                   DEALLOCATE( rrtm_sw_asmcld_dum )
3650                   DEALLOCATE( rrtm_sw_fsfcld_dum )
3651                   DEALLOCATE( rrtm_sw_tauaer_dum )
3652                   DEALLOCATE( rrtm_sw_ssaaer_dum )
3653                   DEALLOCATE( rrtm_sw_asmaer_dum )
3654                   DEALLOCATE( rrtm_sw_ecaer_dum )
3655!
3656!--                Save fluxes
3657                   DO k = nzb, nzt+1
3658                      rad_sw_in(k,j,i)  = rrtm_swdflx(0,k)
3659                      rad_sw_out(k,j,i) = rrtm_swuflx(0,k)
3660                   ENDDO
3661!
3662!--                Save heating rates (convert from K/d to K/s)
3663                   DO k = nzb+1, nzt+1
3664                      rad_sw_hr(k,j,i)     = rrtm_swhr(0,k)  * d_hours_day
3665                      rad_sw_cs_hr(k,j,i)  = rrtm_swhrc(0,k) * d_hours_day
3666                   ENDDO
3667
3668!
3669!--                Save surface radiative fluxes onto respective surface elements
3670!--                Horizontal surfaces
3671                   DO  m = surf_lsm_h%start_index(j,i),                        &
3672                           surf_lsm_h%end_index(j,i)
3673                      surf_lsm_h%rad_sw_in(m)     = rrtm_swdflx(0,k_topo)
3674                      surf_lsm_h%rad_sw_out(m)    = rrtm_swuflx(0,k_topo)
3675                   ENDDO             
3676                   DO  m = surf_usm_h%start_index(j,i),                        &
3677                           surf_usm_h%end_index(j,i)
3678                      surf_usm_h%rad_sw_in(m)     = rrtm_swdflx(0,k_topo)
3679                      surf_usm_h%rad_sw_out(m)    = rrtm_swuflx(0,k_topo)
3680                   ENDDO 
3681!
3682!--                Vertical surfaces. Fluxes are obtain at respective vertical
3683!--                level of the surface element
3684                   DO  l = 0, 3
3685                      DO  m = surf_lsm_v(l)%start_index(j,i),                  &
3686                              surf_lsm_v(l)%end_index(j,i)
3687                         k                           = surf_lsm_v(l)%k(m)
3688                         surf_lsm_v(l)%rad_sw_in(m)  = rrtm_swdflx(0,k)
3689                         surf_lsm_v(l)%rad_sw_out(m) = rrtm_swuflx(0,k)
3690                      ENDDO             
3691                      DO  m = surf_usm_v(l)%start_index(j,i),                  &
3692                              surf_usm_v(l)%end_index(j,i)
3693                         k                           = surf_usm_v(l)%k(m)
3694                         surf_usm_v(l)%rad_sw_in(m)  = rrtm_swdflx(0,k)
3695                         surf_usm_v(l)%rad_sw_out(m) = rrtm_swuflx(0,k)
3696                      ENDDO 
3697                   ENDDO
3698!
3699!--             Solar radiation is zero during night
3700                ELSE
3701                   rad_sw_in  = 0.0_wp
3702                   rad_sw_out = 0.0_wp
3703!--             !!!!!!!! ATTENSION !!!!!!!!!!!!!!!
3704!--             Surface radiative fluxes should be also set to zero here                 
3705!--                Save surface radiative fluxes onto respective surface elements
3706!--                Horizontal surfaces
3707                   DO  m = surf_lsm_h%start_index(j,i),                        &
3708                           surf_lsm_h%end_index(j,i)
3709                      surf_lsm_h%rad_sw_in(m)     = 0.0_wp
3710                      surf_lsm_h%rad_sw_out(m)    = 0.0_wp
3711                   ENDDO             
3712                   DO  m = surf_usm_h%start_index(j,i),                        &
3713                           surf_usm_h%end_index(j,i)
3714                      surf_usm_h%rad_sw_in(m)     = 0.0_wp
3715                      surf_usm_h%rad_sw_out(m)    = 0.0_wp
3716                   ENDDO 
3717!
3718!--                Vertical surfaces. Fluxes are obtain at respective vertical
3719!--                level of the surface element
3720                   DO  l = 0, 3
3721                      DO  m = surf_lsm_v(l)%start_index(j,i),                  &
3722                              surf_lsm_v(l)%end_index(j,i)
3723                         k                           = surf_lsm_v(l)%k(m)
3724                         surf_lsm_v(l)%rad_sw_in(m)  = 0.0_wp
3725                         surf_lsm_v(l)%rad_sw_out(m) = 0.0_wp
3726                      ENDDO             
3727                      DO  m = surf_usm_v(l)%start_index(j,i),                  &
3728                              surf_usm_v(l)%end_index(j,i)
3729                         k                           = surf_usm_v(l)%k(m)
3730                         surf_usm_v(l)%rad_sw_in(m)  = 0.0_wp
3731                         surf_usm_v(l)%rad_sw_out(m) = 0.0_wp
3732                      ENDDO 
3733                   ENDDO
3734                ENDIF
3735
3736             ENDDO
3737          ENDDO
3738
3739       ENDIF
3740!
3741!--    Finally, calculate surface net radiation for surface elements.
3742       IF (  .NOT.  radiation_interactions  ) THEN
3743!--       First, for horizontal surfaces   
3744          DO  m = 1, surf_lsm_h%ns
3745             surf_lsm_h%rad_net(m) = surf_lsm_h%rad_sw_in(m)                   &
3746                                   - surf_lsm_h%rad_sw_out(m)                  &
3747                                   + surf_lsm_h%rad_lw_in(m)                   &
3748                                   - surf_lsm_h%rad_lw_out(m)
3749          ENDDO
3750          DO  m = 1, surf_usm_h%ns
3751             surf_usm_h%rad_net(m) = surf_usm_h%rad_sw_in(m)                   &
3752                                   - surf_usm_h%rad_sw_out(m)                  &
3753                                   + surf_usm_h%rad_lw_in(m)                   &
3754                                   - surf_usm_h%rad_lw_out(m)
3755          ENDDO
3756!
3757!--       Vertical surfaces.
3758!--       Todo: weight with azimuth and zenith angle according to their orientation!
3759          DO  l = 0, 3     
3760             DO  m = 1, surf_lsm_v(l)%ns
3761                surf_lsm_v(l)%rad_net(m) = surf_lsm_v(l)%rad_sw_in(m)          &
3762                                         - surf_lsm_v(l)%rad_sw_out(m)         &
3763                                         + surf_lsm_v(l)%rad_lw_in(m)          &
3764                                         - surf_lsm_v(l)%rad_lw_out(m)
3765             ENDDO
3766             DO  m = 1, surf_usm_v(l)%ns
3767                surf_usm_v(l)%rad_net(m) = surf_usm_v(l)%rad_sw_in(m)          &
3768                                         - surf_usm_v(l)%rad_sw_out(m)         &
3769                                         + surf_usm_v(l)%rad_lw_in(m)          &
3770                                         - surf_usm_v(l)%rad_lw_out(m)
3771             ENDDO
3772          ENDDO
3773       ENDIF
3774
3775
3776       CALL exchange_horiz( rad_lw_in,  nbgp )
3777       CALL exchange_horiz( rad_lw_out, nbgp )
3778       CALL exchange_horiz( rad_lw_hr,    nbgp )
3779       CALL exchange_horiz( rad_lw_cs_hr, nbgp )
3780
3781       CALL exchange_horiz( rad_sw_in,  nbgp )
3782       CALL exchange_horiz( rad_sw_out, nbgp ) 
3783       CALL exchange_horiz( rad_sw_hr,    nbgp )
3784       CALL exchange_horiz( rad_sw_cs_hr, nbgp )
3785
3786#endif
3787
3788    END SUBROUTINE radiation_rrtmg
3789
3790
3791!------------------------------------------------------------------------------!
3792! Description:
3793! ------------
3794!> Calculate the cosine of the zenith angle (variable is called zenith)
3795!------------------------------------------------------------------------------!
3796    SUBROUTINE calc_zenith
3797
3798       IMPLICIT NONE
3799
3800       REAL(wp) ::  declination,  & !< solar declination angle
3801                    hour_angle      !< solar hour angle
3802!
3803!--    Calculate current day and time based on the initial values and simulation
3804!--    time
3805       CALL calc_date_and_time
3806
3807!
3808!--    Calculate solar declination and hour angle   
3809       declination = ASIN( decl_1 * SIN(decl_2 * REAL(day_of_year, KIND=wp) - decl_3) )
3810       hour_angle  = 2.0_wp * pi * (time_utc / 86400.0_wp) + lon - pi
3811
3812!
3813!--    Calculate cosine of solar zenith angle
3814       zenith(0) = SIN(lat) * SIN(declination) + COS(lat) * COS(declination)   &
3815                                            * COS(hour_angle)
3816       zenith(0) = MAX(0.0_wp,zenith(0))
3817
3818!
3819!--    Calculate solar directional vector
3820       IF ( sun_direction )  THEN
3821
3822!
3823!--       Direction in longitudes equals to sin(solar_azimuth) * sin(zenith)
3824          sun_dir_lon(0) = -SIN(hour_angle) * COS(declination)
3825
3826!
3827!--       Direction in latitues equals to cos(solar_azimuth) * sin(zenith)
3828          sun_dir_lat(0) = SIN(declination) * COS(lat) - COS(hour_angle) &
3829                              * COS(declination) * SIN(lat)
3830       ENDIF
3831
3832!
3833!--    Check if the sun is up (otheriwse shortwave calculations can be skipped)
3834       IF ( zenith(0) > 0.0_wp )  THEN
3835          sun_up = .TRUE.
3836       ELSE
3837          sun_up = .FALSE.
3838       END IF
3839
3840    END SUBROUTINE calc_zenith
3841
3842#if defined ( __rrtmg ) && defined ( __netcdf )
3843!------------------------------------------------------------------------------!
3844! Description:
3845! ------------
3846!> Calculates surface albedo components based on Briegleb (1992) and
3847!> Briegleb et al. (1986)
3848!------------------------------------------------------------------------------!
3849    SUBROUTINE calc_albedo( surf )
3850
3851        IMPLICIT NONE
3852
3853        INTEGER(iwp)    ::  ind_type !< running index surface tiles
3854        INTEGER(iwp)    ::  m        !< running index surface elements
3855
3856        TYPE(surf_type) ::  surf !< treated surfaces
3857
3858        IF ( sun_up  .AND.  .NOT. average_radiation )  THEN
3859
3860           DO  m = 1, surf%ns
3861!
3862!--           Loop over surface elements
3863              DO  ind_type = 0, SIZE( surf%albedo_type, 1 ) - 1
3864           
3865!
3866!--              Ocean
3867                 IF ( surf%albedo_type(ind_type,m) == 1 )  THEN
3868                    surf%rrtm_aldir(ind_type,m) = 0.026_wp /                    &
3869                                                ( zenith(0)**1.7_wp + 0.065_wp )&
3870                                     + 0.15_wp * ( zenith(0) - 0.1_wp )         &
3871                                               * ( zenith(0) - 0.5_wp )         &
3872                                               * ( zenith(0) - 1.0_wp )
3873                    surf%rrtm_asdir(ind_type,m) = surf%rrtm_aldir(ind_type,m)
3874!
3875!--              Snow
3876                 ELSEIF ( surf%albedo_type(ind_type,m) == 16 )  THEN
3877                    IF ( zenith(0) < 0.5_wp )  THEN
3878                       surf%rrtm_aldir(ind_type,m) =                           &
3879                                 0.5_wp * ( 1.0_wp - surf%aldif(ind_type,m) )  &
3880                                        * ( 3.0_wp / ( 1.0_wp + 4.0_wp         &
3881                                        * zenith(0) ) ) - 1.0_wp
3882                       surf%rrtm_asdir(ind_type,m) =                           &
3883                                 0.5_wp * ( 1.0_wp - surf%asdif(ind_type,m) )  &
3884                                        * ( 3.0_wp / ( 1.0_wp + 4.0_wp         &
3885                                        * zenith(0) ) ) - 1.0_wp
3886
3887                       surf%rrtm_aldir(ind_type,m) =                           &
3888                                       MIN(0.98_wp, surf%rrtm_aldir(ind_type,m))
3889                       surf%rrtm_asdir(ind_type,m) =                           &
3890                                       MIN(0.98_wp, surf%rrtm_asdir(ind_type,m))
3891                    ELSE
3892                       surf%rrtm_aldir(ind_type,m) = surf%aldif(ind_type,m)
3893                       surf%rrtm_asdir(ind_type,m) = surf%asdif(ind_type,m)
3894                    ENDIF
3895!
3896!--              Sea ice
3897                 ELSEIF ( surf%albedo_type(ind_type,m) == 15 )  THEN
3898                    surf%rrtm_aldir(ind_type,m) = surf%aldif(ind_type,m)
3899                    surf%rrtm_asdir(ind_type,m) = surf%asdif(ind_type,m)
3900
3901!
3902!--              Asphalt
3903                 ELSEIF ( surf%albedo_type(ind_type,m) == 17 )  THEN
3904                    surf%rrtm_aldir(ind_type,m) = surf%aldif(ind_type,m)
3905                    surf%rrtm_asdir(ind_type,m) = surf%asdif(ind_type,m)
3906
3907
3908!
3909!--              Bare soil
3910                 ELSEIF ( surf%albedo_type(ind_type,m) == 18 )  THEN
3911                    surf%rrtm_aldir(ind_type,m) = surf%aldif(ind_type,m)
3912                    surf%rrtm_asdir(ind_type,m) = surf%asdif(ind_type,m)
3913
3914!
3915!--              Land surfaces
3916                 ELSE
3917                    SELECT CASE ( surf%albedo_type(ind_type,m) )
3918
3919!
3920!--                    Surface types with strong zenith dependence
3921                       CASE ( 1, 2, 3, 4, 11, 12, 13 )
3922                          surf%rrtm_aldir(ind_type,m) =                        &
3923                                surf%aldif(ind_type,m) * 1.4_wp /              &
3924                                           ( 1.0_wp + 0.8_wp * zenith(0) )
3925                          surf%rrtm_asdir(ind_type,m) =                        &
3926                                surf%asdif(ind_type,m) * 1.4_wp /              &
3927                                           ( 1.0_wp + 0.8_wp * zenith(0) )
3928!
3929!--                    Surface types with weak zenith dependence
3930                       CASE ( 5, 6, 7, 8, 9, 10, 14 )
3931                          surf%rrtm_aldir(ind_type,m) =                        &
3932                                surf%aldif(ind_type,m) * 1.1_wp /              &
3933                                           ( 1.0_wp + 0.2_wp * zenith(0) )
3934                          surf%rrtm_asdir(ind_type,m) =                        &
3935                                surf%asdif(ind_type,m) * 1.1_wp /              &
3936                                           ( 1.0_wp + 0.2_wp * zenith(0) )
3937
3938                       CASE DEFAULT
3939
3940                    END SELECT
3941                 ENDIF
3942!
3943!--              Diffusive albedo is taken from Table 2
3944                 surf%rrtm_aldif(ind_type,m) = surf%aldif(ind_type,m)
3945                 surf%rrtm_asdif(ind_type,m) = surf%asdif(ind_type,m)
3946              ENDDO
3947           ENDDO
3948!
3949!--     Set albedo in case of average radiation
3950        ELSEIF ( sun_up  .AND.  average_radiation )  THEN
3951           surf%rrtm_asdir = albedo_urb
3952           surf%rrtm_asdif = albedo_urb
3953           surf%rrtm_aldir = albedo_urb
3954           surf%rrtm_aldif = albedo_urb 
3955!
3956!--     Darkness
3957        ELSE
3958           surf%rrtm_aldir = 0.0_wp
3959           surf%rrtm_asdir = 0.0_wp
3960           surf%rrtm_aldif = 0.0_wp
3961           surf%rrtm_asdif = 0.0_wp
3962        ENDIF
3963
3964    END SUBROUTINE calc_albedo
3965
3966!------------------------------------------------------------------------------!
3967! Description:
3968! ------------
3969!> Read sounding data (pressure and temperature) from RADIATION_DATA.
3970!------------------------------------------------------------------------------!
3971    SUBROUTINE read_sounding_data
3972
3973       IMPLICIT NONE
3974
3975       INTEGER(iwp) :: id,           & !< NetCDF id of input file
3976                       id_dim_zrad,  & !< pressure level id in the NetCDF file
3977                       id_var,       & !< NetCDF variable id
3978                       k,            & !< loop index
3979                       nz_snd,       & !< number of vertical levels in the sounding data
3980                       nz_snd_start, & !< start vertical index for sounding data to be used
3981                       nz_snd_end      !< end vertical index for souding data to be used
3982
3983       REAL(wp) :: t_surface           !< actual surface temperature
3984
3985       REAL(wp), DIMENSION(:), ALLOCATABLE ::  hyp_snd_tmp, & !< temporary hydrostatic pressure profile (sounding)
3986                                               t_snd_tmp      !< temporary temperature profile (sounding)
3987
3988!
3989!--    In case of updates, deallocate arrays first (sufficient to check one
3990!--    array as the others are automatically allocated). This is required
3991!--    because nzt_rad might change during the update
3992       IF ( ALLOCATED ( hyp_snd ) )  THEN
3993          DEALLOCATE( hyp_snd )
3994          DEALLOCATE( t_snd )
3995          DEALLOCATE ( rrtm_play )
3996          DEALLOCATE ( rrtm_plev )
3997          DEALLOCATE ( rrtm_tlay )
3998          DEALLOCATE ( rrtm_tlev )
3999
4000          DEALLOCATE ( rrtm_cicewp )
4001          DEALLOCATE ( rrtm_cldfr )
4002          DEALLOCATE ( rrtm_cliqwp )
4003          DEALLOCATE ( rrtm_reice )
4004          DEALLOCATE ( rrtm_reliq )
4005          DEALLOCATE ( rrtm_lw_taucld )
4006          DEALLOCATE ( rrtm_lw_tauaer )
4007
4008          DEALLOCATE ( rrtm_lwdflx  )
4009          DEALLOCATE ( rrtm_lwdflxc )
4010          DEALLOCATE ( rrtm_lwuflx  )
4011          DEALLOCATE ( rrtm_lwuflxc )
4012          DEALLOCATE ( rrtm_lwuflx_dt )
4013          DEALLOCATE ( rrtm_lwuflxc_dt )
4014          DEALLOCATE ( rrtm_lwhr  )
4015          DEALLOCATE ( rrtm_lwhrc )
4016
4017          DEALLOCATE ( rrtm_sw_taucld )
4018          DEALLOCATE ( rrtm_sw_ssacld )
4019          DEALLOCATE ( rrtm_sw_asmcld )
4020          DEALLOCATE ( rrtm_sw_fsfcld )
4021          DEALLOCATE ( rrtm_sw_tauaer )
4022          DEALLOCATE ( rrtm_sw_ssaaer )
4023          DEALLOCATE ( rrtm_sw_asmaer ) 
4024          DEALLOCATE ( rrtm_sw_ecaer )   
4025 
4026          DEALLOCATE ( rrtm_swdflx  )
4027          DEALLOCATE ( rrtm_swdflxc )
4028          DEALLOCATE ( rrtm_swuflx  )
4029          DEALLOCATE ( rrtm_swuflxc )
4030          DEALLOCATE ( rrtm_swhr  )
4031          DEALLOCATE ( rrtm_swhrc )
4032          DEALLOCATE ( rrtm_dirdflux )
4033          DEALLOCATE ( rrtm_difdflux )
4034
4035       ENDIF
4036
4037!
4038!--    Open file for reading
4039       nc_stat = NF90_OPEN( rrtm_input_file, NF90_NOWRITE, id )
4040       CALL netcdf_handle_error_rad( 'read_sounding_data', 549 )
4041
4042!
4043!--    Inquire dimension of z axis and save in nz_snd
4044       nc_stat = NF90_INQ_DIMID( id, "Pressure", id_dim_zrad )
4045       nc_stat = NF90_INQUIRE_DIMENSION( id, id_dim_zrad, len = nz_snd )
4046       CALL netcdf_handle_error_rad( 'read_sounding_data', 551 )
4047
4048!
4049! !--    Allocate temporary array for storing pressure data
4050       ALLOCATE( hyp_snd_tmp(1:nz_snd) )
4051       hyp_snd_tmp = 0.0_wp
4052
4053
4054!--    Read pressure from file
4055       nc_stat = NF90_INQ_VARID( id, "Pressure", id_var )
4056       nc_stat = NF90_GET_VAR( id, id_var, hyp_snd_tmp(:), start = (/1/),      &
4057                               count = (/nz_snd/) )
4058       CALL netcdf_handle_error_rad( 'read_sounding_data', 552 )
4059
4060!
4061!--    Allocate temporary array for storing temperature data
4062       ALLOCATE( t_snd_tmp(1:nz_snd) )
4063       t_snd_tmp = 0.0_wp
4064
4065!
4066!--    Read temperature from file
4067       nc_stat = NF90_INQ_VARID( id, "ReferenceTemperature", id_var )
4068       nc_stat = NF90_GET_VAR( id, id_var, t_snd_tmp(:), start = (/1/),        &
4069                               count = (/nz_snd/) )
4070       CALL netcdf_handle_error_rad( 'read_sounding_data', 553 )
4071
4072!
4073!--    Calculate start of sounding data
4074       nz_snd_start = nz_snd + 1
4075       nz_snd_end   = nz_snd + 1
4076
4077!
4078!--    Start filling vertical dimension at 10hPa above the model domain (hyp is
4079!--    in Pa, hyp_snd in hPa).
4080       DO  k = 1, nz_snd
4081          IF ( hyp_snd_tmp(k) < ( hyp(nzt+1) - 1000.0_wp) * 0.01_wp )  THEN
4082             nz_snd_start = k
4083             EXIT
4084          END IF
4085       END DO
4086
4087       IF ( nz_snd_start <= nz_snd )  THEN
4088          nz_snd_end = nz_snd
4089       END IF
4090
4091
4092!
4093!--    Calculate of total grid points for RRTMG calculations
4094       nzt_rad = nzt + nz_snd_end - nz_snd_start + 1
4095
4096!
4097!--    Save data above LES domain in hyp_snd, t_snd
4098       ALLOCATE( hyp_snd(nzb+1:nzt_rad) )
4099       ALLOCATE( t_snd(nzb+1:nzt_rad)   )
4100       hyp_snd = 0.0_wp
4101       t_snd = 0.0_wp
4102
4103       hyp_snd(nzt+2:nzt_rad) = hyp_snd_tmp(nz_snd_start+1:nz_snd_end)
4104       t_snd(nzt+2:nzt_rad)   = t_snd_tmp(nz_snd_start+1:nz_snd_end)
4105
4106       nc_stat = NF90_CLOSE( id )
4107
4108!
4109!--    Calculate pressure levels on zu and zw grid. Sounding data is added at
4110!--    top of the LES domain. This routine does not consider horizontal or
4111!--    vertical variability of pressure and temperature
4112       ALLOCATE ( rrtm_play(0:0,nzb+1:nzt_rad+1)   )
4113       ALLOCATE ( rrtm_plev(0:0,nzb+1:nzt_rad+2)   )
4114
4115       t_surface = pt_surface * exner(nzb)
4116       DO k = nzb+1, nzt+1
4117          rrtm_play(0,k) = hyp(k) * 0.01_wp
4118          rrtm_plev(0,k) = barometric_formula(zw(k-1),                         &
4119                              pt_surface * exner(nzb), &
4120                              surface_pressure )
4121       ENDDO
4122
4123       DO k = nzt+2, nzt_rad
4124          rrtm_play(0,k) = hyp_snd(k)
4125          rrtm_plev(0,k) = 0.5_wp * ( rrtm_play(0,k) + rrtm_play(0,k-1) )
4126       ENDDO
4127       rrtm_plev(0,nzt_rad+1) = MAX( 0.5 * hyp_snd(nzt_rad),                   &
4128                                   1.5 * hyp_snd(nzt_rad)                      &
4129                                 - 0.5 * hyp_snd(nzt_rad-1) )
4130       rrtm_plev(0,nzt_rad+2)  = MIN( 1.0E-4_wp,                               &
4131                                      0.25_wp * rrtm_plev(0,nzt_rad+1) )
4132
4133       rrtm_play(0,nzt_rad+1) = 0.5 * rrtm_plev(0,nzt_rad+1)
4134
4135!
4136!--    Calculate temperature/humidity levels at top of the LES domain.
4137!--    Currently, the temperature is taken from sounding data (might lead to a
4138!--    temperature jump at interface. To do: Humidity is currently not
4139!--    calculated above the LES domain.
4140       ALLOCATE ( rrtm_tlay(0:0,nzb+1:nzt_rad+1)   )
4141       ALLOCATE ( rrtm_tlev(0:0,nzb+1:nzt_rad+2)   )
4142
4143       DO k = nzt+8, nzt_rad
4144          rrtm_tlay(0,k)   = t_snd(k)
4145       ENDDO
4146       rrtm_tlay(0,nzt_rad+1) = 2.0_wp * rrtm_tlay(0,nzt_rad)                  &
4147                                - rrtm_tlay(0,nzt_rad-1)
4148       DO k = nzt+9, nzt_rad+1
4149          rrtm_tlev(0,k)   = rrtm_tlay(0,k-1) + (rrtm_tlay(0,k)                &
4150                             - rrtm_tlay(0,k-1))                               &
4151                             / ( rrtm_play(0,k) - rrtm_play(0,k-1) )           &
4152                             * ( rrtm_plev(0,k) - rrtm_play(0,k-1) )
4153       ENDDO
4154
4155       rrtm_tlev(0,nzt_rad+2)   = 2.0_wp * rrtm_tlay(0,nzt_rad+1)              &
4156                                  - rrtm_tlev(0,nzt_rad)
4157!
4158!--    Allocate remaining RRTMG arrays
4159       ALLOCATE ( rrtm_cicewp(0:0,nzb+1:nzt_rad+1) )
4160       ALLOCATE ( rrtm_cldfr(0:0,nzb+1:nzt_rad+1) )
4161       ALLOCATE ( rrtm_cliqwp(0:0,nzb+1:nzt_rad+1) )
4162       ALLOCATE ( rrtm_reice(0:0,nzb+1:nzt_rad+1) )
4163       ALLOCATE ( rrtm_reliq(0:0,nzb+1:nzt_rad+1) )
4164       ALLOCATE ( rrtm_lw_taucld(1:nbndlw+1,0:0,nzb+1:nzt_rad+1) )
4165       ALLOCATE ( rrtm_lw_tauaer(0:0,nzb+1:nzt_rad+1,1:nbndlw+1) )
4166       ALLOCATE ( rrtm_sw_taucld(1:nbndsw+1,0:0,nzb+1:nzt_rad+1) )
4167       ALLOCATE ( rrtm_sw_ssacld(1:nbndsw+1,0:0,nzb+1:nzt_rad+1) )
4168       ALLOCATE ( rrtm_sw_asmcld(1:nbndsw+1,0:0,nzb+1:nzt_rad+1) )
4169       ALLOCATE ( rrtm_sw_fsfcld(1:nbndsw+1,0:0,nzb+1:nzt_rad+1) )
4170       ALLOCATE ( rrtm_sw_tauaer(0:0,nzb+1:nzt_rad+1,1:nbndsw+1) )
4171       ALLOCATE ( rrtm_sw_ssaaer(0:0,nzb+1:nzt_rad+1,1:nbndsw+1) )
4172       ALLOCATE ( rrtm_sw_asmaer(0:0,nzb+1:nzt_rad+1,1:nbndsw+1) ) 
4173       ALLOCATE ( rrtm_sw_ecaer(0:0,nzb+1:nzt_rad+1,1:naerec+1) )   
4174
4175!
4176!--    The ice phase is currently not considered in PALM
4177       rrtm_cicewp = 0.0_wp
4178       rrtm_reice  = 0.0_wp
4179
4180!
4181!--    Set other parameters (move to NAMELIST parameters in the future)
4182       rrtm_lw_tauaer = 0.0_wp
4183       rrtm_lw_taucld = 0.0_wp
4184       rrtm_sw_taucld = 0.0_wp
4185       rrtm_sw_ssacld = 0.0_wp
4186       rrtm_sw_asmcld = 0.0_wp
4187       rrtm_sw_fsfcld = 0.0_wp
4188       rrtm_sw_tauaer = 0.0_wp
4189       rrtm_sw_ssaaer = 0.0_wp
4190       rrtm_sw_asmaer = 0.0_wp
4191       rrtm_sw_ecaer  = 0.0_wp
4192
4193
4194       ALLOCATE ( rrtm_swdflx(0:0,nzb:nzt_rad+1)  )
4195       ALLOCATE ( rrtm_swuflx(0:0,nzb:nzt_rad+1)  )
4196       ALLOCATE ( rrtm_swhr(0:0,nzb+1:nzt_rad+1)  )
4197       ALLOCATE ( rrtm_swuflxc(0:0,nzb:nzt_rad+1) )
4198       ALLOCATE ( rrtm_swdflxc(0:0,nzb:nzt_rad+1) )
4199       ALLOCATE ( rrtm_swhrc(0:0,nzb+1:nzt_rad+1) )
4200       ALLOCATE ( rrtm_dirdflux(0:0,nzb:nzt_rad+1) )
4201       ALLOCATE ( rrtm_difdflux(0:0,nzb:nzt_rad+1) )
4202
4203       rrtm_swdflx  = 0.0_wp
4204       rrtm_swuflx  = 0.0_wp
4205       rrtm_swhr    = 0.0_wp 
4206       rrtm_swuflxc = 0.0_wp
4207       rrtm_swdflxc = 0.0_wp
4208       rrtm_swhrc   = 0.0_wp
4209       rrtm_dirdflux = 0.0_wp
4210       rrtm_difdflux = 0.0_wp
4211
4212       ALLOCATE ( rrtm_lwdflx(0:0,nzb:nzt_rad+1)  )
4213       ALLOCATE ( rrtm_lwuflx(0:0,nzb:nzt_rad+1)  )
4214       ALLOCATE ( rrtm_lwhr(0:0,nzb+1:nzt_rad+1)  )
4215       ALLOCATE ( rrtm_lwuflxc(0:0,nzb:nzt_rad+1) )
4216       ALLOCATE ( rrtm_lwdflxc(0:0,nzb:nzt_rad+1) )
4217       ALLOCATE ( rrtm_lwhrc(0:0,nzb+1:nzt_rad+1) )
4218
4219       rrtm_lwdflx  = 0.0_wp
4220       rrtm_lwuflx  = 0.0_wp
4221       rrtm_lwhr    = 0.0_wp 
4222       rrtm_lwuflxc = 0.0_wp
4223       rrtm_lwdflxc = 0.0_wp
4224       rrtm_lwhrc   = 0.0_wp
4225
4226       ALLOCATE ( rrtm_lwuflx_dt(0:0,nzb:nzt_rad+1) )
4227       ALLOCATE ( rrtm_lwuflxc_dt(0:0,nzb:nzt_rad+1) )
4228
4229       rrtm_lwuflx_dt = 0.0_wp
4230       rrtm_lwuflxc_dt = 0.0_wp
4231
4232    END SUBROUTINE read_sounding_data
4233
4234
4235!------------------------------------------------------------------------------!
4236! Description:
4237! ------------
4238!> Read trace gas data from file
4239!------------------------------------------------------------------------------!
4240    SUBROUTINE read_trace_gas_data
4241
4242       USE rrsw_ncpar
4243
4244       IMPLICIT NONE
4245
4246       INTEGER(iwp), PARAMETER :: num_trace_gases = 10 !< number of trace gases (absorbers)
4247
4248       CHARACTER(LEN=5), DIMENSION(num_trace_gases), PARAMETER ::              & !< trace gas names
4249           trace_names = (/'O3   ', 'CO2  ', 'CH4  ', 'N2O  ', 'O2   ',        &
4250                           'CFC11', 'CFC12', 'CFC22', 'CCL4 ', 'H2O  '/)
4251
4252       INTEGER(iwp) :: id,     & !< NetCDF id
4253                       k,      & !< loop index
4254                       m,      & !< loop index
4255                       n,      & !< loop index
4256                       nabs,   & !< number of absorbers
4257                       np,     & !< number of pressure levels
4258                       id_abs, & !< NetCDF id of the respective absorber
4259                       id_dim, & !< NetCDF id of asborber's dimension
4260                       id_var    !< NetCDf id ot the absorber
4261
4262       REAL(wp) :: p_mls_l, p_mls_u, p_wgt_l, p_wgt_u, p_mls_m
4263
4264
4265       REAL(wp), DIMENSION(:), ALLOCATABLE   ::  p_mls,          & !< pressure levels for the absorbers
4266                                                 rrtm_play_tmp,  & !< temporary array for pressure zu-levels
4267                                                 rrtm_plev_tmp,  & !< temporary array for pressure zw-levels
4268                                                 trace_path_tmp    !< temporary array for storing trace gas path data
4269
4270       REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  trace_mls,      & !< array for storing the absorber amounts
4271                                                 trace_mls_path, & !< array for storing trace gas path data
4272                                                 trace_mls_tmp     !< temporary array for storing trace gas data
4273
4274
4275!
4276!--    In case of updates, deallocate arrays first (sufficient to check one
4277!--    array as the others are automatically allocated)
4278       IF ( ALLOCATED ( rrtm_o3vmr ) )  THEN
4279          DEALLOCATE ( rrtm_o3vmr  )
4280          DEALLOCATE ( rrtm_co2vmr )
4281          DEALLOCATE ( rrtm_ch4vmr )
4282          DEALLOCATE ( rrtm_n2ovmr )
4283          DEALLOCATE ( rrtm_o2vmr  )
4284          DEALLOCATE ( rrtm_cfc11vmr )
4285          DEALLOCATE ( rrtm_cfc12vmr )
4286          DEALLOCATE ( rrtm_cfc22vmr )
4287          DEALLOCATE ( rrtm_ccl4vmr  )
4288          DEALLOCATE ( rrtm_h2ovmr  )     
4289       ENDIF
4290
4291!
4292!--    Allocate trace gas profiles
4293       ALLOCATE ( rrtm_o3vmr(0:0,1:nzt_rad+1)  )
4294       ALLOCATE ( rrtm_co2vmr(0:0,1:nzt_rad+1) )
4295       ALLOCATE ( rrtm_ch4vmr(0:0,1:nzt_rad+1) )
4296       ALLOCATE ( rrtm_n2ovmr(0:0,1:nzt_rad+1) )
4297       ALLOCATE ( rrtm_o2vmr(0:0,1:nzt_rad+1)  )
4298       ALLOCATE ( rrtm_cfc11vmr(0:0,1:nzt_rad+1) )
4299       ALLOCATE ( rrtm_cfc12vmr(0:0,1:nzt_rad+1) )
4300       ALLOCATE ( rrtm_cfc22vmr(0:0,1:nzt_rad+1) )
4301       ALLOCATE ( rrtm_ccl4vmr(0:0,1:nzt_rad+1)  )
4302       ALLOCATE ( rrtm_h2ovmr(0:0,1:nzt_rad+1)  )
4303
4304!
4305!--    Open file for reading
4306       nc_stat = NF90_OPEN( rrtm_input_file, NF90_NOWRITE, id )
4307       CALL netcdf_handle_error_rad( 'read_trace_gas_data', 549 )
4308!
4309!--    Inquire dimension ids and dimensions
4310       nc_stat = NF90_INQ_DIMID( id, "Pressure", id_dim )
4311       CALL netcdf_handle_error_rad( 'read_trace_gas_data', 550 )
4312       nc_stat = NF90_INQUIRE_DIMENSION( id, id_dim, len = np) 
4313       CALL netcdf_handle_error_rad( 'read_trace_gas_data', 550 )
4314
4315       nc_stat = NF90_INQ_DIMID( id, "Absorber", id_dim )
4316       CALL netcdf_handle_error_rad( 'read_trace_gas_data', 550 )
4317       nc_stat = NF90_INQUIRE_DIMENSION( id, id_dim, len = nabs ) 
4318       CALL netcdf_handle_error_rad( 'read_trace_gas_data', 550 )
4319   
4320
4321!
4322!--    Allocate pressure, and trace gas arrays     
4323       ALLOCATE( p_mls(1:np) )
4324       ALLOCATE( trace_mls(1:num_trace_gases,1:np) ) 
4325       ALLOCATE( trace_mls_tmp(1:nabs,1:np) ) 
4326
4327
4328       nc_stat = NF90_INQ_VARID( id, "Pressure", id_var )
4329       CALL netcdf_handle_error_rad( 'read_trace_gas_data', 550 )
4330       nc_stat = NF90_GET_VAR( id, id_var, p_mls )
4331       CALL netcdf_handle_error_rad( 'read_trace_gas_data', 550 )
4332
4333       nc_stat = NF90_INQ_VARID( id, "AbsorberAmountMLS", id_var )
4334       CALL netcdf_handle_error_rad( 'read_trace_gas_data', 550 )
4335       nc_stat = NF90_GET_VAR( id, id_var, trace_mls_tmp )
4336       CALL netcdf_handle_error_rad( 'read_trace_gas_data', 550 )
4337
4338
4339!
4340!--    Write absorber amounts (mls) to trace_mls
4341       DO n = 1, num_trace_gases
4342          CALL getAbsorberIndex( TRIM( trace_names(n) ), id_abs )
4343
4344          trace_mls(n,1:np) = trace_mls_tmp(id_abs,1:np)
4345
4346!
4347!--       Replace missing values by zero
4348          WHERE ( trace_mls(n,:) > 2.0_wp ) 
4349             trace_mls(n,:) = 0.0_wp
4350          END WHERE
4351       END DO
4352
4353       DEALLOCATE ( trace_mls_tmp )
4354
4355       nc_stat = NF90_CLOSE( id )
4356       CALL netcdf_handle_error_rad( 'read_trace_gas_data', 551 )
4357
4358!
4359!--    Add extra pressure level for calculations of the trace gas paths
4360       ALLOCATE ( rrtm_play_tmp(1:nzt_rad+1) )
4361       ALLOCATE ( rrtm_plev_tmp(1:nzt_rad+2) )
4362
4363       rrtm_play_tmp(1:nzt_rad)   = rrtm_play(0,1:nzt_rad) 
4364       rrtm_plev_tmp(1:nzt_rad+1) = rrtm_plev(0,1:nzt_rad+1)
4365       rrtm_play_tmp(nzt_rad+1)   = rrtm_plev(0,nzt_rad+1) * 0.5_wp
4366       rrtm_plev_tmp(nzt_rad+2)   = MIN( 1.0E-4_wp, 0.25_wp                    &
4367                                         * rrtm_plev(0,nzt_rad+1) )
4368 
4369!
4370!--    Calculate trace gas path (zero at surface) with interpolation to the
4371!--    sounding levels
4372       ALLOCATE ( trace_mls_path(1:nzt_rad+2,1:num_trace_gases) )
4373
4374       trace_mls_path(nzb+1,:) = 0.0_wp
4375       
4376       DO k = nzb+2, nzt_rad+2
4377          DO m = 1, num_trace_gases
4378             trace_mls_path(k,m) = trace_mls_path(k-1,m)
4379
4380!
4381!--          When the pressure level is higher than the trace gas pressure
4382!--          level, assume that
4383             IF ( rrtm_plev_tmp(k-1) > p_mls(1) )  THEN             
4384               
4385                trace_mls_path(k,m) = trace_mls_path(k,m) + trace_mls(m,1)     &
4386                                      * ( rrtm_plev_tmp(k-1)                   &
4387                                          - MAX( p_mls(1), rrtm_plev_tmp(k) )  &
4388                                        ) / g
4389             ENDIF
4390
4391!
4392!--          Integrate for each sounding level from the contributing p_mls
4393!--          levels
4394             DO n = 2, np
4395!
4396!--             Limit p_mls so that it is within the model level
4397                p_mls_u = MIN( rrtm_plev_tmp(k-1),                             &
4398                          MAX( rrtm_plev_tmp(k), p_mls(n) ) )
4399                p_mls_l = MIN( rrtm_plev_tmp(k-1),                             &
4400                          MAX( rrtm_plev_tmp(k), p_mls(n-1) ) )
4401
4402                IF ( p_mls_l > p_mls_u )  THEN
4403
4404!
4405!--                Calculate weights for interpolation
4406                   p_mls_m = 0.5_wp * (p_mls_l + p_mls_u)
4407                   p_wgt_u = (p_mls(n-1) - p_mls_m) / (p_mls(n-1) - p_mls(n))
4408                   p_wgt_l = (p_mls_m - p_mls(n))   / (p_mls(n-1) - p_mls(n))
4409
4410!
4411!--                Add level to trace gas path
4412                   trace_mls_path(k,m) = trace_mls_path(k,m)                   &
4413                                         +  ( p_wgt_u * trace_mls(m,n)         &
4414                                            + p_wgt_l * trace_mls(m,n-1) )     &
4415                                         * (p_mls_l - p_mls_u) / g
4416                ENDIF
4417             ENDDO
4418
4419             IF ( rrtm_plev_tmp(k) < p_mls(np) )  THEN
4420                trace_mls_path(k,m) = trace_mls_path(k,m) + trace_mls(m,np)    &
4421                                      * ( MIN( rrtm_plev_tmp(k-1), p_mls(np) ) &
4422                                          - rrtm_plev_tmp(k)                   &
4423                                        ) / g 
4424             ENDIF 
4425          ENDDO
4426       ENDDO
4427
4428
4429!
4430!--    Prepare trace gas path profiles
4431       ALLOCATE ( trace_path_tmp(1:nzt_rad+1) )
4432
4433       DO m = 1, num_trace_gases
4434
4435          trace_path_tmp(1:nzt_rad+1) = ( trace_mls_path(2:nzt_rad+2,m)        &
4436                                       - trace_mls_path(1:nzt_rad+1,m) ) * g   &
4437                                       / ( rrtm_plev_tmp(1:nzt_rad+1)          &
4438                                       - rrtm_plev_tmp(2:nzt_rad+2) )
4439
4440!
4441!--       Save trace gas paths to the respective arrays
4442          SELECT CASE ( TRIM( trace_names(m) ) )
4443
4444             CASE ( 'O3' )
4445
4446                rrtm_o3vmr(0,:) = trace_path_tmp(:)
4447
4448             CASE ( 'CO2' )
4449
4450                rrtm_co2vmr(0,:) = trace_path_tmp(:)
4451
4452             CASE ( 'CH4' )
4453
4454                rrtm_ch4vmr(0,:) = trace_path_tmp(:)
4455
4456             CASE ( 'N2O' )
4457
4458                rrtm_n2ovmr(0,:) = trace_path_tmp(:)
4459
4460             CASE ( 'O2' )
4461
4462                rrtm_o2vmr(0,:) = trace_path_tmp(:)
4463
4464             CASE ( 'CFC11' )
4465
4466                rrtm_cfc11vmr(0,:) = trace_path_tmp(:)
4467
4468             CASE ( 'CFC12' )
4469
4470                rrtm_cfc12vmr(0,:) = trace_path_tmp(:)
4471
4472             CASE ( 'CFC22' )
4473
4474                rrtm_cfc22vmr(0,:) = trace_path_tmp(:)
4475
4476             CASE ( 'CCL4' )
4477
4478                rrtm_ccl4vmr(0,:) = trace_path_tmp(:)
4479
4480             CASE ( 'H2O' )
4481
4482                rrtm_h2ovmr(0,:) = trace_path_tmp(:)
4483               
4484             CASE DEFAULT
4485
4486          END SELECT
4487
4488       ENDDO
4489
4490       DEALLOCATE ( trace_path_tmp )
4491       DEALLOCATE ( trace_mls_path )
4492       DEALLOCATE ( rrtm_play_tmp )
4493       DEALLOCATE ( rrtm_plev_tmp )
4494       DEALLOCATE ( trace_mls )
4495       DEALLOCATE ( p_mls )
4496
4497    END SUBROUTINE read_trace_gas_data
4498
4499
4500    SUBROUTINE netcdf_handle_error_rad( routine_name, errno )
4501
4502       USE control_parameters,                                                 &
4503           ONLY:  message_string
4504
4505       USE NETCDF
4506
4507       USE pegrid
4508
4509       IMPLICIT NONE
4510
4511       CHARACTER(LEN=6) ::  message_identifier
4512       CHARACTER(LEN=*) ::  routine_name
4513
4514       INTEGER(iwp) ::  errno
4515
4516       IF ( nc_stat /= NF90_NOERR )  THEN
4517
4518          WRITE( message_identifier, '(''NC'',I4.4)' )  errno
4519          message_string = TRIM( NF90_STRERROR( nc_stat ) )
4520
4521          CALL message( routine_name, message_identifier, 2, 2, 0, 6, 1 )
4522
4523       ENDIF
4524
4525    END SUBROUTINE netcdf_handle_error_rad
4526#endif
4527
4528
4529!------------------------------------------------------------------------------!
4530! Description:
4531! ------------
4532!> Calculate temperature tendency due to radiative cooling/heating.
4533!> Cache-optimized version.
4534!------------------------------------------------------------------------------!
4535 SUBROUTINE radiation_tendency_ij ( i, j, tend )
4536
4537    IMPLICIT NONE
4538
4539    INTEGER(iwp) :: i, j, k !< loop indices
4540
4541    REAL(wp), DIMENSION(nzb:nzt+1,nysg:nyng,nxlg:nxrg) :: tend !< pt tendency term
4542
4543    IF ( radiation_scheme == 'rrtmg' )  THEN
4544#if defined  ( __rrtmg )
4545!
4546!--    Calculate tendency based on heating rate
4547       DO k = nzb+1, nzt+1
4548          tend(k,j,i) = tend(k,j,i) + (rad_lw_hr(k,j,i) + rad_sw_hr(k,j,i))    &
4549                                         * d_exner(k) * d_seconds_hour
4550       ENDDO
4551#endif
4552    ENDIF
4553
4554    END SUBROUTINE radiation_tendency_ij
4555
4556
4557!------------------------------------------------------------------------------!
4558! Description:
4559! ------------
4560!> Calculate temperature tendency due to radiative cooling/heating.
4561!> Vector-optimized version
4562!------------------------------------------------------------------------------!
4563 SUBROUTINE radiation_tendency ( tend )
4564
4565    USE indices,                                                               &
4566        ONLY:  nxl, nxr, nyn, nys
4567
4568    IMPLICIT NONE
4569
4570    INTEGER(iwp) :: i, j, k !< loop indices
4571
4572    REAL(wp), DIMENSION(nzb:nzt+1,nysg:nyng,nxlg:nxrg) :: tend !< pt tendency term
4573
4574    IF ( radiation_scheme == 'rrtmg' )  THEN
4575#if defined  ( __rrtmg )
4576!
4577!--    Calculate tendency based on heating rate
4578       DO  i = nxl, nxr
4579          DO  j = nys, nyn
4580             DO k = nzb+1, nzt+1
4581                tend(k,j,i) = tend(k,j,i) + ( rad_lw_hr(k,j,i)                 &
4582                                          +  rad_sw_hr(k,j,i) ) * d_exner(k)   &
4583                                          * d_seconds_hour
4584             ENDDO
4585          ENDDO
4586       ENDDO
4587#endif
4588    ENDIF
4589
4590
4591 END SUBROUTINE radiation_tendency
4592
4593!------------------------------------------------------------------------------!
4594! Description:
4595! ------------
4596!> This subroutine calculates interaction of the solar radiation
4597!> with urban and land surfaces and updates all surface heatfluxes.
4598!> It calculates also the required parameters for RRTMG lower BC.
4599!>
4600!> For more info. see Resler et al. 2017
4601!>
4602!> The new version 2.0 was radically rewriten, the discretization scheme
4603!> has been changed. This new version significantly improves effectivity
4604!> of the paralelization and the scalability of the model.
4605!------------------------------------------------------------------------------!
4606
4607 SUBROUTINE radiation_interaction
4608
4609     IMPLICIT NONE
4610
4611     INTEGER(iwp)                      :: i, j, k, kk, is, js, d, ku, refstep, m, mm, l, ll
4612     INTEGER(iwp)                      :: isurf, isurfsrc, isvf, icsf, ipcgb
4613     INTEGER(iwp)                      :: imrt, imrtf
4614     INTEGER(iwp)                      :: isd                !< solar direction number
4615     INTEGER(iwp)                      :: pc_box_dimshift    !< transform for best accuracy
4616     INTEGER(iwp), DIMENSION(0:3)      :: reorder = (/ 1, 0, 3, 2 /)
4617     
4618     REAL(wp), DIMENSION(3,3)          :: mrot               !< grid rotation matrix (zyx)
4619     REAL(wp), DIMENSION(3,0:nsurf_type):: vnorm             !< face direction normal vectors (zyx)
4620     REAL(wp), DIMENSION(3)            :: sunorig            !< grid rotated solar direction unit vector (zyx)
4621     REAL(wp), DIMENSION(3)            :: sunorig_grid       !< grid squashed solar direction unit vector (zyx)
4622     REAL(wp), DIMENSION(0:nsurf_type) :: costheta           !< direct irradiance factor of solar angle
4623     REAL(wp), DIMENSION(nzub:nzut)    :: pchf_prep          !< precalculated factor for canopy temperature tendency
4624     REAL(wp), DIMENSION(nzub:nzut)    :: pctf_prep          !< precalculated factor for canopy transpiration tendency
4625     REAL(wp), PARAMETER               :: alpha = 0._wp      !< grid rotation (TODO: add to namelist or remove)
4626     REAL(wp)                          :: pc_box_area, pc_abs_frac, pc_abs_eff
4627!     REAL(wp)                          ::  count_surfaces    !< number of all surfaces in model domain
4628!     REAL(wp)                          ::  count_surfaces_l  !< number of all surfaces in sub-domain
4629!     REAL(wp)                          ::  pt_surf_urb       !< mean surface temperature of all surfaces in model domain, temporal work-around
4630!     REAL(wp)                          ::  pt_surf_urb_l     !< mean surface temperature of all surfaces in sub-domain, temporal work-around
4631
4632     REAL(wp), DIMENSION(0:nsurf_type) :: facearea
4633     REAL(wp)                          :: pabsswl  = 0.0_wp  !< total absorbed SW radiation energy in local processor (W)
4634     REAL(wp)                          :: pabssw   = 0.0_wp  !< total absorbed SW radiation energy in all processors (W)
4635     REAL(wp)                          :: pabslwl  = 0.0_wp  !< total absorbed LW radiation energy in local processor (W)
4636     REAL(wp)                          :: pabslw   = 0.0_wp  !< total absorbed LW radiation energy in all processors (W)
4637     REAL(wp)                          :: pemitlwl = 0.0_wp  !< total emitted LW radiation energy in all processors (W)
4638     REAL(wp)                          :: pemitlw  = 0.0_wp  !< total emitted LW radiation energy in all processors (W)
4639     REAL(wp)                          :: pinswl   = 0.0_wp  !< total received SW radiation energy in local processor (W)
4640     REAL(wp)                          :: pinsw    = 0.0_wp  !< total received SW radiation energy in all processor (W)
4641     REAL(wp)                          :: pinlwl   = 0.0_wp  !< total received LW radiation energy in local processor (W)
4642     REAL(wp)                          :: pinlw    = 0.0_wp  !< total received LW radiation energy in all processor (W)
4643     REAL(wp)                          :: emiss_sum_surfl    !< sum of emissisivity of surfaces in local processor
4644     REAL(wp)                          :: emiss_sum_surf     !< sum of emissisivity of surfaces in all processor
4645     REAL(wp)                          :: area_surfl         !< total area of surfaces in local processor
4646     REAL(wp)                          :: area_surf          !< total area of surfaces in all processor
4647     REAL(wp)                          :: area_hor           !< total horizontal area of domain in all processor
4648
4649#if ! defined( __nopointer )
4650     IF ( plant_canopy )  THEN
4651         pchf_prep(:) = r_d * exner(nzub:nzut)                                 &
4652                     / (c_p * hyp(nzub:nzut) * dx*dy*dz(1)) !< equals to 1 / (rho * c_p * Vbox * T)
4653         pctf_prep(:) = r_d * exner(nzub:nzut)                                 &
4654                     / (l_v * hyp(nzub:nzut) * dx*dy*dz(1))
4655     ENDIF
4656#endif
4657     sun_direction = .TRUE.
4658     CALL calc_zenith  !< required also for diffusion radiation
4659
4660!--     prepare rotated normal vectors and irradiance factor
4661     vnorm(1,:) = kdir(:)
4662     vnorm(2,:) = jdir(:)
4663     vnorm(3,:) = idir(:)
4664     mrot(1, :) = (/ 1._wp,  0._wp,      0._wp      /)
4665     mrot(2, :) = (/ 0._wp,  COS(alpha), SIN(alpha) /)
4666     mrot(3, :) = (/ 0._wp, -SIN(alpha), COS(alpha) /)
4667     sunorig = (/ zenith(0), sun_dir_lat, sun_dir_lon /)
4668     sunorig = MATMUL(mrot, sunorig)
4669     DO d = 0, nsurf_type
4670         costheta(d) = DOT_PRODUCT(sunorig, vnorm(:,d))
4671     ENDDO
4672
4673     IF ( zenith(0) > 0 )  THEN
4674!--      now we will "squash" the sunorig vector by grid box size in
4675!--      each dimension, so that this new direction vector will allow us
4676!--      to traverse the ray path within grid coordinates directly
4677         sunorig_grid = (/ sunorig(1)/dz(1), sunorig(2)/dy, sunorig(3)/dx /)
4678!--      sunorig_grid = sunorig_grid / norm2(sunorig_grid)
4679         sunorig_grid = sunorig_grid / SQRT(SUM(sunorig_grid**2))
4680
4681         IF ( npcbl > 0 )  THEN
4682!--         precompute effective box depth with prototype Leaf Area Density
4683            pc_box_dimshift = MAXLOC(ABS(sunorig), 1) - 1
4684            CALL box_absorb(CSHIFT((/dz(1),dy,dx/), pc_box_dimshift),      &
4685                                60, prototype_lad,                          &
4686                                CSHIFT(ABS(sunorig), pc_box_dimshift),      &
4687                                pc_box_area, pc_abs_frac)
4688            pc_box_area = pc_box_area * ABS(sunorig(pc_box_dimshift+1) / sunorig(1))
4689            pc_abs_eff = LOG(1._wp - pc_abs_frac) / prototype_lad
4690         ENDIF
4691     ENDIF
4692
4693!--  if radiation scheme is not RRTMG, split diffusion and direct part of the solar downward radiation
4694!--  comming from radiation model and store it in 2D arrays
4695     IF (  radiation_scheme /= 'rrtmg'  )  CALL calc_diffusion_radiation
4696
4697!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4698!--     First pass: direct + diffuse irradiance + thermal
4699!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4700     surfinswdir   = 0._wp !nsurfl
4701     surfins       = 0._wp !nsurfl
4702     surfinl       = 0._wp !nsurfl
4703     surfoutsl(:)  = 0.0_wp !start-end
4704     surfoutll(:)  = 0.0_wp !start-end
4705     IF ( nmrtbl > 0 )  THEN
4706        mrtinsw(:) = 0._wp
4707        mrtinlw(:) = 0._wp
4708     ENDIF
4709
4710
4711!--  Set up thermal radiation from surfaces
4712!--  emiss_surf is defined only for surfaces for which energy balance is calculated
4713!--  Workaround: reorder surface data type back on 1D array including all surfaces,
4714!--  which implies to reorder horizontal and vertical surfaces
4715!
4716!--  Horizontal walls
4717     mm = 1
4718     DO  i = nxl, nxr
4719        DO  j = nys, nyn
4720!--           urban
4721           DO  m = surf_usm_h%start_index(j,i), surf_usm_h%end_index(j,i)
4722              surfoutll(mm) = SUM ( surf_usm_h%frac(:,m) *                  &
4723                                    surf_usm_h%emissivity(:,m) )            &
4724                                  * sigma_sb                                &
4725                                  * surf_usm_h%pt_surface(m)**4
4726              albedo_surf(mm) = SUM ( surf_usm_h%frac(:,m) *                &
4727                                      surf_usm_h%albedo(:,m) )
4728              emiss_surf(mm)  = SUM ( surf_usm_h%frac(:,m) *                &
4729                                      surf_usm_h%emissivity(:,m) )
4730              mm = mm + 1
4731           ENDDO
4732!--           land
4733           DO  m = surf_lsm_h%start_index(j,i), surf_lsm_h%end_index(j,i)
4734              surfoutll(mm) = SUM ( surf_lsm_h%frac(:,m) *                  &
4735                                    surf_lsm_h%emissivity(:,m) )            &
4736                                  * sigma_sb                                &
4737                                  * surf_lsm_h%pt_surface(m)**4
4738              albedo_surf(mm) = SUM ( surf_lsm_h%frac(:,m) *                &
4739                                      surf_lsm_h%albedo(:,m) )
4740              emiss_surf(mm)  = SUM ( surf_lsm_h%frac(:,m) *                &
4741                                      surf_lsm_h%emissivity(:,m) )
4742              mm = mm + 1
4743           ENDDO
4744        ENDDO
4745     ENDDO
4746!
4747!--     Vertical walls
4748     DO  i = nxl, nxr
4749        DO  j = nys, nyn
4750           DO  ll = 0, 3
4751              l = reorder(ll)
4752!--              urban
4753              DO  m = surf_usm_v(l)%start_index(j,i),                       &
4754                      surf_usm_v(l)%end_index(j,i)
4755                 surfoutll(mm) = SUM ( surf_usm_v(l)%frac(:,m) *            &
4756                                       surf_usm_v(l)%emissivity(:,m) )      &
4757                                  * sigma_sb                                &
4758                                  * surf_usm_v(l)%pt_surface(m)**4
4759                 albedo_surf(mm) = SUM ( surf_usm_v(l)%frac(:,m) *          &
4760                                         surf_usm_v(l)%albedo(:,m) )
4761                 emiss_surf(mm)  = SUM ( surf_usm_v(l)%frac(:,m) *          &
4762                                         surf_usm_v(l)%emissivity(:,m) )
4763                 mm = mm + 1
4764              ENDDO
4765!--              land
4766              DO  m = surf_lsm_v(l)%start_index(j,i),                       &
4767                      surf_lsm_v(l)%end_index(j,i)
4768                 surfoutll(mm) = SUM ( surf_lsm_v(l)%frac(:,m) *            &
4769                                       surf_lsm_v(l)%emissivity(:,m) )      &
4770                                  * sigma_sb                                &
4771                                  * surf_lsm_v(l)%pt_surface(m)**4
4772                 albedo_surf(mm) = SUM ( surf_lsm_v(l)%frac(:,m) *          &
4773                                         surf_lsm_v(l)%albedo(:,m) )
4774                 emiss_surf(mm)  = SUM ( surf_lsm_v(l)%frac(:,m) *          &
4775                                         surf_lsm_v(l)%emissivity(:,m) )
4776                 mm = mm + 1
4777              ENDDO
4778           ENDDO
4779        ENDDO
4780     ENDDO
4781
4782#if defined( __parallel )
4783!--     might be optimized and gather only values relevant for current processor
4784     CALL MPI_AllGatherv(surfoutll, nsurfl, MPI_REAL, &
4785                         surfoutl, nsurfs, surfstart, MPI_REAL, comm2d, ierr) !nsurf global
4786     IF ( ierr /= 0 ) THEN
4787         WRITE(9,*) 'Error MPI_AllGatherv1:', ierr, SIZE(surfoutll), nsurfl, &
4788                     SIZE(surfoutl), nsurfs, surfstart
4789         FLUSH(9)
4790     ENDIF
4791#else
4792     surfoutl(:) = surfoutll(:) !nsurf global
4793#endif
4794
4795     IF ( surface_reflections)  THEN
4796        DO  isvf = 1, nsvfl
4797           isurf = svfsurf(1, isvf)
4798           k     = surfl(iz, isurf)
4799           j     = surfl(iy, isurf)
4800           i     = surfl(ix, isurf)
4801           isurfsrc = svfsurf(2, isvf)
4802!
4803!--        For surface-to-surface factors we calculate thermal radiation in 1st pass
4804           surfinl(isurf) = surfinl(isurf) + svf(1,isvf) * surfoutl(isurfsrc)
4805        ENDDO
4806     ENDIF
4807!
4808!--  diffuse radiation using sky view factor
4809     DO isurf = 1, nsurfl
4810        j = surfl(iy, isurf)
4811        i = surfl(ix, isurf)
4812        surfinswdif(isurf) = rad_sw_in_diff(j,i) * skyvft(isurf)
4813        surfinlwdif(isurf) = rad_lw_in_diff(j,i) * skyvf(isurf)
4814     ENDDO
4815!
4816!--  MRT diffuse irradiance
4817     DO  imrt = 1, nmrtbl
4818        j = mrtbl(iy, imrt)
4819        i = mrtbl(ix, imrt)
4820        mrtinsw(imrt) = mrtskyt(imrt) * rad_sw_in_diff(j,i)
4821        mrtinlw(imrt) = mrtsky(imrt) * rad_lw_in_diff(j,i)
4822     ENDDO
4823
4824     !-- direct radiation
4825     IF ( zenith(0) > 0 )  THEN
4826        !--Identify solar direction vector (discretized number) 1)
4827        !--
4828        j = FLOOR(ACOS(zenith(0)) / pi * raytrace_discrete_elevs)
4829        i = MODULO(NINT(ATAN2(sun_dir_lon(0), sun_dir_lat(0))               &
4830                        / (2._wp*pi) * raytrace_discrete_azims-.5_wp, iwp), &
4831                   raytrace_discrete_azims)
4832        isd = dsidir_rev(j, i)
4833        DO isurf = 1, nsurfl
4834           j = surfl(iy, isurf)
4835           i = surfl(ix, isurf)
4836           surfinswdir(isurf) = rad_sw_in_dir(j,i) * costheta(surfl(id, isurf)) * dsitrans(isurf, isd) / zenith(0)
4837        ENDDO
4838!
4839!--     MRT direct irradiance
4840        DO  imrt = 1, nmrtbl
4841           j = mrtbl(iy, imrt)
4842           i = mrtbl(ix, imrt)
4843           mrtinsw(imrt) = mrtinsw(imrt) + mrtdsit(imrt, isd) * rad_sw_in_dir(j,i) &
4844                                     / zenith(0) / 4._wp ! normal to sphere
4845        ENDDO
4846     ENDIF
4847!
4848!--  MRT first pass thermal
4849     DO  imrtf = 1, nmrtf
4850        imrt = mrtfsurf(1, imrtf)
4851        isurfsrc = mrtfsurf(2, imrtf)
4852        mrtinlw(imrt) = mrtinlw(imrt) + mrtf(imrtf) * surfoutl(isurfsrc)
4853     ENDDO
4854
4855     IF ( npcbl > 0 )  THEN
4856
4857         pcbinswdir(:) = 0._wp
4858         pcbinswdif(:) = 0._wp
4859         pcbinlw(:) = 0._wp  !< will stay always 0 since we don't absorb lw anymore
4860!
4861!--         pcsf first pass
4862         DO icsf = 1, ncsfl
4863             ipcgb = csfsurf(1, icsf)
4864             i = pcbl(ix,ipcgb)
4865             j = pcbl(iy,ipcgb)
4866             k = pcbl(iz,ipcgb)
4867             isurfsrc = csfsurf(2, icsf)
4868
4869             IF ( isurfsrc == -1 )  THEN
4870!--                 Diffuse rad from sky.
4871                 pcbinswdif(ipcgb) = csf(1,icsf) * rad_sw_in_diff(j,i)
4872
4873                 !--Direct rad
4874                 IF ( zenith(0) > 0 )  THEN
4875                    !--Estimate directed box absorption
4876                    pc_abs_frac = 1._wp - exp(pc_abs_eff * lad_s(k,j,i))
4877
4878                    !--isd has already been established, see 1)
4879                    pcbinswdir(ipcgb) = rad_sw_in_dir(j, i) * pc_box_area &
4880                                        * pc_abs_frac * dsitransc(ipcgb, isd)
4881                 ENDIF
4882             ENDIF
4883         ENDDO
4884
4885         pcbinsw(:) = pcbinswdir(:) + pcbinswdif(:)
4886     ENDIF
4887     surfins = surfinswdir + surfinswdif
4888     surfinl = surfinl + surfinlwdif
4889     surfinsw = surfins
4890     surfinlw = surfinl
4891     surfoutsw = 0.0_wp
4892     surfoutlw = surfoutll
4893     surfemitlwl = surfoutll
4894
4895     IF ( .NOT.  surface_reflections )  THEN
4896!
4897!--     Set nrefsteps to 0 to disable reflections       
4898        nrefsteps = 0
4899        surfoutsl = albedo_surf * surfins
4900        surfoutll = (1._wp - emiss_surf) * surfinl
4901        surfoutsw = surfoutsw + surfoutsl
4902        surfoutlw = surfoutlw + surfoutll
4903     ENDIF
4904
4905!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4906!--     Next passes - reflections
4907!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4908     DO refstep = 1, nrefsteps
4909
4910         surfoutsl = albedo_surf * surfins
4911!--         for non-transparent surfaces, longwave albedo is 1 - emissivity
4912         surfoutll = (1._wp - emiss_surf) * surfinl
4913
4914#if defined( __parallel )
4915         CALL MPI_AllGatherv(surfoutsl, nsurfl, MPI_REAL, &
4916             surfouts, nsurfs, surfstart, MPI_REAL, comm2d, ierr)
4917         IF ( ierr /= 0 ) THEN
4918             WRITE(9,*) 'Error MPI_AllGatherv2:', ierr, SIZE(surfoutsl), nsurfl, &
4919                        SIZE(surfouts), nsurfs, surfstart
4920             FLUSH(9)
4921         ENDIF
4922
4923         CALL MPI_AllGatherv(surfoutll, nsurfl, MPI_REAL, &
4924             surfoutl, nsurfs, surfstart, MPI_REAL, comm2d, ierr)
4925         IF ( ierr /= 0 ) THEN
4926             WRITE(9,*) 'Error MPI_AllGatherv3:', ierr, SIZE(surfoutll), nsurfl, &
4927                        SIZE(surfoutl), nsurfs, surfstart
4928             FLUSH(9)
4929         ENDIF
4930
4931#else
4932         surfouts = surfoutsl
4933         surfoutl = surfoutll
4934#endif
4935
4936!--         reset for next pass input
4937         surfins = 0._wp
4938         surfinl = 0._wp
4939
4940!--         reflected radiation
4941         DO isvf = 1, nsvfl
4942             isurf = svfsurf(1, isvf)
4943             isurfsrc = svfsurf(2, isvf)
4944             surfins(isurf) = surfins(isurf) + svf(1,isvf) * svf(2,isvf) * surfouts(isurfsrc)
4945             surfinl(isurf) = surfinl(isurf) + svf(1,isvf) * surfoutl(isurfsrc)
4946         ENDDO
4947
4948!--         radiation absorbed by plant canopy
4949         DO icsf = 1, ncsfl
4950             ipcgb = csfsurf(1, icsf)
4951             isurfsrc = csfsurf(2, icsf)
4952             IF ( isurfsrc == -1 )  CYCLE ! sky->face only in 1st pass, not here
4953
4954             pcbinsw(ipcgb) = pcbinsw(ipcgb) + csf(1,icsf) * surfouts(isurfsrc)
4955         ENDDO
4956!
4957!--      MRT reflected
4958         DO  imrtf = 1, nmrtf
4959            imrt = mrtfsurf(1, imrtf)
4960            isurfsrc = mrtfsurf(2, imrtf)
4961            mrtinsw(imrt) = mrtinsw(imrt) + mrtft(imrtf) * surfouts(isurfsrc)
4962            mrtinlw(imrt) = mrtinlw(imrt) + mrtf(imrtf) * surfoutl(isurfsrc)
4963         ENDDO
4964
4965         surfinsw = surfinsw  + surfins
4966         surfinlw = surfinlw  + surfinl
4967         surfoutsw = surfoutsw + surfoutsl
4968         surfoutlw = surfoutlw + surfoutll
4969
4970     ENDDO ! refstep
4971
4972!--  push heat flux absorbed by plant canopy to respective 3D arrays
4973     IF ( npcbl > 0 )  THEN
4974         pc_heating_rate(:,:,:) = 0.0_wp
4975         pc_transpiration_rate(:,:,:) = 0.0_wp
4976         DO ipcgb = 1, npcbl
4977                 
4978             j = pcbl(iy, ipcgb)
4979             i = pcbl(ix, ipcgb)
4980             k = pcbl(iz, ipcgb)
4981!
4982!--             Following expression equals former kk = k - nzb_s_inner(j,i)
4983             kk = k - get_topography_top_index_ji( j, i, 's' )  !- lad arrays are defined flat
4984             pc_heating_rate(kk, j, i) = (pcbinsw(ipcgb) + pcbinlw(ipcgb)) &
4985                 * pchf_prep(k) * pt(k, j, i) !-- = dT/dt
4986
4987!             pc_transpiration_rate(kk,j,i) = 0.75_wp* (pcbinsw(ipcgb) + pcbinlw(ipcgb)) &
4988!                 * pctf_prep(k) * pt(k, j, i) !-- = dq/dt
4989
4990         ENDDO
4991     ENDIF
4992!
4993!--  Calculate black body MRT (after all reflections)
4994     IF ( nmrtbl > 0 )  THEN
4995        IF ( mrt_include_sw )  THEN
4996           mrt(:) = ((mrtinsw(:) + mrtinlw(:)) / sigma_sb) ** .25_wp
4997        ELSE
4998           mrt(:) = (mrtinlw(:) / sigma_sb) ** .25_wp
4999        ENDIF
5000     ENDIF
5001!
5002!--     Transfer radiation arrays required for energy balance to the respective data types
5003     DO  i = 1, nsurfl
5004        m  = surfl(5,i)
5005!
5006!--     (1) Urban surfaces
5007!--     upward-facing
5008        IF ( surfl(1,i) == iup_u )  THEN
5009           surf_usm_h%rad_sw_in(m)  = surfinsw(i)
5010           surf_usm_h%rad_sw_out(m) = surfoutsw(i)
5011           surf_usm_h%rad_lw_in(m)  = surfinlw(i)
5012           surf_usm_h%rad_lw_out(m) = surfoutlw(i)
5013           surf_usm_h%rad_net(m)    = surfinsw(i) - surfoutsw(i) +          &
5014                                      surfinlw(i) - surfoutlw(i)
5015           surf_usm_h%rad_net_l(m)  = surf_usm_h%rad_net(m)
5016!
5017!--     northward-facding
5018        ELSEIF ( surfl(1,i) == inorth_u )  THEN
5019           surf_usm_v(0)%rad_sw_in(m)  = surfinsw(i)
5020           surf_usm_v(0)%rad_sw_out(m) = surfoutsw(i)
5021           surf_usm_v(0)%rad_lw_in(m)  = surfinlw(i)
5022           surf_usm_v(0)%rad_lw_out(m) = surfoutlw(i)
5023           surf_usm_v(0)%rad_net(m)    = surfinsw(i) - surfoutsw(i) +       &
5024                                         surfinlw(i) - surfoutlw(i)
5025           surf_usm_v(0)%rad_net_l(m)  = surf_usm_v(0)%rad_net(m)
5026!
5027!--     southward-facding
5028        ELSEIF ( surfl(1,i) == isouth_u )  THEN
5029           surf_usm_v(1)%rad_sw_in(m)  = surfinsw(i)
5030           surf_usm_v(1)%rad_sw_out(m) = surfoutsw(i)
5031           surf_usm_v(1)%rad_lw_in(m)  = surfinlw(i)
5032           surf_usm_v(1)%rad_lw_out(m) = surfoutlw(i)
5033           surf_usm_v(1)%rad_net(m)    = surfinsw(i) - surfoutsw(i) +       &
5034                                         surfinlw(i) - surfoutlw(i)
5035           surf_usm_v(1)%rad_net_l(m)  = surf_usm_v(1)%rad_net(m)
5036!
5037!--     eastward-facing
5038        ELSEIF ( surfl(1,i) == ieast_u )  THEN
5039           surf_usm_v(2)%rad_sw_in(m)  = surfinsw(i)
5040           surf_usm_v(2)%rad_sw_out(m) = surfoutsw(i)
5041           surf_usm_v(2)%rad_lw_in(m)  = surfinlw(i)
5042           surf_usm_v(2)%rad_lw_out(m) = surfoutlw(i)
5043           surf_usm_v(2)%rad_net(m)    = surfinsw(i) - surfoutsw(i) +       &
5044                                         surfinlw(i) - surfoutlw(i)
5045           surf_usm_v(2)%rad_net_l(m)  = surf_usm_v(2)%rad_net(m)
5046!
5047!--     westward-facding
5048        ELSEIF ( surfl(1,i) == iwest_u )  THEN
5049           surf_usm_v(3)%rad_sw_in(m)  = surfinsw(i)
5050           surf_usm_v(3)%rad_sw_out(m) = surfoutsw(i)
5051           surf_usm_v(3)%rad_lw_in(m)  = surfinlw(i)
5052           surf_usm_v(3)%rad_lw_out(m) = surfoutlw(i)
5053           surf_usm_v(3)%rad_net(m)    = surfinsw(i) - surfoutsw(i) +       &
5054                                         surfinlw(i) - surfoutlw(i)
5055           surf_usm_v(3)%rad_net_l(m)  = surf_usm_v(3)%rad_net(m)
5056!
5057!--     (2) land surfaces
5058!--     upward-facing
5059        ELSEIF ( surfl(1,i) == iup_l )  THEN
5060           surf_lsm_h%rad_sw_in(m)  = surfinsw(i)
5061           surf_lsm_h%rad_sw_out(m) = surfoutsw(i)
5062           surf_lsm_h%rad_lw_in(m)  = surfinlw(i)
5063           surf_lsm_h%rad_lw_out(m) = surfoutlw(i)
5064           surf_lsm_h%rad_net(m)    = surfinsw(i) - surfoutsw(i) +          &
5065                                      surfinlw(i) - surfoutlw(i)
5066!
5067!--     northward-facding
5068        ELSEIF ( surfl(1,i) == inorth_l )  THEN
5069           surf_lsm_v(0)%rad_sw_in(m)  = surfinsw(i)
5070           surf_lsm_v(0)%rad_sw_out(m) = surfoutsw(i)
5071           surf_lsm_v(0)%rad_lw_in(m)  = surfinlw(i)
5072           surf_lsm_v(0)%rad_lw_out(m) = surfoutlw(i)
5073           surf_lsm_v(0)%rad_net(m)    = surfinsw(i) - surfoutsw(i) +       &
5074                                         surfinlw(i) - surfoutlw(i)
5075!
5076!--     southward-facding
5077        ELSEIF ( surfl(1,i) == isouth_l )  THEN
5078           surf_lsm_v(1)%rad_sw_in(m)  = surfinsw(i)
5079           surf_lsm_v(1)%rad_sw_out(m) = surfoutsw(i)
5080           surf_lsm_v(1)%rad_lw_in(m)  = surfinlw(i)
5081           surf_lsm_v(1)%rad_lw_out(m) = surfoutlw(i)
5082           surf_lsm_v(1)%rad_net(m)    = surfinsw(i) - surfoutsw(i) +       &
5083                                         surfinlw(i) - surfoutlw(i)
5084!
5085!--     eastward-facing
5086        ELSEIF ( surfl(1,i) == ieast_l )  THEN
5087           surf_lsm_v(2)%rad_sw_in(m)  = surfinsw(i)
5088           surf_lsm_v(2)%rad_sw_out(m) = surfoutsw(i)
5089           surf_lsm_v(2)%rad_lw_in(m)  = surfinlw(i)
5090           surf_lsm_v(2)%rad_lw_out(m) = surfoutlw(i)
5091           surf_lsm_v(2)%rad_net(m)    = surfinsw(i) - surfoutsw(i) +       &
5092                                         surfinlw(i) - surfoutlw(i)
5093!
5094!--     westward-facing
5095        ELSEIF ( surfl(1,i) == iwest_l )  THEN
5096           surf_lsm_v(3)%rad_sw_in(m)  = surfinsw(i)
5097           surf_lsm_v(3)%rad_sw_out(m) = surfoutsw(i)
5098           surf_lsm_v(3)%rad_lw_in(m)  = surfinlw(i)
5099           surf_lsm_v(3)%rad_lw_out(m) = surfoutlw(i)
5100           surf_lsm_v(3)%rad_net(m)    = surfinsw(i) - surfoutsw(i) +       &
5101                                         surfinlw(i) - surfoutlw(i)
5102        ENDIF
5103
5104     ENDDO
5105
5106     DO  m = 1, surf_usm_h%ns
5107        surf_usm_h%surfhf(m) = surf_usm_h%rad_sw_in(m)  +                   &
5108                               surf_usm_h%rad_lw_in(m)  -                   &
5109                               surf_usm_h%rad_sw_out(m) -                   &
5110                               surf_usm_h%rad_lw_out(m)
5111     ENDDO
5112     DO  m = 1, surf_lsm_h%ns
5113        surf_lsm_h%surfhf(m) = surf_lsm_h%rad_sw_in(m)  +                   &
5114                               surf_lsm_h%rad_lw_in(m)  -                   &
5115                               surf_lsm_h%rad_sw_out(m) -                   &
5116                               surf_lsm_h%rad_lw_out(m)
5117     ENDDO
5118
5119     DO  l = 0, 3
5120!--     urban
5121        DO  m = 1, surf_usm_v(l)%ns
5122           surf_usm_v(l)%surfhf(m) = surf_usm_v(l)%rad_sw_in(m)  +          &
5123                                     surf_usm_v(l)%rad_lw_in(m)  -          &
5124                                     surf_usm_v(l)%rad_sw_out(m) -          &
5125                                     surf_usm_v(l)%rad_lw_out(m)
5126        ENDDO
5127!--     land
5128        DO  m = 1, surf_lsm_v(l)%ns
5129           surf_lsm_v(l)%surfhf(m) = surf_lsm_v(l)%rad_sw_in(m)  +          &
5130                                     surf_lsm_v(l)%rad_lw_in(m)  -          &
5131                                     surf_lsm_v(l)%rad_sw_out(m) -          &
5132                                     surf_lsm_v(l)%rad_lw_out(m)
5133
5134        ENDDO
5135     ENDDO
5136!
5137!--  Calculate the average temperature, albedo, and emissivity for urban/land
5138!--  domain when using average_radiation in the respective radiation model
5139
5140!--  Precalculate face areas for all face directions using normal vector
5141     DO d = 0, nsurf_type
5142        facearea(d) = 1._wp
5143        IF ( idir(d) == 0 ) facearea(d) = facearea(d) * dx
5144        IF ( jdir(d) == 0 ) facearea(d) = facearea(d) * dy
5145        IF ( kdir(d) == 0 ) facearea(d) = facearea(d) * dz(1)
5146     ENDDO
5147!--  calculate horizontal area
5148! !!! ATTENTION!!! uniform grid is assumed here
5149     area_hor = (nx+1) * (ny+1) * dx * dy
5150!
5151!--  absorbed/received SW & LW and emitted LW energy of all physical
5152!--  surfaces (land and urban) in local processor
5153     pinswl = 0._wp
5154     pinlwl = 0._wp
5155     pabsswl = 0._wp
5156     pabslwl = 0._wp
5157     pemitlwl = 0._wp
5158     emiss_sum_surfl = 0._wp
5159     area_surfl = 0._wp
5160     DO  i = 1, nsurfl
5161        d = surfl(id, i)
5162!--  received SW & LW
5163        pinswl = pinswl + (surfinswdir(i) + surfinswdif(i)) * facearea(d)
5164        pinlwl = pinlwl + surfinlwdif(i) * facearea(d)
5165!--   absorbed SW & LW
5166        pabsswl = pabsswl + (1._wp - albedo_surf(i)) *                   &
5167                                                surfinsw(i) * facearea(d)
5168        pabslwl = pabslwl + emiss_surf(i) * surfinlw(i) * facearea(d)
5169!--   emitted LW
5170        pemitlwl = pemitlwl + surfemitlwl(i) * facearea(d)
5171!--   emissivity and area sum
5172        emiss_sum_surfl = emiss_sum_surfl + emiss_surf(i) * facearea(d)
5173        area_surfl = area_surfl + facearea(d)
5174     END DO
5175!
5176!--  add the absorbed SW energy by plant canopy
5177     IF ( npcbl > 0 )  THEN
5178        pabsswl = pabsswl + SUM(pcbinsw)
5179        pabslwl = pabslwl + SUM(pcbinlw)
5180        pinswl = pinswl + SUM(pcbinswdir) + SUM(pcbinswdif)
5181     ENDIF
5182!
5183!--  gather all rad flux energy in all processors
5184#if defined( __parallel )
5185     CALL MPI_ALLREDUCE( pinswl, pinsw, 1, MPI_REAL, MPI_SUM, comm2d, ierr)
5186     IF ( ierr /= 0 ) THEN
5187         WRITE(9,*) 'Error MPI_AllReduce5:', ierr, pinswl, pinsw
5188         FLUSH(9)
5189     ENDIF
5190     CALL MPI_ALLREDUCE( pinlwl, pinlw, 1, MPI_REAL, MPI_SUM, comm2d, ierr)
5191     IF ( ierr /= 0 ) THEN
5192         WRITE(9,*) 'Error MPI_AllReduce6:', ierr, pinlwl, pinlw
5193         FLUSH(9)
5194     ENDIF
5195     CALL MPI_ALLREDUCE( pabsswl, pabssw, 1, MPI_REAL, MPI_SUM, comm2d, ierr )
5196     IF ( ierr /= 0 ) THEN
5197         WRITE(9,*) 'Error MPI_AllReduce7:', ierr, pabsswl, pabssw
5198         FLUSH(9)
5199     ENDIF
5200     CALL MPI_ALLREDUCE( pabslwl, pabslw, 1, MPI_REAL, MPI_SUM, comm2d, ierr )
5201     IF ( ierr /= 0 ) THEN
5202         WRITE(9,*) 'Error MPI_AllReduce8:', ierr, pabslwl, pabslw
5203         FLUSH(9)
5204     ENDIF
5205     CALL MPI_ALLREDUCE( pemitlwl, pemitlw, 1, MPI_REAL, MPI_SUM, comm2d, ierr )
5206     IF ( ierr /= 0 ) THEN
5207         WRITE(9,*) 'Error MPI_AllReduce8:', ierr, pemitlwl, pemitlw
5208         FLUSH(9)
5209     ENDIF
5210     CALL MPI_ALLREDUCE( emiss_sum_surfl, emiss_sum_surf, 1, MPI_REAL, MPI_SUM, comm2d, ierr )
5211     IF ( ierr /= 0 ) THEN
5212         WRITE(9,*) 'Error MPI_AllReduce9:', ierr, emiss_sum_surfl, emiss_sum_surf
5213         FLUSH(9)
5214     ENDIF
5215     CALL MPI_ALLREDUCE( area_surfl, area_surf, 1, MPI_REAL, MPI_SUM, comm2d, ierr )
5216     IF ( ierr /= 0 ) THEN
5217         WRITE(9,*) 'Error MPI_AllReduce10:', ierr, area_surfl, area_surf
5218         FLUSH(9)
5219     ENDIF
5220#else
5221     pinsw = pinswl
5222     pinlw = pinlwl
5223     pabssw = pabsswl
5224     pabslw = pabslwl
5225     pemitlw = pemitlwl
5226     emiss_sum_surf = emiss_sum_surfl
5227     area_surf = area_surfl
5228#endif
5229
5230!--  (1) albedo
5231     IF ( pinsw /= 0.0_wp )  &
5232          albedo_urb = (pinsw - pabssw) / pinsw
5233!--  (2) average emmsivity
5234     IF ( area_surf /= 0.0_wp ) &
5235          emissivity_urb = emiss_sum_surf / area_surf
5236!
5237!--  Temporally comment out calculation of effective radiative temperature.
5238!--  See below for more explanation.
5239!--  (3) temperature
5240!--   first we calculate an effective horizontal area to account for
5241!--   the effect of vertical surfaces (which contributes to LW emission)
5242!--   We simply use the ratio of the total LW to the incoming LW flux
5243      area_hor = pinlw/rad_lw_in_diff(nyn,nxl)
5244      t_rad_urb = ( (pemitlw - pabslw + emissivity_urb*pinlw) / &
5245           (emissivity_urb*sigma_sb * area_hor) )**0.25_wp
5246!
5247!--  It has been turned out that the effective radiative temperature is far
5248!--  too high during nighttime, resulting in unphysical radiative forcing
5249!--  with wrong signs. For the moment, as a work-around, compute the mean
5250!--  surface temperature from all surface elements, resulting in more
5251!--  physically meaningful radiative forcings.           
5252!      pt_surf_urb_l    = 0.0_wp
5253!      count_surfaces_l = 0.0_wp
5254!      DO  m = 1, surf_lsm_h%ns
5255!         k                = surf_lsm_h%k(m)
5256!         pt_surf_urb_l    = pt_surf_urb_l + surf_lsm_h%pt_surface(m)            &
5257!                            * exner(k)
5258!         count_surfaces_l = count_surfaces_l + 1.0_wp
5259!      ENDDO
5260!      DO  m = 1, surf_usm_h%ns
5261!         k                = surf_usm_h%k(m)
5262!         pt_surf_urb_l    = pt_surf_urb_l + surf_usm_h%pt_surface(m)            &
5263!                            * exner(k)
5264!         count_surfaces_l = count_surfaces_l + 1.0_wp
5265!      ENDDO
5266!      DO  l = 0, 3
5267!         DO  m = 1, surf_lsm_v(l)%ns
5268!            k                = surf_lsm_v(l)%k(m)
5269!            pt_surf_urb_l    = pt_surf_urb_l + surf_lsm_v(l)%pt_surface(m)      &
5270!                            * exner(k)
5271!            count_surfaces_l = count_surfaces_l + 1.0_wp
5272!         ENDDO
5273!         DO  m = 1, surf_usm_v(l)%ns
5274!            k                = surf_usm_v(l)%k(m)
5275!            pt_surf_urb_l    = pt_surf_urb_l + surf_usm_v(l)%pt_surface(m) * exner(k)
5276!            count_surfaces_l = count_surfaces_l + 1.0_wp
5277!         ENDDO
5278!      ENDDO
5279!     
5280!      pt_surf_urb    = 0.0_wp
5281!      count_surfaces = 0.0_wp
5282!     
5283! #if defined( __parallel )
5284!      CALL MPI_ALLREDUCE( count_surfaces_l, count_surfaces, 1, MPI_REAL,        &
5285!                          MPI_SUM, comm2d, ierr)
5286!      CALL MPI_ALLREDUCE( pt_surf_urb_l,  pt_surf_urb,      1, MPI_REAL,        &
5287!                          MPI_SUM, comm2d, ierr)
5288! #else
5289!      count_surfaces_l = count_surfaces
5290!      pt_surf_urb_l    = pt_surf_urb
5291! #endif     
5292!
5293!      t_rad_urb = pt_surf_urb / count_surfaces
5294     
5295
5296    CONTAINS
5297
5298!------------------------------------------------------------------------------!
5299!> Calculates radiation absorbed by box with given size and LAD.
5300!>
5301!> Simulates resol**2 rays (by equally spacing a bounding horizontal square
5302!> conatining all possible rays that would cross the box) and calculates
5303!> average transparency per ray. Returns fraction of absorbed radiation flux
5304!> and area for which this fraction is effective.
5305!------------------------------------------------------------------------------!
5306    PURE SUBROUTINE box_absorb(boxsize, resol, dens, uvec, area, absorb)
5307       IMPLICIT NONE
5308
5309       REAL(wp), DIMENSION(3), INTENT(in) :: &
5310            boxsize, &      !< z, y, x size of box in m
5311            uvec            !< z, y, x unit vector of incoming flux
5312       INTEGER(iwp), INTENT(in) :: &
5313            resol           !< No. of rays in x and y dimensions
5314       REAL(wp), INTENT(in) :: &
5315            dens            !< box density (e.g. Leaf Area Density)
5316       REAL(wp), INTENT(out) :: &
5317            area, &         !< horizontal area for flux absorbtion
5318            absorb          !< fraction of absorbed flux
5319       REAL(wp) :: &
5320            xshift, yshift, &
5321            xmin, xmax, ymin, ymax, &
5322            xorig, yorig, &
5323            dx1, dy1, dz1, dx2, dy2, dz2, &
5324            crdist, &
5325            transp
5326       INTEGER(iwp) :: &
5327            i, j
5328
5329       xshift = uvec(3) / uvec(1) * boxsize(1)
5330       xmin = min(0._wp, -xshift)
5331       xmax = boxsize(3) + max(0._wp, -xshift)
5332       yshift = uvec(2) / uvec(1) * boxsize(1)
5333       ymin = min(0._wp, -yshift)
5334       ymax = boxsize(2) + max(0._wp, -yshift)
5335
5336       transp = 0._wp
5337       DO i = 1, resol
5338          xorig = xmin + (xmax-xmin) * (i-.5_wp) / resol
5339          DO j = 1, resol
5340             yorig = ymin + (ymax-ymin) * (j-.5_wp) / resol
5341
5342             dz1 = 0._wp
5343             dz2 = boxsize(1)/uvec(1)
5344
5345             IF ( uvec(2) > 0._wp )  THEN
5346                dy1 = -yorig             / uvec(2) !< crossing with y=0
5347                dy2 = (boxsize(2)-yorig) / uvec(2) !< crossing with y=boxsize(2)
5348             ELSE !uvec(2)==0
5349                dy1 = -huge(1._wp)
5350                dy2 = huge(1._wp)
5351             ENDIF
5352
5353             IF ( uvec(3) > 0._wp )  THEN
5354                dx1 = -xorig             / uvec(3) !< crossing with x=0
5355                dx2 = (boxsize(3)-xorig) / uvec(3) !< crossing with x=boxsize(3)
5356             ELSE !uvec(3)==0
5357                dx1 = -huge(1._wp)
5358                dx2 = huge(1._wp)
5359             ENDIF
5360
5361             crdist = max(0._wp, (min(dz2, dy2, dx2) - max(dz1, dy1, dx1)))
5362             transp = transp + exp(-ext_coef * dens * crdist)
5363          ENDDO
5364       ENDDO
5365       transp = transp / resol**2
5366       area = (boxsize(3)+xshift)*(boxsize(2)+yshift)
5367       absorb = 1._wp - transp
5368
5369    END SUBROUTINE box_absorb
5370
5371!------------------------------------------------------------------------------!
5372! Description:
5373! ------------
5374!> This subroutine splits direct and diffusion dw radiation
5375!> It sould not be called in case the radiation model already does it
5376!> It follows <CITATION>
5377!------------------------------------------------------------------------------!
5378    SUBROUTINE calc_diffusion_radiation 
5379   
5380        REAL(wp), PARAMETER                          :: lowest_solarUp = 0.1_wp  !< limit the sun elevation to protect stability of the calculation
5381        INTEGER(iwp)                                 :: i, j
5382        REAL(wp)                                     ::  year_angle              !< angle
5383        REAL(wp)                                     ::  etr                     !< extraterestrial radiation
5384        REAL(wp)                                     ::  corrected_solarUp       !< corrected solar up radiation
5385        REAL(wp)                                     ::  horizontalETR           !< horizontal extraterestrial radiation
5386        REAL(wp)                                     ::  clearnessIndex          !< clearness index
5387        REAL(wp)                                     ::  diff_frac               !< diffusion fraction of the radiation
5388
5389       
5390!--     Calculate current day and time based on the initial values and simulation time
5391        year_angle = ( (day_of_year_init * 86400) + time_utc_init              &
5392                        + time_since_reference_point )  * d_seconds_year       &
5393                        * 2.0_wp * pi
5394       
5395        etr = solar_constant * (1.00011_wp +                                   &
5396                          0.034221_wp * cos(year_angle) +                      &
5397                          0.001280_wp * sin(year_angle) +                      &
5398                          0.000719_wp * cos(2.0_wp * year_angle) +             &
5399                          0.000077_wp * sin(2.0_wp * year_angle))
5400       
5401!--   
5402!--     Under a very low angle, we keep extraterestrial radiation at
5403!--     the last small value, therefore the clearness index will be pushed
5404!--     towards 0 while keeping full continuity.
5405!--   
5406        IF ( zenith(0) <= lowest_solarUp )  THEN
5407            corrected_solarUp = lowest_solarUp
5408        ELSE
5409            corrected_solarUp = zenith(0)
5410        ENDIF
5411       
5412        horizontalETR = etr * corrected_solarUp
5413       
5414        DO i = nxl, nxr
5415            DO j = nys, nyn
5416                clearnessIndex = rad_sw_in(0,j,i) / horizontalETR
5417                diff_frac = 1.0_wp / (1.0_wp + exp(-5.0033_wp + 8.6025_wp * clearnessIndex))
5418                rad_sw_in_diff(j,i) = rad_sw_in(0,j,i) * diff_frac
5419                rad_sw_in_dir(j,i)  = rad_sw_in(0,j,i) * (1.0_wp - diff_frac)
5420                rad_lw_in_diff(j,i) = rad_lw_in(0,j,i)
5421            ENDDO
5422        ENDDO
5423       
5424    END SUBROUTINE calc_diffusion_radiation
5425
5426
5427 END SUBROUTINE radiation_interaction
5428   
5429!------------------------------------------------------------------------------!
5430! Description:
5431! ------------
5432!> This subroutine initializes structures needed for radiative transfer
5433!> model. This model calculates transformation processes of the
5434!> radiation inside urban and land canopy layer. The module includes also
5435!> the interaction of the radiation with the resolved plant canopy.
5436!>
5437!> For more info. see Resler et al. 2017
5438!>
5439!> The new version 2.0 was radically rewriten, the discretization scheme
5440!> has been changed. This new version significantly improves effectivity
5441!> of the paralelization and the scalability of the model.
5442!>
5443!------------------------------------------------------------------------------!
5444    SUBROUTINE radiation_interaction_init
5445
5446       USE control_parameters,                                                 &
5447           ONLY:  dz_stretch_level_start
5448           
5449       USE netcdf_data_input_mod,                                              &
5450           ONLY:  leaf_area_density_f
5451
5452       USE plant_canopy_model_mod,                                             &
5453           ONLY:  pch_index, lad_s
5454
5455       IMPLICIT NONE
5456
5457       INTEGER(iwp) :: i, j, k, l, m
5458       INTEGER(iwp) :: k_topo     !< vertical index indicating topography top for given (j,i)
5459       INTEGER(iwp) :: nzptl, nzubl, nzutl, isurf, ipcgb, imrt
5460       REAL(wp)     :: mrl
5461#if defined( __parallel )
5462       INTEGER(iwp), DIMENSION(:), POINTER       ::  gridsurf_rma   !< fortran pointer, but lower bounds are 1
5463       TYPE(c_ptr)                               ::  gridsurf_rma_p !< allocated c pointer
5464       INTEGER(iwp)                              ::  minfo          !< MPI RMA window info handle
5465#endif
5466
5467
5468       !INTEGER(iwp), DIMENSION(1:4,inorth_b:iwest_b)  ::  ijdb                               !< start and end of the local domain border coordinates (set in code)
5469       !LOGICAL, DIMENSION(inorth_b:iwest_b)           ::  isborder                           !< is PE on the border of the domain in four corresponding directions
5470
5471!
5472!--    Find nzub, nzut, nzu via wall_flag_0 array (nzb_s_inner will be
5473!--    removed later). The following contruct finds the lowest / largest index
5474!--    for any upward-facing wall (see bit 12).
5475       nzubl = MINVAL( get_topography_top_index( 's' ) )
5476       nzutl = MAXVAL( get_topography_top_index( 's' ) )
5477
5478       nzubl = MAX( nzubl, nzb )
5479
5480       IF ( plant_canopy )  THEN
5481!--        allocate needed arrays
5482           ALLOCATE( pct(nys:nyn,nxl:nxr) )
5483           ALLOCATE( pch(nys:nyn,nxl:nxr) )
5484
5485!--        calculate plant canopy height
5486           npcbl = 0
5487           pct   = 0
5488           pch   = 0
5489           DO i = nxl, nxr
5490               DO j = nys, nyn
5491!
5492!--                Find topography top index
5493                   k_topo = get_topography_top_index_ji( j, i, 's' )
5494
5495                   DO k = nzt+1, 0, -1
5496                       IF ( lad_s(k,j,i) /= 0.0_wp )  THEN
5497!--                        we are at the top of the pcs
5498                           pct(j,i) = k + k_topo
5499                           pch(j,i) = k
5500                           npcbl = npcbl + pch(j,i)
5501                           EXIT
5502                       ENDIF
5503                   ENDDO
5504               ENDDO
5505           ENDDO
5506
5507           nzutl = MAX( nzutl, MAXVAL( pct ) )
5508           nzptl = MAXVAL( pct )
5509!--        code of plant canopy model uses parameter pch_index
5510!--        we need to setup it here to right value
5511!--        (pch_index, lad_s and other arrays in PCM are defined flat)
5512           pch_index = MERGE( leaf_area_density_f%nz - 1, MAXVAL( pch ),       &
5513                              leaf_area_density_f%from_file )
5514
5515           prototype_lad = MAXVAL( lad_s ) * .9_wp  !< better be *1.0 if lad is either 0 or maxval(lad) everywhere
5516           IF ( prototype_lad <= 0._wp ) prototype_lad = .3_wp
5517           !WRITE(message_string, '(a,f6.3)') 'Precomputing effective box optical ' &
5518           !    // 'depth using prototype leaf area density = ', prototype_lad
5519           !CALL message('usm_init_urban_surface', 'PA0520', 0, 0, -1, 6, 0)
5520       ENDIF
5521
5522       nzutl = MIN( nzutl + nzut_free, nzt )
5523
5524#if defined( __parallel )
5525       CALL MPI_AllReduce(nzubl, nzub, 1, MPI_INTEGER, MPI_MIN, comm2d, ierr )
5526       IF ( ierr /= 0 ) THEN
5527           WRITE(9,*) 'Error MPI_AllReduce11:', ierr, nzubl, nzub
5528           FLUSH(9)
5529       ENDIF
5530       CALL MPI_AllReduce(nzutl, nzut, 1, MPI_INTEGER, MPI_MAX, comm2d, ierr )
5531       IF ( ierr /= 0 ) THEN
5532           WRITE(9,*) 'Error MPI_AllReduce12:', ierr, nzutl, nzut
5533           FLUSH(9)
5534       ENDIF
5535       CALL MPI_AllReduce(nzptl, nzpt, 1, MPI_INTEGER, MPI_MAX, comm2d, ierr )
5536       IF ( ierr /= 0 ) THEN
5537           WRITE(9,*) 'Error MPI_AllReduce13:', ierr, nzptl, nzpt
5538           FLUSH(9)
5539       ENDIF
5540#else
5541       nzub = nzubl
5542       nzut = nzutl
5543       nzpt = nzptl
5544#endif
5545!
5546!--    Stretching (non-uniform grid spacing) is not considered in the radiation
5547!--    model. Therefore, vertical stretching has to be applied above the area
5548!--    where the parts of the radiation model which assume constant grid spacing
5549!--    are active. ABS (...) is required because the default value of
5550!--    dz_stretch_level_start is -9999999.9_wp (negative).
5551       IF ( ABS( dz_stretch_level_start(1) ) <= zw(nzut) ) THEN
5552          WRITE( message_string, * ) 'The lowest level where vertical ',       &
5553                                     'stretching is applied have to be ',      &
5554                                     'greater than ', zw(nzut)
5555          CALL message( 'radiation_interaction_init', 'PA0496', 1, 2, 0, 6, 0 )
5556       ENDIF 
5557!
5558!--    global number of urban and plant layers
5559       nzu = nzut - nzub + 1
5560       nzp = nzpt - nzub + 1
5561!
5562!--    check max_raytracing_dist relative to urban surface layer height
5563       mrl = 2.0_wp * nzu * dz(1)
5564       IF ( max_raytracing_dist == -999.0_wp ) THEN
5565          max_raytracing_dist = mrl
5566       ENDIF
5567!        IF ( max_raytracing_dist <= mrl ) THEN
5568!           IF ( max_raytracing_dist /= -999.0_wp ) THEN
5569! !--          max_raytracing_dist too low
5570!              WRITE(message_string, '(a,f6.1)') 'Max_raytracing_dist too low, ' &
5571!                    // 'override to value ', mrl
5572!              CALL message('radiation_interaction_init', 'PA0521', 0, 0, -1, 6, 0)
5573!           ENDIF
5574!           max_raytracing_dist = mrl
5575!        ENDIF
5576!
5577!--    allocate urban surfaces grid
5578!--    calc number of surfaces in local proc
5579       CALL location_message( '    calculation of indices for surfaces', .TRUE. )
5580       nsurfl = 0
5581!
5582!--    Number of horizontal surfaces including land- and roof surfaces in both USM and LSM. Note that
5583!--    All horizontal surface elements are already counted in surface_mod.
5584       startland = 1
5585       nsurfl    = surf_usm_h%ns + surf_lsm_h%ns
5586       endland   = nsurfl
5587       nlands    = endland - startland + 1
5588
5589!
5590!--    Number of vertical surfaces in both USM and LSM. Note that all vertical surface elements are
5591!--    already counted in surface_mod.
5592       startwall = nsurfl+1
5593       DO  i = 0,3
5594          nsurfl = nsurfl + surf_usm_v(i)%ns + surf_lsm_v(i)%ns
5595       ENDDO
5596       endwall = nsurfl
5597       nwalls  = endwall - startwall + 1
5598
5599!--    fill gridpcbl and pcbl
5600       IF ( npcbl > 0 )  THEN
5601           ALLOCATE( pcbl(iz:ix, 1:npcbl) )
5602           ALLOCATE( gridpcbl(nzub:nzpt,nys:nyn,nxl:nxr) )
5603           pcbl = -1
5604           gridpcbl(:,:,:) = 0
5605           ipcgb = 0
5606           DO i = nxl, nxr
5607               DO j = nys, nyn
5608!
5609!--                Find topography top index
5610                   k_topo = get_topography_top_index_ji( j, i, 's' )
5611
5612                   DO k = k_topo + 1, pct(j,i)
5613                       ipcgb = ipcgb + 1
5614                       gridpcbl(k,j,i) = ipcgb
5615                       pcbl(:,ipcgb) = (/ k, j, i /)
5616                   ENDDO
5617               ENDDO
5618           ENDDO
5619           ALLOCATE( pcbinsw( 1:npcbl ) )
5620           ALLOCATE( pcbinswdir( 1:npcbl ) )
5621           ALLOCATE( pcbinswdif( 1:npcbl ) )
5622           ALLOCATE( pcbinlw( 1:npcbl ) )
5623       ENDIF
5624
5625!--    fill surfl (the ordering of local surfaces given by the following
5626!--    cycles must not be altered, certain file input routines may depend
5627!--    on it)
5628       ALLOCATE(surfl_l(5*nsurfl))  ! is it necessary to allocate it with (5,nsurfl)?
5629       surfl(1:5,1:nsurfl) => surfl_l(1:5*nsurfl)
5630       isurf = 0
5631       IF ( rad_angular_discretization )  THEN
5632!
5633!--       Allocate and fill the reverse indexing array gridsurf
5634#if defined( __parallel )
5635!
5636!--       raytrace_mpi_rma is asserted
5637
5638          CALL MPI_Info_create(minfo, ierr)
5639          IF ( ierr /= 0 ) THEN
5640              WRITE(9,*) 'Error MPI_Info_create1:', ierr
5641              FLUSH(9)
5642          ENDIF
5643          CALL MPI_Info_set(minfo, 'accumulate_ordering', '', ierr)
5644          IF ( ierr /= 0 ) THEN
5645              WRITE(9,*) 'Error MPI_Info_set1:', ierr
5646              FLUSH(9)
5647          ENDIF
5648          CALL MPI_Info_set(minfo, 'accumulate_ops', 'same_op', ierr)
5649          IF ( ierr /= 0 ) THEN
5650              WRITE(9,*) 'Error MPI_Info_set2:', ierr
5651              FLUSH(9)
5652          ENDIF
5653          CALL MPI_Info_set(minfo, 'same_size', 'true', ierr)
5654          IF ( ierr /= 0 ) THEN
5655              WRITE(9,*) 'Error MPI_Info_set3:', ierr
5656              FLUSH(9)
5657          ENDIF
5658          CALL MPI_Info_set(minfo, 'same_disp_unit', 'true', ierr)
5659          IF ( ierr /= 0 ) THEN
5660              WRITE(9,*) 'Error MPI_Info_set4:', ierr
5661              FLUSH(9)
5662          ENDIF
5663
5664          CALL MPI_Win_allocate(INT(STORAGE_SIZE(1_iwp)/8*nsurf_type_u*nzu*nny*nnx, &
5665                                    kind=MPI_ADDRESS_KIND),                         &
5666                                INT(STORAGE_SIZE(1_iwp)/8, kind=MPI_ADDRESS_KIND),  &
5667                                minfo, comm2d, gridsurf_rma_p, win_gridsurf, ierr)
5668          IF ( ierr /= 0 ) THEN
5669              WRITE(9,*) 'Error MPI_Win_allocate1:', ierr, &
5670                 INT(STORAGE_SIZE(1_iwp)/8*nsurf_type_u*nzu*nny*nnx,kind=MPI_ADDRESS_KIND), &
5671                 INT(STORAGE_SIZE(1_iwp)/8, kind=MPI_ADDRESS_KIND), win_gridsurf
5672              FLUSH(9)
5673          ENDIF
5674
5675          CALL MPI_Info_free(minfo, ierr)
5676          IF ( ierr /= 0 ) THEN
5677              WRITE(9,*) 'Error MPI_Info_free1:', ierr
5678              FLUSH(9)
5679          ENDIF
5680
5681!
5682!--       On Intel compilers, calling c_f_pointer to transform a C pointer
5683!--       directly to a multi-dimensional Fotran pointer leads to strange
5684!--       errors on dimension boundaries. However, transforming to a 1D
5685!--       pointer and then redirecting a multidimensional pointer to it works
5686!--       fine.
5687          CALL c_f_pointer(gridsurf_rma_p, gridsurf_rma, (/ nsurf_type_u*nzu*nny*nnx /))
5688          gridsurf(0:nsurf_type_u-1, nzub:nzut, nys:nyn, nxl:nxr) =>                &
5689                     gridsurf_rma(1:nsurf_type_u*nzu*nny*nnx)
5690#else
5691          ALLOCATE(gridsurf(0:nsurf_type_u-1,nzub:nzut,nys:nyn,nxl:nxr) )
5692#endif
5693          gridsurf(:,:,:,:) = -999
5694       ENDIF
5695
5696!--    add horizontal surface elements (land and urban surfaces)
5697!--    TODO: add urban overhanging surfaces (idown_u)
5698       DO i = nxl, nxr
5699           DO j = nys, nyn
5700              DO  m = surf_usm_h%start_index(j,i), surf_usm_h%end_index(j,i)
5701                 k = surf_usm_h%k(m)
5702                 isurf = isurf + 1
5703                 surfl(:,isurf) = (/iup_u,k,j,i,m/)
5704                 IF ( rad_angular_discretization ) THEN
5705                    gridsurf(iup_u,k,j,i) = isurf
5706                 ENDIF
5707              ENDDO
5708
5709              DO  m = surf_lsm_h%start_index(j,i), surf_lsm_h%end_index(j,i)
5710                 k = surf_lsm_h%k(m)
5711                 isurf = isurf + 1
5712                 surfl(:,isurf) = (/iup_l,k,j,i,m/)
5713                 IF ( rad_angular_discretization ) THEN
5714                    gridsurf(iup_u,k,j,i) = isurf
5715                 ENDIF
5716              ENDDO
5717
5718           ENDDO
5719       ENDDO
5720
5721!--    add vertical surface elements (land and urban surfaces)
5722!--    TODO: remove the hard coding of l = 0 to l = idirection
5723       DO i = nxl, nxr
5724           DO j = nys, nyn
5725              l = 0
5726              DO  m = surf_usm_v(l)%start_index(j,i), surf_usm_v(l)%end_index(j,i)
5727                 k = surf_usm_v(l)%k(m)
5728                 isurf = isurf + 1
5729                 surfl(:,isurf) = (/inorth_u,k,j,i,m/)
5730                 IF ( rad_angular_discretization ) THEN
5731                    gridsurf(inorth_u,k,j,i) = isurf
5732                 ENDIF
5733              ENDDO
5734              DO  m = surf_lsm_v(l)%start_index(j,i), surf_lsm_v(l)%end_index(j,i)
5735                 k = surf_lsm_v(l)%k(m)
5736                 isurf = isurf + 1
5737                 surfl(:,isurf) = (/inorth_l,k,j,i,m/)
5738                 IF ( rad_angular_discretization ) THEN
5739                    gridsurf(inorth_u,k,j,i) = isurf
5740                 ENDIF
5741              ENDDO
5742
5743              l = 1
5744              DO  m = surf_usm_v(l)%start_index(j,i), surf_usm_v(l)%end_index(j,i)
5745                 k = surf_usm_v(l)%k(m)
5746                 isurf = isurf + 1
5747                 surfl(:,isurf) = (/isouth_u,k,j,i,m/)
5748                 IF ( rad_angular_discretization ) THEN
5749                    gridsurf(isouth_u,k,j,i) = isurf
5750                 ENDIF
5751              ENDDO
5752              DO  m = surf_lsm_v(l)%start_index(j,i), surf_lsm_v(l)%end_index(j,i)
5753                 k = surf_lsm_v(l)%k(m)
5754                 isurf = isurf + 1
5755                 surfl(:,isurf) = (/isouth_l,k,j,i,m/)
5756                 IF ( rad_angular_discretization ) THEN
5757                    gridsurf(isouth_u,k,j,i) = isurf
5758                 ENDIF
5759              ENDDO
5760
5761              l = 2
5762              DO  m = surf_usm_v(l)%start_index(j,i), surf_usm_v(l)%end_index(j,i)
5763                 k = surf_usm_v(l)%k(m)
5764                 isurf = isurf + 1
5765                 surfl(:,isurf) = (/ieast_u,k,j,i,m/)
5766                 IF ( rad_angular_discretization ) THEN
5767                    gridsurf(ieast_u,k,j,i) = isurf
5768                 ENDIF
5769              ENDDO
5770              DO  m = surf_lsm_v(l)%start_index(j,i), surf_lsm_v(l)%end_index(j,i)
5771                 k = surf_lsm_v(l)%k(m)
5772                 isurf = isurf + 1
5773                 surfl(:,isurf) = (/ieast_l,k,j,i,m/)
5774                 IF ( rad_angular_discretization ) THEN
5775                    gridsurf(ieast_u,k,j,i) = isurf
5776                 ENDIF
5777              ENDDO
5778
5779              l = 3
5780              DO  m = surf_usm_v(l)%start_index(j,i), surf_usm_v(l)%end_index(j,i)
5781                 k = surf_usm_v(l)%k(m)
5782                 isurf = isurf + 1
5783                 surfl(:,isurf) = (/iwest_u,k,j,i,m/)
5784                 IF ( rad_angular_discretization ) THEN
5785                    gridsurf(iwest_u,k,j,i) = isurf
5786                 ENDIF
5787              ENDDO
5788              DO  m = surf_lsm_v(l)%start_index(j,i), surf_lsm_v(l)%end_index(j,i)
5789                 k = surf_lsm_v(l)%k(m)
5790                 isurf = isurf + 1
5791                 surfl(:,isurf) = (/iwest_l,k,j,i,m/)
5792                 IF ( rad_angular_discretization ) THEN
5793                    gridsurf(iwest_u,k,j,i) = isurf
5794                 ENDIF
5795              ENDDO
5796           ENDDO
5797       ENDDO
5798!
5799!--    Add local MRT boxes for specified number of levels
5800       nmrtbl = 0
5801       IF ( mrt_nlevels > 0 )  THEN
5802          DO  i = nxl, nxr
5803             DO  j = nys, nyn
5804                DO  m = surf_usm_h%start_index(j,i), surf_usm_h%end_index(j,i)
5805!
5806!--                Skip roof if requested
5807                   IF ( mrt_skip_roof  .AND.  surf_usm_h%isroof_surf(m) )  CYCLE
5808!
5809!--                Cycle over specified no of levels
5810                   nmrtbl = nmrtbl + mrt_nlevels
5811                ENDDO
5812!
5813!--             Dtto for LSM
5814                DO  m = surf_lsm_h%start_index(j,i), surf_lsm_h%end_index(j,i)
5815                   nmrtbl = nmrtbl + mrt_nlevels
5816                ENDDO
5817             ENDDO
5818          ENDDO
5819
5820          ALLOCATE( mrtbl(iz:ix,nmrtbl), mrtsky(nmrtbl), mrtskyt(nmrtbl), &
5821                    mrtinsw(nmrtbl), mrtinlw(nmrtbl), mrt(nmrtbl) )
5822
5823          imrt = 0
5824          DO  i = nxl, nxr
5825             DO  j = nys, nyn
5826                DO  m = surf_usm_h%start_index(j,i), surf_usm_h%end_index(j,i)
5827!
5828!--                Skip roof if requested
5829                   IF ( mrt_skip_roof  .AND.  surf_usm_h%isroof_surf(m) )  CYCLE
5830!
5831!--                Cycle over specified no of levels
5832                   l = surf_usm_h%k(m)
5833                   DO  k = l, l + mrt_nlevels - 1
5834                      imrt = imrt + 1
5835                      mrtbl(:,imrt) = (/k,j,i/)
5836                   ENDDO
5837                ENDDO
5838!
5839!--             Dtto for LSM
5840                DO  m = surf_lsm_h%start_index(j,i), surf_lsm_h%end_index(j,i)
5841                   l = surf_lsm_h%k(m)
5842                   DO  k = l, l + mrt_nlevels - 1
5843                      imrt = imrt + 1
5844                      mrtbl(:,imrt) = (/k,j,i/)
5845                   ENDDO
5846                ENDDO
5847             ENDDO
5848          ENDDO
5849       ENDIF
5850
5851!
5852!--    broadband albedo of the land, roof and wall surface
5853!--    for domain border and sky set artifically to 1.0
5854!--    what allows us to calculate heat flux leaving over
5855!--    side and top borders of the domain
5856       ALLOCATE ( albedo_surf(nsurfl) )
5857       albedo_surf = 1.0_wp
5858!
5859!--    Also allocate further array for emissivity with identical order of
5860!--    surface elements as radiation arrays.
5861       ALLOCATE ( emiss_surf(nsurfl)  )
5862
5863
5864!
5865!--    global array surf of indices of surfaces and displacement index array surfstart
5866       ALLOCATE(nsurfs(0:numprocs-1))
5867
5868#if defined( __parallel )
5869       CALL MPI_Allgather(nsurfl,1,MPI_INTEGER,nsurfs,1,MPI_INTEGER,comm2d,ierr)
5870       IF ( ierr /= 0 ) THEN
5871         WRITE(9,*) 'Error MPI_AllGather1:', ierr, nsurfl, nsurfs
5872         FLUSH(9)
5873     ENDIF
5874
5875#else
5876       nsurfs(0) = nsurfl
5877#endif
5878       ALLOCATE(surfstart(0:numprocs))
5879       k = 0
5880       DO i=0,numprocs-1
5881           surfstart(i) = k
5882           k = k+nsurfs(i)
5883       ENDDO
5884       surfstart(numprocs) = k
5885       nsurf = k
5886       ALLOCATE(surf_l(5*nsurf))
5887       surf(1:5,1:nsurf) => surf_l(1:5*nsurf)
5888
5889#if defined( __parallel )
5890       CALL MPI_AllGatherv(surfl_l, nsurfl*5, MPI_INTEGER, surf_l, nsurfs*5, &
5891           surfstart(0:numprocs-1)*5, MPI_INTEGER, comm2d, ierr)
5892       IF ( ierr /= 0 ) THEN
5893           WRITE(9,*) 'Error MPI_AllGatherv4:', ierr, SIZE(surfl_l), nsurfl*5, &
5894                      SIZE(surf_l), nsurfs*5, surfstart(0:numprocs-1)*5
5895           FLUSH(9)
5896       ENDIF
5897#else
5898       surf = surfl
5899#endif
5900
5901!--
5902!--    allocation of the arrays for direct and diffusion radiation
5903       CALL location_message( '    allocation of radiation arrays', .TRUE. )
5904!--    rad_sw_in, rad_lw_in are computed in radiation model,
5905!--    splitting of direct and diffusion part is done
5906!--    in calc_diffusion_radiation for now
5907
5908       ALLOCATE( rad_sw_in_dir(nysg:nyng,nxlg:nxrg) )
5909       ALLOCATE( rad_sw_in_diff(nysg:nyng,nxlg:nxrg) )
5910       ALLOCATE( rad_lw_in_diff(nysg:nyng,nxlg:nxrg) )
5911       rad_sw_in_dir  = 0.0_wp
5912       rad_sw_in_diff = 0.0_wp
5913       rad_lw_in_diff = 0.0_wp
5914
5915!--    allocate radiation arrays
5916       ALLOCATE( surfins(nsurfl) )
5917       ALLOCATE( surfinl(nsurfl) )
5918       ALLOCATE( surfinsw(nsurfl) )
5919       ALLOCATE( surfinlw(nsurfl) )
5920       ALLOCATE( surfinswdir(nsurfl) )
5921       ALLOCATE( surfinswdif(nsurfl) )
5922       ALLOCATE( surfinlwdif(nsurfl) )
5923       ALLOCATE( surfoutsl(nsurfl) )
5924       ALLOCATE( surfoutll(nsurfl) )
5925       ALLOCATE( surfoutsw(nsurfl) )
5926       ALLOCATE( surfoutlw(nsurfl) )
5927       ALLOCATE( surfouts(nsurf) )
5928       ALLOCATE( surfoutl(nsurf) )
5929       ALLOCATE( skyvf(nsurfl) )
5930       ALLOCATE( skyvft(nsurfl) )
5931       ALLOCATE( surfemitlwl(nsurfl) )
5932
5933!
5934!--    In case of average_radiation, aggregated surface albedo and emissivity,
5935!--    also set initial value for t_rad_urb.
5936!--    For now set an arbitrary initial value.
5937       IF ( average_radiation )  THEN
5938          albedo_urb = 0.1_wp
5939          emissivity_urb = 0.9_wp
5940          t_rad_urb = pt_surface
5941       ENDIF
5942
5943    END SUBROUTINE radiation_interaction_init
5944
5945!------------------------------------------------------------------------------!
5946! Description:
5947! ------------
5948!> Calculates shape view factors (SVF), plant sink canopy factors (PCSF),
5949!> sky-view factors, discretized path for direct solar radiation, MRT factors
5950!> and other preprocessed data needed for radiation_interaction.
5951!------------------------------------------------------------------------------!
5952    SUBROUTINE radiation_calc_svf
5953   
5954        IMPLICIT NONE
5955       
5956        INTEGER(iwp)                                  :: i, j, k, d, ip, jp
5957        INTEGER(iwp)                                  :: isvf, ksvf, icsf, kcsf, npcsfl, isvf_surflt, imrt, imrtf, ipcgb
5958        INTEGER(iwp)                                  :: sd, td
5959        INTEGER(iwp)                                  :: iaz, izn      !< azimuth, zenith counters
5960        INTEGER(iwp)                                  :: naz, nzn      !< azimuth, zenith num of steps
5961        REAL(wp)                                      :: az0, zn0      !< starting azimuth/zenith
5962        REAL(wp)                                      :: azs, zns      !< azimuth/zenith cycle step
5963        REAL(wp)                                      :: az1, az2      !< relative azimuth of section borders
5964        REAL(wp)                                      :: azmid         !< ray (center) azimuth
5965        REAL(wp), DIMENSION(2)                        :: yxdir         !< y,x *unit* vector of ray direction (in grid units)
5966        REAL(wp), DIMENSION(:), ALLOCATABLE           :: zdirs         !< directions in z (tangent of elevation)
5967        REAL(wp), DIMENSION(:), ALLOCATABLE           :: zbdry         !< zenith angle boundaries
5968        REAL(wp), DIMENSION(:), ALLOCATABLE           :: vffrac        !< view factor fractions for individual rays
5969        REAL(wp), DIMENSION(:), ALLOCATABLE           :: vffrac0       !< dtto (original values)
5970        REAL(wp), DIMENSION(:), ALLOCATABLE           :: ztransp       !< array of transparency in z steps
5971        INTEGER(iwp)                                  :: lowest_free_ray !< index into zdirs
5972        INTEGER(iwp), DIMENSION(:), ALLOCATABLE       :: itarget       !< face indices of detected obstacles
5973        INTEGER(iwp)                                  :: itarg0, itarg1
5974#if defined( __parallel )
5975#endif
5976
5977
5978
5979        REAL(wp),     DIMENSION(0:nsurf_type)         :: facearea
5980        INTEGER(iwp)                                  :: udim
5981        INTEGER(iwp), DIMENSION(:), ALLOCATABLE,TARGET:: nzterrl_l
5982        INTEGER(iwp), DIMENSION(:,:), POINTER         :: nzterrl
5983        REAL(wp),     DIMENSION(:), ALLOCATABLE,TARGET:: csflt_l, pcsflt_l
5984        REAL(wp),     DIMENSION(:,:), POINTER         :: csflt, pcsflt
5985        INTEGER(iwp), DIMENSION(:), ALLOCATABLE,TARGET:: kcsflt_l,kpcsflt_l
5986        INTEGER(iwp), DIMENSION(:,:), POINTER         :: kcsflt,kpcsflt
5987        INTEGER(iwp), DIMENSION(:), ALLOCATABLE       :: icsflt,dcsflt,ipcsflt,dpcsflt
5988        REAL(wp), DIMENSION(3)                        :: uv
5989        LOGICAL                                       :: visible
5990        REAL(wp), DIMENSION(3)                        :: sa, ta          !< real coordinates z,y,x of source and target
5991        REAL(wp)                                      :: transparency, rirrf, sqdist, svfsum
5992        INTEGER(iwp)                                  :: isurflt, isurfs, isurflt_prev
5993        INTEGER(idp)                                  :: ray_skip_maxdist, ray_skip_minval !< skipped raytracing counts
5994        INTEGER(iwp)                                  :: max_track_len !< maximum 2d track length
5995        INTEGER(iwp)                                  :: minfo
5996        REAL(wp), DIMENSION(:), POINTER               :: lad_s_rma       !< fortran 1D pointer
5997        TYPE(c_ptr)                                   :: lad_s_rma_p     !< allocated c pointer
5998#if defined( __parallel )
5999        INTEGER(kind=MPI_ADDRESS_KIND)                :: size_lad_rma
6000#endif
6001!   
6002        INTEGER(iwp), DIMENSION(0:svfnorm_report_num) :: svfnorm_counts
6003        CHARACTER(200)                                :: msg
6004
6005!--     calculation of the SVF
6006        CALL location_message( '    calculation of SVF and CSF', .TRUE. )
6007        CALL radiation_write_debug_log('Start calculation of SVF and CSF')
6008
6009!--     precalculate face areas for different face directions using normal vector
6010        DO d = 0, nsurf_type
6011            facearea(d) = 1._wp
6012            IF ( idir(d) == 0 ) facearea(d) = facearea(d) * dx
6013            IF ( jdir(d) == 0 ) facearea(d) = facearea(d) * dy
6014            IF ( kdir(d) == 0 ) facearea(d) = facearea(d) * dz(1)
6015        ENDDO
6016
6017!--     initialize variables and temporary arrays for calculation of svf and csf
6018        nsvfl  = 0
6019        ncsfl  = 0
6020        nsvfla = gasize
6021        msvf   = 1
6022        ALLOCATE( asvf1(nsvfla) )
6023        asvf => asvf1
6024        IF ( plant_canopy )  THEN
6025            ncsfla = gasize
6026            mcsf   = 1
6027            ALLOCATE( acsf1(ncsfla) )
6028            acsf => acsf1
6029        ENDIF
6030        nmrtf = 0
6031        IF ( mrt_nlevels > 0 )  THEN
6032           nmrtfa = gasize
6033           mmrtf = 1
6034           ALLOCATE ( amrtf1(nmrtfa) )
6035           amrtf => amrtf1
6036        ENDIF
6037        ray_skip_maxdist = 0
6038        ray_skip_minval = 0
6039       
6040!--     initialize temporary terrain and plant canopy height arrays (global 2D array!)
6041        ALLOCATE( nzterr(0:(nx+1)*(ny+1)-1) )
6042#if defined( __parallel )
6043        !ALLOCATE( nzterrl(nys:nyn,nxl:nxr) )
6044        ALLOCATE( nzterrl_l((nyn-nys+1)*(nxr-nxl+1)) )
6045        nzterrl(nys:nyn,nxl:nxr) => nzterrl_l(1:(nyn-nys+1)*(nxr-nxl+1))
6046        nzterrl = get_topography_top_index( 's' )
6047        CALL MPI_AllGather( nzterrl_l, nnx*nny, MPI_INTEGER, &
6048                            nzterr, nnx*nny, MPI_INTEGER, comm2d, ierr )
6049        IF ( ierr /= 0 ) THEN
6050            WRITE(9,*) 'Error MPI_AllGather1:', ierr, SIZE(nzterrl_l), nnx*nny, &
6051                       SIZE(nzterr), nnx*nny
6052            FLUSH(9)
6053        ENDIF
6054        DEALLOCATE(nzterrl_l)
6055#else
6056        nzterr = RESHAPE( get_topography_top_index( 's' ), (/(nx+1)*(ny+1)/) )
6057#endif
6058        IF ( plant_canopy )  THEN
6059            ALLOCATE( plantt(0:(nx+1)*(ny+1)-1) )
6060            maxboxesg = nx + ny + nzp + 1
6061            max_track_len = nx + ny + 1
6062!--         temporary arrays storing values for csf calculation during raytracing
6063            ALLOCATE( boxes(3, maxboxesg) )
6064            ALLOCATE( crlens(maxboxesg) )
6065
6066#if defined( __parallel )
6067            CALL MPI_AllGather( pct, nnx*nny, MPI_INTEGER, &
6068                                plantt, nnx*nny, MPI_INTEGER, comm2d, ierr )
6069            IF ( ierr /= 0 ) THEN
6070                WRITE(9,*) 'Error MPI_AllGather2:', ierr, SIZE(pct), nnx*nny, &
6071                           SIZE(plantt), nnx*nny
6072                FLUSH(9)
6073            ENDIF
6074
6075!--         temporary arrays storing values for csf calculation during raytracing
6076            ALLOCATE( lad_ip(maxboxesg) )
6077            ALLOCATE( lad_disp(maxboxesg) )
6078
6079            IF ( raytrace_mpi_rma )  THEN
6080                ALLOCATE( lad_s_ray(maxboxesg) )
6081               
6082                ! set conditions for RMA communication
6083                CALL MPI_Info_create(minfo, ierr)
6084                IF ( ierr /= 0 ) THEN
6085                    WRITE(9,*) 'Error MPI_Info_create2:', ierr
6086                    FLUSH(9)
6087                ENDIF
6088                CALL MPI_Info_set(minfo, 'accumulate_ordering', '', ierr)
6089                IF ( ierr /= 0 ) THEN
6090                    WRITE(9,*) 'Error MPI_Info_set5:', ierr
6091                    FLUSH(9)
6092                ENDIF
6093                CALL MPI_Info_set(minfo, 'accumulate_ops', 'same_op', ierr)
6094                IF ( ierr /= 0 ) THEN
6095                    WRITE(9,*) 'Error MPI_Info_set6:', ierr
6096                    FLUSH(9)
6097                ENDIF
6098                CALL MPI_Info_set(minfo, 'same_size', 'true', ierr)
6099                IF ( ierr /= 0 ) THEN
6100                    WRITE(9,*) 'Error MPI_Info_set7:', ierr
6101                    FLUSH(9)
6102                ENDIF
6103                CALL MPI_Info_set(minfo, 'same_disp_unit', 'true', ierr)
6104                IF ( ierr /= 0 ) THEN
6105                    WRITE(9,*) 'Error MPI_Info_set8:', ierr
6106                    FLUSH(9)
6107                ENDIF
6108
6109!--             Allocate and initialize the MPI RMA window
6110!--             must be in accordance with allocation of lad_s in plant_canopy_model
6111!--             optimization of memory should be done
6112!--             Argument X of function STORAGE_SIZE(X) needs arbitrary REAL(wp) value, set to 1.0_wp for now
6113                size_lad_rma = STORAGE_SIZE(1.0_wp)/8*nnx*nny*nzp
6114                CALL MPI_Win_allocate(size_lad_rma, STORAGE_SIZE(1.0_wp)/8, minfo, comm2d, &
6115                                        lad_s_rma_p, win_lad, ierr)
6116                IF ( ierr /= 0 ) THEN
6117                    WRITE(9,*) 'Error MPI_Win_allocate2:', ierr, size_lad_rma, &
6118                                STORAGE_SIZE(1.0_wp)/8, win_lad
6119                    FLUSH(9)
6120                ENDIF
6121                CALL c_f_pointer(lad_s_rma_p, lad_s_rma, (/ nzp*nny*nnx /))
6122                sub_lad(nzub:nzpt, nys:nyn, nxl:nxr) => lad_s_rma(1:nzp*nny*nnx)
6123            ELSE
6124                ALLOCATE(sub_lad(nzub:nzpt, nys:nyn, nxl:nxr))
6125            ENDIF
6126#else
6127            plantt = RESHAPE( pct(nys:nyn,nxl:nxr), (/(nx+1)*(ny+1)/) )
6128            ALLOCATE(sub_lad(nzub:nzpt, nys:nyn, nxl:nxr))
6129#endif
6130            plantt_max = MAXVAL(plantt)
6131            ALLOCATE( rt2_track(2, max_track_len), rt2_track_lad(nzub:plantt_max, max_track_len), &
6132                      rt2_track_dist(0:max_track_len), rt2_dist(plantt_max-nzub+2) )
6133
6134            sub_lad(:,:,:) = 0._wp
6135            DO i = nxl, nxr
6136                DO j = nys, nyn
6137                    k = get_topography_top_index_ji( j, i, 's' )
6138
6139                    sub_lad(k:nzpt, j, i) = lad_s(0:nzpt-k, j, i)
6140                ENDDO
6141            ENDDO
6142
6143#if defined( __parallel )
6144            IF ( raytrace_mpi_rma )  THEN
6145                CALL MPI_Info_free(minfo, ierr)
6146                IF ( ierr /= 0 ) THEN
6147                    WRITE(9,*) 'Error MPI_Info_free2:', ierr
6148                    FLUSH(9)
6149                ENDIF
6150                CALL MPI_Win_lock_all(0, win_lad, ierr)
6151                IF ( ierr /= 0 ) THEN
6152                    WRITE(9,*) 'Error MPI_Win_lock_all1:', ierr, win_lad
6153                    FLUSH(9)
6154                ENDIF
6155               
6156            ELSE
6157                ALLOCATE( sub_lad_g(0:(nx+1)*(ny+1)*nzp-1) )
6158                CALL MPI_AllGather( sub_lad, nnx*nny*nzp, MPI_REAL, &
6159                                    sub_lad_g, nnx*nny*nzp, MPI_REAL, comm2d, ierr )
6160                IF ( ierr /= 0 ) THEN
6161                    WRITE(9,*) 'Error MPI_AllGather3:', ierr, SIZE(sub_lad), &
6162                                nnx*nny*nzp, SIZE(sub_lad_g), nnx*nny*nzp
6163                    FLUSH(9)
6164                ENDIF
6165            ENDIF
6166#endif
6167        ENDIF
6168
6169!--     prepare the MPI_Win for collecting the surface indices
6170!--     from the reverse index arrays gridsurf from processors of target surfaces
6171#if defined( __parallel )
6172        IF ( rad_angular_discretization )  THEN
6173!
6174!--         raytrace_mpi_rma is asserted
6175            CALL MPI_Win_lock_all(0, win_gridsurf, ierr)
6176            IF ( ierr /= 0 ) THEN
6177                WRITE(9,*) 'Error MPI_Win_lock_all2:', ierr, win_gridsurf
6178                FLUSH(9)
6179            ENDIF
6180        ENDIF
6181#endif
6182
6183
6184        !--Directions opposite to face normals are not even calculated,
6185        !--they must be preset to 0
6186        !--
6187        dsitrans(:,:) = 0._wp
6188       
6189        DO isurflt = 1, nsurfl
6190!--         determine face centers
6191            td = surfl(id, isurflt)
6192            ta = (/ REAL(surfl(iz, isurflt), wp) - 0.5_wp * kdir(td),  &
6193                      REAL(surfl(iy, isurflt), wp) - 0.5_wp * jdir(td),  &
6194                      REAL(surfl(ix, isurflt), wp) - 0.5_wp * idir(td)  /)
6195
6196            !--Calculate sky view factor and raytrace DSI paths
6197            skyvf(isurflt) = 0._wp
6198            skyvft(isurflt) = 0._wp
6199
6200            !--Select a proper half-sphere for 2D raytracing
6201            SELECT CASE ( td )
6202               CASE ( iup_u, iup_l )
6203                  az0 = 0._wp
6204                  naz = raytrace_discrete_azims
6205                  azs = 2._wp * pi / REAL(naz, wp)
6206                  zn0 = 0._wp
6207                  nzn = raytrace_discrete_elevs / 2
6208                  zns = pi / 2._wp / REAL(nzn, wp)
6209               CASE ( isouth_u, isouth_l )
6210                  az0 = pi / 2._wp
6211                  naz = raytrace_discrete_azims / 2
6212                  azs = pi / REAL(naz, wp)
6213                  zn0 = 0._wp
6214                  nzn = raytrace_discrete_elevs
6215                  zns = pi / REAL(nzn, wp)
6216               CASE ( inorth_u, inorth_l )
6217                  az0 = - pi / 2._wp
6218                  naz = raytrace_discrete_azims / 2
6219                  azs = pi / REAL(naz, wp)
6220                  zn0 = 0._wp
6221                  nzn = raytrace_discrete_elevs
6222                  zns = pi / REAL(nzn, wp)
6223               CASE ( iwest_u, iwest_l )
6224                  az0 = pi
6225                  naz = raytrace_discrete_azims / 2
6226                  azs = pi / REAL(naz, wp)
6227                  zn0 = 0._wp
6228                  nzn = raytrace_discrete_elevs
6229                  zns = pi / REAL(nzn, wp)
6230               CASE ( ieast_u, ieast_l )
6231                  az0 = 0._wp
6232                  naz = raytrace_discrete_azims / 2
6233                  azs = pi / REAL(naz, wp)
6234                  zn0 = 0._wp
6235                  nzn = raytrace_discrete_elevs
6236                  zns = pi / REAL(nzn, wp)
6237               CASE DEFAULT
6238                  WRITE(message_string, *) 'ERROR: the surface type ', td,     &
6239                                           ' is not supported for calculating',&
6240                                           ' SVF'
6241                  CALL message( 'radiation_calc_svf', 'PA0488', 1, 2, 0, 6, 0 )
6242            END SELECT
6243
6244            ALLOCATE ( zdirs(1:nzn), zbdry(0:nzn), vffrac(1:nzn*naz), &
6245                       ztransp(1:nzn*naz), itarget(1:nzn*naz) )   !FIXME allocate itarget only
6246                                                                  !in case of rad_angular_discretization
6247
6248            itarg0 = 1
6249            itarg1 = nzn
6250            zdirs(:) = (/( TAN(pi/2 - (zn0+(REAL(izn,wp)-.5_wp)*zns)), izn=1, nzn )/)
6251            zbdry(:) = (/( zn0+REAL(izn,wp)*zns, izn=0, nzn )/)
6252            IF ( td == iup_u  .OR.  td == iup_l )  THEN
6253               vffrac(1:nzn) = (COS(2 * zbdry(0:nzn-1)) - COS(2 * zbdry(1:nzn))) / 2._wp / REAL(naz, wp)
6254!
6255!--            For horizontal target, vf fractions are constant per azimuth
6256               DO iaz = 1, naz-1
6257                  vffrac(iaz*nzn+1:(iaz+1)*nzn) = vffrac(1:nzn)
6258               ENDDO
6259!--            sum of whole vffrac equals 1, verified
6260            ENDIF
6261!
6262!--         Calculate sky-view factor and direct solar visibility using 2D raytracing
6263            DO iaz = 1, naz
6264               azmid = az0 + (REAL(iaz, wp) - .5_wp) * azs
6265               IF ( td /= iup_u  .AND.  td /= iup_l )  THEN
6266                  az2 = REAL(iaz, wp) * azs - pi/2._wp
6267                  az1 = az2 - azs
6268                  !TODO precalculate after 1st line
6269                  vffrac(itarg0:itarg1) = (SIN(az2) - SIN(az1))               &
6270                              * (zbdry(1:nzn) - zbdry(0:nzn-1)                &
6271                                 + SIN(zbdry(0:nzn-1))*COS(zbdry(0:nzn-1))    &
6272                                 - SIN(zbdry(1:nzn))*COS(zbdry(1:nzn)))       &
6273                              / (2._wp * pi)
6274!--               sum of whole vffrac equals 1, verified
6275               ENDIF
6276               yxdir = (/ COS(azmid), SIN(azmid) /)
6277               CALL raytrace_2d(ta, yxdir, nzn, zdirs,                        &
6278                                    surfstart(myid) + isurflt, facearea(td),  &
6279                                    vffrac(itarg0:itarg1), .TRUE., .TRUE.,    &
6280                                    .FALSE., lowest_free_ray,                 &
6281                                    ztransp(itarg0:itarg1),                   &
6282                                    itarget(itarg0:itarg1))   !FIXME unit vect in grid units + zdirs
6283                                                              !FIXME itarget available only in
6284                                                              !case of rad_angular_discretization
6285               skyvf(isurflt) = skyvf(isurflt) + &
6286                                SUM(vffrac(itarg0:itarg0+lowest_free_ray-1))
6287               skyvft(isurflt) = skyvft(isurflt) + &
6288                                 SUM(ztransp(itarg0:itarg0+lowest_free_ray-1) &
6289                                             * vffrac(itarg0:itarg0+lowest_free_ray-1))
6290 
6291!--            Save direct solar transparency
6292               j = MODULO(NINT(azmid/                                          &
6293                               (2._wp*pi)*raytrace_discrete_azims-.5_wp, iwp), &
6294                          raytrace_discrete_azims)
6295
6296               DO k = 1, raytrace_discrete_elevs/2
6297                  i = dsidir_rev(k-1, j)
6298                  IF ( i /= -1  .AND.  k <= lowest_free_ray )  &
6299                     dsitrans(isurflt, i) = ztransp(itarg0+k-1)
6300               ENDDO
6301
6302               !
6303               !--Advance itarget indices
6304               itarg0 = itarg1 + 1
6305               itarg1 = itarg1 + nzn
6306            ENDDO
6307
6308            IF ( rad_angular_discretization )  THEN
6309!--            sort itarget by face id
6310               CALL quicksort_itarget(itarget,vffrac,ztransp,1,nzn*naz)
6311!
6312!--            find the first valid position
6313               itarg0 = 1
6314               DO WHILE ( itarg0 <= nzn*naz )
6315                  IF ( itarget(itarg0) /= -1 )  EXIT
6316                  itarg0 = itarg0 + 1
6317               ENDDO
6318
6319               DO  i = itarg0, nzn*naz
6320!
6321!--               For duplicate values, only sum up vf fraction value
6322                  IF ( i < nzn*naz )  THEN
6323                     IF ( itarget(i+1) == itarget(i) )  THEN
6324                        vffrac(i+1) = vffrac(i+1) + vffrac(i)
6325                        CYCLE
6326                     ENDIF
6327                  ENDIF
6328!
6329!--               write to the svf array
6330                  nsvfl = nsvfl + 1
6331!--               check dimmension of asvf array and enlarge it if needed
6332                  IF ( nsvfla < nsvfl )  THEN
6333                     k = CEILING(REAL(nsvfla, kind=wp) * grow_factor)
6334                     IF ( msvf == 0 )  THEN
6335                        msvf = 1
6336                        ALLOCATE( asvf1(k) )
6337                        asvf => asvf1
6338                        asvf1(1:nsvfla) = asvf2
6339                        DEALLOCATE( asvf2 )
6340                     ELSE
6341                        msvf = 0
6342                        ALLOCATE( asvf2(k) )
6343                        asvf => asvf2
6344                        asvf2(1:nsvfla) = asvf1
6345                        DEALLOCATE( asvf1 )
6346                     ENDIF
6347
6348                     WRITE (msg,'(A,3I12)') 'Grow asvf:',nsvfl,nsvfla,k
6349                     CALL radiation_write_debug_log( msg )
6350                     
6351                     nsvfla = k
6352                  ENDIF
6353!--               write svf values into the array
6354                  asvf(nsvfl)%isurflt = isurflt
6355                  asvf(nsvfl)%isurfs = itarget(i)
6356                  asvf(nsvfl)%rsvf = vffrac(i)
6357                  asvf(nsvfl)%rtransp = ztransp(i)
6358               END DO
6359
6360            ENDIF ! rad_angular_discretization
6361
6362            DEALLOCATE ( zdirs, zbdry, vffrac, ztransp, itarget ) !FIXME itarget shall be allocated only
6363                                                                  !in case of rad_angular_discretization
6364!
6365!--         Following calculations only required for surface_reflections
6366            IF ( surface_reflections  .AND.  .NOT. rad_angular_discretization )  THEN
6367
6368               DO  isurfs = 1, nsurf
6369                  IF ( .NOT.  surface_facing(surfl(ix, isurflt), surfl(iy, isurflt), &
6370                     surfl(iz, isurflt), surfl(id, isurflt), &
6371                     surf(ix, isurfs), surf(iy, isurfs), &
6372                     surf(iz, isurfs), surf(id, isurfs)) )  THEN
6373                     CYCLE
6374                  ENDIF
6375                 
6376                  sd = surf(id, isurfs)
6377                  sa = (/ REAL(surf(iz, isurfs), wp) - 0.5_wp * kdir(sd),  &
6378                          REAL(surf(iy, isurfs), wp) - 0.5_wp * jdir(sd),  &
6379                          REAL(surf(ix, isurfs), wp) - 0.5_wp * idir(sd)  /)
6380
6381!--               unit vector source -> target
6382                  uv = (/ (ta(1)-sa(1))*dz(1), (ta(2)-sa(2))*dy, (ta(3)-sa(3))*dx /)
6383                  sqdist = SUM(uv(:)**2)
6384                  uv = uv / SQRT(sqdist)
6385
6386!--               reject raytracing above max distance
6387                  IF ( SQRT(sqdist) > max_raytracing_dist ) THEN
6388                     ray_skip_maxdist = ray_skip_maxdist + 1
6389                     CYCLE
6390                  ENDIF
6391                 
6392!--               irradiance factor (our unshaded shape view factor) = view factor per differential target area * source area
6393                  rirrf = dot_product((/ kdir(sd), jdir(sd), idir(sd) /), uv) & ! cosine of source normal and direction
6394                      * dot_product((/ kdir(td), jdir(td), idir(td) /), -uv) &  ! cosine of target normal and reverse direction
6395                      / (pi * sqdist) & ! square of distance between centers
6396                      * facearea(sd)
6397
6398!--               reject raytracing for potentially too small view factor values
6399                  IF ( rirrf < min_irrf_value ) THEN
6400                      ray_skip_minval = ray_skip_minval + 1
6401                      CYCLE
6402                  ENDIF
6403
6404!--               raytrace + process plant canopy sinks within
6405                  CALL raytrace(sa, ta, isurfs, rirrf, facearea(td), .TRUE., &
6406                                visible, transparency)
6407
6408                  IF ( .NOT.  visible ) CYCLE
6409                 ! rsvf = rirrf * transparency
6410
6411!--               write to the svf array
6412                  nsvfl = nsvfl + 1
6413!--               check dimmension of asvf array and enlarge it if needed
6414                  IF ( nsvfla < nsvfl )  THEN
6415                     k = CEILING(REAL(nsvfla, kind=wp) * grow_factor)
6416                     IF ( msvf == 0 )  THEN
6417                        msvf = 1
6418                        ALLOCATE( asvf1(k) )
6419                        asvf => asvf1
6420                        asvf1(1:nsvfla) = asvf2
6421                        DEALLOCATE( asvf2 )
6422                     ELSE
6423                        msvf = 0
6424                        ALLOCATE( asvf2(k) )
6425                        asvf => asvf2
6426                        asvf2(1:nsvfla) = asvf1
6427                        DEALLOCATE( asvf1 )
6428                     ENDIF
6429
6430                     WRITE(msg,'(A,3I12)') 'Grow asvf:',nsvfl,nsvfla,k
6431                     CALL radiation_write_debug_log( msg )
6432                     
6433                     nsvfla = k
6434                  ENDIF
6435!--               write svf values into the array
6436                  asvf(nsvfl)%isurflt = isurflt
6437                  asvf(nsvfl)%isurfs = isurfs
6438                  asvf(nsvfl)%rsvf = rirrf !we postopne multiplication by transparency
6439                  asvf(nsvfl)%rtransp = transparency !a.k.a. Direct Irradiance Factor
6440               ENDDO
6441            ENDIF
6442        ENDDO
6443
6444!--
6445!--     Raytrace to canopy boxes to fill dsitransc TODO optimize
6446        dsitransc(:,:) = 0._wp
6447        az0 = 0._wp
6448        naz = raytrace_discrete_azims
6449        azs = 2._wp * pi / REAL(naz, wp)
6450        zn0 = 0._wp
6451        nzn = raytrace_discrete_elevs / 2
6452        zns = pi / 2._wp / REAL(nzn, wp)
6453        ALLOCATE ( zdirs(1:nzn), vffrac(1:nzn), ztransp(1:nzn), &
6454               itarget(1:nzn) )
6455        zdirs(:) = (/( TAN(pi/2 - (zn0+(REAL(izn,wp)-.5_wp)*zns)), izn=1, nzn )/)
6456        vffrac(:) = 0._wp
6457
6458        DO  ipcgb = 1, npcbl
6459           ta = (/ REAL(pcbl(iz, ipcgb), wp),  &
6460                   REAL(pcbl(iy, ipcgb), wp),  &
6461                   REAL(pcbl(ix, ipcgb), wp) /)
6462!--        Calculate direct solar visibility using 2D raytracing
6463           DO  iaz = 1, naz
6464              azmid = az0 + (REAL(iaz, wp) - .5_wp) * azs
6465              yxdir = (/ COS(azmid), SIN(azmid) /)
6466              CALL raytrace_2d(ta, yxdir, nzn, zdirs,                                &
6467                                   -999, -999._wp, vffrac, .FALSE., .FALSE., .TRUE., &
6468                                   lowest_free_ray, ztransp, itarget) !FIXME unit vect in grid units + zdirs
6469
6470!--           Save direct solar transparency
6471              j = MODULO(NINT(azmid/                                         &
6472                             (2._wp*pi)*raytrace_discrete_azims-.5_wp, iwp), &
6473                         raytrace_discrete_azims)
6474              DO  k = 1, raytrace_discrete_elevs/2
6475                 i = dsidir_rev(k-1, j)
6476                 IF ( i /= -1  .AND.  k <= lowest_free_ray ) &
6477                    dsitransc(ipcgb, i) = ztransp(k)
6478              ENDDO
6479           ENDDO
6480        ENDDO
6481        DEALLOCATE ( zdirs, vffrac, ztransp, itarget )
6482!--
6483!--     Raytrace to MRT boxes
6484        IF ( nmrtbl > 0 )  THEN
6485           mrtdsit(:,:) = 0._wp
6486           mrtsky(:) = 0._wp
6487           mrtskyt(:) = 0._wp
6488           az0 = 0._wp
6489           naz = raytrace_discrete_azims
6490           azs = 2._wp * pi / REAL(naz, wp)
6491           zn0 = 0._wp
6492           nzn = raytrace_discrete_elevs
6493           zns = pi / REAL(nzn, wp)
6494           ALLOCATE ( zdirs(1:nzn), zbdry(0:nzn), vffrac(1:nzn*naz), vffrac0(1:nzn), &
6495                      ztransp(1:nzn*naz), itarget(1:nzn*naz) )   !FIXME allocate itarget only
6496                                                                 !in case of rad_angular_discretization
6497
6498           zdirs(:) = (/( TAN(pi/2 - (zn0+(REAL(izn,wp)-.5_wp)*zns)), izn=1, nzn )/)
6499           zbdry(:) = (/( zn0+REAL(izn,wp)*zns, izn=0, nzn )/)
6500           vffrac0(:) = (COS(zbdry(0:nzn-1)) - COS(zbdry(1:nzn))) / 2._wp / REAL(naz, wp)
6501
6502           DO  imrt = 1, nmrtbl
6503              ta = (/ REAL(mrtbl(iz, imrt), wp),  &
6504                      REAL(mrtbl(iy, imrt), wp),  &
6505                      REAL(mrtbl(ix, imrt), wp) /)
6506!
6507!--           vf fractions are constant per azimuth
6508              DO iaz = 0, naz-1
6509                 vffrac(iaz*nzn+1:(iaz+1)*nzn) = vffrac0(:)
6510              ENDDO
6511!--           sum of whole vffrac equals 1, verified
6512              itarg0 = 1
6513              itarg1 = nzn
6514!
6515!--           Calculate sky-view factor and direct solar visibility using 2D raytracing
6516              DO  iaz = 1, naz
6517                 azmid = az0 + (REAL(iaz, wp) - .5_wp) * azs
6518                 CALL raytrace_2d(ta, (/ COS(azmid), SIN(azmid) /), nzn, zdirs,  &
6519                                  -999, -999._wp, vffrac(itarg0:itarg1), .TRUE., &
6520                                  .FALSE., .TRUE., lowest_free_ray,              &
6521                                  ztransp(itarg0:itarg1),                        &
6522                                  itarget(itarg0:itarg1))   !FIXME unit vect in grid units + zdirs
6523                                                            !FIXME itarget available only in
6524                                                            !case of rad_angular_discretization
6525
6526!--              Sky view factors for MRT
6527                 mrtsky(imrt) = mrtsky(imrt) + &
6528                                  SUM(vffrac(itarg0:itarg0+lowest_free_ray-1))
6529                 mrtskyt(imrt) = mrtskyt(imrt) + &
6530                                   SUM(ztransp(itarg0:itarg0+lowest_free_ray-1) &
6531                                               * vffrac(itarg0:itarg0+lowest_free_ray-1))
6532!--              Direct solar transparency for MRT
6533                 j = MODULO(NINT(azmid/                                         &
6534                                (2._wp*pi)*raytrace_discrete_azims-.5_wp, iwp), &
6535                            raytrace_discrete_azims)
6536                 DO  k = 1, raytrace_discrete_elevs/2
6537                    i = dsidir_rev(k-1, j)
6538                    IF ( i /= -1  .AND.  k <= lowest_free_ray ) &
6539                       mrtdsit(imrt, i) = ztransp(itarg0+k-1)
6540                 ENDDO
6541!
6542!--              Advance itarget indices
6543                 itarg0 = itarg1 + 1
6544                 itarg1 = itarg1 + nzn
6545              ENDDO
6546
6547!--           sort itarget by face id
6548              CALL quicksort_itarget(itarget,vffrac,ztransp,1,nzn*naz)
6549!
6550!--           find the first valid position
6551              itarg0 = 1
6552              DO WHILE ( itarg0 <= nzn*naz )
6553                 IF ( itarget(itarg0) /= -1 )  EXIT
6554                 itarg0 = itarg0 + 1
6555              ENDDO
6556
6557              DO  i = itarg0, nzn*naz
6558!
6559!--              For duplicate values, only sum up vf fraction value
6560                 IF ( i < nzn*naz )  THEN
6561                    IF ( itarget(i+1) == itarget(i) )  THEN
6562                       vffrac(i+1) = vffrac(i+1) + vffrac(i)
6563                       CYCLE
6564                    ENDIF
6565                 ENDIF
6566!
6567!--              write to the mrtf array
6568                 nmrtf = nmrtf + 1
6569!--              check dimmension of mrtf array and enlarge it if needed
6570                 IF ( nmrtfa < nmrtf )  THEN
6571                    k = CEILING(REAL(nmrtfa, kind=wp) * grow_factor)
6572                    IF ( mmrtf == 0 )  THEN
6573                       mmrtf = 1
6574                       ALLOCATE( amrtf1(k) )
6575                       amrtf => amrtf1
6576                       amrtf1(1:nmrtfa) = amrtf2
6577                       DEALLOCATE( amrtf2 )
6578                    ELSE
6579                       mmrtf = 0
6580                       ALLOCATE( amrtf2(k) )
6581                       amrtf => amrtf2
6582                       amrtf2(1:nmrtfa) = amrtf1
6583                       DEALLOCATE( amrtf1 )
6584                    ENDIF
6585
6586                    WRITE (msg,'(A,3I12)') 'Grow amrtf:', nmrtf, nmrtfa, k
6587                    CALL radiation_write_debug_log( msg )
6588
6589                    nmrtfa = k
6590                 ENDIF
6591!--              write mrtf values into the array
6592                 amrtf(nmrtf)%isurflt = imrt
6593                 amrtf(nmrtf)%isurfs = itarget(i)
6594                 amrtf(nmrtf)%rsvf = vffrac(i)
6595                 amrtf(nmrtf)%rtransp = ztransp(i)
6596              ENDDO ! itarg
6597
6598           ENDDO ! imrt
6599           DEALLOCATE ( zdirs, zbdry, vffrac, vffrac0, ztransp, itarget )
6600!
6601!--        Move MRT factors to final arrays
6602           ALLOCATE ( mrtf(nmrtf), mrtft(nmrtf), mrtfsurf(2,nmrtf) )
6603           DO  imrtf = 1, nmrtf
6604              mrtf(imrtf) = amrtf(imrtf)%rsvf
6605              mrtft(imrtf) = amrtf(imrtf)%rsvf * amrtf(imrtf)%rtransp
6606              mrtfsurf(:,imrtf) = (/amrtf(imrtf)%isurflt, amrtf(imrtf)%isurfs /)
6607           ENDDO
6608           IF ( ALLOCATED(amrtf1) )  DEALLOCATE( amrtf1 )
6609           IF ( ALLOCATED(amrtf2) )  DEALLOCATE( amrtf2 )
6610        ENDIF ! nmrtbl > 0
6611
6612        IF ( rad_angular_discretization )  THEN
6613#if defined( __parallel )
6614!--        finalize MPI_RMA communication established to get global index of the surface from grid indices
6615!--        flush all MPI window pending requests
6616           CALL MPI_Win_flush_all(win_gridsurf, ierr)
6617           IF ( ierr /= 0 ) THEN
6618               WRITE(9,*) 'Error MPI_Win_flush_all1:', ierr, win_gridsurf
6619               FLUSH(9)
6620           ENDIF
6621!--        unlock MPI window
6622           CALL MPI_Win_unlock_all(win_gridsurf, ierr)
6623           IF ( ierr /= 0 ) THEN
6624               WRITE(9,*) 'Error MPI_Win_unlock_all1:', ierr, win_gridsurf
6625               FLUSH(9)
6626           ENDIF
6627!--        free MPI window
6628           CALL MPI_Win_free(win_gridsurf, ierr)
6629           IF ( ierr /= 0 ) THEN
6630               WRITE(9,*) 'Error MPI_Win_free1:', ierr, win_gridsurf
6631               FLUSH(9)
6632           ENDIF
6633#else
6634           DEALLOCATE ( gridsurf )
6635#endif
6636        ENDIF
6637
6638        CALL radiation_write_debug_log( 'End of calculation SVF' )
6639        WRITE(msg, *) 'Raytracing skipped for maximum distance of ', &
6640           max_raytracing_dist, ' m on ', ray_skip_maxdist, ' pairs.'
6641        CALL radiation_write_debug_log( msg )
6642        WRITE(msg, *) 'Raytracing skipped for minimum potential value of ', &
6643           min_irrf_value , ' on ', ray_skip_minval, ' pairs.'
6644        CALL radiation_write_debug_log( msg )
6645
6646        CALL location_message( '    waiting for completion of SVF and CSF calculation in all processes', .TRUE. )
6647!--     deallocate temporary global arrays
6648        DEALLOCATE(nzterr)
6649       
6650        IF ( plant_canopy )  THEN
6651!--         finalize mpi_rma communication and deallocate temporary arrays
6652#if defined( __parallel )
6653            IF ( raytrace_mpi_rma )  THEN
6654                CALL MPI_Win_flush_all(win_lad, ierr)
6655                IF ( ierr /= 0 ) THEN
6656                    WRITE(9,*) 'Error MPI_Win_flush_all2:', ierr, win_lad
6657                    FLUSH(9)
6658                ENDIF
6659!--             unlock MPI window
6660                CALL MPI_Win_unlock_all(win_lad, ierr)
6661                IF ( ierr /= 0 ) THEN
6662                    WRITE(9,*) 'Error MPI_Win_unlock_all2:', ierr, win_lad
6663                    FLUSH(9)
6664                ENDIF
6665!--             free MPI window
6666                CALL MPI_Win_free(win_lad, ierr)
6667                IF ( ierr /= 0 ) THEN
6668                    WRITE(9,*) 'Error MPI_Win_free2:', ierr, win_lad
6669                    FLUSH(9)
6670                ENDIF
6671!--             deallocate temporary arrays storing values for csf calculation during raytracing
6672                DEALLOCATE( lad_s_ray )
6673!--             sub_lad is the pointer to lad_s_rma in case of raytrace_mpi_rma
6674!--             and must not be deallocated here
6675            ELSE
6676                DEALLOCATE(sub_lad)
6677                DEALLOCATE(sub_lad_g)
6678            ENDIF
6679#else
6680            DEALLOCATE(sub_lad)
6681#endif
6682            DEALLOCATE( boxes )
6683            DEALLOCATE( crlens )
6684            DEALLOCATE( plantt )
6685            DEALLOCATE( rt2_track, rt2_track_lad, rt2_track_dist, rt2_dist )
6686        ENDIF
6687
6688        CALL location_message( '    calculation of the complete SVF array', .TRUE. )
6689
6690        IF ( rad_angular_discretization )  THEN
6691           CALL radiation_write_debug_log( 'Load svf from the structure array to plain arrays' )
6692           ALLOCATE( svf(ndsvf,nsvfl) )
6693           ALLOCATE( svfsurf(idsvf,nsvfl) )
6694
6695           DO isvf = 1, nsvfl
6696               svf(:, isvf) = (/ asvf(isvf)%rsvf, asvf(isvf)%rtransp /)
6697               svfsurf(:, isvf) = (/ asvf(isvf)%isurflt, asvf(isvf)%isurfs /)
6698           ENDDO
6699        ELSE
6700           CALL radiation_write_debug_log( 'Start SVF sort' )
6701!--        sort svf ( a version of quicksort )
6702           CALL quicksort_svf(asvf,1,nsvfl)
6703
6704           !< load svf from the structure array to plain arrays
6705           CALL radiation_write_debug_log( 'Load svf from the structure array to plain arrays' )
6706           ALLOCATE( svf(ndsvf,nsvfl) )
6707           ALLOCATE( svfsurf(idsvf,nsvfl) )
6708           svfnorm_counts(:) = 0._wp
6709           isurflt_prev = -1
6710           ksvf = 1
6711           svfsum = 0._wp
6712           DO isvf = 1, nsvfl
6713!--            normalize svf per target face
6714               IF ( asvf(ksvf)%isurflt /= isurflt_prev )  THEN
6715                   IF ( isurflt_prev /= -1  .AND.  svfsum /= 0._wp )  THEN
6716                       !< update histogram of logged svf normalization values
6717                       i = searchsorted(svfnorm_report_thresh, svfsum / (1._wp-skyvf(isurflt_prev)))
6718                       svfnorm_counts(i) = svfnorm_counts(i) + 1
6719
6720                       svf(1, isvf_surflt:isvf-1) = svf(1, isvf_surflt:isvf-1) / svfsum * (1._wp-skyvf(isurflt_prev))
6721                   ENDIF
6722                   isurflt_prev = asvf(ksvf)%isurflt
6723                   isvf_surflt = isvf
6724                   svfsum = asvf(ksvf)%rsvf !?? / asvf(ksvf)%rtransp
6725               ELSE
6726                   svfsum = svfsum + asvf(ksvf)%rsvf !?? / asvf(ksvf)%rtransp
6727               ENDIF
6728
6729               svf(:, isvf) = (/ asvf(ksvf)%rsvf, asvf(ksvf)%rtransp /)
6730               svfsurf(:, isvf) = (/ asvf(ksvf)%isurflt, asvf(ksvf)%isurfs /)
6731
6732!--            next element
6733               ksvf = ksvf + 1
6734           ENDDO
6735
6736           IF ( isurflt_prev /= -1  .AND.  svfsum /= 0._wp )  THEN
6737               i = searchsorted(svfnorm_report_thresh, svfsum / (1._wp-skyvf(isurflt_prev)))
6738               svfnorm_counts(i) = svfnorm_counts(i) + 1
6739
6740               svf(1, isvf_surflt:nsvfl) = svf(1, isvf_surflt:nsvfl) / svfsum * (1._wp-skyvf(isurflt_prev))
6741           ENDIF
6742           WRITE(9, *) 'SVF normalization histogram:', svfnorm_counts,  &
6743                       'on thresholds:', svfnorm_report_thresh(1:svfnorm_report_num), '(val < thresh <= val)'
6744           !TODO we should be able to deallocate skyvf, from now on we only need skyvft
6745        ENDIF ! rad_angular_discretization
6746
6747!--     deallocate temporary asvf array
6748!--     DEALLOCATE(asvf) - ifort has a problem with deallocation of allocatable target
6749!--     via pointing pointer - we need to test original targets
6750        IF ( ALLOCATED(asvf1) )  THEN
6751            DEALLOCATE(asvf1)
6752        ENDIF
6753        IF ( ALLOCATED(asvf2) )  THEN
6754            DEALLOCATE(asvf2)
6755        ENDIF
6756
6757        npcsfl = 0
6758        IF ( plant_canopy )  THEN
6759
6760            CALL location_message( '    calculation of the complete CSF array', .TRUE. )
6761            CALL radiation_write_debug_log( 'Calculation of the complete CSF array' )
6762!--         sort and merge csf for the last time, keeping the array size to minimum
6763            CALL merge_and_grow_csf(-1)
6764           
6765!--         aggregate csb among processors
6766!--         allocate necessary arrays
6767            udim = max(ncsfl,1)
6768            ALLOCATE( csflt_l(ndcsf*udim) )
6769            csflt(1:ndcsf,1:udim) => csflt_l(1:ndcsf*udim)
6770            ALLOCATE( kcsflt_l(kdcsf*udim) )
6771            kcsflt(1:kdcsf,1:udim) => kcsflt_l(1:kdcsf*udim)
6772            ALLOCATE( icsflt(0:numprocs-1) )
6773            ALLOCATE( dcsflt(0:numprocs-1) )
6774            ALLOCATE( ipcsflt(0:numprocs-1) )
6775            ALLOCATE( dpcsflt(0:numprocs-1) )
6776           
6777!--         fill out arrays of csf values and
6778!--         arrays of number of elements and displacements
6779!--         for particular precessors
6780            icsflt = 0
6781            dcsflt = 0
6782            ip = -1
6783            j = -1
6784            d = 0
6785            DO kcsf = 1, ncsfl
6786                j = j+1
6787                IF ( acsf(kcsf)%ip /= ip )  THEN
6788!--                 new block of the processor
6789!--                 number of elements of previous block
6790                    IF ( ip>=0) icsflt(ip) = j
6791                    d = d+j
6792!--                 blank blocks
6793                    DO jp = ip+1, acsf(kcsf)%ip-1
6794!--                     number of elements is zero, displacement is equal to previous
6795                        icsflt(jp) = 0
6796                        dcsflt(jp) = d
6797                    ENDDO
6798!--                 the actual block
6799                    ip = acsf(kcsf)%ip
6800                    dcsflt(ip) = d
6801                    j = 0
6802                ENDIF
6803!--             fill out real values of rsvf, rtransp
6804                csflt(1,kcsf) = acsf(kcsf)%rsvf
6805!--             fill out integer values of itz,ity,itx,isurfs
6806                kcsflt(1,kcsf) = acsf(kcsf)%itz
6807                kcsflt(2,kcsf) = acsf(kcsf)%ity
6808                kcsflt(3,kcsf) = acsf(kcsf)%itx
6809                kcsflt(4,kcsf) = acsf(kcsf)%isurfs
6810            ENDDO
6811!--         last blank blocks at the end of array
6812            j = j+1
6813            IF ( ip>=0 ) icsflt(ip) = j
6814            d = d+j
6815            DO jp = ip+1, numprocs-1
6816!--             number of elements is zero, displacement is equal to previous
6817                icsflt(jp) = 0
6818                dcsflt(jp) = d
6819            ENDDO
6820           
6821!--         deallocate temporary acsf array
6822!--         DEALLOCATE(acsf) - ifort has a problem with deallocation of allocatable target
6823!--         via pointing pointer - we need to test original targets
6824            IF ( ALLOCATED(acsf1) )  THEN
6825                DEALLOCATE(acsf1)
6826            ENDIF
6827            IF ( ALLOCATED(acsf2) )  THEN
6828                DEALLOCATE(acsf2)
6829            ENDIF
6830                   
6831#if defined( __parallel )
6832!--         scatter and gather the number of elements to and from all processor
6833!--         and calculate displacements
6834            CALL radiation_write_debug_log( 'Scatter and gather the number of elements to and from all processor' )
6835            CALL MPI_AlltoAll(icsflt,1,MPI_INTEGER,ipcsflt,1,MPI_INTEGER,comm2d, ierr)
6836            IF ( ierr /= 0 ) THEN
6837                WRITE(9,*) 'Error MPI_AlltoAll1:', ierr, SIZE(icsflt), SIZE(ipcsflt)
6838                FLUSH(9)
6839            ENDIF
6840
6841            npcsfl = SUM(ipcsflt)
6842            d = 0
6843            DO i = 0, numprocs-1
6844                dpcsflt(i) = d
6845                d = d + ipcsflt(i)
6846            ENDDO
6847
6848!--         exchange csf fields between processors
6849            CALL radiation_write_debug_log( 'Exchange csf fields between processors' )
6850            udim = max(npcsfl,1)
6851            ALLOCATE( pcsflt_l(ndcsf*udim) )
6852            pcsflt(1:ndcsf,1:udim) => pcsflt_l(1:ndcsf*udim)
6853            ALLOCATE( kpcsflt_l(kdcsf*udim) )
6854            kpcsflt(1:kdcsf,1:udim) => kpcsflt_l(1:kdcsf*udim)
6855            CALL MPI_AlltoAllv(csflt_l, ndcsf*icsflt, ndcsf*dcsflt, MPI_REAL, &
6856                pcsflt_l, ndcsf*ipcsflt, ndcsf*dpcsflt, MPI_REAL, comm2d, ierr)
6857            IF ( ierr /= 0 ) THEN
6858                WRITE(9,*) 'Error MPI_AlltoAllv1:', ierr, SIZE(ipcsflt), ndcsf*icsflt, &
6859                            ndcsf*dcsflt, SIZE(pcsflt_l),ndcsf*ipcsflt, ndcsf*dpcsflt
6860                FLUSH(9)
6861            ENDIF
6862
6863            CALL MPI_AlltoAllv(kcsflt_l, kdcsf*icsflt, kdcsf*dcsflt, MPI_INTEGER, &
6864                kpcsflt_l, kdcsf*ipcsflt, kdcsf*dpcsflt, MPI_INTEGER, comm2d, ierr)
6865            IF ( ierr /= 0 ) THEN
6866                WRITE(9,*) 'Error MPI_AlltoAllv2:', ierr, SIZE(kcsflt_l),kdcsf*icsflt, &
6867                           kdcsf*dcsflt, SIZE(kpcsflt_l), kdcsf*ipcsflt, kdcsf*dpcsflt
6868                FLUSH(9)
6869            ENDIF
6870           
6871#else
6872            npcsfl = ncsfl
6873            ALLOCATE( pcsflt(ndcsf,max(npcsfl,ndcsf)) )
6874            ALLOCATE( kpcsflt(kdcsf,max(npcsfl,kdcsf)) )
6875            pcsflt = csflt
6876            kpcsflt = kcsflt
6877#endif
6878
6879!--         deallocate temporary arrays
6880            DEALLOCATE( csflt_l )
6881            DEALLOCATE( kcsflt_l )
6882            DEALLOCATE( icsflt )
6883            DEALLOCATE( dcsflt )
6884            DEALLOCATE( ipcsflt )
6885            DEALLOCATE( dpcsflt )
6886
6887!--         sort csf ( a version of quicksort )
6888            CALL radiation_write_debug_log( 'Sort csf' )
6889            CALL quicksort_csf2(kpcsflt, pcsflt, 1, npcsfl)
6890
6891!--         aggregate canopy sink factor records with identical box & source
6892!--         againg across all values from all processors
6893            CALL radiation_write_debug_log( 'Aggregate canopy sink factor records with identical box' )
6894
6895            IF ( npcsfl > 0 )  THEN
6896                icsf = 1 !< reading index
6897                kcsf = 1 !< writing index
6898                DO while (icsf < npcsfl)
6899!--                 here kpcsf(kcsf) already has values from kpcsf(icsf)
6900                    IF ( kpcsflt(3,icsf) == kpcsflt(3,icsf+1)  .AND.  &
6901                         kpcsflt(2,icsf) == kpcsflt(2,icsf+1)  .AND.  &
6902                         kpcsflt(1,icsf) == kpcsflt(1,icsf+1)  .AND.  &
6903                         kpcsflt(4,icsf) == kpcsflt(4,icsf+1) )  THEN
6904
6905                        pcsflt(1,kcsf) = pcsflt(1,kcsf) + pcsflt(1,icsf+1)
6906
6907!--                     advance reading index, keep writing index
6908                        icsf = icsf + 1
6909                    ELSE
6910!--                     not identical, just advance and copy
6911                        icsf = icsf + 1
6912                        kcsf = kcsf + 1
6913                        kpcsflt(:,kcsf) = kpcsflt(:,icsf)
6914                        pcsflt(:,kcsf) = pcsflt(:,icsf)
6915                    ENDIF
6916                ENDDO
6917!--             last written item is now also the last item in valid part of array
6918                npcsfl = kcsf
6919            ENDIF
6920
6921            ncsfl = npcsfl
6922            IF ( ncsfl > 0 )  THEN
6923                ALLOCATE( csf(ndcsf,ncsfl) )
6924                ALLOCATE( csfsurf(idcsf,ncsfl) )
6925                DO icsf = 1, ncsfl
6926                    csf(:,icsf) = pcsflt(:,icsf)
6927                    csfsurf(1,icsf) =  gridpcbl(kpcsflt(1,icsf),kpcsflt(2,icsf),kpcsflt(3,icsf))
6928                    csfsurf(2,icsf) =  kpcsflt(4,icsf)
6929                ENDDO
6930            ENDIF
6931           
6932!--         deallocation of temporary arrays
6933            IF ( npcbl > 0 )  DEALLOCATE( gridpcbl )
6934            DEALLOCATE( pcsflt_l )
6935            DEALLOCATE( kpcsflt_l )
6936            CALL radiation_write_debug_log( 'End of aggregate csf' )
6937           
6938        ENDIF
6939
6940#if defined( __parallel )
6941        CALL MPI_BARRIER( comm2d, ierr )
6942#endif
6943        CALL radiation_write_debug_log( 'End of radiation_calc_svf (after mpi_barrier)' )
6944
6945        RETURN
6946       
6947!        WRITE( message_string, * )  &
6948!            'I/O error when processing shape view factors / ',  &
6949!            'plant canopy sink factors / direct irradiance factors.'
6950!        CALL message( 'init_urban_surface', 'PA0502', 2, 2, 0, 6, 0 )
6951       
6952    END SUBROUTINE radiation_calc_svf
6953
6954   
6955!------------------------------------------------------------------------------!
6956! Description:
6957! ------------
6958!> Raytracing for detecting obstacles and calculating compound canopy sink
6959!> factors. (A simple obstacle detection would only need to process faces in
6960!> 3 dimensions without any ordering.)
6961!> Assumtions:
6962!> -----------
6963!> 1. The ray always originates from a face midpoint (only one coordinate equals
6964!>    *.5, i.e. wall) and doesn't travel parallel to the surface (that would mean
6965!>    shape factor=0). Therefore, the ray may never travel exactly along a face
6966!>    or an edge.
6967!> 2. From grid bottom to urban surface top the grid has to be *equidistant*
6968!>    within each of the dimensions, including vertical (but the resolution
6969!>    doesn't need to be the same in all three dimensions).
6970!------------------------------------------------------------------------------!
6971    SUBROUTINE raytrace(src, targ, isrc, rirrf, atarg, create_csf, visible, transparency)
6972        IMPLICIT NONE
6973
6974        REAL(wp), DIMENSION(3), INTENT(in)     :: src, targ    !< real coordinates z,y,x
6975        INTEGER(iwp), INTENT(in)               :: isrc         !< index of source face for csf
6976        REAL(wp), INTENT(in)                   :: rirrf        !< irradiance factor for csf
6977        REAL(wp), INTENT(in)                   :: atarg        !< target surface area for csf
6978        LOGICAL, INTENT(in)                    :: create_csf   !< whether to generate new CSFs during raytracing
6979        LOGICAL, INTENT(out)                   :: visible
6980        REAL(wp), INTENT(out)                  :: transparency !< along whole path
6981        INTEGER(iwp)                           :: i, k, d
6982        INTEGER(iwp)                           :: seldim       !< dimension to be incremented
6983        INTEGER(iwp)                           :: ncsb         !< no of written plant canopy sinkboxes
6984        INTEGER(iwp)                           :: maxboxes     !< max no of gridboxes visited
6985        REAL(wp)                               :: distance     !< euclidean along path
6986        REAL(wp)                               :: crlen        !< length of gridbox crossing
6987        REAL(wp)                               :: lastdist     !< beginning of current crossing
6988        REAL(wp)                               :: nextdist     !< end of current crossing
6989        REAL(wp)                               :: realdist     !< distance in meters per unit distance
6990        REAL(wp)                               :: crmid        !< midpoint of crossing
6991        REAL(wp)                               :: cursink      !< sink factor for current canopy box
6992        REAL(wp), DIMENSION(3)                 :: delta        !< path vector
6993        REAL(wp), DIMENSION(3)                 :: uvect        !< unit vector
6994        REAL(wp), DIMENSION(3)                 :: dimnextdist  !< distance for each dimension increments
6995        INTEGER(iwp), DIMENSION(3)             :: box          !< gridbox being crossed
6996        INTEGER(iwp), DIMENSION(3)             :: dimnext      !< next dimension increments along path
6997        INTEGER(iwp), DIMENSION(3)             :: dimdelta     !< dimension direction = +- 1
6998        INTEGER(iwp)                           :: px, py       !< number of processors in x and y dir before
6999                                                               !< the processor in the question
7000        INTEGER(iwp)                           :: ip           !< number of processor where gridbox reside
7001        INTEGER(iwp)                           :: ig           !< 1D index of gridbox in global 2D array
7002        REAL(wp)                               :: lad_s_target !< recieved lad_s of particular grid box
7003
7004!
7005!--     Maximum number of gridboxes visited equals to maximum number of boundaries crossed in each dimension plus one. That's also
7006!--     the maximum number of plant canopy boxes written. We grow the acsf array accordingly using exponential factor.
7007        maxboxes = SUM(ABS(NINT(targ, iwp) - NINT(src, iwp))) + 1
7008        IF ( plant_canopy  .AND.  ncsfl + maxboxes > ncsfla )  THEN
7009!--         use this code for growing by fixed exponential increments (equivalent to case where ncsfl always increases by 1)
7010!--         k = CEILING(grow_factor ** real(CEILING(log(real(ncsfl + maxboxes, kind=wp)) &
7011!--                                                / log(grow_factor)), kind=wp))
7012!--         or use this code to simply always keep some extra space after growing
7013            k = CEILING(REAL(ncsfl + maxboxes, kind=wp) * grow_factor)
7014
7015            CALL merge_and_grow_csf(k)
7016        ENDIF
7017       
7018        transparency = 1._wp
7019        ncsb = 0
7020
7021        delta(:) = targ(:) - src(:)
7022        distance = SQRT(SUM(delta(:)**2))
7023        IF ( distance == 0._wp )  THEN
7024            visible = .TRUE.
7025            RETURN
7026        ENDIF
7027        uvect(:) = delta(:) / distance
7028        realdist = SQRT(SUM( (uvect(:)*(/dz(1),dy,dx/))**2 ))
7029
7030        lastdist = 0._wp
7031
7032!--     Since all face coordinates have values *.5 and we'd like to use
7033!--     integers, all these have .5 added
7034        DO d = 1, 3
7035            IF ( uvect(d) == 0._wp )  THEN
7036                dimnext(d) = 999999999
7037                dimdelta(d) = 999999999
7038                dimnextdist(d) = 1.0E20_wp
7039            ELSE IF ( uvect(d) > 0._wp )  THEN
7040                dimnext(d) = CEILING(src(d) + .5_wp)
7041                dimdelta(d) = 1
7042                dimnextdist(d) = (dimnext(d) - .5_wp - src(d)) / uvect(d)
7043            ELSE
7044                dimnext(d) = FLOOR(src(d) + .5_wp)
7045                dimdelta(d) = -1
7046                dimnextdist(d) = (dimnext(d) - .5_wp - src(d)) / uvect(d)
7047            ENDIF
7048        ENDDO
7049
7050        DO
7051!--         along what dimension will the next wall crossing be?
7052            seldim = minloc(dimnextdist, 1)
7053            nextdist = dimnextdist(seldim)
7054            IF ( nextdist > distance ) nextdist = distance
7055
7056            crlen = nextdist - lastdist
7057            IF ( crlen > .001_wp )  THEN
7058                crmid = (lastdist + nextdist) * .5_wp
7059                box = NINT(src(:) + uvect(:) * crmid, iwp)
7060
7061!--             calculate index of the grid with global indices (box(2),box(3))
7062!--             in the array nzterr and plantt and id of the coresponding processor
7063                px = box(3)/nnx
7064                py = box(2)/nny
7065                ip = px*pdims(2)+py
7066                ig = ip*nnx*nny + (box(3)-px*nnx)*nny + box(2)-py*nny
7067                IF ( box(1) <= nzterr(ig) )  THEN
7068                    visible = .FALSE.
7069                    RETURN
7070                ENDIF
7071
7072                IF ( plant_canopy )  THEN
7073                    IF ( box(1) <= plantt(ig) )  THEN
7074                        ncsb = ncsb + 1
7075                        boxes(:,ncsb) = box
7076                        crlens(ncsb) = crlen
7077#if defined( __parallel )
7078                        lad_ip(ncsb) = ip
7079                        lad_disp(ncsb) = (box(3)-px*nnx)*(nny*nzp) + (box(2)-py*nny)*nzp + box(1)-nzub
7080#endif
7081                    ENDIF
7082                ENDIF
7083            ENDIF
7084
7085            IF ( nextdist >= distance ) EXIT
7086            lastdist = nextdist
7087            dimnext(seldim) = dimnext(seldim) + dimdelta(seldim)
7088            dimnextdist(seldim) = (dimnext(seldim) - .5_wp - src(seldim)) / uvect(seldim)
7089        ENDDO
7090       
7091        IF ( plant_canopy )  THEN
7092#if defined( __parallel )
7093            IF ( raytrace_mpi_rma )  THEN
7094!--             send requests for lad_s to appropriate processor
7095                CALL cpu_log( log_point_s(77), 'rad_rma_lad', 'start' )
7096                DO i = 1, ncsb
7097                    CALL MPI_Get(lad_s_ray(i), 1, MPI_REAL, lad_ip(i), lad_disp(i), &
7098                                 1, MPI_REAL, win_lad, ierr)
7099                    IF ( ierr /= 0 )  THEN
7100                        WRITE(9,*) 'Error MPI_Get1:', ierr, lad_s_ray(i), &
7101                                   lad_ip(i), lad_disp(i), win_lad
7102                        FLUSH(9)
7103                    ENDIF
7104                ENDDO
7105               
7106!--             wait for all pending local requests complete
7107                CALL MPI_Win_flush_local_all(win_lad, ierr)
7108                IF ( ierr /= 0 )  THEN
7109                    WRITE(9,*) 'Error MPI_Win_flush_local_all1:', ierr, win_lad
7110                    FLUSH(9)
7111                ENDIF
7112                CALL cpu_log( log_point_s(77), 'rad_rma_lad', 'stop' )
7113               
7114            ENDIF
7115#endif
7116
7117!--         calculate csf and transparency
7118            DO i = 1, ncsb
7119#if defined( __parallel )
7120                IF ( raytrace_mpi_rma )  THEN
7121                    lad_s_target = lad_s_ray(i)
7122                ELSE
7123                    lad_s_target = sub_lad_g(lad_ip(i)*nnx*nny*nzp + lad_disp(i))
7124                ENDIF
7125#else
7126                lad_s_target = sub_lad(boxes(1,i),boxes(2,i),boxes(3,i))
7127#endif
7128                cursink = 1._wp - exp(-ext_coef * lad_s_target * crlens(i)*realdist)
7129
7130                IF ( create_csf )  THEN
7131!--                 write svf values into the array
7132                    ncsfl = ncsfl + 1
7133                    acsf(ncsfl)%ip = lad_ip(i)
7134                    acsf(ncsfl)%itx = boxes(3,i)
7135                    acsf(ncsfl)%ity = boxes(2,i)
7136                    acsf(ncsfl)%itz = boxes(1,i)
7137                    acsf(ncsfl)%isurfs = isrc
7138                    acsf(ncsfl)%rsvf = cursink*transparency*rirrf*atarg
7139                ENDIF  !< create_csf
7140
7141                transparency = transparency * (1._wp - cursink)
7142               
7143            ENDDO
7144        ENDIF
7145       
7146        visible = .TRUE.
7147
7148    END SUBROUTINE raytrace
7149   
7150 
7151!------------------------------------------------------------------------------!
7152! Description:
7153! ------------
7154!> A new, more efficient version of ray tracing algorithm that processes a whole
7155!> arc instead of a single ray.
7156!>
7157!> In all comments, horizon means tangent of horizon angle, i.e.
7158!> vertical_delta / horizontal_distance
7159!------------------------------------------------------------------------------!
7160   SUBROUTINE raytrace_2d(origin, yxdir, nrays, zdirs, iorig, aorig, vffrac,  &
7161                              calc_svf, create_csf, skip_1st_pcb,             &
7162                              lowest_free_ray, transparency, itarget)
7163      IMPLICIT NONE
7164
7165      REAL(wp), DIMENSION(3), INTENT(IN)     ::  origin        !< z,y,x coordinates of ray origin
7166      REAL(wp), DIMENSION(2), INTENT(IN)     ::  yxdir         !< y,x *unit* vector of ray direction (in grid units)
7167      INTEGER(iwp)                           ::  nrays         !< number of rays (z directions) to raytrace
7168      REAL(wp), DIMENSION(nrays), INTENT(IN) ::  zdirs         !< list of z directions to raytrace (z/hdist, grid, zenith->nadir)
7169      INTEGER(iwp), INTENT(in)               ::  iorig         !< index of origin face for csf
7170      REAL(wp), INTENT(in)                   ::  aorig         !< origin face area for csf
7171      REAL(wp), DIMENSION(nrays), INTENT(in) ::  vffrac        !< view factor fractions of each ray for csf
7172      LOGICAL, INTENT(in)                    ::  calc_svf      !< whether to calculate SFV (identify obstacle surfaces)
7173      LOGICAL, INTENT(in)                    ::  create_csf    !< whether to create canopy sink factors
7174      LOGICAL, INTENT(in)                    ::  skip_1st_pcb  !< whether to skip first plant canopy box during raytracing
7175      INTEGER(iwp), INTENT(out)              ::  lowest_free_ray !< index into zdirs
7176      REAL(wp), DIMENSION(nrays), INTENT(OUT) ::  transparency !< transparencies of zdirs paths
7177      INTEGER(iwp), DIMENSION(nrays), INTENT(OUT) ::  itarget  !< global indices of target faces for zdirs
7178
7179      INTEGER(iwp), DIMENSION(nrays)         ::  target_procs
7180      REAL(wp)                               ::  horizon       !< highest horizon found after raytracing (z/hdist)
7181      INTEGER(iwp)                           ::  i, k, l, d
7182      INTEGER(iwp)                           ::  seldim       !< dimension to be incremented
7183      REAL(wp), DIMENSION(2)                 ::  yxorigin     !< horizontal copy of origin (y,x)
7184      REAL(wp)                               ::  distance     !< euclidean along path
7185      REAL(wp)                               ::  lastdist     !< beginning of current crossing
7186      REAL(wp)                               ::  nextdist     !< end of current crossing
7187      REAL(wp)                               ::  crmid        !< midpoint of crossing
7188      REAL(wp)                               ::  horz_entry   !< horizon at entry to column
7189      REAL(wp)                               ::  horz_exit    !< horizon at exit from column
7190      REAL(wp)                               ::  bdydim       !< boundary for current dimension
7191      REAL(wp), DIMENSION(2)                 ::  crossdist    !< distances to boundary for dimensions
7192      REAL(wp), DIMENSION(2)                 ::  dimnextdist  !< distance for each dimension increments
7193      INTEGER(iwp), DIMENSION(2)             ::  column       !< grid column being crossed
7194      INTEGER(iwp), DIMENSION(2)             ::  dimnext      !< next dimension increments along path
7195      INTEGER(iwp), DIMENSION(2)             ::  dimdelta     !< dimension direction = +- 1
7196      INTEGER(iwp)                           ::  px, py       !< number of processors in x and y dir before
7197                                                              !< the processor in the question
7198      INTEGER(iwp)                           ::  ip           !< number of processor where gridbox reside
7199      INTEGER(iwp)                           ::  ig           !< 1D index of gridbox in global 2D array
7200      INTEGER(iwp)                           ::  wcount       !< RMA window item count
7201      INTEGER(iwp)                           ::  maxboxes     !< max no of CSF created
7202      INTEGER(iwp)                           ::  nly          !< maximum  plant canopy height
7203      INTEGER(iwp)                           ::  ntrack
7204      REAL(wp)                               ::  zbottom, ztop !< urban surface boundary in real numbers
7205      REAL(wp)                               ::  zorig        !< z coordinate of ray column entry
7206      REAL(wp)                               ::  zexit        !< z coordinate of ray column exit
7207      REAL(wp)                               ::  qdist        !< ratio of real distance to z coord difference
7208      REAL(wp)                               ::  dxxyy        !< square of real horizontal distance
7209      REAL(wp)                               ::  curtrans     !< transparency of current PC box crossing
7210      INTEGER(iwp)                           ::  zb0
7211      INTEGER(iwp)                           ::  zb1
7212      INTEGER(iwp)                           ::  nz
7213      INTEGER(iwp)                           ::  iz
7214      INTEGER(iwp)                           ::  zsgn
7215      INTEGER(iwp)                           ::  lowest_lad   !< lowest column cell for which we need LAD
7216      INTEGER(iwp)                           ::  lastdir      !< wall direction before hitting this column
7217      INTEGER(iwp), DIMENSION(2)             ::  lastcolumn
7218
7219#if defined( __parallel )
7220      INTEGER(MPI_ADDRESS_KIND)              ::  wdisp        !< RMA window displacement
7221#endif
7222     
7223      yxorigin(:) = origin(2:3)
7224      transparency(:) = 1._wp !-- Pre-set the all rays to transparent before reducing
7225      horizon = -HUGE(1._wp)
7226      lowest_free_ray = nrays
7227      IF ( rad_angular_discretization  .AND.  calc_svf )  THEN
7228         ALLOCATE(target_surfl(nrays))
7229         target_surfl(:) = -1
7230         lastdir = -999
7231         lastcolumn(:) = -999
7232      ENDIF
7233
7234!--   Determine distance to boundary (in 2D xy)
7235      IF ( yxdir(1) > 0._wp )  THEN
7236         bdydim = ny + .5_wp !< north global boundary
7237         crossdist(1) = (bdydim - yxorigin(1)) / yxdir(1)
7238      ELSEIF ( yxdir(1) == 0._wp )  THEN
7239         crossdist(1) = HUGE(1._wp)
7240      ELSE
7241          bdydim = -.5_wp !< south global boundary
7242          crossdist(1) = (bdydim - yxorigin(1)) / yxdir(1)
7243      ENDIF
7244
7245      IF ( yxdir(2) >= 0._wp )  THEN
7246          bdydim = nx + .5_wp !< east global boundary
7247          crossdist(2) = (bdydim - yxorigin(2)) / yxdir(2)
7248      ELSEIF ( yxdir(2) == 0._wp )  THEN
7249         crossdist(2) = HUGE(1._wp)
7250      ELSE
7251          bdydim = -.5_wp !< west global boundary
7252          crossdist(2) = (bdydim - yxorigin(2)) / yxdir(2)
7253      ENDIF
7254      distance = minval(crossdist, 1)
7255
7256      IF ( plant_canopy )  THEN
7257         rt2_track_dist(0) = 0._wp
7258         rt2_track_lad(:,:) = 0._wp
7259         nly = plantt_max - nzub + 1
7260      ENDIF
7261
7262      lastdist = 0._wp
7263
7264!--   Since all face coordinates have values *.5 and we'd like to use
7265!--   integers, all these have .5 added
7266      DO  d = 1, 2
7267          IF ( yxdir(d) == 0._wp )  THEN
7268              dimnext(d) = HUGE(1_iwp)
7269              dimdelta(d) = HUGE(1_iwp)
7270              dimnextdist(d) = HUGE(1._wp)
7271          ELSE IF ( yxdir(d) > 0._wp )  THEN
7272              dimnext(d) = FLOOR(yxorigin(d) + .5_wp) + 1
7273              dimdelta(d) = 1
7274              dimnextdist(d) = (dimnext(d) - .5_wp - yxorigin(d)) / yxdir(d)
7275          ELSE
7276              dimnext(d) = CEILING(yxorigin(d) + .5_wp) - 1
7277              dimdelta(d) = -1
7278              dimnextdist(d) = (dimnext(d) - .5_wp - yxorigin(d)) / yxdir(d)
7279          ENDIF
7280      ENDDO
7281
7282      ntrack = 0
7283      DO
7284!--      along what dimension will the next wall crossing be?
7285         seldim = minloc(dimnextdist, 1)
7286         nextdist = dimnextdist(seldim)
7287         IF ( nextdist > distance )  nextdist = distance
7288
7289         IF ( nextdist > lastdist )  THEN
7290            ntrack = ntrack + 1
7291            crmid = (lastdist + nextdist) * .5_wp
7292            column = NINT(yxorigin(:) + yxdir(:) * crmid, iwp)
7293
7294!--         calculate index of the grid with global indices (column(1),column(2))
7295!--         in the array nzterr and plantt and id of the coresponding processor
7296            px = column(2)/nnx
7297            py = column(1)/nny
7298            ip = px*pdims(2)+py
7299            ig = ip*nnx*nny + (column(2)-px*nnx)*nny + column(1)-py*nny
7300
7301            IF ( lastdist == 0._wp )  THEN
7302               horz_entry = -HUGE(1._wp)
7303            ELSE
7304               horz_entry = (REAL(nzterr(ig), wp) + .5_wp - origin(1)) / lastdist
7305            ENDIF
7306            horz_exit = (REAL(nzterr(ig), wp) + .5_wp - origin(1)) / nextdist
7307
7308            IF ( rad_angular_discretization  .AND.  calc_svf )  THEN
7309!
7310!--            Identify vertical obstacles hit by rays in current column
7311               DO WHILE ( lowest_free_ray > 0 )
7312                  IF ( zdirs(lowest_free_ray) > horz_entry )  EXIT
7313!
7314!--               This may only happen after 1st column, so lastdir and lastcolumn are valid
7315                  CALL request_itarget(lastdir,                                         &
7316                        CEILING(-0.5_wp + origin(1) + zdirs(lowest_free_ray)*lastdist), &
7317                        lastcolumn(1), lastcolumn(2),                                   &
7318                        target_surfl(lowest_free_ray), target_procs(lowest_free_ray))
7319                  lowest_free_ray = lowest_free_ray - 1
7320               ENDDO
7321!
7322!--            Identify horizontal obstacles hit by rays in current column
7323               DO WHILE ( lowest_free_ray > 0 )
7324                  IF ( zdirs(lowest_free_ray) > horz_exit )  EXIT
7325                  CALL request_itarget(iup_u, nzterr(ig)+1, column(1), column(2), &
7326                                       target_surfl(lowest_free_ray),           &
7327                                       target_procs(lowest_free_ray))
7328                  lowest_free_ray = lowest_free_ray - 1
7329               ENDDO
7330            ENDIF
7331
7332            horizon = MAX(horizon, horz_entry, horz_exit)
7333
7334            IF ( plant_canopy )  THEN
7335               rt2_track(:, ntrack) = column(:)
7336               rt2_track_dist(ntrack) = nextdist
7337            ENDIF
7338         ENDIF
7339
7340         IF ( nextdist >= distance )  EXIT
7341
7342         IF ( rad_angular_discretization  .AND.  calc_svf )  THEN
7343!
7344!--         Save wall direction of coming building column (= this air column)
7345            IF ( seldim == 1 )  THEN
7346               IF ( dimdelta(seldim) == 1 )  THEN
7347                  lastdir = isouth_u
7348               ELSE
7349                  lastdir = inorth_u
7350               ENDIF
7351            ELSE
7352               IF ( dimdelta(seldim) == 1 )  THEN
7353                  lastdir = iwest_u
7354               ELSE
7355                  lastdir = ieast_u
7356               ENDIF
7357            ENDIF
7358            lastcolumn = column
7359         ENDIF
7360         lastdist = nextdist
7361         dimnext(seldim) = dimnext(seldim) + dimdelta(seldim)
7362         dimnextdist(seldim) = (dimnext(seldim) - .5_wp - yxorigin(seldim)) / yxdir(seldim)
7363      ENDDO
7364
7365      IF ( plant_canopy )  THEN
7366!--      Request LAD WHERE applicable
7367!--     
7368#if defined( __parallel )
7369         IF ( raytrace_mpi_rma )  THEN
7370!--         send requests for lad_s to appropriate processor
7371            !CALL cpu_log( log_point_s(77), 'usm_init_rma', 'start' )
7372            DO  i = 1, ntrack
7373               px = rt2_track(2,i)/nnx
7374               py = rt2_track(1,i)/nny
7375               ip = px*pdims(2)+py
7376               ig = ip*nnx*nny + (rt2_track(2,i)-px*nnx)*nny + rt2_track(1,i)-py*nny
7377
7378               IF ( rad_angular_discretization  .AND.  calc_svf )  THEN
7379!
7380!--               For fixed view resolution, we need plant canopy even for rays
7381!--               to opposing surfaces
7382                  lowest_lad = nzterr(ig) + 1
7383               ELSE
7384!
7385!--               We only need LAD for rays directed above horizon (to sky)
7386                  lowest_lad = CEILING( -0.5_wp + origin(1) +            &
7387                                    MIN( horizon * rt2_track_dist(i-1),  & ! entry
7388                                         horizon * rt2_track_dist(i)   ) ) ! exit
7389               ENDIF
7390!
7391!--            Skip asking for LAD where all plant canopy is under requested level
7392               IF ( plantt(ig) < lowest_lad )  CYCLE
7393
7394               wdisp = (rt2_track(2,i)-px*nnx)*(nny*nzp) + (rt2_track(1,i)-py*nny)*nzp + lowest_lad-nzub
7395               wcount = plantt(ig)-lowest_lad+1
7396               ! TODO send request ASAP - even during raytracing
7397               CALL MPI_Get(rt2_track_lad(lowest_lad:plantt(ig), i), wcount, MPI_REAL, ip,    &
7398                            wdisp, wcount, MPI_REAL, win_lad, ierr)
7399               IF ( ierr /= 0 )  THEN
7400                  WRITE(9,*) 'Error MPI_Get2:', ierr, rt2_track_lad(lowest_lad:plantt(ig), i), &
7401                             wcount, ip, wdisp, win_lad
7402                  FLUSH(9)
7403               ENDIF
7404            ENDDO
7405
7406!--         wait for all pending local requests complete
7407            ! TODO WAIT selectively for each column later when needed
7408            CALL MPI_Win_flush_local_all(win_lad, ierr)
7409            IF ( ierr /= 0 )  THEN
7410               WRITE(9,*) 'Error MPI_Win_flush_local_all2:', ierr, win_lad
7411               FLUSH(9)
7412            ENDIF
7413            !CALL cpu_log( log_point_s(77), 'usm_init_rma', 'stop' )
7414
7415         ELSE ! raytrace_mpi_rma = .F.
7416            DO  i = 1, ntrack
7417               px = rt2_track(2,i)/nnx
7418               py = rt2_track(1,i)/nny
7419               ip = px*pdims(2)+py
7420               ig = ip*nnx*nny*nzp + (rt2_track(2,i)-px*nnx)*(nny*nzp) + (rt2_track(1,i)-py*nny)*nzp
7421               rt2_track_lad(nzub:plantt_max, i) = sub_lad_g(ig:ig+nly-1)
7422            ENDDO
7423         ENDIF
7424#else
7425         DO  i = 1, ntrack
7426            rt2_track_lad(nzub:plantt_max, i) = sub_lad(rt2_track(1,i), rt2_track(2,i), nzub:plantt_max)
7427         ENDDO
7428#endif
7429      ENDIF ! plant_canopy
7430
7431      IF ( rad_angular_discretization  .AND.  calc_svf )  THEN
7432#if defined( __parallel )
7433!--      wait for all gridsurf requests to complete
7434         CALL MPI_Win_flush_local_all(win_gridsurf, ierr)
7435         IF ( ierr /= 0 )  THEN
7436            WRITE(9,*) 'Error MPI_Win_flush_local_all3:', ierr, win_gridsurf
7437            FLUSH(9)
7438         ENDIF
7439#endif
7440!
7441!--      recalculate local surf indices into global ones
7442         DO i = 1, nrays
7443            IF ( target_surfl(i) == -1 )  THEN
7444               itarget(i) = -1
7445            ELSE
7446               itarget(i) = target_surfl(i) + surfstart(target_procs(i))
7447            ENDIF
7448         ENDDO
7449         
7450         DEALLOCATE( target_surfl )
7451         
7452      ELSE
7453         itarget(:) = -1
7454      ENDIF ! rad_angular_discretization
7455
7456      IF ( plant_canopy )  THEN
7457!--      Skip the PCB around origin if requested (for MRT, the PCB might not be there)
7458!--     
7459         IF ( skip_1st_pcb  .AND.  NINT(origin(1)) <= plantt_max )  THEN
7460            rt2_track_lad(NINT(origin(1), iwp), 1) = 0._wp
7461         ENDIF
7462
7463!--      Assert that we have space allocated for CSFs
7464!--     
7465         maxboxes = (ntrack + MAX(CEILING(origin(1)-.5_wp) - nzub,          &
7466                                  nzpt - CEILING(origin(1)-.5_wp))) * nrays
7467         IF ( ncsfl + maxboxes > ncsfla )  THEN
7468!--         use this code for growing by fixed exponential increments (equivalent to case where ncsfl always increases by 1)
7469!--         k = CEILING(grow_factor ** real(CEILING(log(real(ncsfl + maxboxes, kind=wp)) &
7470!--                                                / log(grow_factor)), kind=wp))
7471!--         or use this code to simply always keep some extra space after growing
7472            k = CEILING(REAL(ncsfl + maxboxes, kind=wp) * grow_factor)
7473            CALL merge_and_grow_csf(k)
7474         ENDIF
7475
7476!--      Calculate transparencies and store new CSFs
7477!--     
7478         zbottom = REAL(nzub, wp) - .5_wp
7479         ztop = REAL(plantt_max, wp) + .5_wp
7480
7481!--      Reverse direction of radiation (face->sky), only when calc_svf
7482!--     
7483         IF ( calc_svf )  THEN
7484            DO  i = 1, ntrack ! for each column
7485               dxxyy = ((dy*yxdir(1))**2 + (dx*yxdir(2))**2) * (rt2_track_dist(i)-rt2_track_dist(i-1))**2
7486               px = rt2_track(2,i)/nnx
7487               py = rt2_track(1,i)/nny
7488               ip = px*pdims(2)+py
7489
7490               DO  k = 1, nrays ! for each ray
7491!
7492!--               NOTE 6778:
7493!--               With traditional svf discretization, CSFs under the horizon
7494!--               (i.e. for surface to surface radiation)  are created in
7495!--               raytrace(). With rad_angular_discretization, we must create
7496!--               CSFs under horizon only for one direction, otherwise we would
7497!--               have duplicate amount of energy. Although we could choose
7498!--               either of the two directions (they differ only by
7499!--               discretization error with no bias), we choose the the backward
7500!--               direction, because it tends to cumulate high canopy sink
7501!--               factors closer to raytrace origin, i.e. it should potentially
7502!--               cause less moiree.
7503                  IF ( .NOT. rad_angular_discretization )  THEN
7504                     IF ( zdirs(k) <= horizon )  CYCLE
7505                  ENDIF
7506
7507                  zorig = origin(1) + zdirs(k) * rt2_track_dist(i-1)
7508                  IF ( zorig <= zbottom  .OR.  zorig >= ztop )  CYCLE
7509
7510                  zsgn = INT(SIGN(1._wp, zdirs(k)), iwp)
7511                  rt2_dist(1) = 0._wp
7512                  IF ( zdirs(k) == 0._wp )  THEN ! ray is exactly horizontal
7513                     nz = 2
7514                     rt2_dist(nz) = SQRT(dxxyy)
7515                     iz = CEILING(-.5_wp + zorig, iwp)
7516                  ELSE
7517                     zexit = MIN(MAX(origin(1) + zdirs(k) * rt2_track_dist(i), zbottom), ztop)
7518
7519                     zb0 = FLOOR(  zorig * zsgn - .5_wp) + 1  ! because it must be greater than orig
7520                     zb1 = CEILING(zexit * zsgn - .5_wp) - 1  ! because it must be smaller than exit
7521                     nz = MAX(zb1 - zb0 + 3, 2)
7522                     rt2_dist(nz) = SQRT(((zexit-zorig)*dz(1))**2 + dxxyy)
7523                     qdist = rt2_dist(nz) / (zexit-zorig)
7524                     rt2_dist(2:nz-1) = (/( ((REAL(l, wp) + .5_wp) * zsgn - zorig) * qdist , l = zb0, zb1 )/)
7525                     iz = zb0 * zsgn
7526                  ENDIF
7527
7528                  DO  l = 2, nz
7529                     IF ( rt2_track_lad(iz, i) > 0._wp )  THEN
7530                        curtrans = exp(-ext_coef * rt2_track_lad(iz, i) * (rt2_dist(l)-rt2_dist(l-1)))
7531
7532                        IF ( create_csf )  THEN
7533                           ncsfl = ncsfl + 1
7534                           acsf(ncsfl)%ip = ip
7535                           acsf(ncsfl)%itx = rt2_track(2,i)
7536                           acsf(ncsfl)%ity = rt2_track(1,i)
7537                           acsf(ncsfl)%itz = iz
7538                           acsf(ncsfl)%isurfs = iorig
7539                           acsf(ncsfl)%rsvf = (1._wp - curtrans)*transparency(k)*aorig*vffrac(k)
7540                        ENDIF
7541
7542                        transparency(k) = transparency(k) * curtrans
7543                     ENDIF
7544                     iz = iz + zsgn
7545                  ENDDO ! l = 1, nz - 1
7546               ENDDO ! k = 1, nrays
7547            ENDDO ! i = 1, ntrack
7548
7549            transparency(1:lowest_free_ray) = 1._wp !-- Reset rays above horizon to transparent (see NOTE 6778)
7550         ENDIF
7551
7552!--      Forward direction of radiation (sky->face), always
7553!--     
7554         DO  i = ntrack, 1, -1 ! for each column backwards
7555            dxxyy = ((dy*yxdir(1))**2 + (dx*yxdir(2))**2) * (rt2_track_dist(i)-rt2_track_dist(i-1))**2
7556            px = rt2_track(2,i)/nnx
7557            py = rt2_track(1,i)/nny
7558            ip = px*pdims(2)+py
7559
7560            DO  k = 1, nrays ! for each ray
7561!
7562!--            See NOTE 6778 above
7563               IF ( zdirs(k) <= horizon )  CYCLE
7564
7565               zexit = origin(1) + zdirs(k) * rt2_track_dist(i-1)
7566               IF ( zexit <= zbottom  .OR.  zexit >= ztop )  CYCLE
7567
7568               zsgn = -INT(SIGN(1._wp, zdirs(k)), iwp)
7569               rt2_dist(1) = 0._wp
7570               IF ( zdirs(k) == 0._wp )  THEN ! ray is exactly horizontal
7571                  nz = 2
7572                  rt2_dist(nz) = SQRT(dxxyy)
7573                  iz = NINT(zexit, iwp)
7574               ELSE
7575                  zorig = MIN(MAX(origin(1) + zdirs(k) * rt2_track_dist(i), zbottom), ztop)
7576
7577                  zb0 = FLOOR(  zorig * zsgn - .5_wp) + 1  ! because it must be greater than orig
7578                  zb1 = CEILING(zexit * zsgn - .5_wp) - 1  ! because it must be smaller than exit
7579                  nz = MAX(zb1 - zb0 + 3, 2)
7580                  rt2_dist(nz) = SQRT(((zexit-zorig)*dz(1))**2 + dxxyy)
7581                  qdist = rt2_dist(nz) / (zexit-zorig)
7582                  rt2_dist(2:nz-1) = (/( ((REAL(l, wp) + .5_wp) * zsgn - zorig) * qdist , l = zb0, zb1 )/)
7583                  iz = zb0 * zsgn
7584               ENDIF
7585
7586               DO  l = 2, nz
7587                  IF ( rt2_track_lad(iz, i) > 0._wp )  THEN
7588                     curtrans = exp(-ext_coef * rt2_track_lad(iz, i) * (rt2_dist(l)-rt2_dist(l-1)))
7589
7590                     IF ( create_csf )  THEN
7591                        ncsfl = ncsfl + 1
7592                        acsf(ncsfl)%ip = ip
7593                        acsf(ncsfl)%itx = rt2_track(2,i)
7594                        acsf(ncsfl)%ity = rt2_track(1,i)
7595                        acsf(ncsfl)%itz = iz
7596                        acsf(ncsfl)%isurfs = itarget(k) !if above horizon, then itarget(k)==-1, which
7597                                                        !is also a special ID indicating sky
7598                        acsf(ncsfl)%rsvf = (1._wp - curtrans)*transparency(k)*aorig*vffrac(k)
7599                     ENDIF  ! create_csf
7600
7601                     transparency(k) = transparency(k) * curtrans
7602                  ENDIF
7603                  iz = iz + zsgn
7604               ENDDO ! l = 1, nz - 1
7605            ENDDO ! k = 1, nrays
7606         ENDDO ! i = 1, ntrack
7607      ENDIF ! plant_canopy
7608
7609      IF ( .NOT. (rad_angular_discretization  .AND.  calc_svf) )  THEN
7610!
7611!--      Just update lowest_free_ray according to horizon
7612         DO WHILE ( lowest_free_ray > 0 )
7613            IF ( zdirs(lowest_free_ray) > horizon )  EXIT
7614            lowest_free_ray = lowest_free_ray - 1
7615         ENDDO
7616      ENDIF
7617
7618   CONTAINS
7619      SUBROUTINE request_itarget(d, z, y, x, isurfl, iproc)
7620         INTEGER(iwp), INTENT(in)            ::  d, z, y, x
7621         INTEGER(iwp), TARGET, INTENT(out)   ::  isurfl
7622         INTEGER(iwp), INTENT(out)           ::  iproc
7623         INTEGER(kind=MPI_ADDRESS_KIND)      ::  target_displ  !< index of the grid in the local gridsurf array
7624         INTEGER(iwp)                        ::  px, py        !< number of processors in x and y direction
7625                                                               !< before the processor in the question
7626
7627!--      calculate target processor and index in the remote local target gridsurf array
7628         px = x/nnx
7629         py = y/nny
7630         iproc = px*pdims(2)+py
7631         target_displ = ((x-px*nnx)*nny + y-py*nny)*nzu*nsurf_type_u + (z-nzub)*nsurf_type_u + d
7632
7633#if defined( __parallel )
7634!--      send MPI_Get request to obtain index target_surfl(i)
7635         CALL MPI_Get(isurfl, 1, MPI_INTEGER, iproc, target_displ, &
7636                        1, MPI_INTEGER, win_gridsurf, ierr)
7637         IF ( ierr /= 0 )  THEN
7638            WRITE(9,*) 'Error MPI_Get3:', ierr, isurfl, iproc, target_displ, win_gridsurf
7639            FLUSH(9)
7640         ENDIF
7641#else
7642!--      set index target_surfl(i)
7643         isurfl = gridsurf(d,z,y,x)
7644#endif
7645      END SUBROUTINE request_itarget
7646
7647   END SUBROUTINE raytrace_2d
7648 
7649
7650!------------------------------------------------------------------------------!
7651!
7652! Description:
7653! ------------
7654!> Calculates apparent solar positions for all timesteps and stores discretized
7655!> positions.
7656!------------------------------------------------------------------------------!
7657   SUBROUTINE radiation_presimulate_solar_pos
7658      IMPLICIT NONE
7659
7660      INTEGER(iwp)                              ::  it, i, j
7661      REAL(wp)                                  ::  tsrp_prev
7662      REAL(wp), DIMENSION(:,:), ALLOCATABLE     ::  dsidir_tmp       !< dsidir_tmp[:,i] = unit vector of i-th
7663                                                                     !< appreant solar direction
7664
7665      ALLOCATE ( dsidir_rev(0:raytrace_discrete_elevs/2-1,                 &
7666                            0:raytrace_discrete_azims-1) )
7667      dsidir_rev(:,:) = -1
7668      ALLOCATE ( dsidir_tmp(3,                                             &
7669                     raytrace_discrete_elevs/2*raytrace_discrete_azims) )
7670      ndsidir = 0
7671
7672!
7673!--   We will artificialy update time_since_reference_point and return to
7674!--   true value later
7675      tsrp_prev = time_since_reference_point
7676      sun_direction = .TRUE.
7677
7678!
7679!--   Process spinup time if configured
7680      IF ( spinup_time > 0._wp )  THEN
7681         DO  it = 0, CEILING(spinup_time / dt_spinup)
7682            time_since_reference_point = -spinup_time + REAL(it, wp) * dt_spinup
7683            CALL simulate_pos
7684         ENDDO
7685      ENDIF
7686!
7687!--   Process simulation time
7688      DO  it = 0, CEILING(( end_time - spinup_time ) / dt_radiation)
7689         time_since_reference_point = REAL(it, wp) * dt_radiation
7690         CALL simulate_pos
7691      ENDDO
7692
7693      time_since_reference_point = tsrp_prev
7694
7695!--   Allocate global vars which depend on ndsidir
7696      ALLOCATE ( dsidir ( 3, ndsidir ) )
7697      dsidir(:,:) = dsidir_tmp(:, 1:ndsidir)
7698      DEALLOCATE ( dsidir_tmp )
7699
7700      ALLOCATE ( dsitrans(nsurfl, ndsidir) )
7701      ALLOCATE ( dsitransc(npcbl, ndsidir) )
7702      IF ( nmrtbl > 0 )  ALLOCATE ( mrtdsit(nmrtbl, ndsidir) )
7703
7704      WRITE ( message_string, * ) 'Precalculated', ndsidir, ' solar positions', &
7705                                  'from', it, ' timesteps.'
7706      CALL message( 'radiation_presimulate_solar_pos', 'UI0013', 0, 0, 0, 6, 0 )
7707
7708      CONTAINS
7709
7710      !------------------------------------------------------------------------!
7711      ! Description:
7712      ! ------------
7713      !> Simuates a single position
7714      !------------------------------------------------------------------------!
7715      SUBROUTINE simulate_pos
7716         IMPLICIT NONE
7717!
7718!--      Update apparent solar position based on modified t_s_r_p
7719         CALL calc_zenith
7720         IF ( zenith(0) > 0 )  THEN
7721!--         
7722!--         Identify solar direction vector (discretized number) 1)
7723            i = MODULO(NINT(ATAN2(sun_dir_lon(0), sun_dir_lat(0))               &
7724                            / (2._wp*pi) * raytrace_discrete_azims-.5_wp, iwp), &
7725                       raytrace_discrete_azims)
7726            j = FLOOR(ACOS(zenith(0)) / pi * raytrace_discrete_elevs)
7727            IF ( dsidir_rev(j, i) == -1 )  THEN
7728               ndsidir = ndsidir + 1
7729               dsidir_tmp(:, ndsidir) =                                              &
7730                     (/ COS((REAL(j,wp)+.5_wp) * pi      / raytrace_discrete_elevs), &
7731                        SIN((REAL(j,wp)+.5_wp) * pi      / raytrace_discrete_elevs)  &
7732                      * COS((REAL(i,wp)+.5_wp) * 2_wp*pi / raytrace_discrete_azims), &
7733                        SIN((REAL(j,wp)+.5_wp) * pi      / raytrace_discrete_elevs)  &
7734                      * SIN((REAL(i,wp)+.5_wp) * 2_wp*pi / raytrace_discrete_azims) /)
7735               dsidir_rev(j, i) = ndsidir
7736            ENDIF
7737         ENDIF
7738      END SUBROUTINE simulate_pos
7739
7740   END SUBROUTINE radiation_presimulate_solar_pos
7741
7742
7743
7744!------------------------------------------------------------------------------!
7745! Description:
7746! ------------
7747!> Determines whether two faces are oriented towards each other. Since the
7748!> surfaces follow the gird box surfaces, it checks first whether the two surfaces
7749!> are directed in the same direction, then it checks if the two surfaces are
7750!> located in confronted direction but facing away from each other, e.g. <--| |-->
7751!------------------------------------------------------------------------------!
7752    PURE LOGICAL FUNCTION surface_facing(x, y, z, d, x2, y2, z2, d2)
7753        IMPLICIT NONE
7754        INTEGER(iwp),   INTENT(in)  :: x, y, z, d, x2, y2, z2, d2
7755     
7756        surface_facing = .FALSE.
7757
7758!-- first check: are the two surfaces directed in the same direction
7759        IF ( (d==iup_u  .OR.  d==iup_l )                             &
7760             .AND. (d2==iup_u  .OR. d2==iup_l) ) RETURN
7761        IF ( (d==isouth_u  .OR.  d==isouth_l ) &
7762             .AND.  (d2==isouth_u  .OR.  d2==isouth_l) ) RETURN
7763        IF ( (d==inorth_u  .OR.  d==inorth_l ) &
7764             .AND.  (d2==inorth_u  .OR.  d2==inorth_l) ) RETURN
7765        IF ( (d==iwest_u  .OR.  d==iwest_l )     &
7766             .AND.  (d2==iwest_u  .OR.  d2==iwest_l ) ) RETURN
7767        IF ( (d==ieast_u  .OR.  d==ieast_l )     &
7768             .AND.  (d2==ieast_u  .OR.  d2==ieast_l ) ) RETURN
7769
7770!-- second check: are surfaces facing away from each other
7771        SELECT CASE (d)
7772            CASE (iup_u, iup_l)                     !< upward facing surfaces
7773                IF ( z2 < z ) RETURN
7774            CASE (isouth_u, isouth_l)               !< southward facing surfaces
7775                IF ( y2 > y ) RETURN
7776            CASE (inorth_u, inorth_l)               !< northward facing surfaces
7777                IF ( y2 < y ) RETURN
7778            CASE (iwest_u, iwest_l)                 !< westward facing surfaces
7779                IF ( x2 > x ) RETURN
7780            CASE (ieast_u, ieast_l)                 !< eastward facing surfaces
7781                IF ( x2 < x ) RETURN
7782        END SELECT
7783
7784        SELECT CASE (d2)
7785            CASE (iup_u)                            !< ground, roof
7786                IF ( z < z2 ) RETURN
7787            CASE (isouth_u, isouth_l)               !< south facing
7788                IF ( y > y2 ) RETURN
7789            CASE (inorth_u, inorth_l)               !< north facing
7790                IF ( y < y2 ) RETURN
7791            CASE (iwest_u, iwest_l)                 !< west facing
7792                IF ( x > x2 ) RETURN
7793            CASE (ieast_u, ieast_l)                 !< east facing
7794                IF ( x < x2 ) RETURN
7795            CASE (-1)
7796                CONTINUE
7797        END SELECT
7798
7799        surface_facing = .TRUE.
7800       
7801    END FUNCTION surface_facing
7802
7803
7804!------------------------------------------------------------------------------!
7805!
7806! Description:
7807! ------------
7808!> Soubroutine reads svf and svfsurf data from saved file
7809!> SVF means sky view factors and CSF means canopy sink factors
7810!------------------------------------------------------------------------------!
7811    SUBROUTINE radiation_read_svf
7812
7813       IMPLICIT NONE
7814       
7815       CHARACTER(rad_version_len)   :: rad_version_field
7816       
7817       INTEGER(iwp)                 :: i
7818       INTEGER(iwp)                 :: ndsidir_from_file = 0
7819       INTEGER(iwp)                 :: npcbl_from_file = 0
7820       INTEGER(iwp)                 :: nsurfl_from_file = 0
7821       
7822       DO  i = 0, io_blocks-1
7823          IF ( i == io_group )  THEN
7824
7825!
7826!--          numprocs_previous_run is only known in case of reading restart
7827!--          data. If a new initial run which reads svf data is started the
7828!--          following query will be skipped
7829             IF ( initializing_actions == 'read_restart_data' ) THEN
7830
7831                IF ( numprocs_previous_run /= numprocs ) THEN
7832                   WRITE( message_string, * ) 'A different number of ',        &
7833                                              'processors between the run ',   &
7834                                              'that has written the svf data ',&
7835                                              'and the one that will read it ',&
7836                                              'is not allowed' 
7837                   CALL message( 'check_open', 'PA0491', 1, 2, 0, 6, 0 )
7838                ENDIF
7839
7840             ENDIF
7841             
7842!
7843!--          Open binary file
7844             CALL check_open( 88 )
7845
7846!
7847!--          read and check version
7848             READ ( 88 ) rad_version_field
7849             IF ( TRIM(rad_version_field) /= TRIM(rad_version) )  THEN
7850                 WRITE( message_string, * ) 'Version of binary SVF file "',    &
7851                             TRIM(rad_version_field), '" does not match ',     &
7852                             'the version of model "', TRIM(rad_version), '"'
7853                 CALL message( 'radiation_read_svf', 'PA0482', 1, 2, 0, 6, 0 )
7854             ENDIF
7855             
7856!
7857!--          read nsvfl, ncsfl, nsurfl
7858             READ ( 88 ) nsvfl, ncsfl, nsurfl_from_file, npcbl_from_file,      &
7859                         ndsidir_from_file
7860             
7861             IF ( nsvfl < 0  .OR.  ncsfl < 0 )  THEN
7862                 WRITE( message_string, * ) 'Wrong number of SVF or CSF'
7863                 CALL message( 'radiation_read_svf', 'PA0483', 1, 2, 0, 6, 0 )
7864             ELSE
7865                 WRITE(message_string,*) '    Number of SVF, CSF, and nsurfl ',&
7866                                         'to read', nsvfl, ncsfl,              &
7867                                         nsurfl_from_file
7868                 CALL location_message( message_string, .TRUE. )
7869             ENDIF
7870             
7871             IF ( nsurfl_from_file /= nsurfl )  THEN
7872                 WRITE( message_string, * ) 'nsurfl from SVF file does not ',  &
7873                                            'match calculated nsurfl from ',   &
7874                                            'radiation_interaction_init'
7875                 CALL message( 'radiation_read_svf', 'PA0490', 1, 2, 0, 6, 0 )
7876             ENDIF
7877             
7878             IF ( npcbl_from_file /= npcbl )  THEN
7879                 WRITE( message_string, * ) 'npcbl from SVF file does not ',   &
7880                                            'match calculated npcbl from ',    &
7881                                            'radiation_interaction_init'
7882                 CALL message( 'radiation_read_svf', 'PA0493', 1, 2, 0, 6, 0 )
7883             ENDIF
7884             
7885             IF ( ndsidir_from_file /= ndsidir )  THEN
7886                 WRITE( message_string, * ) 'ndsidir from SVF file does not ', &
7887                                            'match calculated ndsidir from ',  &
7888                                            'radiation_presimulate_solar_pos'
7889                 CALL message( 'radiation_read_svf', 'PA0494', 1, 2, 0, 6, 0 )
7890             ENDIF
7891             
7892!
7893!--          Arrays skyvf, skyvft, dsitrans and dsitransc are allready
7894!--          allocated in radiation_interaction_init and
7895!--          radiation_presimulate_solar_pos
7896             IF ( nsurfl > 0 )  THEN
7897                READ(88) skyvf
7898                READ(88) skyvft
7899                READ(88) dsitrans 
7900             ENDIF
7901             
7902             IF ( plant_canopy  .AND.  npcbl > 0 ) THEN
7903                READ ( 88 )  dsitransc
7904             ENDIF
7905             
7906!
7907!--          The allocation of svf, svfsurf, csf and csfsurf happens in routine
7908!--          radiation_calc_svf which is not called if the program enters
7909!--          radiation_read_svf. Therefore these arrays has to allocate in the
7910!--          following
7911             IF ( nsvfl > 0 )  THEN
7912                ALLOCATE( svf(ndsvf,nsvfl) )
7913                ALLOCATE( svfsurf(idsvf,nsvfl) )
7914                READ(88) svf
7915                READ(88) svfsurf
7916             ENDIF
7917
7918             IF ( plant_canopy  .AND.  ncsfl > 0 )  THEN
7919                ALLOCATE( csf(ndcsf,ncsfl) )
7920                ALLOCATE( csfsurf(idcsf,ncsfl) )
7921                READ(88) csf
7922                READ(88) csfsurf
7923             ENDIF
7924             
7925!
7926!--          Close binary file                 
7927             CALL close_file( 88 )
7928               
7929          ENDIF
7930#if defined( __parallel )
7931          CALL MPI_BARRIER( comm2d, ierr )
7932#endif
7933       ENDDO
7934
7935    END SUBROUTINE radiation_read_svf
7936
7937
7938!------------------------------------------------------------------------------!
7939!
7940! Description:
7941! ------------
7942!> Subroutine stores svf, svfsurf, csf and csfsurf data to a file.
7943!------------------------------------------------------------------------------!
7944    SUBROUTINE radiation_write_svf
7945
7946       IMPLICIT NONE
7947       
7948       INTEGER(iwp)        :: i
7949
7950       DO  i = 0, io_blocks-1
7951          IF ( i == io_group )  THEN
7952!
7953!--          Open binary file
7954             CALL check_open( 89 )
7955
7956             WRITE ( 89 )  rad_version
7957             WRITE ( 89 )  nsvfl, ncsfl, nsurfl, npcbl, ndsidir
7958             IF ( nsurfl > 0 ) THEN
7959                WRITE ( 89 )  skyvf
7960                WRITE ( 89 )  skyvft
7961                WRITE ( 89 )  dsitrans
7962             ENDIF
7963             IF ( npcbl > 0 ) THEN
7964                WRITE ( 89 )  dsitransc
7965             ENDIF
7966             IF ( nsvfl > 0 ) THEN
7967                WRITE ( 89 )  svf
7968                WRITE ( 89 )  svfsurf
7969             ENDIF
7970             IF ( plant_canopy  .AND.  ncsfl > 0 )  THEN
7971                 WRITE ( 89 )  csf
7972                 WRITE ( 89 )  csfsurf
7973             ENDIF
7974
7975!
7976!--          Close binary file                 
7977             CALL close_file( 89 )
7978
7979          ENDIF
7980#if defined( __parallel )
7981          CALL MPI_BARRIER( comm2d, ierr )
7982#endif
7983       ENDDO
7984    END SUBROUTINE radiation_write_svf
7985
7986!------------------------------------------------------------------------------!
7987!
7988! Description:
7989! ------------
7990!> Block of auxiliary subroutines:
7991!> 1. quicksort and corresponding comparison
7992!> 2. merge_and_grow_csf for implementation of "dynamical growing"
7993!>    array for csf
7994!------------------------------------------------------------------------------!
7995!-- quicksort.f -*-f90-*-
7996!-- Author: t-nissie, adaptation J.Resler
7997!-- License: GPLv3
7998!-- Gist: https://gist.github.com/t-nissie/479f0f16966925fa29ea
7999    RECURSIVE SUBROUTINE quicksort_itarget(itarget, vffrac, ztransp, first, last)
8000        IMPLICIT NONE
8001        INTEGER(iwp), DIMENSION(:), INTENT(INOUT)   :: itarget
8002        REAL(wp), DIMENSION(:), INTENT(INOUT)       :: vffrac, ztransp
8003        INTEGER(iwp), INTENT(IN)                    :: first, last
8004        INTEGER(iwp)                                :: x, t
8005        INTEGER(iwp)                                :: i, j
8006        REAL(wp)                                    :: tr
8007
8008        IF ( first>=last ) RETURN
8009        x = itarget((first+last)/2)
8010        i = first
8011        j = last
8012        DO
8013            DO WHILE ( itarget(i) < x )
8014               i=i+1
8015            ENDDO
8016            DO WHILE ( x < itarget(j) )
8017                j=j-1
8018            ENDDO
8019            IF ( i >= j ) EXIT
8020            t = itarget(i);  itarget(i) = itarget(j);  itarget(j) = t
8021            tr = vffrac(i);  vffrac(i) = vffrac(j);  vffrac(j) = tr
8022            tr = ztransp(i);  ztransp(i) = ztransp(j);  ztransp(j) = tr
8023            i=i+1
8024            j=j-1
8025        ENDDO
8026        IF ( first < i-1 ) CALL quicksort_itarget(itarget, vffrac, ztransp, first, i-1)
8027        IF ( j+1 < last )  CALL quicksort_itarget(itarget, vffrac, ztransp, j+1, last)
8028    END SUBROUTINE quicksort_itarget
8029
8030    PURE FUNCTION svf_lt(svf1,svf2) result (res)
8031      TYPE (t_svf), INTENT(in) :: svf1,svf2
8032      LOGICAL                  :: res
8033      IF ( svf1%isurflt < svf2%isurflt  .OR.    &
8034          (svf1%isurflt == svf2%isurflt  .AND.  svf1%isurfs < svf2%isurfs) )  THEN
8035          res = .TRUE.
8036      ELSE
8037          res = .FALSE.
8038      ENDIF
8039    END FUNCTION svf_lt
8040
8041
8042!-- quicksort.f -*-f90-*-
8043!-- Author: t-nissie, adaptation J.Resler
8044!-- License: GPLv3
8045!-- Gist: https://gist.github.com/t-nissie/479f0f16966925fa29ea
8046    RECURSIVE SUBROUTINE quicksort_svf(svfl, first, last)
8047        IMPLICIT NONE
8048        TYPE(t_svf), DIMENSION(:), INTENT(INOUT)  :: svfl
8049        INTEGER(iwp), INTENT(IN)                  :: first, last
8050        TYPE(t_svf)                               :: x, t
8051        INTEGER(iwp)                              :: i, j
8052
8053        IF ( first>=last ) RETURN
8054        x = svfl( (first+last) / 2 )
8055        i = first
8056        j = last
8057        DO
8058            DO while ( svf_lt(svfl(i),x) )
8059               i=i+1
8060            ENDDO
8061            DO while ( svf_lt(x,svfl(j)) )
8062                j=j-1
8063            ENDDO
8064            IF ( i >= j ) EXIT
8065            t = svfl(i);  svfl(i) = svfl(j);  svfl(j) = t
8066            i=i+1
8067            j=j-1
8068        ENDDO
8069        IF ( first < i-1 ) CALL quicksort_svf(svfl, first, i-1)
8070        IF ( j+1 < last )  CALL quicksort_svf(svfl, j+1, last)
8071    END SUBROUTINE quicksort_svf
8072
8073    PURE FUNCTION csf_lt(csf1,csf2) result (res)
8074      TYPE (t_csf), INTENT(in) :: csf1,csf2
8075      LOGICAL                  :: res
8076      IF ( csf1%ip < csf2%ip  .OR.    &
8077           (csf1%ip == csf2%ip  .AND.  csf1%itx < csf2%itx)  .OR.  &
8078           (csf1%ip == csf2%ip  .AND.  csf1%itx == csf2%itx  .AND.  csf1%ity < csf2%ity)  .OR.  &
8079           (csf1%ip == csf2%ip  .AND.  csf1%itx == csf2%itx  .AND.  csf1%ity == csf2%ity  .AND.   &
8080            csf1%itz < csf2%itz)  .OR.  &
8081           (csf1%ip == csf2%ip  .AND.  csf1%itx == csf2%itx  .AND.  csf1%ity == csf2%ity  .AND.   &
8082            csf1%itz == csf2%itz  .AND.  csf1%isurfs < csf2%isurfs) )  THEN
8083          res = .TRUE.
8084      ELSE
8085          res = .FALSE.
8086      ENDIF
8087    END FUNCTION csf_lt
8088
8089
8090!-- quicksort.f -*-f90-*-
8091!-- Author: t-nissie, adaptation J.Resler
8092!-- License: GPLv3
8093!-- Gist: https://gist.github.com/t-nissie/479f0f16966925fa29ea
8094    RECURSIVE SUBROUTINE quicksort_csf(csfl, first, last)
8095        IMPLICIT NONE
8096        TYPE(t_csf), DIMENSION(:), INTENT(INOUT)  :: csfl
8097        INTEGER(iwp), INTENT(IN)                  :: first, last
8098        TYPE(t_csf)                               :: x, t
8099        INTEGER(iwp)                              :: i, j
8100
8101        IF ( first>=last ) RETURN
8102        x = csfl( (first+last)/2 )
8103        i = first
8104        j = last
8105        DO
8106            DO while ( csf_lt(csfl(i),x) )
8107                i=i+1
8108            ENDDO
8109            DO while ( csf_lt(x,csfl(j)) )
8110                j=j-1
8111            ENDDO
8112            IF ( i >= j ) EXIT
8113            t = csfl(i);  csfl(i) = csfl(j);  csfl(j) = t
8114            i=i+1
8115            j=j-1
8116        ENDDO
8117        IF ( first < i-1 ) CALL quicksort_csf(csfl, first, i-1)
8118        IF ( j+1 < last )  CALL quicksort_csf(csfl, j+1, last)
8119    END SUBROUTINE quicksort_csf
8120
8121   
8122    SUBROUTINE merge_and_grow_csf(newsize)
8123        INTEGER(iwp), INTENT(in)                :: newsize  !< new array size after grow, must be >= ncsfl
8124                                                            !< or -1 to shrink to minimum
8125        INTEGER(iwp)                            :: iread, iwrite
8126        TYPE(t_csf), DIMENSION(:), POINTER      :: acsfnew
8127        CHARACTER(100)                          :: msg
8128
8129        IF ( newsize == -1 )  THEN
8130!--         merge in-place
8131            acsfnew => acsf
8132        ELSE
8133!--         allocate new array
8134            IF ( mcsf == 0 )  THEN
8135                ALLOCATE( acsf1(newsize) )
8136                acsfnew => acsf1
8137            ELSE
8138                ALLOCATE( acsf2(newsize) )
8139                acsfnew => acsf2
8140            ENDIF
8141        ENDIF
8142
8143        IF ( ncsfl >= 1 )  THEN
8144!--         sort csf in place (quicksort)
8145            CALL quicksort_csf(acsf,1,ncsfl)
8146
8147!--         while moving to a new array, aggregate canopy sink factor records with identical box & source
8148            acsfnew(1) = acsf(1)
8149            iwrite = 1
8150            DO iread = 2, ncsfl
8151!--             here acsf(kcsf) already has values from acsf(icsf)
8152                IF ( acsfnew(iwrite)%itx == acsf(iread)%itx &
8153                         .AND.  acsfnew(iwrite)%ity == acsf(iread)%ity &
8154                         .AND.  acsfnew(iwrite)%itz == acsf(iread)%itz &
8155                         .AND.  acsfnew(iwrite)%isurfs == acsf(iread)%isurfs )  THEN
8156
8157                    acsfnew(iwrite)%rsvf = acsfnew(iwrite)%rsvf + acsf(iread)%rsvf
8158!--                 advance reading index, keep writing index
8159                ELSE
8160!--                 not identical, just advance and copy
8161                    iwrite = iwrite + 1
8162                    acsfnew(iwrite) = acsf(iread)
8163                ENDIF
8164            ENDDO
8165            ncsfl = iwrite
8166        ENDIF
8167
8168        IF ( newsize == -1 )  THEN
8169!--         allocate new array and copy shrinked data
8170            IF ( mcsf == 0 )  THEN
8171                ALLOCATE( acsf1(ncsfl) )
8172                acsf1(1:ncsfl) = acsf2(1:ncsfl)
8173            ELSE
8174                ALLOCATE( acsf2(ncsfl) )
8175                acsf2(1:ncsfl) = acsf1(1:ncsfl)
8176            ENDIF
8177        ENDIF
8178
8179!--     deallocate old array
8180        IF ( mcsf == 0 )  THEN
8181            mcsf = 1
8182            acsf => acsf1
8183            DEALLOCATE( acsf2 )
8184        ELSE
8185            mcsf = 0
8186            acsf => acsf2
8187            DEALLOCATE( acsf1 )
8188        ENDIF
8189        ncsfla = newsize
8190
8191        WRITE(msg,'(A,2I12)') 'Grow acsf2:',ncsfl,ncsfla
8192        CALL radiation_write_debug_log( msg )
8193
8194    END SUBROUTINE merge_and_grow_csf
8195
8196   
8197!-- quicksort.f -*-f90-*-
8198!-- Author: t-nissie, adaptation J.Resler
8199!-- License: GPLv3
8200!-- Gist: https://gist.github.com/t-nissie/479f0f16966925fa29ea
8201    RECURSIVE SUBROUTINE quicksort_csf2(kpcsflt, pcsflt, first, last)
8202        IMPLICIT NONE
8203        INTEGER(iwp), DIMENSION(:,:), INTENT(INOUT)  :: kpcsflt
8204        REAL(wp), DIMENSION(:,:), INTENT(INOUT)      :: pcsflt
8205        INTEGER(iwp), INTENT(IN)                     :: first, last
8206        REAL(wp), DIMENSION(ndcsf)                   :: t2
8207        INTEGER(iwp), DIMENSION(kdcsf)               :: x, t1
8208        INTEGER(iwp)                                 :: i, j
8209
8210        IF ( first>=last ) RETURN
8211        x = kpcsflt(:, (first+last)/2 )
8212        i = first
8213        j = last
8214        DO
8215            DO while ( csf_lt2(kpcsflt(:,i),x) )
8216                i=i+1
8217            ENDDO
8218            DO while ( csf_lt2(x,kpcsflt(:,j)) )
8219                j=j-1
8220            ENDDO
8221            IF ( i >= j ) EXIT
8222            t1 = kpcsflt(:,i);  kpcsflt(:,i) = kpcsflt(:,j);  kpcsflt(:,j) = t1
8223            t2 = pcsflt(:,i);  pcsflt(:,i) = pcsflt(:,j);  pcsflt(:,j) = t2
8224            i=i+1
8225            j=j-1
8226        ENDDO
8227        IF ( first < i-1 ) CALL quicksort_csf2(kpcsflt, pcsflt, first, i-1)
8228        IF ( j+1 < last )  CALL quicksort_csf2(kpcsflt, pcsflt, j+1, last)
8229    END SUBROUTINE quicksort_csf2
8230   
8231
8232    PURE FUNCTION csf_lt2(item1, item2) result(res)
8233        INTEGER(iwp), DIMENSION(kdcsf), INTENT(in)  :: item1, item2
8234        LOGICAL                                     :: res
8235        res = ( (item1(3) < item2(3))                                                        &
8236             .OR.  (item1(3) == item2(3)  .AND.  item1(2) < item2(2))                            &
8237             .OR.  (item1(3) == item2(3)  .AND.  item1(2) == item2(2)  .AND.  item1(1) < item2(1)) &
8238             .OR.  (item1(3) == item2(3)  .AND.  item1(2) == item2(2)  .AND.  item1(1) == item2(1) &
8239                 .AND.  item1(4) < item2(4)) )
8240    END FUNCTION csf_lt2
8241
8242    PURE FUNCTION searchsorted(athresh, val) result(ind)
8243        REAL(wp), DIMENSION(:), INTENT(IN)  :: athresh
8244        REAL(wp), INTENT(IN)                :: val
8245        INTEGER(iwp)                        :: ind
8246        INTEGER(iwp)                        :: i
8247
8248        DO i = LBOUND(athresh, 1), UBOUND(athresh, 1)
8249            IF ( val < athresh(i) ) THEN
8250                ind = i - 1
8251                RETURN
8252            ENDIF
8253        ENDDO
8254        ind = UBOUND(athresh, 1)
8255    END FUNCTION searchsorted
8256
8257!------------------------------------------------------------------------------!
8258! Description:
8259! ------------
8260!
8261!> radiation_radflux_gridbox subroutine gives the sw and lw radiation fluxes at the
8262!> faces of a gridbox defined at i,j,k and located in the urban layer.
8263!> The total sw and the diffuse sw radiation as well as the lw radiation fluxes at
8264!> the gridbox 6 faces are stored in sw_gridbox, swd_gridbox, and lw_gridbox arrays,
8265!> respectively, in the following order:
8266!>  up_face, down_face, north_face, south_face, east_face, west_face
8267!>
8268!> The subroutine reports also how successful was the search process via the parameter
8269!> i_feedback as follow:
8270!> - i_feedback =  1 : successful
8271!> - i_feedback = -1 : unsuccessful; the requisted point is outside the urban domain
8272!> - i_feedback =  0 : uncomplete; some gridbox faces fluxes are missing
8273!>
8274!>
8275!> It is called outside from usm_urban_surface_mod whenever the radiation fluxes
8276!> are needed.
8277!>
8278!> TODO:
8279!>    - Compare performance when using some combination of the Fortran intrinsic
8280!>      functions, e.g. MINLOC, MAXLOC, ALL, ANY and COUNT functions, which search
8281!>      surfl array for elements meeting user-specified criterion, i.e. i,j,k
8282!>    - Report non-found or incomplete radiation fluxes arrays , if any, at the
8283!>      gridbox faces in an error message form
8284!>
8285!------------------------------------------------------------------------------!
8286    SUBROUTINE radiation_radflux_gridbox(i,j,k,sw_gridbox,swd_gridbox,lw_gridbox,i_feedback)
8287       
8288        IMPLICIT NONE
8289
8290        INTEGER(iwp),                 INTENT(in)  :: i,j,k                 !< gridbox indices at which fluxes are required
8291        INTEGER(iwp)                              :: ii,jj,kk,d            !< surface indices and type
8292        INTEGER(iwp)                              :: l                     !< surface id
8293        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
8294        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
8295        INTEGER(iwp),                 INTENT(out) :: i_feedback            !< feedback to report how the search was successful
8296
8297
8298!-- initialize variables
8299        i_feedback  = -999999
8300        sw_gridbox  = -999999.9_wp
8301        lw_gridbox  = -999999.9_wp
8302        swd_gridbox = -999999.9_wp
8303       
8304!-- check the requisted grid indices
8305        IF ( k < nzb   .OR.  k > nzut  .OR.   &
8306             j < nysg  .OR.  j > nyng  .OR.   &
8307             i < nxlg  .OR.  i > nxrg         &
8308             ) THEN
8309           i_feedback = -1
8310           RETURN
8311        ENDIF
8312
8313!-- search for the required grid and formulate the fluxes at the 6 gridbox faces
8314        DO l = 1, nsurfl
8315            ii = surfl(ix,l)
8316            jj = surfl(iy,l)
8317            kk = surfl(iz,l)
8318
8319            IF ( ii == i  .AND.  jj == j  .AND.  kk == k ) THEN
8320               d = surfl(id,l)
8321
8322               SELECT CASE ( d )
8323
8324               CASE (iup_u,iup_l)                          !- gridbox up_facing face
8325                  sw_gridbox(1) = surfinsw(l)
8326                  lw_gridbox(1) = surfinlw(l)
8327                  swd_gridbox(1) = surfinswdif(l)
8328
8329               CASE (inorth_u,inorth_l)                    !- gridbox north_facing face
8330                  sw_gridbox(3) = surfinsw(l)
8331                  lw_gridbox(3) = surfinlw(l)
8332                  swd_gridbox(3) = surfinswdif(l)
8333
8334               CASE (isouth_u,isouth_l)                    !- gridbox south_facing face
8335                  sw_gridbox(4) = surfinsw(l)
8336                  lw_gridbox(4) = surfinlw(l)
8337                  swd_gridbox(4) = surfinswdif(l)
8338
8339               CASE (ieast_u,ieast_l)                      !- gridbox east_facing face
8340                  sw_gridbox(5) = surfinsw(l)
8341                  lw_gridbox(5) = surfinlw(l)
8342                  swd_gridbox(5) = surfinswdif(l)
8343
8344               CASE (iwest_u,iwest_l)                      !- gridbox west_facing face
8345                  sw_gridbox(6) = surfinsw(l)
8346                  lw_gridbox(6) = surfinlw(l)
8347                  swd_gridbox(6) = surfinswdif(l)
8348
8349               END SELECT
8350
8351            ENDIF
8352
8353        IF ( ALL( sw_gridbox(:)  /= -999999.9_wp )  ) EXIT
8354        ENDDO
8355
8356!-- check the completeness of the fluxes at all gidbox faces       
8357!-- TODO: report non-found or incomplete rad fluxes arrays in an error message form
8358        IF ( ANY( sw_gridbox(:)  <= -999999.9_wp )  .OR.   &
8359             ANY( swd_gridbox(:) <= -999999.9_wp )  .OR.   &
8360             ANY( lw_gridbox(:)  <= -999999.9_wp ) ) THEN
8361           i_feedback = 0
8362        ELSE
8363           i_feedback = 1
8364        ENDIF
8365       
8366        RETURN
8367       
8368    END SUBROUTINE radiation_radflux_gridbox
8369
8370!------------------------------------------------------------------------------!
8371!
8372! Description:
8373! ------------
8374!> Subroutine for averaging 3D data
8375!------------------------------------------------------------------------------!
8376SUBROUTINE radiation_3d_data_averaging( mode, variable )
8377 
8378
8379    USE control_parameters
8380
8381    USE indices
8382
8383    USE kinds
8384
8385    IMPLICIT NONE
8386
8387    CHARACTER (LEN=*) ::  mode    !<
8388    CHARACTER (LEN=*) :: variable !<
8389
8390    LOGICAL      ::  match_lsm !< flag indicating natural-type surface
8391    LOGICAL      ::  match_usm !< flag indicating urban-type surface
8392   
8393    INTEGER(iwp) ::  i !<
8394    INTEGER(iwp) ::  j !<
8395    INTEGER(iwp) ::  k !<
8396    INTEGER(iwp) ::  l, m !< index of current surface element
8397
8398    IF ( mode == 'allocate' )  THEN
8399
8400       SELECT CASE ( TRIM( variable ) )
8401
8402             CASE ( 'rad_net*' )
8403                IF ( .NOT. ALLOCATED( rad_net_av ) )  THEN
8404                   ALLOCATE( rad_net_av(nysg:nyng,nxlg:nxrg) )
8405                ENDIF
8406                rad_net_av = 0.0_wp
8407             
8408             CASE ( 'rad_lw_in*' )
8409                IF ( .NOT. ALLOCATED( rad_lw_in_xy_av ) )  THEN
8410                   ALLOCATE( rad_lw_in_xy_av(nysg:nyng,nxlg:nxrg) )
8411                ENDIF
8412                rad_lw_in_xy_av = 0.0_wp
8413               
8414             CASE ( 'rad_lw_out*' )
8415                IF ( .NOT. ALLOCATED( rad_lw_out_xy_av ) )  THEN
8416                   ALLOCATE( rad_lw_out_xy_av(nysg:nyng,nxlg:nxrg) )
8417                ENDIF
8418                rad_lw_out_xy_av = 0.0_wp
8419               
8420             CASE ( 'rad_sw_in*' )
8421                IF ( .NOT. ALLOCATED( rad_sw_in_xy_av ) )  THEN
8422                   ALLOCATE( rad_sw_in_xy_av(nysg:nyng,nxlg:nxrg) )
8423                ENDIF
8424                rad_sw_in_xy_av = 0.0_wp
8425               
8426             CASE ( 'rad_sw_out*' )
8427                IF ( .NOT. ALLOCATED( rad_sw_out_xy_av ) )  THEN
8428                   ALLOCATE( rad_sw_out_xy_av(nysg:nyng,nxlg:nxrg) )
8429                ENDIF
8430                rad_sw_out_xy_av = 0.0_wp               
8431
8432             CASE ( 'rad_lw_in' )
8433                IF ( .NOT. ALLOCATED( rad_lw_in_av ) )  THEN
8434                   ALLOCATE( rad_lw_in_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
8435                ENDIF
8436                rad_lw_in_av = 0.0_wp
8437
8438             CASE ( 'rad_lw_out' )
8439                IF ( .NOT. ALLOCATED( rad_lw_out_av ) )  THEN
8440                   ALLOCATE( rad_lw_in_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
8441                ENDIF
8442                rad_lw_out_av = 0.0_wp
8443
8444             CASE ( 'rad_lw_cs_hr' )
8445                IF ( .NOT. ALLOCATED( rad_lw_cs_hr_av ) )  THEN
8446                   ALLOCATE( rad_lw_cs_hr_av(nzb+1:nzt+1,nysg:nyng,nxlg:nxrg) )
8447                ENDIF
8448                rad_lw_cs_hr_av = 0.0_wp
8449
8450             CASE ( 'rad_lw_hr' )
8451                IF ( .NOT. ALLOCATED( rad_lw_hr_av ) )  THEN
8452                   ALLOCATE( rad_lw_hr_av(nzb+1:nzt+1,nysg:nyng,nxlg:nxrg) )
8453                ENDIF
8454                rad_lw_hr_av = 0.0_wp
8455
8456             CASE ( 'rad_sw_in' )
8457                IF ( .NOT. ALLOCATED( rad_sw_in_av ) )  THEN
8458                   ALLOCATE( rad_sw_in_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
8459                ENDIF
8460                rad_sw_in_av = 0.0_wp
8461
8462             CASE ( 'rad_sw_out' )
8463                IF ( .NOT. ALLOCATED( rad_sw_out_av ) )  THEN
8464                   ALLOCATE( rad_sw_out_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
8465                ENDIF
8466                rad_sw_out_av = 0.0_wp
8467
8468             CASE ( 'rad_sw_cs_hr' )
8469                IF ( .NOT. ALLOCATED( rad_sw_cs_hr_av ) )  THEN
8470                   ALLOCATE( rad_sw_cs_hr_av(nzb+1:nzt+1,nysg:nyng,nxlg:nxrg) )
8471                ENDIF
8472                rad_sw_cs_hr_av = 0.0_wp
8473
8474             CASE ( 'rad_sw_hr' )
8475                IF ( .NOT. ALLOCATED( rad_sw_hr_av ) )  THEN
8476                   ALLOCATE( rad_sw_hr_av(nzb+1:nzt+1,nysg:nyng,nxlg:nxrg) )
8477                ENDIF
8478                rad_sw_hr_av = 0.0_wp
8479
8480             CASE ( 'rad_mrt_sw' )
8481                IF ( .NOT. ALLOCATED( mrtinsw_av ) )  THEN
8482                   ALLOCATE( mrtinsw_av(nmrtbl) )
8483                ENDIF
8484                mrtinsw_av = 0.0_wp
8485
8486             CASE ( 'rad_mrt_lw' )
8487                IF ( .NOT. ALLOCATED( mrtinlw_av ) )  THEN
8488                   ALLOCATE( mrtinlw_av(nmrtbl) )
8489                ENDIF
8490                mrtinlw_av = 0.0_wp
8491
8492             CASE ( 'rad_mrt' )
8493                IF ( .NOT. ALLOCATED( mrt_av ) )  THEN
8494                   ALLOCATE( mrt_av(nmrtbl) )
8495                ENDIF
8496                mrt_av = 0.0_wp
8497
8498          CASE DEFAULT
8499             CONTINUE
8500
8501       END SELECT
8502
8503    ELSEIF ( mode == 'sum' )  THEN
8504
8505       SELECT CASE ( TRIM( variable ) )
8506
8507          CASE ( 'rad_net*' )
8508             IF ( ALLOCATED( rad_net_av ) ) THEN
8509                DO  i = nxl, nxr
8510                   DO  j = nys, nyn
8511                      match_lsm = surf_lsm_h%start_index(j,i) <=               &
8512                                  surf_lsm_h%end_index(j,i)
8513                      match_usm = surf_usm_h%start_index(j,i) <=               &
8514                                  surf_usm_h%end_index(j,i)
8515
8516                     IF ( match_lsm  .AND.  .NOT. match_usm )  THEN
8517                         m = surf_lsm_h%end_index(j,i)
8518                         rad_net_av(j,i) = rad_net_av(j,i) +                   &
8519                                         surf_lsm_h%rad_net(m)
8520                      ELSEIF ( match_usm )  THEN
8521                         m = surf_usm_h%end_index(j,i)
8522                         rad_net_av(j,i) = rad_net_av(j,i) +                   &
8523                                         surf_usm_h%rad_net(m)
8524                      ENDIF
8525                   ENDDO
8526                ENDDO
8527             ENDIF
8528
8529          CASE ( 'rad_lw_in*' )
8530             IF ( ALLOCATED( rad_lw_in_xy_av ) ) THEN
8531                DO  i = nxl, nxr
8532                   DO  j = nys, nyn
8533                      match_lsm = surf_lsm_h%start_index(j,i) <=               &
8534                                  surf_lsm_h%end_index(j,i)
8535                      match_usm = surf_usm_h%start_index(j,i) <=               &
8536                                  surf_usm_h%end_index(j,i)
8537
8538                      IF ( match_lsm  .AND.  .NOT. match_usm )  THEN
8539                         m = surf_lsm_h%end_index(j,i)
8540                         rad_lw_in_xy_av(j,i) = rad_lw_in_xy_av(j,i) +         &
8541                                         surf_lsm_h%rad_lw_in(m)
8542                      ELSEIF ( match_usm )  THEN
8543                         m = surf_usm_h%end_index(j,i)
8544                         rad_lw_in_xy_av(j,i) = rad_lw_in_xy_av(j,i) +         &
8545                                         surf_usm_h%rad_lw_in(m)
8546                      ENDIF
8547                   ENDDO
8548                ENDDO
8549             ENDIF
8550             
8551          CASE ( 'rad_lw_out*' )
8552             IF ( ALLOCATED( rad_lw_out_xy_av ) ) THEN
8553                DO  i = nxl, nxr
8554                   DO  j = nys, nyn
8555                      match_lsm = surf_lsm_h%start_index(j,i) <=               &
8556                                  surf_lsm_h%end_index(j,i)
8557                      match_usm = surf_usm_h%start_index(j,i) <=               &
8558                                  surf_usm_h%end_index(j,i)
8559
8560                      IF ( match_lsm  .AND.  .NOT. match_usm )  THEN
8561                         m = surf_lsm_h%end_index(j,i)
8562                         rad_lw_out_xy_av(j,i) = rad_lw_out_xy_av(j,i) +       &
8563                                                 surf_lsm_h%rad_lw_out(m)
8564                      ELSEIF ( match_usm )  THEN
8565                         m = surf_usm_h%end_index(j,i)
8566                         rad_lw_out_xy_av(j,i) = rad_lw_out_xy_av(j,i) +       &
8567                                                 surf_usm_h%rad_lw_out(m)
8568                      ENDIF
8569                   ENDDO
8570                ENDDO
8571             ENDIF
8572             
8573          CASE ( 'rad_sw_in*' )
8574             IF ( ALLOCATED( rad_sw_in_xy_av ) ) THEN
8575                DO  i = nxl, nxr
8576                   DO  j = nys, nyn
8577                      match_lsm = surf_lsm_h%start_index(j,i) <=               &
8578                                  surf_lsm_h%end_index(j,i)
8579                      match_usm = surf_usm_h%start_index(j,i) <=               &
8580                                  surf_usm_h%end_index(j,i)
8581
8582                      IF ( match_lsm  .AND.  .NOT. match_usm )  THEN
8583                         m = surf_lsm_h%end_index(j,i)
8584                         rad_sw_in_xy_av(j,i) = rad_sw_in_xy_av(j,i) +         &
8585                                                surf_lsm_h%rad_sw_in(m)
8586                      ELSEIF ( match_usm )  THEN
8587                         m = surf_usm_h%end_index(j,i)
8588                         rad_sw_in_xy_av(j,i) = rad_sw_in_xy_av(j,i) +         &
8589                                                surf_usm_h%rad_sw_in(m)
8590                      ENDIF
8591                   ENDDO
8592                ENDDO
8593             ENDIF
8594             
8595          CASE ( 'rad_sw_out*' )
8596             IF ( ALLOCATED( rad_sw_out_xy_av ) ) THEN
8597                DO  i = nxl, nxr
8598                   DO  j = nys, nyn
8599                      match_lsm = surf_lsm_h%start_index(j,i) <=               &
8600                                  surf_lsm_h%end_index(j,i)
8601                      match_usm = surf_usm_h%start_index(j,i) <=               &
8602                                  surf_usm_h%end_index(j,i)
8603
8604                      IF ( match_lsm  .AND.  .NOT. match_usm )  THEN
8605                         m = surf_lsm_h%end_index(j,i)
8606                         rad_sw_out_xy_av(j,i) = rad_sw_out_xy_av(j,i) +       &
8607                                                 surf_lsm_h%rad_sw_out(m)
8608                      ELSEIF ( match_usm )  THEN
8609                         m = surf_usm_h%end_index(j,i)
8610                         rad_sw_out_xy_av(j,i) = rad_sw_out_xy_av(j,i) +       &
8611                                                 surf_usm_h%rad_sw_out(m)
8612                      ENDIF
8613                   ENDDO
8614                ENDDO
8615             ENDIF
8616             
8617          CASE ( 'rad_lw_in' )
8618             IF ( ALLOCATED( rad_lw_in_av ) ) THEN
8619                DO  i = nxlg, nxrg
8620                   DO  j = nysg, nyng
8621                      DO  k = nzb, nzt+1
8622                         rad_lw_in_av(k,j,i) = rad_lw_in_av(k,j,i)             &
8623                                               + rad_lw_in(k,j,i)
8624                      ENDDO
8625                   ENDDO
8626                ENDDO
8627             ENDIF
8628
8629          CASE ( 'rad_lw_out' )
8630             IF ( ALLOCATED( rad_lw_out_av ) ) THEN
8631                DO  i = nxlg, nxrg
8632                   DO  j = nysg, nyng
8633                      DO  k = nzb, nzt+1
8634                         rad_lw_out_av(k,j,i) = rad_lw_out_av(k,j,i)           &
8635                                                + rad_lw_out(k,j,i)
8636                      ENDDO
8637                   ENDDO
8638                ENDDO
8639             ENDIF
8640
8641          CASE ( 'rad_lw_cs_hr' )
8642             IF ( ALLOCATED( rad_lw_cs_hr_av ) ) THEN
8643                DO  i = nxlg, nxrg
8644                   DO  j = nysg, nyng
8645                      DO  k = nzb, nzt+1
8646                         rad_lw_cs_hr_av(k,j,i) = rad_lw_cs_hr_av(k,j,i)       &
8647                                                  + rad_lw_cs_hr(k,j,i)
8648                      ENDDO
8649                   ENDDO
8650                ENDDO
8651             ENDIF
8652
8653          CASE ( 'rad_lw_hr' )
8654             IF ( ALLOCATED( rad_lw_hr_av ) ) THEN
8655                DO  i = nxlg, nxrg
8656                   DO  j = nysg, nyng
8657                      DO  k = nzb, nzt+1
8658                         rad_lw_hr_av(k,j,i) = rad_lw_hr_av(k,j,i)             &
8659                                               + rad_lw_hr(k,j,i)
8660                      ENDDO
8661                   ENDDO
8662                ENDDO
8663             ENDIF
8664
8665          CASE ( 'rad_sw_in' )
8666             IF ( ALLOCATED( rad_sw_in_av ) ) THEN
8667                DO  i = nxlg, nxrg
8668                   DO  j = nysg, nyng
8669                      DO  k = nzb, nzt+1
8670                         rad_sw_in_av(k,j,i) = rad_sw_in_av(k,j,i)             &
8671                                               + rad_sw_in(k,j,i)
8672                      ENDDO
8673                   ENDDO
8674                ENDDO
8675             ENDIF
8676
8677          CASE ( 'rad_sw_out' )
8678             IF ( ALLOCATED( rad_sw_out_av ) ) THEN
8679                DO  i = nxlg, nxrg
8680                   DO  j = nysg, nyng
8681                      DO  k = nzb, nzt+1
8682                         rad_sw_out_av(k,j,i) = rad_sw_out_av(k,j,i)           &
8683                                                + rad_sw_out(k,j,i)
8684                      ENDDO
8685                   ENDDO
8686                ENDDO
8687             ENDIF
8688
8689          CASE ( 'rad_sw_cs_hr' )
8690             IF ( ALLOCATED( rad_sw_cs_hr_av ) ) THEN
8691                DO  i = nxlg, nxrg
8692                   DO  j = nysg, nyng
8693                      DO  k = nzb, nzt+1
8694                         rad_sw_cs_hr_av(k,j,i) = rad_sw_cs_hr_av(k,j,i)       &
8695                                                  + rad_sw_cs_hr(k,j,i)
8696                      ENDDO
8697                   ENDDO
8698                ENDDO
8699             ENDIF
8700
8701          CASE ( 'rad_sw_hr' )
8702             IF ( ALLOCATED( rad_sw_hr_av ) ) THEN
8703                DO  i = nxlg, nxrg
8704                   DO  j = nysg, nyng
8705                      DO  k = nzb, nzt+1
8706                         rad_sw_hr_av(k,j,i) = rad_sw_hr_av(k,j,i)             &
8707                                               + rad_sw_hr(k,j,i)
8708                      ENDDO
8709                   ENDDO
8710                ENDDO
8711             ENDIF
8712
8713          CASE ( 'rad_mrt_sw' )
8714             IF ( ALLOCATED( mrtinsw_av ) )  THEN
8715                mrtinsw_av(:) = mrtinsw_av(:) + mrtinsw(:)
8716             ENDIF
8717
8718          CASE ( 'rad_mrt_lw' )
8719             IF ( ALLOCATED( mrtinlw_av ) )  THEN
8720                mrtinlw_av(:) = mrtinlw_av(:) + mrtinlw(:)
8721             ENDIF
8722
8723          CASE ( 'rad_mrt' )
8724             IF ( ALLOCATED( mrt_av ) )  THEN
8725                mrt_av(:) = mrt_av(:) + mrt(:)
8726             ENDIF
8727
8728          CASE DEFAULT
8729             CONTINUE
8730
8731       END SELECT
8732
8733    ELSEIF ( mode == 'average' )  THEN
8734
8735       SELECT CASE ( TRIM( variable ) )
8736
8737          CASE ( 'rad_net*' )
8738             IF ( ALLOCATED( rad_net_av ) ) THEN
8739                DO  i = nxlg, nxrg
8740                   DO  j = nysg, nyng
8741                      rad_net_av(j,i) = rad_net_av(j,i)                        &
8742                                        / REAL( average_count_3d, KIND=wp )
8743                   ENDDO
8744                ENDDO
8745             ENDIF
8746             
8747          CASE ( 'rad_lw_in*' )
8748             IF ( ALLOCATED( rad_lw_in_xy_av ) ) THEN
8749                DO  i = nxlg, nxrg
8750                   DO  j = nysg, nyng
8751                      rad_lw_in_xy_av(j,i) = rad_lw_in_xy_av(j,i)              &
8752                                        / REAL( average_count_3d, KIND=wp )
8753                   ENDDO
8754                ENDDO
8755             ENDIF
8756             
8757          CASE ( 'rad_lw_out*' )
8758             IF ( ALLOCATED( rad_lw_out_xy_av ) ) THEN
8759                DO  i = nxlg, nxrg
8760                   DO  j = nysg, nyng
8761                      rad_lw_out_xy_av(j,i) = rad_lw_out_xy_av(j,i)            &
8762                                        / REAL( average_count_3d, KIND=wp )
8763                   ENDDO
8764                ENDDO
8765             ENDIF
8766             
8767          CASE ( 'rad_sw_in*' )
8768             IF ( ALLOCATED( rad_sw_in_xy_av ) ) THEN
8769                DO  i = nxlg, nxrg
8770                   DO  j = nysg, nyng
8771                      rad_sw_in_xy_av(j,i) = rad_sw_in_xy_av(j,i)              &
8772                                        / REAL( average_count_3d, KIND=wp )
8773                   ENDDO
8774                ENDDO
8775             ENDIF
8776             
8777          CASE ( 'rad_sw_out*' )
8778             IF ( ALLOCATED( rad_sw_out_xy_av ) ) THEN
8779                DO  i = nxlg, nxrg
8780                   DO  j = nysg, nyng
8781                      rad_sw_out_xy_av(j,i) = rad_sw_out_xy_av(j,i)             &
8782                                        / REAL( average_count_3d, KIND=wp )
8783                   ENDDO
8784                ENDDO
8785             ENDIF
8786
8787          CASE ( 'rad_lw_in' )
8788             IF ( ALLOCATED( rad_lw_in_av ) ) THEN
8789                DO  i = nxlg, nxrg
8790                   DO  j = nysg, nyng
8791                      DO  k = nzb, nzt+1
8792                         rad_lw_in_av(k,j,i) = rad_lw_in_av(k,j,i)             &
8793                                               / REAL( average_count_3d, KIND=wp )
8794                      ENDDO
8795                   ENDDO
8796                ENDDO
8797             ENDIF
8798
8799          CASE ( 'rad_lw_out' )
8800             IF ( ALLOCATED( rad_lw_out_av ) ) THEN
8801                DO  i = nxlg, nxrg
8802                   DO  j = nysg, nyng
8803                      DO  k = nzb, nzt+1
8804                         rad_lw_out_av(k,j,i) = rad_lw_out_av(k,j,i)           &
8805                                                / REAL( average_count_3d, KIND=wp )
8806                      ENDDO
8807                   ENDDO
8808                ENDDO
8809             ENDIF
8810
8811          CASE ( 'rad_lw_cs_hr' )
8812             IF ( ALLOCATED( rad_lw_cs_hr_av ) ) THEN
8813                DO  i = nxlg, nxrg
8814                   DO  j = nysg, nyng
8815                      DO  k = nzb, nzt+1
8816                         rad_lw_cs_hr_av(k,j,i) = rad_lw_cs_hr_av(k,j,i)       &
8817                                                / REAL( average_count_3d, KIND=wp )
8818                      ENDDO
8819                   ENDDO
8820                ENDDO
8821             ENDIF
8822
8823          CASE ( 'rad_lw_hr' )
8824             IF ( ALLOCATED( rad_lw_hr_av ) ) THEN
8825                DO  i = nxlg, nxrg
8826                   DO  j = nysg, nyng
8827                      DO  k = nzb, nzt+1
8828                         rad_lw_hr_av(k,j,i) = rad_lw_hr_av(k,j,i)             &
8829                                               / REAL( average_count_3d, KIND=wp )
8830                      ENDDO
8831                   ENDDO
8832                ENDDO
8833             ENDIF
8834
8835          CASE ( 'rad_sw_in' )
8836             IF ( ALLOCATED( rad_sw_in_av ) ) THEN
8837                DO  i = nxlg, nxrg
8838                   DO  j = nysg, nyng
8839                      DO  k = nzb, nzt+1
8840                         rad_sw_in_av(k,j,i) = rad_sw_in_av(k,j,i)             &
8841                                               / REAL( average_count_3d, KIND=wp )
8842                      ENDDO
8843                   ENDDO
8844                ENDDO
8845             ENDIF
8846
8847          CASE ( 'rad_sw_out' )
8848             IF ( ALLOCATED( rad_sw_out_av ) ) THEN
8849                DO  i = nxlg, nxrg
8850                   DO  j = nysg, nyng
8851                      DO  k = nzb, nzt+1
8852                         rad_sw_out_av(k,j,i) = rad_sw_out_av(k,j,i)           &
8853                                                / REAL( average_count_3d, KIND=wp )
8854                      ENDDO
8855                   ENDDO
8856                ENDDO
8857             ENDIF
8858
8859          CASE ( 'rad_sw_cs_hr' )
8860             IF ( ALLOCATED( rad_sw_cs_hr_av ) ) THEN
8861                DO  i = nxlg, nxrg
8862                   DO  j = nysg, nyng
8863                      DO  k = nzb, nzt+1
8864                         rad_sw_cs_hr_av(k,j,i) = rad_sw_cs_hr_av(k,j,i)       &
8865                                                / REAL( average_count_3d, KIND=wp )
8866                      ENDDO
8867                   ENDDO
8868                ENDDO
8869             ENDIF
8870
8871          CASE ( 'rad_sw_hr' )
8872             IF ( ALLOCATED( rad_sw_hr_av ) ) THEN
8873                DO  i = nxlg, nxrg
8874                   DO  j = nysg, nyng
8875                      DO  k = nzb, nzt+1
8876                         rad_sw_hr_av(k,j,i) = rad_sw_hr_av(k,j,i)             &
8877                                               / REAL( average_count_3d, KIND=wp )
8878                      ENDDO
8879                   ENDDO
8880                ENDDO
8881             ENDIF
8882
8883          CASE ( 'rad_mrt_sw' )
8884             IF ( ALLOCATED( mrtinsw_av ) )  THEN
8885                mrtinsw_av(:) = mrtinsw_av(:)  / REAL( average_count_3d, KIND=wp )
8886             ENDIF
8887
8888          CASE ( 'rad_mrt_lw' )
8889             IF ( ALLOCATED( mrtinlw_av ) )  THEN
8890                mrtinlw_av(:) = mrtinlw_av(:) / REAL( average_count_3d, KIND=wp )
8891             ENDIF
8892
8893          CASE ( 'rad_mrt' )
8894             IF ( ALLOCATED( mrt_av ) )  THEN
8895                mrt_av(:) = mrt_av(:) / REAL( average_count_3d, KIND=wp )
8896             ENDIF
8897
8898       END SELECT
8899
8900    ENDIF
8901
8902END SUBROUTINE radiation_3d_data_averaging
8903
8904
8905!------------------------------------------------------------------------------!
8906!
8907! Description:
8908! ------------
8909!> Subroutine defining appropriate grid for netcdf variables.
8910!> It is called out from subroutine netcdf.
8911!------------------------------------------------------------------------------!
8912SUBROUTINE radiation_define_netcdf_grid( var, found, grid_x, grid_y, grid_z )
8913   
8914    IMPLICIT NONE
8915
8916    CHARACTER (LEN=*), INTENT(IN)  ::  var         !<
8917    LOGICAL, INTENT(OUT)           ::  found       !<
8918    CHARACTER (LEN=*), INTENT(OUT) ::  grid_x      !<
8919    CHARACTER (LEN=*), INTENT(OUT) ::  grid_y      !<
8920    CHARACTER (LEN=*), INTENT(OUT) ::  grid_z      !<
8921
8922    found  = .TRUE.
8923
8924
8925!
8926!-- Check for the grid
8927    SELECT CASE ( TRIM( var ) )
8928
8929       CASE ( 'rad_lw_cs_hr', 'rad_lw_hr', 'rad_sw_cs_hr', 'rad_sw_hr',        &
8930              'rad_lw_cs_hr_xy', 'rad_lw_hr_xy', 'rad_sw_cs_hr_xy',            &
8931              'rad_sw_hr_xy', 'rad_lw_cs_hr_xz', 'rad_lw_hr_xz',               &
8932              'rad_sw_cs_hr_xz', 'rad_sw_hr_xz', 'rad_lw_cs_hr_yz',            &
8933              'rad_lw_hr_yz', 'rad_sw_cs_hr_yz', 'rad_sw_hr_yz',               &
8934              'rad_mrt', 'rad_mrt_sw', 'rad_mrt_lw' )
8935          grid_x = 'x'
8936          grid_y = 'y'
8937          grid_z = 'zu'
8938
8939       CASE ( 'rad_lw_in', 'rad_lw_out', 'rad_sw_in', 'rad_sw_out',            &
8940              'rad_lw_in_xy', 'rad_lw_out_xy', 'rad_sw_in_xy','rad_sw_out_xy', &
8941              'rad_lw_in_xz', 'rad_lw_out_xz', 'rad_sw_in_xz','rad_sw_out_xz', &
8942              'rad_lw_in_yz', 'rad_lw_out_yz', 'rad_sw_in_yz','rad_sw_out_yz' )
8943          grid_x = 'x'
8944          grid_y = 'y'
8945          grid_z = 'zw'
8946
8947
8948       CASE DEFAULT
8949          found  = .FALSE.
8950          grid_x = 'none'
8951          grid_y = 'none'
8952          grid_z = 'none'
8953
8954        END SELECT
8955
8956    END SUBROUTINE radiation_define_netcdf_grid
8957
8958!------------------------------------------------------------------------------!
8959!
8960! Description:
8961! ------------
8962!> Subroutine defining 2D output variables
8963!------------------------------------------------------------------------------!
8964 SUBROUTINE radiation_data_output_2d( av, variable, found, grid, mode,         &
8965                                      local_pf, two_d, nzb_do, nzt_do )
8966 
8967    USE indices
8968
8969    USE kinds
8970
8971
8972    IMPLICIT NONE
8973
8974    CHARACTER (LEN=*) ::  grid     !<
8975    CHARACTER (LEN=*) ::  mode     !<
8976    CHARACTER (LEN=*) ::  variable !<
8977
8978    INTEGER(iwp) ::  av !<
8979    INTEGER(iwp) ::  i  !<
8980    INTEGER(iwp) ::  j  !<
8981    INTEGER(iwp) ::  k  !<
8982    INTEGER(iwp) ::  m  !< index of surface element at grid point (j,i)
8983    INTEGER(iwp) ::  nzb_do   !<
8984    INTEGER(iwp) ::  nzt_do   !<
8985
8986    LOGICAL      ::  found !<
8987    LOGICAL      ::  two_d !< flag parameter that indicates 2D variables (horizontal cross sections)
8988
8989    REAL(wp) ::  fill_value = -999.0_wp    !< value for the _FillValue attribute
8990
8991    REAL(wp), DIMENSION(nxl:nxr,nys:nyn,nzb_do:nzt_do) ::  local_pf !<
8992
8993    found = .TRUE.
8994
8995    SELECT CASE ( TRIM( variable ) )
8996
8997       CASE ( 'rad_net*_xy' )        ! 2d-array
8998          IF ( av == 0 ) THEN
8999             DO  i = nxl, nxr
9000                DO  j = nys, nyn
9001!
9002!--                Obtain rad_net from its respective surface type
9003!--                Natural-type surfaces
9004                   DO  m = surf_lsm_h%start_index(j,i),                        &
9005                           surf_lsm_h%end_index(j,i) 
9006                      local_pf(i,j,nzb+1) = surf_lsm_h%rad_net(m)
9007                   ENDDO
9008!
9009!--                Urban-type surfaces
9010                   DO  m = surf_usm_h%start_index(j,i),                        &
9011                           surf_usm_h%end_index(j,i) 
9012                      local_pf(i,j,nzb+1) = surf_usm_h%rad_net(m)
9013                   ENDDO
9014                ENDDO
9015             ENDDO
9016          ELSE
9017             IF ( .NOT. ALLOCATED( rad_net_av ) ) THEN
9018                ALLOCATE( rad_net_av(nysg:nyng,nxlg:nxrg) )
9019                rad_net_av = REAL( fill_value, KIND = wp )
9020             ENDIF
9021             DO  i = nxl, nxr
9022                DO  j = nys, nyn 
9023                   local_pf(i,j,nzb+1) = rad_net_av(j,i)
9024                ENDDO
9025             ENDDO
9026          ENDIF
9027          two_d = .TRUE.
9028          grid = 'zu1'
9029         
9030       CASE ( 'rad_lw_in*_xy' )        ! 2d-array
9031          IF ( av == 0 ) THEN
9032             DO  i = nxl, nxr
9033                DO  j = nys, nyn
9034!
9035!--                Obtain rad_net from its respective surface type
9036!--                Natural-type surfaces
9037                   DO  m = surf_lsm_h%start_index(j,i),                        &
9038                           surf_lsm_h%end_index(j,i) 
9039                      local_pf(i,j,nzb+1) = surf_lsm_h%rad_lw_in(m)
9040                   ENDDO
9041!
9042!--                Urban-type surfaces
9043                   DO  m = surf_usm_h%start_index(j,i),                        &
9044                           surf_usm_h%end_index(j,i) 
9045                      local_pf(i,j,nzb+1) = surf_usm_h%rad_lw_in(m)
9046                   ENDDO
9047                ENDDO
9048             ENDDO
9049          ELSE
9050             IF ( .NOT. ALLOCATED( rad_lw_in_xy_av ) ) THEN
9051                ALLOCATE( rad_lw_in_xy_av(nysg:nyng,nxlg:nxrg) )
9052                rad_lw_in_xy_av = REAL( fill_value, KIND = wp )
9053             ENDIF
9054             DO  i = nxl, nxr
9055                DO  j = nys, nyn 
9056                   local_pf(i,j,nzb+1) = rad_lw_in_xy_av(j,i)
9057                ENDDO
9058             ENDDO
9059          ENDIF
9060          two_d = .TRUE.
9061          grid = 'zu1'
9062         
9063       CASE ( 'rad_lw_out*_xy' )        ! 2d-array
9064          IF ( av == 0 ) THEN
9065             DO  i = nxl, nxr
9066                DO  j = nys, nyn
9067!
9068!--                Obtain rad_net from its respective surface type
9069!--                Natural-type surfaces
9070                   DO  m = surf_lsm_h%start_index(j,i),                        &
9071                           surf_lsm_h%end_index(j,i) 
9072                      local_pf(i,j,nzb+1) = surf_lsm_h%rad_lw_out(m)
9073                   ENDDO
9074!
9075!--                Urban-type surfaces
9076                   DO  m = surf_usm_h%start_index(j,i),                        &
9077                           surf_usm_h%end_index(j,i) 
9078                      local_pf(i,j,nzb+1) = surf_usm_h%rad_lw_out(m)
9079                   ENDDO
9080                ENDDO
9081             ENDDO
9082          ELSE
9083             IF ( .NOT. ALLOCATED( rad_lw_out_xy_av ) ) THEN
9084                ALLOCATE( rad_lw_out_xy_av(nysg:nyng,nxlg:nxrg) )
9085                rad_lw_out_xy_av = REAL( fill_value, KIND = wp )
9086             ENDIF
9087             DO  i = nxl, nxr
9088                DO  j = nys, nyn 
9089                   local_pf(i,j,nzb+1) = rad_lw_out_xy_av(j,i)
9090                ENDDO
9091             ENDDO
9092          ENDIF
9093          two_d = .TRUE.
9094          grid = 'zu1'
9095         
9096       CASE ( 'rad_sw_in*_xy' )        ! 2d-array
9097          IF ( av == 0 ) THEN
9098             DO  i = nxl, nxr
9099                DO  j = nys, nyn
9100!
9101!--                Obtain rad_net from its respective surface type
9102!--                Natural-type surfaces
9103                   DO  m = surf_lsm_h%start_index(j,i),                        &
9104                           surf_lsm_h%end_index(j,i) 
9105                      local_pf(i,j,nzb+1) = surf_lsm_h%rad_sw_in(m)
9106                   ENDDO
9107!
9108!--                Urban-type surfaces
9109                   DO  m = surf_usm_h%start_index(j,i),                        &
9110                           surf_usm_h%end_index(j,i) 
9111                      local_pf(i,j,nzb+1) = surf_usm_h%rad_sw_in(m)
9112                   ENDDO
9113                ENDDO
9114             ENDDO
9115          ELSE
9116             IF ( .NOT. ALLOCATED( rad_sw_in_xy_av ) ) THEN
9117                ALLOCATE( rad_sw_in_xy_av(nysg:nyng,nxlg:nxrg) )
9118                rad_sw_in_xy_av = REAL( fill_value, KIND = wp )
9119             ENDIF
9120             DO  i = nxl, nxr
9121                DO  j = nys, nyn 
9122                   local_pf(i,j,nzb+1) = rad_sw_in_xy_av(j,i)
9123                ENDDO
9124             ENDDO
9125          ENDIF
9126          two_d = .TRUE.
9127          grid = 'zu1'
9128         
9129       CASE ( 'rad_sw_out*_xy' )        ! 2d-array
9130          IF ( av == 0 ) THEN
9131             DO  i = nxl, nxr
9132                DO  j = nys, nyn
9133!
9134!--                Obtain rad_net from its respective surface type
9135!--                Natural-type surfaces
9136                   DO  m = surf_lsm_h%start_index(j,i),                        &
9137                           surf_lsm_h%end_index(j,i) 
9138                      local_pf(i,j,nzb+1) = surf_lsm_h%rad_sw_out(m)
9139                   ENDDO
9140!
9141!--                Urban-type surfaces
9142                   DO  m = surf_usm_h%start_index(j,i),                        &
9143                           surf_usm_h%end_index(j,i) 
9144                      local_pf(i,j,nzb+1) = surf_usm_h%rad_sw_out(m)
9145                   ENDDO
9146                ENDDO
9147             ENDDO
9148          ELSE
9149             IF ( .NOT. ALLOCATED( rad_sw_out_xy_av ) ) THEN
9150                ALLOCATE( rad_sw_out_xy_av(nysg:nyng,nxlg:nxrg) )
9151                rad_sw_out_xy_av = REAL( fill_value, KIND = wp )
9152             ENDIF
9153             DO  i = nxl, nxr
9154                DO  j = nys, nyn 
9155                   local_pf(i,j,nzb+1) = rad_sw_out_xy_av(j,i)
9156                ENDDO
9157             ENDDO
9158          ENDIF
9159          two_d = .TRUE.
9160          grid = 'zu1'         
9161         
9162       CASE ( 'rad_lw_in_xy', 'rad_lw_in_xz', 'rad_lw_in_yz' )
9163          IF ( av == 0 ) THEN
9164             DO  i = nxl, nxr
9165                DO  j = nys, nyn
9166                   DO  k = nzb_do, nzt_do
9167                      local_pf(i,j,k) = rad_lw_in(k,j,i)
9168                   ENDDO
9169                ENDDO
9170             ENDDO
9171          ELSE
9172            IF ( .NOT. ALLOCATED( rad_lw_in_av ) ) THEN
9173               ALLOCATE( rad_lw_in_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
9174               rad_lw_in_av = REAL( fill_value, KIND = wp )
9175            ENDIF
9176             DO  i = nxl, nxr
9177                DO  j = nys, nyn 
9178                   DO  k = nzb_do, nzt_do
9179                      local_pf(i,j,k) = rad_lw_in_av(k,j,i)
9180                   ENDDO
9181                ENDDO
9182             ENDDO
9183          ENDIF
9184          IF ( mode == 'xy' )  grid = 'zu'
9185
9186       CASE ( 'rad_lw_out_xy', 'rad_lw_out_xz', 'rad_lw_out_yz' )
9187          IF ( av == 0 ) THEN
9188             DO  i = nxl, nxr
9189                DO  j = nys, nyn
9190                   DO  k = nzb_do, nzt_do
9191                      local_pf(i,j,k) = rad_lw_out(k,j,i)
9192                   ENDDO
9193                ENDDO
9194             ENDDO
9195          ELSE
9196            IF ( .NOT. ALLOCATED( rad_lw_out_av ) ) THEN
9197               ALLOCATE( rad_lw_out_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
9198               rad_lw_out_av = REAL( fill_value, KIND = wp )
9199            ENDIF
9200             DO  i = nxl, nxr
9201                DO  j = nys, nyn 
9202                   DO  k = nzb_do, nzt_do
9203                      local_pf(i,j,k) = rad_lw_out_av(k,j,i)
9204                   ENDDO
9205                ENDDO
9206             ENDDO
9207          ENDIF   
9208          IF ( mode == 'xy' )  grid = 'zu'
9209
9210       CASE ( 'rad_lw_cs_hr_xy', 'rad_lw_cs_hr_xz', 'rad_lw_cs_hr_yz' )
9211          IF ( av == 0 ) THEN
9212             DO  i = nxl, nxr
9213                DO  j = nys, nyn
9214                   DO  k = nzb_do, nzt_do
9215                      local_pf(i,j,k) = rad_lw_cs_hr(k,j,i)
9216                   ENDDO
9217                ENDDO
9218             ENDDO
9219          ELSE
9220            IF ( .NOT. ALLOCATED( rad_lw_cs_hr_av ) ) THEN
9221               ALLOCATE( rad_lw_cs_hr_av(nzb+1:nzt+1,nysg:nyng,nxlg:nxrg) )
9222               rad_lw_cs_hr_av = REAL( fill_value, KIND = wp )
9223            ENDIF
9224             DO  i = nxl, nxr
9225                DO  j = nys, nyn 
9226                   DO  k = nzb_do, nzt_do
9227                      local_pf(i,j,k) = rad_lw_cs_hr_av(k,j,i)
9228                   ENDDO
9229                ENDDO
9230             ENDDO
9231          ENDIF
9232          IF ( mode == 'xy' )  grid = 'zw'
9233
9234       CASE ( 'rad_lw_hr_xy', 'rad_lw_hr_xz', 'rad_lw_hr_yz' )
9235          IF ( av == 0 ) THEN
9236             DO  i = nxl, nxr
9237                DO  j = nys, nyn
9238                   DO  k = nzb_do, nzt_do
9239                      local_pf(i,j,k) = rad_lw_hr(k,j,i)
9240                   ENDDO
9241                ENDDO
9242             ENDDO
9243          ELSE
9244            IF ( .NOT. ALLOCATED( rad_lw_hr_av ) ) THEN
9245               ALLOCATE( rad_lw_hr_av(nzb+1:nzt+1,nysg:nyng,nxlg:nxrg) )
9246               rad_lw_hr_av= REAL( fill_value, KIND = wp )
9247            ENDIF
9248             DO  i = nxl, nxr
9249                DO  j = nys, nyn 
9250                   DO  k = nzb_do, nzt_do
9251                      local_pf(i,j,k) = rad_lw_hr_av(k,j,i)
9252                   ENDDO
9253                ENDDO
9254             ENDDO
9255          ENDIF
9256          IF ( mode == 'xy' )  grid = 'zw'
9257
9258       CASE ( 'rad_sw_in_xy', 'rad_sw_in_xz', 'rad_sw_in_yz' )
9259          IF ( av == 0 ) THEN
9260             DO  i = nxl, nxr
9261                DO  j = nys, nyn
9262                   DO  k = nzb_do, nzt_do
9263                      local_pf(i,j,k) = rad_sw_in(k,j,i)
9264                   ENDDO
9265                ENDDO
9266             ENDDO
9267          ELSE
9268            IF ( .NOT. ALLOCATED( rad_sw_in_av ) ) THEN
9269               ALLOCATE( rad_sw_in_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
9270               rad_sw_in_av = REAL( fill_value, KIND = wp )
9271            ENDIF
9272             DO  i = nxl, nxr
9273                DO  j = nys, nyn 
9274                   DO  k = nzb_do, nzt_do
9275                      local_pf(i,j,k) = rad_sw_in_av(k,j,i)
9276                   ENDDO
9277                ENDDO
9278             ENDDO
9279          ENDIF
9280          IF ( mode == 'xy' )  grid = 'zu'
9281
9282       CASE ( 'rad_sw_out_xy', 'rad_sw_out_xz', 'rad_sw_out_yz' )
9283          IF ( av == 0 ) THEN
9284             DO  i = nxl, nxr
9285                DO  j = nys, nyn
9286                   DO  k = nzb_do, nzt_do
9287                      local_pf(i,j,k) = rad_sw_out(k,j,i)
9288                   ENDDO
9289                ENDDO
9290             ENDDO
9291          ELSE
9292            IF ( .NOT. ALLOCATED( rad_sw_out_av ) ) THEN
9293               ALLOCATE( rad_sw_out_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
9294               rad_sw_out_av = REAL( fill_value, KIND = wp )
9295            ENDIF
9296             DO  i = nxl, nxr
9297                DO  j = nys, nyn 
9298                   DO  k = nzb, nzt+1
9299                      local_pf(i,j,k) = rad_sw_out_av(k,j,i)
9300                   ENDDO
9301                ENDDO
9302             ENDDO
9303          ENDIF
9304          IF ( mode == 'xy' )  grid = 'zu'
9305
9306       CASE ( 'rad_sw_cs_hr_xy', 'rad_sw_cs_hr_xz', 'rad_sw_cs_hr_yz' )
9307          IF ( av == 0 ) THEN
9308             DO  i = nxl, nxr
9309                DO  j = nys, nyn
9310                   DO  k = nzb_do, nzt_do
9311                      local_pf(i,j,k) = rad_sw_cs_hr(k,j,i)
9312                   ENDDO
9313                ENDDO
9314             ENDDO
9315          ELSE
9316            IF ( .NOT. ALLOCATED( rad_sw_cs_hr_av ) ) THEN
9317               ALLOCATE( rad_sw_cs_hr_av(nzb+1:nzt+1,nysg:nyng,nxlg:nxrg) )
9318               rad_sw_cs_hr_av = REAL( fill_value, KIND = wp )
9319            ENDIF
9320             DO  i = nxl, nxr
9321                DO  j = nys, nyn 
9322                   DO  k = nzb_do, nzt_do
9323                      local_pf(i,j,k) = rad_sw_cs_hr_av(k,j,i)
9324                   ENDDO
9325                ENDDO
9326             ENDDO
9327          ENDIF
9328          IF ( mode == 'xy' )  grid = 'zw'
9329
9330       CASE ( 'rad_sw_hr_xy', 'rad_sw_hr_xz', 'rad_sw_hr_yz' )
9331          IF ( av == 0 ) THEN
9332             DO  i = nxl, nxr
9333                DO  j = nys, nyn
9334                   DO  k = nzb_do, nzt_do
9335                      local_pf(i,j,k) = rad_sw_hr(k,j,i)
9336                   ENDDO
9337                ENDDO
9338             ENDDO
9339          ELSE
9340            IF ( .NOT. ALLOCATED( rad_sw_hr_av ) ) THEN
9341               ALLOCATE( rad_sw_hr_av(nzb+1:nzt+1,nysg:nyng,nxlg:nxrg) )
9342               rad_sw_hr_av = REAL( fill_value, KIND = wp )
9343            ENDIF
9344             DO  i = nxl, nxr
9345                DO  j = nys, nyn 
9346                   DO  k = nzb_do, nzt_do
9347                      local_pf(i,j,k) = rad_sw_hr_av(k,j,i)
9348                   ENDDO
9349                ENDDO
9350             ENDDO
9351          ENDIF
9352          IF ( mode == 'xy' )  grid = 'zw'
9353
9354       CASE DEFAULT
9355          found = .FALSE.
9356          grid  = 'none'
9357
9358    END SELECT
9359 
9360 END SUBROUTINE radiation_data_output_2d
9361
9362
9363!------------------------------------------------------------------------------!
9364!
9365! Description:
9366! ------------
9367!> Subroutine defining 3D output variables
9368!------------------------------------------------------------------------------!
9369 SUBROUTINE radiation_data_output_3d( av, variable, found, local_pf, nzb_do, nzt_do )
9370 
9371
9372    USE indices
9373
9374    USE kinds
9375
9376
9377    IMPLICIT NONE
9378
9379    CHARACTER (LEN=*) ::  variable !<
9380
9381    INTEGER(iwp) ::  av          !<
9382    INTEGER(iwp) ::  i, j, k, l  !<
9383    INTEGER(iwp) ::  nzb_do      !<
9384    INTEGER(iwp) ::  nzt_do      !<
9385
9386    LOGICAL      ::  found       !<
9387
9388    REAL(wp)     ::  fill_value = -999.0_wp    !< value for the _FillValue attribute
9389
9390    REAL(sp), DIMENSION(nxl:nxr,nys:nyn,nzb_do:nzt_do) ::  local_pf !<
9391
9392    found = .TRUE.
9393
9394
9395    SELECT CASE ( TRIM( variable ) )
9396
9397      CASE ( 'rad_sw_in' )
9398         IF ( av == 0 )  THEN
9399            DO  i = nxl, nxr
9400               DO  j = nys, nyn
9401                  DO  k = nzb_do, nzt_do
9402                     local_pf(i,j,k) = rad_sw_in(k,j,i)
9403                  ENDDO
9404               ENDDO
9405            ENDDO
9406         ELSE
9407            IF ( .NOT. ALLOCATED( rad_sw_in_av ) ) THEN
9408               ALLOCATE( rad_sw_in_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
9409               rad_sw_in_av = REAL( fill_value, KIND = wp )
9410            ENDIF
9411            DO  i = nxl, nxr
9412               DO  j = nys, nyn
9413                  DO  k = nzb_do, nzt_do
9414                     local_pf(i,j,k) = rad_sw_in_av(k,j,i)
9415                  ENDDO
9416               ENDDO
9417            ENDDO
9418         ENDIF
9419
9420      CASE ( 'rad_sw_out' )
9421         IF ( av == 0 )  THEN
9422            DO  i = nxl, nxr
9423               DO  j = nys, nyn
9424                  DO  k = nzb_do, nzt_do
9425                     local_pf(i,j,k) = rad_sw_out(k,j,i)
9426                  ENDDO
9427               ENDDO
9428            ENDDO
9429         ELSE
9430            IF ( .NOT. ALLOCATED( rad_sw_out_av ) ) THEN
9431               ALLOCATE( rad_sw_out_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
9432               rad_sw_out_av = REAL( fill_value, KIND = wp )
9433            ENDIF
9434            DO  i = nxl, nxr
9435               DO  j = nys, nyn
9436                  DO  k = nzb_do, nzt_do
9437                     local_pf(i,j,k) = rad_sw_out_av(k,j,i)
9438                  ENDDO
9439               ENDDO
9440            ENDDO
9441         ENDIF
9442
9443      CASE ( 'rad_sw_cs_hr' )
9444         IF ( av == 0 )  THEN
9445            DO  i = nxl, nxr
9446               DO  j = nys, nyn
9447                  DO  k = nzb_do, nzt_do
9448                     local_pf(i,j,k) = rad_sw_cs_hr(k,j,i)
9449                  ENDDO
9450               ENDDO
9451            ENDDO
9452         ELSE
9453            IF ( .NOT. ALLOCATED( rad_sw_cs_hr_av ) ) THEN
9454               ALLOCATE( rad_sw_cs_hr_av(nzb+1:nzt+1,nysg:nyng,nxlg:nxrg) )
9455               rad_sw_cs_hr_av = REAL( fill_value, KIND = wp )
9456            ENDIF
9457            DO  i = nxl, nxr
9458               DO  j = nys, nyn
9459                  DO  k = nzb_do, nzt_do
9460                     local_pf(i,j,k) = rad_sw_cs_hr_av(k,j,i)
9461                  ENDDO
9462               ENDDO
9463            ENDDO
9464         ENDIF
9465
9466      CASE ( 'rad_sw_hr' )
9467         IF ( av == 0 )  THEN
9468            DO  i = nxl, nxr
9469               DO  j = nys, nyn
9470                  DO  k = nzb_do, nzt_do
9471                     local_pf(i,j,k) = rad_sw_hr(k,j,i)
9472                  ENDDO
9473               ENDDO
9474            ENDDO
9475         ELSE
9476            IF ( .NOT. ALLOCATED( rad_sw_hr_av ) ) THEN
9477               ALLOCATE( rad_sw_hr_av(nzb+1:nzt+1,nysg:nyng,nxlg:nxrg) )
9478               rad_sw_hr_av = REAL( fill_value, KIND = wp )
9479            ENDIF
9480            DO  i = nxl, nxr
9481               DO  j = nys, nyn
9482                  DO  k = nzb_do, nzt_do
9483                     local_pf(i,j,k) = rad_sw_hr_av(k,j,i)
9484                  ENDDO
9485               ENDDO
9486            ENDDO
9487         ENDIF
9488
9489      CASE ( 'rad_lw_in' )
9490         IF ( av == 0 )  THEN
9491            DO  i = nxl, nxr
9492               DO  j = nys, nyn
9493                  DO  k = nzb_do, nzt_do
9494                     local_pf(i,j,k) = rad_lw_in(k,j,i)
9495                  ENDDO
9496               ENDDO
9497            ENDDO
9498         ELSE
9499            IF ( .NOT. ALLOCATED( rad_lw_in_av ) ) THEN
9500               ALLOCATE( rad_lw_in_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
9501               rad_lw_in_av = REAL( fill_value, KIND = wp )
9502            ENDIF
9503            DO  i = nxl, nxr
9504               DO  j = nys, nyn
9505                  DO  k = nzb_do, nzt_do
9506                     local_pf(i,j,k) = rad_lw_in_av(k,j,i)
9507                  ENDDO
9508               ENDDO
9509            ENDDO
9510         ENDIF
9511
9512      CASE ( 'rad_lw_out' )
9513         IF ( av == 0 )  THEN
9514            DO  i = nxl, nxr
9515               DO  j = nys, nyn
9516                  DO  k = nzb_do, nzt_do
9517                     local_pf(i,j,k) = rad_lw_out(k,j,i)
9518                  ENDDO
9519               ENDDO
9520            ENDDO
9521         ELSE
9522            IF ( .NOT. ALLOCATED( rad_lw_out_av ) ) THEN
9523               ALLOCATE( rad_lw_out_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
9524               rad_lw_out_av = REAL( fill_value, KIND = wp )
9525            ENDIF
9526            DO  i = nxl, nxr
9527               DO  j = nys, nyn
9528                  DO  k = nzb_do, nzt_do
9529                     local_pf(i,j,k) = rad_lw_out_av(k,j,i)
9530                  ENDDO
9531               ENDDO
9532            ENDDO
9533         ENDIF
9534
9535      CASE ( 'rad_lw_cs_hr' )
9536         IF ( av == 0 )  THEN
9537            DO  i = nxl, nxr
9538               DO  j = nys, nyn
9539                  DO  k = nzb_do, nzt_do
9540                     local_pf(i,j,k) = rad_lw_cs_hr(k,j,i)
9541                  ENDDO
9542               ENDDO
9543            ENDDO
9544         ELSE
9545            IF ( .NOT. ALLOCATED( rad_lw_cs_hr_av ) ) THEN
9546               ALLOCATE( rad_lw_cs_hr_av(nzb+1:nzt+1,nysg:nyng,nxlg:nxrg) )
9547               rad_lw_cs_hr_av = REAL( fill_value, KIND = wp )
9548            ENDIF
9549            DO  i = nxl, nxr
9550               DO  j = nys, nyn
9551                  DO  k = nzb_do, nzt_do
9552                     local_pf(i,j,k) = rad_lw_cs_hr_av(k,j,i)
9553                  ENDDO
9554               ENDDO
9555            ENDDO
9556         ENDIF
9557
9558      CASE ( 'rad_lw_hr' )
9559         IF ( av == 0 )  THEN
9560            DO  i = nxl, nxr
9561               DO  j = nys, nyn
9562                  DO  k = nzb_do, nzt_do
9563                     local_pf(i,j,k) = rad_lw_hr(k,j,i)
9564                  ENDDO
9565               ENDDO
9566            ENDDO
9567         ELSE
9568            IF ( .NOT. ALLOCATED( rad_lw_hr_av ) ) THEN
9569               ALLOCATE( rad_lw_hr_av(nzb+1:nzt+1,nysg:nyng,nxlg:nxrg) )
9570              rad_lw_hr_av = REAL( fill_value, KIND = wp )
9571            ENDIF
9572            DO  i = nxl, nxr
9573               DO  j = nys, nyn
9574                  DO  k = nzb_do, nzt_do
9575                     local_pf(i,j,k) = rad_lw_hr_av(k,j,i)
9576                  ENDDO
9577               ENDDO
9578            ENDDO
9579         ENDIF
9580
9581      CASE ( 'rad_mrt_sw' )
9582         local_pf = REAL( fill_value, KIND = wp )
9583         IF ( av == 0 )  THEN
9584            DO  l = 1, nmrtbl
9585               i = mrtbl(ix,l)
9586               j = mrtbl(iy,l)
9587               k = mrtbl(iz,l)
9588               local_pf(i,j,k) = mrtinsw(l)
9589            ENDDO
9590         ELSE
9591            IF ( ALLOCATED( mrtinsw_av ) ) THEN
9592               DO  l = 1, nmrtbl
9593                  i = mrtbl(ix,l)
9594                  j = mrtbl(iy,l)
9595                  k = mrtbl(iz,l)
9596                  local_pf(i,j,k) = mrtinsw_av(l)
9597               ENDDO
9598            ENDIF
9599         ENDIF
9600
9601      CASE ( 'rad_mrt_lw' )
9602         local_pf = REAL( fill_value, KIND = wp )
9603         IF ( av == 0 )  THEN
9604            DO  l = 1, nmrtbl
9605               i = mrtbl(ix,l)
9606               j = mrtbl(iy,l)
9607               k = mrtbl(iz,l)
9608               local_pf(i,j,k) = mrtinlw(l)
9609            ENDDO
9610         ELSE
9611            IF ( ALLOCATED( mrtinlw_av ) ) THEN
9612               DO  l = 1, nmrtbl
9613                  i = mrtbl(ix,l)
9614                  j = mrtbl(iy,l)
9615                  k = mrtbl(iz,l)
9616                  local_pf(i,j,k) = mrtinlw_av(l)
9617               ENDDO
9618            ENDIF
9619         ENDIF
9620
9621      CASE ( 'rad_mrt' )
9622         local_pf = REAL( fill_value, KIND = wp )
9623         IF ( av == 0 )  THEN
9624            DO  l = 1, nmrtbl
9625               i = mrtbl(ix,l)
9626               j = mrtbl(iy,l)
9627               k = mrtbl(iz,l)
9628               local_pf(i,j,k) = mrt(l)
9629            ENDDO
9630         ELSE
9631            IF ( ALLOCATED( mrt_av ) ) THEN
9632               DO  l = 1, nmrtbl
9633                  i = mrtbl(ix,l)
9634                  j = mrtbl(iy,l)
9635                  k = mrtbl(iz,l)
9636                  local_pf(i,j,k) = mrt_av(l)
9637               ENDDO
9638            ENDIF
9639         ENDIF
9640
9641       CASE DEFAULT
9642          found = .FALSE.
9643
9644    END SELECT
9645
9646
9647 END SUBROUTINE radiation_data_output_3d
9648
9649!------------------------------------------------------------------------------!
9650!
9651! Description:
9652! ------------
9653!> Subroutine defining masked data output
9654!------------------------------------------------------------------------------!
9655 SUBROUTINE radiation_data_output_mask( av, variable, found, local_pf )
9656 
9657    USE control_parameters
9658       
9659    USE indices
9660   
9661    USE kinds
9662   
9663
9664    IMPLICIT NONE
9665
9666    CHARACTER (LEN=*) ::  variable   !<
9667
9668    INTEGER(iwp) ::  av   !<
9669    INTEGER(iwp) ::  i    !<
9670    INTEGER(iwp) ::  j    !<
9671    INTEGER(iwp) ::  k    !<
9672
9673    LOGICAL ::  found     !<
9674
9675    REAL(wp),                                                                  &
9676       DIMENSION(mask_size_l(mid,1),mask_size_l(mid,2),mask_size_l(mid,3)) ::  &
9677          local_pf   !<
9678
9679
9680    found = .TRUE.
9681
9682    SELECT CASE ( TRIM( variable ) )
9683
9684
9685       CASE ( 'rad_lw_in' )
9686          IF ( av == 0 )  THEN
9687             DO  i = 1, mask_size_l(mid,1)
9688                DO  j = 1, mask_size_l(mid,2)
9689                   DO  k = 1, mask_size_l(mid,3)
9690                       local_pf(i,j,k) = rad_lw_in(mask_k(mid,k),              &
9691                                            mask_j(mid,j),mask_i(mid,i))
9692                    ENDDO
9693                 ENDDO
9694              ENDDO
9695          ELSE
9696             DO  i = 1, mask_size_l(mid,1)
9697                DO  j = 1, mask_size_l(mid,2)
9698                   DO  k = 1, mask_size_l(mid,3)
9699                       local_pf(i,j,k) = rad_lw_in_av(mask_k(mid,k),           &
9700                                               mask_j(mid,j),mask_i(mid,i))
9701                   ENDDO
9702                ENDDO
9703             ENDDO
9704          ENDIF
9705
9706       CASE ( 'rad_lw_out' )
9707          IF ( av == 0 )  THEN
9708             DO  i = 1, mask_size_l(mid,1)
9709                DO  j = 1, mask_size_l(mid,2)
9710                   DO  k = 1, mask_size_l(mid,3)
9711                       local_pf(i,j,k) = rad_lw_out(mask_k(mid,k),             &
9712                                            mask_j(mid,j),mask_i(mid,i))
9713                    ENDDO
9714                 ENDDO
9715              ENDDO
9716          ELSE
9717             DO  i = 1, mask_size_l(mid,1)
9718                DO  j = 1, mask_size_l(mid,2)
9719                   DO  k = 1, mask_size_l(mid,3)
9720                       local_pf(i,j,k) = rad_lw_out_av(mask_k(mid,k),          &
9721                                               mask_j(mid,j),mask_i(mid,i))
9722                   ENDDO
9723                ENDDO
9724             ENDDO
9725          ENDIF
9726
9727       CASE ( 'rad_lw_cs_hr' )
9728          IF ( av == 0 )  THEN
9729             DO  i = 1, mask_size_l(mid,1)
9730                DO  j = 1, mask_size_l(mid,2)
9731                   DO  k = 1, mask_size_l(mid,3)
9732                       local_pf(i,j,k) = rad_lw_cs_hr(mask_k(mid,k),           &
9733                                            mask_j(mid,j),mask_i(mid,i))
9734                    ENDDO
9735                 ENDDO
9736              ENDDO
9737          ELSE
9738             DO  i = 1, mask_size_l(mid,1)
9739                DO  j = 1, mask_size_l(mid,2)
9740                   DO  k = 1, mask_size_l(mid,3)
9741                       local_pf(i,j,k) = rad_lw_cs_hr_av(mask_k(mid,k),        &
9742                                               mask_j(mid,j),mask_i(mid,i))
9743                   ENDDO
9744                ENDDO
9745             ENDDO
9746          ENDIF
9747
9748       CASE ( 'rad_lw_hr' )
9749          IF ( av == 0 )  THEN
9750             DO  i = 1, mask_size_l(mid,1)
9751                DO  j = 1, mask_size_l(mid,2)
9752                   DO  k = 1, mask_size_l(mid,3)
9753                       local_pf(i,j,k) = rad_lw_hr(mask_k(mid,k),              &
9754                                            mask_j(mid,j),mask_i(mid,i))
9755                    ENDDO
9756                 ENDDO
9757              ENDDO
9758          ELSE
9759             DO  i = 1, mask_size_l(mid,1)
9760                DO  j = 1, mask_size_l(mid,2)
9761                   DO  k = 1, mask_size_l(mid,3)
9762                       local_pf(i,j,k) = rad_lw_hr_av(mask_k(mid,k),           &
9763                                               mask_j(mid,j),mask_i(mid,i))
9764                   ENDDO
9765                ENDDO
9766             ENDDO
9767          ENDIF
9768
9769       CASE ( 'rad_sw_in' )
9770          IF ( av == 0 )  THEN
9771             DO  i = 1, mask_size_l(mid,1)
9772                DO  j = 1, mask_size_l(mid,2)
9773                   DO  k = 1, mask_size_l(mid,3)
9774                       local_pf(i,j,k) = rad_sw_in(mask_k(mid,k),              &
9775                                            mask_j(mid,j),mask_i(mid,i))
9776                    ENDDO
9777                 ENDDO
9778              ENDDO
9779          ELSE
9780             DO  i = 1, mask_size_l(mid,1)
9781                DO  j = 1, mask_size_l(mid,2)
9782                   DO  k = 1, mask_size_l(mid,3)
9783                       local_pf(i,j,k) = rad_sw_in_av(mask_k(mid,k),           &
9784                                               mask_j(mid,j),mask_i(mid,i))
9785                   ENDDO
9786                ENDDO
9787             ENDDO
9788          ENDIF
9789
9790       CASE ( 'rad_sw_out' )
9791          IF ( av == 0 )  THEN
9792             DO  i = 1, mask_size_l(mid,1)
9793                DO  j = 1, mask_size_l(mid,2)
9794                   DO  k = 1, mask_size_l(mid,3)
9795                       local_pf(i,j,k) = rad_sw_out(mask_k(mid,k),             &
9796                                            mask_j(mid,j),mask_i(mid,i))
9797                    ENDDO
9798                 ENDDO
9799              ENDDO
9800          ELSE
9801             DO  i = 1, mask_size_l(mid,1)
9802                DO  j = 1, mask_size_l(mid,2)
9803                   DO  k = 1, mask_size_l(mid,3)
9804                       local_pf(i,j,k) = rad_sw_out_av(mask_k(mid,k),          &
9805                                               mask_j(mid,j),mask_i(mid,i))
9806                   ENDDO
9807                ENDDO
9808             ENDDO
9809          ENDIF
9810
9811       CASE ( 'rad_sw_cs_hr' )
9812          IF ( av == 0 )  THEN
9813             DO  i = 1, mask_size_l(mid,1)
9814                DO  j = 1, mask_size_l(mid,2)
9815                   DO  k = 1, mask_size_l(mid,3)
9816                       local_pf(i,j,k) = rad_sw_cs_hr(mask_k(mid,k),           &
9817                                            mask_j(mid,j),mask_i(mid,i))
9818                    ENDDO
9819                 ENDDO
9820              ENDDO
9821          ELSE
9822             DO  i = 1, mask_size_l(mid,1)
9823                DO  j = 1, mask_size_l(mid,2)
9824                   DO  k = 1, mask_size_l(mid,3)
9825                       local_pf(i,j,k) = rad_sw_cs_hr_av(mask_k(mid,k),        &
9826                                               mask_j(mid,j),mask_i(mid,i))
9827                   ENDDO
9828                ENDDO
9829             ENDDO
9830          ENDIF
9831
9832       CASE ( 'rad_sw_hr' )
9833          IF ( av == 0 )  THEN
9834             DO  i = 1, mask_size_l(mid,1)
9835                DO  j = 1, mask_size_l(mid,2)
9836                   DO  k = 1, mask_size_l(mid,3)
9837                       local_pf(i,j,k) = rad_sw_hr(mask_k(mid,k),              &
9838                                            mask_j(mid,j),mask_i(mid,i))
9839                    ENDDO
9840                 ENDDO
9841              ENDDO
9842          ELSE
9843             DO  i = 1, mask_size_l(mid,1)
9844                DO  j = 1, mask_size_l(mid,2)
9845                   DO  k = 1, mask_size_l(mid,3)
9846                       local_pf(i,j,k) = rad_sw_hr_av(mask_k(mid,k),           &
9847                                               mask_j(mid,j),mask_i(mid,i))
9848                   ENDDO
9849                ENDDO
9850             ENDDO
9851          ENDIF
9852
9853       CASE DEFAULT
9854          found = .FALSE.
9855
9856    END SELECT
9857
9858
9859 END SUBROUTINE radiation_data_output_mask
9860
9861
9862!------------------------------------------------------------------------------!
9863! Description:
9864! ------------
9865!> Subroutine writes local (subdomain) restart data
9866!------------------------------------------------------------------------------!
9867 SUBROUTINE radiation_wrd_local
9868
9869
9870    IMPLICIT NONE
9871
9872
9873    IF ( ALLOCATED( rad_net_av ) )  THEN
9874       CALL wrd_write_string( 'rad_net_av' )
9875       WRITE ( 14 )  rad_net_av
9876    ENDIF
9877   
9878    IF ( ALLOCATED( rad_lw_in_xy_av ) )  THEN
9879       CALL wrd_write_string( 'rad_lw_in_xy_av' )
9880       WRITE ( 14 )  rad_lw_in_xy_av
9881    ENDIF
9882   
9883    IF ( ALLOCATED( rad_lw_out_xy_av ) )  THEN
9884       CALL wrd_write_string( 'rad_lw_out_xy_av' )
9885       WRITE ( 14 )  rad_lw_out_xy_av
9886    ENDIF
9887   
9888    IF ( ALLOCATED( rad_sw_in_xy_av ) )  THEN
9889       CALL wrd_write_string( 'rad_sw_in_xy_av' )
9890       WRITE ( 14 )  rad_sw_in_xy_av
9891    ENDIF
9892   
9893    IF ( ALLOCATED( rad_sw_out_xy_av ) )  THEN
9894       CALL wrd_write_string( 'rad_sw_out_xy_av' )
9895       WRITE ( 14 )  rad_sw_out_xy_av
9896    ENDIF
9897
9898    IF ( ALLOCATED( rad_lw_in ) )  THEN
9899       CALL wrd_write_string( 'rad_lw_in' )
9900       WRITE ( 14 )  rad_lw_in
9901    ENDIF
9902
9903    IF ( ALLOCATED( rad_lw_in_av ) )  THEN
9904       CALL wrd_write_string( 'rad_lw_in_av' )
9905       WRITE ( 14 )  rad_lw_in_av
9906    ENDIF
9907
9908    IF ( ALLOCATED( rad_lw_out ) )  THEN
9909       CALL wrd_write_string( 'rad_lw_out' )
9910       WRITE ( 14 )  rad_lw_out
9911    ENDIF
9912
9913    IF ( ALLOCATED( rad_lw_out_av) )  THEN
9914       CALL wrd_write_string( 'rad_lw_out_av' )
9915       WRITE ( 14 )  rad_lw_out_av
9916    ENDIF
9917
9918    IF ( ALLOCATED( rad_lw_cs_hr) )  THEN
9919       CALL wrd_write_string( 'rad_lw_cs_hr' )
9920       WRITE ( 14 )  rad_lw_cs_hr
9921    ENDIF
9922
9923    IF ( ALLOCATED( rad_lw_cs_hr_av) )  THEN
9924       CALL wrd_write_string( 'rad_lw_cs_hr_av' )
9925       WRITE ( 14 )  rad_lw_cs_hr_av
9926    ENDIF
9927
9928    IF ( ALLOCATED( rad_lw_hr) )  THEN
9929       CALL wrd_write_string( 'rad_lw_hr' )
9930       WRITE ( 14 )  rad_lw_hr
9931    ENDIF
9932
9933    IF ( ALLOCATED( rad_lw_hr_av) )  THEN
9934       CALL wrd_write_string( 'rad_lw_hr_av' )
9935       WRITE ( 14 )  rad_lw_hr_av
9936    ENDIF
9937
9938    IF ( ALLOCATED( rad_sw_in) )  THEN
9939       CALL wrd_write_string( 'rad_sw_in' )
9940       WRITE ( 14 )  rad_sw_in
9941    ENDIF
9942
9943    IF ( ALLOCATED( rad_sw_in_av) )  THEN
9944       CALL wrd_write_string( 'rad_sw_in_av' )
9945       WRITE ( 14 )  rad_sw_in_av
9946    ENDIF
9947
9948    IF ( ALLOCATED( rad_sw_out) )  THEN
9949       CALL wrd_write_string( 'rad_sw_out' )
9950       WRITE ( 14 )  rad_sw_out
9951    ENDIF
9952
9953    IF ( ALLOCATED( rad_sw_out_av) )  THEN
9954       CALL wrd_write_string( 'rad_sw_out_av' )
9955       WRITE ( 14 )  rad_sw_out_av
9956    ENDIF
9957
9958    IF ( ALLOCATED( rad_sw_cs_hr) )  THEN
9959       CALL wrd_write_string( 'rad_sw_cs_hr' )
9960       WRITE ( 14 )  rad_sw_cs_hr
9961    ENDIF
9962
9963    IF ( ALLOCATED( rad_sw_cs_hr_av) )  THEN
9964       CALL wrd_write_string( 'rad_sw_cs_hr_av' )
9965       WRITE ( 14 )  rad_sw_cs_hr_av
9966    ENDIF
9967
9968    IF ( ALLOCATED( rad_sw_hr) )  THEN
9969       CALL wrd_write_string( 'rad_sw_hr' )
9970       WRITE ( 14 )  rad_sw_hr
9971    ENDIF
9972
9973    IF ( ALLOCATED( rad_sw_hr_av) )  THEN
9974       CALL wrd_write_string( 'rad_sw_hr_av' )
9975       WRITE ( 14 )  rad_sw_hr_av
9976    ENDIF
9977
9978
9979 END SUBROUTINE radiation_wrd_local
9980
9981!------------------------------------------------------------------------------!
9982! Description:
9983! ------------
9984!> Subroutine reads local (subdomain) restart data
9985!------------------------------------------------------------------------------!
9986 SUBROUTINE radiation_rrd_local( i, k, nxlf, nxlc, nxl_on_file, nxrf, nxrc,    &
9987                                nxr_on_file, nynf, nync, nyn_on_file, nysf,    &
9988                                nysc, nys_on_file, tmp_2d, tmp_3d, found )
9989 
9990
9991    USE control_parameters
9992       
9993    USE indices
9994   
9995    USE kinds
9996   
9997    USE pegrid
9998
9999
10000    IMPLICIT NONE
10001
10002    INTEGER(iwp) ::  i               !<
10003    INTEGER(iwp) ::  k               !<
10004    INTEGER(iwp) ::  nxlc            !<
10005    INTEGER(iwp) ::  nxlf            !<
10006    INTEGER(iwp) ::  nxl_on_file     !<
10007    INTEGER(iwp) ::  nxrc            !<
10008    INTEGER(iwp) ::  nxrf            !<
10009    INTEGER(iwp) ::  nxr_on_file     !<
10010    INTEGER(iwp) ::  nync            !<
10011    INTEGER(iwp) ::  nynf            !<
10012    INTEGER(iwp) ::  nyn_on_file     !<
10013    INTEGER(iwp) ::  nysc            !<
10014    INTEGER(iwp) ::  nysf            !<
10015    INTEGER(iwp) ::  nys_on_file     !<
10016
10017    LOGICAL, INTENT(OUT)  :: found
10018
10019    REAL(wp), DIMENSION(nys_on_file-nbgp:nyn_on_file+nbgp,nxl_on_file-nbgp:nxr_on_file+nbgp) :: tmp_2d   !<
10020
10021    REAL(wp), DIMENSION(nzb:nzt+1,nys_on_file-nbgp:nyn_on_file+nbgp,nxl_on_file-nbgp:nxr_on_file+nbgp) :: tmp_3d   !<
10022
10023    REAL(wp), DIMENSION(0:0,nys_on_file-nbgp:nyn_on_file+nbgp,nxl_on_file-nbgp:nxr_on_file+nbgp) :: tmp_3d2   !<
10024
10025
10026    found = .TRUE.
10027
10028
10029    SELECT CASE ( restart_string(1:length) )
10030
10031       CASE ( 'rad_net_av' )
10032          IF ( .NOT. ALLOCATED( rad_net_av ) )  THEN
10033             ALLOCATE( rad_net_av(nysg:nyng,nxlg:nxrg) )
10034          ENDIF 
10035          IF ( k == 1 )  READ ( 13 )  tmp_2d
10036          rad_net_av(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  =           &
10037                        tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10038                       
10039       CASE ( 'rad_lw_in_xy_av' )
10040          IF ( .NOT. ALLOCATED( rad_lw_in_xy_av ) )  THEN
10041             ALLOCATE( rad_lw_in_xy_av(nysg:nyng,nxlg:nxrg) )
10042          ENDIF 
10043          IF ( k == 1 )  READ ( 13 )  tmp_2d
10044          rad_lw_in_xy_av(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  =      &
10045                        tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10046                       
10047       CASE ( 'rad_lw_out_xy_av' )
10048          IF ( .NOT. ALLOCATED( rad_lw_out_xy_av ) )  THEN
10049             ALLOCATE( rad_lw_out_xy_av(nysg:nyng,nxlg:nxrg) )
10050          ENDIF 
10051          IF ( k == 1 )  READ ( 13 )  tmp_2d
10052          rad_lw_out_xy_av(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  =     &
10053                        tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10054                       
10055       CASE ( 'rad_sw_in_xy_av' )
10056          IF ( .NOT. ALLOCATED( rad_sw_in_xy_av ) )  THEN
10057             ALLOCATE( rad_sw_in_xy_av(nysg:nyng,nxlg:nxrg) )
10058          ENDIF 
10059          IF ( k == 1 )  READ ( 13 )  tmp_2d
10060          rad_sw_in_xy_av(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  =      &
10061                        tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10062                       
10063       CASE ( 'rad_sw_out_xy_av' )
10064          IF ( .NOT. ALLOCATED( rad_sw_out_xy_av ) )  THEN
10065             ALLOCATE( rad_sw_out_xy_av(nysg:nyng,nxlg:nxrg) )
10066          ENDIF 
10067          IF ( k == 1 )  READ ( 13 )  tmp_2d
10068          rad_sw_out_xy_av(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  =     &
10069                        tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10070                       
10071       CASE ( 'rad_lw_in' )
10072          IF ( .NOT. ALLOCATED( rad_lw_in ) )  THEN
10073             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
10074                  radiation_scheme == 'constant')  THEN
10075                ALLOCATE( rad_lw_in(0:0,nysg:nyng,nxlg:nxrg) )
10076             ELSE
10077                ALLOCATE( rad_lw_in(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
10078             ENDIF
10079          ENDIF 
10080          IF ( k == 1 )  THEN
10081             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
10082                  radiation_scheme == 'constant')  THEN
10083                READ ( 13 )  tmp_3d2
10084                rad_lw_in(0:0,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =   &
10085                   tmp_3d2(0:0,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10086             ELSE
10087                READ ( 13 )  tmp_3d
10088                rad_lw_in(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =     &
10089                    tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10090             ENDIF
10091          ENDIF
10092
10093       CASE ( 'rad_lw_in_av' )
10094          IF ( .NOT. ALLOCATED( rad_lw_in_av ) )  THEN
10095             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
10096                  radiation_scheme == 'constant')  THEN
10097                ALLOCATE( rad_lw_in_av(0:0,nysg:nyng,nxlg:nxrg) )
10098             ELSE
10099                ALLOCATE( rad_lw_in_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
10100             ENDIF
10101          ENDIF 
10102          IF ( k == 1 )  THEN
10103             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
10104                  radiation_scheme == 'constant')  THEN
10105                READ ( 13 )  tmp_3d2
10106                rad_lw_in_av(0:0,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =&
10107                    tmp_3d2(0:0,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10108             ELSE
10109                READ ( 13 )  tmp_3d
10110                rad_lw_in_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =  &
10111                    tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10112             ENDIF
10113          ENDIF
10114
10115       CASE ( 'rad_lw_out' )
10116          IF ( .NOT. ALLOCATED( rad_lw_out ) )  THEN
10117             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
10118                  radiation_scheme == 'constant')  THEN
10119                ALLOCATE( rad_lw_out(0:0,nysg:nyng,nxlg:nxrg) )
10120             ELSE
10121                ALLOCATE( rad_lw_out(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
10122             ENDIF
10123          ENDIF 
10124          IF ( k == 1 )  THEN
10125             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
10126                  radiation_scheme == 'constant')  THEN
10127                READ ( 13 )  tmp_3d2
10128                rad_lw_out(0:0,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =  &
10129                    tmp_3d2(0:0,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10130             ELSE
10131                READ ( 13 )  tmp_3d
10132                rad_lw_out(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =    &
10133                    tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10134             ENDIF
10135          ENDIF
10136
10137       CASE ( 'rad_lw_out_av' )
10138          IF ( .NOT. ALLOCATED( rad_lw_out_av ) )  THEN
10139             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
10140                  radiation_scheme == 'constant')  THEN
10141                ALLOCATE( rad_lw_out_av(0:0,nysg:nyng,nxlg:nxrg) )
10142             ELSE
10143                ALLOCATE( rad_lw_out_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
10144             ENDIF
10145          ENDIF 
10146          IF ( k == 1 )  THEN
10147             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
10148                  radiation_scheme == 'constant')  THEN
10149                READ ( 13 )  tmp_3d2
10150                rad_lw_out_av(0:0,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) &
10151                   = tmp_3d2(0:0,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10152             ELSE
10153                READ ( 13 )  tmp_3d
10154                rad_lw_out_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) = &
10155                    tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10156             ENDIF
10157          ENDIF
10158
10159       CASE ( 'rad_lw_cs_hr' )
10160          IF ( .NOT. ALLOCATED( rad_lw_cs_hr ) )  THEN
10161             ALLOCATE( rad_lw_cs_hr(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
10162          ENDIF
10163          IF ( k == 1 )  READ ( 13 )  tmp_3d
10164          rad_lw_cs_hr(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =        &
10165                  tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10166
10167       CASE ( 'rad_lw_cs_hr_av' )
10168          IF ( .NOT. ALLOCATED( rad_lw_cs_hr_av ) )  THEN
10169             ALLOCATE( rad_lw_cs_hr_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
10170          ENDIF
10171          IF ( k == 1 )  READ ( 13 )  tmp_3d
10172          rad_lw_cs_hr_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =     &
10173                  tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10174
10175       CASE ( 'rad_lw_hr' )
10176          IF ( .NOT. ALLOCATED( rad_lw_hr ) )  THEN
10177             ALLOCATE( rad_lw_hr(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
10178          ENDIF
10179          IF ( k == 1 )  READ ( 13 )  tmp_3d
10180          rad_lw_hr(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =           &
10181                  tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10182
10183       CASE ( 'rad_lw_hr_av' )
10184          IF ( .NOT. ALLOCATED( rad_lw_hr_av ) )  THEN
10185             ALLOCATE( rad_lw_hr_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
10186          ENDIF
10187          IF ( k == 1 )  READ ( 13 )  tmp_3d
10188          rad_lw_hr_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =        &
10189                  tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10190
10191       CASE ( 'rad_sw_in' )
10192          IF ( .NOT. ALLOCATED( rad_sw_in ) )  THEN
10193             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
10194                  radiation_scheme == 'constant')  THEN
10195                ALLOCATE( rad_sw_in(0:0,nysg:nyng,nxlg:nxrg) )
10196             ELSE
10197                ALLOCATE( rad_sw_in(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
10198             ENDIF
10199          ENDIF 
10200          IF ( k == 1 )  THEN
10201             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
10202                  radiation_scheme == 'constant')  THEN
10203                READ ( 13 )  tmp_3d2
10204                rad_sw_in(0:0,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =   &
10205                    tmp_3d2(0:0,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10206             ELSE
10207                READ ( 13 )  tmp_3d
10208                rad_sw_in(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =     &
10209                    tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10210             ENDIF
10211          ENDIF
10212
10213       CASE ( 'rad_sw_in_av' )
10214          IF ( .NOT. ALLOCATED( rad_sw_in_av ) )  THEN
10215             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
10216                  radiation_scheme == 'constant')  THEN
10217                ALLOCATE( rad_sw_in_av(0:0,nysg:nyng,nxlg:nxrg) )
10218             ELSE
10219                ALLOCATE( rad_sw_in_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
10220             ENDIF
10221          ENDIF 
10222          IF ( k == 1 )  THEN
10223             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
10224                  radiation_scheme == 'constant')  THEN
10225                READ ( 13 )  tmp_3d2
10226                rad_sw_in_av(0:0,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =&
10227                    tmp_3d2(0:0,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10228             ELSE
10229                READ ( 13 )  tmp_3d
10230                rad_sw_in_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =  &
10231                    tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10232             ENDIF
10233          ENDIF
10234
10235       CASE ( 'rad_sw_out' )
10236          IF ( .NOT. ALLOCATED( rad_sw_out ) )  THEN
10237             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
10238                  radiation_scheme == 'constant')  THEN
10239                ALLOCATE( rad_sw_out(0:0,nysg:nyng,nxlg:nxrg) )
10240             ELSE
10241                ALLOCATE( rad_sw_out(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
10242             ENDIF
10243          ENDIF 
10244          IF ( k == 1 )  THEN
10245             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
10246                  radiation_scheme == 'constant')  THEN
10247                READ ( 13 )  tmp_3d2
10248                rad_sw_out(0:0,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =  &
10249                    tmp_3d2(0:0,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10250             ELSE
10251                READ ( 13 )  tmp_3d
10252                rad_sw_out(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =    &
10253                    tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10254             ENDIF
10255          ENDIF
10256
10257       CASE ( 'rad_sw_out_av' )
10258          IF ( .NOT. ALLOCATED( rad_sw_out_av ) )  THEN
10259             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
10260                  radiation_scheme == 'constant')  THEN
10261                ALLOCATE( rad_sw_out_av(0:0,nysg:nyng,nxlg:nxrg) )
10262             ELSE
10263                ALLOCATE( rad_sw_out_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
10264             ENDIF
10265          ENDIF 
10266          IF ( k == 1 )  THEN
10267             IF ( radiation_scheme == 'clear-sky'  .OR.                    &
10268                  radiation_scheme == 'constant')  THEN
10269                READ ( 13 )  tmp_3d2
10270                rad_sw_out_av(0:0,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) &
10271                   = tmp_3d2(0:0,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10272             ELSE
10273                READ ( 13 )  tmp_3d
10274                rad_sw_out_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) = &
10275                    tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10276             ENDIF
10277          ENDIF
10278
10279       CASE ( 'rad_sw_cs_hr' )
10280          IF ( .NOT. ALLOCATED( rad_sw_cs_hr ) )  THEN
10281             ALLOCATE( rad_sw_cs_hr(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
10282          ENDIF
10283          IF ( k == 1 )  READ ( 13 )  tmp_3d
10284          rad_sw_cs_hr(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =        &
10285                  tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10286
10287       CASE ( 'rad_sw_cs_hr_av' )
10288          IF ( .NOT. ALLOCATED( rad_sw_cs_hr_av ) )  THEN
10289             ALLOCATE( rad_sw_cs_hr_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
10290          ENDIF
10291          IF ( k == 1 )  READ ( 13 )  tmp_3d
10292          rad_sw_cs_hr_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =     &
10293                  tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10294
10295       CASE ( 'rad_sw_hr' )
10296          IF ( .NOT. ALLOCATED( rad_sw_hr ) )  THEN
10297             ALLOCATE( rad_sw_hr(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
10298          ENDIF
10299          IF ( k == 1 )  READ ( 13 )  tmp_3d
10300          rad_sw_hr(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =           &
10301                  tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10302
10303       CASE ( 'rad_sw_hr_av' )
10304          IF ( .NOT. ALLOCATED( rad_sw_hr_av ) )  THEN
10305             ALLOCATE( rad_sw_hr_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
10306          ENDIF
10307          IF ( k == 1 )  READ ( 13 )  tmp_3d
10308          rad_lw_hr_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =        &
10309                  tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
10310
10311       CASE DEFAULT
10312
10313          found = .FALSE.
10314
10315    END SELECT
10316
10317 END SUBROUTINE radiation_rrd_local
10318
10319!------------------------------------------------------------------------------!
10320! Description:
10321! ------------
10322!> Subroutine writes debug information
10323!------------------------------------------------------------------------------!
10324 SUBROUTINE radiation_write_debug_log ( message )
10325    !> it writes debug log with time stamp
10326    CHARACTER(*)  :: message
10327    CHARACTER(15) :: dtc
10328    CHARACTER(8)  :: date
10329    CHARACTER(10) :: time
10330    CHARACTER(5)  :: zone
10331    CALL date_and_time(date, time, zone)
10332    dtc = date(7:8)//','//time(1:2)//':'//time(3:4)//':'//time(5:10)
10333    WRITE(9,'(2A)') dtc, TRIM(message)
10334    FLUSH(9)
10335 END SUBROUTINE radiation_write_debug_log
10336
10337 END MODULE radiation_model_mod
Note: See TracBrowser for help on using the repository browser.