3 Created on Mon May 18 19:48:52 2020
11 from efo.rule
import RuleBase, RuleRlsSpecified
12 from efo.junction
import ReservoirJunction
26 self.
releaserelease = np.full(self.T.Tcont.nSteps, np.nan)
27 self.
tsRlstsRls = np.full(self.T.Tcont.nSteps, int(0))
30 def calc_release(self, rlsProposed, rlsUnCtrl, stor, rlsPrev=None, qIn=None):
32 rlsProposed, rlsPrev=rlsPrev, rlsUnCtrl=rlsUnCtrl, stor=stor, qIn=qIn)
39 if np.any(self.T.fcstDate == self.T.Tcont.curDT):
41 return max(rlsProposed, self.
releaseSchedreleaseSched[1].item())
45 iFcstTs = self.T.get_fcst_step()
46 rlsCur = self.
releaseSchedreleaseSched[iFcstTs].item()
if iFcstTs
else 0.
47 return max(rlsProposed, rlsCur)
61 if cls
is RuleFcstBase:
63 if set(cls.__abstractmethods__) <= attrs:
69 def __init__(self, name, timeFcst, efoResrvr, storTh, riskTol, constants, *,
70 efoNetwork=None, ruleRlsSpecified=None, efoRlsSched=None,
71 maxItr=100, storMax=None, nHrsLead=None):
87 self.
mbrRlsmbrRls = np.full(self.T.Tcont.nSteps, int(0))
89 self.
nStepsLeadnStepsLead = int(nHrsLead/timeFcst.nHrs) + 1
if nHrsLead
else timeFcst.nSteps
91 self.
storMaxstorMax = storMax
if storMax
else storTh
102 for net
in self.
efoNetworkefoNetwork: net.set_init_cond()
104 t = self.T.get_fcst_time()
116 if self.
efoResrvrefoResrvr[0].outletUnCtrl:
122 for i
in range(t.nSteps-1):
127 self.
rlsMaxrlsMax = np.full((t.nSteps, self.
nMembersnMembers, t.nSteps-1), np.nan)
129 self.
prExcThprExcTh = np.full(t.nSteps, np.nan)
133 riskySelect = np.arange(0, self.
nMembersnMembers, dtype=int)
134 riskyMbr = np.copy(riskySelect)
135 iRisky = np.full(self.
nMembersnMembers,
False)
136 iRiskyChk = np.full(self.
nMembersnMembers,
True)
137 volAbvThresh = np.zeros([t.nSteps, self.
nMembersnMembers])
138 vol2Rls = np.zeros([t.nSteps, self.
nMembersnMembers])
139 rlsFcst = np.full(t.nSteps, np.nan)
140 rlsFcst[0] = self.
efoResrvrefoResrvr[0].rlsCtrl[0]
141 rlsMax = np.full(t.nSteps, np.nan)
142 rlsToday = np.empty((t.nSteps-1, self.
nMembersnMembers))
143 rlsSched = np.zeros(t.nSteps)
144 for tsHoriz
in t.steps[1:self.
nStepsLeadnStepsLead]:
145 self.T.step = tsHoriz
147 self.
storFcststorFcst[:, :, tsHoriz-1] = self.
storFcststorFcst[:, :, tsHoriz-2]
150 for curMbr
in riskySelect:
152 if issubclass(type(self.
ruleRlsSpecifiedruleRlsSpecified[curMbr]), RuleRlsSpecified):
154 self.
efoResrvrefoResrvr[curMbr].calc_qout()
158 self.
storFcststorFcst[tsHoriz, curMbr, tsHoriz-1] = self.
efoResrvrefoResrvr[curMbr].stor[tsHoriz].item()
159 if self.
efoResrvrefoResrvr[curMbr].outletUnCtrl:
161 self.
rlsUnCtrlFcstrlsUnCtrlFcst[tsHoriz, curMbr, tsHoriz-1] = self.
efoResrvrefoResrvr[curMbr].rlsUnCtrl[tsHoriz].item()
163 self.
rlsUnCtrlFcstrlsUnCtrlFcst[tsHoriz, curMbr, tsHoriz-1] = 0.
168 storPlusUnCtrl = self.
storFcststorFcst[tsHoriz, :, tsHoriz-1]\
170 iRisky = (storPlusUnCtrl > self.
storThstorTh) & iRiskyChk
177 iRiskyChk = np.copy(iRisky)
179 riskyMbr = np.where(iRisky)[0]
180 nMbrs2Reduce = int(len(riskyMbr) - np.floor(self.
riskTolriskTol[tsHoriz]*self.
nMembersnMembers))
181 volAbvThresh[tsHoriz, riskyMbr] = \
182 self.
storFcststorFcst[tsHoriz, riskyMbr, tsHoriz-1]\
185 mbrSorted = np.argsort(volAbvThresh[tsHoriz, riskyMbr])
186 riskySelect = riskyMbr[mbrSorted[0:nMbrs2Reduce]]
187 self.
iRiskyMbrsiRiskyMbrs[tsHoriz, riskySelect] =
True
192 vol2Rls[tsHoriz, riskySelect] = 1.01*volAbvThresh[tsHoriz, riskySelect]
195 for curMbr
in riskySelect:
197 rlsFcst[1:tsHoriz+1] = np.sum(
198 vol2Rls[:, curMbr])*self.
constantsconstants.af2cfs/tsHoriz
199 self.
rlsNoConstraintrlsNoConstraint[1:tsHoriz+1, curMbr, tsHoriz-1] = np.copy(rlsFcst[1:tsHoriz+1])
201 rlsFcst[1:tsHoriz+1], tsHoriz, curMbr)
202 self.
rlsMaxrlsMax[1:tsHoriz+1, curMbr, tsHoriz-1] = np.copy(rlsMax[1:tsHoriz+1])
203 if np.sum(vol2Rls[:, curMbr]) - np.sum(rlsFcst[1:tsHoriz+1])*self.
constantsconstants.cfs2af > 0.01:
204 iRiskyChk[curMbr] =
False
208 vol2Rls[tsHoriz, curMbr] -= \
209 (np.sum(vol2Rls[:, curMbr]) - np.sum(rlsFcst[1:tsHoriz+1])*self.
constantsconstants.cfs2af)\
210 - np.sum(self.
rlsUnCtrlFcstrlsUnCtrlFcst[1:tsHoriz+1, curMbr, tsHoriz-1])
211 self.
rlsFcstrlsFcst[1:tsHoriz+1, curMbr, tsHoriz-1] = np.copy(rlsFcst[1:tsHoriz+1])
215 if np.isnan(self.
prExcTh_preRlsprExcTh_preRls[tsHoriz, tsHoriz-1]):
219 riskySelect = np.arange(0, self.
nMembersnMembers, dtype=int)
220 riskyMbr = np.copy(riskySelect)
221 iRiskyChk = np.full(self.
nMembersnMembers,
True)
225 rlsToday[:, :] = np.nanmean(self.
rlsFcstrlsFcst[1:int(self.T.fcstFreq/self.T.nHrs)+1, :, :], axis=0).T
226 if np.any(rlsToday[:] > 0.):
231 tsMax, mbrMax = np.where(rlsToday==np.max(rlsToday))
238 self.
tsRlstsRls[self.T.Tcont.step] = int(tsMax[0])
239 self.
mbrRlsmbrRls[self.T.Tcont.step] = int(mbrMax[0])
241 self.
releaserelease[self.T.Tcont.step] = self.
rlsFcstrlsFcst[1, mbrMax[0], tsMax[0]]
242 rlsSched = self.
rlsFcstrlsFcst[:, mbrMax[0], tsMax[0]]
244 if np.any(np.isnan(rlsSched[:int(self.T.fcstFreq/self.T.nHrs)+1])):
245 tsLastRls = np.where(np.isnan(rlsSched))[0][0]
246 rlsSched[tsLastRls:int(self.T.fcstFreq/self.T.nHrs)+1] = rlsSched[tsLastRls - 1]
249 self.
releaserelease[self.T.Tcont.step] = 0.
260 rlsMax = np.copy(self.
efoResrvrefoResrvr[ensMbr].rlsMax[1:tsHoriz+1])
261 rlsCtrlApplied = self.
efoResrvrefoResrvr[ensMbr].rlsCtrl[1:tsHoriz+1]
262 storFcst = self.
storFcststorFcst[1:tsHoriz+1, ensMbr, tsHoriz-1]
263 rlsUnCtrlFcst = self.
rlsUnCtrlFcstrlsUnCtrlFcst[1:tsHoriz+1, ensMbr, tsHoriz-1]
265 rlsFcstInit = np.copy(rlsFcst)
266 rlsFcstPrev = np.array([np.copy(rlsFcst)])
269 for i
in range(1, tsHoriz+1):
270 if issubclass(type(self.
efoResrvrefoResrvr[ensMbr]), ReservoirJunction):
272 if issubclass(type(self.
ruleRlsSpecifiedruleRlsSpecified[ensMbr]), RuleRlsSpecified):
274 self.
ruleRlsSpecifiedruleRlsSpecified[ensMbr].set_release(i, rlsFcst[i-1].item())
278 self.
efoNetworkefoNetwork[ensMbr].process_fcst_junctions()
280 rlsMax[i-1] = self.
efoResrvrefoResrvr[ensMbr].rlsMax[i].item()
281 storFcst[i-1] = self.
efoResrvrefoResrvr[ensMbr].stor[i].item()
283 rlsFcst[i-1] = self.
efoResrvrefoResrvr[ensMbr].rlsCtrl[i].item()
284 if self.
efoResrvrefoResrvr[ensMbr].outletUnCtrl:
285 rlsUnCtrlFcst[i-1] = self.
efoResrvrefoResrvr[ensMbr].rlsUnCtrl[i].item()
287 rlsUnCtrlFcst[i-1] = 0.
289 if curItr == 0: rlsMaxPrev = np.copy(rlsMax)
290 if np.all(rlsFcstInit == rlsCtrlApplied, axis=0)
or curItr >= self.
maxItrmaxItr:
292 elif np.any(np.all(rlsFcstPrev == rlsCtrlApplied, axis=1)):
308 rlsMax2Spill = np.fmax(np.zeros(rlsFcst.size),
309 rlsCtrlApplied - (storFcst - self.
storMaxstorMax)*self.
constantsconstants.af2cfs - rlsUnCtrlFcst)
310 rlsMax = np.fmin(rlsMax, rlsMax2Spill)
312 rlsFcstPrev = np.vstack((rlsFcstPrev, np.copy(rlsCtrlApplied)))
315 rlsMaxPrev = np.copy(rlsMax)
318 return rlsFcst, rlsMax
324 rlsTot = np.nansum(rlsFcst)
328 rlsMax = self.
efoResrvrefoResrvr[ensMbr].rlsMax[1:tsHoriz+1]
329 rlsCtrlApplied = self.
efoResrvrefoResrvr[ensMbr].rlsCtrl[1:tsHoriz+1]
330 storFcst = self.
storFcststorFcst[1:tsHoriz+1, ensMbr, tsHoriz-1]
331 rlsUnCtrlFcst = self.
rlsUnCtrlFcstrlsUnCtrlFcst[1:tsHoriz+1, ensMbr, tsHoriz-1]
332 rlsMaxPrev = np.zeros(len(rlsMax))
333 rlsFcstInit = np.copy(rlsFcst)
334 rlsFcstPrev = np.array([np.copy(rlsFcst)])
339 for i
in range(1, tsHoriz+1):
340 if issubclass(type(self.
efoResrvrefoResrvr[ensMbr]), ReservoirJunction):
342 if issubclass(type(self.
ruleRlsSpecifiedruleRlsSpecified[ensMbr]), RuleRlsSpecified):
343 self.
ruleRlsSpecifiedruleRlsSpecified[ensMbr].set_release(i, np.copy(rlsFcst[i-1]))
346 self.
efoNetworkefoNetwork[ensMbr].process_fcst_junctions()
348 storFcst[i-1] = np.copy(self.
efoResrvrefoResrvr[ensMbr].stor[i])
349 rlsUnCtrlFcst[i-1] = np.copy(self.
efoResrvrefoResrvr[ensMbr].rlsUnCtrl[i])
352 if curItr == 0: rlsMaxPrev = np.copy(rlsMax)
353 if (rlsTot - np.sum(rlsCtrlApplied) < pctConvg*rlsTot
and np.sum(rlsUnCtrlFcst)==0.)\
356 elif np.any(np.all(rlsFcstPrev == rlsCtrlApplied, axis=1)):
357 rlsFcst = np.copy(rlsCtrlApplied)
358 rlsMaxPrev = np.copy(rlsMax)
362 iAbvTarget = storFcst[:] > self.
storThstorTh
363 iUnCtrl = rlsUnCtrlFcst[:] > 0.
366 rlsMax[iAbvTarget | iUnCtrl] = np.fmax(0., rlsCtrlApplied[iAbvTarget | iUnCtrl] \
367 - (storFcst[iAbvTarget | iUnCtrl] - self.
storThstorTh)*self.
constantsconstants.af2cfs \
368 - rlsUnCtrlFcst[iAbvTarget | iUnCtrl])
370 rlsFcstPrev = np.vstack((rlsFcstPrev, np.copy(rlsCtrlApplied)))
372 rlsMaxPrev = np.copy(rlsMax)
374 return rlsFcst, rlsMaxPrev
377 rlsFcst = np.copy(rlsFcstInit)
378 rlsFcstCheck = np.zeros(len(rlsFcst))
379 iVal = ~np.isnan(rlsFcst) & ~np.isnan(rlsMax)
380 iMaxed = np.full(len(rlsFcst),
False)
382 while any(iMaxed==
False)
and any(rlsFcst[iVal] - rlsFcstCheck[iVal] != 0.):
383 rlsFcstCheck = np.copy(rlsFcst)
384 iGrtrMax = rlsFcst > rlsMax
385 iMaxed = iMaxed | iGrtrMax
386 rlsDiffVol = np.sum(rlsFcst[iGrtrMax] - rlsMax[iGrtrMax])
387 rlsFcst[iGrtrMax] = rlsMax[iGrtrMax]
388 rlsAdd = rlsDiffVol/max(1,np.sum(~iMaxed & iVal))
389 rlsFcst[~iMaxed] += rlsAdd
393 rlsFcst = np.copy(rlsFcstInit)
394 rlsFcstCheck = np.copy(rlsFcst)
396 for i
in range(tsHoriz, 0, -1):
397 rlsFcst[i] += carryOver
398 rlsFcstCheck[i] = rlsFcst[i]
399 if rlsFcst[i] > rlsMax[i]:
400 rlsFcst[i] = rlsMax[i]
402 carryOver += (rlsFcstCheck[i] - rlsFcst[i])/(i-1)
if i > 1
else 0.
412 self.
riskEforiskEfo = np.full((self.T.Tcont.nSteps, self.T.nSteps), 0.)
419 self.
releaserelease[self.T.Tcont.step] = rlsSched[1]
424 def __init__(self, name, ruleEfo, ruleEfo_NoRls, tsArchive=0,
425 fileName='efoFcstResults', tsRlsOvrd=None, saveAllRlsSched=False):
437 self.
releaserelease[self.T.Tcont.step] = rlsSched[1]
439 if self.T.Tcont.step == self.
tsArchivetsArchive:
441 t = self.T.get_fcst_time()
446 rlsToday = np.nanmean(
447 self.
ruleEforuleEfo.rlsFcst[1:int(self.T.fcstFreq/self.T.nHrs)+1, :, :self.
tsRlstsRlstsRls], axis=0).T
448 self.
mbrRlsmbrRls = int(np.where(rlsToday==np.max(rlsToday))[1][0])
451 self.
mbrRlsmbrRls = int(self.
ruleEforuleEfo.mbrRls[self.T.Tcont.step])
487 np.savez(self.
fileNamefileName+
'_'+self.T.Tcont.curDT.strftime(
'%Y-%m-%d-%H'),
490 mbrRls = self.
mbrRlsmbrRls,
def calc_release_fcst(self, rlsProposed, rlsUnCtrl, stor, qIn)
def __subclasshook__(cls, C)
def calc_release(self, rlsProposed, rlsUnCtrl, stor, rlsPrev=None, qIn=None)
def __init__(self, name, timeFcst)
def __init__(self, name, ruleEfo, ruleEfo_NoRls, tsArchive=0, fileName='efoFcstResults', tsRlsOvrd=None, saveAllRlsSched=False)
rlsUnCtrlFcst_NoRls_tsRls
def calc_release_fcst(self, rlsProposed, rlsUnCtrl, stor, qIn=None)
def _calc_release_sched(self, rlsFcst, tsHoriz, ensMbr)
def _get_adjusted_release_eqldist(self, rlsFcstInit, rlsMax)
def calc_release_fcst(self, rlsProposed, rlsUnCtrl, stor, qIn=None)
def __init__(self, name, timeFcst, efoResrvr, storTh, riskTol, constants, *efoNetwork=None, ruleRlsSpecified=None, efoRlsSched=None, maxItr=100, storMax=None, nHrsLead=None)
def _get_adjusted_release_rollback(self, rlsFcstInit, tsHoriz, rlsMax)
def old_calc_release_sched(self, rlsFcst, tsHoriz, ensMbr)
def __init__(self, name, rulePfo, ruleEfoNoRls)
def calc_release_fcst(self, rlsProposed, rlsUnCtrl, stor, qIn=None)
def calc_release_fcst(self, rlsProposed, rlsUnCtrl, stor)
def __init__(self, name, timeFcst, fcstNetwork)