Skip to content

Commit 8793b2d

Browse files
committed
move GA infiltration amount to the rasterdomain
1 parent fa44354 commit 8793b2d

File tree

5 files changed

+62
-47
lines changed

5 files changed

+62
-47
lines changed

src/itzi/array_definitions.py

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
from dataclasses import dataclass
1616
from enum import Enum
1717
from typing import Optional
18-
from collections import Counter
1918

2019
import numpy as np
2120

@@ -209,6 +208,17 @@ class ArrayDefinition:
209208
cf_unit="",
210209
var_loc="face",
211210
),
211+
ArrayDefinition(
212+
key="total_infiltration",
213+
csdms_name="",
214+
cf_name="",
215+
category=[ArrayCategory.INTERNAL],
216+
description="Total calculated infiltration. Used for Green-Ampt model",
217+
unit="m",
218+
cf_unit="",
219+
var_loc="face",
220+
fill_value=1e-4,
221+
),
212222
ArrayDefinition(
213223
key="eff_precip",
214224
csdms_name="land_surface_water__effective_precipitation_leq-volume_flux",
@@ -590,19 +600,3 @@ class ArrayDefinition:
590600
+ _ACCUM_ARRAY_DEFINITIONS
591601
+ _OUTPUT_ARRAY_DEFINITIONS
592602
)
593-
594-
number_of_array_definitions = len(ARRAY_DEFINITIONS)
595-
596-
# Some sanity check
597-
for attr in ["key", "csdms_name", "cf_name", "description"]:
598-
all_values = [getattr(arr_def, attr) for arr_def in ARRAY_DEFINITIONS]
599-
# No empty name
600-
if "" in all_values and not attr == "cf_name":
601-
raise ValueError(f"Found empty names in <{attr}>.")
602-
# Make sure there is no duplicates
603-
values_counts = Counter(all_values)
604-
duplicates = [item for item, count in values_counts.items() if count > 1]
605-
if 0 < len(duplicates):
606-
if attr == "cf_name" and len(duplicates) == 1 and "" in duplicates:
607-
continue
608-
raise ValueError(f"Found duplicates in <{attr}>: {duplicates}")

src/itzi/infiltration.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
"""
1414

1515
from datetime import timedelta
16-
import numpy as np
1716

1817
import itzi.flow as flow
1918
from itzi.itzi_error import DtError
@@ -69,22 +68,14 @@ def step(self):
6968
class InfGreenAmpt(InfiltrationModel):
7069
"""Calculate infiltration using Green-Ampt formula"""
7170

72-
def __init__(self, raster_domain, dt_inf):
73-
InfiltrationModel.__init__(self, raster_domain, dt_inf)
74-
# Initial cumulative infiltration set to tiny value
75-
# (prevent division by zero)
76-
self.infiltration_amount = np.full(
77-
shape=self.dom.shape, fill_value=(1e-4), dtype=self.dom.dtype
78-
)
79-
8071
def step(self):
8172
"""update infiltration rate map in m/s."""
8273
flow.infiltration_ga(
8374
arr_h=self.dom.get_array("water_depth"),
8475
arr_eff_por=self.dom.get_array("effective_porosity"),
8576
arr_pressure=self.dom.get_array("capillary_pressure"),
8677
arr_conduct=self.dom.get_array("hydraulic_conductivity"),
87-
arr_inf_amount=self.infiltration_amount,
78+
arr_inf_amount=self.dom.get_array("total_infiltration"),
8879
arr_water_soil_content=self.dom.get_array("soil_water_content"),
8980
arr_inf_out=self.dom.get_array("computed_infiltration"),
9081
dt=self._dt,

src/itzi/rasterdomain.py

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,8 @@ def __init__(self, dtype, arr_mask, cell_shape):
104104

105105
# slice for a simple padding (allow stencil calculation on boundary)
106106
self.simple_pad = (slice(1, -1), slice(1, -1))
107-
# Fill values for input arrays
108-
self.input_fill_values = {
109-
arr_def.key: arr_def.fill_value
110-
for arr_def in ARRAY_DEFINITIONS
111-
if ArrayCategory.INPUT in arr_def.category
112-
}
107+
# Fill values
108+
self.fill_values = {arr_def.key: arr_def.fill_value for arr_def in ARRAY_DEFINITIONS}
113109

114110
# all keys that will be used for the arrays
115111
self.k_input = [
@@ -130,14 +126,7 @@ def __init__(self, dtype, arr_mask, cell_shape):
130126
# Instantiate arrays and padded arrays filled with zeros
131127
self.arr = dict.fromkeys(self.k_all)
132128
self.arrp = dict.fromkeys(self.k_all)
133-
self.create_arrays()
134-
135-
def zeros_array(self):
136-
"""return a np array of the domain dimension, filled with zeros.
137-
dtype is set to object's dtype.
138-
Intended to be used as default for the input model maps.
139-
"""
140-
return np.zeros(shape=self.shape, dtype=self.dtype)
129+
self._create_arrays()
141130

142131
def pad_array(self, arr):
143132
"""Return the original input array
@@ -147,12 +136,13 @@ def pad_array(self, arr):
147136
arr = arr_p[self.simple_pad]
148137
return arr, arr_p
149138

150-
def create_arrays(self):
139+
def _create_arrays(self):
151140
"""Instantiate masked arrays and padded arrays
152141
the unpadded arrays are a slice of the padded ones
153142
"""
154143
for k in self.arr.keys():
155-
self.arr[k], self.arrp[k] = self.pad_array(self.zeros_array())
144+
arr = np.full(fill_value=self.fill_values[k], shape=self.shape, dtype=self.dtype)
145+
self.arr[k], self.arrp[k] = self.pad_array(arr)
156146
return self
157147

158148
def update_mask(self, arr):
@@ -196,14 +186,13 @@ def swap_arrays(self, k1, k2):
196186

197187
def update_array(self, arr_key, arr):
198188
"""Update the values of an array with those of a given array."""
199-
fill_value = self.input_fill_values[arr_key]
200189
if arr.shape != self.shape:
201-
return ValueError
190+
return ValueError(f"Updated values for array '{arr_key}' do not match domain size.")
202191
if arr_key == "water_surface_elevation":
203192
# Calculate actual depth and update the internal depth array
204193
arr = rastermetrics.calculate_h_from_wse(arr_wse=arr, arr_dem=self.get_array("dem"))
205194
arr_key = "water_depth"
206-
self.mask_array(arr, fill_value)
195+
self.mask_array(arr, self.fill_values[arr_key])
207196
self.arr[arr_key][:], self.arrp[arr_key][:] = self.pad_array(arr)
208197
return self
209198

tests/test_array_definitions.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
from collections import Counter
2+
3+
from itzi.array_definitions import ARRAY_DEFINITIONS, ArrayCategory
4+
5+
6+
def test_array_definitions():
7+
# Empty names is acceptable in internal arrays
8+
for attr in ["csdms_name", "cf_name"]:
9+
all_values = [
10+
getattr(arr_def, attr)
11+
for arr_def in ARRAY_DEFINITIONS
12+
if ArrayCategory.INTERNAL not in arr_def.category
13+
]
14+
print(all_values)
15+
# No empty name
16+
if "" in all_values and not attr == "cf_name":
17+
print(attr)
18+
assert False, f"Found empty names in <{attr}>."
19+
# Make sure there is no duplicates
20+
values_counts = Counter(all_values)
21+
duplicates = [item for item, count in values_counts.items() if count > 1]
22+
if 0 < len(duplicates):
23+
if attr == "cf_name" and len(duplicates) == 1 and "" in duplicates:
24+
continue
25+
assert False, f"Found duplicates in <{attr}>: {duplicates}"
26+
27+
# All arrays must have a unique key and description
28+
for attr in ["key", "description"]:
29+
all_values = [getattr(arr_def, attr) for arr_def in ARRAY_DEFINITIONS]
30+
print(all_values)
31+
# No empty name
32+
if "" in all_values and not attr == "cf_name":
33+
print(attr)
34+
assert False, f"Found empty names in <{attr}>."
35+
# Make sure there is no duplicates
36+
values_counts = Counter(all_values)
37+
duplicates = [item for item, count in values_counts.items() if count > 1]
38+
if 0 < len(duplicates):
39+
if attr == "cf_name" and len(duplicates) == 1 and "" in duplicates:
40+
continue
41+
assert False, f"Found duplicates in <{attr}>: {duplicates}"

tests/test_infiltration.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def infiltration_sim(infiltration_parameters):
102102
while elapsed_time < inf_params.time:
103103
inf_sim.step()
104104
elapsed_time += inf_sim._dt
105-
return inf_sim.infiltration_amount.max()
105+
return raster_domain.get_array("total_infiltration").max()
106106

107107

108108
def test_infiltration(reference_infiltration, infiltration_sim):

0 commit comments

Comments
 (0)