Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
299 changes: 209 additions & 90 deletions avaframe/com4FlowPy/com4FlowPy.py

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions avaframe/com4FlowPy/com4FlowPyCfg.ini
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,12 @@ outputNoDataValue = -9999
# depFluxSum
# travelLengthMin
# fpTravelAngleMin
# relIdPolygon
# relIdCount
# if forestInteraction: forestInteraction is automatically added to outputs
# if infra: backCalculation is automatically added to output
# if relVolMin or relVolMax is in outputFiles, the Volume of the PRA should be provided in the raster file in the REL folder
# if relIdCount or relIdPolygon is in outputFiles, the ids of the PRAs should be provided in the raster file in the RELID folder
outputFiles = zDelta|cellCounts|travelLengthMax|fpTravelAngleMax

#++++++++++++ Custom paths True/False
Expand Down Expand Up @@ -256,6 +260,7 @@ useCustomPathDEM = False
workDir =
demPath =
releasePath =
relIdPath =
infraPath =
forestPath =
varUmaxPath =
Expand Down
69 changes: 46 additions & 23 deletions avaframe/com4FlowPy/flowClass.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,32 @@
# -*- coding: utf-8 -*-

"""
Functions for calculations at the 'cell level' (vgl. D'Amboise et al., 2022)
Functions for calculations at the 'cell level' (vgl. D'Amboise et al., 2022)
"""

import numpy as np
import math


class Cell:

def __init__(
self,
rowindex, colindex,
dem_ng, cellsize,
flux, z_delta, parent,
alpha, exp, flux_threshold, max_z_delta,
startcell, fluxDistOldVersionBool=False,
FSI=None, forestParams=None,
rowindex,
colindex,
dem_ng,
cellsize,
flux,
z_delta,
parent,
alpha,
exp,
flux_threshold,
max_z_delta,
startcell,
fluxDistOldVersionBool=False,
FSI=None,
forestParams=None,
):
"""constructor for the Cell class that describes a raster cell that is hit by the GMF.
the constructor function is called every time a new instance of type 'Cell' is
Expand All @@ -26,8 +36,12 @@ def __init__(
* bool --> isStart
* Cell --> startCell
"""
self.rowindex = rowindex # index of the Cell in row-direction (i.e. local y-index in the calculation domain)
self.colindex = colindex # index of the Cell in column-direction (i.e. local x-index in the calculation domain)
self.rowindex = (
rowindex # index of the Cell in row-direction (i.e. local y-index in the calculation domain)
)
self.colindex = (
colindex # index of the Cell in column-direction (i.e. local x-index in the calculation domain)
)
self.dem_ng = dem_ng # elevation values in the 3x3 neigbourhood around the Cell
self.altitude = dem_ng[1, 1] # elevation value of the cell (central cell of 3x3 neighbourhood)
self.cellsize = cellsize # cellsize in meters
Expand All @@ -49,13 +63,17 @@ def __init__(

self.fluxDistOldVersionBool = fluxDistOldVersionBool

self.tanAlpha = np.tan(np.deg2rad(self.alpha)) # moved to constructor, so this doesn't have to be calculated on
self.tanAlpha = np.tan(
np.deg2rad(self.alpha)
) # moved to constructor, so this doesn't have to be calculated on
# every iteration of calc_z_delta(self)

self.min_distance = 0 # minimal distance to start-cell (i.e. along shortest path) min_distance >=
self.minDistXYZ = 0 # minimal distance to start-cell (Actual 3D lenght, not projected!!)
self.max_distance = 0 # NOTE: self.max_distance is never used - maybe remove!?
self.min_gamma = 0 # NOTE: self.min_gamma (assumingly minimal travel angle to cell) never used - maybe remove!?
self.min_gamma = (
0 # NOTE: self.min_gamma (assumingly minimal travel angle to cell) never used - maybe remove!?
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 # NOTE: self.min_gamma (assumingly minimal travel angle to cell) never used - maybe remove!? [ripgrep:NOTE]

)
self.max_gamma = 0
self.sl_gamma = 0

Expand Down Expand Up @@ -103,7 +121,9 @@ def __init__(
elif forestParams["fFrLayerType"] == "relative":
self.AlphaFor = self.alpha + FSI

self.AlphaFor = max(self.AlphaFor, self.alpha) # Friction in Forest can't be lower than without forest
self.AlphaFor = max(
self.AlphaFor, self.alpha
) # Friction in Forest can't be lower than without forest
self.tanAlphaFor = np.tan(np.deg2rad(self.AlphaFor))

# NOTE: This is a quick hack to check if all values for Detrainment are set to 0 (as provided in the
Expand Down Expand Up @@ -195,7 +215,7 @@ def calcDistMin(self, calc3D=False):
_dy = abs(parent.rowindex - self.rowindex) * self.cellsize
_dz = abs(parent.altitude - self.altitude)
_ldistMin.append(math.sqrt(_dx * _dx + _dy * _dy) + parent.min_distance)
_lDistMinXYZ.append(math.sqrt(_dy*_dy + _dy*_dy + _dz*_dz) + parent.minDistXYZ)
_lDistMinXYZ.append(math.sqrt(_dy * _dy + _dy * _dy + _dz * _dz) + parent.minDistXYZ)
self.min_distance = np.amin(_ldistMin)
self.minDistXYZ = np.amin(_lDistMinXYZ)
else:
Expand Down Expand Up @@ -237,8 +257,8 @@ def calc_z_delta(self):
self.z_gamma = self.altitude - self.dem_ng
ds = np.array([[self._SQRT2, 1, self._SQRT2], [1, 0, 1], [self._SQRT2, 1, self._SQRT2]])

if (not self.is_start):
if (not self.forestBool):
if not self.is_start:
if not self.forestBool:
self.calcDistMin()
else:
self.calcDistMin(calc3D=True)
Expand All @@ -252,7 +272,7 @@ def calc_z_delta(self):
_tanAlpha = self.tanAlpha

if self.forestModule in ["forestFriction", "forestDetrainment"]:
if (not self.is_start) and (self.FSI > 0.) and (self.skipForestDist < self.minDistXYZ):
if (not self.is_start) and (self.FSI > 0.0) and (self.skipForestDist < self.minDistXYZ):
# if forestBool, we assume that forestFriciton is activated
# and if FSI > 0 then we also calculate _tanAlpha with forestEffect
# NOTE: We also don't assume a forest Effect on potential Start Zells, since this should
Expand All @@ -266,7 +286,9 @@ def calc_z_delta(self):
_slope = (_rest - self.minAddedFrictionForest) / (0 - self.noFrictionEffectZDelta)
# y = mx + b, shere z_delta is the x
friction = max(self.minAddedFrictionForest, _slope * self.z_delta + _rest)
_alpha_calc = self.alpha + max(0, friction) # NOTE: not sure what this does, seems redundant!
_alpha_calc = self.alpha + max(
0, friction
) # NOTE: not sure what this does, seems redundant!
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

) # NOTE: not sure what this does, seems redundant! [ripgrep:NOTE]

else:
_alpha_calc = self.alpha + self.minAddedFrictionForest

Expand All @@ -284,8 +306,7 @@ def calc_z_delta(self):
self.z_delta_neighbour[self.z_delta_neighbour > self.max_z_delta] = self.max_z_delta

def calc_tanbeta(self):
"""calculates the normalized terrain based routing
"""
"""calculates the normalized terrain based routing"""
_ds = np.array([[self._SQRT2, 1, self._SQRT2], [1, 1, 1], [self._SQRT2, 1, self._SQRT2]])
_distance = _ds * self.cellsize

Expand All @@ -312,7 +333,9 @@ def calc_persistence(self):
dx = parent.colindex - self.colindex
dy = parent.rowindex - self.rowindex

self.no_flow[dy + 1, dx + 1] = 0 # 3x3 Matrix of ones, every parent gets a 0, no flow to a parent field
self.no_flow[dy + 1, dx + 1] = (
0 # 3x3 Matrix of ones, every parent gets a 0, no flow to a parent field
)

maxweight = parent.z_delta
# Old Calculation
Expand Down Expand Up @@ -416,7 +439,7 @@ def calc_distribution(self):
self.dist[self.dist < threshold] = 0
if np.sum(self.dist) != self.flux and count > 0:
# correction/flux conservation for potential rounding losses or gains
# (self.flux - np.sum(self.dist)) will either be negative or positive
# (self.flux - np.sum(self.dist)) will either be negative or positive
# depending on the direction of the rounding error
self.dist[self.dist >= threshold] += (self.flux - np.sum(self.dist)) / count
if count == 0:
Expand All @@ -442,8 +465,8 @@ def forest_detrainment(self):
_noDetrainmentEffectZdelta = self.noDetrainmentEffectZdelta

# detrainment effect scaled to forest, 0 for non-forest
_rest = (self.maxAddedDetrainmentForest * self.FSI)
_rest = self.maxAddedDetrainmentForest * self.FSI
# rise over run (should be negative slope)
slope = (_rest - self.minAddedDetrainmentForest) / (0 - _noDetrainmentEffectZdelta)
# y=mx+b, where zDelta is x
self.detrainment = max(self.minAddedDetrainmentForest, slope * self.z_delta + _rest)
self.detrainment = max(self.minAddedDetrainmentForest, slope * self.z_delta + _rest)
Loading
Loading