@@ -17,6 +17,11 @@ class CrossSectionDefinition:
17
17
shape : CrossSectionShape
18
18
height : str # space-separated list of floats
19
19
width : str # space-separated list of floats
20
+ friction_values : str # space-separated list of floats
21
+ vegetation_stem_densities : str # space-separated list of floats
22
+ vegetation_stem_diameters : str # space-separated list of floats
23
+ vegetation_heights : str # space-separated list of floats
24
+ vegetation_drag_coefficients : str # space-separated list of floats
20
25
21
26
22
27
class CrossSectionDefinitions (Array [CrossSectionDefinition ]):
@@ -43,36 +48,54 @@ def convert(self, ids):
43
48
content_pk = ids ,
44
49
code = self .code [idx ],
45
50
count = 0 ,
51
+ count_yz = 0 ,
46
52
)
47
53
if len (result ) == 0 :
48
54
return result
49
55
50
- offset = 0
51
56
tables = []
57
+ tables_yz = []
52
58
53
- # Numpy array views on width/height based on idx
54
- width_idx = self .width [idx ]
55
- height_idx = self .height [idx ]
56
-
57
- for i , shape in enumerate (self .shape [idx ]):
59
+ for i , self_i in enumerate (idx ):
60
+ shape = self .shape [self_i ]
58
61
tabulator = tabulators [shape ]
59
- result .shape [i ], result .width_1d [i ], result .height_1d [i ], table = tabulator (
60
- shape , width_idx [i ], height_idx [i ]
61
- )
62
+ (
63
+ result .shape [i ],
64
+ result .width_1d [i ],
65
+ result .height_1d [i ],
66
+ table ,
67
+ yz ,
68
+ ) = tabulator (shape , self .width [self_i ], self .height [self_i ])
62
69
if table is not None :
63
70
result .count [i ] = len (table )
64
- result .offset [i ] = offset
65
- offset += len (table )
66
71
tables .append (table )
72
+ if yz is not None :
73
+ result .count_yz [i ] = len (yz )
74
+ yz = set_friction_vegetation_values (
75
+ yz ,
76
+ self .friction_values [self_i ],
77
+ self .vegetation_stem_densities [self_i ],
78
+ self .vegetation_stem_diameters [self_i ],
79
+ self .vegetation_heights [self_i ],
80
+ self .vegetation_drag_coefficients [self_i ],
81
+ )
82
+ tables_yz .append (yz )
67
83
68
84
result .offset [:] = np .roll (np .cumsum (result .count ), 1 )
69
85
result .offset [0 ] = 0
86
+ result .offset_yz [:] = np .roll (np .cumsum (result .count_yz ), 1 )
87
+ result .offset_yz [0 ] = 0
70
88
71
89
if len (tables ) > 0 :
72
90
result .tables = np .concatenate (tables , axis = 0 )
73
91
else :
74
92
result .tables = np .empty ((0 , 2 ))
75
93
94
+ if len (tables_yz ) > 0 :
95
+ result .tables_yz = np .concatenate (tables_yz , axis = 0 )
96
+ else :
97
+ result .tables_yz = np .empty ((0 , 4 ))
98
+
76
99
return result
77
100
78
101
@@ -85,11 +108,14 @@ class CrossSection:
85
108
height_1d : float
86
109
offset : int
87
110
count : int
111
+ offset_yz : int
112
+ count_yz : int
88
113
# tables: Tuple[float, float] has different length so is specified on CrossSections
89
114
90
115
91
116
class CrossSections (Array [CrossSection ]):
92
117
tables = None
118
+ tables_yz = None
93
119
94
120
95
121
def tabulate_builtin (shape , width , height ):
@@ -103,7 +129,7 @@ def tabulate_builtin(shape, width, height):
103
129
height (str): ignored
104
130
105
131
Returns:
106
- tuple: shape, width_1d (float), None, None
132
+ tuple: shape, width_1d (float), None, None, None
107
133
"""
108
134
try :
109
135
width = float (width )
@@ -112,7 +138,7 @@ def tabulate_builtin(shape, width, height):
112
138
f"Unable to parse cross section definition width (got: '{ width } ')."
113
139
)
114
140
115
- return shape , width , None , None
141
+ return shape , width , None , None , None
116
142
117
143
118
144
def tabulate_egg (shape , width , height ):
@@ -125,7 +151,7 @@ def tabulate_egg(shape, width, height):
125
151
126
152
Returns:
127
153
tuple: TABULATED_TRAPEZIUM, width_1d (float),
128
- height_1d (float), table (ndarray of shape (M, 2))
154
+ height_1d (float), table (ndarray of shape (M, 2)), None
129
155
"""
130
156
NUM_INCREMENTS = 16
131
157
@@ -151,17 +177,17 @@ def tabulate_egg(shape, width, height):
151
177
widths = np .sqrt (p / q ) * 2
152
178
153
179
table = np .array ([heights , widths ]).T
154
- return CrossSectionShape .TABULATED_TRAPEZIUM , width , height , table
180
+ return CrossSectionShape .TABULATED_TRAPEZIUM , width , height , table , None
155
181
156
182
157
183
def tabulate_inverted_egg (shape , width , height ):
158
184
"""Tabulate the egg shape, upside down.
159
185
160
186
See tabulate_egg.
161
187
"""
162
- type_ , width , height , table = tabulate_egg (shape , width , height )
188
+ type_ , width , height , table , _ = tabulate_egg (shape , width , height )
163
189
table [:, 1 ] = table [::- 1 , 1 ]
164
- return type_ , width , height , table
190
+ return type_ , width , height , table , None
165
191
166
192
167
193
def tabulate_closed_rectangle (shape , width , height ):
@@ -174,7 +200,7 @@ def tabulate_closed_rectangle(shape, width, height):
174
200
175
201
Returns:
176
202
tuple: TABULATED_RECTANGLE, width_1d (float),
177
- height (float), table (ndarray of shape (M, 2))
203
+ height (float), table (ndarray of shape (M, 2)), None
178
204
"""
179
205
try :
180
206
width = float (width )
@@ -185,7 +211,7 @@ def tabulate_closed_rectangle(shape, width, height):
185
211
f"(got: '{ width } ', '{ height } ')."
186
212
)
187
213
table = np .array ([[0.0 , width ], [height , 0.0 ]], order = "F" )
188
- return CrossSectionShape .TABULATED_RECTANGLE , width , height , table
214
+ return CrossSectionShape .TABULATED_RECTANGLE , width , height , table , None
189
215
190
216
191
217
def _parse_tabulated (width , height ):
@@ -220,7 +246,7 @@ def tabulate_tabulated(shape, width, height):
220
246
221
247
Returns:
222
248
tuple: shape, width_1d (float),
223
- height_1d (float), table (ndarray of shape (M, 2))
249
+ height_1d (float), table (ndarray of shape (M, 2)), None
224
250
"""
225
251
widths , heights = _parse_tabulated (width , height )
226
252
if len (heights ) > 1 and np .any (np .diff (heights ) < 0.0 ):
@@ -229,7 +255,7 @@ def tabulate_tabulated(shape, width, height):
229
255
f"(got: { height } )."
230
256
)
231
257
232
- return shape , np .max (widths ), np .max (heights ), np .array ([heights , widths ]).T
258
+ return shape , np .max (widths ), np .max (heights ), np .array ([heights , widths ]).T , None
233
259
234
260
235
261
def tabulate_yz (shape , width , height ):
@@ -242,7 +268,7 @@ def tabulate_yz(shape, width, height):
242
268
243
269
Returns:
244
270
tuple: shape, width_1d (float),
245
- height_1d (float), table (ndarray of shape (M, 2))
271
+ height_1d (float), table (ndarray of shape (M, 2)), yz (ndarray of shape (M, 4))
246
272
"""
247
273
ys , zs = _parse_tabulated (width , height )
248
274
is_closed = ys [0 ] == ys [- 1 ] and zs [0 ] == zs [- 1 ]
@@ -275,6 +301,13 @@ def tabulate_yz(shape, width, height):
275
301
if is_closed :
276
302
ys = ys [:- 1 ]
277
303
zs = zs [:- 1 ]
304
+ yz = None
305
+ shape_return = CrossSectionShape .TABULATED_TRAPEZIUM
306
+ else :
307
+ yz = np .zeros ((len (ys ), 4 ), dtype = float )
308
+ yz [:, 0 ] = ys
309
+ yz [:, 1 ] = zs
310
+ shape_return = CrossSectionShape .TABULATED_YZ
278
311
279
312
# Adapt non-unique height coordinates. Why?
280
313
# Because if a segment of the profile is exactly horizontal, we need 2 widths
@@ -318,7 +351,7 @@ def tabulate_yz(shape, width, height):
318
351
table = table [1 :]
319
352
320
353
height_1d , width_1d = table .max (axis = 0 ).tolist ()
321
- return CrossSectionShape . TABULATED_TRAPEZIUM , width_1d , height_1d , table
354
+ return shape_return , width_1d , height_1d , table , yz
322
355
323
356
324
357
tabulators = {
@@ -331,3 +364,27 @@ def tabulate_yz(shape, width, height):
331
364
CrossSectionShape .TABULATED_YZ : tabulate_yz ,
332
365
CrossSectionShape .INVERTED_EGG : tabulate_inverted_egg ,
333
366
}
367
+
368
+
369
+ def set_friction_vegetation_values (
370
+ yz ,
371
+ friction_values ,
372
+ vegetation_stem_densities ,
373
+ vegetation_stem_diameters ,
374
+ vegetation_heights ,
375
+ vegetation_drag_coefficients ,
376
+ ):
377
+ """Convert friction and vegetation properties from list into arrays, if available,
378
+ and add to yz"""
379
+ if friction_values is not None :
380
+ fric = np .array ([float (x ) for x in friction_values .split (" " )])
381
+ yz [:- 1 , 2 ] = fric
382
+
383
+ if vegetation_drag_coefficients is not None :
384
+ veg_stemden = np .array ([float (x ) for x in vegetation_stem_densities .split (" " )])
385
+ veg_stemdia = np .array ([float (x ) for x in vegetation_stem_diameters .split (" " )])
386
+ veg_hght = np .array ([float (x ) for x in vegetation_heights .split (" " )])
387
+ veg_drag = np .array ([float (x ) for x in vegetation_drag_coefficients .split (" " )])
388
+ yz [:- 1 , 3 ] = veg_stemden * veg_stemdia * veg_hght * veg_drag
389
+
390
+ return yz
0 commit comments