diff --git a/examples/dev_sandbox/DOX_sat_test.py b/examples/dev_sandbox/DOX_sat_test.py index c733174..6a356f4 100644 --- a/examples/dev_sandbox/DOX_sat_test.py +++ b/examples/dev_sandbox/DOX_sat_test.py @@ -25,7 +25,7 @@ def DOs_atm_alpha( def DOX_sat( TwaterK: xr.DataArray, - pressure_atm: xr.DataArray, + pressure_mb: xr.DataArray, pwv: xr.DataArray, DOs_atm_alpha: xr.DataArray ) -> xr.DataArray: @@ -33,7 +33,7 @@ def DOX_sat( Args: TwaterK: Water temperature kelvin - pressure_atm: Atmospheric pressure (atm) + pressure_mb: Atmospheric pressure (mb) pwv: Patrial pressure of water vapor (atm) DOs_atm_alpha: DO saturation atmospheric correction coefficient """ @@ -44,8 +44,8 @@ def DOX_sat( DOX_sat_uncorrected = -139.34410 + ( 1.575701E05 / TwaterK ) - ( 6.642308E07 / (TwaterK**2.0) ) + ( 1.243800E10 / (TwaterK**3.0) ) - ( 8.621949E11 / (TwaterK**4.0) ) - DOX_sat_corrected = DOX_sat_uncorrected * pressure_atm * \ - (1 - pwv / pressure_atm) * (1 - DOs_atm_alpha * pressure_atm) / \ + DOX_sat_corrected = DOX_sat_uncorrected * pressure_mb * \ + (1 - pwv / pressure_mb) * (1 - DOs_atm_alpha * pressure_mb) / \ ((1 - pwv) * (1 - DOs_atm_alpha)) print(no_exp) diff --git a/examples/dev_sandbox/prof_nsm.py b/examples/dev_sandbox/prof_nsm.py index 68a85db..a6cb10c 100644 --- a/examples/dev_sandbox/prof_nsm.py +++ b/examples/dev_sandbox/prof_nsm.py @@ -163,7 +163,7 @@ 'topwidth': 1, 'slope': 2, 'shear_velocity': 4, - 'pressure_atm': 2, + 'pressure_mb': 2026.5, 'wind_speed': 4, 'q_solar': 4, 'Solid': 1, diff --git a/src/clearwater_modules/nsm1/constants.py b/src/clearwater_modules/nsm1/constants.py index 7a42f3f..1412e49 100644 --- a/src/clearwater_modules/nsm1/constants.py +++ b/src/clearwater_modules/nsm1/constants.py @@ -98,7 +98,7 @@ class BalgaeStaticVariables(TypedDict): krb_20=0.2, kdb_20=0.3, mub_max_theta = 1.047, - krb_theta = 1.047, + krb_theta = 1.06, kdb_theta = 1.047, b_growth_rate_option=1, b_light_limitation_option=1, @@ -130,11 +130,11 @@ class NitrogenStaticVariables(TypedDict): kdnit_20=0.002, rnh4_20=0, vno3_20=0, - knit_theta= 1.047, ## Check values RAS/Kelsey's - kon_theta= 1.047, - kdnit_theta= 1.047, + knit_theta= 1.083, + kon_theta= 1.074, + kdnit_theta= 1.08, rnh4_theta= 1.047, - vno3_theta= 1.047, + vno3_theta= 1.045, KsOxdn=0.1, PN=0.5, PNb=0.5 @@ -156,10 +156,10 @@ class CarbonStaticVariables(TypedDict): DEFAULT_CARBON = CarbonStaticVariables( f_pocp = 0.9, kdoc_20= 0.01, - kdoc_theta = 1.047, f_pocb=0.9, kpoc_20= 0.005, kpoc_theta = 1.047, + kdoc_theta = 1.047, KsOxmc=1.0, pCO2 = 383.0, FCO2 = 0.2, @@ -200,10 +200,12 @@ class N2StaticVariables(TypedDict): class POMStaticVariables(TypedDict): kpom_20: float + h2: float kpom_theta: float DEFAULT_POM = POMStaticVariables( kpom_20 = 0.1, + h2=0.1, kpom_theta = 1.047 ) @@ -216,7 +218,7 @@ class PathogenStaticVariables(TypedDict): DEFAULT_PATHOGEN = PathogenStaticVariables( kdx_20=0.8, - kdx_theta = 1.047, + kdx_theta = 1.07, apx=1, vx=1 ) @@ -232,7 +234,7 @@ class PhosphorusStaticVariables(TypedDict): kop_20 = 0.1, rpo4_20 =0, kop_theta = 1.047, - rpo4_theta = 1.047, + rpo4_theta = 1.074, kdpo4 = 0.0, ) @@ -299,7 +301,7 @@ class GlobalVars(TypedDict): topwidth: float slope: float shear_velocity: float - pressure_atm: float + pressure_mb: float wind_speed: float q_solar: float Solid: int @@ -319,24 +321,24 @@ class GlobalVars(TypedDict): vs = 999, SOD_20 = 999, SOD_theta = 999, + theta=1.047, vb = 0.01, fcom = 0.4, kaw_20_user = 999, kah_20_user = 999, - kaw_theta = 1.047, - kah_theta = 1.047, - hydraulic_reaeration_option = 2, - wind_reaeration_option = 2, + kaw_theta = 1.024, + kah_theta = 1.024, + hydraulic_reaeration_option = 1, + wind_reaeration_option = 1, dt = 1, #TODO Dynamic or static? depth = 1.5, #TODO Dynamic or static? TwaterC = 20, - theta = 1.047, velocity = 1, flow = 2, topwidth = 1, slope = 2, shear_velocity = 4, - pressure_atm = 2, + pressure_mb = 2026.5, wind_speed = 4, q_solar = 500, Solid = 1, diff --git a/src/clearwater_modules/nsm1/dynamic_variables.py b/src/clearwater_modules/nsm1/dynamic_variables.py index 6d925ef..686da5c 100644 --- a/src/clearwater_modules/nsm1/dynamic_variables.py +++ b/src/clearwater_modules/nsm1/dynamic_variables.py @@ -1371,14 +1371,6 @@ class Variable(base.Variable): process=processes.KHN2_tc ) -Variable( - name='P_wv', - long_name='Partial pressure water vapor', - units='atm', - description='Partial pressure water vapor', - use='dynamic', - process=processes.P_wv -) Variable( name='N2sat', diff --git a/src/clearwater_modules/nsm1/processes.py b/src/clearwater_modules/nsm1/processes.py index e452e4f..1d39408 100644 --- a/src/clearwater_modules/nsm1/processes.py +++ b/src/clearwater_modules/nsm1/processes.py @@ -7,13 +7,7 @@ ############################################ From shared processes def celsius_to_kelvin(tempc: xr.DataArray) -> xr.DataArray: - return tempc + 273.16 - - - -def kelvin_to_celsius(tempk: xr.DataArray) -> xr.DataArray: - return tempk - 273.16 - + return tempc + 273.15 def arrhenius_correction( TwaterC: xr.DataArray, @@ -1512,6 +1506,8 @@ def NH4_ApGrowth( def NH4_AbRespiration( use_Balgae: bool, rnb: xr.DataArray, + Fb: xr.DataArray, + depth: xr.DataArray, AbRespiration: xr.DataArray, ) -> xr.DataArray: @@ -1521,10 +1517,12 @@ def NH4_AbRespiration( use_Balgae: true/false to use benthic algae module (unitless), rnb: xr.DataArray, AbRespiration: Benthic algal respiration rate (g/m^2/d), + depth: water depth (m), + Fb: Fraction of bottom area for benthic algae (unitless), """ # TODO changed the calculation for respiration from the inital FORTRAN due to conflict with the reference guide - return xr.where(use_Balgae, rnb * AbRespiration, 0.0 ) + return xr.where(use_Balgae, (rnb * AbRespiration*Fb)/depth, 0.0 ) def NH4_AbGrowth( use_Balgae: bool, @@ -2022,7 +2020,9 @@ def DIP_ApGrowth( def DIP_AbRespiration( rpb: xr.DataArray, AbRespiration: xr.DataArray, - use_Balgae: bool + use_Balgae: bool, + Fb: xr.DataArray, + depth: xr.DataArray ) -> xr.DataArray : """Calculate DIP_AbRespiration: Dissolved inorganic phosphorus released for benthic algal respiration (mg-P/L/d). @@ -2030,9 +2030,11 @@ def DIP_AbRespiration( Args: rpb: Benthic algal P : Benthic algal dry ratio (mg-P/mg-D) AbRespiration: Benthic algal respiration rate (g/m^2/d) - use_Blgae: true/false to use benthic algae module (t/f) + use_Blgae: true/false to use benthic algae module (t/f) + Fb: Fraction of bottom area available for benthic algal (unitless) + depth: water depth (m) """ - return xr.where(use_Balgae, rpb * AbRespiration,0) + return xr.where(use_Balgae, rpb * Fb * AbRespiration /depth,0) def DIP_AbGrowth( rpb: xr.DataArray, @@ -2199,7 +2201,7 @@ def POM_algal_settling( Ap: xr.DataArray, vsap: xr.DataArray, rda: xr.DataArray, - depth: xr.DataArray, + h2: xr.DataArray, use_Algae: xr.DataArray ) -> xr.DataArray: """Calculates the particulate organic matter concentration change due to algal mortality @@ -2208,10 +2210,10 @@ def POM_algal_settling( Ap: Algae concentration (mg/L) vsap: Algal settling velocity (m/d) rda: Ratio of algal biomass to chlorophyll-a - depth: Depth of water in computation cell (m) + h2: active sediment layer thickness (m) use_Algae: Option to consider algal kinetics """ - da: xr.DataArray = xr.where(use_Algae == True, vsap * Ap * rda / depth, 0) + da: xr.DataArray = xr.where(use_Algae == True, vsap * Ap * rda / h2, 0) return da @@ -2234,7 +2236,7 @@ def POM_dissolution( def POM_POC_settling( POC: xr.DataArray, vsoc: xr.DataArray, - depth: xr.DataArray, + h2: xr.DataArray, fcom: xr.DataArray, use_POC: xr.DataArray ) -> xr.DataArray: @@ -2243,11 +2245,11 @@ def POM_POC_settling( Args: POC: Concentration of particulate organic carbon (mg/L) vsoc: POC settling velocity (m/d) - depth: Depth of water (m) + h2: active sediment layer thickness (m) fcom: Fraction of carbon in organic matter (mg-C/mg-D) use_POC: Option to consider particulate organic carbon """ - da: xr.DataArray = xr.where(use_POC == True, vsoc * POC / depth / fcom, 0) + da: xr.DataArray = xr.where(use_POC == True, vsoc * POC / h2 / fcom, 0) return da @@ -2257,7 +2259,7 @@ def POM_benthic_algae_mortality( kdb_tc: xr.DataArray, Fb: xr.DataArray, Fw: xr.DataArray, - depth: xr.DataArray, + h2: xr.DataArray, use_Balgae: xr.DataArray ) -> xr.DataArray: """Calculates particulate organic matter concentration change due to benthic algae mortality @@ -2267,10 +2269,10 @@ def POM_benthic_algae_mortality( kdb_tc: Benthic algae death rate (1/d) Fb: Fraction of bottom area available for benthic algae growth Fw: Fraction of benthic algae mortality into water column - depth: Depth of water in computation cell (m) + h2: active sediment layer thickness (m) use_Balgae: Option for considering benthic algae in DOC budget (boolean) """ - da: xr.DataArray = xr.where(use_Balgae == True, Ab * kdb_tc * Fb * (1 - Fw) / depth, 0) + da: xr.DataArray = xr.where(use_Balgae == True, Ab * kdb_tc * Fb * (1 - Fw) / h2, 0) return da @@ -2279,16 +2281,16 @@ def POM_benthic_algae_mortality( def POM_burial( vb: xr.DataArray, POM: xr.DataArray, - depth: xr.DataArray + h2: xr.DataArray ) -> xr.DataArray: """Calculates particulate organic matter concentration change due to POM burial in the sediments Args: vb: Velocity of burial (m/d) POM: POM concentration (mg/L) - depth: Depth of water in computation cell (m) + h2: active sediment layer thickness (m) """ - return vb * POM / depth + return vb * POM / h2 #note removed 365 from FORTRAN @@ -2898,7 +2900,7 @@ def DOs_atm_alpha( def DOX_sat( TwaterK: xr.DataArray, - pressure_atm: xr.DataArray, + pressure_mb: xr.DataArray, pwv: xr.DataArray, DOs_atm_alpha: xr.DataArray ) -> xr.DataArray: @@ -2906,11 +2908,11 @@ def DOX_sat( Args: TwaterK: Water temperature kelvin - pressure_atm: Atmospheric pressure (atm) + pressure_mb: Atmospheric pressure (mb) pwv: Patrial pressure of water vapor (atm) DOs_atm_alpha: DO saturation atmospheric correction coefficient """ - pressure_atm = pressure_atm * 0.000986923 + pressure_atm = pressure_mb * 0.000986923 DOX_sat_uncorrected = np.exp(-139.34410 + ( 1.575701E05 / TwaterK ) - ( 6.642308E07 / (TwaterK**2.0) ) + ( 1.243800E10 / (TwaterK**3.0) ) - ( 8.621949E11 / (TwaterK**4.0) )) @@ -3465,36 +3467,21 @@ def KHN2_tc( return 0.00065 * np.exp(1300.0 * (1.0 / TwaterK - 1 / 298.15)) -def P_wv( - TwaterK : xr.DataArray, -) -> xr.DataArray : - - """Calculate partial pressure water vapor (atm) - - Constant values found in documentation - - Args: - TwaterK: water temperature kelvin (K) - - """ - return np.exp(11.8571 - (3840.70 / TwaterK) - (216961.0 / (TwaterK**2))) - - def N2sat( KHN2_tc : xr.DataArray, - pressure_atm: xr.DataArray, - P_wv: xr.DataArray + pressure_mb: xr.DataArray, + pwv: xr.DataArray ) -> xr.DataArray: """Calculate N2 at saturation f(Twater and atm pressure) (mg-N/L) Args: KHN2_tc: Henry's law constant (mol/L/atm) - pressure_atm: atmosphric pressure in atm (atm) - P_wv: Partial pressure of water vapor (atm) + pressure_mb: atmosphric pressure in mb (mb) + pwv: Partial pressure of water vapor (atm) """ - N2sat = 2.8E+4 * KHN2_tc * 0.79 * (pressure_atm - P_wv) + N2sat = 2.8E+4 * KHN2_tc * 0.79 * (pressure_mb*0.000986923 - pwv) N2sat = xr.where(N2sat < 0.0,0.000001,N2sat) #Trap saturation concentration to ensure never negative return N2sat diff --git a/src/clearwater_modules/nsm1/static_variables.py b/src/clearwater_modules/nsm1/static_variables.py index 787faea..ba075fd 100644 --- a/src/clearwater_modules/nsm1/static_variables.py +++ b/src/clearwater_modules/nsm1/static_variables.py @@ -473,10 +473,10 @@ class Variable(base.Variable): ) Variable( - name='pressure_atm', - long_name='pressure_atm', - units='TODO', - description='atmospheric pressure in atm', + name='pressure_mb', + long_name='pressure_mb', + units='mb', + description='atmospheric pressure in mb', use='static', ) @@ -918,6 +918,14 @@ class Variable(base.Variable): use='static' ) +Variable( + name='h2', + long_name='active sediment layer thickness', + units='m', + description='active sediment layer thickness', + use='static' +) + ############################################ From CBOD Variable( name='kbod_20', diff --git a/tests/test_10_nsm_carbon_calculations.py b/tests/test_10_nsm_carbon_calculations.py index c89fb6f..87ff36a 100644 --- a/tests/test_10_nsm_carbon_calculations.py +++ b/tests/test_10_nsm_carbon_calculations.py @@ -324,7 +324,7 @@ def default_gvars_params() -> GlobalVars: topwidth = 100, slope = 0.0002, shear_velocity = 0.05334, - pressure_atm = 1013.25, + pressure_mb = 1013.25, wind_speed = 3, q_solar = 500, Solid = 1, diff --git a/tests/test_11_nsm_DOX_calculations.py b/tests/test_11_nsm_DOX_calculations.py index 3e09dc5..bd89e34 100644 --- a/tests/test_11_nsm_DOX_calculations.py +++ b/tests/test_11_nsm_DOX_calculations.py @@ -324,7 +324,7 @@ def default_gvars_params() -> GlobalVars: topwidth = 100, slope = 0.0002, shear_velocity = 0.05334, - pressure_atm = 1013.25, + pressure_mb = 1013.25, wind_speed = 3, q_solar = 500, Solid = 1, @@ -867,7 +867,7 @@ def test_changed_TwaterC( assert isinstance(DOX, float) assert pytest.approx(DOX, tolerance) == 10.39 -def test_changed_pressure_atm( +def test_changed_pressure_mb( time_steps, initial_nsm1_state, default_algae_params, @@ -888,7 +888,7 @@ def test_changed_pressure_atm( """Test the model with default parameters.""" # alter parameters as necessary default_gvars_dict = default_gvars_params - default_gvars_dict['pressure_atm'] = 930 + default_gvars_dict['pressure_mb'] = 930 # instantiate the model nsm1: NutrientBudget = get_nutrient_budget_instance( diff --git a/tests/test_12_nsm_alkalinity_calculations.py b/tests/test_12_nsm_alkalinity_calculations.py index ea913cf..e4e7a17 100644 --- a/tests/test_12_nsm_alkalinity_calculations.py +++ b/tests/test_12_nsm_alkalinity_calculations.py @@ -324,7 +324,7 @@ def default_gvars_params() -> GlobalVars: topwidth = 100, slope = 0.0002, shear_velocity = 0.05334, - pressure_atm = 1013.25, + pressure_mb = 1013.25, wind_speed = 3, q_solar = 500, Solid = 1, diff --git a/tests/test_13_nsm_CBOD_calculations.py b/tests/test_13_nsm_CBOD_calculations.py index bb65dae..79664db 100644 --- a/tests/test_13_nsm_CBOD_calculations.py +++ b/tests/test_13_nsm_CBOD_calculations.py @@ -324,7 +324,7 @@ def default_gvars_params() -> GlobalVars: topwidth = 100, slope = 0.0002, shear_velocity = 0.05334, - pressure_atm = 1013.25, + pressure_mb = 1013.25, wind_speed = 3, q_solar = 500, Solid = 1, diff --git a/tests/test_14_nsm_phosphrous_calculations.py b/tests/test_14_nsm_phosphrous_calculations.py new file mode 100644 index 0000000..783d8e6 --- /dev/null +++ b/tests/test_14_nsm_phosphrous_calculations.py @@ -0,0 +1,1221 @@ +from numba import ( + types, + typed, +) +import pytest + +from clearwater_modules.nsm1 import NutrientBudget +from clearwater_modules.nsm1.constants import ( + AlgaeStaticVariables, + AlkalinityStaticVariables, + BalgaeStaticVariables, + NitrogenStaticVariables, + CarbonStaticVariables, + CBODStaticVariables, + DOXStaticVariables, + N2StaticVariables, + POMStaticVariables, + PathogenStaticVariables, + PhosphorusStaticVariables, + GlobalParameters, + GlobalVars +) + + +@pytest.fixture(scope='function') +def initial_nsm1_state() -> dict[str, float]: + """Return initial state values for the model.""" + return { + + 'Ap': 36.77, + 'Ab': 24, + 'NH4': 0.063, + 'NO3': 5.54, + 'OrgN': 1.726, + 'N2': 1, + 'TIP': 0.071, + 'OrgP': 0.24, + 'POC': 4.356, + 'DOC': 1, + 'DIC': 1, + 'POM': 10, + 'CBOD': 5, + 'DOX': 8, + 'PX': 1, + 'Alk': 1 + + } + +@pytest.fixture(scope='module') +def time_steps() -> int: + return 1 + +@pytest.fixture(scope='function') +def default_algae_params() -> AlgaeStaticVariables: + """Returns default algae static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return AlgaeStaticVariables( + AWd = 100, + AWc= 40, + AWn= 7.2, + AWp= 1, + AWa= 1000, + KL= 10, + KsN= 0.04, + KsP= 0.0012, + mu_max_20= 1, + kdp_20= 0.15, + krp_20= 0.2, + vsap= 0.15, + growth_rate_option = 1, + light_limitation_option = 1, + mu_max_theta= 1.047, + kdp_theta= 1.047, + krp_theta= 1.047, + ) + +@pytest.fixture(scope='function') +def default_alkalinity_params() -> AlkalinityStaticVariables: + """Returns default alkalinity static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return AlkalinityStaticVariables( + r_alkaa = 14.0 / 106.0 / 12.0 / 1000.0, + r_alkan= 18.0 / 106.0 / 12.0 / 1000.0, + r_alkn = 2.0 / 14.0 / 1000.0, + r_alkden = 4.0 / 14.0 / 1000.0, + r_alkba = 14.0 / 106.0 / 12.0 / 1000.0, + r_alkbn =18.0 / 106.0 / 12.0 / 1000.0 + ) + +@pytest.fixture(scope='function') +def default_balgae_params() -> BalgaeStaticVariables: + """Returns default Benthic Algae static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return BalgaeStaticVariables( + BWd = 100, + BWc= 40, + BWn=7.2, + BWp= 1, + BWa= 5000, + KLb= 10, + KsNb= 0.25, + KsPb=0.125, + Ksb=10, + mub_max_20=0.4, + krb_20=0.2, + kdb_20=0.3, + b_growth_rate_option=1, + b_light_limitation_option=1, + Fw=0.9, + Fb=0.9, + mub_max_theta = 1.047, + krb_theta = 1.06, + kdb_theta = 1.047, + ) + +@pytest.fixture(scope='function') +def default_nitrogen_params() -> NitrogenStaticVariables: + """Returns default nitrogen static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return NitrogenStaticVariables( + KNR= 0.6 , + knit_20= 0.1, + kon_20=0.1, + kdnit_20=0.002, + rnh4_20=0, + vno3_20=0, + KsOxdn=0.1, + PN=0.5, + PNb=0.5, + knit_theta= 1.083, + kon_theta= 1.047, + kdnit_theta= 1.045, + rnh4_theta= 1.074, + vno3_theta= 1.08, + ) + +@pytest.fixture(scope='function') +def default_carbon_params() -> CarbonStaticVariables: + """Returns default carbon static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return CarbonStaticVariables( + f_pocp = 0.9, + kdoc_20= 0.01, + f_pocb=0.9, + kpoc_20= 0.005, + KsOxmc=1.0, + pCO2 = 383.0, + FCO2 = 0.2, + roc = 32.0/12.0, + kpoc_theta = 1.047, + kdoc_theta = 1.047, + ) + +@pytest.fixture(scope='function') +def default_CBOD_params() -> CBODStaticVariables: + """Returns default CBOD static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return CBODStaticVariables( + KsOxbod = 0.5, + kbod_20 = 0.12, + ksbod_20 = 0.0, + kbod_theta = 1.047, + ksbod_theta = 1.047 + ) + +@pytest.fixture(scope='function') +def default_DOX_params() -> DOXStaticVariables: + """Returns default DOX static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return DOXStaticVariables( + ron = 2.0 * 32.0 / 14.0, + KsSOD =1, + ) + +@pytest.fixture(scope='function') +def default_N2_params() -> N2StaticVariables: + """Returns default N2 static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return N2StaticVariables( + + ) + +@pytest.fixture(scope='function') +def default_POM_params() -> POMStaticVariables: + """Returns default POM static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return POMStaticVariables( + kpom_20 = 0.1, + h2 = 0.1, + kpom_theta = 1.047 + ) + +@pytest.fixture(scope='function') +def default_pathogen_params() -> PathogenStaticVariables: + """Returns default Pathogens static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return PathogenStaticVariables( + kdx_20=0.8, + apx=1, + vx=1, + kdx_theta = 1.07, + ) + +@pytest.fixture(scope='function') +def default_phosphorus_params() -> PhosphorusStaticVariables: + """Returns default phosphorus static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return PhosphorusStaticVariables( + kop_20 = 0.1, + rpo4_20 =0, + kdpo4 = 0.0, + kop_theta = 1.047, + rpo4_theta = 1.074, + ) + +@pytest.fixture(scope='function') +def default_gp_params() -> GlobalParameters: + """Returns default global parameter static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return GlobalParameters( + use_NH4= False, + use_NO3= False, + use_OrgN= False, + use_OrgP = True, + use_TIP= True, + use_SedFlux= False, + use_POC = False, + use_DOC = False, + use_DOX= False, + use_DIC= False, + use_Algae= True, + use_Balgae= True, + use_N2 = False, + use_Pathogen = False, + use_Alk = False, + use_POM = False + ) + +@pytest.fixture(scope='function') +def default_gvars_params() -> GlobalVars: + """Returns default global variables static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return GlobalVars( + vson = 0.01, + vsoc = 0.01, + vsop = 0.01, + vs = 1, + SOD_20 = 999, + SOD_theta = 999, + vb = 0.01, + fcom = 0.4, + kaw_20_user = 0, + kah_20_user = 1, + hydraulic_reaeration_option = 1, + wind_reaeration_option = 1, + timestep = 1, #TODO Dynamic or static? + depth = 1.5, #TODO Dynamic or static? + TwaterC = 25, + kaw_theta = 1.024, + kah_theta = 1.024, + velocity = 1, + flow = 150, + topwidth = 100, + slope = 0.0002, + shear_velocity = 0.05334, + pressure_mb = 1013.25, + wind_speed = 3, + q_solar = 500, + Solid = 1, + lambda0 = .02, + lambda1 = .0088, + lambda2 = .054, + lambdas = .052, + lambdam = .174, + Fr_PAR = .47 + ) + +def get_nutrient_budget_instance( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + +) -> NutrientBudget: + """Return an instance of the NSM1 class.""" + return NutrientBudget( + time_steps=time_steps, + initial_state_values=initial_nsm1_state, + algae_parameters=default_algae_params, + alkalinity_parameters=default_alkalinity_params, + balgae_parameters=default_balgae_params, + nitrogen_parameters=default_nitrogen_params, + carbon_parameters=default_carbon_params, + CBOD_parameters=default_CBOD_params, + DOX_parameters=default_DOX_params, + N2_parameters=default_N2_params, + POM_parameters=default_POM_params, + pathogen_parameters=default_pathogen_params, + phosphorus_parameters=default_phosphorus_params, + global_parameters=default_gp_params, + global_vars=default_gvars_params, + time_dim='nsm1_time_step', + ) + +@pytest.fixture(scope='module') +def tolerance() -> float: + """Controls the precision of the pytest.approx() function.""" + return 0.000001 + +def test_defaults( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + TIP = nsm1.dataset.isel(nsm1_time_step=-1).TIP.values.item() + + assert isinstance(TIP, float) + assert pytest.approx(TIP, tolerance) == 0.100763082 + + OrgP = nsm1.dataset.isel(nsm1_time_step=-1).OrgP.values.item() + + assert isinstance(OrgP, float) + assert pytest.approx(OrgP, tolerance) == 0.26406066 + +def test_change_kop( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_phosphorus_params['kop_20'] = 0.2 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + + # Run the model + nsm1.increment_timestep() + + TIP = nsm1.dataset.isel(nsm1_time_step=-1).TIP.values.item() + + assert isinstance(TIP, float) + assert pytest.approx(TIP, tolerance) == 0.1309587507 + + OrgP = nsm1.dataset.isel(nsm1_time_step=-1).OrgP.values.item() + + assert isinstance(OrgP, float) + assert pytest.approx(OrgP, tolerance) == 0.233864988 + +def test_change_rpo4( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_phosphorus_params['rpo4_20'] = 0.1 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + + # Run the model + nsm1.increment_timestep() + + TIP = nsm1.dataset.isel(nsm1_time_step=-1).TIP.values.item() + + assert isinstance(TIP, float) + assert pytest.approx(TIP, tolerance) == 0.196027374917 + + OrgP = nsm1.dataset.isel(nsm1_time_step=-1).OrgP.values.item() + + assert isinstance(OrgP, float) + assert pytest.approx(OrgP, tolerance) == 0.2640606566 + +def test_change_use_OrgP( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gp_params['use_OrgP'] = False + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + + # Run the model + nsm1.increment_timestep() + + TIP = nsm1.dataset.isel(nsm1_time_step=-1).TIP.values.item() + + assert isinstance(TIP, float) + assert pytest.approx(TIP, tolerance) == 0.0705674135387 + + OrgP = nsm1.dataset.isel(nsm1_time_step=-1).OrgP.values.item() + + assert isinstance(OrgP, float) + assert pytest.approx(OrgP, tolerance) == 0.24 + +def test_change_use_TIP( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gp_params['use_TIP'] = False + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + + # Run the model + nsm1.increment_timestep() + + TIP = nsm1.dataset.isel(nsm1_time_step=-1).TIP.values.item() + + assert isinstance(TIP, float) + assert pytest.approx(TIP, tolerance) == 0.071 + + OrgP = nsm1.dataset.isel(nsm1_time_step=-1).OrgP.values.item() + + assert isinstance(OrgP, float) + assert pytest.approx(OrgP, tolerance) == 0.26406065661024 + +def test_change_use_algae( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gp_params['use_Algae'] = False + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + + # Run the model + nsm1.increment_timestep() + + TIP = nsm1.dataset.isel(nsm1_time_step=-1).TIP.values.item() + + assert isinstance(TIP, float) + assert pytest.approx(TIP, tolerance) == 0.13233980536753 + + OrgP = nsm1.dataset.isel(nsm1_time_step=-1).OrgP.values.item() + + assert isinstance(OrgP, float) + assert pytest.approx(OrgP, tolerance) == 0.25712131452332 + +def test_change_use_Balgae( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gp_params['use_Balgae'] = False + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + + # Run the model + nsm1.increment_timestep() + + TIP = nsm1.dataset.isel(nsm1_time_step=-1).TIP.values.item() + + assert isinstance(TIP, float) + assert pytest.approx(TIP, tolerance) == 0.0687962668837321 + + OrgP = nsm1.dataset.isel(nsm1_time_step=-1).OrgP.values.item() + + assert isinstance(OrgP, float) + assert pytest.approx(OrgP, tolerance) == 0.21514367350092 + +def test_change_vsop( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['vsop'] = 1 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + + # Run the model + nsm1.increment_timestep() + + TIP = nsm1.dataset.isel(nsm1_time_step=-1).TIP.values.item() + + assert isinstance(TIP, float) + assert pytest.approx(TIP, tolerance) == 0.100763082124724 + + OrgP = nsm1.dataset.isel(nsm1_time_step=-1).OrgP.values.item() + + assert isinstance(OrgP, float) + assert pytest.approx(OrgP, tolerance) == 0.10566065661024 + +def test_change_TIP( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + initial_nsm1_state['TIP'] = 1 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + + # Run the model + nsm1.increment_timestep() + + TIP = nsm1.dataset.isel(nsm1_time_step=-1).TIP.values.item() + + assert isinstance(TIP, float) + assert pytest.approx(TIP, tolerance) == 1.01955224933265 + + OrgP = nsm1.dataset.isel(nsm1_time_step=-1).OrgP.values.item() + + assert isinstance(OrgP, float) + assert pytest.approx(OrgP, tolerance) == 0.26406065661024 + +def test_change_OrgP( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + initial_nsm1_state['OrgP'] = 1 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + + # Run the model + nsm1.increment_timestep() + + TIP = nsm1.dataset.isel(nsm1_time_step=-1).TIP.values.item() + + assert isinstance(TIP, float) + assert pytest.approx(TIP, tolerance) == 0.196382699313724 + + OrgP = nsm1.dataset.isel(nsm1_time_step=-1).OrgP.values.item() + + assert isinstance(OrgP, float) + assert pytest.approx(OrgP, tolerance) == 0.923374372754573 + +def test_change_depth( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['depth'] = 0.5 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + + # Run the model + nsm1.increment_timestep() + + TIP = nsm1.dataset.isel(nsm1_time_step=-1).TIP.values.item() + + assert isinstance(TIP, float) + assert pytest.approx(TIP, tolerance) == 0.161233449642345 + + OrgP = nsm1.dataset.isel(nsm1_time_step=-1).OrgP.values.item() + + assert isinstance(OrgP, float) + assert pytest.approx(OrgP, tolerance) == 0.358694622828881 + +def test_change_TwaterC( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['TwaterC'] = 35 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + + # Run the model + nsm1.increment_timestep() + + TIP = nsm1.dataset.isel(nsm1_time_step=-1).TIP.values.item() + + assert isinstance(TIP, float) + assert pytest.approx(TIP, tolerance) == 0.12612604665317 + + OrgP = nsm1.dataset.isel(nsm1_time_step=-1).OrgP.values.item() + + assert isinstance(OrgP, float) + assert pytest.approx(OrgP, tolerance) == 0.279019500801769 + +def test_change_Ap( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + initial_nsm1_state['Ap'] = 25 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + + # Run the model + nsm1.increment_timestep() + + TIP = nsm1.dataset.isel(nsm1_time_step=-1).TIP.values.item() + + assert isinstance(TIP, float) + assert pytest.approx(TIP, tolerance) ==0.110370059884936 + + OrgP = nsm1.dataset.isel(nsm1_time_step=-1).OrgP.values.item() + + assert isinstance(OrgP, float) + assert pytest.approx(OrgP, tolerance) == 0.261839387739883 + +def test_change_Fw( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_balgae_params['Fw'] = 0.95 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + + # Run the model + nsm1.increment_timestep() + + TIP = nsm1.dataset.isel(nsm1_time_step=-1).TIP.values.item() + + assert isinstance(TIP, float) + assert pytest.approx(TIP, tolerance) == 0.100763082124724 + + OrgP = nsm1.dataset.isel(nsm1_time_step=-1).OrgP.values.item() + + assert isinstance(OrgP, float) + assert pytest.approx(OrgP, tolerance) == 0.26677826678298 + +def test_change_Fb( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_balgae_params['Fb'] = 0.5 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + + # Run the model + nsm1.increment_timestep() + + TIP = nsm1.dataset.isel(nsm1_time_step=-1).TIP.values.item() + + assert isinstance(TIP, float) + assert pytest.approx(TIP, tolerance) == 0.0865556086842829 + + OrgP = nsm1.dataset.isel(nsm1_time_step=-1).OrgP.values.item() + + assert isinstance(OrgP, float) + assert pytest.approx(OrgP, tolerance) ==0.24231977522832 \ No newline at end of file diff --git a/tests/test_15_nsm_POM_calculations.py b/tests/test_15_nsm_POM_calculations.py new file mode 100644 index 0000000..ab92b9e --- /dev/null +++ b/tests/test_15_nsm_POM_calculations.py @@ -0,0 +1,1181 @@ +from numba import ( + types, + typed, +) +import pytest + +from clearwater_modules.nsm1 import NutrientBudget +from clearwater_modules.nsm1.constants import ( + AlgaeStaticVariables, + AlkalinityStaticVariables, + BalgaeStaticVariables, + NitrogenStaticVariables, + CarbonStaticVariables, + CBODStaticVariables, + DOXStaticVariables, + N2StaticVariables, + POMStaticVariables, + PathogenStaticVariables, + PhosphorusStaticVariables, + GlobalParameters, + GlobalVars +) + + +@pytest.fixture(scope='function') +def initial_nsm1_state() -> dict[str, float]: + """Return initial state values for the model.""" + return { + + 'Ap': 36.77, + 'Ab': 24, + 'NH4': 0.063, + 'NO3': 5.54, + 'OrgN': 1.726, + 'N2': 1, + 'TIP': 0.071, + 'OrgP': 0.25, + 'POC': 4.356, + 'DOC': 1, + 'DIC': 1, + 'POM': 10, + 'CBOD': 5, + 'DOX': 8, + 'PX': 1, + 'Alk': 1 + + } + +@pytest.fixture(scope='module') +def time_steps() -> int: + return 1 + +@pytest.fixture(scope='function') +def default_algae_params() -> AlgaeStaticVariables: + """Returns default algae static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return AlgaeStaticVariables( + AWd = 100, + AWc= 40, + AWn= 7.2, + AWp= 1, + AWa= 1000, + KL= 10, + KsN= 0.04, + KsP= 0.0012, + mu_max_20= 1, + kdp_20= 0.15, + krp_20= 0.2, + vsap= 0.15, + growth_rate_option = 1, + light_limitation_option = 1, + mu_max_theta= 1.047, + kdp_theta= 1.047, + krp_theta= 1.047, + ) + +@pytest.fixture(scope='function') +def default_alkalinity_params() -> AlkalinityStaticVariables: + """Returns default alkalinity static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return AlkalinityStaticVariables( + r_alkaa = 14.0 / 106.0 / 12.0 / 1000.0, + r_alkan= 18.0 / 106.0 / 12.0 / 1000.0, + r_alkn = 2.0 / 14.0 / 1000.0, + r_alkden = 4.0 / 14.0 / 1000.0, + r_alkba = 14.0 / 106.0 / 12.0 / 1000.0, + r_alkbn =18.0 / 106.0 / 12.0 / 1000.0 + ) + +@pytest.fixture(scope='function') +def default_balgae_params() -> BalgaeStaticVariables: + """Returns default Benthic Algae static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return BalgaeStaticVariables( + BWd = 100, + BWc= 40, + BWn=7.2, + BWp= 1, + BWa= 5000, + KLb= 10, + KsNb= 0.25, + KsPb=0.125, + Ksb=10, + mub_max_20=0.4, + krb_20=0.2, + kdb_20=0.3, + b_growth_rate_option=1, + b_light_limitation_option=1, + Fw=0.9, + Fb=0.9, + mub_max_theta = 1.047, + krb_theta = 1.06, + kdb_theta = 1.047, + ) + +@pytest.fixture(scope='function') +def default_nitrogen_params() -> NitrogenStaticVariables: + """Returns default nitrogen static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return NitrogenStaticVariables( + KNR= 0.6 , + knit_20= 0.1, + kon_20=0.1, + kdnit_20=0.002, + rnh4_20=0, + vno3_20=0, + KsOxdn=0.1, + PN=0.5, + PNb=0.5, + knit_theta= 1.083, + kon_theta= 1.047, + kdnit_theta= 1.045, + rnh4_theta= 1.074, + vno3_theta= 1.08, + ) + +@pytest.fixture(scope='function') +def default_carbon_params() -> CarbonStaticVariables: + """Returns default carbon static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return CarbonStaticVariables( + f_pocp = 0.9, + kdoc_20= 0.01, + f_pocb=0.9, + kpoc_20= 0.005, + KsOxmc=1.0, + pCO2 = 383.0, + FCO2 = 0.2, + roc = 32.0/12.0, + kpoc_theta = 1.047, + kdoc_theta = 1.047, + ) + +@pytest.fixture(scope='function') +def default_CBOD_params() -> CBODStaticVariables: + """Returns default CBOD static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return CBODStaticVariables( + KsOxbod = 0.5, + kbod_20 = 0.12, + ksbod_20 = 0.0, + kbod_theta = 1.047, + ksbod_theta = 1.047 + ) + +@pytest.fixture(scope='function') +def default_DOX_params() -> DOXStaticVariables: + """Returns default DOX static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return DOXStaticVariables( + ron = 2.0 * 32.0 / 14.0, + KsSOD =1, + ) + +@pytest.fixture(scope='function') +def default_N2_params() -> N2StaticVariables: + """Returns default N2 static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return N2StaticVariables( + + ) + +@pytest.fixture(scope='function') +def default_POM_params() -> POMStaticVariables: + """Returns default POM static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return POMStaticVariables( + kpom_20 = 0.1, + h2 = 0.1, + kpom_theta = 1.047 + ) + +@pytest.fixture(scope='function') +def default_pathogen_params() -> PathogenStaticVariables: + """Returns default Pathogens static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return PathogenStaticVariables( + kdx_20=0.8, + apx=1, + vx=1, + kdx_theta = 1.07, + ) + +@pytest.fixture(scope='function') +def default_phosphorus_params() -> PhosphorusStaticVariables: + """Returns default phosphorus static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return PhosphorusStaticVariables( + kop_20 = 0.1, + rpo4_20 =0, + kdpo4 = 0.0, + kop_theta = 1.047, + rpo4_theta = 1.074, + ) +@pytest.fixture(scope='function') +def default_gp_params() -> GlobalParameters: + """Returns default global parameter static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return GlobalParameters( + use_NH4= False, + use_NO3= False, + use_OrgN= False, + use_OrgP = False, + use_TIP= False, + use_SedFlux= False, + use_POC = True, + use_DOC = False, + use_DOX= False, + use_DIC= False, + use_Algae= True, + use_Balgae= True, + use_N2 = False, + use_Pathogen = False, + use_Alk = False, + use_POM = True + ) + +@pytest.fixture(scope='function') +def default_gvars_params() -> GlobalVars: + """Returns default global variables static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return GlobalVars( + vson = 0.01, + vsoc = 0.01, + vsop = 0.01, + vs = 1, + SOD_20 = 999, + SOD_theta = 999, + vb = 0.01, + fcom = 0.4, + kaw_20_user = 0, + kah_20_user = 1, + hydraulic_reaeration_option = 1, + wind_reaeration_option = 1, + timestep = 1, #TODO Dynamic or static? + depth = 1.5, #TODO Dynamic or static? + TwaterC = 25, + kaw_theta = 1.024, + kah_theta = 1.024, + velocity = 1, + flow = 150, + topwidth = 100, + slope = 0.0002, + shear_velocity = 0.05334, + pressure_mb = 1013.25, + wind_speed = 3, + q_solar = 500, + Solid = 1, + lambda0 = .02, + lambda1 = .0088, + lambda2 = .054, + lambdas = .052, + lambdam = .174, + Fr_PAR = .47 + ) + +def get_nutrient_budget_instance( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + +) -> NutrientBudget: + """Return an instance of the NSM1 class.""" + return NutrientBudget( + time_steps=time_steps, + initial_state_values=initial_nsm1_state, + algae_parameters=default_algae_params, + alkalinity_parameters=default_alkalinity_params, + balgae_parameters=default_balgae_params, + nitrogen_parameters=default_nitrogen_params, + carbon_parameters=default_carbon_params, + CBOD_parameters=default_CBOD_params, + DOX_parameters=default_DOX_params, + N2_parameters=default_N2_params, + POM_parameters=default_POM_params, + pathogen_parameters=default_pathogen_params, + phosphorus_parameters=default_phosphorus_params, + global_parameters=default_gp_params, + global_vars=default_gvars_params, + time_dim='nsm1_time_step', + ) + +@pytest.fixture(scope='module') +def tolerance() -> float: + """Controls the precision of the pytest.approx() function.""" + return 0.000001 + +def test_defaults( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + POM = nsm1.dataset.isel(nsm1_time_step=-1).POM.values.item() + + assert isinstance(POM, float) + assert pytest.approx(POM, tolerance) == 22.49917766047 + +def test_kpom_20( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_POM_params['kpom_20'] = 0.002 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + POM = nsm1.dataset.isel(nsm1_time_step=-1).POM.values.item() + + assert isinstance(POM, float) + assert pytest.approx(POM, tolerance) == 23.732167461065 + +def test_TwaterC( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['TwaterC'] = 10 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + POM = nsm1.dataset.isel(nsm1_time_step=-1).POM.values.item() + + assert isinstance(POM, float) + assert pytest.approx(POM, tolerance) == 19.0663938058932 + +def test_vb( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['vb'] = 0.002 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + POM = nsm1.dataset.isel(nsm1_time_step=-1).POM.values.item() + + assert isinstance(POM, float) + assert pytest.approx(POM, tolerance) == 23.29917766047 + +def test_h2( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_POM_params['h2'] = 0.5 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + POM = nsm1.dataset.isel(nsm1_time_step=-1).POM.values.item() + + assert isinstance(POM, float) + assert pytest.approx(POM, tolerance) == 11.493313245894 + +def test_vsap( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_algae_params['vsap'] = 0.5 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + POM = nsm1.dataset.isel(nsm1_time_step=-1).POM.values.item() + + assert isinstance(POM, float) + assert pytest.approx(POM, tolerance) == 35.36867766047 + +def test_Ap( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + initial_nsm1_state['Ap'] = 50 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + POM = nsm1.dataset.isel(nsm1_time_step=-1).POM.values.item() + + assert isinstance(POM, float) + assert pytest.approx(POM, tolerance) == 24.48367766047 + +def test_Fb( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_balgae_params['Fb'] = 0.2 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + POM = nsm1.dataset.isel(nsm1_time_step=-1).POM.values.item() + + assert isinstance(POM, float) + assert pytest.approx(POM, tolerance) == 16.15808725741 + +def test_Fw( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_balgae_params['Fw'] = 0.97 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + POM = nsm1.dataset.isel(nsm1_time_step=-1).POM.values.item() + + assert isinstance(POM, float) + assert pytest.approx(POM, tolerance) == 16.792196297716 + +def test_vsoc( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['vsoc'] = 0.005 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + POM = nsm1.dataset.isel(nsm1_time_step=-1).POM.values.item() + + assert isinstance(POM, float) + assert pytest.approx(POM, tolerance) == 21.95467766047 + +def test_POC( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + initial_nsm1_state['POC'] = 2 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + POM = nsm1.dataset.isel(nsm1_time_step=-1).POM.values.item() + + assert isinstance(POM, float) + assert pytest.approx(POM, tolerance) == 21.91017766047 + +def test_fcom( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['fcom'] = 0.2 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + POM = nsm1.dataset.isel(nsm1_time_step=-1).POM.values.item() + + assert isinstance(POM, float) + assert pytest.approx(POM, tolerance) == 23.58817766047 + +def test_POM( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + initial_nsm1_state['POM'] = 5 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + POM = nsm1.dataset.isel(nsm1_time_step=-1).POM.values.item() + + assert isinstance(POM, float) + assert pytest.approx(POM, tolerance) == 18.628254089345 + +def test_use_Algae( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gp_params['use_Algae'] = False + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + POM = nsm1.dataset.isel(nsm1_time_step=-1).POM.values.item() + + assert isinstance(POM, float) + assert pytest.approx(POM, tolerance) == 16.98367766047 + +def test_use_Balgae( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gp_params['use_Balgae'] = False + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + POM = nsm1.dataset.isel(nsm1_time_step=-1).POM.values.item() + + assert isinstance(POM, float) + assert pytest.approx(POM, tolerance) == 14.34634714225 + +def test_use_POC( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gp_params['use_POC'] = False + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + POM = nsm1.dataset.isel(nsm1_time_step=-1).POM.values.item() + + assert isinstance(POM, float) + assert pytest.approx(POM, tolerance) == 21.41017766047 \ No newline at end of file diff --git a/tests/test_16_nsm_PX_calculations.py b/tests/test_16_nsm_PX_calculations.py new file mode 100644 index 0000000..6489614 --- /dev/null +++ b/tests/test_16_nsm_PX_calculations.py @@ -0,0 +1,857 @@ +from numba import ( + types, + typed, +) +import pytest + +from clearwater_modules.nsm1 import NutrientBudget +from clearwater_modules.nsm1.constants import ( + AlgaeStaticVariables, + AlkalinityStaticVariables, + BalgaeStaticVariables, + NitrogenStaticVariables, + CarbonStaticVariables, + CBODStaticVariables, + DOXStaticVariables, + N2StaticVariables, + POMStaticVariables, + PathogenStaticVariables, + PhosphorusStaticVariables, + GlobalParameters, + GlobalVars +) + + +@pytest.fixture(scope='function') +def initial_nsm1_state() -> dict[str, float]: + """Return initial state values for the model.""" + return { + + 'Ap': 36.77, + 'Ab': 24, + 'NH4': 0.063, + 'NO3': 5.54, + 'OrgN': 1.726, + 'N2': 1, + 'TIP': 0.071, + 'OrgP': 0.25, + 'POC': 4.356, + 'DOC': 1, + 'DIC': 1, + 'POM': 10, + 'CBOD': 5, + 'DOX': 8, + 'PX': 10, + 'Alk': 1 + + } + +@pytest.fixture(scope='module') +def time_steps() -> int: + return 1 + +@pytest.fixture(scope='function') +def default_algae_params() -> AlgaeStaticVariables: + """Returns default algae static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return AlgaeStaticVariables( + AWd = 100, + AWc= 40, + AWn= 7.2, + AWp= 1, + AWa= 1000, + KL= 10, + KsN= 0.04, + KsP= 0.0012, + mu_max_20= 1, + kdp_20= 0.15, + krp_20= 0.2, + vsap= 0.15, + growth_rate_option = 1, + light_limitation_option = 1, + mu_max_theta= 1.047, + kdp_theta= 1.047, + krp_theta= 1.047, + ) + +@pytest.fixture(scope='function') +def default_alkalinity_params() -> AlkalinityStaticVariables: + """Returns default alkalinity static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return AlkalinityStaticVariables( + r_alkaa = 14.0 / 106.0 / 12.0 / 1000.0, + r_alkan= 18.0 / 106.0 / 12.0 / 1000.0, + r_alkn = 2.0 / 14.0 / 1000.0, + r_alkden = 4.0 / 14.0 / 1000.0, + r_alkba = 14.0 / 106.0 / 12.0 / 1000.0, + r_alkbn =18.0 / 106.0 / 12.0 / 1000.0 + ) + +@pytest.fixture(scope='function') +def default_balgae_params() -> BalgaeStaticVariables: + """Returns default Benthic Algae static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return BalgaeStaticVariables( + BWd = 100, + BWc= 40, + BWn=7.2, + BWp= 1, + BWa= 5000, + KLb= 10, + KsNb= 0.25, + KsPb=0.125, + Ksb=10, + mub_max_20=0.4, + krb_20=0.2, + kdb_20=0.3, + b_growth_rate_option=1, + b_light_limitation_option=1, + Fw=0.9, + Fb=0.9, + mub_max_theta = 1.047, + krb_theta = 1.06, + kdb_theta = 1.047, + ) + +@pytest.fixture(scope='function') +def default_nitrogen_params() -> NitrogenStaticVariables: + """Returns default nitrogen static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return NitrogenStaticVariables( + KNR= 0.6 , + knit_20= 0.1, + kon_20=0.1, + kdnit_20=0.002, + rnh4_20=0, + vno3_20=0, + KsOxdn=0.1, + PN=0.5, + PNb=0.5, + knit_theta= 1.083, + kon_theta= 1.047, + kdnit_theta= 1.045, + rnh4_theta= 1.074, + vno3_theta= 1.08, + ) + +@pytest.fixture(scope='function') +def default_carbon_params() -> CarbonStaticVariables: + """Returns default carbon static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return CarbonStaticVariables( + f_pocp = 0.9, + kdoc_20= 0.01, + f_pocb=0.9, + kpoc_20= 0.005, + KsOxmc=1.0, + pCO2 = 383.0, + FCO2 = 0.2, + roc = 32.0/12.0, + kpoc_theta = 1.047, + kdoc_theta = 1.047, + ) + +@pytest.fixture(scope='function') +def default_CBOD_params() -> CBODStaticVariables: + """Returns default CBOD static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return CBODStaticVariables( + KsOxbod = 0.5, + kbod_20 = 0.12, + ksbod_20 = 0.0, + kbod_theta = 1.047, + ksbod_theta = 1.047 + ) + +@pytest.fixture(scope='function') +def default_DOX_params() -> DOXStaticVariables: + """Returns default DOX static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return DOXStaticVariables( + ron = 2.0 * 32.0 / 14.0, + KsSOD =1, + ) + +@pytest.fixture(scope='function') +def default_N2_params() -> N2StaticVariables: + """Returns default N2 static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return N2StaticVariables( + + ) + +@pytest.fixture(scope='function') +def default_POM_params() -> POMStaticVariables: + """Returns default POM static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return POMStaticVariables( + kpom_20 = 0.1, + h2 = 0.1, + kpom_theta = 1.047 + ) + +@pytest.fixture(scope='function') +def default_pathogen_params() -> PathogenStaticVariables: + """Returns default Pathogens static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return PathogenStaticVariables( + kdx_20=0.8, + apx=0.01, + vx=0.01, + kdx_theta = 1.07, + ) + +@pytest.fixture(scope='function') +def default_phosphorus_params() -> PhosphorusStaticVariables: + """Returns default phosphorus static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return PhosphorusStaticVariables( + kop_20 = 0.1, + rpo4_20 =0, + kdpo4 = 0.0, + kop_theta = 1.047, + rpo4_theta = 1.074, + ) + +@pytest.fixture(scope='function') +def default_gp_params() -> GlobalParameters: + """Returns default global parameter static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return GlobalParameters( + use_NH4= False, + use_NO3= False, + use_OrgN= False, + use_OrgP = False, + use_TIP= False, + use_SedFlux= False, + use_POC = False, + use_DOC = False, + use_DOX= False, + use_DIC= False, + use_Algae= False, + use_Balgae= False, + use_N2 = False, + use_Pathogen = True, + use_Alk = False, + use_POM = False + ) + +@pytest.fixture(scope='function') +def default_gvars_params() -> GlobalVars: + """Returns default global variables static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return GlobalVars( + vson = 0.01, + vsoc = 0.01, + vsop = 0.01, + vs = 1, + SOD_20 = 999, + SOD_theta = 999, + vb = 0.01, + fcom = 0.4, + kaw_20_user = 0, + kah_20_user = 1, + hydraulic_reaeration_option = 1, + wind_reaeration_option = 1, + timestep = 1, #TODO Dynamic or static? + depth = 1.5, #TODO Dynamic or static? + TwaterC = 10, + kaw_theta = 1.024, + kah_theta = 1.024, + velocity = 1, + flow = 150, + topwidth = 100, + slope = 0.0002, + shear_velocity = 0.05334, + pressure_mb = 1013.25, + wind_speed = 3, + q_solar = 1, + Solid = 1, + lambda0 = .02, + lambda1 = .0088, + lambda2 = .054, + lambdas = .052, + lambdam = .174, + Fr_PAR = .47 + ) + +def get_nutrient_budget_instance( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + +) -> NutrientBudget: + """Return an instance of the NSM1 class.""" + return NutrientBudget( + time_steps=time_steps, + initial_state_values=initial_nsm1_state, + algae_parameters=default_algae_params, + alkalinity_parameters=default_alkalinity_params, + balgae_parameters=default_balgae_params, + nitrogen_parameters=default_nitrogen_params, + carbon_parameters=default_carbon_params, + CBOD_parameters=default_CBOD_params, + DOX_parameters=default_DOX_params, + N2_parameters=default_N2_params, + POM_parameters=default_POM_params, + pathogen_parameters=default_pathogen_params, + phosphorus_parameters=default_phosphorus_params, + global_parameters=default_gp_params, + global_vars=default_gvars_params, + time_dim='nsm1_time_step', + ) + +@pytest.fixture(scope='module') +def tolerance() -> float: + """Controls the precision of the pytest.approx() function.""" + return 0.000001 + +def test_defaults( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + PathogenDeath = nsm1.dataset.isel(nsm1_time_step=-1).PathogenDeath.item() + assert isinstance(PathogenDeath, float) + print("PathogenDeath",PathogenDeath) + + PathogenDecay = nsm1.dataset.isel(nsm1_time_step=-1).PathogenDecay.item() + assert isinstance(PathogenDecay, float) + print("PathogenDecay",PathogenDecay) + + PathogenSettling = nsm1.dataset.isel(nsm1_time_step=-1).PathogenSettling.item() + assert isinstance(PathogenSettling, float) + print("PathogenSettling",PathogenSettling) + + L = nsm1.dataset.isel(nsm1_time_step=-1).L.item() + assert isinstance(L, float) + print("L",L) + + + PX = nsm1.dataset.isel(nsm1_time_step=-1).PX.values.item() + + assert isinstance(PX, float) + assert pytest.approx(PX, tolerance) == 5.768024108 + +def test_kdx_20( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_pathogen_params['kdx_20'] = 1.2 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + PX = nsm1.dataset.isel(nsm1_time_step=-1).PX.values.item() + + assert isinstance(PX, float) + assert pytest.approx(PX, tolerance) == 3.73462693954508 + +def test_TwaterC( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['TwaterC'] = 5 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + PX = nsm1.dataset.isel(nsm1_time_step=-1).PX.values.item() + + assert isinstance(PX, float) + assert pytest.approx(PX, tolerance) == 6.93525028802282 + +def test_apx( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_pathogen_params['apx'] = 0.001 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + PathogenDecay = nsm1.dataset.isel(nsm1_time_step=-1).PathogenDecay.item() + assert isinstance(PathogenDecay, float) + print("PathogenDecay",PathogenDecay) + + PX = nsm1.dataset.isel(nsm1_time_step=-1).PX.values.item() + + assert isinstance(PX, float) + assert pytest.approx(PX, tolerance) == 5.85668750743843 + +def test_vx( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_pathogen_params['vx'] = 0.5 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + PX = nsm1.dataset.isel(nsm1_time_step=-1).PX.values.item() + + assert isinstance(PX, float) + assert pytest.approx(PX, tolerance) == 2.50135744141729 + +def test_PX( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + initial_nsm1_state['PX'] = 20 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + PX = nsm1.dataset.isel(nsm1_time_step=-1).PX.values.item() + + assert isinstance(PX, float) + assert pytest.approx(PX, tolerance) == 11.53604822 + +def test_depth( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['depth'] = 3 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + PX = nsm1.dataset.isel(nsm1_time_step=-1).PX.values.item() + + assert isinstance(PX, float) + assert pytest.approx(PX, tolerance) == 5.80281321889601 + +def test_q_solar( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['q_solar'] = 10 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + PX = nsm1.dataset.isel(nsm1_time_step=-1).PX.values.item() + + assert isinstance(PX, float) + assert pytest.approx(PX, tolerance) == 4.8813901145392 + +def test_use_Algae( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gp_params['use_Algae'] = True + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + L = nsm1.dataset.isel(nsm1_time_step=-1).L.item() + assert isinstance(L, float) + print("L",L) + + PX = nsm1.dataset.isel(nsm1_time_step=-1).PX.values.item() + + assert isinstance(PX, float) + assert pytest.approx(PX, tolerance) == 5.812953513 diff --git a/tests/test_17_nsm_N2_calculations.py b/tests/test_17_nsm_N2_calculations.py new file mode 100644 index 0000000..6d493e8 --- /dev/null +++ b/tests/test_17_nsm_N2_calculations.py @@ -0,0 +1,1978 @@ +from numba import ( + types, + typed, +) +import pytest + +from clearwater_modules.nsm1 import NutrientBudget +from clearwater_modules.nsm1.constants import ( + AlgaeStaticVariables, + AlkalinityStaticVariables, + BalgaeStaticVariables, + NitrogenStaticVariables, + CarbonStaticVariables, + CBODStaticVariables, + DOXStaticVariables, + N2StaticVariables, + POMStaticVariables, + PathogenStaticVariables, + PhosphorusStaticVariables, + GlobalParameters, + GlobalVars +) + + +@pytest.fixture(scope='function') +def initial_nsm1_state() -> dict[str, float]: + """Return initial state values for the model.""" + return { + + 'Ap': 36.77, + 'Ab': 24, + 'NH4': 0.063, + 'NO3': 5.54, + 'OrgN': 1.726, + 'N2': 1, + 'TIP': 0.071, + 'OrgP': 0.25, + 'POC': 4.356, + 'DOC': 1, + 'DIC': 1, + 'POM': 10, + 'CBOD': 5, + 'DOX': 8, + 'PX': 1, + 'Alk': 1 + + } + +@pytest.fixture(scope='module') +def time_steps() -> int: + return 1 + +@pytest.fixture(scope='function') +def default_algae_params() -> AlgaeStaticVariables: + """Returns default algae static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return AlgaeStaticVariables( + AWd = 100, + AWc= 40, + AWn= 7.2, + AWp= 1, + AWa= 1000, + KL= 10, + KsN= 0.04, + KsP= 0.0012, + mu_max_20= 1, + kdp_20= 0.15, + krp_20= 0.2, + vsap= 0.15, + growth_rate_option = 1, + light_limitation_option = 1, + mu_max_theta= 1.047, + kdp_theta= 1.047, + krp_theta= 1.047, + ) + +@pytest.fixture(scope='function') +def default_alkalinity_params() -> AlkalinityStaticVariables: + """Returns default alkalinity static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return AlkalinityStaticVariables( + r_alkaa = 14.0 / 106.0 / 12.0 / 1000.0, + r_alkan= 18.0 / 106.0 / 12.0 / 1000.0, + r_alkn = 2.0 / 14.0 / 1000.0, + r_alkden = 4.0 / 14.0 / 1000.0, + r_alkba = 14.0 / 106.0 / 12.0 / 1000.0, + r_alkbn =18.0 / 106.0 / 12.0 / 1000.0 + ) + +@pytest.fixture(scope='function') +def default_balgae_params() -> BalgaeStaticVariables: + """Returns default Benthic Algae static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return BalgaeStaticVariables( + BWd = 100, + BWc= 40, + BWn=7.2, + BWp= 1, + BWa= 5000, + KLb= 10, + KsNb= 0.25, + KsPb=0.125, + Ksb=10, + mub_max_20=0.4, + krb_20=0.2, + kdb_20=0.3, + b_growth_rate_option=1, + b_light_limitation_option=1, + Fw=0.9, + Fb=0.9, + mub_max_theta = 1.047, + krb_theta = 1.06, + kdb_theta = 1.047, + ) + +@pytest.fixture(scope='function') +def default_nitrogen_params() -> NitrogenStaticVariables: + """Returns default nitrogen static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return NitrogenStaticVariables( + KNR= 0.6 , + knit_20= 0.1, + kon_20=0.1, + kdnit_20=0.002, + rnh4_20=0, + vno3_20=0, + KsOxdn=0.1, + PN=0.5, + PNb=0.5, + knit_theta= 1.083, + kon_theta= 1.047, + kdnit_theta= 1.045, + rnh4_theta= 1.074, + vno3_theta= 1.08, + ) + +@pytest.fixture(scope='function') +def default_carbon_params() -> CarbonStaticVariables: + """Returns default carbon static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return CarbonStaticVariables( + f_pocp = 0.9, + kdoc_20= 0.01, + f_pocb=0.9, + kpoc_20= 0.005, + KsOxmc=1.0, + pCO2 = 383.0, + FCO2 = 0.2, + roc = 32.0/12.0, + kpoc_theta = 1.047, + kdoc_theta = 1.047, + ) + +@pytest.fixture(scope='function') +def default_CBOD_params() -> CBODStaticVariables: + """Returns default CBOD static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return CBODStaticVariables( + KsOxbod = 0.5, + kbod_20 = 0.12, + ksbod_20 = 0.0, + kbod_theta = 1.047, + ksbod_theta = 1.047 + ) + +@pytest.fixture(scope='function') +def default_DOX_params() -> DOXStaticVariables: + """Returns default DOX static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return DOXStaticVariables( + ron = 2.0 * 32.0 / 14.0, + KsSOD =1, + ) + +@pytest.fixture(scope='function') +def default_N2_params() -> N2StaticVariables: + """Returns default N2 static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return N2StaticVariables( + + ) + +@pytest.fixture(scope='function') +def default_POM_params() -> POMStaticVariables: + """Returns default POM static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return POMStaticVariables( + kpom_20 = 0.1, + h2 = 0.1, + kpom_theta = 1.047 + ) + +@pytest.fixture(scope='function') +def default_pathogen_params() -> PathogenStaticVariables: + """Returns default Pathogens static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return PathogenStaticVariables( + kdx_20=0.8, + apx=1, + vx=1, + kdx_theta = 1.07, + ) + +@pytest.fixture(scope='function') +def default_phosphorus_params() -> PhosphorusStaticVariables: + """Returns default phosphorus static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return PhosphorusStaticVariables( + kop_20 = 0.1, + rpo4_20 =0, + kdpo4 = 0.0, + kop_theta = 1.047, + rpo4_theta = 1.074, + ) + +@pytest.fixture(scope='function') +def default_gp_params() -> GlobalParameters: + """Returns default global parameter static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return GlobalParameters( + use_NH4= False, + use_NO3= False, + use_OrgN= False, + use_OrgP = False, + use_TIP= False, + use_SedFlux= False, + use_POC = False, + use_DOC = False, + use_DOX= True, + use_DIC= False, + use_Algae= False, + use_Balgae= False, + use_N2 = True, + use_Pathogen = False, + use_Alk = False, + use_POM = False + ) + +@pytest.fixture(scope='function') +def default_gvars_params() -> GlobalVars: + """Returns default global variables static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return GlobalVars( + vson = 0.01, + vsoc = 0.01, + vsop = 0.01, + vs = 1, + SOD_20 = 999, + SOD_theta = 999, + vb = 0.01, + fcom = 0.4, + kaw_20_user = 0, + kah_20_user = 1, + hydraulic_reaeration_option = 1, + wind_reaeration_option = 1, + timestep = 1, #TODO Dynamic or static? + depth = 1.5, #TODO Dynamic or static? + TwaterC = 25, + kaw_theta = 1.024, + kah_theta = 1.024, + velocity = 1, + flow = 150, + topwidth = 100, + slope = 0.0002, + shear_velocity = 0.05334, + pressure_mb = 1013.25, + wind_speed = 3, + q_solar = 500, + Solid = 1, + lambda0 = .02, + lambda1 = .0088, + lambda2 = .054, + lambdas = .052, + lambdam = .174, + Fr_PAR = .47 + ) + +def get_nutrient_budget_instance( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + +) -> NutrientBudget: + """Return an instance of the NSM1 class.""" + return NutrientBudget( + time_steps=time_steps, + initial_state_values=initial_nsm1_state, + algae_parameters=default_algae_params, + alkalinity_parameters=default_alkalinity_params, + balgae_parameters=default_balgae_params, + nitrogen_parameters=default_nitrogen_params, + carbon_parameters=default_carbon_params, + CBOD_parameters=default_CBOD_params, + DOX_parameters=default_DOX_params, + N2_parameters=default_N2_params, + POM_parameters=default_POM_params, + pathogen_parameters=default_pathogen_params, + phosphorus_parameters=default_phosphorus_params, + global_parameters=default_gp_params, + global_vars=default_gvars_params, + time_dim='nsm1_time_step', + ) + +@pytest.fixture(scope='module') +def tolerance() -> float: + """Controls the precision of the pytest.approx() function.""" + return 0.000001 + +def test_defaults( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + + ka_tc = nsm1.dataset.isel(nsm1_time_step=-1).ka_tc.item() + assert isinstance(ka_tc, float) + print("ka_tc",ka_tc) + + + pwv = nsm1.dataset.isel(nsm1_time_step=-1).pwv.item() + assert isinstance(pwv, float) + print("pwv",pwv) + + DOX_sat = nsm1.dataset.isel(nsm1_time_step=-1).DOX_sat.item() + assert isinstance(DOX_sat, float) + print("DOX_sat",DOX_sat) + + DOX = nsm1.dataset.isel(nsm1_time_step=-1).DOX.item() + assert isinstance(DOX, float) + print("DOX",DOX) + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 16.0511281 + +def test_N2( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + initial_state_dict['N2'] = 2 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 15.8869475476111 + +def test_DOX( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + initial_state_dict['DOX'] = 8 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 16.0511280512864 + +def test_use_DOX( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gp_params['use_DOX'] = False + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 16.0511280512864 + +def test_pressure_atm( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['pressure_mb'] = 2026.5 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 32.7897153331295 + + +def test_TwaterC( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['TwaterC'] = 30 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 16.4930672056418 + +def test_Salinity( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['Salinity'] = 5 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 16.0511280512864 + +def test_kah( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['kah_20_user'] = 2 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 31.1022561025728 + +def test_kaw( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['kaw_20_user'] = 0.5 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 21.0681707350485 + +def test_wr_2_hr_2( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['hydraulic_reaeration_option'] = 2 + default_gvars_params['wind_reaeration_option'] = 2 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 65.9366965785228 + +def test_wr_3_hr_3( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['hydraulic_reaeration_option'] = 3 + default_gvars_params['wind_reaeration_option'] = 3 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 46.9755965621132 + +def test_wr_4_hr_4( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['hydraulic_reaeration_option'] = 4 + default_gvars_params['wind_reaeration_option'] = 4 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 46.94093398065 + +def test_wr_5_hr_5( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['hydraulic_reaeration_option'] = 5 + default_gvars_params['wind_reaeration_option'] = 5 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 41.9426132334058 + +def test_wr_6_hr_6( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['hydraulic_reaeration_option'] = 6 + default_gvars_params['wind_reaeration_option'] = 6 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 63.7322409376813 + +def test_wr_7_hr_7( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['hydraulic_reaeration_option'] = 7 + default_gvars_params['wind_reaeration_option'] = 7 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 39.382889432894 + +def test_wr_8_hr_8( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['hydraulic_reaeration_option'] = 8 + default_gvars_params['wind_reaeration_option'] = 8 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 71.8185615550307 + +def test_wr_9_hr_9( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['hydraulic_reaeration_option'] = 9 + default_gvars_params['wind_reaeration_option'] = 9 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 13.2060831760727 + +def test_wr_10_hr_5_depth( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['hydraulic_reaeration_option'] = 5 + default_gvars_params['wind_reaeration_option'] = 10 + default_gvars_params['depth'] = 0.5 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 301.508013077305 + +def test_wr_11_hr_6_depth( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['hydraulic_reaeration_option'] = 6 + default_gvars_params['wind_reaeration_option'] = 11 + default_gvars_params['depth'] = 0.5 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 70.1055933861735 + +def test_wr_12_hr_7_depth( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['hydraulic_reaeration_option'] = 7 + default_gvars_params['wind_reaeration_option'] = 12 + default_gvars_params['depth'] = 0.5 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 101.944511624376 + +def test_wr_13_hr_8_depth( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['hydraulic_reaeration_option'] = 8 + default_gvars_params['wind_reaeration_option'] = 13 + default_gvars_params['flow'] = 0.4 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + kah_tc = nsm1.dataset.isel(nsm1_time_step=-1).kah_tc.item() + assert isinstance(kah_tc, float) + print("kah_tc",kah_tc) + + kaw_tc = nsm1.dataset.isel(nsm1_time_step=-1).kaw_tc.item() + assert isinstance(kaw_tc, float) + print("kaw_tc",kaw_tc) + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 117.0476547 + +def test_wr_7_hr_2_wind_speed( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['hydraulic_reaeration_option'] = 2 + default_gvars_params['wind_reaeration_option'] = 7 + default_gvars_params['wind_speed'] = 5 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 44.208087138308 + +def test_wr_9_hr_3_wind_speed( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['hydraulic_reaeration_option'] = 3 + default_gvars_params['wind_reaeration_option'] = 9 + default_gvars_params['wind_speed'] = 5 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 47.7149213700046 + +def test_wr_13_hr_4_wind_speed( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['hydraulic_reaeration_option'] = 4 + default_gvars_params['wind_reaeration_option'] = 13 + default_gvars_params['wind_speed'] = 0.5 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 43.4278798307678 + +def test_wr_2_hr_2_velocity( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['hydraulic_reaeration_option'] = 2 + default_gvars_params['wind_reaeration_option'] = 2 + default_gvars_params['velocity'] = 2 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 79.2734163846862 + +def test_wr_3_hr_6_flow( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['hydraulic_reaeration_option'] = 6 + default_gvars_params['wind_reaeration_option'] = 3 + default_gvars_params['flow'] = 70 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 65.2387385186712 + +def test_wr_4_hr_7_slope( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['hydraulic_reaeration_option'] = 7 + default_gvars_params['wind_reaeration_option'] = 4 + default_gvars_params['slope'] = 0.001 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + kah_tc = nsm1.dataset.isel(nsm1_time_step=-1).kah_tc.item() + assert isinstance(kah_tc, float) + print("kah_tc",kah_tc) + + kaw_tc = nsm1.dataset.isel(nsm1_time_step=-1).kaw_tc.item() + assert isinstance(kaw_tc, float) + print("kaw_tc",kaw_tc) + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 62.0415408678264 + +def test_wr_5_hr_7_topwidth( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['hydraulic_reaeration_option'] = 7 + default_gvars_params['wind_reaeration_option'] = 5 + default_gvars_params['topwidth'] = 150 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 38.12999386 + +def test_wr_6_hr_6_wind_speed( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['hydraulic_reaeration_option'] = 6 + default_gvars_params['wind_reaeration_option'] = 6 + default_gvars_params['wind_speed'] = 1 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 57.3724446605991 + +def test_wr_7_hr_9_shear_velocity( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['hydraulic_reaeration_option'] = 9 + default_gvars_params['wind_reaeration_option'] = 7 + default_gvars_params['shear_velocity'] = 0.01 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + + + N2 = nsm1.dataset.isel(nsm1_time_step=-1).N2.values.item() + + assert isinstance(N2, float) + assert pytest.approx(N2, tolerance) == 9.66922524093679 \ No newline at end of file diff --git a/tests/test_7_nsm_algae_calculations.py b/tests/test_7_nsm_algae_calculations.py index 79dbfb6..543bb4e 100644 --- a/tests/test_7_nsm_algae_calculations.py +++ b/tests/test_7_nsm_algae_calculations.py @@ -31,10 +31,10 @@ def initial_nsm1_state() -> dict[str, float]: 'Ab': 24, 'NH4': 0.05, 'NO3': 5, - 'OrgN': 1.7, + 'OrgN': 1.726, 'N2': 1, 'TIP': 0.07, - 'OrgP': 0.25, + 'OrgP': 0.24, 'POC': 4, 'DOC': 1, 'DIC': 1, @@ -74,6 +74,9 @@ def default_algae_params() -> AlgaeStaticVariables: vsap= 0.15, growth_rate_option = 1, light_limitation_option = 1, + mu_max_theta= 1.047, + kdp_theta= 1.047, + krp_theta= 1.047, ) @pytest.fixture(scope='function') @@ -108,7 +111,7 @@ def default_balgae_params() -> BalgaeStaticVariables: BWc= 40, BWn=7.2, BWp= 1, - BWa= 3500, + BWa= 5000, KLb= 10, KsNb= 0.25, KsPb=0.125, @@ -119,7 +122,10 @@ def default_balgae_params() -> BalgaeStaticVariables: b_growth_rate_option=1, b_light_limitation_option=1, Fw=0.9, - Fb=0.9 + Fb=0.9, + mub_max_theta = 1.047, + krb_theta = 1.06, + kdb_theta = 1.047, ) @pytest.fixture(scope='function') @@ -140,7 +146,12 @@ def default_nitrogen_params() -> NitrogenStaticVariables: vno3_20=0, KsOxdn=0.1, PN=0.5, - PNb=0.5 + PNb=0.5, + knit_theta= 1.083, + kon_theta= 1.074, + kdnit_theta= 1.08, + rnh4_theta= 1.047, + vno3_theta= 1.045, ) @pytest.fixture(scope='function') @@ -160,7 +171,9 @@ def default_carbon_params() -> CarbonStaticVariables: KsOxmc=1.0, pCO2 = 383.0, FCO2 = 0.2, - roc = 32.0/12.0 + roc = 32.0/12.0, + kpoc_theta = 1.047, + kdoc_theta = 1.047, ) @pytest.fixture(scope='function') @@ -175,7 +188,9 @@ def default_CBOD_params() -> CBODStaticVariables: return CBODStaticVariables( KsOxbod = 0.5, kbod_20 = 0.12, - ksbod_20 = 0.0 + ksbod_20 = 0.0, + kbod_theta = 1.047, + ksbod_theta = 1.047 ) @pytest.fixture(scope='function') @@ -215,7 +230,9 @@ def default_POM_params() -> POMStaticVariables: Returns a typed dictionary, with string keys and float values. """ return POMStaticVariables( - kpom_20 = 0.1 + kpom_20 = 0.1, + h2 = 0.1, + kpom_theta = 1.047 ) @pytest.fixture(scope='function') @@ -230,7 +247,8 @@ def default_pathogen_params() -> PathogenStaticVariables: return PathogenStaticVariables( kdx_20=0.8, apx=1, - vx=1 + vx=1, + kdx_theta = 1.07, ) @pytest.fixture(scope='function') @@ -246,6 +264,8 @@ def default_phosphorus_params() -> PhosphorusStaticVariables: kop_20 = 0.1, rpo4_20 =0, kdpo4 = 0.0, + kop_theta = 1.047, + rpo4_theta = 1.047, ) @pytest.fixture(scope='function') @@ -288,27 +308,29 @@ def default_gvars_params() -> GlobalVars: return GlobalVars( vson = 0.01, vsoc = 0.01, - vsop = 999, - vs = 999, + vsop = 0.01, + vs = 1, SOD_20 = 999, SOD_theta = 999, + theta=1.047, vb = 0.01, fcom = 0.4, - kaw_20_user = 999, - kah_20_user = 999, - hydraulic_reaeration_option = 2, - wind_reaeration_option = 2, + kaw_20_user = 0, + kah_20_user = 1, + hydraulic_reaeration_option = 1, + wind_reaeration_option = 1, timestep = 1, #TODO Dynamic or static? depth = 1.5, #TODO Dynamic or static? TwaterC = 25, - theta = 1.047, + kaw_theta = 1.024, + kah_theta = 1.024, velocity = 1, - flow = 2, - topwidth = 1, - slope = 2, - shear_velocity = 4, - pressure_atm = 2, - wind_speed = 4, + flow = 150, + topwidth = 100, + slope = 0.0002, + shear_velocity = 0.05334, + pressure_mb = 1013.25, + wind_speed = 3, q_solar = 500, Solid = 1, lambda0 = .02, diff --git a/tests/test_8_nsm_balgae_calculations.py b/tests/test_8_nsm_balgae_calculations.py new file mode 100644 index 0000000..84f317d --- /dev/null +++ b/tests/test_8_nsm_balgae_calculations.py @@ -0,0 +1,2006 @@ +from numba import ( + types, + typed, +) +import pytest + +from clearwater_modules.nsm1 import NutrientBudget +from clearwater_modules.nsm1.constants import ( + AlgaeStaticVariables, + AlkalinityStaticVariables, + BalgaeStaticVariables, + NitrogenStaticVariables, + CarbonStaticVariables, + CBODStaticVariables, + DOXStaticVariables, + N2StaticVariables, + POMStaticVariables, + PathogenStaticVariables, + PhosphorusStaticVariables, + GlobalParameters, + GlobalVars +) + + +@pytest.fixture(scope='function') +def initial_nsm1_state() -> dict[str, float]: + """Return initial state values for the model.""" + return { + + 'Ap': 36.77, + 'Ab': 24, + 'NH4': 0.063, + 'NO3': 5.54, + 'OrgN': 1.7, + 'N2': 1, + 'TIP': 0.071, + 'OrgP': 0.25, + 'POC': 4.356, + 'DOC': 1, + 'DIC': 1, + 'POM': 10, + 'CBOD': 5, + 'DOX': 8, + 'PX': 1, + 'Alk': 1 + + } + +@pytest.fixture(scope='module') +def time_steps() -> int: + return 1 + +@pytest.fixture(scope='function') +def default_algae_params() -> AlgaeStaticVariables: + """Returns default algae static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return AlgaeStaticVariables( + AWd = 100, + AWc= 40, + AWn= 7.2, + AWp= 1, + AWa= 1000, + KL= 10, + KsN= 0.04, + KsP= 0.0012, + mu_max_20= 1, + kdp_20= 0.15, + krp_20= 0.2, + vsap= 0.15, + growth_rate_option = 1, + light_limitation_option = 1, + mu_max_theta= 1.047, + kdp_theta= 1.047, + krp_theta= 1.047, + ) + +@pytest.fixture(scope='function') +def default_alkalinity_params() -> AlkalinityStaticVariables: + """Returns default alkalinity static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return AlkalinityStaticVariables( + r_alkaa = 14.0 / 106.0 / 12.0 / 1000.0, + r_alkan= 18.0 / 106.0 / 12.0 / 1000.0, + r_alkn = 2.0 / 14.0 / 1000.0, + r_alkden = 4.0 / 14.0 / 1000.0, + r_alkba = 14.0 / 106.0 / 12.0 / 1000.0, + r_alkbn =18.0 / 106.0 / 12.0 / 1000.0 + ) + +@pytest.fixture(scope='function') +def default_balgae_params() -> BalgaeStaticVariables: + """Returns default Benthic Algae static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return BalgaeStaticVariables( + BWd = 100, + BWc= 40, + BWn=7.2, + BWp= 1, + BWa= 5000, + KLb= 10, + KsNb= 0.25, + KsPb=0.125, + Ksb=10, + mub_max_20=0.4, + krb_20=0.2, + kdb_20=0.3, + b_growth_rate_option=1, + b_light_limitation_option=1, + Fw=0.9, + Fb=0.9, + mub_max_theta = 1.047, + krb_theta = 1.06, + kdb_theta = 1.047, + ) + +@pytest.fixture(scope='function') +def default_nitrogen_params() -> NitrogenStaticVariables: + """Returns default nitrogen static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return NitrogenStaticVariables( + KNR= 0.6 , + knit_20= 0.1, + kon_20=0.1, + kdnit_20=0.002, + rnh4_20=0, + vno3_20=0, + KsOxdn=0.1, + PN=0.5, + PNb=0.5, + knit_theta= 1.083, + kon_theta= 1.074, + kdnit_theta= 1.08, + rnh4_theta= 1.047, + vno3_theta= 1.045, + ) + +@pytest.fixture(scope='function') +def default_carbon_params() -> CarbonStaticVariables: + """Returns default carbon static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return CarbonStaticVariables( + f_pocp = 0.9, + kdoc_20= 0.01, + f_pocb=0.9, + kpoc_20= 0.005, + KsOxmc=1.0, + pCO2 = 383.0, + FCO2 = 0.2, + roc = 32.0/12.0, + kpoc_theta = 1.047, + kdoc_theta = 1.047, + ) + +@pytest.fixture(scope='function') +def default_CBOD_params() -> CBODStaticVariables: + """Returns default CBOD static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return CBODStaticVariables( + KsOxbod = 0.5, + kbod_20 = 0.12, + ksbod_20 = 0.0, + kbod_theta = 1.047, + ksbod_theta = 1.047 + ) + +@pytest.fixture(scope='function') +def default_DOX_params() -> DOXStaticVariables: + """Returns default DOX static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return DOXStaticVariables( + ron = 2.0 * 32.0 / 14.0, + KsSOD =1, + ) + +@pytest.fixture(scope='function') +def default_N2_params() -> N2StaticVariables: + """Returns default N2 static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return N2StaticVariables( + + ) + +@pytest.fixture(scope='function') +def default_POM_params() -> POMStaticVariables: + """Returns default POM static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return POMStaticVariables( + kpom_20 = 0.1, + h2 = 0.1, + kpom_theta = 1.047 + ) + +@pytest.fixture(scope='function') +def default_pathogen_params() -> PathogenStaticVariables: + """Returns default Pathogens static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return PathogenStaticVariables( + kdx_20=0.8, + apx=1, + vx=1, + kdx_theta = 1.07, + ) + +@pytest.fixture(scope='function') +def default_phosphorus_params() -> PhosphorusStaticVariables: + """Returns default phosphorus static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return PhosphorusStaticVariables( + kop_20 = 0.1, + rpo4_20 =0, + kdpo4 = 0.0, + kop_theta = 1.047, + rpo4_theta = 1.047, + ) + +@pytest.fixture(scope='function') +def default_gp_params() -> GlobalParameters: + """Returns default global parameter static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return GlobalParameters( + use_NH4= True, + use_NO3= True, + use_OrgN= True, + use_OrgP = True, + use_TIP= True, + use_SedFlux= False, + use_POC = True, + use_DOC = True, + use_DOX= True, + use_DIC= True, + use_Algae= True, + use_Balgae= True, + use_N2 = True, + use_Pathogen = True, + use_Alk = True, + use_POM = True + ) + +@pytest.fixture(scope='function') +def default_gvars_params() -> GlobalVars: + """Returns default global variables static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return GlobalVars( + vson = 0.01, + vsoc = 0.01, + vsop = 0.01, + vs = 1, + SOD_20 = 999, + SOD_theta = 999, + vb = 0.01, + fcom = 0.4, + kaw_20_user = 0, + kah_20_user = 1, + hydraulic_reaeration_option = 1, + wind_reaeration_option = 1, + timestep = 1, #TODO Dynamic or static? + depth = 1.5, #TODO Dynamic or static? + TwaterC = 25, + kaw_theta = 1.024, + kah_theta = 1.024, + velocity = 1, + flow = 150, + topwidth = 100, + slope = 0.0002, + shear_velocity = 0.05334, + pressure_mb = 1013.25, + wind_speed = 3, + q_solar = 500, + Solid = 1, + lambda0 = .02, + lambda1 = .0088, + lambda2 = .054, + lambdas = .052, + lambdam = .174, + Fr_PAR = .47 + ) + +def get_nutrient_budget_instance( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + +) -> NutrientBudget: + """Return an instance of the NSM1 class.""" + return NutrientBudget( + time_steps=time_steps, + initial_state_values=initial_nsm1_state, + algae_parameters=default_algae_params, + alkalinity_parameters=default_alkalinity_params, + balgae_parameters=default_balgae_params, + nitrogen_parameters=default_nitrogen_params, + carbon_parameters=default_carbon_params, + CBOD_parameters=default_CBOD_params, + DOX_parameters=default_DOX_params, + N2_parameters=default_N2_params, + POM_parameters=default_POM_params, + pathogen_parameters=default_pathogen_params, + phosphorus_parameters=default_phosphorus_params, + global_parameters=default_gp_params, + global_vars=default_gvars_params, + time_dim='nsm1_time_step', + ) + +@pytest.fixture(scope='module') +def tolerance() -> float: + """Controls the precision of the pytest.approx() function.""" + return 0.000001 + +def test_defaults( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel(nsm1_time_step=-1).Ab.values.item() + + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 8.82632 + +def test_changed_KLb( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_balgae_params['KLb'] = 15 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 8.74222 + +def test_changed_KsNb( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_balgae_params['KsNb'] = 0.4 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 8.81861 + +def test_changed_KsPb( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_balgae_params['KsPb'] = 0.05 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 9.01754 + +def test_changed_Ksb( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_balgae_params['Ksb'] = 20 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 8.99459 + +def test_changed_mub_max( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_balgae_params['mub_max_20'] = 1.5 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 9.67469 + +def test_changed_krb( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_balgae_params['krb_20'] = 0.01 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 14.92863 + +def test_changed_kdb( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_balgae_params['kdb_20'] = 0.1 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 14.8654507973722 + +def test_changed_Ab( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + initial_nsm1_state['Ab'] = 40 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 14.54599 + +def test_changed_NH4( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + initial_nsm1_state['NH4'] = 5 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 8.83262 + +def test_changed_NO3( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + initial_nsm1_state['NO3'] = 2 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 8.80525 + +def test_changed_TIP( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + initial_nsm1_state['TIP'] = 3 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 9.33539 + +def test_changed_TwaterC( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['TwaterC'] = 30 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 4.39484 + +def test_changed_depth( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['depth'] = 0.5 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 9.56564 + +def test_changed_Ap( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + initial_nsm1_state['Ap'] = 20 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 8.96109 + +def test_changed_lambda0( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['lambda0'] = 5 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 8.51805 + +def test_changed_lambda1( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['lambda1'] = 0.03 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 8.63363 + +def test_changed_lambda2( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['lambda2'] = 1 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 8.51782 + +def test_changed_lambdam( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['lambdam'] = 0.008 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 9.54539 + +def test_changed_POC( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + initial_nsm1_state['POC'] = 10 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 8.52808 + +def test_changed_fcom( + + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['fcom'] = 0.25 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 8.58832 + +def test_changed_use_algae( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gp_params['use_Algae'] = False + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 9.22085 + +def test_changed_q_solar( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['q_solar'] = 100 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 8.59497 + +def test_changed_use_TIP( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gp_params['use_TIP'] = False + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 9.36945 + +def test_changed_use_POC( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gp_params['use_POC'] = False + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 9.56670 + +def test_changed_use_NH4( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gp_params['use_NH4'] = False + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 8.82617 + +def test_changed_use_NO3( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gp_params['use_NO3'] = False + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 8.58268 + +def test_changed_use_NO3_use_NH4( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gp_params['use_NO3'] = False + default_gp_params['use_NH4'] = False + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 8.84008 + +def test_changed_g2_l1( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_balgae_params['b_growth_rate_option'] = 2 + default_balgae_params['b_light_limitation_option'] = 1 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 8.84008 + +def test_changed_g1_l2( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_balgae_params['b_growth_rate_option'] = 1 + default_balgae_params['b_light_limitation_option'] = 2 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 8.90818 + +def test_changed_g2_l2( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_balgae_params['b_growth_rate_option'] = 2 + default_balgae_params['b_light_limitation_option'] = 2 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 8.92559 + +def test_changed_g1_l3( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_balgae_params['b_growth_rate_option'] = 1 + default_balgae_params['b_light_limitation_option'] = 3 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 9.31883 + +def test_changed_g2_l3( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_balgae_params['b_growth_rate_option'] = 2 + default_balgae_params['b_light_limitation_option'] = 3 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + Ab = nsm1.dataset.isel( + nsm1_time_step=-1).Ab.values.item() + assert isinstance(Ab, float) + assert pytest.approx(Ab, tolerance) == 9.35457 \ No newline at end of file diff --git a/tests/test_9_nsm_nitrogen_calculations.py b/tests/test_9_nsm_nitrogen_calculations.py new file mode 100644 index 0000000..b4ee9a0 --- /dev/null +++ b/tests/test_9_nsm_nitrogen_calculations.py @@ -0,0 +1,1997 @@ +from numba import ( + types, + typed, +) +import pytest + +from clearwater_modules.nsm1 import NutrientBudget +from clearwater_modules.nsm1.constants import ( + AlgaeStaticVariables, + AlkalinityStaticVariables, + BalgaeStaticVariables, + NitrogenStaticVariables, + CarbonStaticVariables, + CBODStaticVariables, + DOXStaticVariables, + N2StaticVariables, + POMStaticVariables, + PathogenStaticVariables, + PhosphorusStaticVariables, + GlobalParameters, + GlobalVars +) + + +@pytest.fixture(scope='function') +def initial_nsm1_state() -> dict[str, float]: + """Return initial state values for the model.""" + return { + + 'Ap': 36.77, + 'Ab': 24, + 'NH4': 0.063, + 'NO3': 5.54, + 'OrgN': 1.726, + 'N2': 1, + 'TIP': 0.071, + 'OrgP': 0.25, + 'POC': 4.356, + 'DOC': 1, + 'DIC': 1, + 'POM': 10, + 'CBOD': 5, + 'DOX': 8, + 'PX': 1, + 'Alk': 1 + + } + +@pytest.fixture(scope='module') +def time_steps() -> int: + return 1 + +@pytest.fixture(scope='function') +def default_algae_params() -> AlgaeStaticVariables: + """Returns default algae static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return AlgaeStaticVariables( + AWd = 100, + AWc= 40, + AWn= 7.2, + AWp= 1, + AWa= 1000, + KL= 10, + KsN= 0.04, + KsP= 0.0012, + mu_max_20= 1, + kdp_20= 0.15, + krp_20= 0.2, + vsap= 0.15, + growth_rate_option = 1, + light_limitation_option = 1, + mu_max_theta= 1.047, + kdp_theta= 1.047, + krp_theta= 1.047, + ) + +@pytest.fixture(scope='function') +def default_alkalinity_params() -> AlkalinityStaticVariables: + """Returns default alkalinity static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return AlkalinityStaticVariables( + r_alkaa = 14.0 / 106.0 / 12.0 / 1000.0, + r_alkan= 18.0 / 106.0 / 12.0 / 1000.0, + r_alkn = 2.0 / 14.0 / 1000.0, + r_alkden = 4.0 / 14.0 / 1000.0, + r_alkba = 14.0 / 106.0 / 12.0 / 1000.0, + r_alkbn =18.0 / 106.0 / 12.0 / 1000.0 + ) + +@pytest.fixture(scope='function') +def default_balgae_params() -> BalgaeStaticVariables: + """Returns default Benthic Algae static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return BalgaeStaticVariables( + BWd = 100, + BWc= 40, + BWn=7.2, + BWp= 1, + BWa= 5000, + KLb= 10, + KsNb= 0.25, + KsPb=0.125, + Ksb=10, + mub_max_20=0.4, + krb_20=0.2, + kdb_20=0.3, + b_growth_rate_option=1, + b_light_limitation_option=1, + Fw=0.9, + Fb=0.9, + mub_max_theta = 1.047, + krb_theta = 1.06, + kdb_theta = 1.047, + ) + +@pytest.fixture(scope='function') +def default_nitrogen_params() -> NitrogenStaticVariables: + """Returns default nitrogen static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return NitrogenStaticVariables( + KNR= 0.6 , + knit_20= 0.1, + kon_20=0.1, + kdnit_20=0.002, + rnh4_20=0, + vno3_20=0, + KsOxdn=0.1, + PN=0.5, + PNb=0.5, + knit_theta= 1.083, + kon_theta= 1.047, + kdnit_theta= 1.045, + rnh4_theta= 1.074, + vno3_theta= 1.08, + ) + +@pytest.fixture(scope='function') +def default_carbon_params() -> CarbonStaticVariables: + """Returns default carbon static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return CarbonStaticVariables( + f_pocp = 0.9, + kdoc_20= 0.01, + f_pocb=0.9, + kpoc_20= 0.005, + KsOxmc=1.0, + pCO2 = 383.0, + FCO2 = 0.2, + roc = 32.0/12.0, + kpoc_theta = 1.047, + kdoc_theta = 1.047, + ) + +@pytest.fixture(scope='function') +def default_CBOD_params() -> CBODStaticVariables: + """Returns default CBOD static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return CBODStaticVariables( + KsOxbod = 0.5, + kbod_20 = 0.12, + ksbod_20 = 0.0, + kbod_theta = 1.047, + ksbod_theta = 1.047 + ) + +@pytest.fixture(scope='function') +def default_DOX_params() -> DOXStaticVariables: + """Returns default DOX static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return DOXStaticVariables( + ron = 2.0 * 32.0 / 14.0, + KsSOD =1, + ) + +@pytest.fixture(scope='function') +def default_N2_params() -> N2StaticVariables: + """Returns default N2 static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return N2StaticVariables( + + ) + +@pytest.fixture(scope='function') +def default_POM_params() -> POMStaticVariables: + """Returns default POM static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return POMStaticVariables( + kpom_20 = 0.1, + h2 = 0.1, + kpom_theta = 1.047 + ) + +@pytest.fixture(scope='function') +def default_pathogen_params() -> PathogenStaticVariables: + """Returns default Pathogens static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return PathogenStaticVariables( + kdx_20=0.8, + apx=1, + vx=1, + kdx_theta = 1.07, + ) + +@pytest.fixture(scope='function') +def default_phosphorus_params() -> PhosphorusStaticVariables: + """Returns default phosphorus static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return PhosphorusStaticVariables( + kop_20 = 0.1, + rpo4_20 =0, + kdpo4 = 0.0, + kop_theta = 1.047, + rpo4_theta = 1.047, + ) + +@pytest.fixture(scope='function') +def default_gp_params() -> GlobalParameters: + """Returns default global parameter static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return GlobalParameters( + use_NH4= True, + use_NO3= True, + use_OrgN= True, + use_OrgP = True, + use_TIP= False, + use_SedFlux= False, + use_POC = False, + use_DOC = True, + use_DOX= True, + use_DIC= True, + use_Algae= True, + use_Balgae= True, + use_N2 = True, + use_Pathogen = True, + use_Alk = True, + use_POM = True + ) + +@pytest.fixture(scope='function') +def default_gvars_params() -> GlobalVars: + """Returns default global variables static variable values for the model. + + NOTE: As of now (3/18/2022) these match the built in defaults, but are + copied here to allow for easy modification of the defaults in the future. + + Returns a typed dictionary, with string keys and float values. + """ + return GlobalVars( + vson = 0.01, + vsoc = 0.01, + vsop = 0.01, + vs = 1, + SOD_20 = 999, + SOD_theta = 999, + vb = 0.01, + fcom = 0.4, + kaw_20_user = 0, + kah_20_user = 1, + hydraulic_reaeration_option = 1, + wind_reaeration_option = 1, + timestep = 1, #TODO Dynamic or static? + depth = 1.5, #TODO Dynamic or static? + TwaterC = 25, + kaw_theta = 1.024, + kah_theta = 1.024, + velocity = 1, + flow = 150, + topwidth = 100, + slope = 0.0002, + shear_velocity = 0.05334, + pressure_mb = 1013.25, + wind_speed = 3, + q_solar = 500, + Solid = 1, + lambda0 = .02, + lambda1 = .0088, + lambda2 = .054, + lambdas = .052, + lambdam = .174, + Fr_PAR = .47 + ) + +def get_nutrient_budget_instance( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + +) -> NutrientBudget: + """Return an instance of the NSM1 class.""" + return NutrientBudget( + time_steps=time_steps, + initial_state_values=initial_nsm1_state, + algae_parameters=default_algae_params, + alkalinity_parameters=default_alkalinity_params, + balgae_parameters=default_balgae_params, + nitrogen_parameters=default_nitrogen_params, + carbon_parameters=default_carbon_params, + CBOD_parameters=default_CBOD_params, + DOX_parameters=default_DOX_params, + N2_parameters=default_N2_params, + POM_parameters=default_POM_params, + pathogen_parameters=default_pathogen_params, + phosphorus_parameters=default_phosphorus_params, + global_parameters=default_gp_params, + global_vars=default_gvars_params, + time_dim='nsm1_time_step', + ) + +@pytest.fixture(scope='module') +def tolerance() -> float: + """Controls the precision of the pytest.approx() function.""" + return 0.000001 + +def test_defaults( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + nsm1.increment_timestep() + + + + krb_tc = nsm1.dataset.isel(nsm1_time_step=-1).krb_tc.item() + assert isinstance(krb_tc, float) + print("krb_tc",krb_tc) + + AbRespiration = nsm1.dataset.isel(nsm1_time_step=-1).AbRespiration.item() + assert isinstance(AbRespiration, float) + print("AbRespiration",AbRespiration) + + + NH4_AbRespiration = nsm1.dataset.isel(nsm1_time_step=-1).NH4_AbRespiration.item() + assert isinstance(NH4_AbRespiration, float) + print("NH4_AbRespiration",NH4_AbRespiration) + + + # Run the model + NH4 = nsm1.dataset.isel(nsm1_time_step=-1).NH4.values.item() + + assert isinstance(NH4, float) + assert pytest.approx(NH4, tolerance) == 0.6101494 + + NO3 = nsm1.dataset.isel(nsm1_time_step=-1).NO3.values.item() + + assert isinstance(NO3, float) + assert pytest.approx(NO3, tolerance) == 5.1260636 + + OrgN = nsm1.dataset.isel(nsm1_time_step=-1).OrgN.values.item() + + assert isinstance(OrgN, float) + assert pytest.approx(OrgN, tolerance) == 1.899502 + +def test_changed_knit( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_nitrogen_params['knit_20'] = 5 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + NH4 = nsm1.dataset.isel( + nsm1_time_step=-1).NH4.values.item() + assert isinstance(NH4, float) + assert pytest.approx(NH4, tolerance) == 0.154017957758354 + + NO3 = nsm1.dataset.isel( + nsm1_time_step=-1).NO3.values.item() + assert isinstance(NO3, float) + assert pytest.approx(NO3, tolerance) == 5.58219498187554 + + OrgN = nsm1.dataset.isel( + nsm1_time_step=-1).OrgN.values.item() + assert isinstance(OrgN, float) + assert pytest.approx(OrgN, tolerance) == 1.89950169149861 + +def test_changed_kon( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_nitrogen_params['kon_20'] = 0.5 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + NH4 = nsm1.dataset.isel( + nsm1_time_step=-1).NH4.values.item() + assert isinstance(NH4, float) + assert pytest.approx(NH4, tolerance) == 1.47877811233963 + + NO3 = nsm1.dataset.isel( + nsm1_time_step=-1).NO3.values.item() + assert isinstance(NO3, float) + assert pytest.approx(NO3, tolerance) == 5.12606356028487 + + OrgN = nsm1.dataset.isel( + nsm1_time_step=-1).OrgN.values.item() + assert isinstance(OrgN, float) + assert pytest.approx(OrgN, tolerance) == 1.03087295850801 + +def test_changed_kdnit( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_nitrogen_params['kdnit_20'] = 2 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + NH4 = nsm1.dataset.isel( + nsm1_time_step=-1).NH4.values.item() + assert isinstance(NH4, float) + assert pytest.approx(NH4, tolerance) == 0.610149 + + NO3 = nsm1.dataset.isel( + nsm1_time_step=-1).NO3.values.item() + assert isinstance(NO3, float) + assert pytest.approx(NO3, tolerance) == 4.955769 + + OrgN = nsm1.dataset.isel( + nsm1_time_step=-1).OrgN.values.item() + assert isinstance(OrgN, float) + assert pytest.approx(OrgN, tolerance) == 1.8995017 + +def test_changed_rnh4( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_nitrogen_params['rnh4_20'] = -0.5 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + NH4 = nsm1.dataset.isel( + nsm1_time_step=-1).NH4.values.item() + assert isinstance(NH4, float) + assert pytest.approx(NH4, tolerance) == 0.133827915386814 + + NO3 = nsm1.dataset.isel( + nsm1_time_step=-1).NO3.values.item() + assert isinstance(NO3, float) + assert pytest.approx(NO3, tolerance) == 5.12606356028487 + + OrgN = nsm1.dataset.isel( + nsm1_time_step=-1).OrgN.values.item() + assert isinstance(OrgN, float) + assert pytest.approx(OrgN, tolerance) == 1.89950169 + +def test_changed_rnh4_KsOxdn( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_nitrogen_params['rnh4_20'] = 1 + default_nitrogen_params['KsOxdn'] = 10 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + NH4 = nsm1.dataset.isel( + nsm1_time_step=-1).NH4.values.item() + assert isinstance(NH4, float) + assert pytest.approx(NH4, tolerance) == 1.5627923 + + NO3 = nsm1.dataset.isel( + nsm1_time_step=-1).NO3.values.item() + assert isinstance(NO3, float) + assert pytest.approx(NO3, tolerance) == 5.11856308 + + OrgN = nsm1.dataset.isel( + nsm1_time_step=-1).OrgN.values.item() + assert isinstance(OrgN, float) + assert pytest.approx(OrgN, tolerance) == 1.89950169 + +def test_changed_vno3( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_nitrogen_params['vno3_20'] = 0.9 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + NH4 = nsm1.dataset.isel( + nsm1_time_step=-1).NH4.values.item() + assert isinstance(NH4, float) + assert pytest.approx(NH4, tolerance) == 0.610149379 + + NO3 = nsm1.dataset.isel( + nsm1_time_step=-1).NO3.values.item() + assert isinstance(NO3, float) + assert pytest.approx(NO3, tolerance) == 0.242017033 + + OrgN = nsm1.dataset.isel( + nsm1_time_step=-1).OrgN.values.item() + assert isinstance(OrgN, float) + assert pytest.approx(OrgN, tolerance) == 1.89950169 + +def test_changed_depth( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['depth'] = 3 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + NH4 = nsm1.dataset.isel( + nsm1_time_step=-1).NH4.values.item() + assert isinstance(NH4, float) + assert pytest.approx(NH4, tolerance) == 0.472669296 + + NO3 = nsm1.dataset.isel( + nsm1_time_step=-1).NO3.values.item() + assert isinstance(NO3, float) + assert pytest.approx(NO3, tolerance) == 5.23749182 + + OrgN = nsm1.dataset.isel( + nsm1_time_step=-1).OrgN.values.item() + assert isinstance(OrgN, float) + assert pytest.approx(OrgN, tolerance) == 1.729153886 + +def test_changed_TwaterC( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gvars_params['TwaterC'] = 10 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + NH4 = nsm1.dataset.isel( + nsm1_time_step=-1).NH4.values.item() + assert isinstance(NH4, float) + assert pytest.approx(NH4, tolerance) == 0.31604458 + + NO3 = nsm1.dataset.isel( + nsm1_time_step=-1).NO3.values.item() + assert isinstance(NO3, float) + assert pytest.approx(NO3, tolerance) == 5.330296324 + + OrgN = nsm1.dataset.isel( + nsm1_time_step=-1).OrgN.values.item() + assert isinstance(OrgN, float) + assert pytest.approx(OrgN, tolerance) == 1.8073881 + +def test_changed_NH4( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + initial_nsm1_state['NH4'] = 0.01 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + NH4 = nsm1.dataset.isel( + nsm1_time_step=-1).NH4.values.item() + assert isinstance(NH4, float) + assert pytest.approx(NH4, tolerance) == 0.569020898 + + NO3 = nsm1.dataset.isel( + nsm1_time_step=-1).NO3.values.item() + assert isinstance(NO3, float) + assert pytest.approx(NO3, tolerance) == 5.114263537 + + OrgN = nsm1.dataset.isel( + nsm1_time_step=-1).OrgN.values.item() + assert isinstance(OrgN, float) + assert pytest.approx(OrgN, tolerance) == 1.89950169 + +def test_changed_NO3( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + initial_nsm1_state['NO3'] = 20 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + NH4 = nsm1.dataset.isel( + nsm1_time_step=-1).NH4.values.item() + assert isinstance(NH4, float) + assert pytest.approx(NH4, tolerance) == 0.61359955 + + NO3 = nsm1.dataset.isel( + nsm1_time_step=-1).NO3.values.item() + assert isinstance(NO3, float) + assert pytest.approx(NO3, tolerance) == 19.57664053 + + OrgN = nsm1.dataset.isel( + nsm1_time_step=-1).OrgN.values.item() + assert isinstance(OrgN, float) + assert pytest.approx(OrgN, tolerance) == 1.89950169 + +def test_changed_Ap( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + initial_nsm1_state['Ap'] = 5 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + NH4 = nsm1.dataset.isel( + nsm1_time_step=-1).NH4.values.item() + assert isinstance(NH4, float) + assert pytest.approx(NH4, tolerance) == 0.5553608647 + + NO3 = nsm1.dataset.isel( + nsm1_time_step=-1).NO3.values.item() + assert isinstance(NO3, float) + assert pytest.approx(NO3, tolerance) == 5.3696889 + + OrgN = nsm1.dataset.isel( + nsm1_time_step=-1).OrgN.values.item() + assert isinstance(OrgN, float) + assert pytest.approx(OrgN, tolerance) == 1.85633245 + +def test_changed_DOX( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + initial_nsm1_state['DOX'] = 1 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + NH4 = nsm1.dataset.isel( + nsm1_time_step=-1).NH4.values.item() + assert isinstance(NH4, float) + assert pytest.approx(NH4, tolerance) == 0.6152233076 + + NO3 = nsm1.dataset.isel( + nsm1_time_step=-1).NO3.values.item() + assert isinstance(NO3, float) + assert pytest.approx(NO3, tolerance) == 5.1199048523 + + OrgN = nsm1.dataset.isel( + nsm1_time_step=-1).OrgN.values.item() + assert isinstance(OrgN, float) + assert pytest.approx(OrgN, tolerance) == 1.899501691 + +def test_changed_OrgN( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + initial_nsm1_state['OrgN'] = 7 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + NH4 = nsm1.dataset.isel( + nsm1_time_step=-1).NH4.values.item() + assert isinstance(NH4, float) + assert pytest.approx(NH4, tolerance) == 1.2736991965 + + NO3 = nsm1.dataset.isel( + nsm1_time_step=-1).NO3.values.item() + assert isinstance(NO3, float) + assert pytest.approx(NO3, tolerance) == 5.12606356 + + OrgN = nsm1.dataset.isel( + nsm1_time_step=-1).OrgN.values.item() + assert isinstance(OrgN, float) + assert pytest.approx(OrgN, tolerance) == 6.47479187 + +def test_changed_use_NH4( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gp_params['use_NH4'] = False + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + NH4 = nsm1.dataset.isel( + nsm1_time_step=-1).NH4.values.item() + assert isinstance(NH4, float) + assert pytest.approx(NH4, tolerance) == 0.063 + + NO3 = nsm1.dataset.isel( + nsm1_time_step=-1).NO3.values.item() + assert isinstance(NO3, float) + assert pytest.approx(NO3, tolerance) == 5.1120288 + + OrgN = nsm1.dataset.isel( + nsm1_time_step=-1).OrgN.values.item() + assert isinstance(OrgN, float) + assert pytest.approx(OrgN, tolerance) == 1.89950169 + +def test_changed_use_NO3( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gp_params['use_NO3'] = False + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + NH4 = nsm1.dataset.isel( + nsm1_time_step=-1).NH4.values.item() + assert isinstance(NH4, float) + assert pytest.approx(NH4, tolerance) == 0.40213002 + + NO3 = nsm1.dataset.isel( + nsm1_time_step=-1).NO3.values.item() + assert isinstance(NO3, float) + assert pytest.approx(NO3, tolerance) == 5.54 + + OrgN = nsm1.dataset.isel( + nsm1_time_step=-1).OrgN.values.item() + assert isinstance(OrgN, float) + assert pytest.approx(OrgN, tolerance) == 1.89950169 + +def test_changed_use_OrgN( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gp_params['use_OrgN'] = False + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + NH4 = nsm1.dataset.isel( + nsm1_time_step=-1).NH4.values.item() + assert isinstance(NH4, float) + assert pytest.approx(NH4, tolerance) == 0.392992196 + + NO3 = nsm1.dataset.isel( + nsm1_time_step=-1).NO3.values.item() + assert isinstance(NO3, float) + assert pytest.approx(NO3, tolerance) == 5.126063560 + + OrgN = nsm1.dataset.isel( + nsm1_time_step=-1).OrgN.values.item() + assert isinstance(OrgN, float) + assert pytest.approx(OrgN, tolerance) == 1.726 + +def test_changed_use_DOX( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gp_params['use_DOX'] = False + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + NH4 = nsm1.dataset.isel( + nsm1_time_step=-1).NH4.values.item() + assert isinstance(NH4, float) + assert pytest.approx(NH4, tolerance) == 0.61007213 + + NO3 = nsm1.dataset.isel( + nsm1_time_step=-1).NO3.values.item() + assert isinstance(NO3, float) + assert pytest.approx(NO3, tolerance) == 5.12631127 + + OrgN = nsm1.dataset.isel( + nsm1_time_step=-1).OrgN.values.item() + assert isinstance(OrgN, float) + assert pytest.approx(OrgN, tolerance) == 1.89950169 + +def test_changed_use_Algae( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gp_params['use_Algae'] = False + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + NH4 = nsm1.dataset.isel( + nsm1_time_step=-1).NH4.values.item() + assert isinstance(NH4, float) + assert pytest.approx(NH4, tolerance) == 0.54676037 + + NO3 = nsm1.dataset.isel( + nsm1_time_step=-1).NO3.values.item() + assert isinstance(NO3, float) + assert pytest.approx(NO3, tolerance) == 5.409982005 + + OrgN = nsm1.dataset.isel( + nsm1_time_step=-1).OrgN.values.item() + assert isinstance(OrgN, float) + assert pytest.approx(OrgN, tolerance) == 1.849538428 + +def test_changed_use_Balgae( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gp_params['use_Balgae'] = False + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + NH4 = nsm1.dataset.isel( + nsm1_time_step=-1).NH4.values.item() + assert isinstance(NH4, float) + assert pytest.approx(NH4, tolerance) == 0.33406138337 + + NO3 = nsm1.dataset.isel( + nsm1_time_step=-1).NO3.values.item() + assert isinstance(NO3, float) + assert pytest.approx(NO3, tolerance) == 5.24974272 + + OrgN = nsm1.dataset.isel( + nsm1_time_step=-1).OrgN.values.item() + assert isinstance(OrgN, float) + assert pytest.approx(OrgN, tolerance) == 1.547299413 + +def test_changed_PN( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_nitrogen_params['PN'] = 0.3 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + NH4 = nsm1.dataset.isel( + nsm1_time_step=-1).NH4.values.item() + assert isinstance(NH4, float) + assert pytest.approx(NH4, tolerance) == 0.6120854746 + + NO3 = nsm1.dataset.isel( + nsm1_time_step=-1).NO3.values.item() + assert isinstance(NO3, float) + assert pytest.approx(NO3, tolerance) == 5.124127465 + + OrgN = nsm1.dataset.isel( + nsm1_time_step=-1).OrgN.values.item() + assert isinstance(OrgN, float) + assert pytest.approx(OrgN, tolerance) == 1.899501691 + +def test_changed_PNb( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_nitrogen_params['PNb'] = 0.7 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + NH4 = nsm1.dataset.isel( + nsm1_time_step=-1).NH4.values.item() + assert isinstance(NH4, float) + assert pytest.approx(NH4, tolerance) == 0.60832257266 + + NO3 = nsm1.dataset.isel( + nsm1_time_step=-1).NO3.values.item() + assert isinstance(NO3, float) + assert pytest.approx(NO3, tolerance) == 5.127890367 + + OrgN = nsm1.dataset.isel( + nsm1_time_step=-1).OrgN.values.item() + assert isinstance(OrgN, float) + assert pytest.approx(OrgN, tolerance) == 1.89950169 + +def test_changed_Fw( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_balgae_params['Fw'] = 0.5 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + NH4 = nsm1.dataset.isel( + nsm1_time_step=-1).NH4.values.item() + assert isinstance(NH4, float) + assert pytest.approx(NH4, tolerance) == 0.610149379 + + NO3 = nsm1.dataset.isel( + nsm1_time_step=-1).NO3.values.item() + assert isinstance(NO3, float) + assert pytest.approx(NO3, tolerance) == 5.12606356028 + + OrgN = nsm1.dataset.isel( + nsm1_time_step=-1).OrgN.values.item() + assert isinstance(OrgN, float) + assert pytest.approx(OrgN, tolerance) == 1.7429673455 + +def test_changed_Fb( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_balgae_params['Fb'] = 0.4 + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + NH4 = nsm1.dataset.isel( + nsm1_time_step=-1).NH4.values.item() + assert isinstance(NH4, float) + assert pytest.approx(NH4, tolerance) == 0.456767159 + + NO3 = nsm1.dataset.isel( + nsm1_time_step=-1).NO3.values.item() + assert isinstance(NO3, float) + assert pytest.approx(NO3, tolerance) == 5.194774206 + + OrgN = nsm1.dataset.isel( + nsm1_time_step=-1).OrgN.values.item() + assert isinstance(OrgN, float) + assert pytest.approx(OrgN, tolerance) == 1.703833759 + +def test_changed_use_Algae_use_Balgae( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gp_params['use_Algae'] = False + default_gp_params['use_Balgae'] = False + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + NH4 = nsm1.dataset.isel( + nsm1_time_step=-1).NH4.values.item() + assert isinstance(NH4, float) + assert pytest.approx(NH4, tolerance) == 0.2708483787 + + NO3 = nsm1.dataset.isel( + nsm1_time_step=-1).NO3.values.item() + assert isinstance(NO3, float) + assert pytest.approx(NO3, tolerance) == 5.549138339 + + OrgN = nsm1.dataset.isel( + nsm1_time_step=-1).OrgN.values.item() + assert isinstance(OrgN, float) + assert pytest.approx(OrgN, tolerance) == 1.49733615 + +def test_changed_use_Algae_use_NH4( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gp_params['use_Algae'] = False + default_gp_params['use_NH4'] = False + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + NH4 = nsm1.dataset.isel( + nsm1_time_step=-1).NH4.values.item() + assert isinstance(NH4, float) + assert pytest.approx(NH4, tolerance) == 0.063 + + NO3 = nsm1.dataset.isel( + nsm1_time_step=-1).NO3.values.item() + assert isinstance(NO3, float) + assert pytest.approx(NO3, tolerance) == 5.39915906 + + OrgN = nsm1.dataset.isel( + nsm1_time_step=-1).OrgN.values.item() + assert isinstance(OrgN, float) + assert pytest.approx(OrgN, tolerance) == 1.849538428 + +def test_changed_use_Algae_use_NH4_use_NO3( + time_steps, + initial_nsm1_state, + default_algae_params, + default_alkalinity_params, + default_balgae_params, + default_nitrogen_params, + default_carbon_params, + default_CBOD_params, + default_DOX_params, + default_N2_params, + default_POM_params, + default_pathogen_params, + default_phosphorus_params, + default_gp_params, + default_gvars_params, + tolerance, +) -> None: + """Test the model with default parameters.""" + # alter parameters as necessary + initial_state_dict = initial_nsm1_state + default_gp_params['use_Algae'] = False + default_gp_params['use_NH4'] = False + default_gp_params['use_NO3'] = False + + # instantiate the model + nsm1: NutrientBudget = get_nutrient_budget_instance( + time_steps=time_steps, + initial_nsm1_state=initial_nsm1_state, + default_algae_params=default_algae_params, + default_alkalinity_params=default_alkalinity_params, + default_balgae_params=default_balgae_params, + default_nitrogen_params=default_nitrogen_params, + default_carbon_params=default_carbon_params, + default_CBOD_params=default_CBOD_params, + default_DOX_params=default_DOX_params, + default_N2_params=default_N2_params, + default_POM_params=default_POM_params, + default_pathogen_params=default_pathogen_params, + default_phosphorus_params=default_phosphorus_params, + default_gp_params=default_gp_params, + default_gvars_params=default_gvars_params + ) + + # Run the model + nsm1.increment_timestep() + NH4 = nsm1.dataset.isel( + nsm1_time_step=-1).NH4.values.item() + assert isinstance(NH4, float) + assert pytest.approx(NH4, tolerance) == 0.063 + + NO3 = nsm1.dataset.isel( + nsm1_time_step=-1).NO3.values.item() + assert isinstance(NO3, float) + assert pytest.approx(NO3, tolerance) == 5.54 + + OrgN = nsm1.dataset.isel( + nsm1_time_step=-1).OrgN.values.item() + assert isinstance(OrgN, float) + assert pytest.approx(OrgN, tolerance) == 1.849538428 \ No newline at end of file