Ignore:
Timestamp:
Oct 29, 2018 7:36:56 PM (5 years ago)
Author:
suehring
Message:

Branch resler -r 3439 re-integrated into current trunk: RTM 3.0, transpiration of plant canopy, output fixes in USM

File:
1 edited

Legend:

Unmodified
Added
Removed
  • palm/trunk/SOURCE/radiation_model_mod.f90

    r3435 r3449  
    2828! -----------------
    2929! $Id$
     30! New RTM version 3.0: (Pavel Krc, Jaroslav Resler, ICS, Prague)
     31!   - Interaction of plant canopy with LW radiation
     32!   - Transpiration from resolved plant canopy dependent on radiation
     33!     called from RTM
     34!
     35!
     36! 3435 2018-10-26 18:25:44Z gronemeier
    3037! - workaround: return unit=illegal in check_data_output for certain variables
    3138!   when check called from init_masks
     
    499506
    500507    USE basic_constants_and_equations_mod,                                     &
    501         ONLY:  c_p, g, lv_d_cp, l_v, pi, r_d, rho_l, solar_constant,           &
     508        ONLY:  c_p, g, lv_d_cp, l_v, pi, r_d, rho_l, solar_constant,      &
    502509               barometric_formula
    503510
     
    544551
    545552    USE plant_canopy_model_mod,                                                &
    546         ONLY:  lad_s, pc_heating_rate, pc_transpiration_rate
     553        ONLY:  lad_s, pc_heating_rate, pc_transpiration_rate, pc_latent_rate,  &
     554               plant_canopy_transpiration, pcm_calc_transpiration_rate
    547555
    548556    USE pegrid
     
    853861    INTEGER(iwp), DIMENSION(0:nsurf_type), PARAMETER ::  jdir = (/0, 0,1,-1,0, 0,0,1,-1,0, 0/)   !< surface normal direction y indices
    854862    INTEGER(iwp), DIMENSION(0:nsurf_type), PARAMETER ::  kdir = (/1,-1,0, 0,0, 0,1,0, 0,0, 0/)   !< surface normal direction z indices
    855                                                                                           !< parameter but set in the code
     863    REAL(wp),     DIMENSION(0:nsurf_type)          :: facearea                            !< area of single face in respective
     864                                                                                          !< direction (will be calc'd)
    856865
    857866
     
    887896!-- configuration parameters (they can be setup in PALM config)
    888897    LOGICAL                                        ::  raytrace_mpi_rma = .TRUE.          !< use MPI RMA to access LAD and gridsurf from remote processes during raytracing
    889     LOGICAL                                        ::  read_svf_on_init = .FALSE.         !< flag parameter indicating wheather SVFs will be read from a file at initialization
    890     LOGICAL                                        ::  write_svf_on_init = .FALSE.        !< flag parameter indicating wheather SVFs will be written out to a file
    891     LOGICAL                                        ::  rad_angular_discretization = .TRUE.!< whether to use fixed resolution discretization of view factors for
     898    LOGICAL                                        ::  rad_angular_discretization = .TRUE.!< whether to use fixed resolution discretization of view factors for
    892899                                                                                          !< reflected radiation (as opposed to all mutually visible pairs)
     900    LOGICAL                                        ::  plant_lw_interact = .TRUE.         !< whether plant canopy interacts with LW radiation (in addition to SW)
    893901    INTEGER(iwp)                                   ::  mrt_nlevels = 0                    !< number of vertical boxes above surface for which to calculate MRT
    894902    LOGICAL                                        ::  mrt_skip_roof = .TRUE.             !< do not calculate MRT above roof surfaces
    895903    LOGICAL                                        ::  mrt_include_sw = .TRUE.            !< should MRT calculation include SW radiation as well?
    896     INTEGER(iwp)                                   ::  nrefsteps = 0                      !< number of reflection steps to perform
     904    INTEGER(iwp)                                   ::  nrefsteps = 3                      !< number of reflection steps to perform
    897905    REAL(wp), PARAMETER                            ::  ext_coef = 0.6_wp                  !< extinction coefficient (a.k.a. alpha)
    898906    INTEGER(iwp), PARAMETER                        ::  rad_version_len = 10               !< length of identification string of rad version
    899     CHARACTER(rad_version_len), PARAMETER          ::  rad_version = 'RAD v. 1.1'         !< identification of version of binary svf and restart files
     907    CHARACTER(rad_version_len), PARAMETER          ::  rad_version = 'RAD v. 3.0'         !< identification of version of binary svf and restart files
    900908    INTEGER(iwp)                                   ::  raytrace_discrete_elevs = 40       !< number of discretization steps for elevation (nadir to zenith)
    901909    INTEGER(iwp)                                   ::  raytrace_discrete_azims = 80       !< number of discretization steps for azimuth (out of 360 degrees)
     
    929937        INTEGER(iwp)                               :: ity               !<
    930938        INTEGER(iwp)                               :: itz               !<
    931         INTEGER(iwp)                               :: isurfs            !<
    932         REAL(wp)                                   :: rsvf              !<
     939        INTEGER(iwp)                               :: isurfs            !< Idx of source face / -1 for sky
     940        REAL(wp)                                   :: rcvf              !< Canopy view factor for faces /
     941                                                                        !< canopy sink factor for sky (-1)
    933942    END TYPE
    934943
     
    976985    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfouts         !< array of reflected sw radiation for all surfaces in i-th reflection
    977986    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfoutl         !< array of reflected + emitted lw radiation for all surfaces in i-th reflection
     987    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfinlg         !< global array of incoming lw radiation from plant canopy
    978988    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfoutsw        !< array of total sw radiation outgoing from nonvirtual surfaces surfaces after all reflection
    979989    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfoutlw        !< array of total lw radiation outgoing from nonvirtual surfaces surfaces after all reflection
     
    29282938       CHARACTER (LEN=80) ::  line  !< dummy string that contains the current line of the parameter file
    29292939       
    2930        NAMELIST /radiation_par/   albedo, albedo_type, albedo_lw_dir,          &
    2931                                   albedo_lw_dif, albedo_sw_dir, albedo_sw_dif, &
    2932                                   constant_albedo, dt_radiation, emissivity,   &
    2933                                   lw_radiation, mrt_nlevels, mrt_skip_roof,    &
    2934                                   mrt_include_sw,  net_radiation,              &
    2935                                   radiation_scheme, skip_time_do_radiation,    &
    2936                                   sw_radiation, unscheduled_radiation_calls,   &
    2937                                   max_raytracing_dist, min_irrf_value,         &
    2938                                   nrefsteps, raytrace_mpi_rma,                 &
    2939                                   surface_reflections, svfnorm_report_thresh,  &
    2940                                   radiation_interactions_on,                   &
    2941                                   rad_angular_discretization,                  &
    2942                                   raytrace_discrete_azims,                     &
    2943                                   raytrace_discrete_elevs
     2940       NAMELIST /radiation_par/   albedo, albedo_lw_dif, albedo_lw_dir,         &
     2941                                  albedo_sw_dif, albedo_sw_dir, albedo_type,    &
     2942                                  constant_albedo, dt_radiation, emissivity,    &
     2943                                  lw_radiation, max_raytracing_dist,            &
     2944                                  min_irrf_value, mrt_include_sw, mrt_nlevels,  &
     2945                                  mrt_skip_roof, net_radiation, nrefsteps,      &
     2946                                  plant_lw_interact, rad_angular_discretization,&
     2947                                  radiation_interactions_on, radiation_scheme,  &
     2948                                  raytrace_discrete_azims,                      &
     2949                                  raytrace_discrete_elevs, raytrace_mpi_rma,    &
     2950                                  skip_time_do_radiation, surface_reflections,  &
     2951                                  svfnorm_report_thresh, sw_radiation,          &
     2952                                  unscheduled_radiation_calls
     2953
    29442954   
    2945        NAMELIST /radiation_parameters/   albedo, albedo_type, albedo_lw_dir,   &
    2946                                   albedo_lw_dif, albedo_sw_dir, albedo_sw_dif, &
    2947                                   constant_albedo, dt_radiation, emissivity,   &
    2948                                   lw_radiation, mrt_nlevels, mrt_skip_roof,    &
    2949                                   mrt_include_sw,  net_radiation,              &
    2950                                   radiation_scheme, skip_time_do_radiation,    &
    2951                                   sw_radiation, unscheduled_radiation_calls,   &
    2952                                   max_raytracing_dist, min_irrf_value,         &
    2953                                   nrefsteps, raytrace_mpi_rma,                 &
    2954                                   surface_reflections, svfnorm_report_thresh,  &
    2955                                   radiation_interactions_on,                   &
    2956                                   rad_angular_discretization,                  &
    2957                                   raytrace_discrete_azims,                     &
    2958                                   raytrace_discrete_elevs
     2955       NAMELIST /radiation_parameters/ albedo, albedo_lw_dif, albedo_lw_dir,    &
     2956                                  albedo_sw_dif, albedo_sw_dir, albedo_type,    &
     2957                                  constant_albedo, dt_radiation, emissivity,    &
     2958                                  lw_radiation, max_raytracing_dist,            &
     2959                                  min_irrf_value, mrt_include_sw, mrt_nlevels,  &
     2960                                  mrt_skip_roof, net_radiation, nrefsteps,      &
     2961                                  plant_lw_interact, rad_angular_discretization,&
     2962                                  radiation_interactions_on, radiation_scheme,  &
     2963                                  raytrace_discrete_azims,                      &
     2964                                  raytrace_discrete_elevs, raytrace_mpi_rma,    &
     2965                                  skip_time_do_radiation, surface_reflections,  &
     2966                                  svfnorm_report_thresh, sw_radiation,          &
     2967                                  unscheduled_radiation_calls
    29592968   
    29602969       line = ' '
     
    46484657     REAL(wp), DIMENSION(0:nsurf_type) :: costheta           !< direct irradiance factor of solar angle
    46494658     REAL(wp), DIMENSION(nzub:nzut)    :: pchf_prep          !< precalculated factor for canopy temperature tendency
    4650      REAL(wp), DIMENSION(nzub:nzut)    :: pctf_prep          !< precalculated factor for canopy transpiration tendency
    46514659     REAL(wp), PARAMETER               :: alpha = 0._wp      !< grid rotation (TODO: add to namelist or remove)
    46524660     REAL(wp)                          :: pc_box_area, pc_abs_frac, pc_abs_eff
    4653      REAL(wp), DIMENSION(0:nsurf_type) :: facearea
     4661     REAL(wp)                          :: asrc               !< area of source face
     4662     REAL(wp)                          :: pcrad              !< irradiance from plant canopy
    46544663     REAL(wp)                          :: pabsswl  = 0.0_wp  !< total absorbed SW radiation energy in local processor (W)
    46554664     REAL(wp)                          :: pabssw   = 0.0_wp  !< total absorbed SW radiation energy in all processors (W)
     
    46724681         pchf_prep(:) = r_d * exner(nzub:nzut)                                 &
    46734682                     / (c_p * hyp(nzub:nzut) * dx*dy*dz(1)) !< equals to 1 / (rho * c_p * Vbox * T)
    4674          pctf_prep(:) = r_d * exner(nzub:nzut)                                 &
    4675                      / (l_v * hyp(nzub:nzut) * dx*dy*dz(1))
    46764683     ENDIF
    46774684#endif
     
    47294736        mrtinlw(:) = 0._wp
    47304737     ENDIF
     4738     surfinlg(:)  = 0._wp !global
    47314739
    47324740
     
    48244832!
    48254833!--        For surface-to-surface factors we calculate thermal radiation in 1st pass
    4826            surfinl(isurf) = surfinl(isurf) + svf(1,isvf) * surfoutl(isurfsrc)
     4834           IF ( plant_lw_interact )  THEN
     4835              surfinl(isurf) = surfinl(isurf) + svf(1,isvf) * svf(2,isvf) * surfoutl(isurfsrc)
     4836           ELSE
     4837              surfinl(isurf) = surfinl(isurf) + svf(1,isvf) * surfoutl(isurfsrc)
     4838           ENDIF
    48274839        ENDDO
    48284840     ENDIF
     
    48334845        i = surfl(ix, isurf)
    48344846        surfinswdif(isurf) = rad_sw_in_diff(j,i) * skyvft(isurf)
    4835         surfinlwdif(isurf) = rad_lw_in_diff(j,i) * skyvf(isurf)
     4847        IF ( plant_lw_interact )  THEN
     4848           surfinlwdif(isurf) = rad_lw_in_diff(j,i) * skyvft(isurf)
     4849        ELSE
     4850           surfinlwdif(isurf) = rad_lw_in_diff(j,i) * skyvf(isurf)
     4851        ENDIF
    48364852     ENDDO
    48374853!
     
    48804896         pcbinswdir(:) = 0._wp
    48814897         pcbinswdif(:) = 0._wp
    4882          pcbinlw(:) = 0._wp  !< will stay always 0 since we don't absorb lw anymore
    4883 !
    4884 !--         pcsf first pass
     4898         pcbinlw(:) = 0._wp
     4899!
     4900!--      pcsf first pass
    48854901         DO icsf = 1, ncsfl
    48864902             ipcgb = csfsurf(1, icsf)
     
    48914907
    48924908             IF ( isurfsrc == -1 )  THEN
    4893 !--                 Diffuse rad from sky.
    4894                  pcbinswdif(ipcgb) = csf(1,icsf) * rad_sw_in_diff(j,i)
    4895 
    4896                  !--Direct rad
    4897                  IF ( zenith(0) > 0 )  THEN
    4898                     !--Estimate directed box absorption
    4899                     pc_abs_frac = 1._wp - exp(pc_abs_eff * lad_s(k,j,i))
    4900 
    4901                     !--isd has already been established, see 1)
    4902                     pcbinswdir(ipcgb) = rad_sw_in_dir(j, i) * pc_box_area &
    4903                                         * pc_abs_frac * dsitransc(ipcgb, isd)
    4904                  ENDIF
     4909!
     4910!--             Diffuse rad from sky.
     4911                pcbinswdif(ipcgb) = csf(1,icsf) * rad_sw_in_diff(j,i)
     4912!
     4913!--             Absorbed diffuse LW from sky minus emitted to sky
     4914                IF ( plant_lw_interact )  THEN
     4915                   pcbinlw(ipcgb) = csf(1,icsf)                                  &
     4916                                       * (rad_lw_in_diff(j, i)                   &
     4917                                          - sigma_sb * (pt(k,j,i)*exner(k))**4)
     4918                ENDIF
     4919!
     4920!--             Direct rad
     4921                IF ( zenith(0) > 0 )  THEN
     4922!--                Estimate directed box absorption
     4923                   pc_abs_frac = 1._wp - exp(pc_abs_eff * lad_s(k,j,i))
     4924!
     4925!--                isd has already been established, see 1)
     4926                   pcbinswdir(ipcgb) = rad_sw_in_dir(j, i) * pc_box_area &
     4927                                       * pc_abs_frac * dsitransc(ipcgb, isd)
     4928                ENDIF
     4929             ELSE
     4930                IF ( plant_lw_interact )  THEN
     4931!
     4932!--                Thermal emission from plan canopy towards respective face
     4933                   pcrad = sigma_sb * (pt(k,j,i) * exner(k))**4 * csf(1,icsf)
     4934                   surfinlg(isurfsrc) = surfinlg(isurfsrc) + pcrad
     4935!
     4936!--                Remove the flux above + absorb LW from first pass from surfaces
     4937                   asrc = facearea(surf(id, isurfsrc))
     4938                   pcbinlw(ipcgb) = pcbinlw(ipcgb)                      &
     4939                                    + (csf(1,icsf) * surfoutl(isurfsrc) & ! Absorb from first pass surf emit
     4940                                       - pcrad)                         & ! Remove emitted heatflux
     4941                                    * asrc
     4942                ENDIF
    49054943             ENDIF
    49064944         ENDDO
     
    49084946         pcbinsw(:) = pcbinswdir(:) + pcbinswdif(:)
    49094947     ENDIF
     4948
     4949     IF ( plant_lw_interact )  THEN
     4950!
     4951!--     Exchange incoming lw radiation from plant canopy
     4952#if defined( __parallel )
     4953        CALL MPI_Allreduce(MPI_IN_PLACE, surfinlg, nsurf, MPI_REAL, MPI_SUM, comm2d, ierr)
     4954        IF ( ierr /= 0 )  THEN
     4955           WRITE (9,*) 'Error MPI_Allreduce:', ierr
     4956           FLUSH(9)
     4957        ENDIF
     4958        surfinl(:) = surfinl(:) + surfinlg(surfstart(myid)+1:surfstart(myid+1))
     4959#else
     4960        surfinl(:) = surfinl(:) + surfinlg(:)
     4961#endif
     4962     ENDIF
     4963
    49104964     surfins = surfinswdir + surfinswdif
    49114965     surfinl = surfinl + surfinlwdif
     
    49665020             isurfsrc = svfsurf(2, isvf)
    49675021             surfins(isurf) = surfins(isurf) + svf(1,isvf) * svf(2,isvf) * surfouts(isurfsrc)
    4968              surfinl(isurf) = surfinl(isurf) + svf(1,isvf) * surfoutl(isurfsrc)
     5022             IF ( plant_lw_interact )  THEN
     5023                surfinl(isurf) = surfinl(isurf) + svf(1,isvf) * svf(2,isvf) * surfoutl(isurfsrc)
     5024             ELSE
     5025                surfinl(isurf) = surfinl(isurf) + svf(1,isvf) * surfoutl(isurfsrc)
     5026             ENDIF
    49695027         ENDDO
    4970 
    4971 !--         radiation absorbed by plant canopy
    4972          DO icsf = 1, ncsfl
     5028!
     5029!--      NOTE: PC absorbtion and MRT from reflected can both be done at once
     5030!--      after all reflections if we do one more MPI_ALLGATHERV on surfout.
     5031!--      Advantage: less local computation. Disadvantage: one more collective
     5032!--      MPI call.
     5033!
     5034!--      Radiation absorbed by plant canopy
     5035         DO  icsf = 1, ncsfl
    49735036             ipcgb = csfsurf(1, icsf)
    49745037             isurfsrc = csfsurf(2, icsf)
    49755038             IF ( isurfsrc == -1 )  CYCLE ! sky->face only in 1st pass, not here
    4976 
    4977              pcbinsw(ipcgb) = pcbinsw(ipcgb) + csf(1,icsf) * surfouts(isurfsrc)
     5039!
     5040!--          Calculate source surface area. If the `surf' array is removed
     5041!--          before timestepping starts (future version), then asrc must be
     5042!--          stored within `csf'
     5043             asrc = facearea(surf(id, isurfsrc))
     5044             pcbinsw(ipcgb) = pcbinsw(ipcgb) + csf(1,icsf) * surfouts(isurfsrc) * asrc
     5045             IF ( plant_lw_interact )  THEN
     5046                pcbinlw(ipcgb) = pcbinlw(ipcgb) + csf(1,icsf) * surfoutl(isurfsrc) * asrc
     5047             ENDIF
    49785048         ENDDO
    49795049!
     
    49965066     IF ( npcbl > 0 )  THEN
    49975067         pc_heating_rate(:,:,:) = 0.0_wp
    4998          pc_transpiration_rate(:,:,:) = 0.0_wp
    49995068         DO ipcgb = 1, npcbl
    5000                  
    50015069             j = pcbl(iy, ipcgb)
    50025070             i = pcbl(ix, ipcgb)
    50035071             k = pcbl(iz, ipcgb)
    50045072!
    5005 !--             Following expression equals former kk = k - nzb_s_inner(j,i)
     5073!--          Following expression equals former kk = k - nzb_s_inner(j,i)
    50065074             kk = k - get_topography_top_index_ji( j, i, 's' )  !- lad arrays are defined flat
    50075075             pc_heating_rate(kk, j, i) = (pcbinsw(ipcgb) + pcbinlw(ipcgb)) &
    50085076                 * pchf_prep(k) * pt(k, j, i) !-- = dT/dt
    5009 
    5010 !             pc_transpiration_rate(kk,j,i) = 0.75_wp* (pcbinsw(ipcgb) + pcbinlw(ipcgb)) &
    5011 !                 * pctf_prep(k) * pt(k, j, i) !-- = dq/dt
    5012 
    50135077         ENDDO
     5078
     5079         IF ( humidity .AND. plant_canopy_transpiration ) THEN
     5080!--          Calculation of plant canopy transpiration rate and correspondidng latent heat rate
     5081             pc_transpiration_rate(:,:,:) = 0.0_wp
     5082             pc_latent_rate(:,:,:) = 0.0_wp
     5083             DO ipcgb = 1, npcbl
     5084                 i = pcbl(ix, ipcgb)
     5085                 j = pcbl(iy, ipcgb)
     5086                 k = pcbl(iz, ipcgb)
     5087                 kk = k - get_topography_top_index_ji( j, i, 's' )  !- lad arrays are defined flat
     5088                 CALL pcm_calc_transpiration_rate( i, j, k, kk, pcbinsw(ipcgb), pcbinlw(ipcgb), &
     5089                                                   pc_transpiration_rate(kk,j,i), pc_latent_rate(kk,j,i) )
     5090              ENDDO
     5091         ENDIF
    50145092     ENDIF
    50155093!
     
    51615239!--  domain when using average_radiation in the respective radiation model
    51625240
    5163 !--  Precalculate face areas for all face directions using normal vector
    5164      DO d = 0, nsurf_type
    5165         facearea(d) = 1._wp
    5166         IF ( idir(d) == 0 ) facearea(d) = facearea(d) * dx
    5167         IF ( jdir(d) == 0 ) facearea(d) = facearea(d) * dy
    5168         IF ( kdir(d) == 0 ) facearea(d) = facearea(d) * dz(1)
    5169      ENDDO
    51705241!--  calculate horizontal area
    51715242! !!! ATTENTION!!! uniform grid is assumed here
     
    54295500       IMPLICIT NONE
    54305501
    5431        INTEGER(iwp) :: i, j, k, l, m
     5502       INTEGER(iwp) :: i, j, k, l, m, d
    54325503       INTEGER(iwp) :: k_topo     !< vertical index indicating topography top for given (j,i)
    54335504       INTEGER(iwp) :: nzptl, nzubl, nzutl, isurf, ipcgb, imrt
     
    54395510#endif
    54405511
     5512!
     5513!--     precalculate face areas for different face directions using normal vector
     5514        DO d = 0, nsurf_type
     5515            facearea(d) = 1._wp
     5516            IF ( idir(d) == 0 ) facearea(d) = facearea(d) * dx
     5517            IF ( jdir(d) == 0 ) facearea(d) = facearea(d) * dy
     5518            IF ( kdir(d) == 0 ) facearea(d) = facearea(d) * dz(1)
     5519        ENDDO
    54415520!
    54425521!--    Find nzub, nzut, nzu via wall_flag_0 array (nzb_s_inner will be
     
    59045983       ALLOCATE( surfouts(nsurf) )
    59055984       ALLOCATE( surfoutl(nsurf) )
     5985       ALLOCATE( surfinlg(nsurf) )
    59065986       ALLOCATE( skyvf(nsurfl) )
    59075987       ALLOCATE( skyvft(nsurfl) )
     
    59406020        REAL(wp)                                      :: az1, az2      !< relative azimuth of section borders
    59416021        REAL(wp)                                      :: azmid         !< ray (center) azimuth
     6022        REAL(wp)                                      :: yxlen         !< |yxdir|
    59426023        REAL(wp), DIMENSION(2)                        :: yxdir         !< y,x *unit* vector of ray direction (in grid units)
    59436024        REAL(wp), DIMENSION(:), ALLOCATABLE           :: zdirs         !< directions in z (tangent of elevation)
     6025        REAL(wp), DIMENSION(:), ALLOCATABLE           :: zcent         !< zenith angle centers
    59446026        REAL(wp), DIMENSION(:), ALLOCATABLE           :: zbdry         !< zenith angle boundaries
    59456027        REAL(wp), DIMENSION(:), ALLOCATABLE           :: vffrac        !< view factor fractions for individual rays
     
    59496031        INTEGER(iwp), DIMENSION(:), ALLOCATABLE       :: itarget       !< face indices of detected obstacles
    59506032        INTEGER(iwp)                                  :: itarg0, itarg1
    5951 #if defined( __parallel )
    5952 #endif
    5953 
    5954 
    5955 
    5956         REAL(wp),     DIMENSION(0:nsurf_type)         :: facearea
     6033
    59576034        INTEGER(iwp)                                  :: udim
    59586035        INTEGER(iwp), DIMENSION(:), ALLOCATABLE,TARGET:: nzterrl_l
     
    59666043        LOGICAL                                       :: visible
    59676044        REAL(wp), DIMENSION(3)                        :: sa, ta          !< real coordinates z,y,x of source and target
     6045        REAL(wp)                                      :: difvf           !< differential view factor
    59686046        REAL(wp)                                      :: transparency, rirrf, sqdist, svfsum
    59696047        INTEGER(iwp)                                  :: isurflt, isurfs, isurflt_prev
     
    59836061        CALL location_message( '    calculation of SVF and CSF', .TRUE. )
    59846062        CALL radiation_write_debug_log('Start calculation of SVF and CSF')
    5985 
    5986 !--     precalculate face areas for different face directions using normal vector
    5987         DO d = 0, nsurf_type
    5988             facearea(d) = 1._wp
    5989             IF ( idir(d) == 0 ) facearea(d) = facearea(d) * dx
    5990             IF ( jdir(d) == 0 ) facearea(d) = facearea(d) * dy
    5991             IF ( kdir(d) == 0 ) facearea(d) = facearea(d) * dz(1)
    5992         ENDDO
    59936063
    59946064!--     initialize variables and temporary arrays for calculation of svf and csf
     
    62196289            END SELECT
    62206290
    6221             ALLOCATE ( zdirs(1:nzn), zbdry(0:nzn), vffrac(1:nzn*naz), &
     6291            ALLOCATE ( zdirs(1:nzn), zcent(1:nzn), zbdry(0:nzn), vffrac(1:nzn*naz), &
    62226292                       ztransp(1:nzn*naz), itarget(1:nzn*naz) )   !FIXME allocate itarget only
    62236293                                                                  !in case of rad_angular_discretization
     
    62256295            itarg0 = 1
    62266296            itarg1 = nzn
    6227             zdirs(:) = (/( TAN(pi/2 - (zn0+(REAL(izn,wp)-.5_wp)*zns)), izn=1, nzn )/)
     6297            zcent(:) = (/( zn0+(REAL(izn,wp)-.5_wp)*zns, izn=1, nzn )/)
    62286298            zbdry(:) = (/( zn0+REAL(izn,wp)*zns, izn=0, nzn )/)
    62296299            IF ( td == iup_u  .OR.  td == iup_l )  THEN
     
    62516321!--               sum of whole vffrac equals 1, verified
    62526322               ENDIF
    6253                yxdir = (/ COS(azmid), SIN(azmid) /)
     6323               yxdir(:) = (/ COS(azmid) / dy, SIN(azmid) / dx /)
     6324               yxlen = SQRT(SUM(yxdir(:)**2))
     6325               zdirs(:) = COS(zcent(:)) / (dz(1) * yxlen * SIN(zcent(:)))
     6326               yxdir(:) = yxdir(:) / yxlen
     6327
    62546328               CALL raytrace_2d(ta, yxdir, nzn, zdirs,                        &
    62556329                                    surfstart(myid) + isurflt, facearea(td),  &
     
    62576331                                    .FALSE., lowest_free_ray,                 &
    62586332                                    ztransp(itarg0:itarg1),                   &
    6259                                     itarget(itarg0:itarg1))   !FIXME unit vect in grid units + zdirs
    6260                                                               !FIXME itarget available only in
    6261                                                               !case of rad_angular_discretization
     6333                                    itarget(itarg0:itarg1))
     6334
    62626335               skyvf(isurflt) = skyvf(isurflt) + &
    62636336                                SUM(vffrac(itarg0:itarg0+lowest_free_ray-1))
     
    63376410            ENDIF ! rad_angular_discretization
    63386411
    6339             DEALLOCATE ( zdirs, zbdry, vffrac, ztransp, itarget ) !FIXME itarget shall be allocated only
     6412            DEALLOCATE ( zdirs, zcent, zbdry, vffrac, ztransp, itarget ) !FIXME itarget shall be allocated only
    63406413                                                                  !in case of rad_angular_discretization
    63416414!
     
    63676440                  ENDIF
    63686441                 
     6442                  difvf = dot_product((/ kdir(sd), jdir(sd), idir(sd) /), uv) & ! cosine of source normal and direction
     6443                      * dot_product((/ kdir(td), jdir(td), idir(td) /), -uv) &  ! cosine of target normal and reverse direction
     6444                      / (pi * sqdist) ! square of distance between centers
     6445!
    63696446!--               irradiance factor (our unshaded shape view factor) = view factor per differential target area * source area
    6370                   rirrf = dot_product((/ kdir(sd), jdir(sd), idir(sd) /), uv) & ! cosine of source normal and direction
    6371                       * dot_product((/ kdir(td), jdir(td), idir(td) /), -uv) &  ! cosine of target normal and reverse direction
    6372                       / (pi * sqdist) & ! square of distance between centers
    6373                       * facearea(sd)
     6447                  rirrf = difvf * facearea(sd)
    63746448
    63756449!--               reject raytracing for potentially too small view factor values
     
    63806454
    63816455!--               raytrace + process plant canopy sinks within
    6382                   CALL raytrace(sa, ta, isurfs, rirrf, facearea(td), .TRUE., &
     6456                  CALL raytrace(sa, ta, isurfs, difvf, facearea(td), .TRUE., &
    63836457                                visible, transparency)
    63846458
     
    64286502        nzn = raytrace_discrete_elevs / 2
    64296503        zns = pi / 2._wp / REAL(nzn, wp)
    6430         ALLOCATE ( zdirs(1:nzn), vffrac(1:nzn), ztransp(1:nzn), &
     6504        ALLOCATE ( zdirs(1:nzn), zcent(1:nzn), vffrac(1:nzn), ztransp(1:nzn), &
    64316505               itarget(1:nzn) )
    6432         zdirs(:) = (/( TAN(pi/2 - (zn0+(REAL(izn,wp)-.5_wp)*zns)), izn=1, nzn )/)
     6506        zcent(:) = (/( zn0+(REAL(izn,wp)-.5_wp)*zns, izn=1, nzn )/)
    64336507        vffrac(:) = 0._wp
    64346508
     
    64406514           DO  iaz = 1, naz
    64416515              azmid = az0 + (REAL(iaz, wp) - .5_wp) * azs
    6442               yxdir = (/ COS(azmid), SIN(azmid) /)
     6516              yxdir(:) = (/ COS(azmid) / dy, SIN(azmid) / dx /)
     6517              yxlen = SQRT(SUM(yxdir(:)**2))
     6518              zdirs(:) = COS(zcent(:)) / (dz(1) * yxlen * SIN(zcent(:)))
     6519              yxdir(:) = yxdir(:) / yxlen
    64436520              CALL raytrace_2d(ta, yxdir, nzn, zdirs,                                &
    64446521                                   -999, -999._wp, vffrac, .FALSE., .FALSE., .TRUE., &
    6445                                    lowest_free_ray, ztransp, itarget) !FIXME unit vect in grid units + zdirs
     6522                                   lowest_free_ray, ztransp, itarget)
    64466523
    64476524!--           Save direct solar transparency
     
    64566533           ENDDO
    64576534        ENDDO
    6458         DEALLOCATE ( zdirs, vffrac, ztransp, itarget )
     6535        DEALLOCATE ( zdirs, zcent, vffrac, ztransp, itarget )
    64596536!--
    64606537!--     Raytrace to MRT boxes
     
    64696546           nzn = raytrace_discrete_elevs
    64706547           zns = pi / REAL(nzn, wp)
    6471            ALLOCATE ( zdirs(1:nzn), zbdry(0:nzn), vffrac(1:nzn*naz), vffrac0(1:nzn), &
     6548           ALLOCATE ( zdirs(1:nzn), zcent(1:nzn), zbdry(0:nzn), vffrac(1:nzn*naz), vffrac0(1:nzn), &
    64726549                      ztransp(1:nzn*naz), itarget(1:nzn*naz) )   !FIXME allocate itarget only
    64736550                                                                 !in case of rad_angular_discretization
    64746551
    6475            zdirs(:) = (/( TAN(pi/2 - (zn0+(REAL(izn,wp)-.5_wp)*zns)), izn=1, nzn )/)
     6552           zcent(:) = (/( zn0+(REAL(izn,wp)-.5_wp)*zns, izn=1, nzn )/)
    64766553           zbdry(:) = (/( zn0+REAL(izn,wp)*zns, izn=0, nzn )/)
    64776554           vffrac0(:) = (COS(zbdry(0:nzn-1)) - COS(zbdry(1:nzn))) / 2._wp / REAL(naz, wp)
     
    64936570              DO  iaz = 1, naz
    64946571                 azmid = az0 + (REAL(iaz, wp) - .5_wp) * azs
    6495                  CALL raytrace_2d(ta, (/ COS(azmid), SIN(azmid) /), nzn, zdirs,  &
     6572                 yxdir(:) = (/ COS(azmid) / dy, SIN(azmid) / dx /)
     6573                 yxlen = SQRT(SUM(yxdir(:)**2))
     6574                 zdirs(:) = COS(zcent(:)) / (dz(1) * yxlen * SIN(zcent(:)))
     6575                 yxdir(:) = yxdir(:) / yxlen
     6576
     6577                 CALL raytrace_2d(ta, yxdir, nzn, zdirs,                         &
    64966578                                  -999, -999._wp, vffrac(itarg0:itarg1), .TRUE., &
    64976579                                  .FALSE., .TRUE., lowest_free_ray,              &
    64986580                                  ztransp(itarg0:itarg1),                        &
    6499                                   itarget(itarg0:itarg1))   !FIXME unit vect in grid units + zdirs
    6500                                                             !FIXME itarget available only in
    6501                                                             !case of rad_angular_discretization
     6581                                  itarget(itarg0:itarg1))
    65026582
    65036583!--              Sky view factors for MRT
     
    65746654
    65756655           ENDDO ! imrt
    6576            DEALLOCATE ( zdirs, zbdry, vffrac, vffrac0, ztransp, itarget )
     6656           DEALLOCATE ( zdirs, zcent, zbdry, vffrac, vffrac0, ztransp, itarget )
    65776657!
    65786658!--        Move MRT factors to final arrays
     
    67786858                    j = 0
    67796859                ENDIF
    6780 !--             fill out real values of rsvf, rtransp
    6781                 csflt(1,kcsf) = acsf(kcsf)%rsvf
     6860                csflt(1,kcsf) = acsf(kcsf)%rcvf
    67826861!--             fill out integer values of itz,ity,itx,isurfs
    67836862                kcsflt(1,kcsf) = acsf(kcsf)%itz
     
    69467025!>    doesn't need to be the same in all three dimensions).
    69477026!------------------------------------------------------------------------------!
    6948     SUBROUTINE raytrace(src, targ, isrc, rirrf, atarg, create_csf, visible, transparency)
     7027    SUBROUTINE raytrace(src, targ, isrc, difvf, atarg, create_csf, visible, transparency)
    69497028        IMPLICIT NONE
    69507029
    69517030        REAL(wp), DIMENSION(3), INTENT(in)     :: src, targ    !< real coordinates z,y,x
    69527031        INTEGER(iwp), INTENT(in)               :: isrc         !< index of source face for csf
    6953         REAL(wp), INTENT(in)                   :: rirrf        !< irradiance factor for csf
     7032        REAL(wp), INTENT(in)                   :: difvf        !< differential view factor for csf
    69547033        REAL(wp), INTENT(in)                   :: atarg        !< target surface area for csf
    69557034        LOGICAL, INTENT(in)                    :: create_csf   !< whether to generate new CSFs during raytracing
     
    71137192                    acsf(ncsfl)%itz = boxes(1,i)
    71147193                    acsf(ncsfl)%isurfs = isrc
    7115                     acsf(ncsfl)%rsvf = cursink*transparency*rirrf*atarg
     7194                    acsf(ncsfl)%rcvf = cursink*transparency*difvf*atarg
    71167195                ENDIF  !< create_csf
    71177196
     
    75147593                           acsf(ncsfl)%itz = iz
    75157594                           acsf(ncsfl)%isurfs = iorig
    7516                            acsf(ncsfl)%rsvf = (1._wp - curtrans)*transparency(k)*aorig*vffrac(k)
     7595                           acsf(ncsfl)%rcvf = (1._wp - curtrans)*transparency(k)*vffrac(k)
    75177596                        ENDIF
    75187597
     
    75717650                        acsf(ncsfl)%ity = rt2_track(1,i)
    75727651                        acsf(ncsfl)%itz = iz
    7573                         acsf(ncsfl)%isurfs = itarget(k) !if above horizon, then itarget(k)==-1, which
    7574                                                         !is also a special ID indicating sky
    7575                         acsf(ncsfl)%rsvf = (1._wp - curtrans)*transparency(k)*aorig*vffrac(k)
     7652                        IF ( itarget(k) /= -1 )  ERROR STOP !FIXME remove after test
     7653                        acsf(ncsfl)%isurfs = -1
     7654                        acsf(ncsfl)%rcvf = (1._wp - curtrans)*transparency(k)*aorig*vffrac(k)
    75767655                     ENDIF  ! create_csf
    75777656
     
    76007679         INTEGER(iwp), TARGET, INTENT(out)   ::  isurfl
    76017680         INTEGER(iwp), INTENT(out)           ::  iproc
     7681#if defined( __parallel )
     7682#else
     7683         INTEGER(iwp)                        ::  target_displ  !< index of the grid in the local gridsurf array
     7684#endif
    76027685         INTEGER(iwp)                        ::  px, py        !< number of processors in x and y direction
    76037686                                                               !< before the processor in the question
     
    81388221                         .AND.  acsfnew(iwrite)%isurfs == acsf(iread)%isurfs )  THEN
    81398222
    8140                     acsfnew(iwrite)%rsvf = acsfnew(iwrite)%rsvf + acsf(iread)%rsvf
     8223                    acsfnew(iwrite)%rcvf = acsfnew(iwrite)%rcvf + acsf(iread)%rcvf
    81418224!--                 advance reading index, keep writing index
    81428225                ELSE
Note: See TracChangeset for help on using the changeset viewer.