diff --git a/HSP2/GQUAL.py b/HSP2/GQUAL.py index 67632fd1..50978f64 100644 --- a/HSP2/GQUAL.py +++ b/HSP2/GQUAL.py @@ -643,26 +643,31 @@ def _gqual_(ui, ts): if tempfg == 1: if 'TW' not in ts: errors[6] += 1 # ERRMSG6: timeseries not available + ts['TW_GQ'] = zeros(simlen) else: ts['TW_GQ'] = ts['TW'] if phflag == 1: if 'PHVAL' not in ts: errors[7] += 1 # ERRMSG7: timeseries not available + ts['PHVAL_GQ'] = zeros(simlen) else: ts['PHVAL_GQ'] = ts['PHVAL'] if roxfg == 1: if 'ROC' not in ts: errors[8] += 1 # ERRMSG8: timeseries not available + ts['ROC_GQ'] = zeros(simlen) else: ts['ROC_GQ'] = ts['ROC'] if cldfg == 1: if 'CLOUD' not in ts: errors[9] += 1 # ERRMSG9: timeseries not available + ts['CLOUD_GQ'] = zeros(simlen) else: ts['CLOUD_GQ'] = ts['CLOUD'] if sdfg == 1: if 'SSED4' not in ts: errors[10] += 1 # ERRMSG10: timeseries not available + ts['SDCNC_GQ'] = zeros(simlen) else: ts['SDCNC_GQ'] = ts['SSED4'] if phytfg == 1: diff --git a/HSP2/HTRCH.py b/HSP2/HTRCH.py index eced0105..852c7a38 100644 --- a/HSP2/HTRCH.py +++ b/HSP2/HTRCH.py @@ -167,6 +167,8 @@ def _htrch_(ui, ts): tgrnd = ui['TGRND'] kmud = ui['KMUD'] * delt60 # convert rate coefficients from kcal/m2/C/hr to kcal/m2/C/ivl kgrnd = ui['KGRND'] * delt60 + else: + muddep = 0.0 if uunits == 1: # input units are deg.F, but need deg.C muddep = muddep / 3.281 diff --git a/HSP2/NUTRX_Class.py b/HSP2/NUTRX_Class.py index 293b3927..a166e9cd 100644 --- a/HSP2/NUTRX_Class.py +++ b/HSP2/NUTRX_Class.py @@ -201,7 +201,7 @@ def __init__(self, siminfo, nexits, vol, ui_rq, ui, ts, OXRX): self.NUADFG = zeros(7, dtype=np.int32) for j in range(1, 7): - self.NUADFG[j] = int(ui['NUADFG' + str(j)]) + self.NUADFG[j] = int(ui['NUADFG(' + str(j) + ')']) # error handling: if self.TAMFG == 0 and (self.AMVFG == 1 or self.ADNHFG == 1): diff --git a/HSP2/PHCARB_Class.py b/HSP2/PHCARB_Class.py new file mode 100644 index 00000000..8ebd0461 --- /dev/null +++ b/HSP2/PHCARB_Class.py @@ -0,0 +1,144 @@ +import numpy as np +from numpy import zeros, array +import numba as nb +from numba.typed import Dict +from numba.experimental import jitclass +from math import exp, log + +from HSP2.ADCALC import advect +from HSP2.RQUTIL import benth + +spec = [ + ('AFACT', nb.float64), + ('alkcon', nb.int32), + ('anaer', nb.int32), + ('BENRFG', nb.int32), + ('brco2', nb.float64[:]), + ('cfcinv', nb.float64), + ('co2', nb.float64), + ('conv', nb.float64), + ('delt60', nb.float64), + ('delth', nb.float64), + ('delts', nb.float64), + ('errors', nb.int64[:]), + ('ico2', nb.float64), + ('itic', nb.float64), + ('ncons', nb.int32), + ('nexits', nb.int32), + ('oco2', nb.float64[:]), + ('otic', nb.float64[:]), + ('ph', nb.float64), + ('phcnt', nb.int32), + ('roco2', nb.float64), + ('rotic', nb.float64), + ('uunits', nb.int32), + ('svol', nb.float64), + ('tic', nb.float64), + ('vol', nb.float64), +] + +@jitclass(spec) +class PHCARB_Class: + + #------------------------------------------------------------------- + # class initialization: + #------------------------------------------------------------------- + def __init__(self, siminfo, nexits, vol, ui_rq, ui, ts): + + ''' Initialize variables for pH, carbon dioxide, total inorganic carbon, and alkalinity ''' + + self.errors = zeros(int(ui['errlen']), dtype=np.int64) + + delt60 = siminfo['delt'] / 60.0 # delt60 - simulation time interval in hours + self.delt60 = delt60 + self.simlen = int(siminfo['steps']) + self.delts = siminfo['delt'] * 60 + self.uunits = int(siminfo['units']) + + self.nexits = int(nexits) + + self.vol = vol + self.svol = self.vol + + # inflow/outflow conversion factor: + if self.uunits == 2: # SI conversion: (g/m3)*(m3/ivld) --> [kg/ivld] + self.conv = 1.0e-3 + else: # Eng. conversion: (g/m3)*(ft3/ivld) --> [lb/ivld] + self.conv = 6.2428e-5 + + # required values from other modules: + self.BENRFG = int(ui_rq['BENRFG']) # via table-type benth-flag + self.anaer = int(ui_rq['ANAER']) + + # flags - table-type ph-parm1 + self.phcnt = int(ui['PHCNT']) # is the maximum number of iterations to pH solution. + self.alkcon = int(ui['ALKCON']) # ALKCON is the number of the conservative substance which is alkalinity. + + ncons = int(ui_rq['NCONS']) + if self.alkcon > ncons: + self.errors[0] += 1 + # ERRMSG: Invalid CONS index specified for ALKCON (i.e., ALKCON > NCONS). + + # flags - table-type ph-parm2 + self.cfcinv = ui['CFCINV'] + + self.brco2 = zeros(2) + for i in range(2): + self.brco2[i] = ui['BRCO2' + str(i+1)] * self.delt60 + + # table-type ph-init + self.tic = ui['TIC'] + self.co2 = ui['CO2'] + self.ph = ui['PH'] + + # initialize outflows: + self.roco2 = 0.0 + self.rotic = 0.0 + + self.oco2 = zeros(nexits) + self.otic = zeros(nexits) + + return + + #------------------------------------------------------------------- + # simulation (single timestep): + #------------------------------------------------------------------- + + def simulate(self, phif1, phif2, avdepe, tw, dox, advectData): + + ''' simulate ph, carbon dioxide, total inorganic carbon, and alkalinity''' + + # hydraulics: + (nexits, vols, vol, srovol, erovol, sovol, eovol) = advectData + + self.vol = vol + + # inflows: convert from [mass/ivld] to [conc.*vol/ivld] + self.itic = phif1 / self.conv + self.ico2 = phif2 / self.conv + + # advect TIC: + (self.tic, self.rotic, self.otic) = \ + advect(self.itic, self.bod, nexits, self.svol, self.vol, srovol, erovol, sovol, eovol) + + # advect CO2: + (self.co2, self.roco2, self.oco2) = \ + advect(self.ico2, self.co2, nexits, self.svol, self.vol, srovol, erovol, sovol, eovol) + + if self.CONSFG == 0: + pass + else: + # con(alkcon) is available from section cons + pass + + + if self.vol > 0.0: + pass + + self.svol = self.vol # svol is volume at start of time step, update for next time thru + + return + + #------------------------------------------------------------------- + # utility functions: + #------------------------------------------------------------------- \ No newline at end of file diff --git a/HSP2/PLANK_Class.py b/HSP2/PLANK_Class.py index 7a0fc1aa..eefccc16 100644 --- a/HSP2/PLANK_Class.py +++ b/HSP2/PLANK_Class.py @@ -321,7 +321,9 @@ def __init__(self, siminfo, nexits, vol, ui_rq, ui, ts, OXRX, NUTRX): self.numbal = self.BALFG # single species or none self.cfsaex = 1.0 - if self.HTFG == 0 or 'CFSAEX' in ui: # fraction of surface exposed - table-type surf-exposed + if self.HTFG > 0 and 'CFSAEX' in ui_rq: # via heat-parm input table + self.cfsaex = ui_rq['CFSAEX'] + elif 'CFSAEX' in ui: # fraction of surface exposed - table-type surf-exposed self.cfsaex = ui['CFSAEX'] # table-type plnk-parm1 @@ -348,10 +350,16 @@ def __init__(self, siminfo, nexits, vol, ui_rq, ui, ts, OXRX, NUTRX): self.cmmn = ui['CMMN'] self.cmmnp = ui['CMMNP'] self.cmmp = ui['CMMP'] + self.talgrh = ui['TALGRH'] self.talgrl = ui['TALGRL'] self.talgrm = ui['TALGRM'] + if self.uunits == 1: + self.talgrh = (self.talgrh - 32.0) * 0.555 + self.talgrl = (self.talgrl - 32.0) * 0.555 + self.talgrm = (self.talgrm - 32.0) * 0.555 + # table-type plnk-parm3 self.alr20 = ui['ALR20'] * delt60 # convert rates from 1/hr to 1/ivl self.aldh = ui['ALDH'] * delt60 @@ -652,6 +660,9 @@ def simulate(self, tw, phval, co2, tss, OXRX, NUTRX, iphyto, izoo, iorn, iorp, i else: # use full depth and velocity self.balvel = avvele self.baldep = avdepe + else: + self.balvel = 0.0 + self.baldep = 0.0 # calculate solar radiation absorbed; solrad is the solar radiation at gage, # corrected for location of reach; 0.97 accounts for surface reflection @@ -690,7 +701,7 @@ def simulate(self, tw, phval, co2, tss, OXRX, NUTRX, iphyto, izoo, iorn, iorp, i # sestonic algae growth & respiration #----------------------------------------------------------- if self.PHYFG == 1: # simulate phytoplankton, phyrx only called here - (po4,no3,tam,dox,self.orn,self.orp,self.orc,bod,self.phyto,self.limphy,self.co2,self.phycla, + (po4,no3,tam,dox,self.orn,self.orp,self.orc,bod,self.phyto,self.limphy,self.pyco2,self.phycla, dophy,bodphy,tamphy,no3phy,po4phy,phdth,phgro,ornphy,orpphy,orcphy) \ = self.phyrx(self.phylit,tw,self.talgrl,self.talgrh,self.talgrm,self.malgr,self.cmmp, \ self.cmmnp,NUTRX.TAMFG,self.AMRFG,self.NSFG,self.cmmn,self.cmmlt,self.delt60, \ @@ -716,7 +727,7 @@ def simulate(self, tw, phval, co2, tss, OXRX, NUTRX, iphyto, izoo, iorn, iorp, i # zooplankton growth & death: #----------------------------------------------------------- if self.ZOOFG == 1: # simulate zooplankton, zorx only called here - (dox,bod,self.zoo,self.orn,self.orp,self.orc,tam,no3,po4,zeat,zco2,dozoo,bodzoo,nitzoo,po4zoo,zgro,zdth,zorn,zorp,zorc) \ + (dox,bod,self.zoo,self.orn,self.orp,self.orc,tam,no3,po4,zeat,self.zoco2,dozoo,bodzoo,nitzoo,po4zoo,zgro,zdth,zorn,zorp,zorc) \ = self.zorx(self.zfil20,self.tczfil,tw,self.phyto,self.mzoeat,self.zexdel,self.cvpb, \ self.zres20,self.tczres,NUTRX.anaer,self.zomass,NUTRX.TAMFG,self.refr, \ self.ZFOOD,self.zd,self.oxzd,self.cvbn,self.cvbp,self.cvbc,self.cvnrbo,self.cvbo, \ @@ -1253,6 +1264,11 @@ def litrch(inlit, extb, extcla, extsed, avdepe, baldep, PHYFG, BALFG): ''' calculate light correction factor to algal growth (cflit); determine amount of light available to phytoplankton and benthic algae''' ln01 = 4.60517 # minus natural log 0.01 + + cflit = 0.0 + phylit = 0.0 + ballit = 0.0 + if inlit > 0.0: # calculate extinction of light based on the base extinction # coefficient of the water incremented by self-shading effects @@ -1290,10 +1306,10 @@ def litrch(inlit, extb, extcla, extsed, avdepe, baldep, PHYFG, BALFG): ballit = inlit * exp(-extco * baldep) if ballit < 0.0001: ballit = 0.0 + else: # there is no incident solar radiation; algal growth cannot occur - cflit = 0.0 - phylit = 0.0 - ballit = 0.0 + pass + return phylit, ballit, cflit @staticmethod @@ -1629,7 +1645,7 @@ def pksums(self, NUTRX, phyto, zoo, orn, orp, orc, no3, tam, no2, snh4, po4, spo tp = -1.0e30 if (self.vol <= 0): - return + return torn, torp, torc, potbod, tn, tp # Calculate sums: tval = 0.0 diff --git a/HSP2/RQUAL.py b/HSP2/RQUAL.py index 7fbcd3ab..a8cfde9d 100644 --- a/HSP2/RQUAL.py +++ b/HSP2/RQUAL.py @@ -6,7 +6,7 @@ import logging import numpy as np from numpy import where, zeros, array, float64 -from numba import types +from numba import types, njit from numba.typed import Dict from HSP2.utilities import make_numba_dict, initm @@ -27,9 +27,6 @@ def rqual(store, siminfo, uci, uci_oxrx, uci_nutrx, uci_plank, uci_phcarb, ts): ''' Simulate constituents involved in biochemical transformations''' - #ERRMSGS =('') - #errors = zeros(len(ERRMSGS), dtype=np.int32) - # simulation information: delt60 = siminfo['delt'] / 60 # delt60 - simulation time interval in hours simlen = siminfo['steps'] @@ -94,7 +91,7 @@ def rqual(store, siminfo, uci, uci_oxrx, uci_nutrx, uci_plank, uci_phcarb, ts): n = (2 * j) - 1 # dry deposition: - nuadfg_dd = int(ui_nutrx['NUADFG' + str(j)]) + nuadfg_dd = int(ui_nutrx['NUADFG(' + str(j) + ')']) NUADFX = zeros(simlen) if nuadfg_dd > 0: @@ -107,7 +104,7 @@ def rqual(store, siminfo, uci, uci_oxrx, uci_nutrx, uci_plank, uci_phcarb, ts): ts['NUADFX' + str(j)] = NUADFX # wet deposition: - nuadfg_wd = int(ui_nutrx['NUADFG' + str(j+1)]) + nuadfg_wd = int(ui_nutrx['NUADFG(' + str(j+1) + ')']) NUADCN = zeros(simlen) if nuadfg_wd > 0: @@ -126,7 +123,7 @@ def rqual(store, siminfo, uci, uci_oxrx, uci_nutrx, uci_plank, uci_phcarb, ts): # dry deposition: PLADFX = zeros(simlen) - pladfg_dd = int(ui_plank['PLADFG' + str(j)]) + pladfg_dd = int(ui_plank['PLADFG(' + str(j) + ')']) if pladfg_dd > 0: PLADFX = initm(siminfo, ui, pladfg_dd, 'PLANK_MONTHLY/PLADFX', 0.0) @@ -139,7 +136,7 @@ def rqual(store, siminfo, uci, uci_oxrx, uci_nutrx, uci_plank, uci_phcarb, ts): # wet deposition: PLADCN = zeros(simlen) - pladfg_wd = int(ui_plank['PLADFG' + str(j+1)]) + pladfg_wd = int(ui_plank['PLADFG(' + str(j+1) + ')']) if pladfg_wd > 0: PLADCN = initm(siminfo, ui, pladfg_wd, 'PLANK_MONTHLY/PLADCN', 0.0) @@ -157,22 +154,42 @@ def rqual(store, siminfo, uci, uci_oxrx, uci_nutrx, uci_plank, uci_phcarb, ts): # initialize & run integerated WQ simulation: #--------------------------------------------------------------------- + (err_oxrx, err_nutrx, err_plank, err_phcarb) \ + = _rqual_run(siminfo_, ui, ui_oxrx, ui_nutrx, ui_plank, ui_phcarb, ts) + + #--------------------------------------------------------------------- + # compile errors & return: + #--------------------------------------------------------------------- + + (errors, ERRMSGS) = _compile_errors(NUTFG, PLKFG, PHFG, err_oxrx, err_nutrx, err_plank, err_phcarb) + + return errors, ERRMSGS + + +@njit(cache=True) +def _rqual_run(siminfo_, ui, ui_oxrx, ui_nutrx, ui_plank, ui_phcarb, ts): + # initialize WQ simulation: RQUAL = RQUAL_Class(siminfo_, ui, ui_oxrx, ui_nutrx, ui_plank, ui_phcarb, ts) # run WQ simulation: RQUAL.simulate(ts) - #--------------------------------------------------------------------- - # compile errors & return: - #--------------------------------------------------------------------- - errlen_oxr = len(RQUAL.OXRX.errors) + # return error data: + #TO-DO! - return PHCARB errors once implemented + errors_PHCARB = zeros(2, dtype=np.int64) + + return RQUAL.OXRX.errors, RQUAL.NUTRX.errors, RQUAL.PLANK.errors, errors_PHCARB + +def _compile_errors(NUTFG, PLKFG, PHFG, err_oxrx, err_nutrx, err_plank, err_phcarb): + + errlen_oxr = len(err_oxrx) errlen_ntr = 0; errlen_plk = 0; errlen_phc = 0 if NUTFG == 1: - errlen_ntr = len(RQUAL.NUTRX.errors) + errlen_ntr = len(err_nutrx) if PLKFG == 1: - errlen_plk += len(RQUAL.PLANK.errors) + errlen_plk += len(err_plank) if PHFG == 1: #errlen_phc += len(RQUAL.PHCARB.errors) pass @@ -185,22 +202,22 @@ def rqual(store, siminfo, uci, uci_oxrx, uci_nutrx, uci_plank, uci_phcarb, ts): ierr = -1 for i in range(errlen_oxr): ierr += 1 - errors[ierr] = RQUAL.OXRX.errors[i] + errors[ierr] = err_oxrx[i] ERRMSGS += (ERRMSGS_oxrx[i],) for i in range(errlen_ntr): ierr += 1 - errors[ierr] = RQUAL.NUTRX.errors[i] + errors[ierr] = err_nutrx[i] ERRMSGS += (ERRMSGS_nutrx[i],) for i in range(errlen_plk): ierr += 1 - errors[ierr] = RQUAL.PLANK.errors[i] + errors[ierr] = err_plank[i] ERRMSGS += (ERRMSGS_plank[i],) for i in range(errlen_phc): ierr += 1 - errors[ierr] = RQUAL.PHCARB.errors[i] + errors[ierr] = err_phcarb[i] ERRMSGS += (ERRMSGS_phcarb[i],) return errors, ERRMSGS @@ -233,7 +250,7 @@ def expand_OXRX_masslinks(flags, uci, dat, recs): recs.append(rec) - return + return recs def expand_NUTRX_masslinks(flags, uci, dat, recs): @@ -250,7 +267,7 @@ def expand_NUTRX_masslinks(flags, uci, dat, recs): rec['SMEMSB2'] = '' else: rec['SMEMN'] = 'NUCF9' - rec['SMEMSB2'] = dat.SMEMSB1 # exit number + rec['SMEMSB1'] = dat.SMEMSB1 # exit number rec['SMEMSB2'] = str(i) # species index rec['TMEMN'] = 'NUIF1' @@ -274,7 +291,7 @@ def expand_NUTRX_masslinks(flags, uci, dat, recs): rec['SMEMSB2'] = '1' # NH4 index else: rec['SMEMN'] = 'OSNH4' - rec['SMEMSB2'] = dat.SMEMSB1 # exit number + rec['SMEMSB1'] = dat.SMEMSB1 # exit number rec['SMEMSB2'] = str(j) # sediment type rec['TMEMN'] = 'NUIF2' @@ -295,7 +312,7 @@ def expand_NUTRX_masslinks(flags, uci, dat, recs): rec['SMEMSB2'] = '2' # PO4 index else: rec['SMEMN'] = 'OSPO4' - rec['SMEMSB2'] = dat.SMEMSB1 # exit number + rec['SMEMSB1'] = dat.SMEMSB1 # exit number rec['SMEMSB2'] = str(j) # sediment type rec['TMEMN'] = 'NUIF2' @@ -304,7 +321,7 @@ def expand_NUTRX_masslinks(flags, uci, dat, recs): rec['SVOL'] = dat.SVOL recs.append(rec) - return + return recs def expand_PLANK_masslinks(flags, uci, dat, recs): if flags['PLANK']: @@ -319,8 +336,8 @@ def expand_PLANK_masslinks(flags, uci, dat, recs): rec['SMEMSB1'] = str(i) # species index rec['SMEMSB2'] = '' else: - rec['SMEMN'] = 'TPKCF2' - rec['SMEMSB2'] = dat.SMEMSB1 # exit number + rec['SMEMN'] = 'PKCF2' + rec['SMEMSB1'] = dat.SMEMSB1 # exit number rec['SMEMSB2'] = str(i) # species index rec['TMEMN'] = 'PKIF' @@ -329,7 +346,7 @@ def expand_PLANK_masslinks(flags, uci, dat, recs): rec['SVOL'] = dat.SVOL recs.append(rec) - return + return recs def expand_PHCARB_masslinks(flags, uci, dat, recs): @@ -346,7 +363,7 @@ def expand_PHCARB_masslinks(flags, uci, dat, recs): rec['SMEMSB2'] = '' else: rec['SMEMN'] = 'PHCF2' - rec['SMEMSB2'] = dat.SMEMSB1 # exit number + rec['SMEMSB1'] = dat.SMEMSB1 # exit number rec['SMEMSB2'] = str(i) # species index rec['TMEMN'] = 'PHIF' @@ -355,4 +372,4 @@ def expand_PHCARB_masslinks(flags, uci, dat, recs): rec['SVOL'] = dat.SVOL recs.append(rec) - return \ No newline at end of file + return recs \ No newline at end of file diff --git a/HSP2/RQUAL_Class.py b/HSP2/RQUAL_Class.py index 0cade940..02f677a4 100644 --- a/HSP2/RQUAL_Class.py +++ b/HSP2/RQUAL_Class.py @@ -558,7 +558,7 @@ def simulate(self, ts): if self.nexits > 1: for i in range(self.nexits): - osed[i,j] = ts['OSED' + str(i+1)][loop] + osed[i,j] = ts['OSED' + str(j) + str(i+1)][loop] else: osed[0,j] = rosed[j] @@ -687,8 +687,8 @@ def simulate(self, ts): if self.nexits > 1: for i in range(self.nexits): - ts['OXCF2' + str(i + 1) + '1'][loop] = self.OXRX.odox[i] * self.OXRX.conv - ts['OXCF2' + str(i + 1) + '2'][loop] = self.OXRX.obod[i] * self.OXRX.conv + ts['OXCF2' + str(i + 1) + ' 1'][loop] = self.OXRX.odox[i] * self.OXRX.conv + ts['OXCF2' + str(i + 1) + ' 2'][loop] = self.OXRX.obod[i] * self.OXRX.conv # NUTRX results: if self.NUTFG == 1: @@ -750,9 +750,10 @@ def simulate(self, ts): self.PHYTO[loop] = self.PLANK.phyto self.ZOO[loop] = self.PLANK.zoo - self.BENAL1[loop] = self.PLANK.benal[0] - self.TBENAL1[loop] = self.PLANK.tbenal[1] - self.TBENAL2[loop] = self.PLANK.tbenal[2] + if self.PLANK.BALFG: + self.BENAL1[loop] = self.PLANK.benal[0] + self.TBENAL1[loop] = self.PLANK.tbenal[1] + self.TBENAL2[loop] = self.PLANK.tbenal[2] self.PHYCLA[loop] = self.PLANK.phycla self.ORN[loop] = self.PLANK.orn diff --git a/HSP2/configuration.py b/HSP2/configuration.py index 158039be..4bdc3ae1 100644 --- a/HSP2/configuration.py +++ b/HSP2/configuration.py @@ -30,6 +30,7 @@ from HSP2.RQUAL import expand_OXRX_masslinks from HSP2.RQUAL import expand_NUTRX_masslinks from HSP2.RQUAL import expand_PLANK_masslinks +from HSP2.RQUAL import expand_PHCARB_masslinks #from HSP2.GENER import gener from HSP2.COPY import Copy diff --git a/HSP2/main.py b/HSP2/main.py index 1b6e0c30..15e9ed55 100644 --- a/HSP2/main.py +++ b/HSP2/main.py @@ -45,12 +45,13 @@ def main(hdfname, saveall=False, jupyterlab=True): # main processing loop msg(1, f'Simulation Start: {start}, Stop: {stop}') for _, operation, segment, delt in opseq.itertuples(): + msg(2, f'{operation} {segment} DELT(minutes): {delt}') + if operation == 'COPY': copy_instances[segment] = activities[operation](store, siminfo, ddext_sources[(operation,segment)]) elif operation == 'GENER': gener_instances[segment] = activities[operation](segment, copy_instances, gener_instances, ddlinks, ddgener) else: - msg(2, f'{operation} {segment} DELT(minutes): {delt}') siminfo['delt'] = delt siminfo['tindex'] = date_range(start, stop, freq=Minute(delt))[1:] siminfo['steps'] = len(siminfo['tindex']) @@ -60,6 +61,13 @@ def main(hdfname, saveall=False, jupyterlab=True): ts = get_gener_timeseries(ts, gener_instances, ddlinks[segment]) flags = uci[(operation, 'GENERAL', segment)]['ACTIVITY'] if operation == 'RCHRES': + # Add nutrient adsorption flags: + if flags['NUTRX'] == 1: + flags['TAMFG'] = uci[(operation, 'NUTRX', segment)]['FLAGS']['NH3FG'] + flags['ADNHFG'] = uci[(operation, 'NUTRX', segment)]['FLAGS']['ADNHFG'] + flags['PO4FG'] = uci[(operation, 'NUTRX', segment)]['FLAGS']['PO4FG'] + flags['ADPOFG'] = uci[(operation, 'NUTRX', segment)]['FLAGS']['ADPOFG'] + get_flows(store, ts, flags, uci, segment, ddlinks, ddmasslinks, siminfo['steps'], msg) for activity, function in activities[operation].items(): @@ -162,6 +170,10 @@ def main(hdfname, saveall=False, jupyterlab=True): ui['PARAMETERS']['SSED2'] = uci[(operation, 'SEDTRN', segment)]['STATES']['SSED2'] ui['PARAMETERS']['SSED3'] = uci[(operation, 'SEDTRN', segment)]['STATES']['SSED3'] + # PLANK module inputs: + if flags['HTRCH']: + ui['PARAMETERS']['CFSAEX'] = uci[(operation, 'HTRCH', segment)]['PARAMETERS']['CFSAEX'] + # NUTRX, PLANK, PHCARB module inputs: ui_nutrx = uci[(operation, 'NUTRX', segment)] ui_plank = uci[(operation, 'PLANK', segment)] @@ -239,7 +251,11 @@ def get_uci(store): siminfo['units'] = int(temp['Units']) elif module == 'LINKS': for row in store[path].fillna('').itertuples(): - ddlinks[f'{row.TVOLNO}{row.TOPFST}'].append(row) + if row.TVOLNO != '': + ddlinks[f'{row.TVOLNO}'].append(row) + else: + ddlinks[f'{row.TOPFST}'].append(row) + elif module == 'MASS_LINKS': for row in store[path].replace('na','').itertuples(): ddmasslinks[row.MLNO].append(row) @@ -418,9 +434,11 @@ def get_gener_timeseries(ts: Dict, gener_instances: Dict, ddlinks: List) -> Dict if link.SVOL == 'GENER': gener = gener_instances[link.SVOLNO] series = gener.get_ts() - if link.MFACTOR != 1: + if link.MFACTOR != 1: series *= link.MFACTOR - ts[f'{link.TMEMN}{link.TMEMSB1}{link.TMEMSB2}'] = series + + ts[f'{link.TMEMN}{link.TMEMSB1} {link.TMEMSB2}'.rstrip()] = series + return ts diff --git a/HSP2tools/data/SaveTable.csv b/HSP2tools/data/SaveTable.csv index 691fdf4a..12b269cf 100644 --- a/HSP2tools/data/SaveTable.csv +++ b/HSP2tools/data/SaveTable.csv @@ -411,12 +411,72 @@ RCHRES,NUTRX,NUCF11,0 RCHRES,NUTRX,NUCF12,0 RCHRES,NUTRX,NUCF13,0 RCHRES,NUTRX,NUCF14,0 -RCHRES,NUTRX,NUCF21 1,0 -RCHRES,NUTRX,NUCF22 1,0 -RCHRES,NUTRX,NUCF23 1,0 -RCHRES,NUTRX,NUCF21 2,0 -RCHRES,NUTRX,NUCF22 2,0 -RCHRES,NUTRX,NUCF23 2,0 +RCHRES,NUTRX,NUCF21 1,1 +RCHRES,NUTRX,NUCF22 1,1 +RCHRES,NUTRX,NUCF23 1,1 +RCHRES,NUTRX,NUCF21 2,1 +RCHRES,NUTRX,NUCF22 2,1 +RCHRES,NUTRX,NUCF23 2,1 +RCHRES,NUTRX,NUCF91 1,1 +RCHRES,NUTRX,NUCF91 2,1 +RCHRES,NUTRX,NUCF91 3,1 +RCHRES,NUTRX,NUCF91 4,1 +RCHRES,NUTRX,NUCF92 1,1 +RCHRES,NUTRX,NUCF92 2,1 +RCHRES,NUTRX,NUCF92 3,1 +RCHRES,NUTRX,NUCF92 4,1 +RCHRES,NUTRX,NUCF93 1,1 +RCHRES,NUTRX,NUCF93 2,1 +RCHRES,NUTRX,NUCF93 3,1 +RCHRES,NUTRX,NUCF93 4,1 +RCHRES,NUTRX,NUCF94 1,1 +RCHRES,NUTRX,NUCF94 2,1 +RCHRES,NUTRX,NUCF94 3,1 +RCHRES,NUTRX,NUCF94 4,1 +RCHRES,NUTRX,NUCF95 1,1 +RCHRES,NUTRX,NUCF95 2,1 +RCHRES,NUTRX,NUCF95 3,1 +RCHRES,NUTRX,NUCF95 4,1 +RCHRES,NUTRX,OSNH41 1,1 +RCHRES,NUTRX,OSNH41 2,1 +RCHRES,NUTRX,OSNH41 3,1 +RCHRES,NUTRX,OSNH41 4,1 +RCHRES,NUTRX,OSNH42 1,1 +RCHRES,NUTRX,OSNH42 2,1 +RCHRES,NUTRX,OSNH42 3,1 +RCHRES,NUTRX,OSNH42 4,1 +RCHRES,NUTRX,OSNH43 1,1 +RCHRES,NUTRX,OSNH43 2,1 +RCHRES,NUTRX,OSNH43 3,1 +RCHRES,NUTRX,OSNH43 4,1 +RCHRES,NUTRX,OSNH44 1,1 +RCHRES,NUTRX,OSNH44 2,1 +RCHRES,NUTRX,OSNH44 3,1 +RCHRES,NUTRX,OSNH44 4,1 +RCHRES,NUTRX,OSNH45 1,1 +RCHRES,NUTRX,OSNH45 2,1 +RCHRES,NUTRX,OSNH45 3,1 +RCHRES,NUTRX,OSNH45 4,1 +RCHRES,NUTRX,OSPO41 1,1 +RCHRES,NUTRX,OSPO41 2,1 +RCHRES,NUTRX,OSPO41 3,1 +RCHRES,NUTRX,OSPO41 4,1 +RCHRES,NUTRX,OSPO42 1,1 +RCHRES,NUTRX,OSPO42 2,1 +RCHRES,NUTRX,OSPO42 3,1 +RCHRES,NUTRX,OSPO42 4,1 +RCHRES,NUTRX,OSPO43 1,1 +RCHRES,NUTRX,OSPO43 2,1 +RCHRES,NUTRX,OSPO43 3,1 +RCHRES,NUTRX,OSPO43 4,1 +RCHRES,NUTRX,OSPO44 1,1 +RCHRES,NUTRX,OSPO44 2,1 +RCHRES,NUTRX,OSPO44 3,1 +RCHRES,NUTRX,OSPO44 4,1 +RCHRES,NUTRX,OSPO45 1,1 +RCHRES,NUTRX,OSPO45 2,1 +RCHRES,NUTRX,OSPO45 3,1 +RCHRES,NUTRX,OSPO45 4,1 RCHRES,NUTRX,RNO3,0 RCHRES,NUTRX,RTAM,0 RCHRES,NUTRX,RNO2,0 @@ -447,17 +507,61 @@ RCHRES,PLANK,PKIF_ZOO,0 RCHRES,PLANK,PKIF_ORN,0 RCHRES,PLANK,PKIF_ORP,0 RCHRES,PLANK,PKIF_ORC,0 -RCHRES,PLANK,PKCF11,0 -RCHRES,PLANK,PKCF12,0 -RCHRES,PLANK,PKCF13,0 -RCHRES,PLANK,PKCF14,0 -RCHRES,PLANK,PKCF15,0 +RCHRES,PLANK,PKCF11,1 +RCHRES,PLANK,PKCF12,1 +RCHRES,PLANK,PKCF13,1 +RCHRES,PLANK,PKCF14,1 +RCHRES,PLANK,PKCF15,1 RCHRES,PLANK,ROTORN,0 RCHRES,PLANK,ROTORP,0 RCHRES,PLANK,ROTORC,0 -RCHRES,PHCARB,PHCF1,0 -RCHRES,PHCARB,PHCF2,0 -RCHRES,PHCARB,PHCF3,0 -RCHRES,PHCARB,PHIF,0 -RCHRES,PHCARB,PHST,0 -RCHRES,PHCARB,SATCO2,0 +RCHRES,PLANK,PKCF21 1,1 +RCHRES,PLANK,PKCF21 2,1 +RCHRES,PLANK,PKCF21 3,1 +RCHRES,PLANK,PKCF21 4,1 +RCHRES,PLANK,PKCF21 5,1 +RCHRES,PLANK,PKCF22 1,1 +RCHRES,PLANK,PKCF22 2,1 +RCHRES,PLANK,PKCF22 3,1 +RCHRES,PLANK,PKCF22 4,1 +RCHRES,PLANK,PKCF22 5,1 +RCHRES,PLANK,PKCF23 1,1 +RCHRES,PLANK,PKCF23 2,1 +RCHRES,PLANK,PKCF23 3,1 +RCHRES,PLANK,PKCF23 4,1 +RCHRES,PLANK,PKCF23 5,1 +RCHRES,PLANK,PKCF24 1,1 +RCHRES,PLANK,PKCF24 2,1 +RCHRES,PLANK,PKCF24 3,1 +RCHRES,PLANK,PKCF24 4,1 +RCHRES,PLANK,PKCF24 5,1 +RCHRES,PLANK,PKCF25 1,1 +RCHRES,PLANK,PKCF25 2,1 +RCHRES,PLANK,PKCF25 3,1 +RCHRES,PLANK,PKCF25 4,1 +RCHRES,PLANK,PKCF25 5,1 +RCHRES,PLANK,TPKCF21 1,1 +RCHRES,PLANK,TPKCF21 2,1 +RCHRES,PLANK,TPKCF21 3,1 +RCHRES,PLANK,TPKCF21 4,1 +RCHRES,PLANK,TPKCF21 5,1 +RCHRES,PLANK,TPKCF22 1,1 +RCHRES,PLANK,TPKCF22 2,1 +RCHRES,PLANK,TPKCF22 3,1 +RCHRES,PLANK,TPKCF22 4,1 +RCHRES,PLANK,TPKCF22 5,1 +RCHRES,PLANK,TPKCF23 1,1 +RCHRES,PLANK,TPKCF23 2,1 +RCHRES,PLANK,TPKCF23 3,1 +RCHRES,PLANK,TPKCF23 4,1 +RCHRES,PLANK,TPKCF23 5,1 +RCHRES,PLANK,TPKCF24 1,1 +RCHRES,PLANK,TPKCF24 2,1 +RCHRES,PLANK,TPKCF24 3,1 +RCHRES,PLANK,TPKCF24 4,1 +RCHRES,PLANK,TPKCF24 5,1 +RCHRES,PLANK,TPKCF25 1,1 +RCHRES,PLANK,TPKCF25 2,1 +RCHRES,PLANK,TPKCF25 3,1 +RCHRES,PLANK,TPKCF25 4,1 +RCHRES,PLANK,TPKCF25 5,1 \ No newline at end of file