From a28dd036115f98e3a2b0b74c1b3d41b4c46ca72a Mon Sep 17 00:00:00 2001 From: Fletcher Chapin Date: Thu, 8 Oct 2020 16:04:41 -0700 Subject: [PATCH] Added min and max rows to LFOM expert inputs (#280) * Added min and max rows to LFOM expert inputs * Renamed from min_rows to min_row_n * Changed default min_row_n to 4 so tests will still pass * Added tests for this feature * Bumping version --- aguaclara/design/lfom.py | 14 +++++++++++--- setup.py | 2 +- tests/design/test_lfom.py | 32 ++++++++++++++++++++++++-------- 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/aguaclara/design/lfom.py b/aguaclara/design/lfom.py index ae8c3d5b..bd9caf26 100644 --- a/aguaclara/design/lfom.py +++ b/aguaclara/design/lfom.py @@ -3,8 +3,9 @@ water level within the entrance tank. Example: - >>> from aguaclara.design.lfom import * - >>> lfom = LFOM(q = 20 * u.L / u.s, hl = 20 * u.cm) + >>> from aguaclara.core.units import u + >>> from aguaclara.design.lfom import LFOM + >>> lfom = LFOM(q=20 * u.L / u.s, hl=20 * u.cm) >>> lfom.row_n 6 """ @@ -34,6 +35,10 @@ class LFOM(Component): (optional) - ``orifice_s (float * u.cm)``: The spacing between orifices (optional, defaults to 0.5cm) + - ``min_row_n (int)``: Minimum number of rows of orifices (optional, + defaults to 4) + - ``max_row_n (int)``: Maximum number of rows of orifices (optional, + defaults to 10) """ def __init__(self, **kwargs): self.hl = 20.0 * u.cm @@ -41,6 +46,8 @@ def __init__(self, **kwargs): self.sdr = 26.0 self.drill_bits = drills.DRILL_BITS_D_IMPERIAL self.orifice_s = 0.5 * u.cm + self.min_row_n = 4 + self.max_row_n = 10 super().__init__(**kwargs) @@ -59,7 +66,8 @@ def row_n(self): """ The number of rows.""" N_estimated = (self.hl * np.pi / (2 * self.stout_w_per_flow(self.hl) * \ self.q)).to(u.dimensionless) - row_n = min(10, max(4, math.trunc(N_estimated.magnitude))) + row_n = min(self.max_row_n, + max(self.min_row_n, math.trunc(N_estimated.magnitude))) return row_n @property diff --git a/setup.py b/setup.py index 82d0ed56..094f1bf2 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name = 'aguaclara', - version = '0.2.4', + version = '0.2.5', description = ( 'An open-source Python package for designing and performing research ' 'on AguaClara water treatment plants.' diff --git a/tests/design/test_lfom.py b/tests/design/test_lfom.py index 3e0646cc..0ef97cbf 100644 --- a/tests/design/test_lfom.py +++ b/tests/design/test_lfom.py @@ -6,50 +6,66 @@ lfom_20 = LFOM(q = 20.0 * u.L / u.s) lfom_60 = LFOM(q = 60.0 * u.L / u.s) +lfom_60_5_rows = LFOM(q=60 * u.L / u.s, min_row_n=5) @pytest.mark.parametrize('actual, expected', [ (lfom_20.stout_w_per_flow(10 * u.cm) , 3.6077317813933907 * u.s / u.m ** 2), # 0 (lfom_60.stout_w_per_flow(10 * u.cm) , 3.6077317813933907 * u.s / u.m ** 2), + (lfom_60_5_rows.stout_w_per_flow(10 * u.cm) , 3.6077317813933907 * u.s / u.m ** 2), (lfom_20.row_n, 6), (lfom_60.row_n, 4), + (lfom_60_5_rows.row_n, 5), # 5 (lfom_20.row_b.to(u.m), 0.03333333333333333 * u.m), - (lfom_60.row_b.to(u.m), 0.05 * u.m), # 5 + (lfom_60.row_b.to(u.m), 0.05 * u.m), + (lfom_60_5_rows.row_b.to(u.m), 0.04 * u.m), (lfom_20.vel_critical.to(u.m/u.s), 0.8405802802312778 * u.m/u.s), - (lfom_60.vel_critical.to(u.m/u.s), 0.8405802802312778 * u.m/u.s), + (lfom_60.vel_critical.to(u.m/u.s), 0.8405802802312778 * u.m/u.s), # 10 + (lfom_60_5_rows.vel_critical.to(u.m/u.s), 0.8405802802312778 * u.m/u.s), (lfom_20.pipe_a_min.to(u.m**2), 0.035689630967485675 * u.m**2), (lfom_60.pipe_a_min.to(u.m**2), 0.10706889290245702 * u.m**2), + (lfom_60_5_rows.pipe_a_min.to(u.m**2), 0.107068893 * u.m**2), - (lfom_20.pipe_nd.to(u.inch), 10.0 * u.inch), # 10 + (lfom_20.pipe_nd.to(u.inch), 10.0 * u.inch), # 15 (lfom_60.pipe_nd.to(u.inch), 16.0 * u.inch), + (lfom_60_5_rows.pipe_nd.to(u.inch), 16.0 * u.inch), (lfom_20.top_row_orifice_a.to(u.m**2), 0.0017763243361009463 * u.m ** 2), (lfom_60.top_row_orifice_a.to(u.m**2), 0.00818156664907796 * u.m ** 2), + (lfom_60_5_rows.top_row_orifice_a.to(u.m**2), 0.00645370681 * u.m ** 2), # 20 (lfom_20.orifice_d_max.to(u.m), 0.047557190718114956 * u.m), - (lfom_60.orifice_d_max.to(u.m), 0.10206416704942245 * u.m), # 15 + (lfom_60.orifice_d_max.to(u.m), 0.10206416704942245 * u.m), + (lfom_60_5_rows.orifice_d_max.to(u.m), 0.0906483023 * u.m), (lfom_20.orifice_d.to(u.m), 0.03175 * u.m), - (lfom_60.orifice_d.to(u.m), 0.044449999999999996 * u.m), + (lfom_60.orifice_d.to(u.m), 0.044449999999999996 * u.m), # 25 + (lfom_60_5_rows.orifice_d.to(u.m), 0.0381 * u.m), + (lfom_20.drill_bit_a.to(u.m**2), 0.0007917304360898403 * u.m ** 2), (lfom_60.drill_bit_a.to(u.m**2), 0.0015517916547360866 * u.m ** 2), + (lfom_60_5_rows.drill_bit_a.to(u.m**2), 0.00114009183 * u.m ** 2), - (lfom_20.orifice_n_max_per_row, 21), # 20 + (lfom_20.orifice_n_max_per_row, 21), # 30 (lfom_60.orifice_n_max_per_row, 23), + (lfom_60_5_rows.orifice_n_max_per_row, 27), (lfom_20.q_per_row[5], 20.0 * u.L / u.s), (lfom_60.q_per_row[3], 60.0 * u.L / u.s), + (lfom_60_5_rows.q_per_row[4], 60.0 * u.L / u.s), # 35 (lfom_20.q_submerged(3, [4, 3, 2]), 5.939085475350429 * u.L / u.s), - (lfom_60.q_submerged(3, [4, 3, 2]), 14.34566338987966 * u.L / u.s), # 25 + (lfom_60.q_submerged(3, [4, 3, 2]), 14.34566338987966 * u.L / u.s), + (lfom_60_5_rows.q_submerged(3, [4, 3, 2]), 9.36855673 * u.L / u.s), (lfom_20.orifice_n_per_row[0], 12), - (lfom_60.orifice_n_per_row[0], 21) + (lfom_60.orifice_n_per_row[0], 21), # 40 + (lfom_60_5_rows.orifice_n_per_row[0], 27), ]) def test_lfom(actual, expected): if (type(actual) == u.Quantity and type(expected) == u.Quantity):