R/radiation.R
radiation.Rd
This is a wrapper function for calculating total diffuse, direct and total radiation load per unit area on extruded polygon surfaces. The function operates on obstacle geometry and a set of sun positions with associated meteorological estimates for direct and diffuse radiation (see Details below).
radiation( grid, obstacles, obstacles_height_field, solar_pos = solarpos2(obstacles, time), time = NULL, solar_normal, solar_diffuse, radius = Inf, returnList = FALSE, parallel = getOption("mc.cores") )
grid | A 3D |
---|---|
obstacles | A |
obstacles_height_field | Name of attribute in |
solar_pos | A |
time | When |
solar_normal | Direct Normal Irradiance (e.g. in Wh/m^2), at sun positions corresponding to |
solar_diffuse | Diffuse Horizontal Irradiance (e.g. in Wh/m^2), at sun positions corresponding to |
radius | Effective search radius (in CRS units) for considering obstacles when calculating shadow and SVF. The default is to use a global search, i.e. |
returnList | Logical, determines whether to return summed radiation over the entire period per 3D point (default, |
parallel | Number of parallel processes or a predefined socket cluster. With |
If returnList=FALSE
(the default), then returned object is a data.frame
, with rows corresponding to grid
points and four columns corresponding to the following estimates:
svf
Computed Sky View Factor (see function SVF
)
direct
Total direct radiation for each grid point
diffuse
Total diffuse radiation for each grid point
total
Total radiation (direct + diffuse) for each grid point
Each row of the data.frame
gives summed radiation values for the entire time period in solar_pos
, solar_normal
and solar_diffuse
If returnList=TRUE
then returned object is a list
with two elements:
direct
Total direct radiation for each grid point
diffuse
Total diffuse radiation for each grid point
Each of the elements is a matrix
with rows corresponding to grid
points and columns corresponding to time steps in solar_pos
, solar_normal
and solar_diffuse
Input arguments for this function comprise the following:
An extruded polygon obstacles layer (obstacles
and obstacles_height_field
) inducing shading on the queried grid
A grid of 3D points (grid
) where radiation is to be estimated. May be created from the 'obstacles' layer, or a subset of it, using function surfaceGrid
. For instance, in the code example (see below) radiation is estimated on a grid covering just one of four buildings in the build
layer (the first building), but all four buildings are taken into account for evaluating self- and mutual-shading by the buildings.
Solar positions matrix (solar_pos
)
Direct and diffuse radiation meteorological estimate vectors (solar_normal
and solar_diffuse
)
Given these inputs, the function goes through the following steps:
Determining whether each grid point is shaded, at each solar position, using inShadow
Calculating the coefficient of Direct Normal Irradiance reduction, using coefDirect
Summing direct radiation considering (1) mutual shading, (2) direst radiation coefficient and (3) direct radiation estimates
Calculating the Sky View Factor (SVF) for each point, using SVF
Summing diffuse radiation load considering (1) SVF and (2) diffuse radiation estimates
Summing total (direct + diffuse) radiation load
# Create surface grid grid = surfaceGrid( obstacles = build[1, ], obstacles_height_field = "BLDG_HT", res = 2 ) solar_pos = tmy[, c("sun_az", "sun_elev")] solar_pos = as.matrix(solar_pos) # Summed 10-hour radiation estimates for two 3D points rad1 = radiation( grid = grid[1:2, ], obstacles = build, obstacles_height_field = "BLDG_HT", solar_pos = solar_pos[8:17, , drop = FALSE], solar_normal = tmy$solar_normal[8:17], solar_diffuse = tmy$solar_diffuse[8:17], returnList = TRUE )#> Determining Shadow #> | | | 0% | |======= | 10% | |============== | 20% | |===================== | 30% | |============================ | 40% | |=================================== | 50% | |========================================== | 60% | |================================================= | 70% | |======================================================== | 80% | |=============================================================== | 90% | |======================================================================| 100% #> Done #> Calculating SVF #> Donerad1#> $direct #> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] #> [1,] 131.5884 293.0234 399.9672 475.75 490.5326 437.2193 319.5239 175.1429 #> [2,] 131.5884 293.0234 399.9672 475.75 490.5326 437.2193 319.5239 175.1429 #> [,9] [,10] #> [1,] 32.61533 0 #> [2,] 32.61533 0 #> #> $diffuse #> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] #> [1,] 36.29564 45.97448 53.23361 53.23361 54.04018 55.65332 54.84675 45.16791 #> [2,] 44.38150 56.21657 65.09287 65.09287 66.07913 68.05164 67.06538 55.23032 #> [,9] [,10] #> [1,] 17.74454 0.8065699 #> [2,] 21.69762 0.9862556 #>if (FALSE) { # Same, using 'time' instead of 'solar_pos' rad2 = radiation( grid = grid[1:2, ], obstacles = build, obstacles_height_field = "BLDG_HT", time = as.POSIXct(tmy$time[8:17], tz = "Asia/Jerusalem"), solar_normal = tmy$solar_normal[8:17], solar_diffuse = tmy$solar_diffuse[8:17], returnList = TRUE ) rad2 # Differences due to the fact that 'tmy' data come with their own # solar positions, not exactly matching those calulated using 'maptools::solarpos' rad1$direct - rad2$direct rad1$diffuse - rad2$diffuse } if (FALSE) { ### Warning! The calculation below takes some time. # Annual radiation estimates for entire surface of one building rad = radiation( grid = grid, obstacles = build, obstacles_height_field = "BLDG_HT", solar_pos = solar_pos, solar_normal = tmy$solar_normal, solar_diffuse = tmy$solar_diffuse, parallel = 3 ) # 3D plot of the results library(plot3D) opar = par(mfrow=c(1, 3)) scatter3D( x = coordinates(grid)[, 1], y = coordinates(grid)[, 2], z = coordinates(grid)[, 3], colvar = rad$direct / 1000, scale = FALSE, theta = 55, pch = 20, cex = 1.35, clab = expression(paste("kWh / ", m^2)), main = "Direct radiation" ) scatter3D( x = coordinates(grid)[, 1], y = coordinates(grid)[, 2], z = coordinates(grid)[, 3], colvar = rad$diffuse / 1000, scale = FALSE, theta = 55, pch = 20, cex = 1.35, clab = expression(paste("kWh / ", m^2)), main = "Diffuse radiation" ) scatter3D( x = coordinates(grid)[, 1], y = coordinates(grid)[, 2], z = coordinates(grid)[, 3], colvar = rad$total / 1000, scale = FALSE, theta = 55, pch = 20, cex = 1.35, clab = expression(paste("kWh / ", m^2)), main = "Total radiation" ) par(opar) }