3 Created on Mon May 18 19:48:52 2020
11 from efo.rule
import RuleBase, RuleRlsSpecified
12 from efo.junction
import ReservoirJunction
15 import concurrent.futures
28 self.
releaserelease = np.full(self.T.Tcont.nSteps, np.nan)
31 def calc_release(self, rlsProposed, rlsUnCtrl, stor, rlsPrev=None, qIn=None):
33 rlsProposed, rlsPrev=rlsPrev, rlsUnCtrl=rlsUnCtrl, stor=stor, qIn=qIn)
48 if cls
is RuleFcstBase:
50 if set(cls.__abstractmethods__) <= attrs:
56 def __init__(self, name, timeFcst, efoResrvr, storTh, riskTol, constants, *,
57 efoNetwork=None, ruleRlsSpecified=None, efoRlsSched=None):
80 for net
in self.
efoNetworkefoNetwork: net.set_init_cond()
82 t = self.T.get_fcst_time()
92 for i
in range(t.nSteps-1):
97 self.
rlsMaxrlsMax = np.full((t.nSteps, self.
nMembersnMembers, t.nSteps-1), np.nan)
99 self.
prExcThprExcTh = np.full(t.nSteps, np.nan)
102 riskySelect = np.arange(0, self.
nMembersnMembers, dtype=int)
103 riskyMbr = np.copy(riskySelect)
104 iRisky = np.full(self.
nMembersnMembers,
False)
105 iRiskyChk = np.full(self.
nMembersnMembers,
True)
106 volAbvThresh = np.zeros([t.nSteps, self.
nMembersnMembers])
107 vol2Rls = np.zeros([t.nSteps, self.
nMembersnMembers])
108 rlsFcst = np.full(t.nSteps, np.nan)
109 rlsFcst[0] = self.
efoResrvrefoResrvr[0].rlsCtrl[0]
110 rlsMax = np.full(t.nSteps, np.nan)
111 rlsToday = np.empty((t.nSteps-1, self.
nMembersnMembers))
112 rlsSched = np.zeros(t.nSteps)
113 for tsHoriz
in t.steps[1:]:
114 self.T.step = tsHoriz
116 self.
storFcststorFcst[:, :, tsHoriz-1] = self.
storFcststorFcst[:, :, tsHoriz-2]
118 future2ensMbr = dict()
119 with concurrent.futures.ProcessPoolExecutor(max_workers=6)
as executor:
120 for j
in range(self.
nMembersnMembers):
122 if issubclass(type(self.
ruleRlsSpecifiedruleRlsSpecified[riskySelect[j]]), RuleRlsSpecified):
123 self.
ruleRlsSpecifiedruleRlsSpecified[riskySelect[j]].set_release(tsHoriz, 0)
126 future2ensMbr.update( {executor.submit(self.
efoResrvrefoResrvr[j].calc_qout()): j} )
130 for curFuture
in concurrent.futures.as_completed(future2ensMbr):
131 curMbr = future2ensMbr[curFuture]
132 self.
storFcststorFcst[tsHoriz, riskySelect[curMbr], tsHoriz-1] = self.
efoResrvrefoResrvr[curMbr].stor[tsHoriz]
133 self.
rlsUnCtrlFcstrlsUnCtrlFcst[tsHoriz, riskySelect[curMbr], tsHoriz-1] = \
134 self.
efoResrvrefoResrvr[curMbr].rlsUnCtrl[tsHoriz]
145 storPlusUnCtrl = self.
storFcststorFcst[tsHoriz, :, tsHoriz-1]\
147 iRisky = (storPlusUnCtrl > self.
storThstorTh) & iRiskyChk
151 iRiskyChk = np.copy(iRisky)
153 riskyMbr = np.where(iRisky)[0]
154 nMbrs2Reduce = int(len(riskyMbr) - np.floor(self.
riskTolriskTol[tsHoriz]*self.
nMembersnMembers))
155 volAbvThresh[tsHoriz, riskyMbr] = \
156 self.
storFcststorFcst[tsHoriz, riskyMbr, tsHoriz-1]\
159 mbrSorted = np.argsort(volAbvThresh[tsHoriz, riskyMbr])
160 riskySelect = riskyMbr[mbrSorted[0:nMbrs2Reduce]]
161 self.
iRiskyMbrsiRiskyMbrs[tsHoriz, riskySelect] =
True
166 vol2Rls[tsHoriz, riskySelect] = 1.01*volAbvThresh[tsHoriz, riskySelect]
168 for j
in range(len(riskySelect)):
169 rlsFcst[1:tsHoriz+1] = np.sum(
170 vol2Rls[:, riskySelect[j]])*self.
constantsconstants.af2cfs/tsHoriz
171 self.
rlsNoConstraintrlsNoConstraint[1:tsHoriz+1, riskySelect[j], tsHoriz-1] = np.copy(rlsFcst[1:tsHoriz+1])
173 rlsFcst[1:tsHoriz+1], tsHoriz, riskySelect[j])
174 self.
rlsMaxrlsMax[1:tsHoriz+1, riskySelect[j], tsHoriz-1] = np.copy(rlsMax[1:tsHoriz+1])
175 if np.sum(rlsFcst[1:tsHoriz+1])*self.
constantsconstants.cfs2af < np.sum(vol2Rls[:, riskySelect[j]]):
176 iRiskyChk[riskySelect[j]] =
False
177 vol2Rls[tsHoriz, riskySelect[j]] = \
178 vol2Rls[tsHoriz, riskySelect[j]] - \
179 (np.sum(vol2Rls[:, riskySelect[j]]) - np.sum(rlsFcst[1:tsHoriz+1])*self.
constantsconstants.cfs2af)
180 self.
rlsFcstrlsFcst[1:tsHoriz+1, riskySelect[j], tsHoriz-1] = np.copy(rlsFcst[1:tsHoriz+1])
187 riskySelect = np.arange(0, self.
nMembersnMembers, dtype=int)
188 riskyMbr = np.copy(riskySelect)
189 iRiskyChk = np.full(self.
nMembersnMembers,
True)
191 rlsToday[:, :] = self.
rlsFcstrlsFcst[1, :, :].T
192 if np.any(rlsToday[:] > 0):
195 tsMax, mbrMax = np.where(rlsToday==np.max(rlsToday))
197 self.
releaserelease[self.T.Tcont.step] = self.
rlsFcstrlsFcst[1, mbrMax[0], tsMax[0]]
198 rlsSched = self.
rlsFcstrlsFcst[:, mbrMax[0], tsMax[0]]
201 self.
releaserelease[self.T.Tcont.step] = 0
206 rlsTot = np.nansum(rlsFcst)
210 rlsMax = self.
efoResrvrefoResrvr[ensMbr].rlsMax[1:tsHoriz+1]
211 rlsApplied = self.
efoResrvrefoResrvr[ensMbr].rlsCtrl[1:tsHoriz+1]
212 rlsMaxPrev = np.zeros(len(rlsMax))
213 rlsFcstInit = np.copy(rlsFcst)
217 for i
in range(1, tsHoriz+1):
218 if issubclass(type(self.
efoResrvrefoResrvr[ensMbr]), ReservoirJunction):
220 if issubclass(type(self.
ruleRlsSpecifiedruleRlsSpecified[ensMbr]), RuleRlsSpecified):
221 self.
ruleRlsSpecifiedruleRlsSpecified[ensMbr].set_release(i, np.copy(rlsFcst[i-1]))
224 self.
efoNetworkefoNetwork[ensMbr].process_fcst_junctions()
225 self.
storFcststorFcst[i, ensMbr, tsHoriz-1] = np.copy(self.
efoResrvrefoResrvr[ensMbr].stor[i])
228 if rlsTot - np.sum(rlsApplied) < pctConvg*rlsTot\
229 or np.all(np.absolute(rlsMaxPrev - rlsMax) < 0.01)
or curItr > maxItr:
233 rlsMaxPrev = np.copy(rlsMax)
235 return rlsFcst, np.copy(rlsMax)
238 rlsFcst = np.copy(rlsFcstInit)
239 rlsFcstCheck = np.zeros(len(rlsFcst))
240 iVal = ~np.isnan(rlsFcst) & ~np.isnan(rlsMax)
241 iMaxed = np.full(len(rlsFcst),
False)
244 while any(iMaxed[1:]==
False)
and any(rlsFcst[iVal] - rlsFcstCheck[iVal] != 0):
245 rlsFcstCheck = np.copy(rlsFcst)
246 iGrtrMax = rlsFcst > rlsMax
247 iMaxed = iMaxed | iGrtrMax
248 rlsDiffVol = np.sum(rlsFcst[iGrtrMax] - rlsMax[iGrtrMax])
249 rlsFcst[iGrtrMax] = rlsMax[iGrtrMax]
250 rlsAdd = rlsDiffVol/max(1,np.sum(~iMaxed & iVal))
251 rlsFcst[~iMaxed] += rlsAdd
255 rlsFcst = np.copy(rlsFcstInit)
256 rlsFcstCheck = np.copy(rlsFcst)
258 for i
in range(tsHoriz, 0, -1):
259 rlsFcst[i] += carryOver
260 rlsFcstCheck[i] = rlsFcst[i]
261 if rlsFcst[i] > rlsMax[i]:
262 rlsFcst[i] = rlsMax[i]
264 carryOver += (rlsFcstCheck[i] - rlsFcst[i])/(i-1)
if i > 1
else 0
274 rlsTot = np.nansum(rlsFcst)
278 rlsMax = self.efoResrvr[ensMbr].rlsMax[1:tsHoriz+1]
279 rlsApplied = self.efoResrvr[ensMbr].rlsCtrl[1:tsHoriz+1]
280 rlsMaxPrev = np.zeros(len(rlsMax))
281 rlsFcstInit = np.copy(rlsFcst)
285 for i
in range(1, tsHoriz+1):
286 if issubclass(type(self.efoResrvr[ensMbr]), ReservoirJunction):
288 if issubclass(type(self.ruleRlsSpecified[ensMbr]), RuleRlsSpecified):
289 self.ruleRlsSpecified[ensMbr].set_release(i, np.copy(rlsFcst[i-1]))
292 self.efoNetwork[ensMbr].process_fcst_junctions()
293 self.storFcst[i, ensMbr, tsHoriz-1] = np.copy(self.efoResrvr[ensMbr].stor[i])
296 if rlsTot - np.sum(rlsApplied) < pctConvg*rlsTot\
297 or np.all(np.absolute(rlsMaxPrev - rlsMax) < 0.01)
or curItr > maxItr:
300 rlsFcst = self._get_adjusted_release_eqldist(rlsFcstInit, rlsMax)
301 rlsMaxPrev = np.copy(rlsMax)
303 return rlsFcst, np.copy(rlsMax)
306 rlsFcst = np.copy(rlsFcstInit)
307 rlsFcstCheck = np.zeros(len(rlsFcst))
308 iVal = ~np.isnan(rlsFcst) & ~np.isnan(rlsMax)
309 iMaxed = np.full(len(rlsFcst),
False)
312 while any(iMaxed[1:]==
False)
and any(rlsFcst[iVal] - rlsFcstCheck[iVal] != 0):
313 rlsFcstCheck = np.copy(rlsFcst)
314 iGrtrMax = rlsFcst > rlsMax
315 iMaxed = iMaxed | iGrtrMax
316 rlsDiffVol = np.sum(rlsFcst[iGrtrMax] - rlsMax[iGrtrMax])
317 rlsFcst[iGrtrMax] = rlsMax[iGrtrMax]
318 rlsAdd = rlsDiffVol/max(1,np.sum(~iMaxed & iVal))
319 rlsFcst[~iMaxed] += rlsAdd
329 self.
riskEforiskEfo = np.full((self.T.Tcont.nSteps, self.T.nSteps), 0.)
336 self.
releaserelease[self.T.Tcont.step] = rlsSched[1]
def _get_adjusted_release_eqldist(self, rlsFcstInit, rlsMax)
def _calc_release_sched(self, rlsFcst, tsHoriz, ensMbr)
def __init__(self, name, timeFcst)
def __subclasshook__(cls, C)
def calc_release_fcst(self, rlsProposed, rlsUnCtrl, stor, qIn)
def calc_release(self, rlsProposed, rlsUnCtrl, stor, rlsPrev=None, qIn=None)
def _get_adjusted_release_rollback(self, rlsFcstInit, tsHoriz, rlsMax)
def __init__(self, name, timeFcst, efoResrvr, storTh, riskTol, constants, *efoNetwork=None, ruleRlsSpecified=None, efoRlsSched=None)
def _calc_release_sched(self, rlsFcst, tsHoriz, ensMbr)
def calc_release_fcst(self, rlsProposed, rlsUnCtrl, stor, qIn=None)
def _get_adjusted_release_eqldist(self, rlsFcstInit, rlsMax)
def calc_release_fcst(self, rlsProposed, rlsUnCtrl, stor, qIn=None)
def __init__(self, name, rulePfo, ruleEfoNoRls)
def __init__(self, name, timeFcst, fcstNetwork)
def calc_release_fcst(self, rlsProposed, rlsUnCtrl, stor)