diff --git a/examples/dev_sandbox/prof_nsm.py b/examples/dev_sandbox/prof_nsm.py
new file mode 100644
index 0000000..68a85db
--- /dev/null
+++ b/examples/dev_sandbox/prof_nsm.py
@@ -0,0 +1,217 @@
+"""A script to allow for debugging of the NSM module."""
+import time
+import sys
+import clearwater_modules as cwm
+from clearwater_modules.nsm1.model import NutrientBudget
+
+
+
+
+initial_state_values = {
+ 'Ap': 1,
+ 'Ab': 1,
+ 'NH4': 1,
+ 'NO3': 1,
+ 'OrgN': 1,
+ 'N2': 1,
+ 'TIP': 1,
+ 'OrgP': 1,
+ 'POC': 1,
+ 'DOC': 1,
+ 'DIC': 1,
+ 'POM': 1,
+ 'CBOD': 1,
+ 'DOX': 1,
+ 'PX': 1,
+ 'Alk': 1
+}
+
+algae_parameters = {
+ '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,
+ 'lambda0': .5,
+ 'lambda1': .5,
+ 'lambda2': .5,
+ 'lambdas': .5,
+ 'lambdam': .5,
+ 'Fr_PAR': .5
+}
+
+balgae_parameters = {
+ 'BWd': 100,
+ 'BWc': 40,
+ 'BWn': 7.2,
+ 'BWp': 1,
+ 'BWa': 3500,
+
+ '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
+}
+
+nitrogen_parameters = {
+ '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
+}
+
+phosphorus_parameters = {
+ 'kop_20': 0.1,
+ 'rpo4_20': 0
+}
+
+POM_parameters = {
+ 'kpom_20': 0.1
+}
+
+CBOD_parameters = {
+ 'KsOxbod': 0.5,
+ 'kbod_20': 0.12,
+ 'ksbod_20': 0
+}
+
+carbon_parameters = {
+ 'f_pocp': 0.9,
+ 'kdoc_20': 0.01,
+ 'f_pocb': 0.9,
+ 'kpoc_20': 0.005,
+ 'K_sOxmc': 1,
+ 'pCO2': 383,
+ 'FCO2': 0.2
+}
+
+pathogen_parameters = {
+ 'kdx': 0.8,
+ 'apx': 1,
+ 'vx': 1
+}
+
+alkalinity_parameters = {
+ 'r_alkaa': 1,
+ 'r_alkan': 1,
+ 'r_alkn': 1,
+ 'r_alkden': 1,
+ 'r_alkba': 1,
+ 'r_alkbn': 1
+}
+
+global_parameters = {
+ 'use_NH4': True,
+ 'use_NO3': True,
+ 'use_OrgN': True,
+ 'use_TIP': True,
+ 'use_SedFlux': False,
+ 'use_DOX': True,
+ 'use_Algae': True,
+ 'use_Balgae': True,
+ 'use_OrgP': True,
+ 'use_POC': True,
+ 'use_DOC': True,
+ 'use_DIC': True,
+ 'use_N2': True,
+ 'use_Pathogen': True,
+ 'use_Alk': True,
+ 'use_POM': True
+}
+
+
+global_vars = {
+ 'vson': 0.01,
+ 'vsoc': 0.01,
+ 'vsop': 999,
+ 'vs': 999,
+ 'SOD_20': 999,
+ 'SOD_theta': 999,
+ 'vb': 0.01,
+ 'fcom': 0.4,
+ 'kaw_20_user': 999,
+ 'kah_20_user': 999,
+ 'hydraulic_reaeration_option': 2,
+ 'wind_reaeration_option': 2,
+ 'timestep': 86400,
+ 'depth': 1,
+ 'TwaterC': 20,
+ 'theta': 1.047,
+ 'velocity': 1,
+ 'flow': 2,
+ 'topwidth': 1,
+ 'slope': 2,
+ 'shear_velocity': 4,
+ 'pressure_atm': 2,
+ 'wind_speed': 4,
+ 'q_solar': 4,
+ 'Solid': 1,
+}
+
+DOX_parameters = {
+ 'DOX': 6.5,
+}
+N2_parameters = {}
+
+def main(iters: int):
+ ti = time.time()
+ # define starting state values
+ nsm_model = NutrientBudget(
+ initial_state_values=initial_state_values, # mandatory
+ algae_parameters=algae_parameters,
+ alkalinity_parameters=alkalinity_parameters,
+ balgae_parameters=balgae_parameters,
+ carbon_parameters=carbon_parameters,
+ CBOD_parameters=CBOD_parameters,
+ DOX_parameters=DOX_parameters,
+ nitrogen_parameters=nitrogen_parameters,
+ POM_parameters=POM_parameters,
+ N2_parameters=N2_parameters,
+ phosphorus_parameters=phosphorus_parameters,
+ pathogen_parameters=pathogen_parameters,
+ global_parameters=global_parameters,
+ global_vars=global_vars,
+ track_dynamic_variables=True, # default is true
+ hotstart_dataset=None, # default is None
+ time_dim='year', # default is "timestep"
+ )
+ # print(nsm_model.get_variable_names())
+ print(nsm_model.dynamic_variables_names)
+
+ for _ in range(iters):
+ nsm_model.increment_timestep()
+
+
+if __name__ == '__main__':
+ if len(sys.argv) > 1:
+ try:
+ iters = int(sys.argv[1])
+ print(f'Running {iters} iterations.')
+ except ValueError:
+ raise ValueError('Argument must be an integer # of iterations.')
+ else:
+ print('No argument given, defaulting to 100 iteration.')
+ iters = 100
+
+ main(iters=iters)
diff --git a/examples/model_architecture.ipynb b/examples/model_architecture.ipynb
index 98e4002..4a9f8bd 100644
--- a/examples/model_architecture.ipynb
+++ b/examples/model_architecture.ipynb
@@ -170,52 +170,12 @@
},
{
"cell_type": "code",
- "execution_count": 3,
+ "execution_count": 2,
"id": "a5d34d2d-03a6-41e1-92fc-9e6fba72d6f5",
"metadata": {
"tags": []
},
"outputs": [
- {
- "data": {
- "application/javascript": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n var py_version = '3.2.2'.replace('rc', '-rc.').replace('.dev', '-dev.');\n var is_dev = py_version.indexOf(\"+\") !== -1 || py_version.indexOf(\"-\") !== -1;\n var reloading = false;\n var Bokeh = root.Bokeh;\n var bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks;\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n if (js_exports == null) js_exports = {};\n\n root._bokeh_onload_callbacks.push(callback);\n\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n run_callbacks();\n return null;\n }\n if (!reloading) {\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n }\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n window._bokeh_on_load = on_load\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'jspanel': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/jspanel', 'jspanel-modal': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal', 'jspanel-tooltip': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip', 'jspanel-hint': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint', 'jspanel-layout': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout', 'jspanel-contextmenu': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu', 'jspanel-dock': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@7.2.3/dist/gridstack-all', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'jspanel': {'exports': 'jsPanel'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"jspanel\"], function(jsPanel) {\n\twindow.jsPanel = jsPanel\n\ton_load()\n })\n require([\"jspanel-modal\"], function() {\n\ton_load()\n })\n require([\"jspanel-tooltip\"], function() {\n\ton_load()\n })\n require([\"jspanel-hint\"], function() {\n\ton_load()\n })\n require([\"jspanel-layout\"], function() {\n\ton_load()\n })\n require([\"jspanel-contextmenu\"], function() {\n\ton_load()\n })\n require([\"jspanel-dock\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 9;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n }\n\n var existing_stylesheets = []\n var links = document.getElementsByTagName('link')\n for (var i = 0; i < links.length; i++) {\n var link = links[i]\n if (link.href != null) {\n\texisting_stylesheets.push(link.href)\n }\n }\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n if (existing_stylesheets.indexOf(url) !== -1) {\n\ton_load()\n\tcontinue;\n }\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n } if (((window['jsPanel'] !== undefined) && (!(window['jsPanel'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.2.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/jspanel.js', 'https://cdn.holoviz.org/panel/1.2.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal.js', 'https://cdn.holoviz.org/panel/1.2.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip.js', 'https://cdn.holoviz.org/panel/1.2.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint.js', 'https://cdn.holoviz.org/panel/1.2.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout.js', 'https://cdn.holoviz.org/panel/1.2.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu.js', 'https://cdn.holoviz.org/panel/1.2.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.2.3/dist/bundled/gridstack/gridstack@7.2.3/dist/gridstack-all.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.2.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } var existing_scripts = []\n var scripts = document.getElementsByTagName('script')\n for (var i = 0; i < scripts.length; i++) {\n var script = scripts[i]\n if (script.src != null) {\n\texisting_scripts.push(script.src)\n }\n }\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (const name in js_exports) {\n var url = js_exports[name];\n if (skip.indexOf(url) >= 0 || root[name] != null) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onerror = on_error;\n element.async = false;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n element.textContent = `\n import ${name} from \"${url}\"\n window.${name} = ${name}\n window._bokeh_on_load()\n `\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.2.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.2.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.2.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.2.2.min.js\", \"https://cdn.holoviz.org/panel/1.2.3/dist/panel.min.js\"];\n var js_modules = [];\n var js_exports = {};\n var css_urls = [];\n var inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n // Cache old bokeh versions\n if (Bokeh != undefined && !reloading) {\n\tvar NewBokeh = root.Bokeh;\n\tif (Bokeh.versions === undefined) {\n\t Bokeh.versions = new Map();\n\t}\n\tif (NewBokeh.version !== Bokeh.version) {\n\t Bokeh.versions.set(NewBokeh.version, NewBokeh)\n\t}\n\troot.Bokeh = Bokeh;\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n root._bokeh_is_initializing = false\n }\n\n function load_or_wait() {\n // Implement a backoff loop that tries to ensure we do not load multiple\n // versions of Bokeh and its dependencies at the same time.\n // In recent versions we use the root._bokeh_is_initializing flag\n // to determine whether there is an ongoing attempt to initialize\n // bokeh, however for backward compatibility we also try to ensure\n // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n // before older versions are fully initialized.\n if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n root._bokeh_is_initializing = false;\n root._bokeh_onload_callbacks = undefined;\n console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n load_or_wait();\n } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n setTimeout(load_or_wait, 100);\n } else {\n Bokeh = root.Bokeh;\n bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n root._bokeh_is_initializing = true\n root._bokeh_onload_callbacks = []\n if (!reloading && (!bokeh_loaded || is_dev)) {\n\troot.Bokeh = undefined;\n }\n load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n\tconsole.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n\trun_inline_js();\n });\n }\n }\n // Give older versions of the autoload script a head-start to ensure\n // they initialize before we start loading newer version.\n setTimeout(load_or_wait, 100)\n}(window));",
- "application/vnd.holoviews_load.v0+json": ""
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "application/javascript": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n",
- "application/vnd.holoviews_load.v0+json": ""
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "text/html": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
{
"name": "stdout",
"output_type": "stream",
@@ -591,98 +551,98 @@
" fill: currentColor;\n",
"}\n",
"
<xarray.Dataset>\n",
- "Dimensions: (year: 2, x: 1, y: 1)\n",
+ "Dimensions: (tsm_time_step: 2, x: 1, y: 1)\n",
"Coordinates:\n",
- " * year (year) int32 0 1\n",
+ " * tsm_time_step (tsm_time_step) int32 0 1\n",
" * x (x) float64 1.0\n",
" * y (y) float64 1.0\n",
"Data variables: (12/52)\n",
- " water_temp_c (year, x, y) float64 20.0 20.0\n",
- " surface_area (year, x, y) int32 1 1\n",
- " volume (year, x, y) int32 1 1\n",
+ " water_temp_c (tsm_time_step, x, y) float64 20.0 20.0\n",
+ " surface_area (tsm_time_step, x, y) float64 1.0 1.0\n",
+ " volume (tsm_time_step, x, y) float64 1.0 1.0\n",
" use_sed_temp (x, y) bool True\n",
" stefan_boltzmann (x, y) float64 5.67e-08\n",
" cp_air (x, y) int32 1005\n",
" ... ...\n",
- " q_sediment (year, x, y) float64 nan -401.5\n",
- " dTdt_sediment_c (year, x, y) float64 nan 129.6\n",
- " q_longwave_down (year, x, y) float64 nan 337.8\n",
- " q_longwave_up (year, x, y) float64 nan 406.2\n",
- " q_net (year, x, y) float64 nan -151.1\n",
- " dTdt_water_c (year, x, y) float64 nan -3.619e-05
water_temp_c
(year, x, y)
float64
20.0 20.0
- long_name :
- Water temperature
- units :
- degC
- description :
- TSM state variable for water temperature
array([[[20. ]],\n",
+ " q_sediment (tsm_time_step, x, y) float64 nan -401.5\n",
+ " dTdt_sediment_c (tsm_time_step, x, y) float64 nan 129.6\n",
+ " q_net (tsm_time_step, x, y) float64 nan -151.1\n",
+ " q_longwave_down (tsm_time_step, x, y) float64 nan 337.8\n",
+ " q_longwave_up (tsm_time_step, x, y) float64 nan 406.2\n",
+ " dTdt_water_c (tsm_time_step, x, y) float64 nan -3.619e-05
water_temp_c
(tsm_time_step, x, y)
float64
20.0 20.0
- long_name :
- Water temperature
- units :
- degC
- description :
- TSM state variable for water temperature
array([[[20. ]],\n",
"\n",
- " [[19.99996381]]])
surface_area
(year, x, y)
int32
1 1
- long_name :
- Surface area
- units :
- m^2
- description :
- Surface area
array([[[1]],\n",
+ " [[19.99996381]]])
surface_area
(tsm_time_step, x, y)
float64
1.0 1.0
- long_name :
- Surface area
- units :
- m^2
- description :
- Surface area
array([[[1.]],\n",
"\n",
- " [[1]]])
volume
(year, x, y)
int32
1 1
- long_name :
- Volume
- units :
- m^3
- description :
- Volume
array([[[1]],\n",
+ " [[1.]]])
volume
(tsm_time_step, x, y)
float64
1.0 1.0
- long_name :
- Volume
- units :
- m^3
- description :
- Volume
array([[[1.]],\n",
"\n",
- " [[1]]])
use_sed_temp
(x, y)
bool
True
- long_name :
- Use Sediment Temperature?
- units :
- boolean
- description :
- Controls whether to use/calculate sediment temperature or not.
stefan_boltzmann
(x, y)
float64
5.67e-08
- long_name :
- Stefan-Boltzmann Constant
- units :
- W m-2 K-4
- description :
- The Stefan-Boltzmann constant.
cp_air
(x, y)
int32
1005
- long_name :
- Specific Heat Capacity of Air
- units :
- J kg-1 K-1
- description :
- The specific heat capacity of air.
emissivity_water
(x, y)
float64
0.97
- long_name :
- Emissivity of Water
- units :
- 1
- description :
- The emissivity of water.
gravity
(x, y)
float64
9.806
- long_name :
- Gravity
- units :
- m s-2
- description :
- The acceleration due to gravity.
a0
(x, y)
float64
6.985e+03
- long_name :
- Albedo of Water
- units :
- unitless
- description :
- The albedo of water.
a1
(x, y)
float64
-188.9
- long_name :
- Albedo of Water
- units :
- unitless
- description :
- The albedo of water.
a2
(x, y)
float64
2.133
- long_name :
- Albedo of Water
- units :
- unitless
- description :
- The albedo of water.
a3
(x, y)
float64
-0.01289
- long_name :
- Albedo of Water
- units :
- unitless
- description :
- The albedo of water.
a4
(x, y)
float64
4.394e-05
- long_name :
- Albedo of Water
- units :
- unitless
- description :
- The albedo of water.
a5
(x, y)
float64
-8.024e-08
- long_name :
- Albedo of Water
- units :
- unitless
- description :
- The albedo of water.
a6
(x, y)
float64
6.137e-11
- long_name :
- Albedo of Water
- units :
- unitless
- description :
- The albedo of water.
pb
(x, y)
int32
1600
- long_name :
- Bulk Density of Sediment
- units :
- kg m-3
- description :
- The bulk density of sediment.
cps
(x, y)
int32
1673
- long_name :
- CPS
- units :
- J kg-1 K-1
- description :
- The CPS.
h2
(x, y)
float64
0.1
- long_name :
- H2
- units :
- m
- description :
- The H2.
alphas
(x, y)
float64
0.0432
- long_name :
- Alphas
- units :
- m-1
- description :
- The alphas.
richardson_option
(x, y)
bool
True
- long_name :
- Richardson Option
- units :
- unitless
- description :
- The Richardson option.
air_temp_c
(x, y)
int32
20
- long_name :
- Air Temperature
- units :
- C
- description :
- The air temperature.
q_solar
(x, y)
int32
400
- long_name :
- Solar Heat Flux
- units :
- W m-2
- description :
- The solar heat flux.
sed_temp_c
(x, y)
int32
5
- long_name :
- Sediment Temperature
- units :
- C
- description :
- The sediment temperature.
eair_mb
(x, y)
int32
1
- long_name :
- Eair MB
- units :
- mb
- description :
- The eair MB.
pressure_mb
(x, y)
int32
1013
- long_name :
- Pressure
- units :
- mb
- description :
- The pressure.
cloudiness
(x, y)
float64
0.1
- long_name :
- Cloudiness
- units :
- unitless
- description :
- The cloudiness.
wind_speed
(x, y)
int32
3
- long_name :
- Wind Speed
- units :
- m s-1
- description :
- The wind speed.
wind_a
(x, y)
float64
0.3
- long_name :
- Wind A
- units :
- m s-1
- description :
- The wind A.
wind_b
(x, y)
float64
1.5
- long_name :
- Wind B
- units :
- m s-1
- description :
- The wind B.
wind_c
(x, y)
int32
1
- long_name :
- Wind C
- units :
- m s-1
- description :
- The wind C.
wind_kh_kw
(x, y)
int32
1
- long_name :
- Wind KH KW
- units :
- m s-1
- description :
- The wind KH KW.
air_temp_k
(year, x, y)
float64
nan 293.2
- long_name :
- Air temperature
- units :
- K
- description :
- Air temperature
array([[[ nan]],\n",
+ " [[1.]]])
use_sed_temp
(x, y)
bool
True
- long_name :
- Use Sediment Temperature?
- units :
- boolean
- description :
- Controls whether to use/calculate sediment temperature or not.
stefan_boltzmann
(x, y)
float64
5.67e-08
- long_name :
- Stefan-Boltzmann Constant
- units :
- W m-2 K-4
- description :
- The Stefan-Boltzmann constant.
cp_air
(x, y)
int32
1005
- long_name :
- Specific Heat Capacity of Air
- units :
- J kg-1 K-1
- description :
- The specific heat capacity of air.
emissivity_water
(x, y)
float64
0.97
- long_name :
- Emissivity of Water
- units :
- 1
- description :
- The emissivity of water.
gravity
(x, y)
float64
9.806
- long_name :
- Gravity
- units :
- m s-2
- description :
- The acceleration due to gravity.
a0
(x, y)
float64
6.985e+03
- long_name :
- Albedo of Water
- units :
- unitless
- description :
- The albedo of water.
a1
(x, y)
float64
-188.9
- long_name :
- Albedo of Water
- units :
- unitless
- description :
- The albedo of water.
a2
(x, y)
float64
2.133
- long_name :
- Albedo of Water
- units :
- unitless
- description :
- The albedo of water.
a3
(x, y)
float64
-0.01289
- long_name :
- Albedo of Water
- units :
- unitless
- description :
- The albedo of water.
a4
(x, y)
float64
4.394e-05
- long_name :
- Albedo of Water
- units :
- unitless
- description :
- The albedo of water.
a5
(x, y)
float64
-8.024e-08
- long_name :
- Albedo of Water
- units :
- unitless
- description :
- The albedo of water.
a6
(x, y)
float64
6.137e-11
- long_name :
- Albedo of Water
- units :
- unitless
- description :
- The albedo of water.
pb
(x, y)
int32
1600
- long_name :
- Bulk Density of Sediment
- units :
- kg m-3
- description :
- The bulk density of sediment.
cps
(x, y)
int32
1673
- long_name :
- CPS
- units :
- J kg-1 K-1
- description :
- The CPS.
h2
(x, y)
float64
0.1
- long_name :
- H2
- units :
- m
- description :
- The H2.
alphas
(x, y)
float64
0.0432
- long_name :
- Alphas
- units :
- m-1
- description :
- The alphas.
richardson_option
(x, y)
bool
True
- long_name :
- Richardson Option
- units :
- unitless
- description :
- The Richardson option.
air_temp_c
(x, y)
int32
20
- long_name :
- Air Temperature
- units :
- C
- description :
- The air temperature.
q_solar
(x, y)
int32
400
- long_name :
- Solar Heat Flux
- units :
- W m-2
- description :
- The solar heat flux.
sed_temp_c
(x, y)
int32
5
- long_name :
- Sediment Temperature
- units :
- C
- description :
- The sediment temperature.
eair_mb
(x, y)
int32
1
- long_name :
- Eair MB
- units :
- mb
- description :
- The eair MB.
pressure_mb
(x, y)
int32
1013
- long_name :
- Pressure
- units :
- mb
- description :
- The pressure.
cloudiness
(x, y)
float64
0.1
- long_name :
- Cloudiness
- units :
- unitless
- description :
- The cloudiness.
wind_speed
(x, y)
int32
3
- long_name :
- Wind Speed
- units :
- m s-1
- description :
- The wind speed.
wind_a
(x, y)
float64
0.3
- long_name :
- Wind A
- units :
- m s-1
- description :
- The wind A.
wind_b
(x, y)
float64
1.5
- long_name :
- Wind B
- units :
- m s-1
- description :
- The wind B.
wind_c
(x, y)
int32
1
- long_name :
- Wind C
- units :
- m s-1
- description :
- The wind C.
wind_kh_kw
(x, y)
int32
1
- long_name :
- Wind KH KW
- units :
- m s-1
- description :
- The wind KH KW.
air_temp_k
(tsm_time_step, x, y)
float64
nan 293.2
- long_name :
- Air temperature
- units :
- K
- description :
- Air temperature
array([[[ nan]],\n",
"\n",
- " [[293.16]]])
water_temp_k
(year, x, y)
float64
nan 293.2
- long_name :
- Water temperature
- units :
- K
- description :
- Water temperature
array([[[ nan]],\n",
+ " [[293.16]]])
water_temp_k
(tsm_time_step, x, y)
float64
nan 293.2
- long_name :
- Water temperature
- units :
- K
- description :
- Water temperature
array([[[ nan]],\n",
"\n",
- " [[293.16]]])
mixing_ratio_air
(year, x, y)
float64
nan 0.0006146
- long_name :
- Mixing ratio of air
- units :
- unitless
- description :
- Mixing ratio of air
array([[[ nan]],\n",
+ " [[293.16]]])
mixing_ratio_air
(tsm_time_step, x, y)
float64
nan 0.0006146
- long_name :
- Mixing ratio of air
- units :
- unitless
- description :
- Mixing ratio of air
array([[[ nan]],\n",
"\n",
- " [[0.00061462]]])
density_air
(year, x, y)
float64
nan 1.202
- long_name :
- Density of air
- units :
- kg/m^3
- description :
- Density of air
array([[[ nan]],\n",
+ " [[0.00061462]]])
density_air
(tsm_time_step, x, y)
float64
nan 1.202
- long_name :
- Density of air
- units :
- kg/m^3
- description :
- Density of air
array([[[ nan]],\n",
"\n",
- " [[1.20204653]]])
density_water
(year, x, y)
float64
nan 998.2
- long_name :
- Density of water
- units :
- kg/m^3
- description :
- Density of water
array([[[ nan]],\n",
+ " [[1.20204653]]])
density_water
(tsm_time_step, x, y)
float64
nan 998.2
- long_name :
- Density of water
- units :
- kg/m^3
- description :
- Density of water
array([[[ nan]],\n",
"\n",
- " [[998.20668383]]])
esat_mb
(year, x, y)
float64
nan 23.63
- long_name :
- Saturation vapor pressure
- units :
- mb
- description :
- Saturation vapor pressure
array([[[ nan]],\n",
+ " [[998.20668383]]])
esat_mb
(tsm_time_step, x, y)
float64
nan 23.63
- long_name :
- Saturation vapor pressure
- units :
- mb
- description :
- Saturation vapor pressure
array([[[ nan]],\n",
"\n",
- " [[23.62941518]]])
density_air_sat
(year, x, y)
float64
nan 1.192
- long_name :
- Density of air at saturation
- units :
- kg/m^3
- description :
- Density of air at saturation
array([[[ nan]],\n",
+ " [[23.62941518]]])
density_air_sat
(tsm_time_step, x, y)
float64
nan 1.192
- long_name :
- Density of air at saturation
- units :
- kg/m^3
- description :
- Density of air at saturation
array([[[ nan]],\n",
"\n",
- " [[1.19185468]]])
ri_number
(year, x, y)
float64
nan 0.01848
- long_name :
- Richardson number
- units :
- unitless
- description :
- Richardson number
array([[[ nan]],\n",
+ " [[1.19185468]]])
ri_number
(tsm_time_step, x, y)
float64
nan 0.01848
- long_name :
- Richardson number
- units :
- unitless
- description :
- Richardson number
array([[[ nan]],\n",
"\n",
- " [[0.01847614]]])
ri_function
(year, x, y)
float64
nan 0.6771
- long_name :
- Richardson function
- units :
- unitless
- description :
- Richardson function
array([[[ nan]],\n",
+ " [[0.01847614]]])
ri_function
(tsm_time_step, x, y)
float64
nan 0.6771
- long_name :
- Richardson function
- units :
- unitless
- description :
- Richardson function
array([[[ nan]],\n",
"\n",
- " [[0.67707413]]])
lv
(year, x, y)
float64
nan 1.801e+06
- long_name :
- Latent heat of vaporization
- units :
- J/kg
- description :
- Latent heat of vaporization
array([[[ nan]],\n",
+ " [[0.67707413]]])
lv
(tsm_time_step, x, y)
float64
nan 1.801e+06
- long_name :
- Latent heat of vaporization
- units :
- J/kg
- description :
- Latent heat of vaporization
array([[[ nan]],\n",
"\n",
- " [[1800595.4616]]])
cp_water
(year, x, y)
float64
nan 4.182e+03
- long_name :
- Specific heat of water
- units :
- J/kg/K
- description :
- Specific heat of water
array([[[ nan]],\n",
+ " [[1800595.4616]]])
cp_water
(tsm_time_step, x, y)
float64
nan 4.182e+03
- long_name :
- Specific heat of water
- units :
- J/kg/K
- description :
- Specific heat of water
array([[[ nan]],\n",
"\n",
- " [[4182.]]])
emissivity_air
(year, x, y)
float64
nan 0.8053
- long_name :
- Emissivity of air
- units :
- unitless
- description :
- Emissivity of air
array([[[ nan]],\n",
+ " [[4182.]]])
emissivity_air
(tsm_time_step, x, y)
float64
nan 0.8053
- long_name :
- Emissivity of air
- units :
- unitless
- description :
- Emissivity of air
array([[[ nan]],\n",
"\n",
- " [[0.8052839]]])
wind_function
(year, x, y)
float64
nan 3.25e-06
- long_name :
- Wind function
- units :
- unitless
- description :
- Wind function
array([[[ nan]],\n",
+ " [[0.8052839]]])
wind_function
(tsm_time_step, x, y)
float64
nan 3.25e-06
- long_name :
- Wind function
- units :
- unitless
- description :
- Wind function
array([[[ nan]],\n",
"\n",
- " [[3.2499558e-06]]])
q_latent
(year, x, y)
float64
nan 81.16
- long_name :
- Latent heat flux
- units :
- W/m^2
- description :
- Latent heat flux
array([[[ nan]],\n",
+ " [[3.2499558e-06]]])
q_latent
(tsm_time_step, x, y)
float64
nan 81.16
- long_name :
- Latent heat flux
- units :
- W/m^2
- description :
- Latent heat flux
array([[[ nan]],\n",
"\n",
- " [[81.1649171]]])
q_sensible
(year, x, y)
float64
nan 0.0
- long_name :
- Sensible heat flux
- units :
- W/m^2
- description :
- Sensible heat flux
array([[[nan]],\n",
+ " [[81.1649171]]])
q_sensible
(tsm_time_step, x, y)
float64
nan 0.0
- long_name :
- Sensible heat flux
- units :
- W/m^2
- description :
- Sensible heat flux
array([[[nan]],\n",
"\n",
- " [[ 0.]]])
q_sediment
(year, x, y)
float64
nan -401.5
- long_name :
- Sediment heat flux
- units :
- W/m^2
- description :
- Sediment heat flux
array([[[ nan]],\n",
+ " [[ 0.]]])
q_sediment
(tsm_time_step, x, y)
float64
nan -401.5
- long_name :
- Sediment heat flux
- units :
- W/m^2
- description :
- Sediment heat flux
array([[[ nan]],\n",
"\n",
- " [[-401.52]]])
dTdt_sediment_c
(year, x, y)
float64
nan 129.6
- long_name :
- Sediment temperature change
- units :
- degC
- description :
- Sediment temperature change
array([[[ nan]],\n",
+ " [[-401.52]]])
dTdt_sediment_c
(tsm_time_step, x, y)
float64
nan 129.6
- long_name :
- Sediment temperature change
- units :
- degC
- description :
- Sediment temperature change
array([[[ nan]],\n",
"\n",
- " [[129.6]]])
q_longwave_down
(year, x, y)
float64
nan 337.8
- long_name :
- Downwelling longwave radiation
- units :
- W/m2
- description :
- Downwelling longwave radiation
array([[[ nan]],\n",
+ " [[129.6]]])
q_net
(tsm_time_step, x, y)
float64
nan -151.1
- long_name :
- Net heat flux
- units :
- W/m^2
- description :
- Net heat flux
array([[[ nan]],\n",
"\n",
- " [[337.82252346]]])
q_longwave_up
(year, x, y)
float64
nan 406.2
- long_name :
- Upwelling longwave radiation
- units :
- W/m2
- description :
- Upwelling longwave radiation
array([[[ nan]],\n",
+ " [[-151.09393929]]])
q_longwave_down
(tsm_time_step, x, y)
float64
nan 337.8
- long_name :
- Downwelling longwave radiation
- units :
- W/m2
- description :
- Downwelling longwave radiation
array([[[ nan]],\n",
"\n",
- " [[406.23154566]]])
q_net
(year, x, y)
float64
nan -151.1
- long_name :
- Net heat flux
- units :
- W/m^2
- description :
- Net heat flux
array([[[ nan]],\n",
+ " [[337.82252346]]])
q_longwave_up
(tsm_time_step, x, y)
float64
nan 406.2
- long_name :
- Upwelling longwave radiation
- units :
- W/m2
- description :
- Upwelling longwave radiation
array([[[ nan]],\n",
"\n",
- " [[-151.09393929]]])
dTdt_water_c
(year, x, y)
float64
nan -3.619e-05
- long_name :
- Water temperature change
- units :
- degC
- description :
- Water temperature change
array([[[ nan]],\n",
+ " [[406.23154566]]])
dTdt_water_c
(tsm_time_step, x, y)
float64
nan -3.619e-05
- long_name :
- Water temperature change
- units :
- degC
- description :
- Water temperature change
array([[[ nan]],\n",
"\n",
- " [[-3.61944967e-05]]])
"
+ " [[-3.61944967e-05]]])
"
],
"text/plain": [
"\n",
- "Dimensions: (year: 2, x: 1, y: 1)\n",
+ "Dimensions: (tsm_time_step: 2, x: 1, y: 1)\n",
"Coordinates:\n",
- " * year (year) int32 0 1\n",
+ " * tsm_time_step (tsm_time_step) int32 0 1\n",
" * x (x) float64 1.0\n",
" * y (y) float64 1.0\n",
"Data variables: (12/52)\n",
- " water_temp_c (year, x, y) float64 20.0 20.0\n",
- " surface_area (year, x, y) int32 1 1\n",
- " volume (year, x, y) int32 1 1\n",
+ " water_temp_c (tsm_time_step, x, y) float64 20.0 20.0\n",
+ " surface_area (tsm_time_step, x, y) float64 1.0 1.0\n",
+ " volume (tsm_time_step, x, y) float64 1.0 1.0\n",
" use_sed_temp (x, y) bool True\n",
" stefan_boltzmann (x, y) float64 5.67e-08\n",
" cp_air (x, y) int32 1005\n",
" ... ...\n",
- " q_sediment (year, x, y) float64 nan -401.5\n",
- " dTdt_sediment_c (year, x, y) float64 nan 129.6\n",
- " q_longwave_down (year, x, y) float64 nan 337.8\n",
- " q_longwave_up (year, x, y) float64 nan 406.2\n",
- " q_net (year, x, y) float64 nan -151.1\n",
- " dTdt_water_c (year, x, y) float64 nan -3.619e-05"
+ " q_sediment (tsm_time_step, x, y) float64 nan -401.5\n",
+ " dTdt_sediment_c (tsm_time_step, x, y) float64 nan 129.6\n",
+ " q_net (tsm_time_step, x, y) float64 nan -151.1\n",
+ " q_longwave_down (tsm_time_step, x, y) float64 nan 337.8\n",
+ " q_longwave_up (tsm_time_step, x, y) float64 nan 406.2\n",
+ " dTdt_water_c (tsm_time_step, x, y) float64 nan -3.619e-05"
]
},
- "execution_count": 1,
+ "execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
@@ -731,15 +691,58 @@
" 'richardson_option': True\n",
"}\n",
"\n",
+ "time_step = 1\n",
+ "\n",
"tsm_model = cwm.tsm.EnergyBudget(\n",
+ " time_steps=time_step,\n",
" initial_state_values=initial_state_values, # mandatory\n",
" temp_parameters=temp_parameters,\n",
" meteo_parameters=meteo_parameters,\n",
" track_dynamic_variables=True, # default is true\n",
" hotstart_dataset=None, # default is None\n",
- " time_dim='year', # default is \"timestep\"\n",
+ " time_dim='tsm_time_step', # default is \"timestep\"\n",
")\n",
"\n",
+ "tsm_model.increment_timestep()\n",
+ "tsm_model.dataset\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "644f6baf",
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "KeyError",
+ "evalue": "\"not all values found in index 'tsm_time_step'. Try setting the `method` keyword argument (example: method='nearest').\"",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[1;31mKeyError\u001b[0m Traceback (most recent call last)",
+ "File \u001b[1;32mc:\\Anaconda3\\envs\\clearwater_dev_env\\Lib\\site-packages\\pandas\\core\\indexes\\base.py:3790\u001b[0m, in \u001b[0;36mIndex.get_loc\u001b[1;34m(self, key)\u001b[0m\n\u001b[0;32m 3789\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m-> 3790\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_engine\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_loc\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcasted_key\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 3791\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m err:\n",
+ "File \u001b[1;32mindex.pyx:152\u001b[0m, in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[1;34m()\u001b[0m\n",
+ "File \u001b[1;32mindex.pyx:181\u001b[0m, in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[1;34m()\u001b[0m\n",
+ "File \u001b[1;32mpandas\\_libs\\hashtable_class_helper.pxi:4484\u001b[0m, in \u001b[0;36mpandas._libs.hashtable.Int32HashTable.get_item\u001b[1;34m()\u001b[0m\n",
+ "File \u001b[1;32mpandas\\_libs\\hashtable_class_helper.pxi:4508\u001b[0m, in \u001b[0;36mpandas._libs.hashtable.Int32HashTable.get_item\u001b[1;34m()\u001b[0m\n",
+ "\u001b[1;31mKeyError\u001b[0m: 2",
+ "\nThe above exception was the direct cause of the following exception:\n",
+ "\u001b[1;31mKeyError\u001b[0m Traceback (most recent call last)",
+ "File \u001b[1;32mc:\\Anaconda3\\envs\\clearwater_dev_env\\Lib\\site-packages\\xarray\\core\\indexes.py:772\u001b[0m, in \u001b[0;36mPandasIndex.sel\u001b[1;34m(self, labels, method, tolerance)\u001b[0m\n\u001b[0;32m 771\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 772\u001b[0m indexer \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mindex\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_loc\u001b[49m\u001b[43m(\u001b[49m\u001b[43mlabel_value\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 773\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n",
+ "File \u001b[1;32mc:\\Anaconda3\\envs\\clearwater_dev_env\\Lib\\site-packages\\pandas\\core\\indexes\\base.py:3797\u001b[0m, in \u001b[0;36mIndex.get_loc\u001b[1;34m(self, key)\u001b[0m\n\u001b[0;32m 3796\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m InvalidIndexError(key)\n\u001b[1;32m-> 3797\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m(key) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01merr\u001b[39;00m\n\u001b[0;32m 3798\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m:\n\u001b[0;32m 3799\u001b[0m \u001b[38;5;66;03m# If we have a listlike key, _check_indexing_error will raise\u001b[39;00m\n\u001b[0;32m 3800\u001b[0m \u001b[38;5;66;03m# InvalidIndexError. Otherwise we fall through and re-raise\u001b[39;00m\n\u001b[0;32m 3801\u001b[0m \u001b[38;5;66;03m# the TypeError.\u001b[39;00m\n",
+ "\u001b[1;31mKeyError\u001b[0m: 2",
+ "\nThe above exception was the direct cause of the following exception:\n",
+ "\u001b[1;31mKeyError\u001b[0m Traceback (most recent call last)",
+ "Cell \u001b[1;32mIn[3], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[43mtsm_model\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mincrement_timestep\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 2\u001b[0m tsm_model\u001b[38;5;241m.\u001b[39mdataset\n",
+ "File \u001b[1;32m~\\Documents\\GitHub\\ClearWater-modules\\src\\clearwater_modules\\base.py:530\u001b[0m, in \u001b[0;36mModel.increment_timestep\u001b[1;34m(self, update_state_values)\u001b[0m\n\u001b[0;32m 523\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtimestep_ds \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtimestep_ds\u001b[38;5;241m.\u001b[39mdrop_vars(\n\u001b[0;32m 524\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdynamic_variables_names\n\u001b[0;32m 525\u001b[0m )\n\u001b[0;32m 526\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtimestep_ds \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtimestep_ds\u001b[38;5;241m.\u001b[39mdrop_vars(\n\u001b[0;32m 527\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_non_updateable_static_variables\n\u001b[0;32m 528\u001b[0m )\n\u001b[1;32m--> 530\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdataset\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtemporal_variables\u001b[49m\u001b[43m]\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mloc\u001b[49m\u001b[43m[\u001b[49m\n\u001b[0;32m 531\u001b[0m \u001b[43m \u001b[49m\u001b[43m{\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtime_dim\u001b[49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtimestep\u001b[49m\u001b[43m}\u001b[49m\n\u001b[0;32m 532\u001b[0m \u001b[43m\u001b[49m\u001b[43m]\u001b[49m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtimestep_ds\n\u001b[0;32m 534\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdataset\n",
+ "File \u001b[1;32mc:\\Anaconda3\\envs\\clearwater_dev_env\\Lib\\site-packages\\xarray\\core\\dataset.py:510\u001b[0m, in \u001b[0;36m_LocIndexer.__setitem__\u001b[1;34m(self, key, value)\u001b[0m\n\u001b[0;32m 504\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\n\u001b[0;32m 505\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcan only set locations defined by dictionaries from Dataset.loc.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 506\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m Got: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mkey\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 507\u001b[0m )\n\u001b[0;32m 509\u001b[0m \u001b[38;5;66;03m# set new values\u001b[39;00m\n\u001b[1;32m--> 510\u001b[0m dim_indexers \u001b[38;5;241m=\u001b[39m \u001b[43mmap_index_queries\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdataset\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mkey\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241m.\u001b[39mdim_indexers\n\u001b[0;32m 511\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdataset[dim_indexers] \u001b[38;5;241m=\u001b[39m value\n",
+ "File \u001b[1;32mc:\\Anaconda3\\envs\\clearwater_dev_env\\Lib\\site-packages\\xarray\\core\\indexing.py:193\u001b[0m, in \u001b[0;36mmap_index_queries\u001b[1;34m(obj, indexers, method, tolerance, **indexers_kwargs)\u001b[0m\n\u001b[0;32m 191\u001b[0m results\u001b[38;5;241m.\u001b[39mappend(IndexSelResult(labels))\n\u001b[0;32m 192\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m--> 193\u001b[0m results\u001b[38;5;241m.\u001b[39mappend(\u001b[43mindex\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msel\u001b[49m\u001b[43m(\u001b[49m\u001b[43mlabels\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43moptions\u001b[49m\u001b[43m)\u001b[49m)\n\u001b[0;32m 195\u001b[0m merged \u001b[38;5;241m=\u001b[39m merge_sel_results(results)\n\u001b[0;32m 197\u001b[0m \u001b[38;5;66;03m# drop dimension coordinates found in dimension indexers\u001b[39;00m\n\u001b[0;32m 198\u001b[0m \u001b[38;5;66;03m# (also drop multi-index if any)\u001b[39;00m\n\u001b[0;32m 199\u001b[0m \u001b[38;5;66;03m# (.sel() already ensures alignment)\u001b[39;00m\n",
+ "File \u001b[1;32mc:\\Anaconda3\\envs\\clearwater_dev_env\\Lib\\site-packages\\xarray\\core\\indexes.py:774\u001b[0m, in \u001b[0;36mPandasIndex.sel\u001b[1;34m(self, labels, method, tolerance)\u001b[0m\n\u001b[0;32m 772\u001b[0m indexer \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mindex\u001b[38;5;241m.\u001b[39mget_loc(label_value)\n\u001b[0;32m 773\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m--> 774\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m(\n\u001b[0;32m 775\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mnot all values found in index \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mcoord_name\u001b[38;5;132;01m!r}\u001b[39;00m\u001b[38;5;124m. \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 776\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mTry setting the `method` keyword argument (example: method=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnearest\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m).\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 777\u001b[0m ) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01me\u001b[39;00m\n\u001b[0;32m 779\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m label_array\u001b[38;5;241m.\u001b[39mdtype\u001b[38;5;241m.\u001b[39mkind \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mb\u001b[39m\u001b[38;5;124m\"\u001b[39m:\n\u001b[0;32m 780\u001b[0m indexer \u001b[38;5;241m=\u001b[39m label_array\n",
+ "\u001b[1;31mKeyError\u001b[0m: \"not all values found in index 'tsm_time_step'. Try setting the `method` keyword argument (example: method='nearest').\""
+ ]
+ }
+ ],
+ "source": [
"tsm_model.increment_timestep()\n",
"tsm_model.dataset"
]
diff --git a/examples/model_architecture_nsm.ipynb b/examples/model_architecture_nsm.ipynb
index 8ca83c1..0bf5dbb 100644
--- a/examples/model_architecture_nsm.ipynb
+++ b/examples/model_architecture_nsm.ipynb
@@ -41,12 +41,131 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 1,
"id": "663a1e5a-4311-42e7-babc-6e254a5ff9cf",
"metadata": {
"tags": []
},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "application/javascript": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n var py_version = '3.3.4'.replace('rc', '-rc.').replace('.dev', '-dev.');\n var reloading = false;\n var Bokeh = root.Bokeh;\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks;\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n if (js_exports == null) js_exports = {};\n\n root._bokeh_onload_callbacks.push(callback);\n\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n run_callbacks();\n return null;\n }\n if (!reloading) {\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n }\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n window._bokeh_on_load = on_load\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'jspanel': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/jspanel', 'jspanel-modal': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal', 'jspanel-tooltip': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip', 'jspanel-hint': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint', 'jspanel-layout': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout', 'jspanel-contextmenu': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu', 'jspanel-dock': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@7.2.3/dist/gridstack-all', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'jspanel': {'exports': 'jsPanel'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"jspanel\"], function(jsPanel) {\n\twindow.jsPanel = jsPanel\n\ton_load()\n })\n require([\"jspanel-modal\"], function() {\n\ton_load()\n })\n require([\"jspanel-tooltip\"], function() {\n\ton_load()\n })\n require([\"jspanel-hint\"], function() {\n\ton_load()\n })\n require([\"jspanel-layout\"], function() {\n\ton_load()\n })\n require([\"jspanel-contextmenu\"], function() {\n\ton_load()\n })\n require([\"jspanel-dock\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 9;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n }\n\n var existing_stylesheets = []\n var links = document.getElementsByTagName('link')\n for (var i = 0; i < links.length; i++) {\n var link = links[i]\n if (link.href != null) {\n\texisting_stylesheets.push(link.href)\n }\n }\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n if (existing_stylesheets.indexOf(url) !== -1) {\n\ton_load()\n\tcontinue;\n }\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n } if (((window['jsPanel'] !== undefined) && (!(window['jsPanel'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.3.8/dist/bundled/floatpanel/jspanel4@4.12.0/dist/jspanel.js', 'https://cdn.holoviz.org/panel/1.3.8/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal.js', 'https://cdn.holoviz.org/panel/1.3.8/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip.js', 'https://cdn.holoviz.org/panel/1.3.8/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint.js', 'https://cdn.holoviz.org/panel/1.3.8/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout.js', 'https://cdn.holoviz.org/panel/1.3.8/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu.js', 'https://cdn.holoviz.org/panel/1.3.8/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.3.8/dist/bundled/gridstack/gridstack@7.2.3/dist/gridstack-all.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.3.8/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } var existing_scripts = []\n var scripts = document.getElementsByTagName('script')\n for (var i = 0; i < scripts.length; i++) {\n var script = scripts[i]\n if (script.src != null) {\n\texisting_scripts.push(script.src)\n }\n }\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (const name in js_exports) {\n var url = js_exports[name];\n if (skip.indexOf(url) >= 0 || root[name] != null) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onerror = on_error;\n element.async = false;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n element.textContent = `\n import ${name} from \"${url}\"\n window.${name} = ${name}\n window._bokeh_on_load()\n `\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.3.4.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.3.4.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.3.4.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.3.4.min.js\", \"https://cdn.holoviz.org/panel/1.3.8/dist/panel.min.js\"];\n var js_modules = [];\n var js_exports = {};\n var css_urls = [];\n var inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n\ttry {\n inline_js[i].call(root, root.Bokeh);\n\t} catch(e) {\n\t if (!reloading) {\n\t throw e;\n\t }\n\t}\n }\n // Cache old bokeh versions\n if (Bokeh != undefined && !reloading) {\n\tvar NewBokeh = root.Bokeh;\n\tif (Bokeh.versions === undefined) {\n\t Bokeh.versions = new Map();\n\t}\n\tif (NewBokeh.version !== Bokeh.version) {\n\t Bokeh.versions.set(NewBokeh.version, NewBokeh)\n\t}\n\troot.Bokeh = Bokeh;\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n root._bokeh_is_initializing = false\n }\n\n function load_or_wait() {\n // Implement a backoff loop that tries to ensure we do not load multiple\n // versions of Bokeh and its dependencies at the same time.\n // In recent versions we use the root._bokeh_is_initializing flag\n // to determine whether there is an ongoing attempt to initialize\n // bokeh, however for backward compatibility we also try to ensure\n // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n // before older versions are fully initialized.\n if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n root._bokeh_is_initializing = false;\n root._bokeh_onload_callbacks = undefined;\n console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n load_or_wait();\n } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n setTimeout(load_or_wait, 100);\n } else {\n root._bokeh_is_initializing = true\n root._bokeh_onload_callbacks = []\n var bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n if (!reloading && !bokeh_loaded) {\n\troot.Bokeh = undefined;\n }\n load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n\tconsole.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n\trun_inline_js();\n });\n }\n }\n // Give older versions of the autoload script a head-start to ensure\n // they initialize before we start loading newer version.\n setTimeout(load_or_wait, 100)\n}(window));",
+ "application/vnd.holoviews_load.v0+json": ""
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/javascript": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n",
+ "application/vnd.holoviews_load.v0+json": ""
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.holoviews_exec.v0+json": "",
+ "text/html": [
+ "\n",
+ ""
+ ]
+ },
+ "metadata": {
+ "application/vnd.holoviews_exec.v0+json": {
+ "id": "p1002"
+ }
+ },
+ "output_type": "display_data"
+ }
+ ],
"source": [
"import clearwater_modules as cwm\n",
"import clearwater_modules.sorter as sorter\n",
@@ -59,12 +178,38 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 2,
"id": "01c71150",
"metadata": {
"tags": []
},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['__builtins__',\n",
+ " '__cached__',\n",
+ " '__doc__',\n",
+ " '__file__',\n",
+ " '__loader__',\n",
+ " '__name__',\n",
+ " '__package__',\n",
+ " '__path__',\n",
+ " '__spec__',\n",
+ " '__version__',\n",
+ " 'base',\n",
+ " 'nsm1',\n",
+ " 'shared',\n",
+ " 'sorter',\n",
+ " 'tsm',\n",
+ " 'utils']"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
"# Confirm that sub-modules are imported\n",
"dir(cwm)"
@@ -72,7 +217,7 @@
},
{
"cell_type": "code",
- "execution_count": 3,
+ "execution_count": 13,
"id": "3bce5192",
"metadata": {},
"outputs": [
@@ -81,7 +226,416 @@
"output_type": "stream",
"text": [
"Initializing from dicts...\n",
- "Model initialized from input dicts successfully!.\n"
+ "Model initialized from input dicts successfully!.\n",
+ "['TwaterK', 'SOD_tc', 'kah_20', 'kah_tc', 'kaw_20', 'kaw_tc', 'ka_tc', 'L', 'PAR', 'fdp', 'rna', 'rpa', 'rca', 'rda', 'mu_max_tc', 'krp_tc', 'kdp_tc', 'FL', 'FN', 'FP', 'mu', 'ApGrowth', 'ApRespiration', 'ApDeath', 'ApSettling', 'dApdt', 'mub_max_tc', 'krb_tc', 'kdb_tc', 'rnb', 'rpb', 'rcb', 'rab', 'FLb', 'FNb', 'FPb', 'FSb', 'mub', 'AbGrowth', 'AbRespiration', 'AbDeath', 'dAbdt', 'Chlb', 'knit_tc', 'rnh4_tc', 'vno3_tc', 'kon_tc', 'kdnit_tc', 'ApUptakeFr_NH4', 'ApUptakeFr_NO3', 'AbUptakeFr_NH4', 'AbUptakeFr_NO3', 'ApDeath_OrgN', 'AbDeath_OrgN', 'OrgN_NH4_Decay', 'OrgN_Settling', 'dOrgNdt', 'NH4_Nitrification', 'NH4fromBed', 'NH4_ApRespiration', 'NH4_ApGrowth', 'NH4_AbRespiration', 'NH4_AbGrowth', 'dNH4dt', 'NO3_Denit', 'NO3_BedDenit', 'NO3_ApGrowth', 'NO3_AbGrowth', 'dNO3dt', 'DIN', 'TON', 'TKN', 'TN', 'NitrificationInhibition', 'kop_tc', 'rpo4_tc', 'OrgP_DIP_decay', 'OrgP_Settling', 'ApDeath_OrgP', 'AbDeath_OrgP', 'dOrgPdt', 'DIPfromBed', 'TIP_Settling', 'DIP_ApRespiration', 'DIP_ApGrowth', 'DIP_AbRespiration', 'DIP_AbGrowth', 'dTIPdt', 'TOP', 'TP', 'DIP', 'kpom_tc', 'POM_algal_settling', 'POM_dissolution', 'POM_POC_settling', 'POM_benthic_algae_mortality', 'POM_burial', 'dPOMdt', 'kbod_tc', 'ksbod_tc', 'CBOD_oxidation', 'CBOD_sedimentation', 'dCBODdt', 'kpoc_tc', 'POC_settling', 'POC_hydrolysis', 'POC_algal_mortality', 'POC_benthic_algae_mortality', 'dPOCdt', 'kdoc_tc', 'DOC_algal_mortality', 'DOC_benthic_algae_mortality', 'DOC_DIC_oxidation', 'dDOCdt', 'K_H', 'Atm_CO2_reaeration', 'DIC_algal_respiration', 'DIC_algal_photosynthesis', 'DIC_benthic_algae_respiration', 'DIC_benthic_algae_photosynthesis', 'DIC_CBOD_oxidation', 'DIC_sed_release', 'dDICdt', 'DOX_sat', 'pwv', 'DOs_atm_alpha', 'Atm_O2_reaeration', 'DOX_ApGrowth', 'DOX_ApRespiration', 'DOX_Nitrification', 'DOX_DOC_oxidation', 'DOX_CBOD_oxidation', 'DOX_AbGrowth', 'DOX_AbRespiration', 'DOX_SOD', 'dDOXdt', 'kdx_tc', 'PathogenDeath', 'PathogenDecay', 'PathogenSettling', 'dPXdt', 'Alk_denitrification', 'Alk_nitrification', 'Alk_algal_growth', 'Alk_algal_respiration', 'Alk_benthic_algae_growth', 'Alk_benthic_algae_respiration', 'dAlkdt', 'KHN2_tc', 'P_wv', 'N2sat', 'dN2dt', 'TDG']\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "C:\\Users\\l2edeknw\\Documents\\Projects\\ToddERDC\\ClearWater-modules\\src\\clearwater_modules\\nsm1\\processes.py:3454: RuntimeWarning: divide by zero encountered in divide\n",
+ " return xr.where(use_DOX,(79.0 * N2 / N2sat) + (21.0 * DOX / DOX_sat), N2/N2sat)\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Variable | Inputs\n",
+ "------------------\n",
+ "TwaterK | ['TwaterC']\n",
+ "SOD_tc | ['SOD_20', 'TwaterC', 'SOD_theta', 'DOX', 'KsSOD', 'use_DOX']\n",
+ "kah_20 | ['kah_20_user', 'hydraulic_reaeration_option', 'velocity', 'depth', 'flow', 'topwidth', 'slope', 'shear_velocity']\n",
+ "kah_tc | ['TwaterC', 'kah_20', 'theta']\n",
+ "kaw_20 | ['kaw_20_user', 'wind_speed', 'wind_reaeration_option']\n",
+ "kaw_tc | ['TwaterC', 'kaw_20', 'theta']\n",
+ "ka_tc | ['kah_tc', 'kaw_tc', 'depth']\n",
+ "L | ['lambda0', 'lambda1', 'lambda2', 'lambdas', 'lambdam', 'Solid', 'POC', 'fcom', 'use_Algae', 'use_POC', 'Ap']\n",
+ "PAR | ['use_Algae', 'use_Balgae', 'q_solar', 'Fr_PAR']\n",
+ "fdp | ['use_TIP', 'Solid', 'kdpo4']\n",
+ "rna | ['AWn', 'AWa']\n",
+ "rpa | ['AWp', 'AWa']\n",
+ "rca | ['AWc', 'AWa']\n",
+ "rda | ['AWd', 'AWa']\n",
+ "mu_max_tc | ['TwaterC', 'mu_max_20']\n",
+ "krp_tc | ['TwaterC', 'krp_20']\n",
+ "kdp_tc | ['TwaterC', 'kdp_20']\n",
+ "FL | ['L', 'depth', 'Ap', 'PAR', 'light_limitation_option', 'KL']\n",
+ "FN | ['use_NH4', 'use_NO3', 'NH4', 'NO3', 'KsN']\n",
+ "FP | ['fdp', 'TIP', 'use_TIP', 'KsP']\n",
+ "mu | ['mu_max_tc', 'growth_rate_option', 'FL', 'FP', 'FN']\n",
+ "ApGrowth | ['mu', 'Ap']\n",
+ "ApRespiration | ['krp_tc', 'Ap']\n",
+ "ApDeath | ['kdp_tc', 'Ap']\n",
+ "ApSettling | ['vsap', 'Ap', 'depth']\n",
+ "dApdt | ['ApGrowth', 'ApRespiration', 'ApDeath', 'ApSettling']\n",
+ "mub_max_tc | ['mub_max_20', 'TwaterC']\n",
+ "krb_tc | ['krb_20', 'TwaterC']\n",
+ "kdb_tc | ['kdb_20', 'TwaterC']\n",
+ "rnb | ['BWn', 'BWd']\n",
+ "rpb | ['BWp', 'BWd']\n",
+ "rcb | ['BWc', 'BWd']\n",
+ "rab | ['BWa', 'BWd']\n",
+ "FLb | ['L', 'depth', 'Ab', 'PAR', 'b_light_limitation_option', 'KLb']\n",
+ "FNb | ['use_NH4', 'use_NO3', 'NH4', 'NO3', 'KsNb']\n",
+ "FPb | ['fdp', 'TIP', 'use_TIP', 'KsPb']\n",
+ "FSb | ['Ab', 'Ksb']\n",
+ "mub | ['mub_max_tc', 'b_growth_rate_option', 'FLb', 'FPb', 'FNb', 'FSb']\n",
+ "AbGrowth | ['mub', 'Ab']\n",
+ "AbRespiration | ['krb_tc', 'Ab']\n",
+ "AbDeath | ['kdb_tc', 'Ab']\n",
+ "dAbdt | ['AbGrowth', 'AbRespiration', 'AbDeath']\n",
+ "Chlb | ['rab', 'Ab']\n",
+ "knit_tc | ['TwaterC', 'knit_20']\n",
+ "rnh4_tc | ['TwaterC', 'rnh4_20']\n",
+ "vno3_tc | ['TwaterC', 'vno3_20']\n",
+ "kon_tc | ['TwaterC', 'kon_20']\n",
+ "kdnit_tc | ['TwaterC', 'kdnit_20']\n",
+ "ApUptakeFr_NH4 | ['use_NH4', 'use_NO3', 'use_Algae', 'PN', 'NH4', 'NO3']\n",
+ "ApUptakeFr_NO3 | ['ApUptakeFr_NH4']\n",
+ "AbUptakeFr_NH4 | ['use_NH4', 'use_NO3', 'use_Balgae', 'PNb', 'NH4', 'NO3']\n",
+ "AbUptakeFr_NO3 | ['AbUptakeFr_NH4']\n",
+ "ApDeath_OrgN | ['use_Algae', 'rna', 'ApDeath']\n",
+ "AbDeath_OrgN | ['use_Balgae', 'rnb', 'Fw', 'Fb', 'depth', 'AbDeath']\n",
+ "OrgN_NH4_Decay | ['kon_tc', 'OrgN', 'use_OrgN']\n",
+ "OrgN_Settling | ['vson', 'depth', 'OrgN']\n",
+ "dOrgNdt | ['use_OrgN', 'ApDeath_OrgN', 'AbDeath_OrgN', 'OrgN_NH4_Decay', 'OrgN_Settling']\n",
+ "NH4fromBed | ['depth', 'rnh4_tc']\n",
+ "NH4_ApRespiration | ['use_Algae', 'ApRespiration', 'rna']\n",
+ "NH4_ApGrowth | ['use_Algae', 'ApGrowth', 'rna', 'ApUptakeFr_NH4']\n",
+ "NH4_AbRespiration | ['use_Balgae', 'rnb', 'AbRespiration']\n",
+ "NH4_AbGrowth | ['use_Balgae', 'rnb', 'AbGrowth', 'AbUptakeFr_NH4', 'Fb', 'depth']\n",
+ "NO3_Denit | ['use_DOX', 'DOX', 'KsOxdn', 'kdnit_tc', 'NO3']\n",
+ "NO3_BedDenit | ['depth', 'vno3_tc', 'NO3']\n",
+ "NO3_ApGrowth | ['use_Algae', 'ApUptakeFr_NO3', 'rna', 'ApGrowth']\n",
+ "NO3_AbGrowth | ['use_Balgae', 'AbUptakeFr_NO3', 'rnb', 'Fb', 'AbGrowth', 'depth']\n",
+ "DIN | ['use_NH4', 'use_NO3', 'NH4', 'NO3']\n",
+ "TON | ['use_OrgN', 'use_Algae', 'OrgN', 'rna', 'Ap']\n",
+ "TKN | ['use_NH4', 'NH4', 'TON']\n",
+ "TN | ['DIN', 'TON']\n",
+ "NitrificationInhibition | ['use_DOX', 'KNR', 'DOX']\n",
+ "kop_tc | ['TwaterC', 'kop_20']\n",
+ "rpo4_tc | ['TwaterC', 'rpo4_20']\n",
+ "OrgP_DIP_decay | ['kop_tc', 'OrgP', 'use_OrgP']\n",
+ "OrgP_Settling | ['vsop', 'depth', 'OrgP']\n",
+ "ApDeath_OrgP | ['rpa', 'ApDeath', 'use_Algae']\n",
+ "AbDeath_OrgP | ['rpb', 'AbDeath', 'Fw', 'Fb', 'depth', 'use_Balgae']\n",
+ "dOrgPdt | ['ApDeath_OrgP', 'AbDeath_OrgP', 'OrgP_DIP_decay', 'OrgP_Settling', 'use_OrgP']\n",
+ "DIPfromBed | ['depth', 'rpo4_tc']\n",
+ "TIP_Settling | ['vs', 'depth', 'fdp', 'TIP']\n",
+ "DIP_ApRespiration | ['rpa', 'ApRespiration', 'use_Algae']\n",
+ "DIP_ApGrowth | ['rpa', 'ApGrowth', 'use_Algae']\n",
+ "DIP_AbRespiration | ['rpb', 'AbRespiration', 'use_Balgae']\n",
+ "DIP_AbGrowth | ['rpb', 'AbGrowth', 'Fb', 'depth', 'use_Balgae']\n",
+ "dTIPdt | ['OrgP_DIP_decay', 'TIP_Settling', 'DIPfromBed', 'DIP_ApRespiration', 'DIP_ApGrowth', 'DIP_AbRespiration', 'DIP_AbGrowth', 'use_TIP']\n",
+ "TOP | ['use_OrgP', 'OrgP', 'use_Algae', 'rpa', 'Ap']\n",
+ "TP | ['use_TIP', 'TOP', 'TIP']\n",
+ "DIP | ['fdp', 'TIP']\n",
+ "kpom_tc | ['TwaterC', 'kpom_20']\n",
+ "POM_algal_settling | ['Ap', 'vsap', 'rda', 'depth', 'use_Algae']\n",
+ "POM_dissolution | ['POM', 'kpom_tc']\n",
+ "POM_POC_settling | ['POC', 'vsoc', 'depth', 'fcom', 'use_POC']\n",
+ "POM_benthic_algae_mortality | ['Ab', 'kdb_tc', 'Fb', 'Fw', 'depth', 'use_Balgae']\n",
+ "POM_burial | ['vb', 'POM', 'depth']\n",
+ "dPOMdt | ['POM_algal_settling', 'POM_dissolution', 'POM_POC_settling', 'POM_benthic_algae_mortality', 'POM_burial']\n",
+ "kbod_tc | ['TwaterC', 'kbod_20']\n",
+ "ksbod_tc | ['TwaterC', 'ksbod_20']\n",
+ "CBOD_oxidation | ['DOX', 'CBOD', 'kbod_tc', 'KsOxbod', 'use_DOX']\n",
+ "CBOD_sedimentation | ['CBOD', 'ksbod_tc']\n",
+ "dCBODdt | ['CBOD_oxidation', 'CBOD_sedimentation']\n",
+ "kpoc_tc | ['TwaterC', 'kpoc_20']\n",
+ "POC_settling | ['vsoc', 'depth', 'POC']\n",
+ "POC_hydrolysis | ['kpoc_tc', 'POC']\n",
+ "POC_algal_mortality | ['f_pocp', 'kdp_tc', 'rca', 'Ap', 'use_Algae']\n",
+ "POC_benthic_algae_mortality | ['depth', 'f_pocb', 'kdb_tc', 'rcb', 'Ab', 'Fb', 'Fw', 'use_Balgae']\n",
+ "dPOCdt | ['POC_settling', 'POC_hydrolysis', 'POC_algal_mortality', 'POC_benthic_algae_mortality']\n",
+ "kdoc_tc | ['TwaterC', 'kdoc_20']\n",
+ "DOC_algal_mortality | ['f_pocp', 'kdp_tc', 'rca', 'Ap', 'use_Algae']\n",
+ "DOC_benthic_algae_mortality | ['depth', 'f_pocb', 'kdb_tc', 'rcb', 'Ab', 'Fb', 'Fw', 'use_Balgae']\n",
+ "DOC_DIC_oxidation | ['DOX', 'KsOxmc', 'kdoc_tc', 'DOC', 'use_DOX']\n",
+ "dDOCdt | ['DOC_DIC_oxidation', 'POC_hydrolysis', 'DOC_algal_mortality', 'DOC_benthic_algae_mortality']\n",
+ "K_H | ['TwaterC']\n",
+ "Atm_CO2_reaeration | ['ka_tc', 'K_H', 'pCO2', 'FCO2', 'DIC']\n",
+ "DIC_algal_respiration | ['ApRespiration', 'rca', 'use_Algae']\n",
+ "DIC_algal_photosynthesis | ['ApGrowth', 'rca', 'use_Algae']\n",
+ "DIC_benthic_algae_respiration | ['AbRespiration', 'rcb', 'Fb', 'depth', 'use_Balgae']\n",
+ "DIC_benthic_algae_photosynthesis | ['AbGrowth', 'rcb', 'Fb', 'depth', 'use_Balgae']\n",
+ "DIC_CBOD_oxidation | ['DOX', 'CBOD', 'roc', 'kbod_tc', 'KsOxbod', 'use_DOX']\n",
+ "DIC_sed_release | ['SOD_tc', 'roc', 'depth']\n",
+ "dDICdt | ['Atm_CO2_reaeration', 'DIC_algal_respiration', 'DIC_algal_photosynthesis', 'DIC_benthic_algae_respiration', 'DIC_benthic_algae_photosynthesis', 'DIC_CBOD_oxidation', 'DIC_sed_release']\n",
+ "pwv | ['TwaterK']\n",
+ "DOs_atm_alpha | ['TwaterK']\n",
+ "DOX_ApGrowth | ['ApGrowth', 'rca', 'roc', 'ApUptakeFr_NH4', 'use_Algae']\n",
+ "DOX_ApRespiration | ['ApRespiration', 'rca', 'roc', 'use_Algae']\n",
+ "DOX_Nitrification | ['KNR', 'DOX', 'ron', 'knit_tc', 'NH4', 'use_NH4']\n",
+ "DOX_DOC_oxidation | ['DOC_DIC_oxidation', 'roc', 'use_DOC']\n",
+ "DOX_CBOD_oxidation | ['DIC_CBOD_oxidation', 'roc']\n",
+ "DOX_AbGrowth | ['AbUptakeFr_NH4', 'roc', 'rcb', 'AbGrowth', 'Fb', 'depth', 'use_Balgae']\n",
+ "DOX_AbRespiration | ['roc', 'rcb', 'AbRespiration', 'Fb', 'depth', 'use_Balgae']\n",
+ "DOX_SOD | ['depth', 'SOD_tc']\n",
+ "kdx_tc | ['TwaterC', 'kdx_20']\n",
+ "PathogenDeath | ['kdx_tc', 'PX']\n",
+ "PathogenDecay | ['apx', 'q_solar', 'L', 'depth', 'PX']\n",
+ "PathogenSettling | ['vx', 'depth', 'PX']\n",
+ "dPXdt | ['PathogenDeath', 'PathogenDecay', 'PathogenSettling']\n",
+ "Alk_denitrification | ['DOX', 'NO3', 'kdnit_tc', 'KsOxdn', 'r_alkden', 'use_NO3', 'use_DOX']\n",
+ "Alk_nitrification | ['DOX', 'NH4', 'knit_tc', 'KNR', 'r_alkn', 'use_NH4', 'use_DOX']\n",
+ "Alk_algal_growth | ['ApGrowth', 'r_alkaa', 'r_alkan', 'ApUptakeFr_NH4', 'use_Algae']\n",
+ "Alk_algal_respiration | ['ApRespiration', 'r_alkaa', 'use_Algae']\n",
+ "Alk_benthic_algae_growth | ['AbGrowth', 'depth', 'r_alkba', 'r_alkbn', 'AbUptakeFr_NH4', 'Fb', 'use_Balgae']\n",
+ "Alk_benthic_algae_respiration | ['AbRespiration', 'depth', 'r_alkba', 'Fb', 'use_Balgae']\n",
+ "dAlkdt | ['Alk_denitrification', 'Alk_nitrification', 'Alk_algal_growth', 'Alk_algal_respiration', 'Alk_benthic_algae_growth', 'Alk_benthic_algae_respiration']\n",
+ "KHN2_tc | ['TwaterK']\n",
+ "P_wv | ['TwaterK']\n",
+ "N2sat | ['KHN2_tc', 'pressure_atm', 'P_wv']\n",
+ "dN2dt | ['ka_tc', 'N2sat', 'N2']\n",
+ "Ap | ['Ap', 'dApdt', 'timestep']\n",
+ "Ab | ['Ab', 'dAbdt', 'timestep']\n",
+ "OrgN | ['OrgN', 'dOrgNdt', 'timestep']\n",
+ "N2 | ['N2', 'dN2dt', 'timestep']\n",
+ "TIP | ['TIP', 'dTIPdt', 'timestep']\n",
+ "OrgP | ['OrgP', 'dOrgPdt', 'timestep']\n",
+ "POC | ['POC', 'dPOCdt', 'timestep']\n",
+ "DOC | ['DOC', 'dDOCdt', 'timestep']\n",
+ "DIC | ['DIC', 'dDICdt', 'timestep']\n",
+ "POM | ['dPOMdt', 'POM', 'timestep']\n",
+ "CBOD | ['CBOD', 'dCBODdt', 'timestep']\n",
+ "PX | ['PX', 'dPXdt', 'timestep']\n",
+ "Alk | ['Alk', 'dAlkdt', 'timestep']\n",
+ "NH4_Nitrification | ['NitrificationInhibition', 'NH4', 'knit_tc', 'use_NH4']\n",
+ "dNH4dt | ['use_NH4', 'OrgN_NH4_Decay', 'NH4_Nitrification', 'NH4fromBed', 'NH4_ApRespiration', 'NH4_ApGrowth', 'NH4_AbRespiration', 'NH4_AbGrowth']\n",
+ "dNO3dt | ['use_NO3', 'NH4_Nitrification', 'NO3_Denit', 'NO3_BedDenit', 'NO3_ApGrowth', 'NO3_AbGrowth']\n",
+ "DOX_sat | ['TwaterK', 'pressure_atm', 'pwv', 'DOs_atm_alpha']\n",
+ "Atm_O2_reaeration | ['ka_tc', 'DOX_sat', 'DOX']\n",
+ "dDOXdt | ['Atm_O2_reaeration', 'DOX_ApGrowth', 'DOX_ApRespiration', 'DOX_Nitrification', 'DOX_DOC_oxidation', 'DOX_CBOD_oxidation', 'DOX_AbGrowth', 'DOX_AbRespiration', 'DOX_SOD']\n",
+ "TDG | ['N2', 'N2sat', 'DOX', 'DOX_sat', 'use_DOX']\n",
+ "NH4 | ['NH4', 'dNH4dt', 'timestep']\n",
+ "NO3 | ['NO3', 'dNO3dt', 'timestep']\n",
+ "DOX | ['DOX', 'dDOXdt', 'timestep']\n"
+ ]
+ }
+ ],
+ "source": [
+ "import clearwater_modules as cwm\n",
+ "import clearwater_modules.sorter as sorter\n",
+ "import numba\n",
+ "import random\n",
+ "import hvplot.xarray\n",
+ "import warnings\n",
+ "warnings.filterwarnings(\"ignore\")\n",
+ "from clearwater_modules.nsm1.model import NutrientBudget\n",
+ "\n",
+ "\n",
+ "\n",
+ "initial_state_values = {'Ap': 1,\n",
+ " 'Ab': 1,\n",
+ " 'NH4': 1,\n",
+ " 'NO3': 1,\n",
+ " 'OrgN': 1,\n",
+ " 'N2': 1,\n",
+ " 'TIP': 1,\n",
+ " 'OrgP': 1,\n",
+ " 'POC': 1,\n",
+ " 'DOC': 1,\n",
+ " 'DIC': 1,\n",
+ " 'POM': 1,\n",
+ " 'CBOD': 1,\n",
+ " 'DOX': 1,\n",
+ " 'PX': 1,\n",
+ " 'Alk': 1}\n",
+ "\n",
+ "algae_parameters = {\n",
+ " 'AWd': 100,\n",
+ " 'AWc': 40,\n",
+ " 'AWn': 7.2,\n",
+ " 'AWp': 1,\n",
+ " 'AWa': 1000,\n",
+ " 'KL': 10,\n",
+ " 'KsN': 0.04,\n",
+ " 'KsP': 0.0012,\n",
+ " 'mu_max_20': 1,\n",
+ " 'kdp_20': 0.15,\n",
+ " 'krp_20': 0.2,\n",
+ " 'vsap': 0.15,\n",
+ " 'growth_rate_option': 1,\n",
+ " 'light_limitation_option': 1,\n",
+ " 'lambda0': .5,\n",
+ " 'lambda1': .5,\n",
+ " 'lambda2': .5,\n",
+ " 'lambdas': .5,\n",
+ " 'lambdam': .5, \n",
+ " 'Fr_PAR': .5 \n",
+ "}\n",
+ "\n",
+ "balgae_parameters = {\n",
+ " 'BWd': 100,\n",
+ " 'BWc': 40,\n",
+ " 'BWn': 7.2,\n",
+ " 'BWp': 1,\n",
+ " 'BWa': 3500,\n",
+ "\n",
+ " 'KLb': 10,\n",
+ " 'KsNb': 0.25,\n",
+ " 'KsPb': 0.125,\n",
+ " 'Ksb': 10,\n",
+ " 'mub_max_20': 0.4,\n",
+ " 'krb_20': 0.2,\n",
+ " 'kdb_20': 0.3,\n",
+ " 'b_growth_rate_option': 1,\n",
+ " 'b_light_limitation_option': 1,\n",
+ " 'Fw': 0.9,\n",
+ " 'Fb': 0.9\n",
+ "}\n",
+ "\n",
+ "nitrogen_parameters = {\n",
+ " 'KNR': 0.6,\n",
+ " 'knit_20': 0.1,\n",
+ " 'kon_20': 0.1,\n",
+ " 'kdnit_20': 0.002,\n",
+ " 'rnh4_20': 0,\n",
+ " 'vno3_20': 0,\n",
+ " 'KsOxdn': 0.1,\n",
+ " 'PN': 0.5,\n",
+ " 'PNb': 0.5\n",
+ "}\n",
+ "\n",
+ "phosphorus_parameters = {\n",
+ " 'kop_20': 0.1,\n",
+ " 'rpo4_20': 0\n",
+ "}\n",
+ "\n",
+ "POM_parameters = {\n",
+ " 'kpom_20': 0.1\n",
+ "}\n",
+ "\n",
+ "CBOD_parameters = {\n",
+ " 'KsOxbod': 0.5,\n",
+ " 'kbod_20': 0.12,\n",
+ " 'ksbod_20': 0\n",
+ "}\n",
+ "\n",
+ "carbon_parameters = {\n",
+ " 'f_pocp': 0.9,\n",
+ " 'kdoc_20': 0.01,\n",
+ " 'f_pocb': 0.9,\n",
+ " 'kpoc_20': 0.005,\n",
+ " 'K_sOxmc': 1,\n",
+ " 'pCO2': 383,\n",
+ " 'FCO2': 0.2\n",
+ "}\n",
+ "\n",
+ "pathogen_parameters = {\n",
+ " 'kdx': 0.8,\n",
+ " 'apx': 1,\n",
+ " 'vx': 1\n",
+ "}\n",
+ "\n",
+ "alkalinity_parameters = {\n",
+ " 'r_alkaa': 1,\n",
+ " 'r_alkan': 1,\n",
+ " 'r_alkn': 1,\n",
+ " 'r_alkden': 1,\n",
+ " 'r_alkba': 1,\n",
+ " 'r_alkbn': 1 \n",
+ "}\n",
+ "\n",
+ "global_parameters = {\n",
+ " 'use_NH4': True,\n",
+ " 'use_NO3': True, \n",
+ " 'use_OrgN': True,\n",
+ " 'use_TIP': True, \n",
+ " 'use_SedFlux': False,\n",
+ " 'use_DOX': True,\n",
+ " 'use_Algae': True,\n",
+ " 'use_Balgae': True,\n",
+ " 'use_OrgP': True,\n",
+ " 'use_POC': True,\n",
+ " 'use_DOC': True,\n",
+ " 'use_DIC': True,\n",
+ " 'use_N2': True,\n",
+ " 'use_Pathogen': True,\n",
+ " 'use_Alk': True,\n",
+ " 'use_POM': True \n",
+ "}\n",
+ "\n",
+ "\n",
+ "global_vars = {\n",
+ " 'vson': 0.01,\n",
+ " 'vsoc': 0.01,\n",
+ " 'vsop': 999,\n",
+ " 'vs': 999,\n",
+ " 'SOD_20': 999,\n",
+ " 'SOD_theta': 999,\n",
+ " 'vb': 0.01,\n",
+ " 'fcom': 0.4,\n",
+ " 'kaw_20_user': 999,\n",
+ " 'kah_20_user': 999,\n",
+ " 'hydraulic_reaeration_option': 2,\n",
+ " 'wind_reaeration_option': 2, \n",
+ " 'timestep': 86400,\n",
+ " 'depth': 1,\n",
+ " 'TwaterC': 20,\n",
+ " 'theta': 1.047,\n",
+ " 'velocity': 1,\n",
+ " 'flow': 2,\n",
+ " 'topwidth': 1,\n",
+ " 'slope': 2,\n",
+ " 'shear_velocity': 4,\n",
+ " 'pressure_atm': 2,\n",
+ " 'wind_speed': 4,\n",
+ " 'q_solar': 4,\n",
+ " 'Solid': 1\n",
+ "}\n",
+ "\n",
+ "DOX_parameters = {}\n",
+ "N2_parameters = {}\n",
+ "\n",
+ "time_steps=1 \n",
+ "\n",
+ "nsm_model = NutrientBudget(\n",
+ " time_steps=time_steps,\n",
+ " initial_state_values=initial_state_values, # mandatory\n",
+ " algae_parameters=algae_parameters,\n",
+ " alkalinity_parameters=alkalinity_parameters,\n",
+ " balgae_parameters=balgae_parameters,\n",
+ " carbon_parameters=carbon_parameters,\n",
+ " CBOD_parameters=CBOD_parameters,\n",
+ " DOX_parameters=DOX_parameters,\n",
+ " nitrogen_parameters=nitrogen_parameters,\n",
+ " POM_parameters=POM_parameters,\n",
+ " N2_parameters=N2_parameters,\n",
+ " phosphorus_parameters=phosphorus_parameters,\n",
+ " pathogen_parameters=pathogen_parameters,\n",
+ " global_parameters=global_parameters,\n",
+ " global_vars=global_vars, \n",
+ " track_dynamic_variables=True, # default is true\n",
+ " hotstart_dataset=None, # default is None\n",
+ " time_dim='year', # default is \"timestep\"\n",
+ ")\n",
+ "\n",
+ "print(nsm_model.dynamic_variables_names)\n",
+ "\n",
+ "nsm_model.increment_timestep()\n",
+ "nsm_model.dataset\n",
+ "\n",
+ "print('Variable | Inputs\\n------------------')\n",
+ "for i in nsm_model.computation_order:\n",
+ " print(f'{i.name} | {sorter.get_process_args(i.process)}')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "32673258",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "C:\\Users\\l2edeknw\\Documents\\Projects\\ToddERDC\\ClearWater-modules\\src\\clearwater_modules\\nsm1\\processes.py:3454: RuntimeWarning: divide by zero encountered in divide\n",
+ " return xr.where(use_DOX,(79.0 * N2 / N2sat) + (21.0 * DOX / DOX_sat), N2/N2sat)\n"
]
},
{
@@ -450,227 +1004,395 @@
" stroke: currentColor;\n",
" fill: currentColor;\n",
"}\n",
- "<xarray.Dataset>\n",
- "Dimensions: (year: 1, x: 1, y: 1)\n",
- "Coordinates:\n",
- " * year (year) int32 0\n",
- " * x (x) float64 1.0\n",
- " * y (y) float64 1.0\n",
- "Data variables:\n",
- " *empty*
"
- ],
- "text/plain": [
- "\n",
- "Dimensions: (year: 1, x: 1, y: 1)\n",
+ "<xarray.Dataset> Size: 3kB\n",
+ "Dimensions: (year: 2, x: 1, y: 1)\n",
"Coordinates:\n",
- " * year (year) int32 0\n",
- " * x (x) float64 1.0\n",
- " * y (y) float64 1.0\n",
- "Data variables:\n",
- " *empty*"
+ " * year (year) int32 8B 0 1\n",
+ " * x (x) float64 8B 1.0\n",
+ " * y (y) float64 8B 1.0\n",
+ "Data variables: (12/281)\n",
+ " Ap (year, x, y) float64 16B 1.0 -3.05e+04\n",
+ " Ab (year, x, y) float64 16B 1.0 -3.967e+04\n",
+ " NH4 (year, x, y) float64 16B 1.0 5.951e+03\n",
+ " NO3 (year, x, y) float64 16B 1.0 3.724e+03\n",
+ " OrgN (year, x, y) float64 16B 1.0 -7.898e+03\n",
+ " N2 (year, x, y) float64 16B 1.0 2.191e+07\n",
+ " ... ...\n",
+ " dAlkdt (year, x, y) float64 16B nan 0.3351\n",
+ " KHN2_tc (year, x, y) float64 16B nan 0.0007001\n",
+ " P_wv (year, x, y) float64 16B nan 0.02309\n",
+ " N2sat (year, x, y) float64 16B nan 30.61\n",
+ " dN2dt (year, x, y) float64 16B nan 253.6\n",
+ " TDG (year, x, y) float64 16B nan inf
Ap
(year, x, y)
float64
1.0 -3.05e+04
- long_name :
- Algae Concentration
- units :
- ug-Chla/L
- description :
- Algal Concentration
array([[[ 1.00000000e+00]],\n",
+ "\n",
+ " [[-3.05018421e+04]]])
Ab
(year, x, y)
float64
1.0 -3.967e+04
- long_name :
- Benthic Algae Concentration
- units :
- g-D/m^2
- description :
- Benthic Algae Concentration
array([[[ 1.00000000e+00]],\n",
+ "\n",
+ " [[-3.96704364e+04]]])
NH4
(year, x, y)
float64
1.0 5.951e+03
- long_name :
- Ammonium Concentration
- units :
- mg-N/L
- description :
- Ammonium Concentration
array([[[1.00000000e+00]],\n",
+ "\n",
+ " [[5.95127331e+03]]])
NO3
(year, x, y)
float64
1.0 3.724e+03
- long_name :
- Nitrate Concentration
- units :
- mg-N/L
- description :
- Nitrate Concentration
array([[[1.00000000e+00]],\n",
+ "\n",
+ " [[3.72352315e+03]]])
OrgN
(year, x, y)
float64
1.0 -7.898e+03
- long_name :
- Organic Nitrogen Concentration
- units :
- mg-N/L
- description :
- Organic Nitrogen Concentration
array([[[ 1.0000000e+00]],\n",
+ "\n",
+ " [[-7.8980336e+03]]])
N2
(year, x, y)
float64
1.0 2.191e+07
- long_name :
- Nitrogen concentration air
- units :
- mg-N/L
- description :
- Nitrogen concentration air
array([[[1.00000000e+00]],\n",
+ "\n",
+ " [[2.19067976e+07]]])
TIP
(year, x, y)
float64
1.0 8.787e+03
- long_name :
- Total Inorganic Phosphorus
- units :
- mg-P/L
- description :
- Total Inorganic Phosphorus Concentration
array([[[1.00000000e+00]],\n",
+ "\n",
+ " [[8.78662577e+03]]])
OrgP
(year, x, y)
float64
1.0 -8.632e+07
- long_name :
- Total Organic Phosphorus
- units :
- mg-P/L
- description :
- Total Organic Phosphorus Concentration
array([[[ 1.00000000e+00]],\n",
+ "\n",
+ " [[-8.63220161e+07]]])
POC
(year, x, y)
float64
1.0 6.73e+03
- long_name :
- Particulate Organic Carbon
- units :
- mg-C/L
- description :
- Particulate Organic Carbon Concentration
array([[[1.000000e+00]],\n",
+ "\n",
+ " [[6.729832e+03]]])
DOC
(year, x, y)
float64
1.0 892.6
- long_name :
- Dissolved Organic Carbon
- units :
- mg-C/L
- description :
- Dissolved Organic Carbon Concentration
array([[[ 1. ]],\n",
+ "\n",
+ " [[892.648]]])
DIC
(year, x, y)
float64
1.0 -1.701e+09
- long_name :
- Dissolved Inorganic Carbon
- units :
- mg-C/L
- description :
- Dissolved Inorganic Carbon Concentration
array([[[ 1.00000000e+00]],\n",
+ "\n",
+ " [[-1.70069724e+09]]])
POM
(year, x, y)
float64
1.0 -3.714e+03
- long_name :
- Particulate Organic Matter
- units :
- mg-D/L
- description :
- Particulate Organic Matter Concentration
array([[[ 1.0000e+00]],\n",
+ "\n",
+ " [[-3.7142e+03]]])
CBOD
(year, x, y)
float64
1.0 -6.911e+03
- long_name :
- Carbonaceous Biochemical Oxygen Demand
- units :
- mg-O2/L
- description :
- Carbonaceous Biochemical Oxygen Demand Concentration
array([[[ 1.000e+00]],\n",
+ "\n",
+ " [[-6.911e+03]]])
DOX
(year, x, y)
float64
1.0 -4.391e+07
- long_name :
- Dissolved Oxygen
- units :
- mg-O2/L
- description :
- Dissolved Oxygen
array([[[ 1.00000000e+00]],\n",
+ "\n",
+ " [[-4.39110823e+07]]])
PX
(year, x, y)
float64
1.0 -4.802e+05
- long_name :
- Pathogen
- units :
- cfu/100mL
- description :
- Pathogen concentration
array([[[ 1.00000000e+00]],\n",
+ "\n",
+ " [[-4.80184883e+05]]])
Alk
(year, x, y)
float64
1.0 2.895e+04
- long_name :
- Alkalinity
- units :
- mg-CaCO3/L
- description :
- Alkalinity concentration
array([[[1.00000000e+00]],\n",
+ "\n",
+ " [[2.89504416e+04]]])
vson
(x, y)
float64
0.01
- long_name :
- Organic N settling velocity
- units :
- m/d
- description :
- Organic N settling velocity
vsoc
(x, y)
float64
0.01
- long_name :
- POC settling velocity
- units :
- m/d
- description :
- POC settling velocity
vsop
(x, y)
int32
999
- long_name :
- Organic phosphorus settling velocity
- units :
- m/d
- description :
- Organic phosphorus settling velocity
vs
(x, y)
int32
999
- long_name :
- Sediment settling velocity
- units :
- m/d
- description :
- Sediment settling velocity
SOD_20
(x, y)
int32
999
- long_name :
- Sediment oxygen demand at 20 degrees C
- units :
- g-O2/m/d
- description :
- Sediment oxygen demand at 20 degrees C
SOD_theta
(x, y)
int32
999
- long_name :
- Arrhenius coefficient for sediment oxygen demand
- units :
- unitless
- description :
- Arrhenius coefficient for sediment oxygen demand
fcom
(x, y)
float64
0.4
- long_name :
- Fraction of carbon in organic matter
- units :
- mg-C/mg-D
- description :
- Fraction of carbon in organic matter
vb
(x, y)
float64
0.01
- long_name :
- Burial velocity
- units :
- m/d
- description :
- Rate at which constituents are buried on the bottom
kaw_20_user
(x, y)
int32
999
- long_name :
- Wind oxygen reaeration velocity at 20C
- units :
- m/d
- description :
- Wind oxygen reaeration velocity at 20C
kah_20_user
(x, y)
int32
999
- long_name :
- Hydraulic oxygen reaeration rate at 20C
- units :
- 1/d
- description :
- Hydraulic oxygen reaeration rate at 20C
hydraulic_reaeration_option
(x, y)
int32
2
- long_name :
- Option for chosing the method by which O2 reaeration rate is calculated
- units :
- unitless
- description :
- Selects method for computing O2 reaeration rate
wind_reaeration_option
(x, y)
int32
2
- long_name :
- Option for chosing the method by which wind reaeration is calculated
- units :
- unitless
- description :
- Selects method for computing O2 reaeration due to wind
use_NH4
(x, y)
bool
True
- long_name :
- Use ammonium module
- units :
- unitless
- description :
- True/False use ammonium module
use_NO3
(x, y)
bool
True
- long_name :
- Use nitrate module
- units :
- unitless
- description :
- True/False use nitrate module
use_OrgN
(x, y)
bool
True
- long_name :
- Use organic nitrogen module
- units :
- unitless
- description :
- True/False use organic nitrogen module
use_SedFlux
(x, y)
bool
False
- long_name :
- Use sediment flux module
- units :
- unitless
- description :
- True/False use sediment flux module
use_DOX
(x, y)
bool
True
- long_name :
- Use dissolved oxygen module
- units :
- unitless
- description :
- True/False use dissolved oxygen module
use_Algae
(x, y)
bool
True
- long_name :
- Use algae module
- units :
- unitless
- description :
- True/False use algae module
use_Balgae
(x, y)
bool
True
- long_name :
- Use benthic algae module
- units :
- unitless
- description :
- True/False use benthic algae module
use_TIP
(x, y)
bool
True
- long_name :
- Use total inorganic phosphorus module
- units :
- unitless
- description :
- True/False use total inorganic phosphorus module
use_OrgP
(x, y)
bool
True
- long_name :
- Use total organic phosphorus module
- units :
- unitless
- description :
- True/False use total organic phosphorus module
use_POC
(x, y)
bool
True
- long_name :
- Use particulate organic carbon module
- units :
- unitless
- description :
- True/False use particulate organic carbon module
use_DOC
(x, y)
bool
True
- long_name :
- Use dissolved organic carbon module
- units :
- unitless
- description :
- True/False use dissolved organic carbon module
use_DIC
(x, y)
bool
True
- long_name :
- Use dissolved inorganic carbon module
- units :
- unitless
- description :
- True/False use dissolved inorganic carbon module
use_N2
(x, y)
bool
True
- long_name :
- Use dissolved N2 module
- units :
- unitless
- description :
- True/False use N2 module
use_Pathogen
(x, y)
bool
True
- long_name :
- Use pathogen module
- units :
- unitless
- description :
- True/False use pathogen module
use_Alk
(x, y)
bool
True
- long_name :
- Use alkalinity module
- units :
- unitless
- description :
- True/False use alkalinity module
use_POM
(x, y)
bool
True
- long_name :
- Use particulate organic matter module
- units :
- unitless
- description :
- True/False use particulate organic matter module
timestep
(x, y)
int32
86400
- long_name :
- timestep
- units :
- d
- description :
- calculation timestep
depth
(x, y)
int32
1
- long_name :
- Depth of water in cell
- units :
- m
- description :
- Depth of water in cell
TwaterC
(x, y)
int32
20
- long_name :
- Water temperature in celsius
- units :
- degrees C
- description :
- Water temperature in celsius
theta
(x, y)
float64
1.047
- long_name :
- Water temperature theta adjustment factor
- units :
- unitless
- description :
- Water temperature theta adjustment factor
velocity
(x, y)
int32
1
- long_name :
- velocity
- units :
- m/s
- description :
- Average water velocity in cell
flow
(x, y)
int32
2
- long_name :
- flow
- units :
- m3/s
- description :
- Average flow rate in cell
topwidth
(x, y)
int32
1
- long_name :
- topwidth
- units :
- m
- description :
- Average topwidth of cell
slope
(x, y)
int32
2
- long_name :
- slope
- units :
- TODO
- description :
- Average slope of bottom surface
shear_velocity
(x, y)
int32
4
- long_name :
- shear_velocity
- units :
- TODO
- description :
- Average shear velocity on bottom surface
pressure_atm
(x, y)
int32
2
- long_name :
- pressure_atm
- units :
- TODO
- description :
- atmospheric pressure in atm
wind_speed
(x, y)
int32
4
- long_name :
- Wind speed at 10 meters above the water surface
- units :
- m/s
- description :
- Wind speed at 10 meters above the water surface
q_solar
(x, y)
int32
4
- long_name :
- Incident short-wave solar radiation
- units :
- W/m2
- description :
- Incident short-wave solar radiation
Solid
(x, y)
int32
1
- long_name :
- Solid reaeration option
- units :
- Unknown
- description :
- Solid
AWd
(x, y)
int32
100
- long_name :
- Algal Dry Weight
- units :
- mg
- description :
- Algal Dry Weight
AWc
(x, y)
int32
40
- long_name :
- Carbon Weight
- units :
- mg
- description :
- Carbon Weight
AWn
(x, y)
float64
7.2
- long_name :
- Nitrogen Weight
- units :
- mg
- description :
- Nitrogen Weight
AWp
(x, y)
int32
1
- long_name :
- Phosphorus Weight
- units :
- mg
- description :
- Phosphorus Weight
AWa
(x, y)
int32
1000
- long_name :
- Algal Chlorophyll
- units :
- ug Chla
- description :
- Algal Chlorophyll
KL
(x, y)
int32
10
- long_name :
- Light Limiting Constant for Algal Growth
- units :
- W/m^2
- description :
- Light Limiting Constant for Algal Growth
KsN
(x, y)
float64
0.04
- long_name :
- Half-Saturation N Limiting Constant for Algal Growth
- units :
- mg-N/L
- description :
- Half-Saturation N Limiting Constant for Algal Growth
KsP
(x, y)
float64
0.0012
- long_name :
- Half-Saturation P Limiting Constant for Algal Growth
- units :
- mg-P/L
- description :
- Half-Saturation P Limiting Constant for Algal Growth
mu_max_20
(x, y)
int32
1
- long_name :
- Max Algae Growth
- units :
- 1/d
- description :
- Max Algae Growth at 20C
kdp_20
(x, y)
float64
0.15
- long_name :
- Algal Mortality Rate
- units :
- 1/d
- description :
- Algal Mortality Rate at 20C
krp_20
(x, y)
float64
0.2
- long_name :
- Algal Respiration Rate
- units :
- 1/d
- description :
- Algal Respiration Rate at 20C
vsap
(x, y)
float64
0.15
- long_name :
- Algal Setting Velocity
- units :
- m/d
- description :
- Algal Setting Velocity
growth_rate_option
(x, y)
int32
1
- long_name :
- Growth Rate Option
- units :
- 1/d
- description :
- Algal growth rate option 1) multiplicative, 2) Limiting Nutrient, 3) Harmonic Mean Option
light_limitation_option
(x, y)
int32
1
- long_name :
- Light Limitation Option
- units :
- 1/d
- description :
- Algal light limitation 1) half-saturation, 2) Smith model, 3) Steele model
lambda0
(x, y)
float64
0.02
- long_name :
- lambda0
- units :
- 1/m
- description :
- background portion
lambda1
(x, y)
float64
0.0088
- long_name :
- lambda1
- units :
- 1/m/(ug Chla/L)
- description :
- linear self shading
lambda2
(x, y)
float64
0.054
- long_name :
- lambda2
- units :
- unitless
- description :
- nonlinear
lambdas
(x, y)
float64
0.052
- long_name :
- lambdas
- units :
- L/mg/m
- description :
- ISS portion
lambdam
(x, y)
float64
0.0174
- long_name :
- lambdam
- units :
- L/mg/m
- description :
- POM portion
Fr_PAR
(x, y)
float64
0.47
- long_name :
- fraction PAR
- units :
- unitless
- description :
- fraction of solar radiation within the PAR of the spectrum
Fw
(x, y)
float64
0.9
- long_name :
- Fraction of benthic algae mortality into water column
- units :
- unitless
- description :
- Fraction of benthic algae mortality into water column
Fb
(x, y)
float64
0.9
- long_name :
- Fraction of bottom area available for benthic algae
- units :
- unitless
- description :
- Fraction of bottom area available for benthic algae
BWd
(x, y)
int32
100
- long_name :
- Benthic algae dry weight
- units :
- unitless
- description :
- Benthic algae dry weight
BWc
(x, y)
int32
40
- long_name :
- Benthic algae carbon
- units :
- unitless
- description :
- Benthic algae carbon
BWn
(x, y)
float64
7.2
- long_name :
- Benthic algae nitrogen
- units :
- unitless
- description :
- Benthic algae nitrogen
BWp
(x, y)
int32
1
- long_name :
- Benthic algae phosphorus
- units :
- unitless
- description :
- Benthic algae phosphorus
BWa
(x, y)
int32
3500
- long_name :
- Benthic algae Chla
- units :
- unitless
- description :
- Benthic algae Chla
KLb
(x, y)
int32
10
- long_name :
- Light limiting constant for benthic algae growth
- units :
- W/m^2
- description :
- Light limiting constant for benthic algae growth
KsNb
(x, y)
float64
0.25
- long_name :
- Half-Saturation N limiting constant for Benthic algae
- units :
- mg-N/L
- description :
- Half-Saturation N limiting constant for Benthic algae
KsPb
(x, y)
float64
0.125
- long_name :
- Half-Saturation P limiting constant for Benthic algae
- units :
- mg-P/L
- description :
- Half-Saturation P limiting constant for Benthic algae
Ksb
(x, y)
int32
10
- long_name :
- Half-Saturation density constant for benthic algae growth
- units :
- g-D/m^2
- description :
- Half-Saturation density constant for benthic algae growth
mub_max_20
(x, y)
float64
0.4
- long_name :
- Maximum benthic algal growth rate
- units :
- 1/d
- description :
- maximum benthic algal growth rate
krb_20
(x, y)
float64
0.2
- long_name :
- Benthic algal respiration rate
- units :
- 1/d
- description :
- Benthic algal respiration rate
kdb_20
(x, y)
float64
0.3
- long_name :
- Benthic algal mortality rate
- units :
- 1/d
- description :
- Benthic algal mortality rate
b_growth_rate_option
(x, y)
int32
1
- long_name :
- Benthic Algal growth rate options
- units :
- unitless
- description :
- Benthic Algal growth rate with two options: 1) Multiplicative, 2) Limiting Nutritent
b_light_limitation_option
(x, y)
int32
1
- long_name :
- Benthic Algal light limitation rate options
- units :
- unitless
- description :
- Benthic Algal light limitation rate with three options: 1) Half-saturation formulation, 2) Smiths Model, 3) Steeles Model
KNR
(x, y)
float64
0.6
- long_name :
- Oxygen inhabitation factor for nitrification
- units :
- mg-O2/L
- description :
- Oxygen inhabitation factor for nitrification
knit_20
(x, y)
float64
0.1
- long_name :
- Nitrification Rate Ammonia decay at 20C
- units :
- 1/d
- description :
- Nitrification Rate Ammonia NH4 -> NO3 decay at 20C
kon_20
(x, y)
float64
0.1
- long_name :
- Decay Rate of OrgN to NH4 at 20C
- units :
- 1/d
- description :
- Decay Rate of OrgN to NH4 at 20C
kdnit_20
(x, y)
float64
0.002
- long_name :
- Denitrification rate at 20C
- units :
- 1/d
- description :
- Denitrification rate at 20C
rnh4_20
(x, y)
int32
0
- long_name :
- Sediment release rate of NH4 at 20C
- units :
- g-N/m^2/d
- description :
- Sediment release rate of NH4 at 20C
vno3_20
(x, y)
int32
0
- long_name :
- Sediment denitrification velocity at 20C
- units :
- m/d
- description :
- Sediment denitrification velocity at 20C
KsOxdn
(x, y)
float64
0.1
- long_name :
- Half-saturation oxygen inhibition constant for denitrification
- units :
- mg-O2/L
- description :
- Half-saturation oxygen inhibition constant for denitrification
PN
(x, y)
float64
0.5
- long_name :
- NH4 preference factor algae
- units :
- unitless
- description :
- NH4 preference factor algae (1=full NH4, 0=full NO3)
PNb
(x, y)
float64
0.5
- long_name :
- NH4 preference factor benthic algae
- units :
- unitless
- description :
- NH4 preference factor benthic algae (1=full NH4, 0=full NO3)
kop_20
(x, y)
float64
0.1
- long_name :
- Decay rate of organic P to DIP
- units :
- 1/d
- description :
- Decay rate of organic P to DIP
rpo4_20
(x, y)
int32
0
- long_name :
- Benthic sediment release rate of DIP
- units :
- g-P/m^2/d
- description :
- Benthic sediment release rate of DIP
kdpo4
(x, y)
float64
0.0
- long_name :
- solid partitioning coeff. of PO4
- units :
- L/kg
- description :
- solid partitioning coeff. of PO4
kpom_20
(x, y)
float64
0.1
- long_name :
- POM dissolution rate at 20C
- units :
- 1/d
- description :
- POM dissolution rate at 20C
kbod_20
(x, y)
float64
0.12
- long_name :
- CBOD oxidation rate at 20C
- units :
- 1/d
- description :
- CBOD oxidation rate at 20C
ksbod_20
(x, y)
int32
0
- long_name :
- CBOD sedimentation rate at 20C
- units :
- m/d
- description :
- CBOD sedimentation rate at 20C
KsOxbod
(x, y)
float64
0.5
- long_name :
- Half saturation oxygen attenuation constant for CBOD oxidation
- units :
- mg-O2/L
- description :
- Half saturation oxygen attenuation constant for CBOD oxidation
f_pocp
(x, y)
float64
0.9
- long_name :
- Fraction of algal mortality into POC
- units :
- unitless
- description :
- Fraction of dead algae that converts to particulate organic carbon
kdoc_20
(x, y)
float64
0.01
- long_name :
- Dissolved organic carbon oxidation rate
- units :
- 1/d
- description :
- Dissolved organic carbon oxidation rate
f_pocb
(x, y)
float64
0.9
- long_name :
- fraction of benthic algal mortality into POC
- units :
- unitless
- description :
- fraction of benthic algal mortality into POC
kpoc_20
(x, y)
float64
0.005
- long_name :
- POC hydrolysis rate at 20 degrees Celsius
- units :
- 1/d
- description :
- POC hydrolysis rate at 20 degrees Celsius
KsOxmc
(x, y)
float64
1.0
- long_name :
- half saturation oxygen attenuation constant for DOC oxidation rate
- units :
- mg-O2/L
- description :
- half saturation oxygen attenuation constant for DOC oxidation rate
pCO2
(x, y)
int32
383
- long_name :
- partial atmospheric CO2 pressure
- units :
- ppm
- description :
- partial pressure of CO2 in the atmosphere
FCO2
(x, y)
float64
0.2
- long_name :
- CO2 reaeration rate
- units :
- 1/d
- description :
- CO2 reaeration rate
roc
(x, y)
float64
2.667
- long_name :
- O2:C ratio for carbon oxidation
- units :
- mg-O2/mg-C
- description :
- O2:C ratio for carbon oxidation (32/12)
ron
(x, y)
float64
4.571
- long_name :
- O2:N ratio for nitrification
- units :
- mg-O2/mg-N
- description :
- O2:N ratio for nitrification (2*32/14)
KsSOD
(x, y)
int32
1
- long_name :
- half saturation oxygen attenuation constant for SOD
- units :
- mg/L
- description :
- half saturation oxygen attenuation constant for SOD
kdx_20
(x, y)
float64
0.8
- long_name :
- Pathogen death rate at 20C
- units :
- 1/d
- description :
- Pathogen death rate at 20C
apx
(x, y)
int32
1
- long_name :
- Light efficiency factor for pathogen decay
- units :
- unitless
- description :
- Light efficiency factor for pathogen decay
vx
(x, y)
int32
1
- long_name :
- Pathogen net settling velocity
- units :
- unitless
- description :
- Pathogen net settling velocity
r_alkaa
(x, y)
int32
1
- long_name :
- Ratio translating algal growth into Alk if NH4 is the N source
- units :
- eq/ug-Chla
- description :
- Ratio translating algal growth into Alk if NH4 is the N source
r_alkan
(x, y)
int32
1
- long_name :
- Ratio translating algal growth into Alk if NO3 is the N source
- units :
- eq/ug-Chla
- description :
- Ratio translating algal growth into Alk if NO3 is the N source
r_alkn
(x, y)
int32
1
- long_name :
- Ratio translating NH4 nitrification into Alk
- units :
- eq/mg-N
- description :
- Ratio translating NH4 nitrification into Alk
r_alkden
(x, y)
int32
1
- long_name :
- Ratio translating NO3 denitrification into Alk
- units :
- eq/mg-N
- description :
- Ratio translating NO3 denitrification into Alk
r_alkba
(x, y)
int32
1
- long_name :
- Ratio translating benthic algae growth into Alk if NH4 is the N source
- units :
- eq/mg-D
- description :
- Ratio translating benthic algae growth into Alk if NH4 is the N source
r_alkbn
(x, y)
int32
1
- long_name :
- Ratio translating benthic algae growth into Alk if NO3 is the N source
- units :
- eq/mg-D
- description :
- Ratio translating benthic algae growth into Alk if NO3 is the N source
TwaterK
(year, x, y)
float64
nan 293.2
- long_name :
- Water Temperature K
- units :
- K
- description :
- Water temperature degree kelvin
array([[[ nan]],\n",
+ "\n",
+ " [[293.16]]])
SOD_tc
(year, x, y)
float64
nan 499.5
- long_name :
- Sediment Oxygen Demand at water temperature tc
- units :
- mg/L
- description :
- Sediment Oxygen Demand at water temperature tc
array([[[ nan]],\n",
+ "\n",
+ " [[499.5]]])
kah_20
(year, x, y)
float64
nan 3.93
- long_name :
- Hydraulic oxygen reaeration rate adjusted for hydraulics
- units :
- 1/d
- description :
- Hydraulic oxygen reaeration rate adjusted for hydraulic parameters according to XX lit
array([[[ nan]],\n",
+ "\n",
+ " [[3.93]]])
kah_tc
(year, x, y)
float64
nan 3.93
- long_name :
- Hydraulic oxygen reaeration rate adjusted for temperature
- units :
- 1/d
- description :
- Hydraulic oxygen reaeration rate adjusted for temperature
array([[[ nan]],\n",
+ "\n",
+ " [[3.93]]])
kaw_20
(year, x, y)
float64
nan 4.35
- long_name :
- Wind oxygen reaeration velocity adjusted for hydraulics
- units :
- m/d
- description :
- Wind oxygen reaeration velocity adjusted for hydraulic parameters according to XX lit
array([[[ nan]],\n",
+ "\n",
+ " [[4.35037249]]])
kaw_tc
(year, x, y)
float64
nan 4.35
- long_name :
- Wind oxygen reaeration velocity adjusted for temperature
- units :
- m/d
- description :
- Wind oxygen reaeration velocity adjusted for temperature
array([[[ nan]],\n",
+ "\n",
+ " [[4.35037249]]])
ka_tc
(year, x, y)
float64
nan 8.28
- long_name :
- Oxygen reaeration rate
- units :
- 1/d
- description :
- Oxygen reaeration rate
array([[[ nan]],\n",
+ "\n",
+ " [[8.28037249]]])
L
(year, x, y)
float64
nan 0.1263
- long_name :
- Light attenuation coefficient
- units :
- unitless
- description :
- Light attenuation coefficient
array([[[ nan]],\n",
+ "\n",
+ " [[0.1263]]])
PAR
(year, x, y)
float64
nan 1.88
- long_name :
- surface light intensity
- units :
- W/m2
- description :
- surface light intensity
array([[[ nan]],\n",
+ "\n",
+ " [[1.88]]])
fdp
(year, x, y)
float64
nan 1.0
- long_name :
- Fraction phosphorus dissolved
- units :
- Unitless
- description :
- Fraction phosphorus dissolved
array([[[nan]],\n",
+ "\n",
+ " [[ 1.]]])
rna
(year, x, y)
float64
nan 0.0072
- long_name :
- Algal N:Chla Ratio
- units :
- mg-N/ug Chla
- description :
- Algal N:Chla Ratio
array([[[ nan]],\n",
+ "\n",
+ " [[0.0072]]])
rpa
(year, x, y)
float64
nan 0.001
- long_name :
- Algal P:Chla Ratio
- units :
- mg-P/ug Chla
- description :
- Algal P:Chla Ratio
array([[[ nan]],\n",
+ "\n",
+ " [[0.001]]])
rca
(year, x, y)
float64
nan 0.04
- long_name :
- Algal C:Chla Ratio
- units :
- mg-C/ug Chla
- description :
- Algal C:Chla Ratio
array([[[ nan]],\n",
+ "\n",
+ " [[0.04]]])
rda
(year, x, y)
float64
nan 0.1
- long_name :
- Algal D:Chla Ratio
- units :
- mg-D/ug Chla
- description :
- Algal D:Chla Ratio
array([[[nan]],\n",
+ "\n",
+ " [[0.1]]])
mu_max_tc
(year, x, y)
float64
nan 1.0
- long_name :
- Max Algae Growth with Temperature Correction
- units :
- 1/d
- description :
- Max Algae Growth with Temperature Correction
array([[[nan]],\n",
+ "\n",
+ " [[ 1.]]])
krp_tc
(year, x, y)
float64
nan 0.2
- long_name :
- Algal Respiration Rate with Temperature Correction
- units :
- 1/d
- description :
- Algal Respiration Rate with Temperature Correction
array([[[nan]],\n",
+ "\n",
+ " [[0.2]]])
kdp_tc
(year, x, y)
float64
nan 0.15
- long_name :
- Algal Mortality Rate with Temperature Correction
- units :
- 1/d
- description :
- Algal Mortality Rate with Temperature Correction
array([[[ nan]],\n",
+ "\n",
+ " [[0.15]]])
FL
(year, x, y)
float64
nan 0.1501
- long_name :
- Algal Light Limitation
- units :
- unitless
- description :
- Algal Light Limitation
array([[[ nan]],\n",
+ "\n",
+ " [[0.15007688]]])
FN
(year, x, y)
float64
nan 0.9804
- long_name :
- Algal Nitrogen Limitation
- units :
- unitless
- description :
- Algal Nitrogen Limitation
array([[[ nan]],\n",
+ "\n",
+ " [[0.98039216]]])
FP
(year, x, y)
float64
nan 0.9988
- long_name :
- Algal Phosphorus Limitation
- units :
- unitless
- description :
- Algal Phosphorus Limitation
array([[[ nan]],\n",
+ "\n",
+ " [[0.99880144]]])
mu
(year, x, y)
float64
nan 0.147
- long_name :
- Algal Growth Rate
- units :
- 1/d
- description :
- Algal Growth Rate
array([[[ nan]],\n",
+ "\n",
+ " [[0.14695785]]])
ApGrowth
(year, x, y)
float64
nan 0.147
- long_name :
- Algal Growth
- units :
- ug-Chala/L/d
- description :
- Algal Growth
array([[[ nan]],\n",
+ "\n",
+ " [[0.14695785]]])
ApRespiration
(year, x, y)
float64
nan 0.2
- long_name :
- Algal Respiration
- units :
- ug-Chala/L/d
- description :
- Algal Respiration
array([[[nan]],\n",
+ "\n",
+ " [[0.2]]])
ApDeath
(year, x, y)
float64
nan 0.15
- long_name :
- Algal Death
- units :
- ug-Chala/L/d
- description :
- Algal Death
array([[[ nan]],\n",
+ "\n",
+ " [[0.15]]])
ApSettling
(year, x, y)
float64
nan 0.15
- long_name :
- Algal Settling
- units :
- ug-Chala/L/d
- description :
- Algal Settling
array([[[ nan]],\n",
+ "\n",
+ " [[0.15]]])
dApdt
(year, x, y)
float64
nan -0.353
- long_name :
- Algal Biomass Concentration Change
- units :
- ug-Chala/L/d
- description :
- Algal Biomass Concentration Change
array([[[ nan]],\n",
+ "\n",
+ " [[-0.35304215]]])
mub_max_tc
(year, x, y)
float64
nan 0.4
- long_name :
- Maximum benthic algal growth rate
- units :
- 1/d
- description :
- Maximum benthic algal growth rate with temperature correction
array([[[nan]],\n",
+ "\n",
+ " [[0.4]]])
krb_tc
(year, x, y)
float64
nan 0.2
- long_name :
- Benthic algae respiration rate
- units :
- 1/d
- description :
- Benthic algae respiration rate with temperature correction
array([[[nan]],\n",
+ "\n",
+ " [[0.2]]])
kdb_tc
(year, x, y)
float64
nan 0.3
- long_name :
- Benthic algae mortality rate
- units :
- 1/d
- description :
- Benthic algae mortality rate with temperature correction
array([[[nan]],\n",
+ "\n",
+ " [[0.3]]])
rnb
(year, x, y)
float64
nan 0.072
- long_name :
- Ratio nitrogen to dry weight
- units :
- mg-N/mg-D
- description :
- Ratio benthic algae nitrogen to dry weight
array([[[ nan]],\n",
+ "\n",
+ " [[0.072]]])
rpb
(year, x, y)
float64
nan 0.01
- long_name :
- Ratio benthic algae phosphorus to dry weight
- units :
- mg-P/mg-D
- description :
- Ratio benthic algae phosphorus to dry weight
array([[[ nan]],\n",
+ "\n",
+ " [[0.01]]])
rcb
(year, x, y)
float64
nan 0.4
- long_name :
- Ratio benthic algae carbon to dry weight
- units :
- mg-C/mg-D
- description :
- Ratio benthic algae carbon to dry weight
array([[[nan]],\n",
+ "\n",
+ " [[0.4]]])
rab
(year, x, y)
float64
nan 35.0
- long_name :
- Ratio benthic algae chlorophyll-a to dry weight
- units :
- ug-Chala-a/mg-D
- description :
- Ratio benthic algae chlorophyll-a to dry weight
array([[[nan]],\n",
+ "\n",
+ " [[35.]]])
FLb
(year, x, y)
float64
nan 0.1421
- long_name :
- Benthic algal light limitation factor
- units :
- unitless
- description :
- Benthic algal light limitation factor
array([[[ nan]],\n",
+ "\n",
+ " [[0.14214184]]])
FNb
(year, x, y)
float64
nan 0.8889
- long_name :
- Benthic algal nitrogen limitation factor
- units :
- unitless
- description :
- Benthic algal nitrogen limitation factor
array([[[ nan]],\n",
+ "\n",
+ " [[0.88888889]]])
FPb
(year, x, y)
float64
nan 0.8889
- long_name :
- Benthic algal phosphorous limitation factor
- units :
- unitless
- description :
- Benthic algal phosphorous limitation factor
array([[[ nan]],\n",
+ "\n",
+ " [[0.88888889]]])
FSb
(year, x, y)
float64
nan 0.9091
- long_name :
- Benthic algal density attenuation
- units :
- unitless
- description :
- Benthic algal density attenuation
array([[[ nan]],\n",
+ "\n",
+ " [[0.90909091]]])
mub
(year, x, y)
float64
nan 0.04084
- long_name :
- Benthic algae specific growth rate
- units :
- 1/d
- description :
- Benthic algae specific growth rate
array([[[ nan]],\n",
+ "\n",
+ " [[0.04083986]]])
AbGrowth
(year, x, y)
float64
nan 0.04084
- long_name :
- Benthic algae growth rate
- units :
- g/m^2/d
- description :
- Benthic algae growth rate
array([[[ nan]],\n",
+ "\n",
+ " [[0.04083986]]])
AbRespiration
(year, x, y)
float64
nan 0.2
- long_name :
- Benthic algae respiration rate
- units :
- g/m^2/d
- description :
- Benthic algae respiration rate
array([[[nan]],\n",
+ "\n",
+ " [[0.2]]])
AbDeath
(year, x, y)
float64
nan 0.3
- long_name :
- Benthic algae death rate
- units :
- g/m^2/d
- description :
- Benthic algae death rate
array([[[nan]],\n",
+ "\n",
+ " [[0.3]]])
dAbdt
(year, x, y)
float64
nan -0.4592
- long_name :
- Change in benthic algae concentration
- units :
- g/m^2/d
- description :
- Change in benthic algae concentration
array([[[ nan]],\n",
+ "\n",
+ " [[-0.45916014]]])
Chlb
(year, x, y)
float64
nan 35.0
- long_name :
- Chlorophyll-a concentration
- units :
- mg-Chla/m^2
- description :
- Chlorophyll-a concentration
array([[[nan]],\n",
+ "\n",
+ " [[35.]]])
knit_tc
(year, x, y)
float64
nan 0.1
- long_name :
- Nitrification rate ammonia decay
- units :
- 1/d
- description :
- Nitrification rate ammonia decay temperature correction
array([[[nan]],\n",
+ "\n",
+ " [[0.1]]])
rnh4_tc
(year, x, y)
float64
nan 0.0
- long_name :
- Sediment release rate of NH4
- units :
- 1/d
- description :
- Sediment release rate of NH4 temperature correction
array([[[nan]],\n",
+ "\n",
+ " [[ 0.]]])
vno3_tc
(year, x, y)
float64
nan 0.0
- long_name :
- Sediment denitrification velocity
- units :
- m/d
- description :
- Sediment denitrification velocity temperature correction
array([[[nan]],\n",
+ "\n",
+ " [[ 0.]]])
kon_tc
(year, x, y)
float64
nan 0.1
- long_name :
- Decay rate of OrgN to NH4
- units :
- 1/d
- description :
- Decay rate of OrgN to NH4 temperature correction
array([[[nan]],\n",
+ "\n",
+ " [[0.1]]])
kdnit_tc
(year, x, y)
float64
nan 0.002
- long_name :
- Denitrification rate
- units :
- 1/d
- description :
- Denitrification rate temperature correction
array([[[ nan]],\n",
+ "\n",
+ " [[0.002]]])
ApUptakeFr_NH4
(year, x, y)
float64
nan 0.5
- long_name :
- Fraction of actual floating algal uptake from ammonia pool
- units :
- unitless
- description :
- Fraction of actual floating algal uptake from ammonia pool
array([[[nan]],\n",
+ "\n",
+ " [[0.5]]])
ApUptakeFr_NO3
(year, x, y)
float64
nan 0.5
- long_name :
- Fraction of actual floating algal uptake from nitrate pool
- units :
- unitless
- description :
- Fraction of actual floating algal uptake from nitrate pool
array([[[nan]],\n",
+ "\n",
+ " [[0.5]]])
AbUptakeFr_NH4
(year, x, y)
float64
nan 0.5
- long_name :
- Fraction of actual benthic algal uptake from ammonia pool
- units :
- unitless
- description :
- Fraction of actual benthic algal uptake from ammonia pool
array([[[nan]],\n",
+ "\n",
+ " [[0.5]]])
AbUptakeFr_NO3
(year, x, y)
float64
nan 0.5
- long_name :
- Fraction of actual benthic algal uptake from nitrate pool
- units :
- unitless
- description :
- Fraction of actual benthic algal uptake from nitrate pool
array([[[nan]],\n",
+ "\n",
+ " [[0.5]]])
ApDeath_OrgN
(year, x, y)
float64
nan 0.00108
- long_name :
- Algae -> OrgN
- units :
- mg-N/L/d
- description :
- Algae conversion to Organic nitrogen
array([[[ nan]],\n",
+ "\n",
+ " [[0.00108]]])
AbDeath_OrgN
(year, x, y)
float64
nan 0.0175
- long_name :
- Benthic Algae -> OrgN
- units :
- mg-N/L/d
- description :
- Benthic algae conversion to Organic nitrogen
array([[[ nan]],\n",
+ "\n",
+ " [[0.017496]]])
OrgN_NH4_Decay
(year, x, y)
float64
nan 0.1
- long_name :
- OrgN -> NH4
- units :
- mg-N/L/d
- description :
- Organic nitrogen to ammonium decay
array([[[nan]],\n",
+ "\n",
+ " [[0.1]]])
OrgN_Settling
(year, x, y)
float64
nan 0.01
- long_name :
- OrgN -> bed
- units :
- mg-N/L/d
- description :
- Organic nitrogen to bed settling
array([[[ nan]],\n",
+ "\n",
+ " [[0.01]]])
dOrgNdt
(year, x, y)
float64
nan -0.09142
- long_name :
- Change in organic nitrogen
- units :
- mg-N/L
- description :
- Change in organic nitrogen
array([[[ nan]],\n",
+ "\n",
+ " [[-0.091424]]])
NH4_Nitrification
(year, x, y)
float64
nan 0.04512
- long_name :
- NH4 -> NO3 Nitrification
- units :
- mg-N/L/d
- description :
- NH4 Nitrification
array([[[ nan]],\n",
+ "\n",
+ " [[0.04511884]]])
NH4fromBed
(year, x, y)
float64
nan 0.0
- long_name :
- bed -> NH4 (diffusion)
- units :
- mg-N/L/d
- description :
- Sediment bed release of NH4
array([[[nan]],\n",
+ "\n",
+ " [[ 0.]]])
NH4_ApRespiration
(year, x, y)
float64
nan 0.00144
- long_name :
- Floating algae -> NH4
- units :
- mg-N/L/d
- description :
- Floating algae to NH4
array([[[ nan]],\n",
+ "\n",
+ " [[0.00144]]])
NH4_ApGrowth
(year, x, y)
float64
nan 0.000529
- long_name :
- NH4 -> Floating algae
- units :
- mg-N/L/d
- description :
- NH4 uptake to algae
array([[[ nan]],\n",
+ "\n",
+ " [[0.00052905]]])
NH4_AbRespiration
(year, x, y)
float64
nan 0.0144
- long_name :
- Benthic algae -> NH4
- units :
- mg-N/L/d
- description :
- Benthic algae release of NH4
array([[[ nan]],\n",
+ "\n",
+ " [[0.0144]]])
NH4_AbGrowth
(year, x, y)
float64
nan 0.001323
- long_name :
- NH4 -> Benthic Algae
- units :
- mg-N/L/d
- description :
- Benthic algae uptake of NH4
array([[[ nan]],\n",
+ "\n",
+ " [[0.00132321]]])
dNH4dt
(year, x, y)
float64
nan 0.06887
- long_name :
- Change in ammonium concentration
- units :
- mg-N/L
- description :
- Change in ammonium concentration
array([[[ nan]],\n",
+ "\n",
+ " [[0.0688689]]])
NO3_Denit
(year, x, y)
float64
nan 0.0001818
- long_name :
- NO3 -> Loss
- units :
- mg-N/L/d
- description :
- NO3 loss from denitrification
array([[[ nan]],\n",
+ "\n",
+ " [[0.00018182]]])
NO3_BedDenit
(year, x, y)
float64
nan 0.0
- long_name :
- Sediment denitrification
- units :
- mg-N/L/d
- description :
- Sediment denitrification
array([[[nan]],\n",
+ "\n",
+ " [[ 0.]]])
NO3_ApGrowth
(year, x, y)
float64
nan 0.000529
- long_name :
- NO3 -> Floating algae
- units :
- mg-N/L/d
- description :
- NO3 uptake to floating algae
array([[[ nan]],\n",
+ "\n",
+ " [[0.00052905]]])
NO3_AbGrowth
(year, x, y)
float64
nan 0.001323
- long_name :
- NO3 -> Benthic algae
- units :
- mg-N/L/d
- description :
- NO3 uptake to benthic algae
array([[[ nan]],\n",
+ "\n",
+ " [[0.00132321]]])
dNO3dt
(year, x, y)
float64
nan 0.04308
- long_name :
- Change in nitrate concentration
- units :
- mg-N/L
- description :
- Change in nitrate concentration
array([[[ nan]],\n",
+ "\n",
+ " [[0.04308476]]])
DIN
(year, x, y)
float64
nan 2.0
- long_name :
- Dissolve inorganic nitrogen
- units :
- mg-N/L
- description :
- Dissolve inorganic nitrogen
array([[[nan]],\n",
+ "\n",
+ " [[ 2.]]])
TON
(year, x, y)
float64
nan 1.007
- long_name :
- Total organic nitrogen
- units :
- mg-N/L
- description :
- Total organic nitrogen
array([[[ nan]],\n",
+ "\n",
+ " [[1.0072]]])
TKN
(year, x, y)
float64
nan 2.007
- long_name :
- Total kjeldhl nitrogen
- units :
- mg-N/L
- description :
- Total kjeldhl nitrogen
array([[[ nan]],\n",
+ "\n",
+ " [[2.0072]]])
TN
(year, x, y)
float64
nan 3.007
- long_name :
- Total nitrogen
- units :
- mg-N/L
- description :
- Total nitrogen
array([[[ nan]],\n",
+ "\n",
+ " [[3.0072]]])
NitrificationInhibition
(year, x, y)
float64
nan 0.4512
- long_name :
- Nitrification Inhibitation (limits nitrification under low DO conditions)
- units :
- unitless
- description :
- Nitrification Inhibitation (limits nitrification under low DO conditions)
array([[[ nan]],\n",
+ "\n",
+ " [[0.45118836]]])
kop_tc
(year, x, y)
float64
nan 0.1
- long_name :
- Decay rate of organic P to DIP
- units :
- 1/d
- description :
- Decay rate of organic P to DIP temperature correction
array([[[nan]],\n",
+ "\n",
+ " [[0.1]]])
rpo4_tc
(year, x, y)
float64
nan 0.0
- long_name :
- Benthic sediment release rate of DIP
- units :
- g-P/m2/d
- description :
- Benthic sediment release rate of DIP temperature correction
array([[[nan]],\n",
+ "\n",
+ " [[ 0.]]])
OrgP_DIP_decay
(year, x, y)
float64
nan 0.1
- long_name :
- Organic phosphorus decay to dissolve inorganic phosphorus
- units :
- mg-P/L/d
- description :
- Organic phosphorus decay to dissolve inorganic phosphorus
array([[[nan]],\n",
+ "\n",
+ " [[0.1]]])
OrgP_Settling
(year, x, y)
float64
nan 999.0
- long_name :
- Organic phosphorus settling to sediment
- units :
- mg-P/L/d
- description :
- Organic phosphorus settling to sediment
array([[[ nan]],\n",
+ "\n",
+ " [[999.]]])
ApDeath_OrgP
(year, x, y)
float64
nan 0.00015
- long_name :
- Algal death turning into organic phosphorus
- units :
- mg-P/L/d
- description :
- Algal death turning into organic phosphorus
array([[[ nan]],\n",
+ "\n",
+ " [[0.00015]]])
AbDeath_OrgP
(year, x, y)
float64
nan 0.00243
- long_name :
- Benthic algal death turning into organic phosphorus
- units :
- mg-P/L/d
- description :
- Benthic algal death turning into organic phosphorus
array([[[ nan]],\n",
+ "\n",
+ " [[0.00243]]])
dOrgPdt
(year, x, y)
float64
nan -999.1
- long_name :
- Change in organic phosphorus concentration
- units :
- mg-P/L/d
- description :
- Change in organic phosphorus concentration
array([[[ nan]],\n",
+ "\n",
+ " [[-999.09742]]])
DIPfromBed
(year, x, y)
float64
nan 0.0
- long_name :
- Dissolved Organic Phosphorus coming from Bed calculated without SedFlux modules
- units :
- mg-P/L/d
- description :
- Dissolved Organic Phosphorus coming from Bed calculated without SedFlux modules
array([[[nan]],\n",
+ "\n",
+ " [[ 0.]]])
TIP_Settling
(year, x, y)
float64
nan 0.0
- long_name :
- Total inorganic phosphorus settling from water to bed
- units :
- mg-P/L/d
- description :
- Total inorganic phosphorus settling from water to bed
array([[[nan]],\n",
+ "\n",
+ " [[ 0.]]])
DIP_ApRespiration
(year, x, y)
float64
nan 0.0002
- long_name :
- Dissolved inorganic phosphorus released from algal respiration
- units :
- mg-P/L/d
- description :
- Dissolved inorganic phosphorus released from algal respiration
array([[[ nan]],\n",
+ "\n",
+ " [[0.0002]]])
DIP_ApGrowth
(year, x, y)
float64
nan 0.000147
- long_name :
- Dissolved inorganic phosphorus consumed for algal growth
- units :
- mg-P/L/d
- description :
- Dissolved inorganic phosphorus consumed for algal growth
array([[[ nan]],\n",
+ "\n",
+ " [[0.00014696]]])
DIP_AbRespiration
(year, x, y)
float64
nan 0.002
- long_name :
- Dissolved inorganic phosphorus released for benthic algal respiration
- units :
- mg-P/L/d
- description :
- Dissolved inorganic phosphorus released for benthic algal respiration
array([[[ nan]],\n",
+ "\n",
+ " [[0.002]]])
DIP_AbGrowth
(year, x, y)
float64
nan 0.0003676
- long_name :
- Dissolved inorganic phosphorus consumed for benthic algal growth
- units :
- mg-P/L/d
- description :
- Dissolved inorganic phosphorus consumed for benthic algal growth
array([[[ nan]],\n",
+ "\n",
+ " [[0.00036756]]])
dTIPdt
(year, x, y)
float64
nan 0.1017
- long_name :
- Change in dissolved inorganic phosphorus water concentration
- units :
- mg-P/L/d
- description :
- Change in dissolved inorganic phosphorus water concentration
array([[[ nan]],\n",
+ "\n",
+ " [[0.10168548]]])
TOP
(year, x, y)
float64
nan 1.001
- long_name :
- Total organic phosphorus
- units :
- mg-P/L
- description :
- Total organic phosphorus
array([[[ nan]],\n",
+ "\n",
+ " [[1.001]]])
TP
(year, x, y)
float64
nan 2.001
- long_name :
- Total phosphorus
- units :
- mg-P/L
- description :
- Total phosphorus
array([[[ nan]],\n",
+ "\n",
+ " [[2.001]]])
DIP
(year, x, y)
float64
nan 1.0
- long_name :
- Dissolve inorganic phosphorus
- units :
- mg-P/L
- description :
- Dissolve inorganic phosphorus
array([[[nan]],\n",
+ "\n",
+ " [[ 1.]]])
kpom_tc
(year, x, y)
float64
nan 0.1
- long_name :
- POM dissolution rate adjusted for temperature
- units :
- 1/d
- description :
- POM dissolution rate adjusted for temperature
array([[[nan]],\n",
+ "\n",
+ " [[0.1]]])
POM_algal_settling
(year, x, y)
float64
nan 0.015
- long_name :
- POM concentration change due to algal settling
- units :
- mg/L/d
- description :
- POM concentration change due to algal settling
array([[[ nan]],\n",
+ "\n",
+ " [[0.015]]])
POM_dissolution
(year, x, y)
float64
nan 0.1
- long_name :
- POM concentration change due to dissolution
- units :
- mg/L/d
- description :
- POM concentration change due to dissolution
array([[[nan]],\n",
+ "\n",
+ " [[0.1]]])
POM_POC_settling
(year, x, y)
float64
nan 0.025
- long_name :
- POM concentration change due to POC settling
- units :
- mg/L/d
- description :
- POM concentration change due to POC settling
array([[[ nan]],\n",
+ "\n",
+ " [[0.025]]])
POM_benthic_algae_mortality
(year, x, y)
float64
nan 0.027
- long_name :
- POM concentration change due to algae mortality
- units :
- mg/L/d
- description :
- POM concentration change due to algae mortality
array([[[ nan]],\n",
+ "\n",
+ " [[0.027]]])
POM_burial
(year, x, y)
float64
nan 0.01
- long_name :
- POM concentration change due to burial
- units :
- mg/L/d
- description :
- POM concentration change due to burial
array([[[ nan]],\n",
+ "\n",
+ " [[0.01]]])
dPOMdt
(year, x, y)
float64
nan -0.043
- long_name :
- Change in POM concentration for one timestep
- units :
- mg/L/d
- description :
- Change in POM concentration for one timestep
array([[[ nan]],\n",
+ "\n",
+ " [[-0.043]]])
kbod_tc
(year, x, y)
float64
nan 0.12
- long_name :
- Temperature adjusted oxidation rate
- units :
- 1/d
- description :
- Temperature adjusted oxidation rate
array([[[ nan]],\n",
+ "\n",
+ " [[0.12]]])
ksbod_tc
(year, x, y)
float64
nan 0.0
- long_name :
- Temperature adjusted sedimentation rate
- units :
- m/d
- description :
- Temperature adjusted sedimentation rate
array([[[nan]],\n",
+ "\n",
+ " [[ 0.]]])
CBOD_oxidation
(year, x, y)
float64
nan 0.08
- long_name :
- CBOD oxidation
- units :
- mg/L/d
- description :
- CBOD oxidation
array([[[ nan]],\n",
+ "\n",
+ " [[0.08]]])
CBOD_sedimentation
(year, x, y)
float64
nan 0.0
- long_name :
- CBOD sedimentation
- units :
- mg/L/d
- description :
- CBOD sedimentation
array([[[nan]],\n",
+ "\n",
+ " [[ 0.]]])
dCBODdt
(year, x, y)
float64
nan -0.08
- long_name :
- Change in CBOD concentration for the given timestep
- units :
- mg/L/d
- description :
- Change in CBOD concentration for the given timestep
array([[[ nan]],\n",
+ "\n",
+ " [[-0.08]]])
kpoc_tc
(year, x, y)
float64
nan 0.005
- long_name :
- Temperature adjusted POC hydrolysis rate
- units :
- 1/d
- description :
- Temperature adjusted POC hydrolysis rate
array([[[ nan]],\n",
+ "\n",
+ " [[0.005]]])
POC_settling
(year, x, y)
float64
nan 0.01
- long_name :
- POC concentration removed from cell due to settling
- units :
- mg/L/d
- description :
- POC concentration removed from cell due to settling
array([[[ nan]],\n",
+ "\n",
+ " [[0.01]]])
POC_hydrolysis
(year, x, y)
float64
nan 0.005
- long_name :
- POC concentration removed from cell due to hydrolysis
- units :
- mg/L/d
- description :
- POC concentration removed from cell due to hydrolysis
array([[[ nan]],\n",
+ "\n",
+ " [[0.005]]])
POC_algal_mortality
(year, x, y)
float64
nan 0.0054
- long_name :
- POC concentration added to cell due to algal mortality
- units :
- mg/L/d
- description :
- POC concentration added to cell due to algal mortality
array([[[ nan]],\n",
+ "\n",
+ " [[0.0054]]])
POC_benthic_algae_mortality
(year, x, y)
float64
nan 0.08748
- long_name :
- POC concentration added to cell due to benthic algae mortality
- units :
- mg/L/d
- description :
- POC concentration added to cell due to benthic algae mortality
array([[[ nan]],\n",
+ "\n",
+ " [[0.08748]]])
dPOCdt
(year, x, y)
float64
nan 0.07788
- long_name :
- POC concentration change per timestep
- units :
- mg/L/d
- description :
- POC concentration change per timestep
array([[[ nan]],\n",
+ "\n",
+ " [[0.07788]]])
kdoc_tc
(year, x, y)
float64
nan 0.01
- long_name :
- Dissolved organic carbon oxidation rate adjusted for temperature
- units :
- 1/d
- description :
- Dissolved organic carbon oxidation rate adjusted for temperature
array([[[ nan]],\n",
+ "\n",
+ " [[0.01]]])
DOC_algal_mortality
(year, x, y)
float64
nan 0.0006
- long_name :
- DOC concentration added to cell due to algal mortality
- units :
- mg/L/d
- description :
- DOC concentration added to cell due to algal mortality
array([[[ nan]],\n",
+ "\n",
+ " [[0.0006]]])
DOC_benthic_algae_mortality
(year, x, y)
float64
nan 0.00972
- long_name :
- DOC concentration added to cell due to benthic algae mortality
- units :
- mg/L/d
- description :
- DOC concentration added to cell due to benthic algae mortality
array([[[ nan]],\n",
+ "\n",
+ " [[0.00972]]])
DOC_DIC_oxidation
(year, x, y)
float64
nan 0.005
- long_name :
- DOC concentration lost to cell due to oxidation
- units :
- mg/L/d
- description :
- DOC concentration lost to cell due to oxidation
array([[[ nan]],\n",
+ "\n",
+ " [[0.005]]])
dDOCdt
(year, x, y)
float64
nan 0.01032
- long_name :
- DOC concentration change per timestep
- units :
- mg/L/d
- description :
- DOC concentration change per timestep
array([[[ nan]],\n",
+ "\n",
+ " [[0.01032]]])
K_H
(year, x, y)
float64
nan 0.03931
- long_name :
- Henrys coefficient
- units :
- mol/L-atm
- description :
- Henrys coefficient controlling the relative proportion of gaseous and aqueous phase CO2
array([[[ nan]],\n",
+ "\n",
+ " [[0.03931489]]])
Atm_CO2_reaeration
(year, x, y)
float64
nan -1.987e+04
- long_name :
- Atmospheric CO2 reaeration
- units :
- mg/L/d
- description :
- Amount of DIC concentration change due to atmospheric exchange
array([[[ nan]],\n",
+ "\n",
+ " [[-19871.39779666]]])
DIC_algal_respiration
(year, x, y)
float64
nan 0.008
- long_name :
- DIC generated by algal respiration
- units :
- mg/L/d
- description :
- DIC generated by algal respiration
array([[[ nan]],\n",
+ "\n",
+ " [[0.008]]])
DIC_algal_photosynthesis
(year, x, y)
float64
nan 0.005878
- long_name :
- DIC consumed by algal photosynthesis
- units :
- mg/L/d
- description :
- DIC consumed by algal photosynthesis
array([[[ nan]],\n",
+ "\n",
+ " [[0.00587831]]])
DIC_benthic_algae_respiration
(year, x, y)
float64
nan 0.072
- long_name :
- DIC generated by benthic algae respiration
- units :
- mg/L/d
- description :
- DIC generated by benthic algae respiration
array([[[ nan]],\n",
+ "\n",
+ " [[0.072]]])
DIC_benthic_algae_photosynthesis
(year, x, y)
float64
nan 0.0147
- long_name :
- DIC consumed by benthic algae photosynthesis
- units :
- mg/L/d
- description :
- DIC consumed by benthic algae photosynthesis
array([[[ nan]],\n",
+ "\n",
+ " [[0.01470235]]])
DIC_CBOD_oxidation
(year, x, y)
float64
nan 0.03
- long_name :
- DIC concentration change due to CBOD oxidation
- units :
- mg/L/d
- description :
- DIC concentration change due to CBOD oxidation
array([[[ nan]],\n",
+ "\n",
+ " [[0.03]]])
DIC_sed_release
(year, x, y)
float64
nan 187.3
- long_name :
- DIC concentration change due to sediment release
- units :
- mg/L/d
- description :
- DIC concentration change due to sediment release
array([[[ nan]],\n",
+ "\n",
+ " [[187.3125]]])
dDICdt
(year, x, y)
float64
nan -1.968e+04
- long_name :
- DIC concentration change per timestep
- units :
- mg/L/d
- description :
- DIC concentration change per timestep
array([[[ nan]],\n",
+ "\n",
+ " [[-19683.99587732]]])
DOX_sat
(year, x, y)
float64
nan 0.0
- long_name :
- DO saturation concentration
- units :
- mg/L
- description :
- DO saturation concentration in water as a function of water temperature (K)
array([[[nan]],\n",
+ "\n",
+ " [[ 0.]]])
pwv
(year, x, y)
float64
nan 0.02309
- long_name :
- Partial pressure of water vapor
- units :
- atm
- description :
- Partial pressure of water vapor
array([[[ nan]],\n",
+ "\n",
+ " [[0.02308854]]])
DOs_atm_alpha
(year, x, y)
float64
nan 0.002326
- long_name :
- DO saturation atmospheric correction coefficient
- units :
- unitless
- description :
- DO saturation atmospheric correction coefficient
array([[[ nan]],\n",
+ "\n",
+ " [[0.00232582]]])
Atm_O2_reaeration
(year, x, y)
float64
nan -8.28
- long_name :
- Atmospheric oxygen reaeration
- units :
- mg/L/d
- description :
- Atmospheric oxygen reaeration, can fluctuate both in and out of waterbody
array([[[ nan]],\n",
+ "\n",
+ " [[-8.28037249]]])
DOX_ApGrowth
(year, x, y)
float64
nan 0.01804
- long_name :
- Dissolved oxygen flux due to algal photosynthesis
- units :
- mg/L/d
- description :
- Dissolved oxygen flux due to algal photosynthesis
array([[[ nan]],\n",
+ "\n",
+ " [[0.01804162]]])
DOX_ApRespiration
(year, x, y)
float64
nan 0.02133
- long_name :
- Dissolved oxygen flux due to algal respiration
- units :
- mg/L/d
- description :
- Dissolved oxygen flux due to algal respiration
array([[[ nan]],\n",
+ "\n",
+ " [[0.02133333]]])
DOX_Nitrification
(year, x, y)
float64
nan 0.2063
- long_name :
- Dissolved oxygen flux due to nitrification
- units :
- mg/L/d
- description :
- Dissolved oxygen flux due to nitrification
array([[[ nan]],\n",
+ "\n",
+ " [[0.20625754]]])
DOX_DOC_oxidation
(year, x, y)
float64
nan 0.01333
- long_name :
- Dissolved oxygen flux due to DOC oxidation
- units :
- mg/L/d
- description :
- Dissolved oxygen flux due to DOC oxidation
array([[[ nan]],\n",
+ "\n",
+ " [[0.01333333]]])
DOX_CBOD_oxidation
(year, x, y)
float64
nan 0.08
- long_name :
- Dissolved oxygen flux due to CBOD oxidation
- units :
- mg/L/d
- description :
- Dissolved oxygen flux due to CBOD oxidation
array([[[ nan]],\n",
+ "\n",
+ " [[0.08]]])
DOX_AbGrowth
(year, x, y)
float64
nan 0.04512
- long_name :
- Dissolved oxygen flux due to benthic algae photosynthesis
- units :
- mg/L/d
- description :
- Dissolved oxygen flux due to benthic algae photosynthesis
array([[[ nan]],\n",
+ "\n",
+ " [[0.04512419]]])
DOX_AbRespiration
(year, x, y)
float64
nan 0.192
- long_name :
- Dissolved oxygen flux due to benthic algae respiration
- units :
- mg/L/d
- description :
- Dissolved oxygen flux due to benthic algae respiration
array([[[ nan]],\n",
+ "\n",
+ " [[0.192]]])
DOX_SOD
(year, x, y)
float64
nan 499.5
- long_name :
- Dissolved oxygen flux due to sediment oxygen demand
- units :
- mg/L/d
- description :
- Dissolved oxygen flux due to sediment oxygen demand
array([[[ nan]],\n",
+ "\n",
+ " [[499.5]]])
dDOXdt
(year, x, y)
float64
nan -508.2
- long_name :
- Change in dissolved oxygen concentration for one timestep
- units :
- mg/L/d
- description :
- Change in dissolved oxygen concentration for one timestep
array([[[ nan]],\n",
+ "\n",
+ " [[-508.23013089]]])
kdx_tc
(year, x, y)
float64
nan 0.8
- long_name :
- Pathogen death rate
- units :
- 1/d
- description :
- Pathogen death rate with temperature correction
array([[[nan]],\n",
+ "\n",
+ " [[0.8]]])
PathogenDeath
(year, x, y)
float64
nan 0.8
- long_name :
- Pathogen natural death
- units :
- cfu/100mL/d
- description :
- Pathogen natural death
array([[[nan]],\n",
+ "\n",
+ " [[0.8]]])
PathogenDecay
(year, x, y)
float64
nan 3.758
- long_name :
- Pathogen death due to light
- units :
- cfu/100mL/d
- description :
- Pathogen death due to light
array([[[ nan]],\n",
+ "\n",
+ " [[3.75770698]]])
PathogenSettling
(year, x, y)
float64
nan 1.0
- long_name :
- Pathogen settling
- units :
- cfu/100mL/d
- description :
- Pathogen settling
array([[[nan]],\n",
+ "\n",
+ " [[ 1.]]])
dPXdt
(year, x, y)
float64
nan -5.558
- long_name :
- Change in pathogen concentration
- units :
- cfu/100mL/d
- description :
- Change in pathogen concentration
array([[[ nan]],\n",
+ "\n",
+ " [[-5.55770698]]])
Alk_denitrification
(year, x, y)
float64
nan 0.0001818
- long_name :
- Alkalinity change due to denitrification
- units :
- mg/L/d
- description :
- Alkalinity change due to denitrification
array([[[ nan]],\n",
+ "\n",
+ " [[0.00018182]]])
Alk_nitrification
(year, x, y)
float64
nan 0.04512
- long_name :
- Alkalinity change due to nitrification
- units :
- mg/L/d
- description :
- Alkalinity change due to nitrification
array([[[ nan]],\n",
+ "\n",
+ " [[0.04511884]]])
Alk_algal_growth
(year, x, y)
float64
nan 0.0
- long_name :
- Alkalinity change due to algal growth
- units :
- mg/L/d
- description :
- Alkalinity change due to algal growth
array([[[nan]],\n",
+ "\n",
+ " [[ 0.]]])
Alk_algal_respiration
(year, x, y)
float64
nan 0.2
- long_name :
- Alkalinity change due to algal respiration
- units :
- mg/L/d
- description :
- Alkalinity change due to algal respiration
array([[[nan]],\n",
+ "\n",
+ " [[0.2]]])
Alk_benthic_algae_growth
(year, x, y)
float64
nan 0.0
- long_name :
- Alkalinity change due to benthic algae growth
- units :
- mg/L/d
- description :
- Alkalinity change due to benthic algae growth
array([[[nan]],\n",
+ "\n",
+ " [[ 0.]]])
Alk_benthic_algae_respiration
(year, x, y)
float64
nan 0.18
- long_name :
- Alkalinity change due to benthic algae growth
- units :
- mg/L/d
- description :
- Alkalinity change due to benthic algae growth
array([[[ nan]],\n",
+ "\n",
+ " [[0.18]]])
dAlkdt
(year, x, y)
float64
nan 0.3351
- long_name :
- Alkalinity concentration change per timestep
- units :
- mg/L/d
- description :
- Alkalinity concentration change per timestep
array([[[ nan]],\n",
+ "\n",
+ " [[0.33506298]]])
KHN2_tc
(year, x, y)
float64
nan 0.0007001
- long_name :
- Henrys law constant
- units :
- mol/L/atm
- description :
- Henrys law constant temperature corrected
array([[[ nan]],\n",
+ "\n",
+ " [[0.00070008]]])
P_wv
(year, x, y)
float64
nan 0.02309
- long_name :
- Partial pressure water vapor
- units :
- atm
- description :
- Partial pressure water vapor
array([[[ nan]],\n",
+ "\n",
+ " [[0.02308854]]])
N2sat
(year, x, y)
float64
nan 30.61
- long_name :
- N2 at saturation
- units :
- mg-N/L
- description :
- N2 at saturation f(Twater and atm pressure)
array([[[ nan]],\n",
+ "\n",
+ " [[30.6138397]]])
dN2dt
(year, x, y)
float64
nan 253.6
- long_name :
- Change in N2 air concentration
- units :
- mg-N/L/d
- description :
- Change in N2 air concentration
array([[[ nan]],\n",
+ "\n",
+ " [[253.55088691]]])
TDG
(year, x, y)
float64
nan inf
- long_name :
- Total dissolved gas
- units :
- %
- description :
- Total dissolved gas
array([[[nan]],\n",
+ "\n",
+ " [[inf]]])
"
+ ],
+ "text/plain": [
+ " Size: 3kB\n",
+ "Dimensions: (year: 2, x: 1, y: 1)\n",
+ "Coordinates:\n",
+ " * year (year) int32 8B 0 1\n",
+ " * x (x) float64 8B 1.0\n",
+ " * y (y) float64 8B 1.0\n",
+ "Data variables: (12/281)\n",
+ " Ap (year, x, y) float64 16B 1.0 -3.05e+04\n",
+ " Ab (year, x, y) float64 16B 1.0 -3.967e+04\n",
+ " NH4 (year, x, y) float64 16B 1.0 5.951e+03\n",
+ " NO3 (year, x, y) float64 16B 1.0 3.724e+03\n",
+ " OrgN (year, x, y) float64 16B 1.0 -7.898e+03\n",
+ " N2 (year, x, y) float64 16B 1.0 2.191e+07\n",
+ " ... ...\n",
+ " dAlkdt (year, x, y) float64 16B nan 0.3351\n",
+ " KHN2_tc (year, x, y) float64 16B nan 0.0007001\n",
+ " P_wv (year, x, y) float64 16B nan 0.02309\n",
+ " N2sat (year, x, y) float64 16B nan 30.61\n",
+ " dN2dt (year, x, y) float64 16B nan 253.6\n",
+ " TDG (year, x, y) float64 16B nan inf"
]
},
- "execution_count": 3,
+ "execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
- "import clearwater_modules as cwm\n",
- "import clearwater_modules.sorter as sorter\n",
- "import numba\n",
- "import random\n",
- "import hvplot.xarray\n",
- "import warnings\n",
- "warnings.filterwarnings(\"ignore\")\n",
- "from clearwater_modules.nsm1.model import NutrientBudget\n",
- "import clearwater_modules.nsm1.model as test\n",
- "\n",
- "\n",
- "\n",
- "initial_state_values = {'Ap': 1,\n",
- " 'Ab': 1,\n",
- " 'NH4': 1,\n",
- " 'NO3': 1,\n",
- " 'OrgN': 1,\n",
- " 'N2': 1,\n",
- " 'TIP': 1,\n",
- " 'OrgP': 1,\n",
- " 'POC': 1,\n",
- " 'DOC': 1,\n",
- " 'DIC': 1,\n",
- " 'POM': 1,\n",
- " 'CBOD': 1,\n",
- " 'DOX': 1,\n",
- " 'PX': 1,\n",
- " 'Alk': 1}\n",
- "\n",
- "algae_parameters = {\n",
- " 'AWd': 100,\n",
- " 'AWc': 40,\n",
- " 'AWn': 7.2,\n",
- " 'AWp': 1,\n",
- " 'AWa': 1000,\n",
- " \n",
- " 'KL': 10,\n",
- " 'KsN': 0.04,\n",
- " 'KsP': 0.0012,\n",
- " 'mu_max_20': 1,\n",
- " 'kdp_20': 0.15,\n",
- " 'krp_20': 0.2,\n",
- " 'vsap': 0.15,\n",
- " 'growth_rate_option': 1,\n",
- " 'light_limitation_option': 1\n",
- "}\n",
- "\n",
- "balgae_parameters = {\n",
- " 'BWd': 100,\n",
- " 'BWc': 40,\n",
- " 'Bwn': 7.2,\n",
- " 'BWp': 1,\n",
- " 'BWa': 3500,\n",
- "\n",
- " 'KLb': 10,\n",
- " 'KsNb': 0.25,\n",
- " 'KsPb': 0.125,\n",
- " 'Ksb': 10,\n",
- " 'mub_max_20': 0.4,\n",
- " 'krb_20': 0.2,\n",
- " 'kdb_20': 0.3,\n",
- " 'b_growth_rate_option': 1,\n",
- " 'b_light_limitation_option': 1,\n",
- " 'Fw': 0.9,\n",
- " 'Fb': 0.9\n",
- "}\n",
- "\n",
- "nitrogen_parameters = {\n",
- " 'KNR': 0.6,\n",
- " 'knit_20': 0.1,\n",
- " 'kon_20': 0.1,\n",
- " 'kdnit_20': 0.002,\n",
- " 'rnh4_20': 0,\n",
- " 'vno3_20': 0,\n",
- " 'KsOxdn': 0.1,\n",
- " 'PN': 0.5,\n",
- " 'PNb': 0.5\n",
- "}\n",
- "\n",
- "phosphorus_parameters = {\n",
- " 'kop_20': 0.1,\n",
- " 'rpo4_20': 0\n",
- "}\n",
- "\n",
- "POM_parameters = {\n",
- " 'kpom_20': 0.1\n",
- "}\n",
- "\n",
- "CBOD_parameters = {\n",
- " 'kbod_20': 0.12,\n",
- " 'ksbod_20': 0,\n",
- " 'ksOxbod': 0.5\n",
- "}\n",
- "\n",
- "carbon_parameters = {\n",
- " 'F_pocp': 0.9,\n",
- " 'kdoc_20': 0.01,\n",
- " 'F_pocb': 0.9,\n",
- " 'kpoc_20': 0.005,\n",
- " 'K_sOxmc': 1,\n",
- " 'pCO2': 383,\n",
- " 'FCO2': 0.2\n",
- "}\n",
- "\n",
- "pathogen_parameters = {\n",
- " 'kdx': 0.8,\n",
- " 'apx': 1,\n",
- " 'vx': 1\n",
- "}\n",
- "\n",
- "alkalinity_parameters = {\n",
- " 'r_alkaa': 1,\n",
- " 'r_alkan': 1,\n",
- " 'r_alkn': 1,\n",
- " 'r_alkden': 1,\n",
- " 'r_alkba': 1,\n",
- " 'r_alkbn': 1 \n",
- "}\n",
- "\n",
- "global_parameters = {\n",
- " 'use_NH4': True,\n",
- " 'use_NO3': True, \n",
- " 'use_OrgN': True,\n",
- " 'use_TIP': True, \n",
- " 'use_SedFlux': True,\n",
- " 'use_DOX': True,\n",
- " 'use_Algae': True,\n",
- " 'use_Balgae': True,\n",
- " 'use_OrgP': True,\n",
- " 'use_POC': True,\n",
- " 'use_DOC': True,\n",
- " 'use_DIC': True,\n",
- " 'use_N2': True,\n",
- " 'use_Pathogen': True,\n",
- " 'use_Alk': True,\n",
- " 'use_POM': True \n",
- "}\n",
- "\n",
- "\n",
- "global_vars = {\n",
- " 'vson': 0.01,\n",
- " 'vsoc': 0.01,\n",
- " 'vsop': 999,\n",
- " 'vs': 999,\n",
- " 'SOD_20': 999,\n",
- " 'SOD_theta': 999,\n",
- " 'vb': 0.01,\n",
- " 'fcom': 0.4,\n",
- " 'kaw_20_user': 999,\n",
- " 'kah_20_user': 999,\n",
- " 'hydraulic_reaeration_option': 2,\n",
- " 'wind_reaeration_option': 2,\n",
- " 'Fr_PAR': .5,\n",
- " 'lambda0': .5,\n",
- " 'lambda1': .5,\n",
- " 'lambda2': .5,\n",
- " 'lambdas': .5,\n",
- " 'lambdam': .5, \n",
- " 'timestep': 86400,\n",
- " 'velocity': 1,\n",
- " 'flow': 2,\n",
- " 'topwidth': 1,\n",
- " 'slope': 2,\n",
- " 'shear_velocity': 4,\n",
- " 'pressure_atm': 2,\n",
- " 'wind_speed': 4,\n",
- " 'q_solar': 4,\n",
- " 'Solid': 1\n",
- "}\n",
- "\n",
- "DOX_parameters = {}\n",
- "N2_parameters = {}\n",
- "\n",
- "\n",
- "nsm_model = NutrientBudget(\n",
- " initial_state_values=initial_state_values, # mandatory\n",
- " algae_parameters=algae_parameters,\n",
- " alkalinity_parameters=alkalinity_parameters,\n",
- " balgae_parameters=balgae_parameters,\n",
- " carbon_parameters=carbon_parameters,\n",
- " CBOD_parameters=CBOD_parameters,\n",
- " DOX_parameters=DOX_parameters,\n",
- " nitrogen_parameters=nitrogen_parameters,\n",
- " POM_parameters=POM_parameters,\n",
- " N2_parameters=N2_parameters,\n",
- " phosphorus_parameters=phosphorus_parameters,\n",
- " pathogen_parameters=pathogen_parameters,\n",
- " global_parameters=global_parameters,\n",
- " global_vars=global_vars, \n",
- " track_dynamic_variables=True, # default is true\n",
- " hotstart_dataset=None, # default is None\n",
- " time_dim='year', # default is \"timestep\"\n",
- ")\n",
- "\n",
- "#print(tsm_model.get_state_variables())\n",
+ "nsm_model.increment_timestep()\n",
"nsm_model.dataset"
]
},
@@ -716,7 +1438,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 6,
"id": "a5d34d2d-03a6-41e1-92fc-9e6fba72d6f5",
"metadata": {
"tags": []
@@ -1440,7 +2162,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.11.6"
+ "version": "3.11.8"
},
"toc-autonumbering": true
},
diff --git a/src/clearwater_modules/nsm1/__init__.py b/src/clearwater_modules/nsm1/__init__.py
index a807441..b359a7f 100644
--- a/src/clearwater_modules/nsm1/__init__.py
+++ b/src/clearwater_modules/nsm1/__init__.py
@@ -1,36 +1,4 @@
-"""
-=======================================================================================
-Nutrient Simulation Module 1 (NSM1)
-=======================================================================================
-
-Developed by:
-* Dr. Todd E. Steissberg (ERDC-EL)
-* Dr. Billy E. Johnson (ERDC-EL, LimnoTech)
-* Dr. Zhonglong Zhang (Portland State University)
-* Mr. Mark Jensen (HEC)
-
-This module computes the water quality of a single computational cell. The algorithms
-and structure of this program were adapted from the Fortran 95 version of this module,
-developed by:
-* Dr. Billy E. Johnson (ERDC-EL)
-* Dr. Zhonglong Zhang (Portland State University)
-* Mr. Mark Jensen (HEC)
-
-Version 1.0
-
-Initial Version: June 5, 2021
-"""
-
-from clearwater_modules.nsm1 import algae
-from clearwater_modules.nsm1 import alkalinity
-from clearwater_modules.nsm1 import balgae
-from clearwater_modules.nsm1 import carbon
-from clearwater_modules.nsm1 import CBOD
-from clearwater_modules.nsm1 import DOX
-from clearwater_modules.nsm1 import nitrogen
-from clearwater_modules.nsm1 import POM
-
-
-class NSM1:
- def __init__(self):
- pass
+from clearwater_modules.nsm1 import state_variables
+from clearwater_modules.nsm1 import dynamic_variables
+from clearwater_modules.nsm1 import static_variables
+from clearwater_modules.nsm1.model import NutrientBudget
\ No newline at end of file
diff --git a/src/clearwater_modules/nsm1/algae/processes.py b/src/clearwater_modules/nsm1/algae/processes.py
index e232666..852460f 100644
--- a/src/clearwater_modules/nsm1/algae/processes.py
+++ b/src/clearwater_modules/nsm1/algae/processes.py
@@ -3,6 +3,7 @@
"""
import numba
import xarray as xr
+import numpy as np
from clearwater_modules.shared.processes import arrhenius_correction
import math
@@ -116,7 +117,7 @@ def FL(
Ap: xr.DataArray,
PAR: xr.DataArray,
light_limitation_option: int,
- KL: xr.DataArray,
+ KL: int,
) -> xr.DataArray:
"""Calculate Algal light limitation: FL (unitless).
@@ -131,12 +132,13 @@ def FL(
KEXT = L * depth
+
FL = xr.where(Ap <= 0.0 or KEXT <= 0.0 or PAR <= 0.0, 0,
xr.where(light_limitation_option==1, (1.0 / KEXT) * math.log((KL + PAR) /(KL + PAR * math.exp(-KEXT))),
xr.where(light_limitation_option==2,
- xr.where(abs(KL)<0.0000000001, 1, (1.0 / KEXT) * math.log( (PAR / KL + ((1.0 + (PAR / KL)**2.0)**0.5)) / (PAR * math.exp(-KEXT) / KL + ((1.0 + (PAR * math.exp(-KEXT) / KL)**2.0)**0.5)))),
+ xr.where(abs(KL)< 0.0000000001, 1, (1.0 / KEXT) * math.log( (PAR / KL + ((1.0 + (PAR / KL)**2.0)**0.5)) / (PAR * math.exp(-KEXT) / KL + ((1.0 + (PAR * math.exp(-KEXT) / KL)**2.0)**0.5)))),
xr.where(light_limitation_option==3,
- xr.where(abs(KL)<0.0000000001,0,(2.718/KEXT) * (math.exp(-PAR/KL * math.exp(-KEXT)) - math.exp(-PAR/KL))), "NaN"))))
+ xr.where(abs(KL)< 0.0000000001,0,(2.718/KEXT) * (math.exp(-PAR/KL * math.exp(-KEXT)) - math.exp(-PAR/KL))), "NaN"))))
FL= xr.where(FL > 1.0, 1.0,
diff --git a/src/clearwater_modules/nsm1/balgae/dynamic_variables.py b/src/clearwater_modules/nsm1/balgae/dynamic_variables.py
index 67b00db..bff3bca 100644
--- a/src/clearwater_modules/nsm1/balgae/dynamic_variables.py
+++ b/src/clearwater_modules/nsm1/balgae/dynamic_variables.py
@@ -12,7 +12,6 @@
class Variable(base.Variable):
...
-
Variable(
name='mub_max_tc',
long_name='Maximum benthic algal growth rate',
diff --git a/src/clearwater_modules/nsm1/carbon/static_variables.py b/src/clearwater_modules/nsm1/carbon/static_variables.py
index 91780df..ad5bcfe 100644
--- a/src/clearwater_modules/nsm1/carbon/static_variables.py
+++ b/src/clearwater_modules/nsm1/carbon/static_variables.py
@@ -72,6 +72,6 @@ class Variable(base.Variable):
name='roc',
long_name='O2:C ratio for carbon oxidation',
units='mg-O2/mg-C',
- description='32/12',
+ description='O2:C ratio for carbon oxidation (32/12)',
use='static'
)
\ No newline at end of file
diff --git a/src/clearwater_modules/nsm1/constants.py b/src/clearwater_modules/nsm1/constants.py
index 37ed441..14af78b 100644
--- a/src/clearwater_modules/nsm1/constants.py
+++ b/src/clearwater_modules/nsm1/constants.py
@@ -10,7 +10,6 @@ class AlgaeStaticVariables(TypedDict):
AWn: float
AWp: float
AWa: float
-
KL: float
KsN: float
KsP: float
@@ -19,7 +18,7 @@ class AlgaeStaticVariables(TypedDict):
krp_20: float
vsap: float
growth_rate_option: int
- light_limitation_option: int
+ light_limitation_option: int
DEFAULT_ALGAE = AlgaeStaticVariables(
AWd = 100,
@@ -27,7 +26,6 @@ class AlgaeStaticVariables(TypedDict):
AWn= 7.2,
AWp= 1,
AWa= 1000,
-
KL= 10,
KsN= 0.04,
KsP= 0.0012,
@@ -36,7 +34,7 @@ class AlgaeStaticVariables(TypedDict):
krp_20= 0.2,
vsap= 0.15,
growth_rate_option = 1,
- light_limitation_option = 1
+ light_limitation_option = 1,
)
class AlkalinityStaticVariables(TypedDict):
@@ -47,7 +45,7 @@ class AlkalinityStaticVariables(TypedDict):
r_alkba: float
r_alkbn: float
-DEFAULT_Alkalinity = AlkalinityStaticVariables(
+DEFAULT_ALKALINITY = 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,
@@ -60,7 +58,7 @@ class AlkalinityStaticVariables(TypedDict):
class BalgaeStaticVariables(TypedDict):
BWd: float
BWc: float
- Bwn: float
+ BWn: float
BWp: float
BWa: float
@@ -79,7 +77,7 @@ class BalgaeStaticVariables(TypedDict):
DEFAULT_BALGAE = BalgaeStaticVariables(
BWd = 100,
BWc= 40,
- Bwn=7.2,
+ BWn=7.2,
BWp= 1,
BWa= 3500,
@@ -127,12 +125,11 @@ class CarbonStaticVariables(TypedDict):
f_pocb: float
kpoc_20: float
KsOxmc: float
- kac_20: float
pCO2: float
FCO2: float
roc: float
-DEFAULT_Carbon = CarbonStaticVariables(
+DEFAULT_CARBON = CarbonStaticVariables(
f_pocp = 0.9,
kdoc_20= 0.01,
f_pocb=0.9,
@@ -144,14 +141,14 @@ class CarbonStaticVariables(TypedDict):
)
class CBODStaticVariables(TypedDict):
+ KsOxbod: float
kbod_20: float
ksbod_20: float
- KsOxbod: float
DEFAULT_CBOD = CBODStaticVariables(
+ KsOxbod = 0.5,
kbod_20 = 0.12,
- ksbod_20 = 0.0,
- KsOxbod = 0.5
+ ksbod_20 = 0.0
)
class DOXStaticVariables(TypedDict):
@@ -170,15 +167,6 @@ class N2StaticVariables(TypedDict):
)
-class PhosphorusStaticVariables(TypedDict):
- kop_20: float
- rpo4_20: float
-
-DEFAULT_PHOSPHORUS = PhosphorusStaticVariables(
- kop_20 = 0.1,
- rpo4_20 = 0
-)
-
class POMStaticVariables(TypedDict):
kpom_20: float
@@ -188,46 +176,6 @@ class POMStaticVariables(TypedDict):
)
-class CBODStaticVariables(TypedDict):
- kbod_20: float
- ksbod_20: float
- ksOxbod: float
-
-DEFAULT_CBOD = CBODStaticVariables(
- kbod_20 = 0.12,
- ksbod_20 = 0,
- ksOxbod = 0.5
-)
-
-
-class CarbonStaticVariables(TypedDict):
- F_pocp: float
- kdoc_20: float
- F_pocb: float
- kpoc_20: float
- K_sOxmc: float
- pCO2: float
- FCO2: float
-
-DEFAULT_CARBON = CarbonStaticVariables(
- F_pocp = 0.9,
- kdoc_20 = 0.01,
- F_pocb = 0.9,
- kpoc_20 = 0.005,
- K_sOxmc = 1,
- pCO2 = 383,
- FCO2 = 0.2
-)
-
-
-class DOXStaticVariables(TypedDict):
- ...
-
-DEFAULT_DOX = DOXStaticVariables(
-
-)
-
-
class PathogenStaticVariables(TypedDict):
kdx_20: float
apx: float
@@ -239,23 +187,6 @@ class PathogenStaticVariables(TypedDict):
vx=1
)
-class AlkalinityStaticVariables(TypedDict):
- r_alkaa: float
- r_alkan: float
- r_alkn: float
- r_alkden: float
- r_alkba: float
- r_alkbn: float
-
-DEFAULT_ALKALINITY = AlkalinityStaticVariables(
- r_alkaa = 1,
- r_alkan = 1,
- r_alkn = 1,
- r_alkden = 1,
- r_alkba = 1,
- r_alkbn = 1
-)
-
class PhosphorusStaticVariables(TypedDict):
kop_20: float
rpo4_20: float
@@ -267,12 +198,6 @@ class PhosphorusStaticVariables(TypedDict):
kdpo4 = 0.0,
)
-class POMStaticVariables(TypedDict):
- kpom_20: float
-
-DEFAULT_POM = POMStaticVariables(
- kpom_20 = 0.01,
-)
class GlobalParameters(TypedDict):
use_NH4 : bool
@@ -312,7 +237,6 @@ class GlobalParameters(TypedDict):
use_POM = True
)
-
class GlobalVars(TypedDict):
vson: float
vsoc: float
@@ -326,13 +250,10 @@ class GlobalVars(TypedDict):
kah_20_user: float
hydraulic_reaeration_option: int
wind_reaeration_option: int
- Fr_PAR: float
- lambda0: float
- lambda1: float
- lambda2: float
- lambdas: float
- lambdam: float
timestep: float
+ depth: float
+ TwaterC: float
+ theta: float
velocity: float
flow: float
topwidth: float
@@ -342,6 +263,13 @@ class GlobalVars(TypedDict):
wind_speed: float
q_solar: float
Solid: int
+ lambda0: float
+ lambda1: float
+ lambda2: float
+ lambdas: float
+ lambdam: float
+ Fr_PAR: float
+
DEFAULT_GLOBALVARS = GlobalVars(
@@ -356,14 +284,11 @@ class GlobalVars(TypedDict):
kaw_20_user = 999,
kah_20_user = 999,
hydraulic_reaeration_option = 2,
- wind_reaeration_option = 2,
- Fr_PAR = .5,
- lambda0 = .5,
- lambda1 = .5,
- lambda2 = .5,
- lambdas = .5,
- lambdam = .5,
- timestep = 86400,
+ wind_reaeration_option = 2,
+ timestep = 1, #TODO Dynamic or static?
+ depth = 1.5, #TODO Dynamic or static?
+ TwaterC = 20,
+ theta = 1.047,
velocity = 1,
flow = 2,
topwidth = 1,
@@ -371,6 +296,12 @@ class GlobalVars(TypedDict):
shear_velocity = 4,
pressure_atm = 2,
wind_speed = 4,
- q_solar = 4,
- Solid = 1
+ q_solar = 500,
+ Solid = 1,
+ lambda0 = .02,
+ lambda1 = .0088,
+ lambda2 = .054,
+ lambdas = .052,
+ lambdam = .0174,
+ Fr_PAR = .47
)
diff --git a/src/clearwater_modules/nsm1/dynamic_variables.py b/src/clearwater_modules/nsm1/dynamic_variables.py
new file mode 100644
index 0000000..6d925ef
--- /dev/null
+++ b/src/clearwater_modules/nsm1/dynamic_variables.py
@@ -0,0 +1,1408 @@
+import clearwater_modules.base as base
+from clearwater_modules.nsm1.model import NutrientBudget
+
+import clearwater_modules.nsm1.processes as processes
+
+@base.register_variable(models=NutrientBudget)
+class Variable(base.Variable):
+ ...
+
+############################################ From dynamic_variables_global
+
+Variable(
+ name='TwaterK',
+ long_name='Water Temperature K',
+ units='K',
+ description='Water temperature degree kelvin',
+ use='dynamic',
+ process=processes.TwaterK
+)
+
+Variable(
+ name='SOD_tc',
+ long_name='Sediment Oxygen Demand at water temperature tc',
+ units='mg/L',
+ description='Sediment Oxygen Demand at water temperature tc',
+ use='dynamic',
+ process=processes.SOD_tc
+)
+
+Variable(
+ name='kah_20',
+ long_name='Hydraulic oxygen reaeration rate adjusted for hydraulics',
+ units='1/d',
+ description='Hydraulic oxygen reaeration rate adjusted for hydraulic parameters according to XX lit',
+ use='dynamic',
+ process=processes.kah_20
+)
+
+Variable(
+ name='kah_tc',
+ long_name='Hydraulic oxygen reaeration rate adjusted for temperature',
+ units='1/d',
+ description='Hydraulic oxygen reaeration rate adjusted for temperature',
+ use='dynamic',
+ process=processes.kah_tc
+)
+
+Variable(
+ name='kaw_20',
+ long_name='Wind oxygen reaeration velocity adjusted for hydraulics',
+ units='m/d',
+ description='Wind oxygen reaeration velocity adjusted for hydraulic parameters according to XX lit',
+ use='dynamic',
+ process=processes.kaw_20
+)
+
+Variable(
+ name='kaw_tc',
+ long_name='Wind oxygen reaeration velocity adjusted for temperature',
+ units='m/d',
+ description='Wind oxygen reaeration velocity adjusted for temperature',
+ use='dynamic',
+ process=processes.kaw_tc
+)
+
+Variable(
+ name='ka_tc',
+ long_name='Oxygen reaeration rate',
+ units='1/d',
+ description='Oxygen reaeration rate',
+ use='dynamic',
+ process=processes.ka_tc
+)
+
+Variable(
+ name='L',
+ long_name='Light attenuation coefficient',
+ units='unitless',
+ description='Light attenuation coefficient',
+ use='dynamic',
+ process=processes.L
+)
+
+Variable(
+ name='PAR',
+ long_name='surface light intensity',
+ units='W/m2',
+ description='surface light intensity',
+ use='dynamic',
+ process=processes.PAR
+)
+
+Variable(
+ name='fdp',
+ long_name='Fraction phosphorus dissolved',
+ units='Unitless',
+ description='Fraction phosphorus dissolved',
+ use='dynamic',
+ process=processes.fdp
+)
+
+############################################ From algae
+Variable(
+ name='rna',
+ long_name='Algal N:Chla Ratio',
+ units='mg-N/ug Chla',
+ description='Algal N:Chla Ratio',
+ use='dynamic',
+ process=processes.rna
+)
+
+Variable(
+ name='rpa',
+ long_name='Algal P:Chla Ratio',
+ units='mg-P/ug Chla',
+ description='Algal P:Chla Ratio',
+ use='dynamic',
+ process=processes.rpa
+)
+
+Variable(
+ name='rca',
+ long_name='Algal C:Chla Ratio',
+ units='mg-C/ug Chla',
+ description='Algal C:Chla Ratio',
+ use='dynamic',
+ process=processes.rca
+)
+
+Variable(
+ name='rda',
+ long_name='Algal D:Chla Ratio',
+ units='mg-D/ug Chla',
+ description='Algal D:Chla Ratio',
+ use='dynamic',
+ process=processes.rda
+)
+
+Variable(
+ name='mu_max_tc',
+ long_name='Max Algae Growth with Temperature Correction',
+ units='1/d',
+ description='Max Algae Growth with Temperature Correction',
+ use='dynamic',
+ process=processes.mu_max_tc,
+)
+
+Variable(
+ name='krp_tc',
+ long_name='Algal Respiration Rate with Temperature Correction',
+ units='1/d',
+ description='Algal Respiration Rate with Temperature Correction',
+ use='dynamic',
+ process=processes.krp_tc,
+)
+
+Variable(
+ name='kdp_tc',
+ long_name='Algal Mortality Rate with Temperature Correction',
+ units='1/d',
+ description='Algal Mortality Rate with Temperature Correction',
+ use='dynamic',
+ process=processes.kdp_tc,
+)
+
+Variable(
+ name='FL',
+ long_name='Algal Light Limitation',
+ units='unitless',
+ description='Algal Light Limitation',
+ use='dynamic',
+ process=processes.FL,
+)
+
+Variable(
+ name='FN',
+ long_name='Algal Nitrogen Limitation',
+ units='unitless',
+ description='Algal Nitrogen Limitation',
+ use='dynamic',
+ process=processes.FN,
+)
+
+Variable(
+ name='FP',
+ long_name='Algal Phosphorus Limitation',
+ units='unitless',
+ description='Algal Phosphorus Limitation',
+ use='dynamic',
+ process=processes.FP,
+)
+
+Variable(
+ name='mu',
+ long_name='Algal Growth Rate',
+ units='1/d',
+ description='Algal Growth Rate',
+ use='dynamic',
+ process=processes.mu,
+)
+
+Variable(
+ name='ApGrowth',
+ long_name='Algal Growth',
+ units='ug-Chala/L/d',
+ description='Algal Growth',
+ use='dynamic',
+ process=processes.ApGrowth,
+)
+
+Variable(
+ name='ApRespiration',
+ long_name='Algal Respiration',
+ units='ug-Chala/L/d',
+ description='Algal Respiration',
+ use='dynamic',
+ process=processes.ApRespiration,
+)
+
+Variable(
+ name='ApDeath',
+ long_name='Algal Death',
+ units='ug-Chala/L/d',
+ description='Algal Death',
+ use='dynamic',
+ process=processes.ApDeath,
+)
+
+Variable(
+ name='ApSettling',
+ long_name='Algal Settling',
+ units='ug-Chala/L/d',
+ description='Algal Settling',
+ use='dynamic',
+ process=processes.ApSettling,
+)
+
+Variable(
+ name='dApdt',
+ long_name='Algal Biomass Concentration Change',
+ units='ug-Chala/L/d',
+ description='Algal Biomass Concentration Change',
+ use='dynamic',
+ process=processes.dApdt,
+)
+
+############################################ From benthic algae
+Variable(
+ name='mub_max_tc',
+ long_name='Maximum benthic algal growth rate',
+ units='1/d',
+ description='Maximum benthic algal growth rate with temperature correction',
+ use='dynamic',
+ process=processes.mub_max_tc
+)
+
+Variable(
+ name='krb_tc',
+ long_name='Benthic algae respiration rate',
+ units='1/d',
+ description='Benthic algae respiration rate with temperature correction',
+ use='dynamic',
+ process=processes.krb_tc
+)
+
+Variable(
+ name='kdb_tc',
+ long_name='Benthic algae mortality rate',
+ units='1/d',
+ description='Benthic algae mortality rate with temperature correction',
+ use='dynamic',
+ process=processes.kdb_tc
+)
+
+Variable(
+ name='rnb',
+ long_name='Ratio nitrogen to dry weight',
+ units='mg-N/mg-D',
+ description='Ratio benthic algae nitrogen to dry weight',
+ use='dynamic',
+ process=processes.rnb
+)
+
+Variable(
+ name='rpb',
+ long_name='Ratio benthic algae phosphorus to dry weight',
+ units='mg-P/mg-D',
+ description='Ratio benthic algae phosphorus to dry weight',
+ use='dynamic',
+ process=processes.rpb
+)
+
+Variable(
+ name='rcb',
+ long_name='Ratio benthic algae carbon to dry weight',
+ units='mg-C/mg-D',
+ description='Ratio benthic algae carbon to dry weight',
+ use='dynamic',
+ process=processes.rcb
+)
+
+Variable(
+ name='rab',
+ long_name='Ratio benthic algae chlorophyll-a to dry weight',
+ units='ug-Chala-a/mg-D',
+ description='Ratio benthic algae chlorophyll-a to dry weight',
+ use='dynamic',
+ process=processes.rab
+)
+
+Variable(
+ name='FLb',
+ long_name='Benthic algal light limitation factor',
+ units='unitless',
+ description='Benthic algal light limitation factor',
+ use='dynamic',
+ process=processes.FLb
+)
+
+Variable(
+ name='FNb',
+ long_name='Benthic algal nitrogen limitation factor',
+ units='unitless',
+ description='Benthic algal nitrogen limitation factor',
+ use='dynamic',
+ process=processes.FNb
+)
+
+Variable(
+ name='FPb',
+ long_name='Benthic algal phosphorous limitation factor',
+ units='unitless',
+ description='Benthic algal phosphorous limitation factor',
+ use='dynamic',
+ process=processes.FPb
+)
+
+Variable(
+ name='FSb',
+ long_name='Benthic algal density attenuation',
+ units='unitless',
+ description='Benthic algal density attenuation',
+ use='dynamic',
+ process=processes.FSb
+)
+
+Variable(
+ name='mub',
+ long_name='Benthic algae specific growth rate',
+ units='1/d',
+ description='Benthic algae specific growth rate',
+ use='dynamic',
+ process=processes.mub
+)
+
+Variable(
+ name='AbGrowth',
+ long_name='Benthic algae growth rate',
+ units='g/m^2/d',
+ description='Benthic algae growth rate',
+ use='dynamic',
+ process=processes.AbGrowth
+)
+
+Variable(
+ name='AbRespiration',
+ long_name='Benthic algae respiration rate',
+ units='g/m^2/d',
+ description='Benthic algae respiration rate',
+ use='dynamic',
+ process=processes.AbRespiration
+)
+
+Variable(
+ name='AbDeath',
+ long_name='Benthic algae death rate',
+ units='g/m^2/d',
+ description='Benthic algae death rate',
+ use='dynamic',
+ process=processes.AbDeath
+)
+
+Variable(
+ name='dAbdt',
+ long_name='Change in benthic algae concentration',
+ units='g/m^2/d',
+ description='Change in benthic algae concentration',
+ use='dynamic',
+ process=processes.dAbdt
+)
+
+Variable(#TODO: figure out what this is...
+ name='Chlb',
+ long_name='Chlorophyll-a concentration',
+ units='mg-Chla/m^2',
+ description='Chlorophyll-a concentration',
+ use='dynamic',
+ process=processes.Chlb
+)
+
+############################################ From nitrogen
+Variable(
+ name='knit_tc',
+ long_name='Nitrification rate ammonia decay',
+ units='1/d',
+ description='Nitrification rate ammonia decay temperature correction',
+ use='dynamic',
+ process=processes.knit_tc
+)
+
+Variable(
+ name='rnh4_tc',
+ long_name='Sediment release rate of NH4',
+ units='1/d',
+ description=' Sediment release rate of NH4 temperature correction',
+ use='dynamic',
+ process=processes.rnh4_tc
+)
+
+Variable(
+ name='vno3_tc',
+ long_name='Sediment denitrification velocity',
+ units='m/d',
+ description='Sediment denitrification velocity temperature correction',
+ use='dynamic',
+ process=processes.vno3_tc
+)
+
+Variable(
+ name='kon_tc',
+ long_name='Decay rate of OrgN to NH4',
+ units='1/d',
+ description='Decay rate of OrgN to NH4 temperature correction',
+ use='dynamic',
+ process=processes.kon_tc
+)
+
+Variable(
+ name='kdnit_tc',
+ long_name='Denitrification rate',
+ units='1/d',
+ description='Denitrification rate temperature correction',
+ use='dynamic',
+ process=processes.kdnit_tc
+)
+
+Variable(
+ name='ApUptakeFr_NH4',
+ long_name='Fraction of actual floating algal uptake from ammonia pool',
+ units='unitless',
+ description='Fraction of actual floating algal uptake from ammonia pool',
+ use='dynamic',
+ process=processes.ApUptakeFr_NH4
+)
+
+Variable(
+ name='ApUptakeFr_NO3',
+ long_name='Fraction of actual floating algal uptake from nitrate pool',
+ units='unitless',
+ description='Fraction of actual floating algal uptake from nitrate pool',
+ use='dynamic',
+ process=processes.ApUptakeFr_NO3
+)
+
+Variable(
+ name='AbUptakeFr_NH4',
+ long_name='Fraction of actual benthic algal uptake from ammonia pool',
+ units='unitless',
+ description='Fraction of actual benthic algal uptake from ammonia pool',
+ use='dynamic',
+ process=processes.AbUptakeFr_NH4
+)
+
+Variable(
+ name='AbUptakeFr_NO3',
+ long_name='Fraction of actual benthic algal uptake from nitrate pool',
+ units='unitless',
+ description='Fraction of actual benthic algal uptake from nitrate pool',
+ use='dynamic',
+ process=processes.AbUptakeFr_NO3
+)
+
+Variable(
+ name='ApDeath_OrgN',
+ long_name='Algae -> OrgN',
+ units='mg-N/L/d',
+ description='Algae conversion to Organic nitrogen',
+ use='dynamic',
+ process=processes.ApDeath_OrgN
+)
+
+Variable(
+ name='AbDeath_OrgN',
+ long_name='Benthic Algae -> OrgN',
+ units='mg-N/L/d',
+ description='Benthic algae conversion to Organic nitrogen',
+ use='dynamic',
+ process=processes.AbDeath_OrgN
+)
+
+Variable(
+ name='OrgN_NH4_Decay',
+ long_name='OrgN -> NH4',
+ units='mg-N/L/d',
+ description='Organic nitrogen to ammonium decay',
+ use='dynamic',
+ process=processes.OrgN_NH4_Decay
+)
+
+Variable(
+ name='OrgN_Settling',
+ long_name='OrgN -> bed',
+ units='mg-N/L/d',
+ description='Organic nitrogen to bed settling',
+ use='dynamic',
+ process=processes.OrgN_Settling
+)
+
+Variable(
+ name='dOrgNdt',
+ long_name='Change in organic nitrogen',
+ units='mg-N/L',
+ description='Change in organic nitrogen',
+ use='dynamic',
+ process=processes.dOrgNdt
+)
+
+Variable(
+ name='NH4_Nitrification',
+ long_name='NH4 -> NO3 Nitrification',
+ units='mg-N/L/d',
+ description='NH4 Nitrification',
+ use='dynamic',
+ process=processes.NH4_Nitrification
+)
+
+Variable(
+ name='NH4fromBed',
+ long_name='bed -> NH4 (diffusion)',
+ units='mg-N/L/d',
+ description='Sediment bed release of NH4',
+ use='dynamic',
+ process=processes.NH4fromBed
+)
+
+Variable(
+ name='NH4_ApRespiration',
+ long_name='Floating algae -> NH4',
+ units='mg-N/L/d',
+ description='Floating algae to NH4',
+ use='dynamic',
+ process=processes.NH4_ApRespiration
+)
+
+Variable(
+ name='NH4_ApGrowth',
+ long_name='NH4 -> Floating algae',
+ units='mg-N/L/d',
+ description='NH4 uptake to algae',
+ use='dynamic',
+ process=processes.NH4_ApGrowth
+)
+
+Variable(
+ name='NH4_AbRespiration',
+ long_name='Benthic algae -> NH4',
+ units='mg-N/L/d',
+ description='Benthic algae release of NH4',
+ use='dynamic',
+ process=processes.NH4_AbRespiration
+)
+
+Variable(
+ name='NH4_AbGrowth',
+ long_name='NH4 -> Benthic Algae',
+ units='mg-N/L/d',
+ description='Benthic algae uptake of NH4',
+ use='dynamic',
+ process=processes.NH4_AbGrowth
+)
+
+Variable(
+ name='dNH4dt',
+ long_name='Change in ammonium concentration',
+ units='mg-N/L',
+ description='Change in ammonium concentration',
+ use='dynamic',
+ process=processes.dNH4dt
+)
+
+Variable(
+ name='NO3_Denit',
+ long_name='NO3 -> Loss',
+ units='mg-N/L/d',
+ description='NO3 loss from denitrification',
+ use='dynamic',
+ process=processes.NO3_Denit
+)
+
+Variable(
+ name='NO3_BedDenit',
+ long_name='Sediment denitrification',
+ units='mg-N/L/d',
+ description='Sediment denitrification',
+ use='dynamic',
+ process=processes.NO3_BedDenit
+)
+
+Variable(
+ name='NO3_ApGrowth',
+ long_name='NO3 -> Floating algae',
+ units='mg-N/L/d',
+ description='NO3 uptake to floating algae',
+ use='dynamic',
+ process=processes.NO3_ApGrowth
+)
+
+Variable(
+ name='NO3_AbGrowth',
+ long_name='NO3 -> Benthic algae',
+ units='mg-N/L/d',
+ description='NO3 uptake to benthic algae',
+ use='dynamic',
+ process=processes.NO3_AbGrowth
+)
+
+Variable(
+ name='dNO3dt',
+ long_name='Change in nitrate concentration',
+ units='mg-N/L',
+ description='Change in nitrate concentration',
+ use='dynamic',
+ process=processes.dNO3dt
+)
+
+Variable(
+ name='DIN',
+ long_name='Dissolve inorganic nitrogen',
+ units='mg-N/L',
+ description='Dissolve inorganic nitrogen',
+ use='dynamic',
+ process=processes.DIN
+)
+
+Variable(
+ name='TON',
+ long_name='Total organic nitrogen',
+ units='mg-N/L',
+ description='Total organic nitrogen',
+ use='dynamic',
+ process=processes.TON
+)
+
+Variable(
+ name='TKN',
+ long_name='Total kjeldhl nitrogen',
+ units='mg-N/L',
+ description='Total kjeldhl nitrogen',
+ use='dynamic',
+ process=processes.TKN
+)
+
+Variable(
+ name='TN',
+ long_name='Total nitrogen',
+ units='mg-N/L',
+ description='Total nitrogen',
+ use='dynamic',
+ process=processes.TN
+)
+
+Variable(
+ name='NitrificationInhibition',
+ long_name='Nitrification Inhibitation (limits nitrification under low DO conditions)',
+ units='unitless',
+ description='Nitrification Inhibitation (limits nitrification under low DO conditions)',
+ use='dynamic',
+ process=processes.NitrificationInhibition
+)
+
+############################################ From phosphorus
+Variable(
+ name='kop_tc',
+ long_name='Decay rate of organic P to DIP',
+ units='1/d',
+ description='Decay rate of organic P to DIP temperature correction',
+ use='dynamic',
+ process=processes.kop_tc
+)
+
+Variable(
+ name='rpo4_tc',
+ long_name='Benthic sediment release rate of DIP',
+ units='g-P/m2/d',
+ description='Benthic sediment release rate of DIP temperature correction',
+ use='dynamic',
+ process=processes.rpo4_tc
+)
+
+Variable(
+ name='OrgP_DIP_decay',
+ long_name='Organic phosphorus decay to dissolve inorganic phosphorus',
+ units='mg-P/L/d',
+ description='Organic phosphorus decay to dissolve inorganic phosphorus',
+ use='dynamic',
+ process=processes.OrgP_DIP_decay
+)
+
+Variable(
+ name='OrgP_Settling',
+ long_name='Organic phosphorus settling to sediment',
+ units='mg-P/L/d',
+ description='Organic phosphorus settling to sediment',
+ use='dynamic',
+ process=processes.OrgP_Settling
+)
+
+Variable(
+ name='ApDeath_OrgP',
+ long_name='Algal death turning into organic phosphorus',
+ units='mg-P/L/d',
+ description='Algal death turning into organic phosphorus',
+ use='dynamic',
+ process=processes.ApDeath_OrgP
+)
+
+Variable(
+ name='AbDeath_OrgP',
+ long_name='Benthic algal death turning into organic phosphorus',
+ units='mg-P/L/d',
+ description='Benthic algal death turning into organic phosphorus',
+ use='dynamic',
+ process=processes.AbDeath_OrgP
+)
+
+Variable(
+ name='dOrgPdt',
+ long_name='Change in organic phosphorus concentration',
+ units='mg-P/L/d',
+ description='Change in organic phosphorus concentration',
+ use='dynamic',
+ process=processes.dOrgPdt
+)
+
+Variable(#TODO: find correct process
+ name='DIPfromBed',
+ long_name='Dissolved Organic Phosphorus coming from Bed calculated without SedFlux modules',
+ units='mg-P/L/d',
+ description='Dissolved Organic Phosphorus coming from Bed calculated without SedFlux modules',
+ use='dynamic',
+ process=processes.DIPfromBed
+)
+
+Variable(
+ name='TIP_Settling',
+ long_name='Total inorganic phosphorus settling from water to bed',
+ units='mg-P/L/d',
+ description='Total inorganic phosphorus settling from water to bed',
+ use='dynamic',
+ process=processes.TIP_Settling
+)
+
+Variable(
+ name='OrgP_DIP_decay',
+ long_name='Total organic phosphorus decaying to dissolved inorganic phosphrous',
+ units='mg-P/L/d',
+ description='Total organic phosphorus decaying to dissolved inorganic phosphrous',
+ use='dynamic',
+ process=processes.OrgP_DIP_decay
+)
+
+Variable(
+ name='DIP_ApRespiration',
+ long_name='Dissolved inorganic phosphorus released from algal respiration',
+ units='mg-P/L/d',
+ description='Dissolved inorganic phosphorus released from algal respiration',
+ use='dynamic',
+ process=processes.DIP_ApRespiration
+)
+
+Variable(
+ name='DIP_ApGrowth',
+ long_name='Dissolved inorganic phosphorus consumed for algal growth',
+ units='mg-P/L/d',
+ description='Dissolved inorganic phosphorus consumed for algal growth',
+ use='dynamic',
+ process=processes.DIP_ApGrowth
+)
+
+Variable(
+ name='DIP_AbRespiration',
+ long_name='Dissolved inorganic phosphorus released for benthic algal respiration',
+ units='mg-P/L/d',
+ description='Dissolved inorganic phosphorus released for benthic algal respiration',
+ use='dynamic',
+ process=processes.DIP_AbRespiration
+)
+
+Variable(
+ name='DIP_AbGrowth',
+ long_name='Dissolved inorganic phosphorus consumed for benthic algal growth',
+ units='mg-P/L/d',
+ description='Dissolved inorganic phosphorus consumed for benthic algal growth',
+ use='dynamic',
+ process=processes.DIP_AbGrowth
+)
+
+Variable(
+ name='dTIPdt',
+ long_name='Change in dissolved inorganic phosphorus water concentration',
+ units='mg-P/L/d',
+ description='Change in dissolved inorganic phosphorus water concentration',
+ use='dynamic',
+ process=processes.dTIPdt
+)
+
+Variable(
+ name='TOP',
+ long_name='Total organic phosphorus',
+ units='mg-P/L',
+ description='Total organic phosphorus',
+ use='dynamic',
+ process=processes.TOP
+)
+
+Variable(
+ name='TP',
+ long_name='Total phosphorus',
+ units='mg-P/L',
+ description='Total phosphorus',
+ use='dynamic',
+ process=processes.TP
+)
+
+Variable(
+ name='DIP',
+ long_name='Dissolve inorganic phosphorus',
+ units='mg-P/L',
+ description='Dissolve inorganic phosphorus',
+ use='dynamic',
+ process=processes.DIP
+)
+
+############################################ From POM
+Variable(
+ name='kpom_tc',
+ long_name='POM dissolution rate adjusted for temperature',
+ units='1/d',
+ description='POM dissolution rate adjusted for temperature',
+ use='dynamic',
+ process=processes.kpom_tc
+)
+
+Variable(
+ name='POM_algal_settling',
+ long_name='POM concentration change due to algal settling',
+ units='mg/L/d',
+ description='POM concentration change due to algal settling',
+ use='dynamic',
+ process=processes.POM_algal_settling
+)
+
+Variable(
+ name='POM_dissolution',
+ long_name='POM concentration change due to dissolution',
+ units='mg/L/d',
+ description='POM concentration change due to dissolution',
+ use='dynamic',
+ process=processes.POM_dissolution
+)
+
+Variable(
+ name='POM_POC_settling',
+ long_name='POM concentration change due to POC settling',
+ units='mg/L/d',
+ description='POM concentration change due to POC settling',
+ use='dynamic',
+ process=processes.POM_POC_settling
+)
+
+Variable(
+ name='POM_benthic_algae_mortality',
+ long_name='POM concentration change due to algae mortality',
+ units='mg/L/d',
+ description='POM concentration change due to algae mortality',
+ use='dynamic',
+ process=processes.POM_benthic_algae_mortality
+)
+
+Variable(
+ name='POM_burial',
+ long_name='POM concentration change due to burial',
+ units='mg/L/d',
+ description='POM concentration change due to burial',
+ use='dynamic',
+ process=processes.POM_burial
+)
+
+Variable(
+ name='dPOMdt',
+ long_name='Change in POM concentration for one timestep',
+ units='mg/L/d',
+ description='Change in POM concentration for one timestep',
+ use='dynamic',
+ process=processes.dPOMdt
+)
+
+############################################ From CBOD
+Variable(
+ name='kbod_tc',
+ long_name='Temperature adjusted oxidation rate',
+ units='1/d',
+ description='Temperature adjusted oxidation rate',
+ use='dynamic',
+ process=processes.kbod_tc
+)
+
+Variable(
+ name='ksbod_tc',
+ long_name='Temperature adjusted sedimentation rate',
+ units='m/d',
+ description='Temperature adjusted sedimentation rate',
+ use='dynamic',
+ process=processes.ksbod_tc
+)
+
+Variable(
+ name='CBOD_oxidation',
+ long_name='CBOD oxidation',
+ units='mg/L/d',
+ description='CBOD oxidation',
+ use='dynamic',
+ process=processes.CBOD_oxidation
+)
+
+Variable(
+ name='CBOD_sedimentation',
+ long_name='CBOD sedimentation',
+ units='mg/L/d',
+ description='CBOD sedimentation',
+ use='dynamic',
+ process=processes.CBOD_sedimentation
+)
+
+Variable(
+ name='dCBODdt',
+ long_name='Change in CBOD concentration for the given timestep',
+ units='mg/L/d',
+ description='Change in CBOD concentration for the given timestep',
+ use='dynamic',
+ process=processes.dCBODdt
+)
+
+############################################ From carbon
+Variable(
+ name='kpoc_tc',
+ long_name='Temperature adjusted POC hydrolysis rate',
+ units='1/d',
+ description='Temperature adjusted POC hydrolysis rate',
+ use='dynamic',
+ process=processes.kpoc_tc,
+)
+
+Variable(
+ name='POC_settling',
+ long_name='POC concentration removed from cell due to settling',
+ units='mg/L/d',
+ description='POC concentration removed from cell due to settling',
+ use='dynamic',
+ process=processes.POC_settling,
+)
+
+Variable(
+ name='POC_hydrolysis',
+ long_name='POC concentration removed from cell due to hydrolysis',
+ units='mg/L/d',
+ description='POC concentration removed from cell due to hydrolysis',
+ use='dynamic',
+ process=processes.POC_hydrolysis,
+)
+
+Variable(
+ name='POC_algal_mortality',
+ long_name='POC concentration added to cell due to algal mortality',
+ units='mg/L/d',
+ description='POC concentration added to cell due to algal mortality',
+ use='dynamic',
+ process=processes.POC_algal_mortality,
+)
+
+Variable(
+ name='POC_benthic_algae_mortality',
+ long_name='POC concentration added to cell due to benthic algae mortality',
+ units='mg/L/d',
+ description='POC concentration added to cell due to benthic algae mortality',
+ use='dynamic',
+ process=processes.POC_benthic_algae_mortality,
+)
+
+Variable(
+ name='dPOCdt',
+ long_name='POC concentration change per timestep',
+ units='mg/L/d',
+ description='POC concentration change per timestep',
+ use='dynamic',
+ process=processes.dPOCdt
+)
+
+Variable(
+ name='kdoc_tc',
+ long_name='Dissolved organic carbon oxidation rate adjusted for temperature',
+ units='1/d',
+ description='Dissolved organic carbon oxidation rate adjusted for temperature',
+ use='dynamic',
+ process=processes.kdoc_tc
+)
+
+Variable(
+ name='DOC_algal_mortality',
+ long_name='DOC concentration added to cell due to algal mortality',
+ units='mg/L/d',
+ description='DOC concentration added to cell due to algal mortality',
+ use='dynamic',
+ process=processes.DOC_algal_mortality
+)
+
+Variable(
+ name='DOC_benthic_algae_mortality',
+ long_name='DOC concentration added to cell due to benthic algae mortality',
+ units='mg/L/d',
+ description='DOC concentration added to cell due to benthic algae mortality',
+ use='dynamic',
+ process=processes.DOC_benthic_algae_mortality,
+)
+
+Variable(
+ name='DOC_DIC_oxidation',
+ long_name='DOC concentration lost to cell due to oxidation',
+ units='mg/L/d',
+ description='DOC concentration lost to cell due to oxidation',
+ use='dynamic',
+ process=processes.DOC_DIC_oxidation
+)
+
+Variable(
+ name='dDOCdt',
+ long_name='DOC concentration change per timestep',
+ units='mg/L/d',
+ description='DOC concentration change per timestep',
+ use='dynamic',
+ process=processes.dDOCdt
+)
+
+Variable(
+ name='K_H',
+ long_name='Henrys coefficient',
+ units='mol/L-atm',
+ description='Henrys coefficient controlling the relative proportion of gaseous and aqueous phase CO2',
+ use='dynamic',
+ process=processes.Henrys_k
+)
+
+Variable(
+ name='Atm_CO2_reaeration',
+ long_name='Atmospheric CO2 reaeration',
+ units='mg/L/d',
+ description='Amount of DIC concentration change due to atmospheric exchange',
+ use='dynamic',
+ process=processes.Atmospheric_CO2_reaeration
+)
+
+Variable(
+ name='DIC_algal_respiration',
+ long_name='DIC generated by algal respiration',
+ units='mg/L/d',
+ description='DIC generated by algal respiration',
+ use='dynamic',
+ process=processes.DIC_algal_respiration
+)
+
+Variable(
+ name='DIC_algal_photosynthesis',
+ long_name='DIC consumed by algal photosynthesis',
+ units='mg/L/d',
+ description='DIC consumed by algal photosynthesis',
+ use='dynamic',
+ process=processes.DIC_algal_photosynthesis
+)
+
+Variable(
+ name='DIC_benthic_algae_respiration',
+ long_name='DIC generated by benthic algae respiration',
+ units='mg/L/d',
+ description='DIC generated by benthic algae respiration',
+ use='dynamic',
+ process=processes.DIC_benthic_algae_respiration
+)
+
+Variable(
+ name='DIC_benthic_algae_photosynthesis',
+ long_name='DIC consumed by benthic algae photosynthesis',
+ units='mg/L/d',
+ description='DIC consumed by benthic algae photosynthesis',
+ use='dynamic',
+ process=processes.DIC_benthic_algae_photosynthesis
+)
+
+Variable(
+ name='DIC_CBOD_oxidation',
+ long_name='DIC concentration change due to CBOD oxidation',
+ units='mg/L/d',
+ description='DIC concentration change due to CBOD oxidation',
+ use='dynamic',
+ process=processes.DIC_CBOD_oxidation
+)
+
+
+Variable(
+ name='DIC_sed_release',
+ long_name='DIC concentration change due to sediment release',
+ units='mg/L/d',
+ description='DIC concentration change due to sediment release',
+ use='dynamic',
+ process=processes.DIC_sed_release
+)
+
+Variable(
+ name='dDICdt',
+ long_name='DIC concentration change per timestep',
+ units='mg/L/d',
+ description='DIC concentration change per timestep',
+ use='dynamic',
+ process=processes.dDICdt
+)
+
+############################################ From DOX
+Variable(
+ name='DOX_sat',
+ long_name='DO saturation concentration',
+ units='mg/L',
+ description='DO saturation concentration in water as a function of water temperature (K)',
+ use='dynamic',
+ process=processes.DOX_sat
+)
+
+Variable(
+ name='pwv',
+ long_name='Partial pressure of water vapor',
+ units='atm',
+ description='Partial pressure of water vapor',
+ use='dynamic',
+ process=processes.pwv
+)
+
+Variable(
+ name='DOs_atm_alpha',
+ long_name='DO saturation atmospheric correction coefficient',
+ units='unitless',
+ description='DO saturation atmospheric correction coefficient',
+ use='dynamic',
+ process=processes.DOs_atm_alpha
+)
+
+Variable(
+ name='Atm_O2_reaeration',
+ long_name='Atmospheric oxygen reaeration',
+ units='mg/L/d',
+ description='Atmospheric oxygen reaeration, can fluctuate both in and out of waterbody',
+ use='dynamic',
+ process=processes.Atm_O2_reaeration
+)
+
+Variable(
+ name='DOX_ApGrowth',
+ long_name='Dissolved oxygen flux due to algal photosynthesis',
+ units='mg/L/d',
+ description='Dissolved oxygen flux due to algal photosynthesis',
+ use='dynamic',
+ process=processes.DOX_ApGrowth
+)
+
+Variable(
+ name='DOX_ApRespiration',
+ long_name='Dissolved oxygen flux due to algal respiration',
+ units='mg/L/d',
+ description='Dissolved oxygen flux due to algal respiration',
+ use='dynamic',
+ process=processes.DOX_ApRespiration
+)
+
+Variable(
+ name='DOX_Nitrification',
+ long_name='Dissolved oxygen flux due to nitrification',
+ units='mg/L/d',
+ description='Dissolved oxygen flux due to nitrification',
+ use='dynamic',
+ process=processes.DOX_Nitrification
+)
+
+Variable(
+ name='DOX_DOC_oxidation',
+ long_name='Dissolved oxygen flux due to DOC oxidation',
+ units='mg/L/d',
+ description='Dissolved oxygen flux due to DOC oxidation',
+ use='dynamic',
+ process=processes.DOX_DOC_oxidation
+)
+
+Variable(
+ name='DOX_CBOD_oxidation',
+ long_name='Dissolved oxygen flux due to CBOD oxidation',
+ units='mg/L/d',
+ description='Dissolved oxygen flux due to CBOD oxidation',
+ use='dynamic',
+ process=processes.DOX_CBOD_oxidation
+)
+
+Variable(
+ name='DOX_AbGrowth',
+ long_name='Dissolved oxygen flux due to benthic algae photosynthesis',
+ units='mg/L/d',
+ description='Dissolved oxygen flux due to benthic algae photosynthesis',
+ use='dynamic',
+ process=processes.DOX_AbGrowth
+)
+
+Variable(
+ name='DOX_AbRespiration',
+ long_name='Dissolved oxygen flux due to benthic algae respiration',
+ units='mg/L/d',
+ description='Dissolved oxygen flux due to benthic algae respiration',
+ use='dynamic',
+ process=processes.DOX_AbRespiration
+)
+
+Variable(
+ name='DOX_SOD',
+ long_name='Dissolved oxygen flux due to sediment oxygen demand',
+ units='mg/L/d',
+ description='Dissolved oxygen flux due to sediment oxygen demand',
+ use='dynamic',
+ process=processes.DOX_SOD
+)
+
+Variable(
+ name='dDOXdt',
+ long_name='Change in dissolved oxygen concentration for one timestep',
+ units='mg/L/d',
+ description='Change in dissolved oxygen concentration for one timestep',
+ use='dynamic',
+ process=processes.dDOXdt
+)
+
+############################################ From pathogen
+Variable(
+ name='kdx_tc',
+ long_name='Pathogen death rate',
+ units='1/d',
+ description='Pathogen death rate with temperature correction',
+ use='dynamic',
+ process=processes.kdx_tc
+)
+
+Variable(
+ name='PathogenDeath',
+ long_name='Pathogen natural death',
+ units='cfu/100mL/d',
+ description='Pathogen natural death',
+ use='dynamic',
+ process=processes.PathogenDeath
+)
+
+Variable(
+ name='PathogenDecay',
+ long_name='Pathogen death due to light',
+ units='cfu/100mL/d',
+ description='Pathogen death due to light',
+ use='dynamic',
+ process=processes.PathogenDecay
+)
+
+Variable(
+ name='PathogenSettling',
+ long_name='Pathogen settling',
+ units='cfu/100mL/d',
+ description='Pathogen settling',
+ use='dynamic',
+ process=processes.PathogenSettling
+)
+
+Variable(
+ name='dPXdt',
+ long_name='Change in pathogen concentration',
+ units='cfu/100mL/d',
+ description='Change in pathogen concentration',
+ use='dynamic',
+ process=processes.dPXdt
+)
+
+############################################ From alkalinity
+Variable(
+ name='Alk_denitrification',
+ long_name='Alkalinity change due to denitrification',
+ units='mg/L/d',
+ description='Alkalinity change due to denitrification',
+ use='dynamic',
+ process=processes.Alk_denitrification
+)
+
+Variable(
+ name='Alk_nitrification',
+ long_name='Alkalinity change due to nitrification',
+ units='mg/L/d',
+ description='Alkalinity change due to nitrification',
+ use='dynamic',
+ process=processes.Alk_nitrification
+)
+
+Variable(
+ name='Alk_algal_growth',
+ long_name='Alkalinity change due to algal growth',
+ units='mg/L/d',
+ description='Alkalinity change due to algal growth',
+ use='dynamic',
+ process=processes.Alk_algal_growth
+)
+
+Variable(
+ name='Alk_algal_respiration',
+ long_name='Alkalinity change due to algal respiration',
+ units='mg/L/d',
+ description='Alkalinity change due to algal respiration',
+ use='dynamic',
+ process=processes.Alk_algal_respiration
+)
+
+Variable(
+ name='Alk_benthic_algae_growth',
+ long_name='Alkalinity change due to benthic algae growth',
+ units='mg/L/d',
+ description='Alkalinity change due to benthic algae growth',
+ use='dynamic',
+ process=processes.Alk_benthic_algae_growth
+)
+
+Variable(
+ name='Alk_benthic_algae_respiration',
+ long_name='Alkalinity change due to benthic algae growth',
+ units='mg/L/d',
+ description='Alkalinity change due to benthic algae growth',
+ use='dynamic',
+ process=processes.Alk_benthic_algae_respiration
+)
+
+Variable(
+ name='dAlkdt',
+ long_name='Alkalinity concentration change per timestep',
+ units='mg/L/d',
+ description='Alkalinity concentration change per timestep',
+ use='dynamic',
+ process=processes.dAlkdt
+)
+
+############################################ From N2
+Variable(
+ name='KHN2_tc',
+ long_name='Henrys law constant',
+ units='mol/L/atm',
+ description='Henrys law constant temperature corrected',
+ use='dynamic',
+ 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',
+ long_name='N2 at saturation',
+ units='mg-N/L',
+ description='N2 at saturation f(Twater and atm pressure)',
+ use='dynamic',
+ process=processes.N2sat
+)
+
+Variable(
+ name='dN2dt',
+ long_name='Change in N2 air concentration',
+ units='mg-N/L/d',
+ description='Change in N2 air concentration',
+ use='dynamic',
+ process=processes.dN2dt
+)
+
+Variable(
+ name='TDG',
+ long_name='Total dissolved gas',
+ units='%',
+ description='Total dissolved gas',
+ use='dynamic',
+ process=processes.TDG
+)
diff --git a/src/clearwater_modules/nsm1/model.py b/src/clearwater_modules/nsm1/model.py
index 1da9c1d..2bc1121 100644
--- a/src/clearwater_modules/nsm1/model.py
+++ b/src/clearwater_modules/nsm1/model.py
@@ -18,6 +18,7 @@ class NutrientBudget(base.Model):
def __init__(
self,
+ time_steps: int,
initial_state_values: Optional[base.InitialVariablesDict] = None,
updateable_static_variables: Optional[list[str]] = None,
algae_parameters: Optional[dict[str, float]] = None,
@@ -168,6 +169,7 @@ def __init__(
#static_variable_values['use_sed_temp'] = use_sed_temp
super().__init__(
+ time_steps=time_steps,
initial_state_values=initial_state_values,
static_variable_values=static_variable_values,
updateable_static_variables=updateable_static_variables,
diff --git a/src/clearwater_modules/nsm1/n2/processes.py b/src/clearwater_modules/nsm1/n2/processes.py
index 75341f4..5e6005b 100644
--- a/src/clearwater_modules/nsm1/n2/processes.py
+++ b/src/clearwater_modules/nsm1/n2/processes.py
@@ -82,6 +82,7 @@ def dN2dt(
def N2(
N2: xr.DataArray,
dN2dt : xr.DataArray,
+ timestep: xr.DataArray
) -> xr.DataArray:
"""Calculate change in N2 air concentration (mg-N/L/d)
@@ -89,9 +90,10 @@ def N2(
Args:
N2: Nitrogen concentration air (mg-N/L)
dN2dt: Change in nitrogen concentration air
+ timestep: Current iteration timestep (d)
"""
- return N2 + dN2dt
+ return N2 + dN2dt * timestep
@numba.njit
def TDG(
diff --git a/src/clearwater_modules/nsm1/pathogens/processes.py b/src/clearwater_modules/nsm1/pathogens/processes.py
index 509094a..2488f49 100644
--- a/src/clearwater_modules/nsm1/pathogens/processes.py
+++ b/src/clearwater_modules/nsm1/pathogens/processes.py
@@ -95,7 +95,8 @@ def dPXdt(
@numba.njit
def PX(
PX:xr.DataArray,
- dPXdt: xr.DataArray
+ dPXdt: xr.DataArray,
+ timestep: xr.DataArray
) -> xr.DataArray :
@@ -104,5 +105,6 @@ def PX(
Args:
dPXdt: change in pathogen concentration (cfu/100mL/d)
PX: Pathogen concentration (cfu/100mL)
+ timestep: Current iteration timestep (d)
"""
- return PX+dPXdt
\ No newline at end of file
+ return PX + timestep * dPXdt
\ No newline at end of file
diff --git a/src/clearwater_modules/nsm1/processes.py b/src/clearwater_modules/nsm1/processes.py
new file mode 100644
index 0000000..3837b07
--- /dev/null
+++ b/src/clearwater_modules/nsm1/processes.py
@@ -0,0 +1,3507 @@
+import warnings
+import numba
+import numpy as np
+import xarray as xr
+import math
+
+############################################ 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
+
+
+def arrhenius_correction(
+ TwaterC: xr.DataArray,
+ rc20: xr.DataArray,
+ theta: xr.DataArray,
+) -> xr.DataArray:
+ """
+ Computes an adjusted kinetics reaction rate coefficient for the specified water
+ temperature using the van't Hoff form of the Arrhenius equation
+
+ Parameters
+ ----------
+ TwaterC : xr.DataArray
+ Water temperature in degrees Celsius
+ rc20 : xr.DataArray
+ Kinetics reaction (decay) coefficient at 20 degrees Celsius
+ theta : xr.DataArray
+ Temperature correction factor
+
+ Returns
+ ----------
+ float
+ Adjusted kinetics rate for the specified water temperature
+ """
+ return rc20 * theta**(TwaterC - 20.0)
+
+
+
+def TwaterK(
+ TwaterC : xr.DataArray,
+) -> xr.DataArray :
+ """Calculate temperature in kelvin (K)
+ Args:
+ TwaterC: water temperature celcius (C)
+ """
+ return celsius_to_kelvin(TwaterC)
+
+
+def kah_20(
+ kah_20_user: xr.DataArray,
+ hydraulic_reaeration_option: xr.DataArray,
+ velocity: xr.DataArray,
+ depth: xr.DataArray,
+ flow: xr.DataArray,
+ topwidth: xr.DataArray,
+ slope: xr.DataArray,
+ shear_velocity: xr.DataArray
+) -> xr.DataArray:
+ """Calculate hydraulic oxygen reaeration rate based on flow parameters in different cells
+
+ Args:
+ kah_20_user: User defined O2 reaeration rate at 20 degrees (1/d)
+ hydraulic_reaeration_option: Integer value which selects method for computing O2 reaeration rate
+ velocity: Average water velocity in cell (m/s)
+ depth: Average water depth in cell (m)
+ flow: Average flow rate in cell (m3/s)
+ topwidth: Average topwidth of cell (m)
+ slope: Average slope of bottom surface
+ shear_velocity: Average shear velocity on bottom surface (m/s)
+ """
+ da: np.ndarray = np.select(
+ condlist = [hydraulic_reaeration_option == 1,
+ hydraulic_reaeration_option == 2,
+ hydraulic_reaeration_option == 3,
+ hydraulic_reaeration_option == 4,
+ (hydraulic_reaeration_option == 5) & (depth < 0.61),
+ (hydraulic_reaeration_option == 5) & (depth > 0.61),
+ (hydraulic_reaeration_option == 5) & (depth == 0.61),
+ (hydraulic_reaeration_option == 6) & (flow < 0.556),
+ (hydraulic_reaeration_option == 6) & (flow >= 0.556),
+ (hydraulic_reaeration_option == 7) & (flow < 0.556),
+ (hydraulic_reaeration_option == 7) & (flow >= 0.556),
+ (hydraulic_reaeration_option == 8) & (flow < 0.425),
+ (hydraulic_reaeration_option == 8) & (flow >= 0.425),
+ hydraulic_reaeration_option == 9],
+
+ choicelist = [kah_20_user,
+ (3.93 * velocity**0.5) / (depth**1.5),
+ (5.32 * velocity**0.67) / (depth**1.85),
+ (5.026 * velocity) / (depth**1.67),
+ (5.32 * velocity**0.67) / (depth**1.85),
+ (3.93 * velocity**0.5) / (depth**1.5),
+ (5.026 * velocity) / (depth**1.67),
+ 517 * (velocity * slope)**0.524 * flow**-0.242,
+ 596 * (velocity * slope)**0.528 * flow**-0.136,
+ 88 * (velocity * slope)**0.313 * depth**-0.353,
+ 142 * (velocity * slope)**0.333 * depth**-0.66 * topwidth**-0.243,
+ 31183 * velocity * slope,
+ 15308 * velocity * slope,
+ 2.16 * (1 + 9 * (velocity / (9.81 * depth)**0.5)**0.25) * shear_velocity / depth
+ ],
+ default = kah_20_user,
+ )
+
+ return da
+
+
+
+def kah_tc(
+ TwaterC: xr.DataArray,
+ kah_20: xr.DataArray,
+ theta: xr.DataArray
+) -> xr.DataArray:
+ """Calculate the temperature adjusted hydraulic oxygen reaeration rate (/d)
+
+ Args:
+ TwaterC: Water temperature in Celsius
+ kah_20: Hydraulic oxygen reaeration rate at 20 degrees Celsius
+ theta: Arrhenius coefficient
+ """
+ return arrhenius_correction(TwaterC, kah_20, theta)
+
+
+def kaw_20(
+ kaw_20_user: xr.DataArray,
+ wind_speed: xr.DataArray,
+ wind_reaeration_option: xr.DataArray
+) -> xr.DataArray:
+ """Calculate the wind oxygen reaeration velocity (m/d) based on wind speed, r stands for regional
+
+ Args:
+ kaw_20_user: User defined wind oxygen reaeration velocity at 20 degrees C (m/d)
+ wind_speed: Wind speed at 10 meters above the water surface (m/s)
+ wind_reaeration_option: Integer value which selects method for computing wind oxygen reaeration velocity
+ """
+ Uw10 = wind_speed * (10 / 2)**0.143
+
+ da: np.ndarray = np.select(
+ condlist = [
+ wind_reaeration_option == 1,
+ wind_reaeration_option == 2,
+ (wind_reaeration_option == 3) & (Uw10 <= 3.5),
+ (wind_reaeration_option == 3) & (Uw10 > 3.5),
+ wind_reaeration_option == 4,
+ wind_reaeration_option == 5,
+ wind_reaeration_option == 6,
+ (wind_reaeration_option == 7) & (Uw10 <= 5.5),
+ (wind_reaeration_option == 7) & (Uw10 > 5.5),
+ wind_reaeration_option == 8,
+ (wind_reaeration_option == 9) & (Uw10 <= 4.1),
+ (wind_reaeration_option == 9) & (Uw10 > 4.1),
+ wind_reaeration_option == 10,
+ wind_reaeration_option == 11,
+ wind_reaeration_option == 12,
+ (wind_reaeration_option == 13) & (Uw10 < 1.6),
+ (wind_reaeration_option == 13) & (Uw10 >= 1.6),
+ ],
+
+ choicelist = [
+ kaw_20_user,
+ 0.864 * Uw10,
+ 0.2 * Uw10,
+ 0.057 * Uw10**2,
+ 0.728 * Uw10**0.5 - 0.317 * Uw10 + 0.0372 * Uw10**2,
+ 0.0986 * Uw10**1.64,
+ 0.5 + 0.05 * Uw10**2,
+ 0.362 * Uw10**0.5,
+ 0.0277 * Uw10**2,
+ 0.64 + 0.128 * Uw10**2,
+ 0.156 * Uw10**0.63,
+ 0.0269 * Uw10**1.9,
+ 0.0276 * Uw10**2,
+ 0.0432 * Uw10**2,
+ 0.319 * Uw10,
+ 0.398,
+ 0.155 * Uw10**2
+ ],
+ default = kaw_20_user,
+ )
+
+ return da
+
+
+
+def kaw_tc(
+ TwaterC: xr.DataArray,
+ kaw_20: xr.DataArray,
+ theta: xr.DataArray
+) -> xr.DataArray:
+ """Calculate the temperature adjusted wind oxygen reaeration velocity (m/d)
+
+ Args:
+ water_temp_c: Water temperature in Celsius
+ kaw_20: Wind oxygen reaeration velocity at 20 degrees Celsius
+ theta: Arrhenius coefficient
+ """
+ return arrhenius_correction(TwaterC, kaw_20, theta)
+
+
+
+def ka_tc(
+ kah_tc: xr.DataArray,
+ kaw_tc: xr.DataArray,
+ depth: xr.DataArray
+) -> xr.DataArray:
+ """Compute the oxygen reaeration rate, adjusted for temperature (1/d)
+
+ Args:
+ kah_tc: Oxygen reaeration rate adjusted for temperature (1/d)
+ kaw_tc: Wind oxygen reaeration velocity adjusted for temperature (m/d)
+ depth: Average water depth in cell (m)
+ """
+ return kaw_tc / depth + kah_tc
+
+def SOD_tc(
+ SOD_20: xr.DataArray,
+ TwaterC: xr.DataArray,
+ SOD_theta: xr.DataArray,
+ DOX: xr.DataArray,
+ KsSOD: xr.DataArray,
+ use_DOX: xr.DataArray
+) -> xr.DataArray:
+ """Compute the sediment oxygen demand corrected by temperature and dissolved oxygen concentration
+
+ Args:
+ SOD_20: Sediment oxygen demand at 20 degrees celsius (mg-O2/m2)
+ TwaterC: Water temperature in degrees C
+ theta: Arrhenius coefficient
+ use_DOX: Option to consider DOX concentration in water in calculation of sediment oxygen demand
+ """
+ SOD_tc = arrhenius_correction(TwaterC, SOD_20, SOD_theta)
+
+ da: xr.DataArray = xr.where(use_DOX == True, SOD_tc * DOX / (DOX + KsSOD), SOD_tc)
+
+ return da
+
+def L(
+ lambda0: xr.DataArray,
+ lambda1: xr.DataArray,
+ lambda2: xr.DataArray,
+ lambdas: xr.DataArray,
+ lambdam: xr.DataArray,
+ Solid: xr.DataArray,
+ POC: xr.DataArray,
+ fcom: xr.DataArray,
+ use_Algae: xr.DataArray,
+ use_POC: xr.DataArray,
+ Ap: xr.DataArray,
+
+) -> xr.DataArray:
+ """Compute L: lambda: light extinction coefficient (unitless)
+
+ Args:
+ lambda0: background portion (1/m)
+ lambda1: linear self shading (1/m/(ug Chla/L))
+ lambda2: non-linear (unitless),
+ lambdas: ISS portion (L/mg/m),
+ lambdam: POM portion (L/mg/m)
+ Solid: #TODO define this
+ POC: particulate organic carbon (mg-C/L)
+ fcom: ratio of carbon to organic matter (mg-C/mg-D)
+ use_Algae: true/false use algae module (t/f)
+ use_POC: true/falseo use particulate organic carbon module (t/f)
+ Ap: algae concentration (ug-Chla/L)
+ """
+ L: xr.DataArray = lambda0 #+ lambdas * Solid
+
+ L: xr.DataArray = xr.where (use_POC, L+lambdam*(POC/fcom), L)
+ L: xr.DataArray = xr.where (use_Algae, L+lambda1*Ap + lambda2*Ap**(2/3), L)
+
+ return L
+
+def PAR(
+ use_Algae : bool,
+ use_Balgae: bool,
+ q_solar: xr.DataArray,
+ Fr_PAR: xr.DataArray,
+) -> xr.DataArray :
+ """Calculate temperature in kelvin (K)
+ Args:
+ use_Algae : true/false use algae module (t/f)
+ use_Balgae: true/falsoe use balgae module (t/f)
+ q_solar: solar radiation (1/d),
+ Fr_PAR: fraction of solar radiation within the PAR of the spectrum
+ """
+ return xr.where ((use_Algae) | (use_Balgae), q_solar * Fr_PAR, 0)
+
+#TODO does not appear HEC-RAS actually uses Solid in any calculations
+def fdp(
+ use_TIP: bool,
+ Solid : xr.DataArray,
+ kdpo4: xr.DataArray
+) -> xr.DataArray :
+
+ """Calculate kop_tc: Decay rate of organic P to DIP temperature correction (1/d).
+
+ Args:
+ use_TIP: true/false use total inorganic phosphrous,
+ Solid : #TODO define this
+ kdpo4: solid partitioning coeff. of PO4 (L/kg)
+ """
+
+ return xr.where(use_TIP, 1, 0)
+
+############################################ From algae
+
+def rna(
+ AWn: xr.DataArray,
+ AWa: xr.DataArray
+) -> xr.DataArray:
+ """Calculate rna (mg-N/ug-Chla).
+
+ Args:
+ AWn: Nitrogen Weight (mg)
+ AWa: Algal Chlorophyll (ug-Chla)
+ """
+ return AWn/AWa
+
+
+
+def rpa(
+ AWp: xr.DataArray,
+ AWa: xr.DataArray
+) -> xr.DataArray:
+ """Calculate rpa (mg-P/ug-Chla).
+
+ Args:
+ AWp: Phosphorus Weight (mg)
+ AWa: Algal Chlorophyll (ug-Chla)
+ """
+
+ return AWp/AWa
+
+
+
+def rca(
+ AWc: xr.DataArray,
+ AWa: xr.DataArray
+) -> xr.DataArray:
+ """Calculate rca (mg-C/ug-Chla).
+
+ Args:
+ AWc: Carbon Weight (mg)
+ AWa: Algal Chlorophyll (ug-Chla)
+ """
+ return AWc/AWa
+
+
+
+def rda(
+ AWd: xr.DataArray,
+ AWa: xr.DataArray
+) -> xr.DataArray:
+ """Calculate rda (mg-D/ug-Chla).
+
+ Args:
+ AWd: Dry Algal Weight (mg)
+ AWa: Algal Chlorophyll (ug-Chla)
+ """
+ return AWd/AWa
+
+
+
+def mu_max_tc(
+ TwaterC: xr.DataArray,
+ mu_max_20: xr.DataArray
+) -> xr.DataArray:
+ """Calculate mu_max_tc (1/d).
+
+ Args:
+ TwaterC: Water temperature (C)
+ mu_max: Max Algae growth (1/d)
+ """
+
+ return arrhenius_correction(TwaterC, mu_max_20, 1.047)
+
+
+
+def krp_tc(
+ TwaterC: xr.DataArray,
+ krp_20: xr.DataArray
+) -> xr.DataArray:
+ """Calculate krp_tc (1/d).
+
+ Args:
+ TwaterC: Water temperature (C)
+ krp: Algal respiration rate at 20 degree (1/d)
+ """
+
+ return arrhenius_correction(TwaterC, krp_20, 1.047)
+
+
+
+def kdp_tc(
+ TwaterC: xr.DataArray,
+ kdp_20: xr.DataArray
+) -> xr.DataArray:
+ """Calculate kdp_tc (1/d).
+
+ Args:
+ TwaterC: Water temperature (C)
+ kdp: Algal death rate at 20 degree (1/d)
+ """
+
+ return arrhenius_correction(TwaterC, kdp_20, 1.047)
+
+
+def FL(
+ L: xr.DataArray,
+ depth: xr.DataArray,
+ Ap: xr.DataArray,
+ PAR: xr.DataArray,
+ light_limitation_option: xr.DataArray,
+ KL: xr.DataArray,
+) -> np.ndarray:
+ """Calculate Algal light limitation: FL (unitless).
+
+ Args:
+ L: Lambda light attenuation coefficient (unitless)
+ depth: Water depth (m)
+ Ap: Algae Concentration (mg-Chla/L)
+ PAR: Surface light intensity (W/m^2)
+ light_limitation_option: Algal light limitation option 1) Half-saturation, 2) Smith model, 3) Steele model (unitless)
+ KL: Light limitation constant for algal growth (W/m^2)
+ """
+ warnings.filterwarnings("ignore", category=RuntimeWarning)
+
+ FL_orig: np.ndarray = np.select(
+ condlist = [
+ (Ap <= 0.0) | (L * depth <= 0.0) | (PAR <= 0.0),
+ light_limitation_option == 1,
+ (light_limitation_option == 2) & (np.abs(KL) < 0.0000000001),
+ (light_limitation_option == 2) & (np.abs(KL) >= 0.0000000001),
+ (light_limitation_option == 3) & (np.abs(KL) < 0.0000000001),
+ (light_limitation_option == 3) & (np.abs(KL) >= 0.0000000001),
+ ],
+
+ choicelist = [
+ 0,
+ (1.0 / (L * depth)) * np.log((KL + PAR) /(KL + PAR * np.exp(-(L * depth)))),
+ 1,
+ (1.0 / (L * depth)) * np.log( (PAR / KL + ((1.0 + (PAR / KL)**2.0)**0.5)) / (PAR * np.exp(-(L * depth)) / KL + ((1.0 + (PAR * np.exp(-(L * depth)) / KL)**2.0)**0.5))),
+ 0,
+ (2.718/(L * depth)) * (np.exp(-PAR/KL * np.exp(-(L * depth))) - np.exp(-PAR/KL))
+ ],
+
+ default = np.nan
+ )
+
+ FL: np.ndarray = np.select(
+ condlist = [
+ FL_orig > 1.0,
+ FL_orig < 0.0,
+ ],
+
+ choicelist = [
+ 1.0,
+ 0.0
+ ],
+
+ default = FL_orig
+ )
+ warnings.filterwarnings("default", category=RuntimeWarning)
+ return FL
+
+
+def FN(
+ use_NH4: bool,
+ use_NO3: bool,
+ NH4: xr.DataArray,
+ NO3: xr.DataArray,
+ KsN: xr.DataArray,
+
+) -> xr.DataArray:
+ """Calculate Algal nitrogen limitation: FN (unitless).
+
+ Args:
+ use_NH4: Use NH4 module true or false (true/false)
+ use_NO3: Use NO3 module true or false (true/false)
+ NH4: Ammonium concentration (mg-N/L)
+ NO3: Nitrate concentration (mg-N/L)
+ KsN: Michaelis-Menton half-saturation constant relating inorganic N to algal growth (mg-N/L)
+ """
+
+ #FN_orig = xr.where(use_NH4 or use_NO3, (NH4 + NO3) / (KsN + NH4 + NO3), 1)
+
+ FN_orig: np.ndarray = np.select(
+ condlist= [
+ (use_NH4 == True) & (use_NO3 == True),
+ (use_NH4 == False) & (use_NO3 == True),
+ (use_NH4 == True) & (use_NO3 == False),
+ (use_NH4 == False) & (use_NO3 == False),
+ ],
+
+ choicelist= [
+ (NH4 + NO3) / (KsN + NH4 + NO3),
+ (NO3) / (KsN + NO3),
+ (NH4) / (KsN + NH4),
+ 1
+ ],
+
+ default = 1
+ )
+
+
+ FN: np.ndarray = np.select(
+ condlist= [
+ np.isnan(FN_orig),
+ FN_orig > 1.0
+ ],
+
+ choicelist= [
+ 0,
+ 1.0
+ ],
+
+ default = FN_orig
+ )
+
+ return FN
+
+
+def FP(
+ fdp: xr.DataArray,
+ TIP: xr.DataArray,
+ use_TIP: bool,
+ KsP: xr.DataArray
+) -> xr.DataArray:
+ """Calculate Algal phosphorous limitation: FP (unitless).
+
+ Args:
+ use_TIP: Use Total Inorganic Phosphorus module true or false (true/false)
+ TIP: Total Inorganic Phosphorus concentration (mg-P/L)
+ KsP: Michaelis-Menton half-saturation constant relating inorganic P to algal growth (mg-P/L)
+ fdp: Fraction P dissolved (unitless)
+ """
+
+ FP_orig = xr.where(use_TIP, fdp * TIP / (KsP + fdp * TIP), 1.0)
+
+ FP: np.ndarray = np.select(
+ condlist= [
+ np.isnan(FP_orig),
+ FP_orig > 1.0
+ ],
+
+ choicelist= [
+ 0,
+ 1.0
+ ],
+
+ default = FP_orig
+ )
+
+ return FP
+
+
+def mu(
+ mu_max_tc: xr.DataArray,
+ growth_rate_option: int,
+ FL: xr.DataArray,
+ FP: xr.DataArray,
+ FN: xr.DataArray
+
+) -> xr.DataArray:
+ """Calculate Algal growth rate with three options 1) Multiplicative, 2) Limiting nutrient, 3) Harmonic Mean (1/d)
+
+ Args:
+ mu_max_tc: Max algae growth temperature corrected (1/d)
+ growth_rate_option: Algal growth rate with options 1) Multiplicative, 2) Limiting nutrient, 3) Harmonic Mean (unitless)
+ FL: Algae light limitation factor (unitless)
+ FP: Algae phosphorus limitation factor (unitless)
+ FN: Algae nitrogen limitation factor (unitless)
+ """
+
+ mu: np.ndarray = np.select(
+ condlist = [
+ growth_rate_option == 1,
+ (growth_rate_option == 2) & (FP > FN),
+ (growth_rate_option == 2) & (FN > FP),
+ (growth_rate_option == 3) & ((FN == 0.0) | (FP == 0.0)),
+ (growth_rate_option == 3) & (FN != 0) & (FP != 0)
+ ],
+
+ choicelist = [
+ mu_max_tc * FL * FP * FN,
+ mu_max_tc * FL * FN,
+ mu_max_tc * FL * FP,
+ 0,
+ mu_max_tc * FL * 2.0 / (1.0 / FN + 1.0 / FP)
+ ],
+
+ default = np.nan
+ )
+
+ return mu
+
+
+
+def ApGrowth(
+ mu: xr.DataArray,
+ Ap: xr.DataArray
+) -> xr.DataArray:
+ """Calculate Algal growth (ug-Chla/L/d)
+
+ Args:
+ mu: Algal growth rate (1/d)
+ Ap: Algae concentration (ug-Chla/L)
+ """
+
+ return mu * Ap
+
+
+
+def ApRespiration(
+ krp_tc: xr.DataArray,
+ Ap: xr.DataArray
+) -> xr.DataArray:
+ """Calculate Algal Respiration (ug-Chla/L/d)
+
+ Args:
+ krp_tc: Algal respiration rate temperature corrected (1/d)
+ Ap: Algae concentration (ug-Chla/L)
+ """
+
+ return krp_tc * Ap
+
+
+
+def ApDeath(
+ kdp_tc: xr.DataArray,
+ Ap: xr.DataArray
+) -> xr.DataArray:
+ """Calculate Algal death (ug-Chla/L/d)
+
+ Args:
+ kdp_tc: Algal death rate temperature corrected (1/d)
+ Ap: Algae concentration (ug-Chla/L)
+ """
+ return kdp_tc * Ap
+
+
+
+def ApSettling(
+ vsap: xr.DataArray,
+ Ap: xr.DataArray,
+ depth: xr.DataArray
+) -> xr.DataArray:
+ """Calculate Algal setting rate (ug-Chla/L/d)
+
+ Args:
+ vsap: Algal settling velocity (m/d)
+ Ap: Algae concentration (ug-Chla/L)
+ depth: Depth from Water Surface (m)s
+ """
+ return vsap / depth * Ap
+
+
+
+def dApdt(
+ ApGrowth: xr.DataArray,
+ ApRespiration: xr.DataArray,
+ ApDeath: xr.DataArray,
+ ApSettling: xr.DataArray
+) -> xr.DataArray:
+ """Calculate change in algae biomass concentration (ug-Chla/L/d)
+
+ Args:
+ ApGrowth: Algal growth (ug-Chla/L/d)
+ ApRespiration: Algal respiration (ug-Chla/L/d)
+ ApDeath: Algal death (ug-Chla/L/d)
+ ApSettling: Algal settling (ug-Chla/L/d)
+ """
+
+ return ApGrowth - ApRespiration - ApDeath - ApSettling
+
+
+
+def Ap(
+ Ap: xr.DataArray,
+ dApdt: xr.DataArray,
+ timestep: xr.DataArray
+) -> xr.DataArray:
+ """Calculate new algae concentration (ug-Chla/L)
+
+ Args:
+ Ap: Initial algae biomass concentration (ug-Chla/L)
+ dApdt: Change in algae biomass concentration (ug-Chla/L/d)
+ timestep: current iteration timestep (d)
+ """
+ return Ap + dApdt * timestep
+
+############################################ From benthic algae
+
+def mub_max_tc(
+ mub_max_20: xr.DataArray,
+ TwaterC: xr.DataArray
+) -> xr.DataArray:
+ """Calculate mub_max_tc: Maximum benthic algal growth rate with temperature correction (1/d).
+
+ Args:
+ mu_max_20: Maximum benthic algal growth rate at 20C (1/d)
+ TwaterC: Water temperature (C)
+ """
+ return arrhenius_correction(TwaterC, mub_max_20, 1.047)
+
+
+
+def krb_tc(
+ krb_20: xr.DataArray,
+ TwaterC: xr.DataArray
+) -> xr.DataArray:
+ """Calculate krb_tc: Benthic algae respiration rate with temperature correction (1/d).
+
+ Args:
+ krb_20: Benthic algae respiration rate at 20C (1/d)
+ TwaterC: Water temperature (C)
+ """
+ return arrhenius_correction(TwaterC, krb_20, 1.06)
+
+
+
+def kdb_tc(
+ kdb_20: xr.DataArray,
+ TwaterC: xr.DataArray
+) -> xr.DataArray:
+ """Calculate kdb_tc: Benthic algae mortality rate with temperature correction (1/d).
+
+ Args:
+ kdb_20: Benthic algae mortality rate at 20C (1/d)
+ TwaterC: Water temperature (C)
+ """
+ return arrhenius_correction(TwaterC, kdb_20, 1.047)
+
+
+
+def rnb(
+ BWn: xr.DataArray,
+ BWd: xr.DataArray
+) -> xr.DataArray:
+ """Calculate rnb (mg-N/mg-D).
+
+ Args:
+ BWn: Benthic algae nitrogen (unitless)
+ BWd: Benthic algae dry weight (unitless)
+ """
+ return BWn/BWd
+
+
+
+def rpb(
+ BWp: xr.DataArray,
+ BWd: xr.DataArray
+) -> xr.DataArray:
+ """Calculate rpd: Benthic algae phosphorus to dry weight ratio (mg-P/mg-D).
+
+ Args:
+ BWp: Benthic algae phosphorus (mg-P)
+ BWd: Benthic algae dry weight (mg-D)
+ """
+ return BWp/BWd
+
+
+
+def rcb(
+ BWc: xr.DataArray,
+ BWd: xr.DataArray
+) -> xr.DataArray:
+ """Calculate rcb: Benthic algae carbon to dry weight ratio (mg-C/mg-D).
+
+ Args:
+ BWc: Benthic algae carbon (mg-C)
+ BWd: Benthic algae dry weight (mg-D)
+ """
+ return BWc/BWd
+
+
+
+def rab(
+ BWa: xr.DataArray,
+ BWd: xr.DataArray
+) -> xr.DataArray:
+ """Calculate rab: Benthic algae chlorophyll-a to dry weight ratio (ug-Chla-a/mg-D).
+
+ Args:
+ BWa: Benthic algae chlorophyll-a (ug-Chla-a)
+ BWd: Benthic algae dry weight (mg-D)
+ """
+ return BWa/BWd
+
+
+def FLb(
+ L: xr.DataArray,
+ depth: xr.DataArray,
+ Ab: xr.DataArray,
+ PAR: xr.DataArray,
+ b_light_limitation_option: xr.DataArray,
+ KLb: xr.DataArray,
+
+) -> xr.DataArray:
+ """Calculate Benthic algal light limitation: FLb (unitless).
+
+ Args:
+ L: Lambda light attenuation coefficient (unitless)
+ depth: Water depth (m)
+ Ab: Benthic algae Concentration (g/m^2)
+ PAR: Surface light intensity (W/m^2)
+ b_light_limitation_option: Benthic light limitation option 1) Half-saturation, 2) Smith model, 3) Steele model (unitless)
+ KLb: Light limitation constant for benthic algal growth (W/m^2)
+ """
+
+ # Note that KENT is defined differently here than it was for the algal equations.
+ # The equations are different, this expression is more convenient here.
+ KEXT = np.exp(-L*depth)
+
+ FLb_orig: np.ndarray = np.select(
+ condlist = [
+ (Ab <= 0.0) | (KEXT <= 0.0) | (PAR <= 0.0),
+ b_light_limitation_option == 1,
+ b_light_limitation_option == 2,
+ (b_light_limitation_option == 3) & (abs(KLb) < 1.0E-10),
+ (b_light_limitation_option == 3) & (abs(KLb) >= 1.0E-10)
+ ],
+
+ choicelist = [
+ 0.0,
+ PAR * KEXT / (KLb + PAR * KEXT),
+ PAR * KEXT / ((KLb**2.0 + (PAR * KEXT)**2.0)**0.5),
+ 0.0,
+ PAR * KEXT / KLb * np.exp(1.0 - PAR * KEXT / KLb)
+ ],
+
+ default = np.nan
+ )
+
+ FLb: np.ndarray = np.select(
+ condlist = [
+ FLb_orig > 1.0,
+ FLb_orig < 0.0
+ ],
+
+ choicelist = [
+ 1.0,
+ 0.0
+ ],
+
+ default = FLb_orig
+ )
+
+ return FLb
+
+
+def FNb(
+ use_NH4: bool,
+ use_NO3: bool,
+ NH4: xr.DataArray,
+ NO3: xr.DataArray,
+ KsNb: xr.DataArray,
+
+) -> xr.DataArray:
+ """Calculate Benthic algae nitrogen limitation: FNb (unitless).
+
+ Args:
+ use_NH4: Use NH4 module true or false (true/false)
+ use_NO3: Use NO3 module true or false (true/false)
+ NH4: Ammonium concentration (mg-N/L)
+ NO3: Nitrate concentration (mg-N/L)
+ KsNb: Michaelis-Menton half-saturation constant relating inorganic N to benthic algal growth (mg-N/L)
+ """
+
+ #FNb_orig = xr.where(use_NH4 or use_NO3, (NH4 + NO3) / (KsNb + NH4 + NO3),1)
+
+ FNb_orig: np.ndarray = np.select(
+ condlist= [
+ (use_NH4 == True) & (use_NO3 == True),
+ (use_NH4 == True) & (use_NO3 == False),
+ (use_NH4 == False) & (use_NO3 == True),
+ (use_NH4 == False) & (use_NO3 == False),
+ ],
+
+ choicelist= [
+ (NH4 + NO3) / (KsNb + NH4 + NO3),
+ (NH4) / (KsNb + NH4),
+ (NO3) / (KsNb + NO3),
+ 1
+ ],
+
+ default = 1
+ )
+
+ FNb: np.ndarray = np.select(
+ condlist= [
+ np.isnan(FNb_orig),
+ FNb_orig > 1.0
+ ],
+
+ choicelist= [
+ 0.0,
+ 1.0
+ ],
+
+ default = FNb_orig
+ )
+
+ return FNb
+
+
+def FPb(
+ fdp: xr.DataArray,
+ TIP: xr.DataArray,
+ use_TIP: bool,
+ KsPb: xr.DataArray
+) -> xr.DataArray:
+ """Calculate benthic algae phosphorous limitation: FPb (unitless).
+
+ Args:
+ use_TIP: Use Total Inorganic Phosphorus module true or false (true/false)
+ TIP: Total Inorganic Phosphorus concentration (mg-P/L)
+ KsPb: Michaelis-Menton half-saturation constant relating inorganic P to benthic algal growth (mg-P/L)
+ fdp: Fraction P dissolved (unitless)
+ """
+
+ FPb_orig = xr.where(use_TIP, fdp * TIP / (KsPb + fdp * TIP),1.0)
+
+ FPb: np.ndarray = np.select(
+ condlist= [
+ np.isnan(FPb_orig),
+ FPb_orig > 1.0
+ ],
+
+ choicelist= [
+ 0.0,
+ 1.0
+ ],
+
+ default = FPb_orig
+ )
+
+ return FPb
+
+
+def FSb(
+ Ab: xr.DataArray,
+ Ksb: xr.DataArray,
+
+) -> xr.DataArray:
+ """Calculate benthic density attenuation (unitless)
+
+ Args:
+ Ab: Benthic algae concentration (g/m^2)
+ Ksb: Half-saturation density constant for benthic algae growth (g-D/m^2)
+
+ """
+
+ FSb_orig = 1.0 - (Ab / (Ab + Ksb))
+
+ FSb: np.ndarray = np.select(
+ condlist= [
+ np.isnan(FSb_orig),
+ FSb_orig > 1.0
+ ],
+
+ choicelist= [
+ 0.0,
+ 1.0
+ ],
+
+ default = FSb_orig
+ )
+
+ return FSb
+
+def mub(
+ mub_max_tc: xr.DataArray,
+ b_growth_rate_option: int,
+ FLb: xr.DataArray,
+ FPb: xr.DataArray,
+ FNb: xr.DataArray,
+ FSb: xr.DataArray,
+
+) -> xr.DataArray:
+ """Calculate benthic algae specific growth rate (1/d)
+
+ Args:
+ mub_max_tc: Maximum benthic algal growth rate with temperature correction (1/d)
+ b_growth_rate_option: Benthic Algal growth rate with three options 1) Multiplicative, 2) Limiting Nutrient
+ FLb: Benethic algal light limitation (unitless)
+ FPb: Benthic algae phosphorous limitation (unitless)
+ FNb: Benthic algae nitrogen limitation (unitless)
+ FSb: Benthic density attenuation (unitless),
+ """
+
+ # Benthic Local Specific Growth Rate
+
+ mub: np.ndarray = np.select(
+ condlist= [
+ b_growth_rate_option == 1,
+ (b_growth_rate_option != 1) & (FPb > FNb),
+ (b_growth_rate_option != 1) & (FNb > FPb)
+ ],
+
+ choicelist= [
+ mub_max_tc * FLb * FPb * FNb * FSb,
+ mub_max_tc * FLb * FSb * FNb,
+ mub_max_tc * FLb * FSb * FPb
+ ],
+
+ default = 0
+ )
+
+ return mub
+
+
+def AbGrowth(
+ mub: xr.DataArray,
+ Ab: xr.DataArray
+) -> xr.DataArray:
+ """Calculate Benthic algal growth (g/m^2/d)
+
+ Args:
+ mub: Benthic algae growth rate (1/d)
+ Ab: Benthic algae concentration (g/m^2)
+ """
+
+ return mub * Ab
+
+
+
+def AbRespiration(
+ krb_tc: xr.DataArray,
+ Ab: xr.DataArray
+) -> xr.DataArray:
+ """Calculate benthic algal Respiration (g/m^2/d)
+
+ Args:
+ krb_tc: Benthic algal respiration rate temperature corrected (1/d)
+ Ab: Algae concentration (g/m^2)
+ """
+ return krb_tc * Ab
+
+
+
+def AbDeath(
+ kdb_tc: xr.DataArray,
+ Ab: xr.DataArray
+) -> xr.DataArray:
+ """Calculate benthic algae death (g/m^2/d)
+
+ Args:
+ kdb_tc: Benthic algae death rate temperature corrected (1/d)
+ Ab: Benthic algae concentration (g/m^2)
+ """
+
+ return kdb_tc * Ab
+
+
+
+def dAbdt(
+ AbGrowth: xr.DataArray,
+ AbRespiration: xr.DataArray,
+ AbDeath: xr.DataArray
+
+) -> xr.DataArray:
+ """Calculate change in benthic algae concentration (g/m^2/d)
+
+ Args:
+ AbGrowth: Benthic algae growth rate (g/m^2/d)
+ AbRespiration: Benthic algae respiration rate (g/m^2/d)
+ AbDeath: Benthic algae death rate (g/m^2/d)
+ """
+ return AbGrowth - AbRespiration - AbDeath
+
+
+
+def Ab(
+ Ab: xr.DataArray,
+ dAbdt: xr.DataArray,
+ timestep: xr.DataArray,
+
+) -> xr.DataArray:
+ """Calculate Ab: New concentration benthic algae (mg-N/L)
+
+ Args:
+ Ab: Concentration of benthic algae (mg-N/L)
+ dAbdt: Change in Ab (mg-N/L/d)
+ timestep: current iteration timestep (d)
+
+ """
+
+ return Ab + dAbdt * timestep
+
+
+def Chlb(
+ rab: xr.DataArray,
+ Ab: xr.DataArray,
+
+) -> xr.DataArray:
+ """Calculate chlorophyll-a concentration (mg-Chla/m^2)
+
+ Args:
+ rab: Balgae Chla to Dry ratio (mg-D/ug-Chla)
+ Ab: Benthic algae concentration (g/m^2)
+ """
+
+ return rab * Ab
+
+
+############################################ From nitrogen
+
+
+def knit_tc(
+ TwaterC: xr.DataArray,
+ knit_20: xr.DataArray
+) -> xr.DataArray:
+ """Calculate knit_tc: Nitrification rate ammonia decay NH4 to NO3 temperature correction (1/d). #TODO only if use_NH4 = true
+
+ Args:
+ TwaterC: Water temperature (C)
+ knit_20: Nitrification rate ammonia decay (1/d)
+ """
+
+ return arrhenius_correction(TwaterC, knit_20, 1.083)
+
+
+
+def rnh4_tc(
+ TwaterC: xr.DataArray,
+ rnh4_20: xr.DataArray
+) -> xr.DataArray:
+ """Calculate rnh4_tc: Sediment release rate of NH4 temperature correction(1/d). #TODO only if use_sedflux = true
+
+ Args:
+ TwaterC: Water temperature (C)
+ rnh4_20: Sediment release rate of NH4 (1/d)
+ """
+
+ return arrhenius_correction(TwaterC, rnh4_20, 1.074)
+
+
+
+def vno3_tc(
+ TwaterC: xr.DataArray,
+ vno3_20: xr.DataArray
+) -> xr.DataArray:
+ """Calculate vno3_tc: Sediment denitrification velocity temperature correction (m/d). #TODO only if use_sedflux = true
+
+ Args:
+ TwaterC: Water temperature (C)
+ vno3_20: Sedimet release rate of NO3 (1/d)
+ """
+
+ return arrhenius_correction(TwaterC, vno3_20, 1.08)
+
+
+
+def kon_tc(
+ TwaterC: xr.DataArray,
+ kon_20: xr.DataArray
+) -> xr.DataArray:
+ """Calculate kon_tc: Decay rate of OrgN to NH4 temperature correction(1/d). #TODO only if use_OrgN = true
+
+ Args:
+ TwaterC: Water temperature (C)
+ kon_20: Decay rate of OrgN to NH4 (1/d)
+ """
+
+ return arrhenius_correction(TwaterC, kon_20, 1.074)
+
+
+
+def kdnit_tc(
+ TwaterC: xr.DataArray,
+ kdnit_20: xr.DataArray
+) -> xr.DataArray:
+ """Calculate kdnit_tc: Denitrification rate temperature correction (1/d). #TODO only if use_NO3 = true
+
+ Args:
+ TwaterC: Water temperature (C)
+ kdnit_20: Denitrification rate (1/d)
+ """
+
+ return arrhenius_correction(TwaterC, kdnit_20, 1.045)
+
+
+def ApUptakeFr_NH4(
+ use_NH4: bool,
+ use_NO3: bool,
+ use_Algae: bool,
+ PN: xr.DataArray,
+ NH4: xr.DataArray,
+ NO3: xr.DataArray,
+
+) -> xr.DataArray:
+ """Calculate ApUptakeFr_NH4:
+
+ Args:
+ use_NH4: use ammonium module (unitless)
+ use_NO3: use nitrate module (unitless)
+ use_Algae: use algae module (unitless)
+ PN: NH4 preference factor algae (unitless)
+ NH4: Ammonium water concentration (mg-N/L)
+ NO3: Nitrate water concentration (mg-N/L)
+ """
+ # set value of UptakeFr_NH4/NO3 for special conditions
+ ApUptakeFr_NH4: np.ndarray = np.select(
+ condlist = [
+ use_NH4 & ~use_NO3,
+ ~use_NH4 & use_NO3,
+ ~use_NH4 & ~use_NO3,
+ use_Algae & use_NH4 & use_NO3
+ ],
+
+ choicelist = [
+ 1.0,
+ 0.0,
+ 0.5,
+ PN * NH4 / (PN * NH4 + (1.0 - PN) * NO3)
+ ],
+
+ default = np.nan
+ )
+
+ # Check for case when NH4 and NO3 are very small. If so, force uptake_fractions appropriately.
+ ApUptakeFr_NH4 = xr.where(np.isnan(ApUptakeFr_NH4),PN,ApUptakeFr_NH4)
+
+ return ApUptakeFr_NH4
+
+
+
+def ApUptakeFr_NO3(
+ ApUptakeFr_NH4: xr.DataArray
+) -> xr.DataArray:
+ """Calculate ApUptakeFr_NO3: Fraction of actual xr.DataArraying algal uptake from nitrate pool (unitless)
+
+ Args:
+ ApUptakeFr_NH4: Fraction of actual xr.DataArraying algal uptake from ammonia pool
+ """
+
+ return 1 - ApUptakeFr_NH4
+
+
+def AbUptakeFr_NH4(
+ use_NH4: bool,
+ use_NO3: bool,
+ use_Balgae: bool,
+ PNb: xr.DataArray,
+ NH4: xr.DataArray,
+ NO3: xr.DataArray,
+
+) -> xr.DataArray:
+ """Calculate AbUptakeFr_NH4: Fraction of actual benthic algal uptake from ammonia pool
+
+ Args:
+ use_NH4: use ammonium module (unitless)
+ use_NO3: use nitrate module (unitless)
+ use_Balgae: use benthic algae module (unitless)
+ PNb: NH4 preference factor benthic algae (unitless)
+ NH4: Ammonium water concentration (mg-N/L)
+ NO3: Nitrate water concentration (mg-N/L)
+ """
+ AbUptakeFr_NH4: np.ndarray = np.select(
+ condlist = [
+ (use_NH4) & (~use_NO3),
+ (~use_NH4) & (use_NO3),
+ (~use_NH4) & (~use_NO3),
+ (use_Balgae) & (use_NH4) & (use_NO3)
+ ],
+
+ choicelist = [
+ 1.0,
+ 0.0,
+ 0.5,
+ (PNb * NH4) / (PNb * NH4 + (1.0 - PNb) * NO3)
+ ],
+
+ default = np.nan
+ )
+
+ AbUptakeFr_NH4 = xr.where(np.isnan(AbUptakeFr_NH4),PNb,AbUptakeFr_NH4)
+
+ return AbUptakeFr_NH4
+
+
+
+def AbUptakeFr_NO3(
+ AbUptakeFr_NH4: xr.DataArray
+) -> xr.DataArray:
+ """Calculate AbUptakeFr_NO3: Fraction of actual benthic algal uptake from nitrate pool (unitless)
+
+ Args:
+ AbUptakeFr_NH4: Fraction of actual benthic algal uptake from ammonia pool
+ """
+
+ return 1 - AbUptakeFr_NH4
+
+def OrgN_NH4_Decay(
+ kon_tc: xr.DataArray,
+ OrgN: xr.DataArray,
+ use_OrgN: bool
+) -> xr.DataArray:
+ """Calculate OrgN_NH4: OrgN -> NH4 (mg-N/L/d)
+
+ Args:
+ kon_tc: Decay rate of organic nitrogen to nitrate with temperature correction (1/d),
+ OrgN: Concentration of organic nitrogen (mg-N/L)
+ use_OrgN: true/false use organic nitrogen (t/f)
+ """
+
+ return xr.where(use_OrgN, kon_tc * OrgN,0)
+
+
+def OrgN_Settling(
+ vson: xr.DataArray,
+ depth: xr.DataArray,
+ OrgN: xr.DataArray,
+) -> xr.DataArray:
+ """Calculate OrgN_Settling: OrgN -> bed (mg-N/L/d)
+
+ Args:
+ vson: Organic nitrogen settling velocity (m/d)
+ depth: water depth (m)
+ """
+
+ return vson / depth * OrgN
+
+def ApDeath_OrgN(
+ use_Algae: bool,
+ rna: xr.DataArray,
+ ApDeath: xr.DataArray,
+) -> xr.DataArray:
+ """Calculate ApDeath_OrgN: Algae -> OrgN (mg-N/L/d)
+
+ Args:
+ use_Algae: true/false to use algae module (unitless)
+ rna: Algal N: Chla ratio (mg-N/ug-Chla)
+ ApDeath: Algal death rate (ug-Chla/L/d)
+ """
+
+ return xr.where(use_Algae, rna * ApDeath, 0.0)
+
+def AbDeath_OrgN(
+ use_Balgae: bool,
+ rnb: xr.DataArray,
+ Fw: xr.DataArray,
+ Fb: xr.DataArray,
+ depth: xr.DataArray,
+ AbDeath: xr.DataArray,
+) -> xr.DataArray:
+ """Calculate ApDeath_OrgN: Algae -> OrgN (mg-N/L/d)
+
+ Args:
+ use_Balgae: true/false to use benthic algae module (unitless),
+ rnb: Benthic algal N: Benthic Algal Dry Weight (mg-N/mg-D)
+ Fw: Fraction benthic algae mortality into water column (unitless)
+ Fb: Fraction of bottom area for benthic algae (unitless)
+ depth: water depth (m)
+ AbDeath: Benthic algal death rate (g/m^2/d)
+ """
+
+ return xr.where(use_Balgae, rnb * Fw * Fb * AbDeath / depth, 0.0)
+
+def dOrgNdt(
+ use_OrgN: bool,
+ ApDeath_OrgN: xr.DataArray,
+ AbDeath_OrgN: xr.DataArray,
+ OrgN_NH4_Decay: xr.DataArray,
+ OrgN_Settling: xr.DataArray,
+
+) -> xr.DataArray:
+ """Calculate dOrgNdt: Change in Organic Nitrogen (mg-N/L/d)
+
+ Args:
+ use_OrgN: true/false to use organic nitrogen module (unitless)
+ ApDeath_OrgN: Algae -> OrgN (mg-N/L/d)
+ AbDeath_OrgN: Benthic Algae -> OrgN (mg-N/L/d)
+ OrgN_NH4_Decay: OrgN -> NH4 (mg-N/L/d)
+ OrgN_Settling: OrgN -> bed (mg-N/L/d)
+
+ """
+
+ return xr.where(use_OrgN, ApDeath_OrgN + AbDeath_OrgN - OrgN_NH4_Decay - OrgN_Settling,0)
+
+
+def OrgN(
+ OrgN: xr.DataArray,
+ dOrgNdt: xr.DataArray,
+ timestep: xr.DataArray,
+
+) -> xr.DataArray:
+ """Calculate OrgN: New concentration OrgN (mg-N/L)
+
+ Args:
+ OrgN: Concentration of organic nitrogen (mg-N/L)
+ dOrgNdt: Change in Organic Nitrogen (mg-N/L/d)
+ timestep: current iteration timestep (d)
+
+ """
+
+ return OrgN + dOrgNdt * timestep
+
+def NitrificationInhibition(
+ use_DOX: bool,
+ KNR: xr.DataArray,
+ DOX: xr.DataArray,
+
+) -> xr.DataArray:
+ """Calculate NitrificationInhibition: Nitrification Inhibitation (limits nitrification under low DO conditions)
+
+ Args:
+ KNR: Oxygen inhabitation factor for nitrification (mg-O2/L),
+ DOX: Dissolved oxygen concentration (mg-O2/L),
+ use_DOX: true/false to use dissolve oxygen module (unitless),
+
+ """
+
+ return xr.where (use_DOX, 1.0 - np.exp(-KNR * DOX), 1.0)
+
+def NH4_Nitrification(
+ NitrificationInhibition: xr.DataArray,
+ NH4: xr.DataArray,
+ knit_tc: xr.DataArray,
+ use_NH4: xr.DataArray
+
+) -> xr.DataArray:
+ """Calculate NH4_Nitrification: NH4 -> NO3 Nitrification (mg-N/L/day)
+
+ Args:
+ NitrificationInhibition: Nitrification Inhibitation (limits nitrification under low DO conditions)
+ knit_tc: Nitrification rate ammonia decay NH4 to NO3 temperature correction (1/d).
+ NH4: Ammonium concentration (mg-N/L),
+ """
+
+ return xr.where(use_NH4,NitrificationInhibition * knit_tc * NH4,0)
+
+
+def NH4fromBed(
+ depth: xr.DataArray,
+ rnh4_tc: xr.DataArray,
+
+) -> xr.DataArray:
+ """Calculate NH4fromBed: bed -> NH4 (diffusion) (mg-N/L/day)
+
+ Args:
+ depth: water depth (m),
+ rnh4_tc: Sediment release rate of NH4 temperature correction(1/d).
+
+ """
+
+ return rnh4_tc / depth
+
+def NH4_ApRespiration(
+ use_Algae: bool,
+ ApRespiration: xr.DataArray,
+ rna: xr.DataArray,
+
+) -> xr.DataArray:
+ """Calculate NH4_ApRespiration: Floating algae -> NH4 (mg-N/L/day)
+
+ Args:
+ use_Algae: true/false to use algae module (unitless),
+ rna: Algal N: Chla ratio (mg-N/ug-Chla),
+ ApRespiration: Algal respiration rate (ug-Chla/L/d),
+ """
+
+ return xr.where (use_Algae, rna * ApRespiration, 0.0)
+
+def NH4_ApGrowth(
+ use_Algae: bool,
+ ApGrowth: xr.DataArray,
+ rna: xr.DataArray,
+ ApUptakeFr_NH4: xr.DataArray,
+
+) -> xr.DataArray:
+ """Calculate NH4_ApGrowth: NH4 -> Floating algae (mg-N/L/day)
+
+ Args:
+ use_Algae: true/false to use algae module (unitless),
+ rna: Algal N: Chla ratio (mg-N/ug-Chla),
+ ApGrowth: Algal growth rate (ug-Chla/L/d),
+ ApUptakeFr_NH4: Fraction of actual xr.DataArraying algal uptake from ammonia pool
+ """
+
+ return xr.where(use_Algae, ApUptakeFr_NH4 * rna * ApGrowth, 0.0)
+
+def NH4_AbRespiration(
+ use_Balgae: bool,
+ rnb: xr.DataArray,
+ AbRespiration: xr.DataArray,
+
+) -> xr.DataArray:
+ """Calculate NH4_AbRespiration: Benthic algae -> NH4 (mg-N/L/day)
+
+ Args:
+ use_Balgae: true/false to use benthic algae module (unitless),
+ rnb: xr.DataArray,
+ AbRespiration: Benthic algal respiration rate (g/m^2/d),
+ """
+ # 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 )
+
+def NH4_AbGrowth(
+ use_Balgae: bool,
+ rnb: xr.DataArray,
+ AbGrowth: xr.DataArray,
+ AbUptakeFr_NH4: xr.DataArray,
+ Fb: xr.DataArray,
+ depth: xr.DataArray,
+
+) -> xr.DataArray:
+ """Calculate NH4_AbGrowth: NH4 -> Benthic Algae (g-N/L/day)
+
+ Args:
+ use_Balgae: true/false to use benthic algae module (unitless),
+ rnb: xr.DataArray,
+ AbGrowth: Benthic alga growth rate (g/m^2/d),
+ depth: water depth (m),
+ Fb: Fraction of bottom area for benthic algae (unitless),
+ AbUptakeFr_NH4: Fraction of actual benthic algal uptake from ammonia pool
+ """
+
+ return xr.where(use_Balgae,(AbUptakeFr_NH4 * rnb * Fb * AbGrowth) / depth, 0.0 )
+
+def dNH4dt(
+ use_NH4: bool,
+ OrgN_NH4_Decay: xr.DataArray,
+ NH4_Nitrification: xr.DataArray,
+ NH4fromBed: xr.DataArray,
+ NH4_ApRespiration: xr.DataArray,
+ NH4_ApGrowth: xr.DataArray,
+ NH4_AbRespiration: xr.DataArray,
+ NH4_AbGrowth: xr.DataArray,
+
+
+) -> xr.DataArray:
+ """Calculate dNH4dt: Change in Ammonium (mg-N/L)
+
+ Args:
+ use_OrgN: true/false to use organic nitrogen module (unitless),
+ use_NH4: true/false to use ammonium module (unitless),
+ OrgN_NH4_Decay: OrgN -> NH4 (mg-N/L/d)
+ NH4_Nitrification: NH4 -> NO3 Nitrification (mg-N/L/day)
+ NH4fromBed: bed -> NH4 (diffusion) (mg-N/L/day)
+ NH4_ApRespiration: Floating algae -> NH4 (mg-N/L/day)
+ NH4_ApGrowth: NH4 -> Floating algae (mg-N/L/day)
+ NH4_AbRespiration: Benthic algae -> NH4 (mg-N/L/day)
+ NH4_AbGrowth: NH4 -> Benthic Algae (g-N/L/day)
+
+ Ammonia Nitrogen (NH4) (mg-N/day*L)
+ dNH4/dt = OrgN_NH4_Decay
+ (OrgN -> NH4)
+ - NH4 Oxidation (NH4 -> NO3)
+ - NH4AlgalUptake (NH4 -> xr.DataArraying Algae)
+ + Benthos NH4 (Benthos -> NH4)
+ - Benthic Algae Uptake (NH4 -> Benthic Algae)
+
+ """
+
+ return xr.where(use_NH4, OrgN_NH4_Decay - NH4_Nitrification + NH4fromBed + NH4_ApRespiration - NH4_ApGrowth + NH4_AbRespiration - NH4_AbGrowth, 0.0)
+
+
+def NH4(
+ NH4: xr.DataArray,
+ dNH4dt: xr.DataArray,
+ timestep: xr.DataArray,
+
+) -> xr.DataArray:
+ """Calculate NH4: New concentration NH4 (mg-N/L)
+
+ Args:
+ NH4: Concentration of NH4 (mg-N/L)
+ dNH4dt: Change in NH4 (mg-N/L/d)
+ timestep: current iteration timestep (d)
+
+ """
+
+ return NH4 + dNH4dt * timestep
+
+def NO3_Denit(
+ use_DOX: bool,
+ DOX: xr.DataArray,
+ KsOxdn: xr.DataArray,
+ kdnit_tc: xr.DataArray,
+ NO3: xr.DataArray,
+
+) -> xr.DataArray:
+ """Calculate NO3_Denit: NO3 -> Loss (mg-N/L/day)
+
+ Args:
+ use_DOX: true/false to use dissolve oxygen module (unitless),
+ KsOxdn: Half-saturation oxygen inhibition constant for denitrification (mg-O2/L)
+ DOX: Dissolved oxygen concentration (mg-O2/L),
+ NO3: Nitrate concentration (mg-N/L),
+ kdnit_tc: Denitrification rate temperature correction (1/d)
+
+ """
+
+ NO3_Denit: np.ndarray = np.select(
+ condlist = [
+ (use_DOX) & (np.isnan((1.0 - (DOX / (DOX + KsOxdn))) * kdnit_tc * NO3)),
+ use_DOX
+ ],
+
+ choicelist = [
+ kdnit_tc * NO3,
+ (1.0 - (DOX / (DOX + KsOxdn))) * kdnit_tc * NO3
+ ],
+
+ default = 0.0
+ )
+
+ return NO3_Denit
+
+
+def NO3_BedDenit(
+ depth: xr.DataArray,
+ vno3_tc: xr.DataArray,
+ NO3: xr.DataArray,
+
+) -> xr.DataArray:
+ """Calculate NO3_BedDenit: Sediment denitrification (mg-N/L/day)
+
+ Args:
+ depth: water depth (m),
+ NO3: Nitrate concentration (mg-N/L)
+ vno3_tc: Sediment denitrification velocity temperature correction (m/d)
+
+ """
+
+ return vno3_tc * NO3 / depth
+
+def NO3_ApGrowth(
+ use_Algae: bool,
+ ApUptakeFr_NO3: xr.DataArray,
+ rna: xr.DataArray,
+ ApGrowth: xr.DataArray,
+
+) -> xr.DataArray:
+ """Calculate NO3_ApGrowth: NO3 -> Floating algae (mg-N/L/day)
+
+ Args:
+ use_Algae: true/false to use algae module (unitless),
+ rna: Algal N: Chla ratio (mg-N/ug-Chla),
+ ApGrowth: Algal growth rate (ug-Chla/L/d),
+ ApUptakeFr_NO3: Fraction of actual algal uptake from nitrate pool (unitless)
+
+
+ """
+
+ return xr.where(use_Algae, ApUptakeFr_NO3 * rna * ApGrowth, 0.0)
+
+def NO3_AbGrowth(
+ use_Balgae: bool,
+ AbUptakeFr_NO3: xr.DataArray,
+ rnb: xr.DataArray,
+ Fb: xr.DataArray,
+ AbGrowth: xr.DataArray,
+ depth: xr.DataArray,
+
+) -> xr.DataArray:
+ """Calculate NO3_AbGrowth: NO3 -> Benthic Algae (g-N/L/day)
+
+ Args:
+ use_Balgae: true/false to use benthic algae module (unitless),
+ depth: water depth (m),
+ rnb: Benthic algal N: Benthic Algal Dry Weight (mg-N/mg-D),
+ Fb: Fraction of bottom area for benthic algae (unitless),
+ AbGrowth: Benthic alga growth rate (g/m^2/d),
+ AbUptakeFr_NO3: Fraction of actual benthic algal uptake from nitrate pool (unitless)
+ """
+
+ return xr.where(use_Balgae, (AbUptakeFr_NO3 * rnb * Fb * AbGrowth) / depth, 0.0)
+
+
+def dNO3dt(
+ use_NO3: bool,
+ NH4_Nitrification: xr.DataArray,
+ NO3_Denit: xr.DataArray,
+ NO3_BedDenit: xr.DataArray,
+ NO3_ApGrowth: xr.DataArray,
+ NO3_AbGrowth: xr.DataArray,
+
+) -> xr.DataArray:
+ """Calculate dNO3dt: Change in nitrate (mg-N/L)
+
+ Args:
+ use_NH4: true/false to use ammonium module (unitless),
+ use_NO3: true/false to use nitrate module (unitless),
+ NH4_Nitrification: NH4 -> NO3 Nitrification (mg-N/L/day)
+ NO3_Denit: NO3 -> Loss (mg-N/L/day),
+ NO3_BedDenit: Sediment denitrification (mg-N/L/day)
+ NO3_ApGrowth: NO3 -> Floating algae (mg-N/L/day)
+ NO3_AbGrowth: NO3 -> Benthic Algae (g-N/L/day)
+
+ Nitrite Nitrogen (NO3) (mg-N/day*L)
+ dNO3/dt = NH4 Oxidation (NH4 -> NO3)
+ - NO3 Sediment Denitrification
+ - NO3 Algal Uptake (NO3-> xr.DataArraying Algae)
+ - NO3 Benthic Algal Uptake (NO3-> Benthic Algae)
+
+ """
+
+
+ return xr.where(use_NO3, NH4_Nitrification - NO3_Denit - NO3_BedDenit - NO3_ApGrowth - NO3_AbGrowth ,0)
+
+
+def NO3(
+ NO3: xr.DataArray,
+ dNO3dt: xr.DataArray,
+ timestep: xr.DataArray,
+
+) -> xr.DataArray:
+ """Calculate NO3: New concentration NO# (mg-N/L)
+
+ Args:
+ NO3: Concentration of NO3 (mg-N/L)
+ dNO3dt: Change in NO3(mg-N/L/d)
+ timestep: current iteration timestep (d)
+
+ """
+
+ return NO3 + dNO3dt * timestep
+
+
+def DIN(
+ use_NH4: bool,
+ use_NO3: bool,
+ NH4: xr.DataArray,
+ NO3: xr.DataArray,
+
+) -> xr.DataArray:
+ """Calculate DIN: Dissolve inorganic nitrogen (mg-N/L)
+
+ Args:
+ use_NH4: true/false to use ammonium module (unitless),
+ use_NO3: true/false to use nitrate module (unitless),
+ NH4: Ammonium concentration (mg-N/L),
+ NO3: Nitrate concentration (mg-N/L),
+ """
+ DIN = 0.0
+ DIN = xr.where(use_NH4, DIN + NH4,DIN)
+ DIN = xr.where(use_NO3, DIN + NO3, DIN)
+
+ return DIN
+
+
+def TON(
+ use_OrgN: bool,
+ use_Algae: bool,
+ OrgN: xr.DataArray,
+ rna: xr.DataArray,
+ Ap: xr.DataArray
+
+) -> xr.DataArray:
+ """Calculate TON: Total organic nitrogen (mg-N/L)
+
+ Args:
+ use_OrgN: true/false to use organic nitrogen module (unitless),
+ use_Algae: true/false to use algae module (unitless),
+ OrgN: Organic nitrogen concentration (mg-N/L),
+ rna: Algal N: Chla ratio (mg-N/ug-Chla),
+ Ap: Algae water concentration (ug-Chla/L)
+
+ """
+ TON = 0.0
+ TON = xr.where(use_OrgN, TON + OrgN, TON)
+ TON = xr.where(use_Algae, TON + rna * Ap, TON)
+
+ return TON
+
+
+def TKN(
+ use_NH4: bool,
+ NH4: xr.DataArray,
+ TON: xr.DataArray
+
+) -> xr.DataArray:
+ """Calculate TKN: Total kjeldhl (mg-N/L)
+
+ Args:
+ use_NH4: true/false to use organic nitrogen module (unitless),
+ NH4: Ammonium concentration (mg-N/L)
+ TON: Total organic nitrogen (mg-N/L)
+ """
+ TKN = 0.0
+ TKN = xr.where(use_NH4, TKN + NH4, TKN)
+
+ return TKN + TON
+
+
+
+def TN(
+ DIN: xr.DataArray,
+ TON: xr.DataArray,
+
+) -> xr.DataArray:
+ """Calculate TN: Total nitrogen (mg-N/L)
+
+ Args:
+ DIN: Dissolve inorganic nitrogen (mg-N/L)
+ TON: Total organic nitrogen (mg-N/L)
+ """
+
+ return DIN + TON
+
+################################### From phosphorus
+
+def kop_tc(
+ TwaterC : xr.DataArray,
+ kop_20: xr.DataArray
+) -> xr.DataArray :
+
+ """Calculate kop_tc: Decay rate of organic P to DIP temperature correction (1/d).
+
+ Args:
+ TwaterC: Water temperature (C)
+ kop_20: Decay rate of organic P to DIP at 20C (1/d)
+ """
+
+ return arrhenius_correction(TwaterC, kop_20, 1.047)
+
+
+def rpo4_tc(
+ TwaterC : xr.DataArray,
+ rpo4_20: xr.DataArray
+) -> xr.DataArray :
+
+ """Calculate rpo4_tc: Benthic sediment release rate of DIP temperature correction(g-P/m2/d).
+
+ Args:
+ TwaterC: Water temperature (C)
+ kop_20: Benthic sediment release rate of DIP at 20C (1/d)
+ """
+
+ return arrhenius_correction(TwaterC, rpo4_20, 1.074)
+
+def OrgP_DIP_decay(
+ kop_tc : xr.DataArray,
+ OrgP: xr.DataArray,
+ use_OrgP: bool,
+) -> xr.DataArray :
+
+ """Calculate OrgP_DIP: organic phosphorus decay to dissolve inorganic phosphorus (mg-P/L/d).
+
+ Args:
+ kop_tc: Decay rate of organic P to DIP temperature correction (1/d)
+ OrgP: Organic phosphorus concentration (mg-P/L)
+ use_OrgP: true/false use organic phosphorus (t/f)
+ """
+ return xr.where(use_OrgP,kop_tc * OrgP,0)
+
+
+def OrgP_Settling(
+ vsop : xr.DataArray,
+ depth: xr.DataArray,
+ OrgP: xr.DataArray,
+) -> xr.DataArray :
+
+ """Calculate OrgP_Settling: organic phosphorus settling to sediment (mg-P/L/d).
+
+ Args:
+ vsop: Organic phosphorus settling velocity (m/d)
+ depth: water depth (m)
+ OrgP: Organic phosphorus concentration (mg-P/L)
+ """
+ return (vsop / depth) * OrgP
+
+def ApDeath_OrgP(
+ rpa : xr.DataArray,
+ ApDeath: xr.DataArray,
+ use_Algae: bool,
+) -> xr.DataArray :
+
+ """Calculate ApDeath_OrgP: Algal death turning into organic phosphorus (mg-P/L/d).
+
+ Args:
+ rpa: Algal P : Chla ratio (mg-P/ug-Chla)
+ ApDeath: Algal death rate (ug-Chla/L/d)
+ use_Algae: true/false to use algae module (T/F)
+
+ """
+
+ return xr.where(use_Algae, rpa * ApDeath,0)
+
+def AbDeath_OrgP(
+ rpb : xr.DataArray,
+ AbDeath: xr.DataArray,
+ Fw: xr.DataArray,
+ Fb: xr.DataArray,
+ depth: xr.DataArray,
+ use_Balgae: bool
+) -> xr.DataArray :
+
+ """Calculate AbDeath_OrgP: Benthic algal death turning into organic phosphorus (mg-P/L/d).
+
+ Args:
+ rpb : Benthic algal P: Benthic algal dry (mg-P/mg-D)
+ AbDeath: Benthic algal death rate (g/m^2/d)
+ Fw: Fraction benthic algal death to water column (unitless)
+ Fb: Fraction bottom area avalible for benthic algae (unitless)
+ depth: water depth (m)
+ use_Balgae: true/false use benthic algae module (t/f)
+
+ """
+
+ return xr.where(use_Balgae, (rpb * Fw *Fb * AbDeath) / depth,0)
+
+def dOrgPdt(
+ ApDeath_OrgP : xr.DataArray,
+ AbDeath_OrgP: xr.DataArray,
+ OrgP_DIP_decay: xr.DataArray,
+ OrgP_Settling: xr.DataArray,
+ use_OrgP: bool,
+) -> xr.DataArray :
+ """Calculate dOrgPdt: change in organic phosphorus concentration (mg-P/L/d).
+
+ Args:
+ ApDeath_OrgP: Algal death turns into organic phosphrous
+ AbDeath_OrgP: Benthic algal death turns into organic phosphrous
+ OrgP_DIP_decay: Organic phosphrous decaying into dissolve inorganic phosphrous
+ OrgP_Settling: Organic phosphrous settling into sediment
+ use_OrgP: true/false to use organic phosphorus module (true/false)
+ use_Algae: true/false to use algae module (true/false)
+ use_Balgae: true/false to use benthic algae module (true/false)
+ """
+
+ return xr.where(use_OrgP, -OrgP_DIP_decay-OrgP_Settling + ApDeath_OrgP + AbDeath_OrgP, 0)
+
+
+def DIPfromBed(
+ depth:xr.DataArray,
+ rpo4_tc: xr.DataArray,
+) -> xr.DataArray :
+ """Calculate DIPfromBed: Dissolved Organic Phosphorus coming from Bed calculated without a SedFlux module (mg-P/L/d).
+
+ Args:
+ depth: water depth (m)
+ rpo4_tc: Benthic sediment release rate of DIP temperature correction(g-P/m2/d)
+ """
+ return rpo4_tc / depth
+
+#TODO calcuate fdp?
+
+def TIP_Settling(
+ vs: xr.DataArray,
+ depth: xr.DataArray,
+ fdp: xr.DataArray,
+ TIP: xr.DataArray
+) -> xr.DataArray :
+
+ """Calculate TIP_Settling: Total inorganic phosphorus settling from water to bed (mg-P/L/d).
+
+ Args:
+ vs: Sediment settling velocity (m/d)
+ depth: water depth (m)
+ fdp: Fraction phosphorus dissolved (unitless)
+ TIP: Total inorganic phosphorus water concentration (mg-P/L)
+ """
+ return vs / depth * (1.0 - fdp) * TIP
+
+def DIP_ApRespiration(
+ rpa: xr.DataArray,
+ ApRespiration: xr.DataArray,
+ use_Algae: bool
+
+) -> xr.DataArray :
+ """Calculate DIP_ApRespiration: Dissolved inorganic phosphorus released from algal respiration (mg-P/L/d).
+
+ Args:
+ rpa: Algal P : Chla ratio (mg-P/ug-Chla)
+ ApRespiration: Algal respiration rate (ug-Chla/L/d)
+ use_Algae: true/false to use algae module (t/f)
+ """
+ return xr.where(use_Algae, rpa * ApRespiration,0)
+
+def DIP_ApGrowth(
+ rpa: xr.DataArray,
+ ApGrowth: xr.DataArray,
+ use_Algae: bool
+
+) -> xr.DataArray :
+ """Calculate DIP_ApGrowth: Dissolved inorganic phosphorus consumed for algal growth (mg-P/L/d).
+
+ Args:
+ rpa: Algal P : Chla ratio (mg-P/ug-Chla)
+ ApGrowth: Algal growth rate (ug-Chla/L/d)
+ use_Algae: true/false to use algae module (t/f)
+ """
+ return xr.where(use_Algae, rpa * ApGrowth,0)
+
+def DIP_AbRespiration(
+ rpb: xr.DataArray,
+ AbRespiration: xr.DataArray,
+ use_Balgae: bool
+
+) -> xr.DataArray :
+ """Calculate DIP_AbRespiration: Dissolved inorganic phosphorus released for benthic algal respiration (mg-P/L/d).
+
+ 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)
+ """
+ return xr.where(use_Balgae, rpb * AbRespiration,0)
+
+def DIP_AbGrowth(
+ rpb: xr.DataArray,
+ AbGrowth: xr.DataArray,
+ Fb: xr.DataArray,
+ depth: xr.DataArray,
+ use_Balgae: bool
+
+) -> xr.DataArray :
+ """Calculate DIP_AbGrowth: Dissolved inorganic phosphorus consumed for benthic algal growth (mg-P/L/d).
+
+ Args:
+ rpb: Benthic algal P : Benthic algal dry ratio (mg-P/mg-D)
+ AbGrowth: Benthic algal growth rate (g/m^2/d)
+ Fb: Fraction of bottom area available for benthic algal (unitless)
+ depth: water depth (m)
+ use_Balgae: true/false to use benthic algae module (t/f)
+ """
+ return xr.where(use_Balgae, rpb * Fb * AbGrowth / depth,0)
+
+def dTIPdt(
+ OrgP_DIP_decay: xr.DataArray,
+ TIP_Settling: xr.DataArray,
+ DIPfromBed: xr.DataArray,
+ DIP_ApRespiration: xr.DataArray,
+ DIP_ApGrowth: xr.DataArray,
+ DIP_AbRespiration: xr.DataArray,
+ DIP_AbGrowth: xr.DataArray,
+ use_TIP: bool,
+
+) -> xr.DataArray :
+
+ """Calculate dTIPdt: Change in dissolved inorganic phosphorus water concentration (mg-P/L/d).
+
+ Args:
+ OrgP_DIP_decay: Total organic phosphorus decaying to dissolved inorganic phosphrous (mg-P/L/d),
+ TIP_Settling: Total inorganic phosphorus settling from water to bed (mg-P/L/d),
+ DIPfromBed_NoSedFlux: Dissolved Organic Phosphorus coming from Bed calculated without SedFlux modules (mg-P/L/d),
+ DIPfromBed_SedFlux: Dissolved Organic Phosphorus coming from Bed calculated using SedFlux modules (mg-P/L/d),
+ DIP_ApRespiration: Dissolved inorganic phosphorus released from algal respiration (mg-P/L/d),
+ DIP_ApGrowth: Dissolved inorganic phosphorus consumed for algal growth (mg-P/L/d),
+ DIP_AbRespiration: Dissolved inorganic phosphorus released for benthic algal respiration (mg-P/L/d),
+ DIP_AbGrowth: Dissolved inorganic phosphorus consumed for benthic algal growth (mg-P/L/d),
+ use_TIP: true/false to use total inorganic phosphorus module (true/false),
+
+
+ dTIP/dt = OrgP Decay (OrgP -> DIP)
+ - DIP AlgalUptake (DIP -> xr.DataArraying Algae)
+ - DIP BenthicAlgae Uptake (DIP -> xr.DataArraying Algae)
+ - TIP Settling (TIP -> bed)
+ + DIP From Benthos (Benthos -> DIP)
+ """
+
+ return xr.where(use_TIP, - TIP_Settling + DIPfromBed + OrgP_DIP_decay + DIP_ApRespiration - DIP_ApGrowth + DIP_AbRespiration - DIP_AbGrowth, 0)
+
+
+
+def TIP(
+ TIP: xr.DataArray,
+ dTIPdt: xr.DataArray,
+ timestep: xr.DataArray
+
+) -> xr.DataArray :
+ """Calculate TIP: New total inorganic phosphorus (mg-P/L).
+
+ Args:
+ dTIPdt: Change in total inorganic phosphorus (mg-P/L/d)
+ TIP: Total inorganic phosphorus water concentration (mg-P/L),
+ timestep: current iteration timestep (d)
+ """
+ return TIP + dTIPdt * timestep
+
+
+def OrgP(
+ OrgP: xr.DataArray,
+ dOrgPdt: xr.DataArray,
+ timestep: xr.DataArray
+
+) -> xr.DataArray :
+ """Calculate OrgP: New total organic phosphorus (mg-P/L).
+
+ Args:
+ dOrgPdt: Change in total organic phosphorus (mg-P/L/d)
+ OrgP: Total organic phosphorus water concentration (mg-P/L),
+ timestep: current iteration timestep (d)
+ """
+ return OrgP + dOrgPdt * timestep
+
+def TOP(
+ use_OrgP: bool,
+ OrgP: xr.DataArray,
+ use_Algae: bool,
+ rpa: xr.DataArray,
+ Ap: xr.DataArray
+
+) -> xr.DataArray :
+ """Calculate TOP: Total organic phosphorus (mg-P/L).
+
+ Args:
+ use_OrgP: true/false to use organic phosphorus module (true/false),
+ OrgP: New organic phosphorus water concentration (mg-P/L),
+ use_Algae: true/false to use algae module (true/false),
+ rpa: Algal P: Chla ratio (mg-P/ug-Chla),
+ Ap: Algal water concentration (ug-Chla/L)
+ """
+ TOP = 0.0
+ TOP = xr.where(use_OrgP, TOP + OrgP,TOP)
+ TOP = xr.where(use_Algae, TOP + rpa*Ap, TOP)
+
+ return TOP
+
+
+def TP(
+ use_TIP: bool,
+ TOP: xr.DataArray,
+ TIP: xr.DataArray
+
+) -> xr.DataArray :
+ """Calculate TP: Total phosphorus (mg-P/L).
+
+ Args:
+ use_TIP: true/false to use total inorganic phosphorus module (true/false),
+ TIP: New total inorganic phosphorus water concentration (mg-P/L),
+ TOP: Total organic phosphorus water concentration (mg-P/L)
+ """
+ TP = TOP
+ TP = xr.where(use_TIP,TP + TIP,TP)
+ return TP
+
+
+def DIP(
+ fdp: xr.DataArray,
+ TIP: xr.DataArray
+
+) -> xr.DataArray :
+ """Calculate DIP: Dissolve inorganich phosphorus (mg-P/L).
+
+ Args:
+ fdp: fraction P dissolved
+ TIP: New total inorganic phosphorus water concentration (mg-P/L),
+ """
+ return TIP * fdp
+
+
+################################### From POM
+
+def kpom_tc(
+ TwaterC: float,
+ kpom_20: float,
+) -> float:
+ """Calculate the temperature adjusted POM dissolution rate (1/d)
+
+ Args:
+ TwaterC: Water temperature in Celsius
+ kpom_20: POM dissolution rate at 20 degrees Celsius (1/d)
+ """
+ return arrhenius_correction(TwaterC, kpom_20, 1.047)
+
+
+def POM_algal_settling(
+ Ap: xr.DataArray,
+ vsap: xr.DataArray,
+ rda: xr.DataArray,
+ depth: xr.DataArray,
+ use_Algae: xr.DataArray
+) -> xr.DataArray:
+ """Calculates the particulate organic matter concentration change due to algal mortality
+
+ Args:
+ 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)
+ use_Algae: Option to consider algal kinetics
+ """
+ da: xr.DataArray = xr.where(use_Algae == True, vsap * Ap * rda / depth, 0)
+
+ return da
+
+
+
+def POM_dissolution(
+ POM: xr.DataArray,
+ kpom_tc: xr.DataArray
+) -> xr.DataArray:
+ """Calculates the particulate organic matter concentration change due to POM dissolution
+
+ Args:
+ POM: Concentration of particulate organic matter (mg/L)
+ kpom_tc: POM dissolution rate corrected for temperature (1/d)
+ """
+
+ return POM * kpom_tc
+
+
+def POM_POC_settling(
+ POC: xr.DataArray,
+ vsoc: xr.DataArray,
+ depth: xr.DataArray,
+ fcom: xr.DataArray,
+ use_POC: xr.DataArray
+) -> xr.DataArray:
+ """Calculates particulate organic matter concentration change due to POM settling
+
+ Args:
+ POC: Concentration of particulate organic carbon (mg/L)
+ vsoc: POC settling velocity (m/d)
+ depth: Depth of water (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)
+
+ return da
+
+
+def POM_benthic_algae_mortality(
+ Ab: xr.DataArray,
+ kdb_tc: xr.DataArray,
+ Fb: xr.DataArray,
+ Fw: xr.DataArray,
+ depth: xr.DataArray,
+ use_Balgae: xr.DataArray
+) -> xr.DataArray:
+ """Calculates particulate organic matter concentration change due to benthic algae mortality
+
+ Args:
+ Ab: Benthic algae concentration (mg/L)
+ 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)
+ 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)
+
+ return da
+
+
+
+def POM_burial(
+ vb: xr.DataArray,
+ POM: xr.DataArray,
+ depth: 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)
+ """
+ return vb * POM / depth
+
+
+
+def dPOMdt(
+ POM_algal_settling: xr.DataArray,
+ POM_dissolution: xr.DataArray,
+ POM_POC_settling: xr.DataArray,
+ POM_benthic_algae_mortality: xr.DataArray,
+ POM_burial: xr.DataArray,
+) -> xr.DataArray:
+ """Calculates the concentration change of POM for one timestep
+
+ Args:
+ POM_algal_settling: POM concentration change due to algal settling (mg/L/d)
+ POM_dissolution: POM concentration change due to dissolution (mg/L/d)
+ POM_POC_settling: POM concentration change due to POC settling (mg/L/d)
+ POM_benthic_algae_mortality: POM concentration change due to benthic algae mortality (mg/L/d)
+ POM_burial: POM concentration change due to burial (mg/L/d)
+ """
+ return POM_algal_settling - POM_dissolution + POM_POC_settling + POM_benthic_algae_mortality - POM_burial
+
+
+
+def POM(
+ dPOMdt: xr.DataArray,
+ POM: xr.DataArray,
+ timestep: xr.DataArray
+) -> xr.DataArray:
+ """Computes updated particulate organic matter concentration (mg/L)
+
+ Args:
+ dPOMdt: Change in POM concentration over timestep (mg/L/d)
+ POM: POM concentration from previous timestep (mg/L)
+ timestep: Current iteration timestep (d)
+ """
+ return POM + dPOMdt * timestep
+
+
+################################## From CBOD
+
+def kbod_tc(
+ TwaterC: xr.DataArray,
+ kbod_20: xr.DataArray,
+) -> xr.DataArray:
+ """Calculate the temperature adjusted CBOD oxidation rate (1/d)
+
+ Args:
+ TwaterC: water temperature in Celsius
+ kbod_20: CBOD oxidation rate at 20 degrees Celsius (1/d)
+ """
+
+ kbod_tc = arrhenius_correction(TwaterC, kbod_20, 1.047)
+ return kbod_tc
+
+
+
+def ksbod_tc(
+ TwaterC: xr.DataArray,
+ ksbod_20: xr.DataArray,
+) -> xr.DataArray:
+ """Calculate the temperature adjusted CBOD sedimentation rate (m/d)
+
+ Args:
+ TwaterC: water temperature in Celsius
+ ksbod_20: CBOD sedimentation rate at 20 degrees Celsius (m/d)
+ """
+
+ ksbod_tc = arrhenius_correction(TwaterC, ksbod_20, 1.024)
+ return ksbod_tc
+
+
+
+def CBOD_oxidation(
+ DOX: xr.DataArray,
+ CBOD: xr.DataArray,
+ kbod_tc: xr.DataArray,
+ KsOxbod: xr.DataArray,
+ use_DOX: xr.DataArray
+) -> xr.DataArray:
+ """Calculates CBOD oxidation
+
+ Args:
+ DOX: Dissolved oxygen concentration (mg-O2/L)
+ CBOD: Carbonaceous biochemical oxygen demand (mg-O2/L)
+ kbod_tc: Temperature adjusted CBOD oxidation rate (1/d)
+ KsOxbod: Half-saturation oxygen attenuation for CBOD oxidation (mg-O2/L)
+ use_DOX: Option to consider DOX concentration in calculation of CBOD oxidation
+ """
+ da: xr.DataArray = xr.where(use_DOX == True, (DOX / (KsOxbod + DOX)) * kbod_tc * CBOD, kbod_tc * CBOD)
+
+ return da
+
+
+
+def CBOD_sedimentation(
+ CBOD: xr.DataArray,
+ ksbod_tc: xr.DataArray
+) -> xr.DataArray:
+ """Calculates CBOD sedimentation for each group
+
+ Args:
+ CBOD: CBOD concentration (mg-O2/L)
+ ksbod_tc: Temperature adjusted sedimentation rate (m/d)
+ """
+
+ CBOD_sedimentation = CBOD * ksbod_tc
+ return CBOD_sedimentation
+
+
+
+def dCBODdt(
+ CBOD_oxidation: xr.DataArray,
+ CBOD_sedimentation: xr.DataArray
+) -> xr.DataArray:
+ """Computes change in each CBOD group for a given timestep
+
+ Args:
+ CBOD_oxidation: CBOD concentration change due to oxidation (mg/L/d)
+ CBOD_sedimentation: CBOD concentration change due to sedimentation (mg/L/d)
+ """
+ return - CBOD_oxidation - CBOD_sedimentation
+
+
+
+def CBOD(
+ CBOD: xr.DataArray,
+ dCBODdt: xr.DataArray,
+ timestep: xr.DataArray
+) -> xr.DataArray:
+ """Calculates new CBOD concentration for next timestep
+
+ Args:
+ CBOD: CBOD concentration from previous timestep (mg/L)
+ dCBODdt: CBOD concentration change for current timestep (mg/L/d)
+ timestep: current iteration timestep (d)
+ """
+ return CBOD + dCBODdt * timestep
+
+############################### From Carbon
+
+
+def kpoc_tc(
+ TwaterC: xr.DataArray,
+ kpoc_20: xr.DataArray,
+) -> xr.DataArray:
+ """Calculate the temperature adjusted POC hydrolysis rate (/d)
+
+ Args:
+ TwaterC: Water temperature in Celsius
+ kpoc_20: POC hydrolysis rate at 20 degrees Celsius (1/d)
+ """
+ return arrhenius_correction(TwaterC, kpoc_20, 1.047)
+
+
+
+def POC_hydrolysis(
+ kpoc_tc: xr.DataArray,
+ POC: xr.DataArray,
+) -> xr.DataArray:
+ """Calculate the POC concentration change due to hydrolysis for a given timestep
+
+ Args:
+ kpoc_tc: POC hydrolysis rate at given water temperature (1/d)
+ POC: POC concentration (mg/L)
+ """
+ return kpoc_tc * POC
+
+
+
+def POC_settling(
+ vsoc: xr.DataArray,
+ depth: xr.DataArray,
+ POC: xr.DataArray
+) -> xr.DataArray:
+ """Calculate the POC concentration change due to settling for a given timestep
+
+ Args:
+ vsoc: POC settling velocity (m/d)
+ depth: Water depth of cell (m)
+ POC: POC concentration (mg/L)
+ """
+ return vsoc / depth * POC
+
+
+def POC_algal_mortality(
+ f_pocp: xr.DataArray,
+ kdp_tc: xr.DataArray,
+ rca: xr.DataArray,
+ Ap: xr.DataArray,
+ use_Algae: xr.DataArray
+) -> xr.DataArray:
+ """Calculate the POC concentration change due to algal mortality
+
+ Args:
+ f_pocp: Fraction of algal mortality into POC
+ kdp_tc: Algal death rate at water temperature (1/d)
+ rca: Algal C to chlorophyll-a ratio (mg-C/ugChla)
+ Ap: Algae concentration (mg/L)
+ use_Algae: Option for considering algae in POC budget (boolean)
+ """
+ da: xr.DataArray = xr.where(use_Algae == True, f_pocp * kdp_tc * rca * Ap, 0)
+
+ return da
+
+
+def POC_benthic_algae_mortality(
+ depth: xr.DataArray,
+ f_pocb: xr.DataArray,
+ kdb_tc: xr.DataArray,
+ rcb: xr.DataArray,
+ Ab: xr.DataArray,
+ Fb: xr.DataArray,
+ Fw: xr.DataArray,
+ use_Balgae: xr.DataArray
+) -> xr.DataArray:
+ """Calculate the POC concentration change due to benthic algae mortality
+
+ Args:
+ depth: Water depth in cell (m)
+ f_pocb: Fraction of benthic algal mortality into POC
+ kdb_tc: Benthic algae death rate (1/d)
+ rcb: Benthic algae C to biomass weight ratio (mg-C/mg-D)
+ Ab: Benthic algae concentration (mg/L)
+ Fb: Fraction of bottom area available for benthic algae growth
+ Fw: Fraction of benthic algae mortality into water column
+ use_Balgae: Option for considering benthic algae in POC budget (boolean)
+ """
+ da: xr.DataArray = xr.where(use_Balgae == True, (1 / depth) * f_pocb * kdb_tc * rcb * Ab * Fb * Fw, 0)
+
+ return da
+
+
+def dPOCdt(
+ POC_settling: xr.DataArray,
+ POC_hydrolysis: xr.DataArray,
+ POC_algal_mortality: xr.DataArray,
+ POC_benthic_algae_mortality: xr.DataArray
+) -> xr.DataArray:
+ """Calculate the change in POC concentration
+
+ Args:
+ POC_settling: Concentration change of POC due to settling (mg/L/d)
+ POC_hydrolysis: Concentration change of POC due to hydrolysis (mg/L/d)
+ POC_algal_mortality: Concentration change of POC due to algal mortality (mg/L/d)
+ POC_benthic_algae_mortality: Concentration change of POC due to benthic algae mortality (mg/L/d)
+ """
+ return POC_algal_mortality + POC_benthic_algae_mortality - POC_settling - POC_hydrolysis
+
+
+
+def POC(
+ POC: xr.DataArray,
+ dPOCdt: xr.DataArray,
+ timestep: xr.DataArray
+) -> xr.DataArray:
+ """Calculate the POC concentration at the next time step
+
+ Args:
+ POC: Concentration of POC from previous timestep (mg/L)
+ dPOCdt: POC concentration change for current timestep (mg/L/d)
+ timestep: current iteration timestep (d)
+ """
+ return POC + dPOCdt * timestep
+
+
+def DOC_algal_mortality(
+ f_pocp: xr.DataArray,
+ kdp_tc: xr.DataArray,
+ rca: xr.DataArray,
+ Ap: xr.DataArray,
+ use_Algae: xr.DataArray
+) -> xr.DataArray:
+ """Calculate the DOC concentration change due to algal mortality
+
+ Args:
+ f_pocp: Fraction of algal mortality into POC
+ kdp_tc: Algal death rate at water temperature (1/d)
+ rca: Algal C to chlorophyll-a ratio (mg-C/ug-Chla)
+ Ap: Algae concentration (mg/L)
+ use_Algae: Option for considering algae in DOC budget (boolean)
+ """
+ da: xr.DataArray = xr.where(use_Algae == True, (1 - f_pocp) * kdp_tc * rca * Ap, 0)
+
+ return da
+
+
+def DOC_benthic_algae_mortality(
+ depth: xr.DataArray,
+ f_pocb: xr.DataArray,
+ kdb_tc: xr.DataArray,
+ rcb: xr.DataArray,
+ Ab: xr.DataArray,
+ Fb: xr.DataArray,
+ Fw: xr.DataArray,
+ use_Balgae: xr.DataArray
+) -> xr.DataArray:
+ """Calculate the DOC concentration change due to benthic algae mortality
+
+ Args:
+ depth: Water depth in cell (m)
+ F_pocb: Fraction of benthic algal mortality into POC
+ kdb_tc: Benthic algae death rate (1/d)
+ rcb: Benthic algae C to biomass weight ratio (mg-C/mg-D)
+ Ab: Benthic algae concentration (mg/L)
+ Fb: Fraction of bottom area available for benthic algae growth
+ Fw: Fraction of benthic algae mortality into water column
+ use_Balgae: Option for considering benthic algae in DOC budget (boolean)
+ """
+ da: xr.DataArray = xr.where(use_Balgae == True, (1 / depth) * (1 - f_pocb) * kdb_tc * rcb * Ab * Fb * Fw, 0)
+
+ return da
+
+
+
+def kdoc_tc(
+ TwaterC: xr.DataArray,
+ kdoc_20: xr.DataArray,
+) -> xr.DataArray:
+ """Calculate the temperature adjusted DOC oxidation rate (1/d)
+
+ Args:
+ TwaterC: Water temperature in Celsius
+ kdoc_20: DOC oxidation rate at 20 degrees Celsius (1/d)
+ """
+ return arrhenius_correction(TwaterC, kdoc_20, 1.047)
+
+
+def DOC_DIC_oxidation(
+ DOX: xr.DataArray,
+ KsOxmc: xr.DataArray,
+ kdoc_tc: xr.DataArray,
+ DOC: xr.DataArray,
+ use_DOX: xr.DataArray
+) -> xr.DataArray:
+ """Calculates the DOC concentration change due to oxidation
+
+ Args:
+ DOX: Concentration of dissolved oxygen (mg/L)
+ KsOxmc: Half saturation oxygen attenuation constant for DOC oxidation rate (mg-O2/L)
+ kdoc_tc: DOC oxidation rate (1/d)
+ DOC: Concentration of dissolved organic carbon (mg/L)
+ use_DOX: Option for considering dissolved oxygen concentration in DOC oxidation calculation (boolean)
+ """
+ da: xr.DataArray = xr.where(use_DOX == True, DOX / (KsOxmc + DOX) * kdoc_tc * DOC, kdoc_tc * DOC)
+
+ return da
+
+
+
+def dDOCdt(
+ DOC_DIC_oxidation: xr.DataArray,
+ POC_hydrolysis: xr.DataArray,
+ DOC_algal_mortality: xr.DataArray,
+ DOC_benthic_algae_mortality: xr.DataArray
+) -> xr.DataArray:
+ """Calculates the change in DOC concentration
+
+ Args:
+ POC_hydrolysis: DOC concentration change due to POC hydrolysis (mg/L/d)
+ DOC_POM_dissolution: DOC concentration change due to POM dissolution (mg/L/d)
+ DOC_denitrification: DOC concentration change due to DOC denitrification (mg/L/d)
+ DOC_algal_mortality: DOC concentration change due to algal mortality (mg/L/d)
+ DOC_benthic_algae_mortality: DOC concentration change due to benthic algae mortality (mg/L/d)
+ DOC_oxidation: DOC concentration change due to DOC oxidation (mg/L/d)
+ """
+ return POC_hydrolysis + DOC_algal_mortality + DOC_benthic_algae_mortality - DOC_DIC_oxidation
+
+
+
+def DOC(
+ DOC: xr.DataArray,
+ dDOCdt: xr.DataArray,
+ timestep: xr.DataArray
+) -> xr.DataArray:
+ """Calculate the DOC concentration at the next time step
+
+ Args:
+ DOC: Dissolved organic carbon concentration from previous timestep (mg/L)
+ dDOCdt: Dissolved organic carbon concentration change for current timestep (mg/L/d)
+ timestep: current iteration timestep (d)
+ """
+ return DOC + dDOCdt * timestep
+
+
+
+def Henrys_k(
+ TwaterC: xr.DataArray
+) -> xr.DataArray:
+ """Calculates the temperature dependent Henry's coefficient (mol/L/atm)
+
+ Args:
+ TwaterC: Water temperature in celsius
+ """
+ return 10**(2385.73 / (TwaterC + 273.15) + .0152642 * (TwaterC + 273.15) - 14.0184)
+
+
+def Atmospheric_CO2_reaeration(
+ ka_tc: xr.DataArray,
+ K_H: xr.DataArray,
+ pCO2: xr.DataArray,
+ FCO2: xr.DataArray,
+ DIC: xr.DataArray
+) -> xr.DataArray:
+ """Calculates the atmospheric input of CO2 into the waterbody
+
+ Args:
+ ka_tc: CO2 reaeration rate adjusted for temperature, same as O2 reaeration rate (1/d)
+ K_H: Henry's Law constant (mol/L/atm)
+ pCO2: Partial pressure of CO2 in the atmosphere (ppm)
+ FCO2: Fraction of CO2 in total inorganic carbon
+ DIC: Dissolved inorganic carbon concentration (mg/L)
+ """
+ return 12 * ka_tc * (10**-3 * K_H * pCO2 - 10**3 * FCO2 * DIC)
+
+
+def DIC_algal_respiration(
+ ApRespiration: xr.DataArray,
+ rca: xr.DataArray,
+ use_Algae: xr.DataArray
+) -> xr.DataArray:
+ """Calculates DIC concentration change due to algal respiration
+
+ Args:
+ ApRespiration: Algae respiration calculated in algae module (ug-Chla/L/d)
+ rca: Ratio of carbon to chlorophyll-a (mg-C/ug-Chla)
+ use_Algae: Option to consider algae in the DIC budget (boolean)
+ """
+ da: xr.DataArray = xr.where(use_Algae == True, ApRespiration * rca, 0)
+
+ return da
+
+
+def DIC_algal_photosynthesis(
+ ApGrowth: xr.DataArray,
+ rca: xr.DataArray,
+ use_Algae: xr.DataArray
+) -> xr.DataArray:
+ """Calculates DIC concentration change due to algal photosynthesis
+
+ Args:
+ ApGrowth: Algal photosynthesis calculated in algae module (ug-Chla/L/d)
+ rca: Ratio of carbon to chlorophyll-a (mg-C/ug-Chla)
+ use_Algae: Option to consider algae in the DIC budget (boolean)
+ """
+ da: xr.DataArray = xr.where(use_Algae == True, ApGrowth * rca, 0)
+
+ return da
+
+
+def DIC_benthic_algae_respiration(
+ AbRespiration: xr.DataArray,
+ rcb: xr.DataArray,
+ Fb: xr.DataArray,
+ depth: xr.DataArray,
+ use_Balgae: xr.DataArray
+) -> xr.DataArray:
+ """Calculates DIC flux due to benthic algae respiration
+
+ Args:
+ AbRespiration: Benthic algae respiration calculated in benthic algae module (g/m2/d)
+ rcb: Benthic algae carbon to dry weight ratio (mg-C/mg-D)
+ Fb: Fraction of bottom area available for benthic algae growth
+ depth: Depth of water (m)
+ use_Balgae: Option to consider benthic algae in the DIC budget (boolean)
+ """
+ da: xr.DataArray = xr.where(use_Balgae == True, AbRespiration * rcb * Fb * (1 / depth), 0)
+
+ return da
+
+
+def DIC_benthic_algae_photosynthesis(
+ AbGrowth: xr.DataArray,
+ rcb: xr.DataArray,
+ Fb: xr.DataArray,
+ depth: xr.DataArray,
+ use_Balgae: xr.DataArray
+) -> xr.DataArray:
+ """Calculates DIC flux due to benthic algae growth
+
+ Args:
+ AbGrowth: Benthic algae photosynthesis calculated in the benthic algae module (g/m2/d)
+ rcb: Benthic algae carbon to dry weight ratio (mg-C/mg-D)
+ Fb: Fraction of bottom area available for benthic algae growth
+ depth: Depth of water (m)
+ use_Balgae: Option to consider benthic algae in the DIC budget (boolean)
+ """
+ da: xr.DataArray = xr.where(use_Balgae == True, AbGrowth * rcb * Fb * (1 / depth), 0)
+
+ return da
+
+
+def DIC_CBOD_oxidation(
+ DOX: xr.DataArray,
+ CBOD: xr.DataArray,
+ roc: xr.DataArray,
+ kbod_tc: xr.DataArray, #imported from CBOD module
+ KsOxbod: xr.DataArray, #imported from CBOD module
+ use_DOX: xr.DataArray
+) -> xr.DataArray:
+ """Calculates DIC concentration change due to CBOD oxidation
+
+ Args:
+ DOX: Dissolved oxygen concentration (mg/L)
+ CBOD: Carbonaceous biochemical oxygen demand concentration (mg/L)
+ roc: Ratio of O2 to carbon for carbon oxidation (mg-O2/mg-C)
+ kbod_tc: CBOD oxidation rate (1/d)
+ KsOxbod: Half saturation oxygen attenuation constant for CBOD oxidation (mg-O2/L)
+ use_DOX: Option to consider dissolved oxygen in CBOD oxidation calculation (boolean)
+ """
+
+ da: xr.DataArray = xr.where(use_DOX == True, (1 / roc) * (DOX / (KsOxbod + DOX)) * kbod_tc * CBOD, CBOD * kbod_tc)
+
+ return da
+
+
+def DIC_sed_release(
+ SOD_tc: xr.DataArray,
+ roc: xr.DataArray,
+ depth: xr.DataArray,
+
+) -> xr.DataArray:
+ """Computes the sediment release of DIC
+
+ Args:
+ SOD_tc: Sediment oxygen demand adjusted for water temperature (mg-O2/L/d)
+ roc: Ratio of O2 to carbon for carbon oxidation (mg-O2/mg-C)
+ depth: Water depth (m)
+ """
+ return SOD_tc / roc / depth
+
+
+
+def dDICdt(
+ Atm_CO2_reaeration: xr.DataArray,
+ DIC_algal_respiration: xr.DataArray,
+ DIC_algal_photosynthesis: xr.DataArray,
+ DIC_benthic_algae_respiration: xr.DataArray,
+ DIC_benthic_algae_photosynthesis: xr.DataArray,
+ DIC_CBOD_oxidation: xr.DataArray,
+ DIC_sed_release: xr.DataArray
+) -> xr.DataArray:
+ """Calculates the change in DIC
+
+ Args:
+ Atm_CO2_reaeration: DIC concentration change due to atmospheric CO2 reaeration (mg/L/d)
+ DIC_algal_respiration: DIC concentration change due to algal respiration (mg/L/d)
+ DIC_algal_photosynthesis: DIC concentration change due to algal photosynthesis (mg/L/d)
+ DIC_benthic_algae_respiration: DIC concentration change due to benthic algae respiration (mg/L/d)
+ DIC_benthic_algae_photosynthesis: DIC concentration change due to benthic algae photosynthesis (mg/L/d)
+ DIC_CBOD_oxidation: DIC concentration change due to CBOD oxidation (mg/L/d)
+ DIC_sed_release: DIC concentration change due to sediment release (mg/L/d)
+ """
+ return Atm_CO2_reaeration + DIC_algal_respiration + DIC_benthic_algae_respiration + DIC_CBOD_oxidation + DIC_sed_release - DIC_algal_photosynthesis - DIC_benthic_algae_photosynthesis
+
+
+
+def DIC(
+ DIC: xr.DataArray,
+ dDICdt: xr.DataArray,
+ timestep: xr.DataArray
+) -> xr.DataArray:
+ """Calculate the DIC concentration at the next time step
+
+ Args:
+ DIC: Concentration of DIC from previous timestep (mg/L)
+ dDICdt: Change in concentration of DIC for current timestep (mg/L/d)
+ timestep: Current iteration timestep (d)
+ """
+ return DIC + dDICdt * timestep
+
+
+######################################## From DOX
+
+
+#TODO: make sure np.exp will work here...
+
+def pwv(
+ TwaterK: xr.DataArray
+) -> xr.DataArray:
+ """Calculate partial pressure of water vapor
+
+ Args:
+ TwaterK: Water temperature kelvin
+ """
+ return np.exp(11.8571 - 3840.70 / TwaterK - 216961 / TwaterK ** 2)
+
+
+
+def DOs_atm_alpha(
+ TwaterK: xr.DataArray
+) -> xr.DataArray:
+ """Calculate DO saturation atmospheric correction coefficient
+
+ Args:
+ TwaterK: Water temperature kelvin
+ """
+ return .000975 - 1.426 * 10 ** -5 * TwaterK + 6.436 * 10 ** -8 * TwaterK ** 2
+
+
+
+def DOX_sat(
+ TwaterK: xr.DataArray,
+ pressure_atm: xr.DataArray,
+ pwv: xr.DataArray,
+ DOs_atm_alpha: xr.DataArray
+) -> xr.DataArray:
+ """Calculate DO saturation value
+
+ Args:
+ TwaterK: Water temperature kelvin
+ pressure_atm: Atmospheric pressure (atm)
+ pwv: Patrial pressure of water vapor (atm)
+ DOs_atm_alpha: DO saturation atmospheric correction coefficient
+ """
+ DOX_sat_uncorrected = np.exp(-139.34410 + 1.575701 * 10 ** 5 / TwaterK - 6.642308 * 10 ** 7 / TwaterK ** 2
+ + 1.243800 * 10 ** 10 / TwaterK - 8.621949 * 10 ** 11 / TwaterK)
+
+ DOX_sat_corrected = DOX_sat_uncorrected * pressure_atm * \
+ (1 - pwv / pressure_atm) * (1 - DOs_atm_alpha * pressure_atm) / \
+ ((1 - pwv) * (1 - DOs_atm_alpha))
+ return DOX_sat_corrected
+
+
+
+def Atm_O2_reaeration(
+ ka_tc: xr.DataArray,
+ DOX_sat: xr.DataArray,
+ DOX: xr.DataArray
+) -> xr.DataArray:
+ """Compute the atmospheric O2 reaeration flux
+
+ Args:
+ ka_tc: Oxygen reaeration rate adjusted for temperature (1/d)
+ DOX_sat: Dissolved oxygen saturation concentration (mg/L)
+ DOX: Dissolved oxygen concentration (mg/L)
+ """
+ return ka_tc * (DOX_sat - DOX)
+
+
+def DOX_ApGrowth(
+ ApGrowth: xr.DataArray,
+ rca: xr.DataArray,
+ roc: xr.DataArray,
+ ApUptakeFr_NH4: xr.DataArray,
+ use_Algae: xr.DataArray
+) -> xr.DataArray:
+ """Compute DOX flux due to algal photosynthesis
+
+ Args:
+ ApGrowth: Algae photosynthesis, calculated in the algae module (ug-Chla/L/d)
+ rca: Ratio of algal carbon to chlorophyll-a (mg-C/ug-Chla)
+ roc: Ratio of oxygen to carbon for carbon oxidation (mg-O2/mg-C)
+ ApUptakeFr_NH4: Fraction of actual algal uptake that is from the ammonia pool, calculated in nitrogen module
+ """
+ da: xr.DataArray = xr.where(use_Algae == True, ApGrowth * rca * roc * (138 / 106 - 32 * ApUptakeFr_NH4 / 106), 0)
+
+ return da
+
+
+def DOX_ApRespiration(
+ ApRespiration: xr.DataArray,
+ rca: xr.DataArray,
+ roc: xr.DataArray,
+ use_Algae: xr.DataArray
+) -> xr.DataArray:
+ """Compute DOX flux due to algal photosynthesis
+
+ Args:
+ ApRespiration: algae respiration, calculated in the algae module
+ rca: Ratio of algal carbon to chlorophyll-a (mg-C/ug-Chla)
+ roc: Ratio of oxygen to carbon for carbon oxidation (mg-O2/mg-C)
+ """
+ da: xr.DataArray = xr.where(use_Algae == True, ApRespiration * rca * roc, 0)
+
+ return da
+
+
+def DOX_Nitrification(
+ KNR: xr.DataArray,
+ DOX: xr.DataArray,
+ ron: xr.DataArray,
+ knit_tc: xr.DataArray,
+ NH4: xr.DataArray,
+ use_NH4: xr.DataArray
+) -> xr.DataArray:
+ """Compute DOX flux due to nitrification of ammonia
+
+ Args:
+ KNR: Oxygen inhibition factor for nitrification (mg-O2/L)
+ DOX: Dissolved oxygen concentration (mg/L)
+ ron: Ratio of oxygen to nitrogen for nitrificiation (mg-O2/mg-N)
+ knit_tc: Nitrification rate of NH4 to NO3 (1/d)
+ NH4: Ammonia/ammonium concentration
+ """
+ da: xr.DataArray = xr.where(use_NH4 == True, (1.0 - np.exp(-KNR * DOX)) * ron * knit_tc * NH4, 0)
+
+ return da
+
+
+def DOX_DOC_oxidation(
+ DOC_DIC_oxidation: xr.DataArray,
+ roc: xr.DataArray,
+ use_DOC: xr.DataArray
+) -> xr.DataArray:
+ """Computes dissolved oxygen flux due to oxidation of dissolved organic carbon
+
+ Args:
+ DOC_DIC_Oxidation: Dissolved organic carbon oxidation, calculated in carbon module (mg/L/d)
+ roc: Ratio of oxygen to carbon for carbon oxidation (mg-O2/mg-C)
+ """
+ da: xr.DataArray = xr.where(use_DOC == True, roc * DOC_DIC_oxidation, 0)
+
+ return da
+
+
+
+def DOX_CBOD_oxidation(
+ DIC_CBOD_oxidation: xr.DataArray,
+ roc: xr.DataArray
+) -> xr.DataArray:
+ """Compute dissolved oxygen flux due to CBOD oxidation
+
+ Args:
+ DIC_CBOD_Oxidation: Carbonaceous biochemical oxygen demand oxidation, calculated in CBOD module (mg/L/d)
+ roc: Ratio of oxygen to carbon for carbon oxidation (mg-O2/mg-C)
+ """
+ return DIC_CBOD_oxidation * roc
+
+
+def DOX_AbGrowth(
+ AbUptakeFr_NH4: xr.DataArray,
+ roc: xr.DataArray,
+ rcb: xr.DataArray,
+ AbGrowth: xr.DataArray,
+ Fb: xr.DataArray,
+ depth: xr.DataArray,
+ use_Balgae: xr.DataArray
+) -> xr.DataArray:
+ """Compute dissolved oxygen flux due to benthic algae growth
+
+ Args:
+ AbUptakeFr_NH4: Fraction of actual benthic algal uptake that is from the ammonia pool, calculated in nitrogen module
+ roc: Ratio of oxygen to carbon for carbon oxidation (mg-O2/mg-C)
+ rcb: Benthic algae carbon to dry weight ratio (mg-C/mg-D)
+ AbGrowth: Benthic algae photosynthesis, calculated in benthic algae module (mg/L/d)
+ Fb: Fraction of bottom area available for benthic algae growth
+ depth: Water depth (m)
+ use_Balgae: Option to consider benthic algae in the DOX budget
+ """
+ da: xr.DataArray = xr.where(use_Balgae == True, (138 / 106 - 32 / 106 * AbUptakeFr_NH4) * roc * rcb * AbGrowth * Fb / depth, 0)
+
+ return da
+
+
+def DOX_AbRespiration(
+ roc: xr.DataArray,
+ rcb: xr.DataArray,
+ AbRespiration: xr.DataArray,
+ Fb: xr.DataArray,
+ depth: xr.DataArray,
+ use_Balgae: xr.DataArray
+) -> xr.DataArray:
+ """Compute dissolved oxygen flux due to benthic algae respiration
+
+ Args:
+ roc: Ratio of oxygen to carbon for carbon oxidation (mg-O2/mg-C)
+ rcb: Benthic algae carbon to dry weight ratio (mg-C/mg-D)
+ AbRespiration: Benthic algae respiration, calculated in the benthic algae module
+ Fb: Fraction of bottom area available for benthic algae growth
+ depth: Water depth (m)
+ use_BAlgae: Option to consider benthic algae in the DOX budget
+ """
+
+ da: xr.DataArray = xr.where(use_Balgae == True, roc * rcb * AbRespiration * Fb / depth, 0)
+
+ return da
+
+
+def DOX_SOD(
+ depth: xr.DataArray,
+ SOD_tc: xr.DataArray
+) -> xr.DataArray:
+ """Compute dissolved oxygen flux due to sediment oxygen demand
+
+ Args:
+ depth: Water depth (m)
+ SOD_tc: Sediment oxygen demand not considering the SedFlux budget (mg-O2/m2)
+ """
+
+ return SOD_tc / depth
+
+
+def dDOXdt(
+ Atm_O2_reaeration: xr.DataArray,
+ DOX_ApGrowth: xr.DataArray,
+ DOX_ApRespiration: xr.DataArray,
+ DOX_Nitrification: xr.DataArray,
+ DOX_DOC_oxidation: xr.DataArray,
+ DOX_CBOD_oxidation: xr.DataArray,
+ DOX_AbGrowth: xr.DataArray,
+ DOX_AbRespiration: xr.DataArray,
+ DOX_SOD: xr.DataArray
+) -> xr.DataArray:
+ """Compute change in dissolved oxygen concentration for one timestep
+
+ Args:
+ Atm_O2_reaeration: DOX concentration change due to atmospheric O2 reaeration (mg/L/d)
+ DOX_ApGrowth: DOX concentration change due to algal photosynthesis (mg/L/d)
+ DOX_ApRespiration: DOX concentration change due to algal respiration (mg/L/d)
+ DOX_Nitrification: DOX concentration change due to nitrification (mg/L/d)
+ DOX_DOC_oxidation: DOX concentration change due to DOC oxidation (mg/L/d)
+ DOX_CBOD_oxidation: DOX concentration change due to CBOD oxidation (mg/L/d)
+ DOX_AbGrowth: DOX concentration change due to benthic algae photosynthesis (mg/L/d)
+ DOX_AbRespiration: DOX concentration change due to benthic algae respiration (mg/L/d)
+ DOX_SOD: DOX concentration change due to sediment oxygen demand (mg/L/d)
+ """
+ return Atm_O2_reaeration + DOX_ApGrowth - DOX_ApRespiration - DOX_Nitrification - DOX_DOC_oxidation - DOX_CBOD_oxidation + DOX_AbGrowth - DOX_AbRespiration - DOX_SOD
+
+
+
+def DOX(
+ DOX: xr.DataArray,
+ dDOXdt: xr.DataArray,
+ timestep: xr.DataArray
+) -> xr.DataArray:
+ """Computes updated dissolved oxygen concentration
+
+ Args:
+ DOX: Dissolved oxygen concentration from previous timestep
+ dDOXdt: Change in dissolved oxygen concentration over timestep
+ timestep: Current iteration timestep (d)
+ """
+ return DOX + dDOXdt * timestep
+
+######################################### From pathogen
+
+
+
+def kdx_tc(
+ TwaterC : xr.DataArray,
+ kdx_20: xr.DataArray
+) -> xr.DataArray :
+
+ """Calculate kdx_tc: pathogen death rate (1/d).
+
+ Args:
+ TwaterC: Water temperature (C)
+ kdx_20: Pathogen death rate at 20 degree (1/d)
+ """
+
+ return arrhenius_correction(TwaterC, kdx_20, 1.07)
+
+
+def PathogenDeath(
+ kdx_tc : xr.DataArray,
+ PX: xr.DataArray
+) -> xr.DataArray :
+
+ """Calculate PathogenDeath: pathogen natural death (cfu/100mL/d).
+
+ Args:
+ kdx_tc: pathogen death rate with temperature correction (1/d),
+ PX: pathogen concentration (cfu/100mL)
+
+ """
+ return kdx_tc * PX
+
+def PathogenDecay(
+ apx: xr.DataArray,
+ q_solar: xr.DataArray,
+ L: xr.DataArray,
+ depth: xr.DataArray,
+ PX: xr.DataArray
+) -> xr.DataArray :
+
+ """Calculate PathogenDecay: pathogen death due to light (cfu/100mL/d).
+
+ Args:
+ apx: light efficiency factor for pathogen decay,
+ q_solar: Incident short-wave solar radiation (W/m2),
+ L: lambda (1/m),
+ depth: water depth (m),
+ PX: Pathogen concentration (cfu/100mL)
+
+ """
+ return apx * q_solar / (L * depth) * (1 - np.exp(-L * depth)) * PX
+
+
+def PathogenSettling(
+ vx: xr.DataArray,
+ depth: xr.DataArray,
+ PX: xr.DataArray
+) -> xr.DataArray :
+
+ """Calculate PathogenSettling: pathogen settling (cfu/100mL/d).
+
+ Args:
+ vx: pathogen net settling velocity (m)
+ depth: water depth (m),
+ PX: Pathogen concentration (cfu/100mL)
+ """
+ return vx/depth*PX
+
+
+def dPXdt(
+ PathogenDeath: xr.DataArray,
+ PathogenDecay: xr.DataArray,
+ PathogenSettling: xr.DataArray
+
+) -> xr.DataArray :
+
+ """Calculate dPXdt: change in pathogen concentration (cfu/100mL/d).
+
+ Args:
+ PathogenSettling: pathogen settling (cfu/100mL/d)
+ PathogenDecay: pathogen death due to light (cfu/100mL/d)
+ PathogenDeath: pathogen natural death (cfu/100mL/d)
+
+ """
+ return -PathogenDeath - PathogenDecay - PathogenSettling
+
+
+def PX(
+ PX:xr.DataArray,
+ dPXdt: xr.DataArray,
+ timestep: xr.DataArray
+
+) -> xr.DataArray :
+
+ """Calculate PX: New pathogen concentration (cfu/100mL).
+
+ Args:
+ dPXdt: change in pathogen concentration (cfu/100mL/d)
+ PX: Pathogen concentration (cfu/100mL)
+ timestep: Current iteration timestep (d)
+ """
+ return PX + timestep * dPXdt
+
+
+##################################### From alkalinity
+
+def Alk_denitrification(
+ DOX: xr.DataArray,
+ NO3: xr.DataArray,
+ kdnit_tc: xr.DataArray,
+ KsOxdn: xr.DataArray,
+ r_alkden: xr.DataArray,
+ use_NO3: xr.DataArray,
+ use_DOX: xr.DataArray
+) -> xr.DataArray:
+ """Calculate the alkalinity concentration change due to denitrification of nitrate
+
+ Args:
+ DOX: Concentration of dissolved oxygen (mg/L)
+ NO3: Concentration of nitrate (mg/L)
+ kdnit_tc: Denitrification rate corrected for temperature (1/d)
+ KsOxdn: Half-saturation oxygen inhibition constant for denitrification (mg-O2/L)
+ ralkden: Ratio translating NO3 denitrification into Alk (eq/mg-N)
+ use_NO3: Option to use nitrate
+ use_DOX: Option to use dissolved oxygen
+ """
+
+ da: np.ndarray = np.select(
+ condlist = [
+ (use_NO3) & (use_DOX),
+ use_NO3
+ ],
+
+ choicelist = [
+ r_alkden * (1.0 - (DOX / (DOX + KsOxdn))) * kdnit_tc * NO3,
+ r_alkden * kdnit_tc * NO3
+ ],
+
+ default = 0
+ )
+
+ return da
+
+
+def Alk_nitrification(
+ DOX: xr.DataArray,
+ NH4: xr.DataArray,
+ knit_tc: xr.DataArray,
+ KNR: xr.DataArray,
+ r_alkn: xr.DataArray,
+ use_NH4: xr.DataArray,
+ use_DOX: xr.DataArray
+) -> xr.DataArray:
+ """Calculate the alkalinity concentration change due to nitrification of ammonium
+
+ Args:
+ DOX: Concentration of dissolved oxygen (mg/L)
+ NH4: Concentration of ammonia/ammonium (mg/L)
+ knit_tc: Nitrification rate corrected for temperature (1/d)
+ KNR: Oxygen inhibition factor for nitrification (mg-O2/L)
+ r_alkn: Ratio translating NH4 nitrification into Alk (eq/mg-N)
+ use_NH4: Option to use ammonium
+ use_DOX: Option to use dissolved oxygen
+ """
+
+ da: np.ndarray = np.select(
+ condlist = [
+ (use_NH4) & (use_DOX),
+ use_NH4
+ ],
+
+ choicelist = [
+ r_alkn * (1 - np.exp(-KNR * DOX)) * knit_tc * NH4,
+ knit_tc * NH4
+ ],
+
+ default = 0
+ )
+
+ return da
+
+
+def Alk_algal_growth(
+ ApGrowth: xr.DataArray,
+ r_alkaa: xr.DataArray,
+ r_alkan: xr.DataArray,
+ ApUptakeFr_NH4 : xr.DataArray,
+ use_Algae: xr.DataArray
+) -> xr.DataArray:
+ """Calculate the alkalinity concentration change due to algal growth
+
+ Args:
+ ApGrowth: Algal photosynthesis calculated in algae module (ug-Chla/L/d)
+ r_alkaa: Ratio translating algal growth into Alk if NH4 is the N source (eq/ug-Chla)
+ r_alkan: Ratio translating algal growth into Alk if NO3 is the N source (eq/ug-Chla)
+ ApUptakeFr_NH4 : Preference fraction of algal N uptake from NH4
+ use_Algae: Option to use algae
+ """
+ da: xr.DataArray = xr.where(use_Algae == True, (r_alkaa * ApUptakeFr_NH4 - r_alkan * (1 - ApUptakeFr_NH4 )) * ApGrowth, 0)
+
+ return da
+
+
+def Alk_algal_respiration(
+ ApRespiration: xr.DataArray,
+ r_alkaa: xr.DataArray,
+ use_Algae: xr.DataArray
+) -> xr.DataArray:
+ """Calculate the alkalinity concentration change due to algal respiration
+
+ Args:
+ ApRespiration: Algae respiration calculated in algae module (ug-Chla/L/d)
+ r_alkaa: Ratio translating algal growth into Alk if NH4 is the N source (eq/ug-Chla)
+ use_Algae: Option to use algae
+ """
+ da: xr.DataArray = xr.where(use_Algae == True, ApRespiration * r_alkaa, 0)
+
+ return da
+
+
+def Alk_benthic_algae_growth(
+ AbGrowth: xr.DataArray,
+ depth: xr.DataArray,
+ r_alkba: xr.DataArray,
+ r_alkbn: xr.DataArray,
+ AbUptakeFr_NH4 : xr.DataArray,
+ Fb: xr.DataArray,
+ use_Balgae: xr.DataArray
+) -> xr.DataArray:
+ """Calculate the alkalinity concentration change due to algal growth
+
+ Args:
+ ApGrowth: Algal photosynthesis calculated in algae module (ug-Chla/L/d)
+ depth: Depth of water (m)
+ r_alkaa: Ratio translating algal growth into Alk if NH4 is the N source (eq/ug-Chla)
+ r_alkan: Ratio translating algal growth into Alk if NO3 is the N source (eq/ug-Chla)
+ AbUptakeFr_NH4 : Preference fraction of benthic algae N uptake from NH4
+ Fb: Fraction of bottom area available for benthic algae growth
+ use_Balgae: Option to use benthic algae
+ """
+ da: xr.DataArray = xr.where(use_Balgae == True, (1 / depth) *(r_alkba * AbUptakeFr_NH4 - r_alkbn * (1 - AbUptakeFr_NH4 )) * AbGrowth * Fb, 0)
+
+ return da
+
+
+def Alk_benthic_algae_respiration(
+ AbRespiration: xr.DataArray,
+ depth: xr.DataArray,
+ r_alkba: xr.DataArray,
+ Fb: xr.DataArray,
+ use_Balgae: xr.DataArray
+) -> xr.DataArray:
+ """Calculate the alkalinity concentration change due to algal respiration
+
+ Args:
+ ApRespiration: Algae respiration calculated in algae module (ug-Chla/L/d)
+ r_alkaa: Ratio translating algal growth into Alk if NH4 is the N source (eq/ug-Chla)
+ Fb: Fraction of bottom area available for benthic algae growth
+ use_Balgae: Option to use betnhic algae
+ """
+ da: xr.DataArray = xr.where(use_Balgae == True, (1 / depth) * r_alkba * AbRespiration * Fb, 0)
+
+ return da
+
+
+
+def dAlkdt(
+ Alk_denitrification: xr.DataArray,
+ Alk_nitrification: xr.DataArray,
+ Alk_algal_growth: xr.DataArray,
+ Alk_algal_respiration: xr.DataArray,
+ Alk_benthic_algae_growth: xr.DataArray,
+ Alk_benthic_algae_respiration: xr.DataArray
+) -> xr.DataArray:
+ """Computes the change in alkalinity for timestep
+
+ Args:
+ Alk_denitrification: xr.DataArray,
+ Alk_nitrification: xr.DataArray,
+ Alk_algal_growth: xr.DataArray,
+ Alk_algal_respiration: xr.DataArray,
+ Alk_benthic_algae_growth: xr.DataArray,
+ Alk_benthic_algae_respiration: xr.DataArray
+ """
+ return Alk_denitrification - Alk_nitrification - Alk_algal_growth + Alk_algal_respiration - Alk_benthic_algae_growth + Alk_benthic_algae_respiration
+
+
+
+def Alk(
+ Alk: xr.DataArray,
+ dAlkdt: xr.DataArray,
+ timestep: xr.DataArray,
+) -> xr.DataArray:
+ """Computes the alkalinity concentration at the next timestep
+
+ Args:
+ Alk: Concentration of alkalinity from previous timestep (mg/L)
+ dAlkdt: Change in concentration of alkalinity for current timestep (mg/L/d)
+ timestep: Current iteration timestep (d)
+ """
+ return Alk + dAlkdt * timestep
+
+##################################### From N2
+
+
+def KHN2_tc(
+ TwaterK : xr.DataArray,
+) -> xr.DataArray :
+
+ """Calculate Henry's law constant (mol/L/atm)
+
+ Constant values found on NIST
+
+ Args:
+ TwaterK: water temperature kelvin (K)
+ Henry's law constant for solubility in water at 298.15K: 0.00065 (mol/(kg*bar))
+ Temperature dependence constant: 1300 (K)
+ Reference temperature: 298.15 (K)
+ """
+
+ 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
+) -> 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)
+ """
+
+ N2sat = 2.8E+4 * KHN2_tc * 0.79 * (pressure_atm - P_wv)
+ N2sat = xr.where(N2sat < 0.0,0.0,N2sat) #Trap saturation concentration to ensure never negative
+
+ return N2sat
+
+
+def dN2dt(
+ ka_tc : xr.DataArray,
+ N2sat : xr.DataArray,
+ N2: xr.DataArray,
+) -> xr.DataArray:
+
+ """Calculate change in N2 air concentration (mg-N/L/d)
+
+ Args:
+ ka_tc: Oxygen re-aeration rate (1/d)
+ N2sat: N2 at saturation f(Twater and atm pressure) (mg-N/L)
+ N2: Nitrogen concentration air (mg-N/L)
+ """
+
+ return 1.034 * ka_tc * (N2sat - N2)
+
+
+def N2(
+ N2: xr.DataArray,
+ dN2dt : xr.DataArray,
+ timestep: xr.DataArray
+) -> xr.DataArray:
+
+ """Calculate change in N2 air concentration (mg-N/L/d)
+
+ Args:
+ N2: Nitrogen concentration air (mg-N/L)
+ dN2dt: Change in nitrogen concentration air
+ timestep: Current iteration timestep (d)
+ """
+
+ return N2 + dN2dt * timestep
+
+def TDG(
+ N2: xr.DataArray,
+ N2sat : xr.DataArray,
+ DOX: xr.DataArray,
+ DOX_sat: xr.DataArray,
+ use_DOX: bool,
+) -> xr.DataArray:
+
+ """Calculate total dissolved gas (%)
+
+ Args:
+ N2: Nitrogen concentration air (mg-N/L)
+ N2sat: N2 at saturation f(Twater and atm pressure) (mg-N/L)
+ DOX: Dissolved oxygen concentration (mg-O2/L)
+ DOX_sat: O2 at saturation f(Twater and atm pressure) (mg-O2/L)
+ use_DOX: true/false use dissolved oxygen module (true/false)
+ """
+
+ return xr.where(use_DOX,(79.0 * N2 / N2sat) + (21.0 * DOX / DOX_sat), N2/N2sat)
\ No newline at end of file
diff --git a/src/clearwater_modules/nsm1/state_variables.py b/src/clearwater_modules/nsm1/state_variables.py
index b986abd..2cb76e0 100644
--- a/src/clearwater_modules/nsm1/state_variables.py
+++ b/src/clearwater_modules/nsm1/state_variables.py
@@ -1,17 +1,6 @@
from clearwater_modules import base
from clearwater_modules.nsm1.model import NutrientBudget
-import clearwater_modules.nsm1.algae.processes as algae_processes
-import clearwater_modules.nsm1.alkalinity.processes as alkalinity_processes
-import clearwater_modules.nsm1.balgae.processes as balgae_processes
-import clearwater_modules.nsm1.carbon.processes as carbon_processes
-import clearwater_modules.nsm1.CBOD.processes as CBOD_processes
-import clearwater_modules.nsm1.DOX.processes as DOX_processes
-import clearwater_modules.nsm1.n2.processes as n2_processes
-import clearwater_modules.nsm1.nitrogen.processes as nitrogen_processes
-import clearwater_modules.nsm1.pathogens.processes as pathogens_processes
-import clearwater_modules.nsm1.phosphorus.processes as phosphorus_processes
-import clearwater_modules.nsm1.POM.processes as POM_processes
-import clearwater_modules.shared.processes as shared_processes
+import clearwater_modules.nsm1.processes as processes
@base.register_variable(models=NutrientBudget)
@@ -23,15 +12,13 @@ class Variable(base.Variable):
def mock_equation(water_temp_c: float) -> float:
return water_temp_c ** 2
-# TODO: import state variables from CWR such as surface_area volume, and timestep, as well as kah inputs
-
Variable(
name='Ap',
long_name='Algae Concentration',
units='ug-Chla/L',
description='Algal Concentration',
use='state',
- process=algae_processes.Ap
+ process=processes.Ap
)
Variable(
@@ -40,7 +27,7 @@ def mock_equation(water_temp_c: float) -> float:
units='g-D/m^2',
description='Benthic Algae Concentration',
use='state',
- process=balgae_processes.Ab
+ process=processes.Ab
)
Variable(
@@ -49,7 +36,7 @@ def mock_equation(water_temp_c: float) -> float:
units='mg-N/L',
description='Ammonium Concentration',
use='state',
- process=nitrogen_processes.NH4
+ process=processes.NH4
)
Variable(
@@ -58,7 +45,7 @@ def mock_equation(water_temp_c: float) -> float:
units='mg-N/L',
description='Nitrate Concentration',
use='state',
- process=nitrogen_processes.NO3
+ process=processes.NO3
)
Variable(
@@ -67,7 +54,7 @@ def mock_equation(water_temp_c: float) -> float:
units='mg-N/L',
description='Organic Nitrogen Concentration',
use='state',
- process=nitrogen_processes.OrgN
+ process=processes.OrgN
)
Variable(
@@ -76,7 +63,7 @@ def mock_equation(water_temp_c: float) -> float:
units='mg-N/L',
description='Nitrogen concentration air',
use='state',
- process=n2_processes.N2
+ process=processes.N2
)
Variable(
@@ -85,7 +72,7 @@ def mock_equation(water_temp_c: float) -> float:
units='mg-P/L',
description='Total Inorganic Phosphorus Concentration',
use='state',
- process=phosphorus_processes.TIP
+ process=processes.TIP
)
Variable(
@@ -94,7 +81,7 @@ def mock_equation(water_temp_c: float) -> float:
units='mg-P/L',
description='Total Organic Phosphorus Concentration',
use='state',
- process=phosphorus_processes.OrgP
+ process=processes.OrgP
)
Variable(
@@ -103,7 +90,7 @@ def mock_equation(water_temp_c: float) -> float:
units='mg-C/L',
description='Particulate Organic Carbon Concentration',
use='state',
- process=carbon_processes.POC
+ process=processes.POC
)
Variable(
@@ -112,7 +99,7 @@ def mock_equation(water_temp_c: float) -> float:
units='mg-C/L',
description='Dissolved Organic Carbon Concentration',
use='state',
- process=carbon_processes.DOC
+ process=processes.DOC
)
Variable(
@@ -121,7 +108,7 @@ def mock_equation(water_temp_c: float) -> float:
units='mg-C/L',
description='Dissolved Inorganic Carbon Concentration',
use='state',
- process=carbon_processes.DIC
+ process=processes.DIC
)
Variable(
@@ -130,16 +117,7 @@ def mock_equation(water_temp_c: float) -> float:
units='mg-D/L',
description='Particulate Organic Matter Concentration',
use='state',
- process=POM_processes.POM
-)
-
-Variable(
- name='POM2',
- long_name='Sediment Particulate Organic Matter',
- units='mg-D/L',
- description='Sediment Particulate Organic Matter Concentration',
- use='state',
- process=mock_equation#TODO might be Sedflux
+ process=processes.POM
)
Variable(
@@ -148,7 +126,7 @@ def mock_equation(water_temp_c: float) -> float:
units='mg-O2/L',
description='Carbonaceous Biochemical Oxygen Demand Concentration',
use='state',
- process=CBOD_processes.CBOD
+ process=processes.CBOD
)
Variable(
@@ -157,7 +135,7 @@ def mock_equation(water_temp_c: float) -> float:
units='mg-O2/L',
description='Dissolved Oxygen',
use='state',
- process=DOX_processes.DOX
+ process=processes.DOX
)
Variable(
@@ -166,7 +144,7 @@ def mock_equation(water_temp_c: float) -> float:
units='cfu/100mL',
description='Pathogen concentration',
use='state',
- process=pathogens_processes.PX
+ process=processes.PX
)
Variable(
@@ -175,5 +153,5 @@ def mock_equation(water_temp_c: float) -> float:
units='mg-CaCO3/L',
description='Alkalinity concentration',
use='state',
- process=alkalinity_processes.Alk
+ process=processes.Alk
)
\ No newline at end of file
diff --git a/src/clearwater_modules/nsm1/static_variables.py b/src/clearwater_modules/nsm1/static_variables.py
new file mode 100644
index 0000000..0d0cabc
--- /dev/null
+++ b/src/clearwater_modules/nsm1/static_variables.py
@@ -0,0 +1,944 @@
+import clearwater_modules.base as base
+from clearwater_modules.nsm1.model import NutrientBudget
+
+
+@base.register_variable(models=NutrientBudget)
+class Variable(base.Variable):
+ ...
+
+############################################ From static_variables_global
+Variable(
+ name='vson',
+ long_name='Organic N settling velocity',
+ units='m/d',
+ description='Organic N settling velocity',
+ use='static',
+)
+
+Variable(
+ name='vsoc',
+ long_name='POC settling velocity',
+ units='m/d',
+ description='POC settling velocity',
+ use='static'
+)
+
+Variable(
+ name='vsop',
+ long_name='Organic phosphorus settling velocity',
+ units='m/d',
+ description='Organic phosphorus settling velocity',
+ use='static'
+)
+
+Variable(
+ name='vs',
+ long_name='Sediment settling velocity',
+ units='m/d',
+ description='Sediment settling velocity',
+ use='static'
+)
+
+Variable(
+ name='SOD_20',
+ long_name='Sediment oxygen demand at 20 degrees C',
+ units='g-O2/m/d',
+ description='Sediment oxygen demand at 20 degrees C',
+ use='static'
+)
+
+Variable(
+ name='SOD_theta',
+ long_name='Arrhenius coefficient for sediment oxygen demand',
+ units='unitless',
+ description='Arrhenius coefficient for sediment oxygen demand',
+ use='static'
+)
+
+Variable(
+ name='fcom',
+ long_name='Fraction of carbon in organic matter',
+ units='mg-C/mg-D',
+ description='Fraction of carbon in organic matter',
+ use='static'
+)
+
+Variable(
+ name='vb',
+ long_name='Burial velocity',
+ units='m/d',
+ description='Rate at which constituents are buried on the bottom',
+ use='static'
+)
+
+Variable(
+ name='kaw_20_user',
+ long_name='Wind oxygen reaeration velocity at 20C',
+ units='m/d',
+ description='Wind oxygen reaeration velocity at 20C',
+ use='static'
+)
+
+Variable(
+ name='kah_20_user',
+ long_name='Hydraulic oxygen reaeration rate at 20C',
+ units='1/d',
+ description='Hydraulic oxygen reaeration rate at 20C',
+ use='static'
+)
+
+Variable(
+ name='hydraulic_reaeration_option',
+ long_name='Option for chosing the method by which O2 reaeration rate is calculated',
+ units='unitless',
+ description='Selects method for computing O2 reaeration rate',
+ use='static'
+)
+
+Variable(
+ name='wind_reaeration_option',
+ long_name='Option for chosing the method by which wind reaeration is calculated',
+ units='unitless',
+ description='Selects method for computing O2 reaeration due to wind',
+ use='static'
+)
+
+Variable(
+ name='use_NH4',
+ long_name='Use ammonium module',
+ units='unitless',
+ description='True/False use ammonium module',
+ use='static',
+)
+
+Variable(
+ name='use_NO3',
+ long_name='Use nitrate module',
+ units='unitless',
+ description='True/False use nitrate module',
+ use='static',
+)
+
+Variable(
+ name='use_OrgN',
+ long_name='Use organic nitrogen module',
+ units='unitless',
+ description='True/False use organic nitrogen module',
+ use='static',
+)
+
+Variable(
+ name='use_SedFlux',
+ long_name='Use sediment flux module',
+ units='unitless',
+ description='True/False use sediment flux module',
+ use='static',
+)
+
+Variable(
+ name='use_DOX',
+ long_name='Use dissolved oxygen module',
+ units='unitless',
+ description='True/False use dissolved oxygen module',
+ use='static',
+)
+
+Variable(
+ name='use_Algae',
+ long_name='Use algae module',
+ units='unitless',
+ description='True/False use algae module',
+ use='static',
+)
+
+Variable(
+ name='use_Balgae',
+ long_name='Use benthic algae module',
+ units='unitless',
+ description='True/False use benthic algae module',
+ use='static',
+)
+
+Variable(
+ name='use_TIP',
+ long_name='Use total inorganic phosphorus module',
+ units='unitless',
+ description='True/False use total inorganic phosphorus module',
+ use='static',
+)
+
+Variable(
+ name='use_OrgP',
+ long_name='Use total organic phosphorus module',
+ units='unitless',
+ description='True/False use total organic phosphorus module',
+ use='static',
+)
+
+Variable(
+ name='use_POC',
+ long_name='Use particulate organic carbon module',
+ units='unitless',
+ description='True/False use particulate organic carbon module',
+ use='static',
+)
+
+Variable(
+ name='use_DOC',
+ long_name='Use dissolved organic carbon module',
+ units='unitless',
+ description='True/False use dissolved organic carbon module',
+ use='static',
+)
+
+Variable(
+ name='use_DIC',
+ long_name='Use dissolved inorganic carbon module',
+ units='unitless',
+ description='True/False use dissolved inorganic carbon module',
+ use='static',
+)
+
+Variable(
+ name='use_N2',
+ long_name='Use dissolved N2 module',
+ units='unitless',
+ description='True/False use N2 module',
+ use='static',
+)
+
+Variable(
+ name='use_Pathogen',
+ long_name='Use pathogen module',
+ units='unitless',
+ description='True/False use pathogen module',
+ use='static',
+)
+
+Variable(
+ name='use_Alk',
+ long_name='Use alkalinity module',
+ units='unitless',
+ description='True/False use alkalinity module',
+ use='static',
+)
+
+Variable(
+ name='use_POM',
+ long_name='Use particulate organic matter module',
+ units='unitless',
+ description='True/False use particulate organic matter module',
+ use='static',
+)
+
+Variable(
+ name='timestep',
+ long_name='timestep',
+ units='d',
+ description='calculation timestep',
+ use='static',
+)
+
+Variable(
+ name='depth',
+ long_name='Depth of water in cell',
+ units='m',
+ description='Depth of water in cell',
+ use='static',
+)
+
+Variable(
+ name='TwaterC',
+ long_name='Water temperature in celsius',
+ units='degrees C',
+ description='Water temperature in celsius',
+ use='static'
+)
+
+Variable(
+ name='theta',
+ long_name='Water temperature theta adjustment factor',
+ units='unitless',
+ description='Water temperature theta adjustment factor',
+ use='static'
+)
+
+Variable(
+ name='velocity',
+ long_name='velocity',
+ units='m/s',
+ description='Average water velocity in cell',
+ use='static',
+)
+
+Variable(
+ name='flow',
+ long_name='flow',
+ units='m3/s',
+ description='Average flow rate in cell',
+ use='static',
+)
+
+Variable(
+ name='topwidth',
+ long_name='topwidth',
+ units='m',
+ description='Average topwidth of cell',
+ use='static',
+)
+
+#TODO find units for slope
+Variable(
+ name='slope',
+ long_name='slope',
+ units='TODO',
+ description='Average slope of bottom surface',
+ use='static',
+)
+
+Variable(
+ name='shear_velocity',
+ long_name='shear_velocity',
+ units='TODO',
+ description='Average shear velocity on bottom surface',
+ use='static',
+)
+
+Variable(
+ name='pressure_atm',
+ long_name='pressure_atm',
+ units='TODO',
+ description='atmospheric pressure in atm',
+ use='static',
+)
+
+Variable(
+ name='wind_speed',
+ long_name='Wind speed at 10 meters above the water surface',
+ units='m/s',
+ description='Wind speed at 10 meters above the water surface',
+ use='static',
+)
+
+Variable(
+ name='q_solar',
+ long_name='Incident short-wave solar radiation',
+ units='W/m2',
+ description='Incident short-wave solar radiation',
+ use='static',
+)
+
+#TODO figure out what Solid is
+Variable(
+ name='Solid',
+ long_name='Solid reaeration option',
+ units='Unknown',
+ description='Solid',
+ use='static',
+)
+
+############################################ From algae
+Variable(
+ name='AWd',
+ long_name='Algal Dry Weight',
+ units='mg',
+ description='Algal Dry Weight',
+ use='static',
+)
+
+Variable(
+ name='AWc',
+ long_name='Carbon Weight',
+ units='mg',
+ description='Carbon Weight',
+ use='static',
+)
+
+Variable(
+ name='AWn',
+ long_name='Nitrogen Weight',
+ units='mg',
+ description='Nitrogen Weight',
+ use='static',
+)
+
+Variable(
+ name='AWp',
+ long_name='Phosphorus Weight',
+ units='mg',
+ description='Phosphorus Weight',
+ use='static',
+)
+
+Variable(
+ name='AWa',
+ long_name='Algal Chlorophyll',
+ units='ug Chla',
+ description='Algal Chlorophyll',
+ use='static',
+)
+
+Variable(
+ name='KL',
+ long_name='Light Limiting Constant for Algal Growth',
+ units='W/m^2',
+ description='Light Limiting Constant for Algal Growth',
+ use='static',
+)
+
+Variable(
+ name='KsN',
+ long_name='Half-Saturation N Limiting Constant for Algal Growth',
+ units='mg-N/L',
+ description='Half-Saturation N Limiting Constant for Algal Growth',
+ use='static',
+)
+
+Variable(
+ name='KsP',
+ long_name='Half-Saturation P Limiting Constant for Algal Growth',
+ units='mg-P/L',
+ description='Half-Saturation P Limiting Constant for Algal Growth',
+ use='static',
+)
+
+Variable(
+ name='mu_max_20',
+ long_name='Max Algae Growth',
+ units='1/d',
+ description='Max Algae Growth at 20C',
+ use='static',
+)
+
+Variable(
+ name='kdp_20',
+ long_name='Algal Mortality Rate',
+ units='1/d',
+ description='Algal Mortality Rate at 20C',
+ use='static',
+)
+
+Variable(
+ name='krp_20',
+ long_name='Algal Respiration Rate',
+ units='1/d',
+ description='Algal Respiration Rate at 20C',
+ use='static',
+)
+
+Variable(
+ name='vsap',
+ long_name='Algal Setting Velocity',
+ units='m/d',
+ description='Algal Setting Velocity',
+ use='static',
+)
+
+Variable(
+ name='growth_rate_option',
+ long_name='Growth Rate Option',
+ units='1/d',
+ description='Algal growth rate option 1) multiplicative, 2) Limiting Nutrient, 3) Harmonic Mean Option',
+ use='static',
+)
+
+Variable(
+ name='light_limitation_option',
+ long_name='Light Limitation Option',
+ units='1/d',
+ description='Algal light limitation 1) half-saturation, 2) Smith model, 3) Steele model',
+ use='static',
+)
+
+Variable(
+ name='lambda0',
+ long_name='lambda0',
+ units='1/m',
+ description='background portion',
+ use='static',
+)
+
+Variable(
+ name='lambda1',
+ long_name='lambda1',
+ units='1/m/(ug Chla/L)',
+ description='linear self shading',
+ use='static',
+)
+
+Variable(
+ name='lambda2',
+ long_name='lambda2',
+ units='unitless',
+ description='nonlinear',
+ use='static',
+)
+
+Variable(
+ name='lambdas',
+ long_name='lambdas',
+ units='L/mg/m',
+ description='ISS portion',
+ use='static',
+)
+
+Variable(
+ name='lambdam',
+ long_name='lambdam',
+ units='L/mg/m',
+ description='POM portion',
+ use='static',
+)
+
+Variable(
+ name='Fr_PAR',
+ long_name='fraction PAR',
+ units='unitless',
+ description='fraction of solar radiation within the PAR of the spectrum',
+ use='static',
+)
+
+############################################ From benthic algae
+Variable(
+ name='Fw',
+ long_name='Fraction of benthic algae mortality into water column',
+ units='unitless',
+ description='Fraction of benthic algae mortality into water column',
+ use='static',
+)
+
+Variable(
+ name='Fb',
+ long_name='Fraction of bottom area available for benthic algae',
+ units='unitless',
+ description='Fraction of bottom area available for benthic algae',
+ use='static',
+)
+
+Variable(
+ name='BWd',
+ long_name='Benthic algae dry weight',
+ units='unitless',
+ description='Benthic algae dry weight',
+ use='static',
+)
+
+Variable(
+ name='BWc',
+ long_name='Benthic algae carbon',
+ units='unitless',
+ description='Benthic algae carbon',
+ use='static',
+)
+
+Variable(
+ name='BWn',
+ long_name='Benthic algae nitrogen',
+ units='unitless',
+ description='Benthic algae nitrogen',
+ use='static',
+)
+
+Variable(
+ name='BWp',
+ long_name='Benthic algae phosphorus',
+ units='unitless',
+ description='Benthic algae phosphorus',
+ use='static',
+)
+
+Variable(
+ name='BWa',
+ long_name='Benthic algae Chla',
+ units='unitless',
+ description='Benthic algae Chla',
+ use='static',
+)
+
+Variable(
+ name='KLb',
+ long_name='Light limiting constant for benthic algae growth',
+ units='W/m^2',
+ description='Light limiting constant for benthic algae growth',
+ use='static',
+)
+
+Variable(
+ name='KsNb',
+ long_name='Half-Saturation N limiting constant for Benthic algae',
+ units='mg-N/L',
+ description='Half-Saturation N limiting constant for Benthic algae',
+ use='static',
+)
+
+Variable(
+ name='KsPb',
+ long_name='Half-Saturation P limiting constant for Benthic algae',
+ units='mg-P/L',
+ description='Half-Saturation P limiting constant for Benthic algae',
+ use='static',
+)
+
+Variable(
+ name='Ksb',
+ long_name='Half-Saturation density constant for benthic algae growth',
+ units='g-D/m^2',
+ description='Half-Saturation density constant for benthic algae growth',
+ use='static',
+)
+
+Variable(
+ name='mub_max_20',
+ long_name='Maximum benthic algal growth rate',
+ units='1/d',
+ description='maximum benthic algal growth rate',
+ use='static',
+)
+
+Variable(
+ name='krb_20',
+ long_name='Benthic algal respiration rate',
+ units='1/d',
+ description='Benthic algal respiration rate',
+ use='static',
+)
+
+Variable(
+ name='kdb_20',
+ long_name='Benthic algal mortality rate',
+ units='1/d',
+ description='Benthic algal mortality rate',
+ use='static',
+)
+
+Variable(
+ name='b_growth_rate_option',
+ long_name='Benthic Algal growth rate options',
+ units='unitless',
+ description='Benthic Algal growth rate with two options: 1) Multiplicative, 2) Limiting Nutritent',
+ use='static',
+)
+
+Variable(
+ name='b_light_limitation_option',
+ long_name='Benthic Algal light limitation rate options',
+ units='unitless',
+ description='Benthic Algal light limitation rate with three options: 1) Half-saturation formulation, 2) Smiths Model, 3) Steeles Model',
+ use='static',
+)
+
+Variable(
+ name='Fb',
+ long_name='Fraction of bottom area available for benthic algae growth',
+ units='unitless',
+ description='Fraction of bottom area available for benthic algae growth',
+ use='static'
+)
+
+Variable(
+ name='Fw',
+ long_name='Fraction of benthic algae mortality into water column',
+ units='unitless',
+ description='Fraction of benthic algae mortality into water column',
+ use='static'
+)
+
+############################################ From nitrogen
+Variable(
+ name='KNR',
+ long_name='Oxygen inhabitation factor for nitrification',
+ units='mg-O2/L',
+ description='Oxygen inhabitation factor for nitrification',
+ use='static',
+)
+
+Variable(
+ name='knit_20',
+ long_name='Nitrification Rate Ammonia decay at 20C',
+ units='1/d',
+ description='Nitrification Rate Ammonia NH4 -> NO3 decay at 20C',
+ use='static',
+)
+
+Variable(
+ name='kon_20',
+ long_name='Decay Rate of OrgN to NH4 at 20C',
+ units='1/d',
+ description='Decay Rate of OrgN to NH4 at 20C',
+ use='static',
+)
+
+Variable(
+ name='kdnit_20',
+ long_name='Denitrification rate at 20C',
+ units='1/d',
+ description='Denitrification rate at 20C',
+ use='static',
+)
+
+Variable(
+ name='rnh4_20',
+ long_name='Sediment release rate of NH4 at 20C',
+ units='g-N/m^2/d',
+ description='Sediment release rate of NH4 at 20C',
+ use='static'
+)
+
+Variable(
+ name='vno3_20',
+ long_name='Sediment denitrification velocity at 20C',
+ units='m/d',
+ description='Sediment denitrification velocity at 20C',
+ use='static',
+)
+
+Variable(
+ name='KsOxdn',
+ long_name='Half-saturation oxygen inhibition constant for denitrification',
+ units='mg-O2/L',
+ description='Half-saturation oxygen inhibition constant for denitrification',
+ use='static',
+)
+
+Variable(
+ name='PN',
+ long_name='NH4 preference factor algae',
+ units='unitless',
+ description='NH4 preference factor algae (1=full NH4, 0=full NO3)',
+ use='static',
+)
+
+Variable(
+ name='PNb',
+ long_name='NH4 preference factor benthic algae',
+ units='unitless',
+ description='NH4 preference factor benthic algae (1=full NH4, 0=full NO3)',
+ use='static',
+)
+
+############################################ From phosphorus
+Variable(
+ name='kop_20',
+ long_name='Decay rate of organic P to DIP',
+ units='1/d',
+ description='Decay rate of organic P to DIP',
+ use='static',
+)
+
+Variable(
+ name='rpo4_20',
+ long_name='Benthic sediment release rate of DIP',
+ units='g-P/m^2/d',
+ description='Benthic sediment release rate of DIP',
+ use='static',
+)
+
+Variable(
+ name='kdpo4',
+ long_name='solid partitioning coeff. of PO4',
+ units='L/kg',
+ description='solid partitioning coeff. of PO4',
+ use='static',
+)
+
+############################################ From POM
+Variable(
+ name='kpom_20',
+ long_name='POM dissolution rate at 20C',
+ units='1/d',
+ description='POM dissolution rate at 20C',
+ use='static'
+)
+
+############################################ From CBOD
+Variable(
+ name='kbod_20',
+ long_name='CBOD oxidation rate at 20C',
+ units='1/d',
+ description='CBOD oxidation rate at 20C',
+ use='static'
+)
+
+Variable(
+ name='ksbod_20',
+ long_name='CBOD sedimentation rate at 20C',
+ units='m/d',
+ description='CBOD sedimentation rate at 20C',
+ use='static'
+)
+
+Variable(
+ name='KsOxbod',
+ long_name='Half saturation oxygen attenuation constant for CBOD oxidation',
+ units='mg-O2/L',
+ description='Half saturation oxygen attenuation constant for CBOD oxidation',
+ use='static'
+)
+
+############################################ From Carbon
+Variable(
+ name='f_pocp',
+ long_name='Fraction of algal mortality into POC',
+ units='unitless',
+ description='Fraction of dead algae that converts to particulate organic carbon',
+ use='static'
+)
+
+Variable(
+ name='kdoc_20',
+ long_name='Dissolved organic carbon oxidation rate',
+ units='1/d',
+ description='Dissolved organic carbon oxidation rate',
+ use='static'
+)
+
+Variable(
+ name='f_pocb',
+ long_name='fraction of benthic algal mortality into POC',
+ units='unitless',
+ description='fraction of benthic algal mortality into POC',
+ use='static'
+)
+
+Variable(
+ name='kpoc_20',
+ long_name='POC hydrolysis rate at 20 degrees Celsius',
+ units='1/d',
+ description='POC hydrolysis rate at 20 degrees Celsius',
+ use='static'
+)
+
+Variable(
+ name='KsOxmc',
+ long_name='half saturation oxygen attenuation constant for DOC oxidation rate',
+ units='mg-O2/L',
+ description='half saturation oxygen attenuation constant for DOC oxidation rate',
+ use='static'
+)
+
+Variable(
+ name='pCO2',
+ long_name='partial atmospheric CO2 pressure',
+ units='ppm',
+ description='partial pressure of CO2 in the atmosphere',
+ use='static'
+)
+
+Variable(
+ name='FCO2',
+ long_name='CO2 reaeration rate',
+ units='1/d',
+ description='CO2 reaeration rate',
+ use='static'
+)
+
+Variable(
+ name='roc',
+ long_name='O2:C ratio for carbon oxidation',
+ units='mg-O2/mg-C',
+ description='O2:C ratio for carbon oxidation (32/12)',
+ use='static'
+)
+
+############################################ From DOX
+Variable(
+ name='ron',
+ long_name='O2:N ratio for nitrification',
+ units='mg-O2/mg-N',
+ description='O2:N ratio for nitrification (2*32/14)',
+ use='static'
+)
+
+Variable(
+ name='KsSOD',
+ long_name='half saturation oxygen attenuation constant for SOD',
+ units='mg/L',
+ description='half saturation oxygen attenuation constant for SOD',
+ use='static'
+)
+
+############################################ From Pathogen
+Variable(
+ name='kdx_20',
+ long_name='Pathogen death rate at 20C',
+ units='1/d',
+ description='Pathogen death rate at 20C',
+ use='static',
+)
+
+Variable(
+ name='apx',
+ long_name='Light efficiency factor for pathogen decay',
+ units='unitless',
+ description='Light efficiency factor for pathogen decay',
+ use='static',
+)
+
+Variable(
+ name='vx',
+ long_name='Pathogen net settling velocity',
+ units='unitless',
+ description='Pathogen net settling velocity',
+ use='static',
+)
+
+############################################ From Alkalinity
+Variable(
+ name='r_alkaa',
+ long_name='Ratio translating algal growth into Alk if NH4 is the N source',
+ units='eq/ug-Chla',
+ description='Ratio translating algal growth into Alk if NH4 is the N source',
+ use='static'
+)
+
+Variable(
+ name='r_alkan',
+ long_name='Ratio translating algal growth into Alk if NO3 is the N source',
+ units='eq/ug-Chla',
+ description='Ratio translating algal growth into Alk if NO3 is the N source',
+ use='static'
+)
+
+Variable(
+ name='r_alkn',
+ long_name='Ratio translating NH4 nitrification into Alk',
+ units='eq/mg-N',
+ description='Ratio translating NH4 nitrification into Alk',
+ use='static'
+)
+
+Variable(
+ name='r_alkden',
+ long_name='Ratio translating NO3 denitrification into Alk',
+ units='eq/mg-N',
+ description='Ratio translating NO3 denitrification into Alk',
+ use='static'
+)
+
+Variable(
+ name='r_alkba',
+ long_name='Ratio translating benthic algae growth into Alk if NH4 is the N source',
+ units='eq/mg-D',
+ description='Ratio translating benthic algae growth into Alk if NH4 is the N source',
+ use='static'
+)
+
+Variable(
+ name='r_alkbn',
+ long_name='Ratio translating benthic algae growth into Alk if NO3 is the N source',
+ units='eq/mg-D',
+ description='Ratio translating benthic algae growth into Alk if NO3 is the N source',
+ use='static'
+)
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/test_6_nsm_module.py b/tests/test_6_nsm_module.py
new file mode 100644
index 0000000..93daf42
--- /dev/null
+++ b/tests/test_6_nsm_module.py
@@ -0,0 +1,117 @@
+import numpy as np
+import pytest
+
+from clearwater_modules.nsm1.model import (
+ NutrientBudget
+)
+
+from clearwater_modules.nsm1.constants import (
+ DEFAULT_ALGAE,
+ DEFAULT_ALKALINITY,
+ DEFAULT_BALGAE,
+ DEFAULT_NITROGEN,
+ DEFAULT_CARBON,
+ DEFAULT_CBOD,
+ DEFAULT_DOX,
+ DEFAULT_N2,
+ DEFAULT_POM,
+ DEFAULT_PATHOGEN,
+ DEFAULT_PHOSPHORUS,
+ DEFAULT_GLOBALPARAMETERS,
+ DEFAULT_GLOBALVARS
+)
+
+
+@pytest.fixture(scope='module')
+def initial_nsm1_state(initial_array) -> dict[str, float]:
+ """Return initial state values for the model."""
+ return {
+ 'Ap': initial_array,
+ 'Ab': initial_array,
+ 'NH4': initial_array,
+ 'NO3': initial_array,
+ 'OrgN': initial_array,
+ 'N2': initial_array,
+ 'TIP': initial_array,
+ 'OrgP': initial_array,
+ 'POC': initial_array,
+ 'DOC': initial_array,
+ 'DIC': initial_array,
+ 'POM': initial_array,
+ 'CBOD': initial_array,
+ 'DOX': initial_array,
+ 'PX': initial_array,
+ 'Alk': initial_array,
+ }
+
+
+@pytest.fixture(scope='module')
+def time_steps() -> int:
+ return 1
+
+
+@pytest.fixture(scope='module')
+def nsm1_state_variable_names(initial_state_values) -> list[str]:
+ """Return the names of the state variables."""
+ return list(initial_state_values.keys())
+
+
+@pytest.fixture(scope='module')
+def nutrient_budget_instance(
+ time_steps,
+ initial_nsm1_state
+) -> NutrientBudget:
+ """Return an instance of the NSM1 class."""
+ return NutrientBudget(
+ time_steps=time_steps,
+ initial_state_values=initial_nsm1_state,
+ updateable_static_variables=['vson'],
+ time_dim='nsm1_time_step',
+ )
+
+
+def test_nsm1_specific_attributes(nutrient_budget_instance) -> None:
+ """Checks that all NSM1 variables are present."""
+ assert nutrient_budget_instance.time_dim == 'nsm1_time_step'
+ assert isinstance(nutrient_budget_instance.algae_parameters, dict)
+ assert isinstance(nutrient_budget_instance.alkalinity_parameters, dict)
+ assert isinstance(nutrient_budget_instance.balgae_parameters, dict)
+ assert isinstance(nutrient_budget_instance.nitrogen_parameters, dict)
+ assert isinstance(nutrient_budget_instance.carbon_parameters, dict)
+ assert isinstance(nutrient_budget_instance.CBOD_parameters, dict)
+ assert isinstance(nutrient_budget_instance.DOX_parameters, dict)
+ assert isinstance(nutrient_budget_instance.N2_parameters, dict)
+ assert isinstance(nutrient_budget_instance.POM_parameters, dict)
+ assert isinstance(nutrient_budget_instance.pathogen_parameters, dict)
+ assert isinstance(nutrient_budget_instance.phosphorus_parameters, dict)
+ assert isinstance(nutrient_budget_instance.global_parameters, dict)
+ assert isinstance(nutrient_budget_instance.global_vars, dict)
+
+ assert nutrient_budget_instance.updateable_static_variables == ['vson']
+
+ assert nutrient_budget_instance.algae_parameters == DEFAULT_ALGAE
+ assert nutrient_budget_instance.alkalinity_parameters == DEFAULT_ALKALINITY
+ assert nutrient_budget_instance.balgae_parameters == DEFAULT_BALGAE
+ assert nutrient_budget_instance.nitrogen_parameters == DEFAULT_NITROGEN
+ assert nutrient_budget_instance.carbon_parameters == DEFAULT_CARBON
+ assert nutrient_budget_instance.CBOD_parameters == DEFAULT_CBOD
+ assert nutrient_budget_instance.DOX_parameters == DEFAULT_DOX
+ assert nutrient_budget_instance.N2_parameters == DEFAULT_N2
+ assert nutrient_budget_instance.POM_parameters == DEFAULT_POM
+ assert nutrient_budget_instance.pathogen_parameters == DEFAULT_PATHOGEN
+ assert nutrient_budget_instance.phosphorus_parameters == DEFAULT_PHOSPHORUS
+ assert nutrient_budget_instance.global_parameters == DEFAULT_GLOBALPARAMETERS
+ assert nutrient_budget_instance.global_vars == DEFAULT_GLOBALVARS
+
+def test_nsm1_variable_sorting(nutrient_budget_instance) -> None:
+ """Checks that we can auto-sort our NSM1 variable"""
+ assert isinstance(nutrient_budget_instance.computation_order, list)
+ assert nutrient_budget_instance.computation_order[-1].name == 'DOX' #TODO what is first?
+
+
+def test_nsm1_timestep(nutrient_budget_instance) -> None:
+ """Checks that we can auto-sort our NSM1 variable"""
+ nutrient_budget_instance.increment_timestep()
+ assert len(nutrient_budget_instance.dataset.nsm1_time_step) == 2
+ assert nutrient_budget_instance.dataset.sel(nsm1_time_step=1).isnull().any() == False
+
diff --git a/tests/test_7_nsm_algae_calculations.py b/tests/test_7_nsm_algae_calculations.py
new file mode 100644
index 0000000..79dbfb6
--- /dev/null
+++ b/tests/test_7_nsm_algae_calculations.py
@@ -0,0 +1,1909 @@
+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': 40,
+ 'Ab': 24,
+ 'NH4': 0.05,
+ 'NO3': 5,
+ 'OrgN': 1.7,
+ 'N2': 1,
+ 'TIP': 0.07,
+ 'OrgP': 0.25,
+ 'POC': 4,
+ '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,
+ )
+
+@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= 3500,
+ 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
+ )
+
+@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
+ )
+
+@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
+ )
+
+@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
+ )
+
+@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
+ )
+
+@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
+ )
+
+@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,
+ )
+
+@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 = 999,
+ vs = 999,
+ SOD_20 = 999,
+ SOD_theta = 999,
+ vb = 0.01,
+ fcom = 0.4,
+ kaw_20_user = 999,
+ kah_20_user = 999,
+ hydraulic_reaeration_option = 2,
+ wind_reaeration_option = 2,
+ timestep = 1, #TODO Dynamic or static?
+ depth = 1.5, #TODO Dynamic or static?
+ TwaterC = 25,
+ theta = 1.047,
+ velocity = 1,
+ flow = 2,
+ topwidth = 1,
+ slope = 2,
+ shear_velocity = 4,
+ pressure_atm = 2,
+ wind_speed = 4,
+ 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()
+ Ap = nsm1.dataset.isel(nsm1_time_step=-1).Ap.values.item()
+
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 52.668069
+
+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_state_dict['Ap'] = 60.0
+
+ # 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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 74.849998
+
+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_state_dict['NH4'] = 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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 52.680781
+
+def test_changed_KL(
+ 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['KL'] = 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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 49.229049
+
+def test_changed_KsN(
+ 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['KsN'] = 0.02
+
+ # 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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 52.803304
+
+def test_changed_KsP(
+ 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['KsP'] = 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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 50.931103
+
+def test_changed_mu_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_algae_params['mu_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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 69.809173
+
+def test_changed_kdp(
+ 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['kdp_20'] = 0.09
+
+ # 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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 55.687635
+
+def test_changed_krp(
+ 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['krp_20'] = 0.09
+
+ # 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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 58.203941
+
+def test_changed_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.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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 51.334735
+
+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_state_dict['NO3'] = 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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 52.802629
+
+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_state_dict['TIP'] = 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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 52.842286
+
+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'] = 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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 62.384696
+
+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'] = 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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 47.171170
+
+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'] = 250
+
+def test_changed_Fr_PAR(
+ 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['Fr_PAR'] = 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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 45.185221
+
+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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 52.665375
+
+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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 37.582388
+
+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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 53.255764
+
+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_algae_params['growth_rate_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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 52.939611
+
+def test_changed_g3_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_algae_params['growth_rate_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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 53.096967
+
+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_algae_params['growth_rate_option'] = 3
+ default_algae_params['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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 59.847275
+
+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_algae_params['growth_rate_option'] = 2
+ default_algae_params['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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 60.175682
+
+def test_changed_g3_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_algae_params['growth_rate_option'] = 3
+ default_algae_params['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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 60.365992
+
+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_algae_params['growth_rate_option'] = 1
+ default_algae_params['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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 40.479472
+
+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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 31.938218
+
+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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 46.601473
+
+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'] = 0.02
+
+ # 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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 55.635473
+
+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.009
+
+ # 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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 62.784764
+
+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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 63.113783
+
+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_state_dict['POC'] = 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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 46.458270
+
+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.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()
+ Ap = nsm1.dataset.isel(
+ nsm1_time_step=-1).Ap.values.item()
+ assert isinstance(Ap, float)
+ assert pytest.approx(Ap, tolerance) == 56.937679
\ No newline at end of file