# RiverWare_Ruleset 6.7 Development
# Created 13:28 March 20, 2015
#
RULESET
AGENDA_ORDER DESCENDING;
DESCRIPTION "For use with Lite1.12.mdl.gz or higher
2008-2025 Basin States' Proposal
Shortage - Step Short Original
Powell - BS6.v2 with the Upper Equalization line in place of the 602a storage
Surplus - No Partial Domestic (7 State Plan Level 3). Only Quantified (7 State Plan Level 1) and Domestic (7 State Plan Leve 2). From 2017-2025 CAP gets a Domestic surplus. Domestic surplus schedules from 2017-2025 reflect the States' Proposal (7 State Plan Surplus Schedules.xxx Level 2).
2006,2007,2026-2060
Shortage - 80P1050 AbsPro1000
Powell - Normal
Surplus - None (2006) ISG (2007) 70R (2026-2060)
";
PRECISION 8;
BEGIN
POLICY_GROUP "Mead & Powell Rules";
DESCRIPTION "";
ACTIVE TRUE;
BEGIN
RULE "Set Powell Minimum Content";
DESCRIPTION "";
ACTIVE FALSE;
RULE_EXEC_CONSTRAINT TRUE;
BEGIN
$ "PowellData.MinimumContent" [] := IF ( @"t" > @"24:00:00 December 31, 2025" OR @"t" < @"24:00:00 December 31, 2008" )
THEN
0.00000000 "acre-ft"
ELSE
0.00000000 "acre-ft" COMMENTED_BY "If 2008-2025 don't protect minimum power pool"
ENDIF;
END;
RULE "602a Storage";
DESCRIPTION "This rule computes the 602a Storage which is used in Equalization. It is
set to execute once per timestep, only when the value is NaN or hasn't
yet been set. ";
ACTIVE TRUE;
RULE_EXEC_CONSTRAINT IsNaN $ "EqualizationData.value602a" [];
BEGIN
$ "EqualizationData.value602a" [] := "602aStorage"( );
END;
RULE "Assurance Level Surplus Volume";
DESCRIPTION "This rule is executed once per timestep and computes a surplus volume which
is used to determine whether or not an Assurance Level Surplus, 7 State Level Plan 1 or 7 State Plan Level 2 surplus will go into effect. The surplus volume (SurplusRelease) is the volume of water in excess of the system space requirement. If this volume if greater than zero, and the current year is greater than or equal to 2017, an Assurance Level Surplus is declared.
The surplus volume indicates the volume of water in excess of the system space requirement at the end of the year. It is computed by first taking the sum of Mead and Powell's content at the beginning of the year and subtracting the max combined storage of Mead and Powell that will meet the system space requirement at the beginning of the year. It is assumed the 30% of the requirement will be met by the UB reservoirs above Powell. Next, this is multiplied by the average of Mead and Powell's bank storage coefficients. An assumed percentile runoff is added and both the scheduled UB demand (evaporation and depletions) and scheduled LB demand (evaporation and depletions) are subtracted.
";
ACTIVE TRUE;
RULE_EXEC_CONSTRAINT TRUE;
BEGIN
$ "Surplus.SurplusRelease" [] := ( $ "Powell.Storage" [@"t - 1"] + $ "Mead.Storage" [@"t - 1"] - "SurplusMaxStorage"( ) ) * ( 1.00000000 + ( $ "Mead.Bank Storage Coefficient" [0.00000000, 0.00000000] + $ "Powell.Bank Storage Coefficient" [0.00000000, 0.00000000] ) / 2.00000000 ) + "ComputeInflowAtProbability"( ) - "SumUBDemands"( ) - "SumLBDemands"( );
END;
RULE "Initialize Random Deviation";
DESCRIPTION "Executed only at the beginning of the run. The purpose of this rule is to initialize the random number generator, RanDev(), used to compute Powell's forecast error. The initialization is done through the calling of ResetRanDev(). Initializing RanDev() specifies from which line in the random number file the first random number is to be retrieved. This line corresponds to the first hydrology year, 1906, which is what SetRewindYear() returns. Initializing RanDev() with a different year will result in a different set of random numbers. Note that this will never assign a value to Dummy.RandomDeviation but will always call ResetRanDev(). ";
ACTIVE TRUE;
RULE_EXEC_CONSTRAINT @"t" == @"Start Timestep";
BEGIN
$ "Powell Forecast Data.DummyRandomDeviation" [] := IF ( NOT "ResetRanDev"( TRUE, "SetRewindYear"( ) ) )
THEN
STOP_RUN "ResetRanDev failed"
ENDIF;
END;
RULE "Powell Forecast Error";
DESCRIPTION "This rule is executed once per timestep and stores each month's forecast error in a slot on a data object, after multiplying it by 1.0 MAF. The function ConstructPowellForecastErrorList() steps through the months calling the function ComputePowellForecastError() and constructs a list of the 12 monthly forecast errors.
The forecast error is applied to the spring (Jan -July) inflow forecast for Powell. In Aug - Dec, the forecast error is set to zero. The error is the sum of a random and deterministic component. The June forecast error is constrained to not exceed half of the forecast error for May. The forecast error for July is set to 25% of June's error.";
ACTIVE TRUE;
RULE_EXEC_CONSTRAINT TRUE;
BEGIN
FOREACH (DATETIME date IN "JanuaryToDecember"( )) DO
$ "Powell Forecast Data.ForecastError" [date] := ( GET @INDEX "GetMonth"( date ) FROM "ConstructPowellForecastErrorList"( ) );
ENDFOREACH;
END;
RULE "Powell Spring Runoff Forecast";
DESCRIPTION "This rule is executed once per timestep and stores the runoff forecast for the spring month's in a slot on a data object. The function ConstructSpringRunoffForecastList() steps through the months calling the function ComputePowellSpringRunoffForecast() and constructs a list of the spring's runoff forecasts.
The runoff forecast is computed by adding the forecast error (computed in Rule 4) to Powell's regulated inflow. It is used in Operations to compute Powell's spring outflow volume and in Equalization to forecast Powell's inflow and July's storage.
";
ACTIVE TRUE;
RULE_EXEC_CONSTRAINT TRUE;
BEGIN
FOREACH (DATETIME date IN "JanuaryToJuly"( )) DO
$ "Powell Forecast Data.Reg Inflow with Error" [date] := GET @INDEX ( "GetMonth"( date ) - 1.00000000 ) FROM "ConstructSpringRunoffForecastList"( );
ENDFOREACH;
END;
RULE "Powell Inflow Forecast";
DESCRIPTION "This rule executes once per timestep and computes the inflow forecast for Powell from January through September. The monthly forecasted inflow is stored in a slot on a data object. The function ForecastPowellInfow() steps through the months, constructs a list with the monthly inflow forecasts, and returns that list. Powell's inflow forecast is used in Equalization to compute its EOWY Storage.";
ACTIVE TRUE;
RULE_EXEC_CONSTRAINT TRUE;
BEGIN
FOREACH (DATETIME date IN "JanuaryToSeptember"( )) DO
$ "EqualizationData.PowellInflowForecast" [date] := GET @INDEX ( "GetMonth"( date ) - 1.00000000 ) FROM "ForecastPowellInflow"( );
ENDFOREACH;
END;
RULE "Compute Powell & Mead Storage";
DESCRIPTION "This rule is executed once per timestep and only when the following conditions are met: The annual adjusted demand schedules for SNWP, MWD, CAP, Coachella, IID and Mexico have been set and the Flood Control Surplus Flag has not been set. The Flood Control Surplus Flag must be NaN because this rule should not re-fire if the above schedules are set to their Flood Control Surplus schedules in the event of a flood control release from Mead. The schedules used in the rule are adjusted internally if a flood control release is made.
This rule calls the function ComputePowellAndMeadStorages() which returns a list of 12 monthly storages for Mead and Powell, a boolean indicating whether or not a Spike Flow release was made, an integer representing the first month in which a flood control release was made (if any), and an integer indicating which policy resulted in computation of Powell's storage. The Spike Flow boolean is not stored because it is possible to tell whether a Spike Flow release was made from the month's corresponding Policy Flag. All the other elements of the list are stored in slots. The monthly Powell and Mead storages are stored on the corresponding reservoir objects. The Flood Control Release Month Index is used to determine whether or not the above schedules need to be adjusted to surplus, from the index to the end of the year. This happens in Rule 9 (Set Mead Storage & Flood Control Surplus), which fires if the Flood Control Release Month Index is non-zero.";
ACTIVE TRUE;
RULE_EXEC_CONSTRAINT NOT IsNaN $ "SNWPDiversion.Total Depletion Requested" [] AND NOT IsNaN $ "MWDDiversion.Total Depletion Requested" [] AND NOT IsNaN $ "CAPDiversion.Total Depletion Requested" [] AND NOT IsNaN $ "CoachellaDiversion.Total Depletion Requested" [] AND NOT IsNaN $ "IIDDiversion.Total Depletion Requested" [] AND NOT IsNaN $ "MexicoDiversion.Total Depletion Requested" [] AND IsNaN $ "Surplus.Flood Control Surplus Flag" [] AND @"t" > @"24:00:00 December 31, 2026";
BEGIN
FOREACH (DATETIME date IN "JanuaryToDecember"( )) DO
FOREACH (LIST storages IN { "ComputePowellAndMeadStorages"( ) }) DO
$ "Powell.Monthly Storage" [date] := "GetListElement"( ( "GetMonth"( date ) * 3.00000000 ) + 1.00000000, storages );
$ "Mead.Monthly Storage" [date] := "GetListElement"( ( "GetMonth"( date ) * 3.00000000 ) + 3.00000000, storages );
$ "MeadFloodControl.Flood Control Release Month Index" [] := IF ( date == @"24:00:00 December 31, Current Year" )
THEN
"GetListElement"( 0.00000000, storages )
ENDIF;
$ "PowellData.PolicyFlag" [date] := "GetListElement"( ( "GetMonth"( date ) * 3.00000000 ) + 2.00000000, storages );
ENDFOREACH;
ENDFOREACH;
END;
RULE "Compute Powell & Mead Storage Hybrid";
DESCRIPTION "This rule is executed once per timestep and only when the following conditions are met: The annual adjusted demand schedules for SNWP, MWD, CAP, Coachella, IID and Mexico have been set and the Flood Control Surplus Flag has not been set. The Flood Control Surplus Flag must be NaN because this rule should not re-fire if the above schedules are set to their Flood Control Surplus schedules in the event of a flood control release from Mead. The schedules used in the rule are adjusted internally if a flood control release is made.
This rule calls the function ComputePowellAndMeadStorages() which returns a list of 12 monthly storages for Mead and Powell, a boolean indicating whether or not a Spike Flow release was made, an integer representing the first month in which a flood control release was made (if any), and an integer indicating which policy resulted in computation of Powell's storage. The Spike Flow boolean is not stored because it is possible to tell whether a Spike Flow release was made from the month's corresponding Policy Flag. All the other elements of the list are stored in slots. The monthly Powell and Mead storages are stored on the corresponding reservoir objects. The Flood Control Release Month Index is used to determine whether or not the above schedules need to be adjusted to surplus, from the index to the end of the year. This happens in Rule 9 (Set Mead Storage & Flood Control Surplus), which fires if the Flood Control Release Month Index is non-zero.";
ACTIVE TRUE;
RULE_EXEC_CONSTRAINT NOT IsNaN $ "SNWPDiversion.Total Depletion Requested" [] AND NOT IsNaN $ "MWDDiversion.Total Depletion Requested" [] AND NOT IsNaN $ "CAPDiversion.Total Depletion Requested" [] AND NOT IsNaN $ "CoachellaDiversion.Total Depletion Requested" [] AND NOT IsNaN $ "IIDDiversion.Total Depletion Requested" [] AND NOT IsNaN $ "MexicoDiversion.Total Depletion Requested" [] AND IsNaN $ "Surplus.Flood Control Surplus Flag" [] AND @"t" <= @"24:00:00 December 31, 2026";
BEGIN
FOREACH (DATETIME date IN "JanuaryToDecember"( )) DO
FOREACH (LIST storages IN { "ComputePowellAndMeadStoragesDD1"( ) }) DO
$ "Powell.Monthly Storage" [date] := "GetListElement"( ( "GetMonth"( date ) * 3.00000000 ) + 1.00000000, storages );
$ "Mead.Monthly Storage" [date] := "GetListElement"( ( "GetMonth"( date ) * 3.00000000 ) + 3.00000000, storages );
$ "MeadFloodControl.Flood Control Release Month Index" [] := IF ( date == @"24:00:00 December 31, Current Year" )
THEN
"GetListElement"( 0.00000000, storages )
ENDIF;
$ "PowellData.PolicyFlag" [date] := "GetListElement"( ( "GetMonth"( date ) * 3.00000000 ) + 2.00000000, storages );
ENDFOREACH;
ENDFOREACH;
END;
RULE "Set Powell Storage";
DESCRIPTION "This rule is executed once per timestep and sets Powell's end of the year storage to the end of the year storage that was solved in the previous rule (Compute Powell & Mead Storages). This rule assumes that the previous rule was effective in computing and setting all Powell and Mead's monthly storages. ";
ACTIVE TRUE;
RULE_EXEC_CONSTRAINT TRUE;
BEGIN
$ "Powell.Storage" [@"t"] := $ "Powell.Monthly Storage" [@"24:00:00 December 31, Current Year"];
END;
RULE "Set Mead Storage & Flood Control Surplus";
DESCRIPTION "This rule is executed only when the Flood Control Release Month Index is non-zero, meaning a flood control release was made during the year. If this rule fires, the result will be the setting of Mead's end of the year storage to the end of the year storage that was solved in Rule 7 Compute Powell & Mead Storages. Because a flood control release was made during the year, the demand schedules for MWD, CAP, SNWP, IID, Coachella and Mexico are set to their flood control surplus schedules from the month of the first flood control release through the end of the year. Two Surplus flags are also set to indicate that a surplus was in effect for the year and that it was a result of Mead's flood control operations. This rules assumes that Rule 7 Compute Powell & Mead Storage was effective in computing and setting all Powell and Mead's monthly storages.";
ACTIVE TRUE;
RULE_EXEC_CONSTRAINT $ "MeadFloodControl.Flood Control Release Month Index" [] != 0.00000000;
BEGIN
$ "Mead.Storage" [@"t"] := $ "Mead.Monthly Storage" [@"24:00:00 December 31, Current Year"];
FOREACH (STRING diversion IN { "MWD" , "CAP" , "SNWP" , "IID" , "Coachella" , "Mexico" }) DO
diversion CONCAT "Diversion.Total Diversion Requested" [] := "VolumeToFlow"( "ComputeFCSurplusDiversion"( diversion ), @"t" );
diversion CONCAT "Diversion.Total Depletion Requested" [] := "VolumeToFlow"( "ComputeFCSurplusDepletion"( diversion ), @"t" );
ENDFOREACH;
$ "Surplus.Flood Control Surplus Flag" [] := 1.00000000;
$ "Surplus.Surplus Flag" [] := 1.00000000;
END;
RULE "Set Mead Storage";
DESCRIPTION "This rule is executed only when the Flood Control Release Month Index is zero, meaning a flood control release was NOT made during the year. In this event, Mead's end of the year storage is set to the end of the year storage that was computed in Rule 7 Compute Powell & Mead Storages. No changes are made to downstream demands. This rule assumes that Rule 7 was effective in computing and setting all Powell and Mead's monthly storages.";
ACTIVE TRUE;
RULE_EXEC_CONSTRAINT $ "MeadFloodControl.Flood Control Release Month Index" [] == 0.00000000;
BEGIN
$ "Mead.Storage" [@"t"] := $ "Mead.Monthly Storage" [@"24:00:00 December 31, Current Year"];
END;
END;
POLICY_GROUP "Phil Test";
DESCRIPTION "";
ACTIVE TRUE;
BEGIN
RULE "TestTwo";
DESCRIPTION "";
ACTIVE TRUE;
RULE_EXEC_CONSTRAINT TRUE;
BEGIN
PRINT "TESTING ToCelcius";
PRINT "ToCelcius"( 63.23000000 "F" );
PRINT "ToCelsius"( 63.23000000 "F" );
PRINT "NetSubBasinDiversionRequirement"( { % "BelowImperialDamColoradoR:RRArizonaPumpers" }, @"t" );
PRINT "NetSubbasinDiversionRequirement"( { % "BelowImperialDamColoradoR:RRArizonaPumpers" }, @"t" );
PRINT "SolveSubBasinDiversions"( { % "BelowImperialDamColoradoR:RRArizonaPumpers" }, @"t" );
PRINT "SolveSubbasinDiversions"( { % "BelowImperialDamColoradoR:RRArizonaPumpers" }, @"t" );
END;
END;
POLICY_GROUP "Shortage Schedule Rules";
DESCRIPTION "";
ACTIVE TRUE;
BEGIN
RULE "AbsPro Only";
DESCRIPTION "If this rule is turned on, then no other shortage rules should be turned on.
This rule is executed once per timestep in the event that the reduction of depletions is needed such that Mead will stay at a minimum elevation defined in Shortage.Level 2 Shortage Trigger, currently set to 1000 ft (the minimum level for operation of SNWA's lower diversion intake). The need for these reductions is determined by checking to see that the current amount of water available for CAP and SNWP in ComputeWaterAvailabeForCAPandSNWP() is enough to meet their demands with a Level 1 Shortage imposed. If the current amount of available water is not sufficient, a Level 2 Shortage is imposed. If after CAP and SNWP take a full shortage the available water is still not enough to protect the shortage elevation, MWD and Mexico receive a shortage. MWD and Mexico are both reduced by half the remaining shortage.
Also, the Level 2 Shortage Flag is set on the Shortage data object and a flag is set on the MeadFloodControl computational subbasin. The purpose of setting the Surplus Schedule Percent flag is to indicate that the same monthly percents used to disaggregate CAP and SNWP's annual surplus schedules should be used to disaggregate their schedules if set by a Level 2 Shortage. ";
ACTIVE FALSE;
RULE_EXEC_CONSTRAINT "ComputeWaterAvailableForCAPandSNWP"( ) < "ComputeCAP&SNWPNormalDepletionVol"( ) AND @"t" > @"24:00:00 December 31, 2016";
BEGIN
FOREACH (STRING diversion IN { "CAP" , "SNWP" , "MWD" , "Mexico" }) DO
diversion CONCAT "Diversion.Total Diversion Requested" [] := "VolumeToFlow"( "ComputeLevel2ShortageDiversion"( diversion ), @"t" );
diversion CONCAT "Diversion.Total Depletion Requested" [] := "VolumeToFlow"( "ComputeLevel2ShortageDepletion"( diversion ), @"t" );
ENDFOREACH;
$ "Shortage.Level 2 Shortage Flag" [] := 1.00000000;
$ "MeadFloodControl.Surplus Schedule Percent" [] := 1.00000000;
$ "Shortage.Shortage Flag" [] := 1.00000000;
$ "Shortage.AbsPro Only Shortage Flag" [] := 1.00000000;
END;
RULE "Step 4 Shortage for SNWA ";
DESCRIPTION "Sets SNWA to 0.0 acre-ft if downstream deliveries and SNWA requested depletion will cause Mead to drop below 1000 ft. This is the only Shortage rule activated for running the "No Protect" scenario.";
ACTIVE TRUE;
RULE_EXEC_CONSTRAINT "ComputeWaterAvailableForSNWP"( ) < ( $ "SNWP Schedule.AnnualNormalDepletionSchedule" [] - "SNWPStep3ShortageAmount"( ) ) AND @"t" <= @"24:00:00 December 31, 2026";
BEGIN
FOREACH (STRING diversion IN { "CAP" , "SNWP" , "Mexico" }) DO
diversion CONCAT "Diversion.Total Diversion Requested" [] := "VolumeToFlow"( "ComputeTier4DiversionSNWAcut"( diversion ), @"t" );
diversion CONCAT "Diversion.Total Depletion Requested" [] := "VolumeToFlow"( "ComputeTier4DepletionSNWAcut"( diversion ), @"t" );
ENDFOREACH;
$ "Shortage.80P1050 Shortage Flag" [] := 1.00000000;
$ "MeadFloodControl.Shortage Schedule Percent" [] := 1.00000000;
$ "Shortage.Shortage Flag" [] := 1.00000000;
END;
RULE "AbsPro with 80P(1050) Shortage";
DESCRIPTION "If this rule is turned on, a lower level shortage rule must also be turned on. The lower level shortage rule must impose shortages in the same manner as the 80P1050(83) Shortages rules do.
This rule is executed once per timestep in the event that the reduction of depletions is needed such that Mead will stay at a minimum elevation defined in Shortage.Level 2 Shortage Trigger, currently set to 1000 ft (the minimum level for operation of SNWA's lower diversion intake). The need for these reductions is determined by checking to see that the current amount of water available for CAP and SNWP in ComputeWaterAvailabeForCAPandSNWP() is enough to meet their demands with a Level 1 Shortage imposed. If the current amount of available water is not sufficient, an additional shortage is imposed. If after CAP and SNWP take a full shortage the available water is still not enough to protect the shortage elevation, MWD and Mexico receive a shortage. MWD and Mexico are both reduced by half the remaining shortage.
Also, the Level 2 Shortage Flag is set on the Shortage data object and a flag is set on the MeadFloodControl computational subbasin. The purpose of setting the Surplus Schedule Percent flag is to indicate that the same monthly percents used to disaggregate CAP and SNWP's annual surplus schedules should be used to disaggregate their schedules if set by a Level 2 Shortage. ";
ACTIVE TRUE;
RULE_EXEC_CONSTRAINT "ComputeWaterAvailableCAP&SNWP&Mexico"( ) < "ComputeCAP&SNWP&MexicoLevel1ShortageDepletionVol"( ) AND @"t" > @"24:00:00 December 31, 2026";
BEGIN
FOREACH (STRING diversion IN { "CAP" , "SNWP" , "MWD" , "Mexico" }) DO
diversion CONCAT "Diversion.Total Diversion Requested" [] := "VolumeToFlow"( "ComputeLevel2ShortageDiversion"( diversion ), @"t" );
diversion CONCAT "Diversion.Total Depletion Requested" [] := "VolumeToFlow"( "ComputeLevel2ShortageDepletion"( diversion ), @"t" );
ENDFOREACH;
$ "Shortage.Level 2 Shortage Flag" [] := 1.00000000;
$ "MeadFloodControl.Surplus Schedule Percent" [] := 1.00000000;
$ "Shortage.Shortage Flag" [] := 1.00000000;
$ "Shortage.AbsPro 80P1050 Shortage Flag" [] := 1.00000000;
END;
RULE "AbsPro with Step Shortage";
DESCRIPTION "If this rule is turned on, the Step 3 Shortage rule must also be turned on.
This rule is executed once per timestep in the event that the reduction of depletions is needed such that Mead will stay at a minimum elevation defined in Shortage.Level 2 Shortage Trigger, currently set to 1000 ft (the minimum level for operation of SNWA's lower diversion intake). The need for these reductions is determined by checking to see that the current amount of water available for CAP and SNWP in ComputeWaterAvailabeForCAPandSNWP() is enough to meet their demands with a Step 3 Shortage is imposed. If the current amount of available water is not sufficient, additional shortage is imposed. If after CAP and SNWP take a full shortage the available water is still not enough to protect the shortage elevation, MWD and Mexico receive a shortage. MWD and Mexico are both reduced by half the remaining shortage.
Also, the Level 2 Shortage Flag is set on the Shortage data object and a flag is set on the MeadFloodControl computational subbasin. The purpose of setting the Surplus Schedule Percent flag is to indicate that the same monthly percents used to disaggregate CAP and SNWP's annual surplus schedules should be used to disaggregate their schedules if set by a Level 2 Shortage. ";
ACTIVE FALSE;
RULE_EXEC_CONSTRAINT "ComputeWaterAvailableForCAPandSNWP"( ) < "ComputeTier3Depletion"( "CAP" );
BEGIN
FOREACH (STRING diversion IN { "CAP" , "SNWP" , "MWD" , "Mexico" }) DO
diversion CONCAT "Diversion.Total Diversion Requested" [] := "VolumeToFlow"( "ComputeLevel2ShortageDiversion"( diversion ), @"t" );
diversion CONCAT "Diversion.Total Depletion Requested" [] := "VolumeToFlow"( "ComputeLevel2ShortageDepletion"( diversion ), @"t" );
ENDFOREACH;
$ "Shortage.Level 2 Shortage Flag" [] := 1.00000000;
$ "MeadFloodControl.Surplus Schedule Percent" [] := 1.00000000;
$ "Shortage.Shortage Flag" [] := 1.00000000;
$ "Shortage.AbsPro Step Shortage Flag" [] := 1.00000000;
END;
RULE "Step 3 Shortage";
DESCRIPTION "";
ACTIVE TRUE;
RULE_EXEC_CONSTRAINT $ "Mead.Pool Elevation" [@"t - 1"] < $ "Shortage.Step Shortage Mead Tier" [0.00000000, 0.00000000] AND @"t" <= @"24:00:00 December 31, 2026";
BEGIN
FOREACH (STRING diversion IN { "CAP" , "SNWP" , "Mexico" }) DO
diversion CONCAT "Diversion.Total Diversion Requested" [] := "VolumeToFlow"( "ComputeTier3Diversion"( diversion ), @"t" );
diversion CONCAT "Diversion.Total Depletion Requested" [] := "VolumeToFlow"( "ComputeTier3Depletion"( diversion ), @"t" );
$ "Shortage.Shortage Flag" [] := 1.00000000;
ENDFOREACH;
$ "Shortage.Step 3 Shortage Flag" [] := 1.00000000;
END;
RULE "Step 2 Shortage";
DESCRIPTION "";
ACTIVE TRUE;
RULE_EXEC_CONSTRAINT $ "Mead.Pool Elevation" [@"t - 1"] < $ "Shortage.Step Shortage Mead Tier" [1.00000000, 0.00000000] AND $ "Mead.Pool Elevation" [@"t - 1"] >= $ "Shortage.Step Shortage Mead Tier" [0.00000000, 0.00000000] AND @"t" <= @"24:00:00 December 31, 2026";
BEGIN
FOREACH (STRING diversion IN { "CAP" , "SNWP" , "Mexico" }) DO
diversion CONCAT "Diversion.Total Diversion Requested" [] := "VolumeToFlow"( "ComputeTier2Diversion"( diversion ), @"t" );
diversion CONCAT "Diversion.Total Depletion Requested" [] := "VolumeToFlow"( "ComputeTier2Depletion"( diversion ), @"t" );
ENDFOREACH;
$ "Shortage.Shortage Flag" [] := 1.00000000;
$ "Shortage.Step 2 Shortage Flag" [] := 1.00000000;
END;
RULE "Step 1 Shortage";
DESCRIPTION "";
ACTIVE TRUE;
RULE_EXEC_CONSTRAINT $ "Mead.Pool Elevation" [@"t - 1"] < $ "Shortage.Step Shortage Mead Tier" [2.00000000, 0.00000000] AND $ "Mead.Pool Elevation" [@"t - 1"] >= $ "Shortage.Step Shortage Mead Tier" [1.00000000, 0.00000000] AND @"t" <= @"24:00:00 December 31, 2026";
BEGIN
FOREACH (STRING diversion IN { "CAP" , "SNWP" , "Mexico" }) DO
diversion CONCAT "Diversion.Total Diversion Requested" [] := "VolumeToFlow"( "ComputeTier1Diversion"( diversion ), @"t" );
diversion CONCAT "Diversion.Total Depletion Requested" [] := "VolumeToFlow"( "ComputeTier1Depletion"( diversion ), @"t" );
ENDFOREACH;
$ "Shortage.Step 1 Shortage Flag" [] := 1.00000000;
$ "Shortage.Shortage Flag" [] := 1.00000000;
END;
RULE "80P1050 Shortage";
DESCRIPTION "";
ACTIVE TRUE;
RULE_EXEC_CONSTRAINT $ "Mead.Pool Elevation" [@"t - 1"] < $ "Shortage.Mead Trigger 80P1050" [@"t - 1"] AND @"t" > @"24:00:00 December 31, 2026";
BEGIN
FOREACH (STRING diversion IN { "CAP" , "SNWP" , "Mexico" }) DO
diversion CONCAT "Diversion.Total Diversion Requested" [] := "VolumeToFlow"( "ComputeShortageDiversion"( diversion ), @"t" );
diversion CONCAT "Diversion.Total Depletion Requested" [] := "VolumeToFlow"( "ComputeShortageDepletion"( diversion ), @"t" );
ENDFOREACH;
$ "Shortage.80P1050 Shortage Flag" [] := 1.00000000;
$ "MeadFloodControl.Shortage Schedule Percent" [] := 1.00000000;
$ "Shortage.Shortage Flag" [] := 1.00000000;
END;
RULE "80P1083 Shortage";
DESCRIPTION "";
ACTIVE FALSE;
RULE_EXEC_CONSTRAINT $ "Mead.Pool Elevation" [@"t - 1"] < $ "Shortage.Mead Trigger 80P1083" [@"t - 1"] AND @"t" > @"24:00:00 December 31, 2016";
BEGIN
FOREACH (STRING diversion IN { "CAP" , "SNWP" }) DO
diversion CONCAT "Diversion.Total Diversion Requested" [] := "VolumeToFlow"( "ComputeShortageDiversion"( diversion ), @"t" );
diversion CONCAT "Diversion.Total Depletion Requested" [] := "VolumeToFlow"( "ComputeShortageDepletion"( diversion ), @"t" );
ENDFOREACH;
$ "Shortage.80P1083 Shortage Flag" [] := 1.00000000;
$ "MeadFloodControl.Shortage Schedule Percent" [] := 1.00000000;
$ "Shortage.Shortage Flag" [] := 1.00000000;
END;
END;
POLICY_GROUP "Surplus Schedule Rules";
DESCRIPTION "";
ACTIVE TRUE;
BEGIN
RULE "7 State Plan Level 1";
DESCRIPTION "Known as a Quantified Surplus, this rule is executed when the amount of water under the 70R strategy (Surplus.SurplusRelease) is greater than 0.0 acre feet and the current year falls within the interim period, up to 2016. Surplus.SurplusRelease is computed in the rule Assurance Level Surplus Volume and represents the amount of water to be made available (under a 70 percentile inflow) to reduce the risk of potential flood control releases from Mead. Upon the execution of this rule, the annual diversion/depletion schedules of the major diversions, minus Mexico, are increased by their individiual Quantified Surplus volumes.
Also, the Surplus Flag on the Surplus data object and the Surplus Schedule Percent flag on the MeadFloodControl computational subbasin is set. The purpose of setting the Surplus Schedule Percent flag is to indicate that the surplus monthly percents are to be used to disaggregate the adjusted annual schedules.";
ACTIVE TRUE;
RULE_EXEC_CONSTRAINT $ "Surplus.SurplusRelease" [] > 0.00000000 "acre-ft" AND @"t" <= @"24:00:00 December 31, 2026";
BEGIN
FOREACH (STRING diversion IN { "MWD" , "CAP" , "SNWP" , "IID" , "Coachella" }) DO
diversion CONCAT "Diversion.Total Diversion Requested" [] := "VolumeToFlow"( "ComputeSurplusDiv7StatePlanLevel1"( diversion ), @"t" );
diversion CONCAT "Diversion.Total Depletion Requested" [] := "VolumeToFlow"( "ComputeSurplusDepl7StatePlanLevel1"( diversion ), @"t" );
ENDFOREACH;
$ "Surplus.Surplus Flag" [] := 1.00000000;
$ "MeadFloodControl.Surplus Schedule Percent" [] := 1.00000000;
$ "Surplus.Quantified Surplus Flag" [] := 1.00000000;
END;
RULE "7 State Plan Level 2";
DESCRIPTION "Also known as a Full Domestic Surplus, this rule is executed once per timestep when Mead's elevation falls between the 7 State Plan Level 1 and 7 State Plan Level 2 surplus triggers. The 7 State Level 1 surplus trigger is based on the 70R strategy (Assurance Level Surplus) in which the slot Surplus.SurplusRelease was computed in the rule Assurance Level Surplus Volume. If Surplus.SurplusRelease is below or equal to 0.0 acre-ft, then it was determined that no extra water is to be released from Mead to reduce the risk of potential flood control. In this event, the annual diversion/depletion schedules for MWD and SNWP are adjusted to their 7 State Plan Level 2 surplus schedules. Note that this rule is only in effect during the interim period, through 2016.
Also, the Surplus Flag on the Surplus data object and the Surplus Schedule Percent flag on the MeadFloodControl computational subbasin is set. The purpose of setting the Surplus Schedule Percent flag is to indicate that the surplus monthly percents are to be used to disaggregate the adjusted annual schedules.";
ACTIVE TRUE;
RULE_EXEC_CONSTRAINT $ "Mead.Pool Elevation" [@"t - 1"] >= $ "Surplus Triggers.7 State Plan Level 2" [@"t - 1"] AND $ "Surplus.SurplusRelease" [] <= 0.00000000 "acre-ft" AND @"t" <= @"24:00:00 December 31, 2026";
BEGIN
FOREACH (STRING diversion IN { "MWD" , "SNWP" } COMMENTED_BY "Does not include CAP after 2016 because AZ has stated they would not take a Domestic Surplus.") DO
diversion CONCAT "Diversion.Total Diversion Requested" [] := "VolumeToFlow"( "ComputeSurplusDiv7StatePlanLevel2"( diversion ), @"t" );
diversion CONCAT "Diversion.Total Depletion Requested" [] := "VolumeToFlow"( "ComputeSurplusDepl7StatePlanLevel2"( diversion ), @"t" );
ENDFOREACH;
$ "Surplus.Surplus Flag" [] := 1.00000000;
$ "MeadFloodControl.Surplus Schedule Percent" [] := 1.00000000;
$ "Surplus.Full Domestic Surplus Flag" [] := 1.00000000;
END;
RULE "7 State Plan Level 2 After 2016";
DESCRIPTION "Also known as a Domestic Surplus, this rule is executed once per timestep when Mead's elevation falls between the 7 State Plan Level 1 and 7 State Plan Level 2 surplus triggers. Is different from original 7 State Plan Level 2 rule because CAP receives surplus water. This is in accordance with Basin States Proposal - 2/3/06.";
ACTIVE FALSE;
RULE_EXEC_CONSTRAINT $ "Mead.Pool Elevation" [@"t - 1"] >= $ "Surplus Triggers.7 State Plan Level 2" [@"t - 1"] AND $ "Surplus.SurplusRelease" [] <= 0.00000000 "acre-ft" AND @"Current Year" != @"Start Year" AND @"t" > @"24:00:00 December 31, 2016" AND @"t" <= @"24:00:00 December 31, 2026";
BEGIN
FOREACH (STRING diversion IN { "MWD" , "SNWP" , "CAP" }) DO
diversion CONCAT "Diversion.Total Diversion Requested" [] := "VolumeToFlow"( "ComputeSurplusDiv7StatePlanLevel2"( diversion ), @"t" );
diversion CONCAT "Diversion.Total Depletion Requested" [] := "VolumeToFlow"( "ComputeSurplusDepl7StatePlanLevel2"( diversion ), @"t" );
ENDFOREACH;
$ "Surplus.Surplus Flag" [] := 1.00000000;
$ "MeadFloodControl.Surplus Schedule Percent" [] := 1.00000000;
$ "Surplus.Full Domestic Surplus Flag" [] := 1.00000000;
END;
RULE "7 State Plan Level 3";
DESCRIPTION "Also known as a Partial Domestic Surplus, this rule is executed once per timestep when Mead's elevation falls between the 7 State Plan Level 2 and 7 State Plan Level 3 surplus triggers. In this event, the annual diversion/depletion schedules for MWD and SNWP are adjusted to their 7 State Plan Level 3 surplus schedules. Note that this rule is only in effect during the interim period, through 2016.";
ACTIVE FALSE;
RULE_EXEC_CONSTRAINT $ "Mead.Pool Elevation" [@"t - 1"] < $ "Surplus Triggers.7 State Plan Level 2" [@"t - 1"] AND $ "Mead.Pool Elevation" [@"t - 1"] >= $ "Surplus Triggers.7 State Plan Level 3" [@"t - 1"] AND @"t" < @"24:00:00 December 31, 2008";
BEGIN
FOREACH (STRING diversion IN { "MWD" , "SNWP" }) DO
diversion CONCAT "Diversion.Total Diversion Requested" [] := "VolumeToFlow"( "ComputeSurplusDiv7StatePlanLevel3"( diversion ), @"t" );
diversion CONCAT "Diversion.Total Depletion Requested" [] := "VolumeToFlow"( "ComputeSurplusDepl7StatePlanLevel3"( diversion ), @"t" );
ENDFOREACH;
$ "Surplus.Surplus Flag" [] := 1.00000000;
$ "MeadFloodControl.Surplus Schedule Percent" [] := 1.00000000;
$ "Surplus.Partial Domestic Surplus Flag" [] := 1.00000000;
END;
RULE "Assurance Level Surplus (70R unlimited)";
DESCRIPTION "This rule is in effect after 2016 and when the value in Surplus.SurplusRelease determined by the rule Assurance Level Surplus Volume is greater than 0.0 acre-ft. The value in Surplus.SurplusRelease represents the amount of water to be made available (under a 70 percentile inflow) to reduce the risk of potential flood control releases from Mead. This rules executes once per timestep and sets the diversion and depletion schedules of MWD, CAP, SNWP, IID and Coachella based on the surplus schedules stored in the data object No Action Annual Surplus Schedules.
The Surplus Flag on the Surplus data object and the Surplus Schedule Percent flag on the MeadFloodControl computational subbasin is set. The purpose of setting the Surplus Schedule Percent flag is to indicate that the surplus monthly percents are to be used to disaggregate the adjusted annual schedules.";
ACTIVE TRUE;
RULE_EXEC_CONSTRAINT $ "Surplus.SurplusRelease" [] > 0.00000000 "acre-ft" AND @"t" > @"24:00:00 December 31, 2026";
BEGIN
FOREACH (STRING diversion IN { "MWD" , "CAP" , "SNWP" , "IID" , "Coachella" }) DO
diversion CONCAT "Diversion.Total Diversion Requested" [] := "VolumeToFlow"( "ComputeSurplusDiversion"( diversion ), @"t" );
diversion CONCAT "Diversion.Total Depletion Requested" [] := "VolumeToFlow"( "ComputeSurplusDepletion"( diversion ), @"t" );
ENDFOREACH;
$ "Surplus.Surplus Flag" [] := 1.00000000;
$ "MeadFloodControl.Surplus Schedule Percent" [] := 1.00000000;
$ "Surplus.Normal 70R Surplus Flag" [] := 1.00000000;
END;
END;
POLICY_GROUP "Normal Schedule Rules";
DESCRIPTION "";
ACTIVE TRUE;
BEGIN
RULE "Set SNWP Normal Schedule";
DESCRIPTION "This rule sets the Total Diversion and Depletion Requested on the SNWP diversion object to the input schedules on the SNWPSchedule data object. This rule will fire only after the conditions for Surplus and Shortage are checked. The execution of this rule means that it has been determined a normal year and all scheduled depletions can be satisfied.";
ACTIVE TRUE;
RULE_EXEC_CONSTRAINT TRUE;
BEGIN
$ "SNWPDiversion.Total Diversion Requested" [] := "VolumeToFlow"( $ "SNWP Schedule.AnnualNormalDiversionSchedule" [], @"t" );
$ "SNWPDiversion.Total Depletion Requested" [] := "VolumeToFlow"( $ "SNWP Schedule.AnnualNormalDepletionSchedule" [], @"t" );
END;
RULE "Set MWD Normal Schedule";
DESCRIPTION "This rule sets the Total Diversion and Depletion Requested on the MWD diversion object to the input schedules on the MWDSchedule data object. This rule will fire only after the conditions for Surplus and Shortage are checked. The execution of this rule means that it has been determined a normal year and all scheduled depletions can be satisfied.";
ACTIVE TRUE;
RULE_EXEC_CONSTRAINT TRUE;
BEGIN
$ "MWDDiversion.Total Diversion Requested" [] := "VolumeToFlow"( $ "MWD Schedule.AnnualNormalDiversionSchedule" [], @"t" );
$ "MWDDiversion.Total Depletion Requested" [] := "VolumeToFlow"( $ "MWD Schedule.AnnualNormalDepletionSchedule" [], @"t" );
END;
RULE "Set CAP Normal Schedule";
DESCRIPTION "This rule sets the Total Diversion and Depletion Requested on the CAP diversion object to the input schedules on the CAPSchedule data object. This rule will fire only after the conditions for Surplus and Shortage are checked. The execution of this rule means that it has been determined a normal year and all the scheduled depletions can be satisfied.";
ACTIVE TRUE;
RULE_EXEC_CONSTRAINT TRUE;
BEGIN
$ "CAPDiversion.Total Diversion Requested" [] := "VolumeToFlow"( $ "CAP Schedule.AnnualNormalDiversionSchedule" [], @"t" );
$ "CAPDiversion.Total Depletion Requested" [] := "VolumeToFlow"( $ "CAP Schedule.AnnualNormalDepletionSchedule" [], @"t" );
END;
RULE "Set Mexico Normal Schedule";
DESCRIPTION "This rule sets the Total Diversion and Depletion Requested on the Mexico diversion object to the input schedules on the MexicoSchedule data object. This rule will fire only after the conditions for Surplus and Shortage are checked. The execution of this rule means that it has been determined a normal year and all scheduled depletions can be satisfied.";
ACTIVE TRUE;
RULE_EXEC_CONSTRAINT TRUE;
BEGIN
$ "MexicoDiversion.Total Diversion Requested" [] := "VolumeToFlow"( $ "Mexico Schedule.AnnualNormalDiversionSchedule" [], @"t" );
$ "MexicoDiversion.Total Depletion Requested" [] := "VolumeToFlow"( $ "Mexico Schedule.AnnualNormalDepletionSchedule" [], @"t" );
END;
RULE "Set Coachella Normal Schedule";
DESCRIPTION "This rule sets the Total Diversion and Depletion Requested on the Coachella diversion obejct to input schedules on the CoachellaSchedule data object. This rule will fire only after the conditions for Surplus and Shortage are checked. The execution of this rule means that it has been determined a normal year and all scheduled depletions can be satisfied.";
ACTIVE TRUE;
RULE_EXEC_CONSTRAINT TRUE;
BEGIN
$ "CoachellaDiversion.Total Diversion Requested" [] := "VolumeToFlow"( $ "Coachella Schedule.AnnualNormalDiversionSchedule" [], @"t" );
$ "CoachellaDiversion.Total Depletion Requested" [] := "VolumeToFlow"( $ "Coachella Schedule.AnnualNormalDepletionSchedule" [], @"t" );
END;
RULE "Set IID Normal Schedule";
DESCRIPTION "This rule sets the Total Diversion and Depletion Requested on the IID diversion object to the input schedules on the IIDSchedule data object. This rule will fire only after the condition for Surplus and Shortage are checked. The execution of this rule means that it has been determined a normal year and all scheduled depletions can be satisfied. ";
ACTIVE TRUE;
RULE_EXEC_CONSTRAINT TRUE;
BEGIN
$ "IIDDiversion.Total Diversion Requested" [] := "VolumeToFlow"( $ "IID Schedule.AnnualNormalDiversionSchedule" [], @"t" );
$ "IIDDiversion.Total Depletion Requested" [] := "VolumeToFlow"( $ "IID Schedule.AnnualNormalDepletionSchedule" [], @"t" );
END;
END;
UTILITY_GROUP "Top Level Policy Functions";
DESCRIPTION "";
ACTIVE TRUE;
BEGIN
FUNCTION "ComputePowellAndMeadStorages" ( )
RETURN_TYPE LIST;
SCALE_UNITS "acre-ft";
DESCRIPTION "Returns a list with the following format: (Spike Flow Boolean, Flood Control Release Month Index, P0, PF0,
M0, P1, PF1, M1, P2, PF2, M2, . . ., P12, PF12, M12) where Spike Flow Boolean indicates whether or not a
Spike Flow release was made, Flood Control Release Month Index represents the month of the first flood
control release (if any), P1 represents Powell's January storage (P0 is Powell's storage at December of
the previous year), PF1 represents the operational policy used to set Powell's storage for the corresponding
month, and M1 represents Mead's January storage. Powell and Mead's storages are computed from January
to December.
";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
FOR ( DATETIME month IN "JanuaryToDecember"( ) ) WITH LIST storages = { FALSE , 0.00000000 , $ "Powell.Storage" [@"t - 1"] , 0.00000000 , $ "Mead.Storage" [@"t - 1"] } COMMENTED_BY "[spikeFlowCheck, floodControlReleaseMonthIndex, powellCurrentMonthStorage, powellCurrentMonthPolicyFlag, meadCurrentMonthStorage]" DO
WITH NUMERIC monthIndex = "GetMonth"( month ) DO
WITH NUMERIC previousPowellStorage = "GetListElement"( ( 3.00000000 * monthIndex - 2.00000000 ), storages ) DO
WITH NUMERIC previousMeadStorage = "GetListElement"( ( 3.00000000 * monthIndex ), storages ) DO
WITH NUMERIC powellReleaseMade = "ComputePowellReleaseMade"( month, storages ) DO
WITH BOOLEAN floodControlReleaseMade = IF ( ( GET @INDEX 1.00000000 FROM storages ) != 0.00000000 )
THEN
TRUE
ELSE
FALSE
ENDIF DO
IF ( ( NOT GET @INDEX 0.00000000 FROM storages ) AND month <= @"24:00:00 July 31, Current Year" )
THEN
WITH BOOLEAN spikeFlowCheck = "CheckSpikeFlowCriteria"( month, previousPowellStorage ) DO
WITH LIST powellStorage = "ComputePowellStorageWithSpikeFlow"( month, powellReleaseMade, previousPowellStorage, previousMeadStorage, spikeFlowCheck, floodControlReleaseMade ) DO
WITH LIST meadStorage = "ComputeMeadStorage"( month, previousPowellStorage, ( GET @INDEX 0.00000000 FROM powellStorage ), previousMeadStorage, ( GET @INDEX 1.00000000 FROM storages ) ) COMMENTED_BY "Arguments (month, previousPowellStorage, currentPowellStorage, previousMeadStorage, floodControlReleaseMonthIndex)
" DO
"CreateList"( storages, powellStorage, meadStorage, spikeFlowCheck )
ENDWITH
ENDWITH
ENDWITH
ELSE
WITH LIST powellStorage = "ComputePowellStorage"( month, powellReleaseMade, previousPowellStorage, previousMeadStorage, floodControlReleaseMade ) DO
WITH LIST meadStorage = "ComputeMeadStorage"( month, previousPowellStorage, ( GET @INDEX 0.00000000 FROM powellStorage ), previousMeadStorage, ( GET @INDEX 1.00000000 FROM storages ) ) DO
"CreateList"( storages, powellStorage, meadStorage, GET @INDEX 0.00000000 FROM storages )
ENDWITH
ENDWITH
ENDIF
ENDWITH
ENDWITH
ENDWITH
ENDWITH
ENDWITH
ENDFOR;
END;
FUNCTION "ComputePowellStorage" ( DATETIME month, NUMERIC powellReleaseMade, NUMERIC previousPowellStorage, NUMERIC previousMeadStorage, BOOLEAN floodControlReleaseMade )
RETURN_TYPE LIST;
SCALE_UNITS "acre-ft";
DESCRIPTION "In Jan - Sept, this function computes Powell's storage by first checking whether or not
the criteria is met for Equalization, ComputeStorageWithEqualization(). In Oct - Dec,
Powell's storage is computed without the check for Equalization,
ComputeStorageWithNOEqualization().";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( month <= @"24:00:00 September 30, Current Year" )
THEN
"ComputeStorageWithEqualization"( month, powellReleaseMade, previousPowellStorage, previousMeadStorage, floodControlReleaseMade )
ELSE
"ComputeStorageWithNOEqualization"( month, powellReleaseMade, previousPowellStorage )
ENDIF;
END;
FUNCTION "ComputePowellStorageWithSpikeFlow" ( DATETIME month, NUMERIC powellReleaseMade, NUMERIC previousPowellStorage, NUMERIC previousMeadStorage, BOOLEAN spikeFlowCheck, BOOLEAN floodControlReleaseMade )
RETURN_TYPE LIST;
SCALE_UNITS "acre-ft";
DESCRIPTION "Given that the spikeFlowCheck is TRUE, a spike flow is made. If Powell is going to spill anyway,
the spike flow comes from the spill, i.e. Powell's release is not increased. If Powell is not going
to spill, the release needs to be increased for the spike flow. Determine the total release by
computing the outflow based on the regular spring operation procedures (constrained to be at
least the outflow trigger) plus the additional volume needed for the spike flow. If the spikeFlowCheck
is FALSE, compute Powell's storage without spike flow consideration.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( spikeFlowCheck )
THEN
WITH NUMERIC powellStorage = "Operations"( month, previousPowellStorage ) DO
IF ( "ComputePowellSpill"( month, powellStorage, previousPowellStorage ) > 0.00000000 "acre-ft/month" )
THEN
"MakeListWithPolicyFlag"( powellStorage, 1.00000000 )
ELSE
"MakeListWithPolicyFlag"( "PowellComputeStorageAtGivenOutflow"( ( "PowellMinSpikeOutflow"( month, powellStorage, previousPowellStorage ) + $ "Powell Spike Flow Data.Additional Bypass Volume" [0.00000000, 0.00000000] / "GetDaysInMonth"( month ) ), previousPowellStorage, month ), 1.00000000 )
ENDIF
ENDWITH
ELSE
"ComputePowellStorage"( month, powellReleaseMade, previousPowellStorage, previousMeadStorage, floodControlReleaseMade )
ENDIF;
END;
FUNCTION "ComputeStorageWithNOEqualization" ( DATETIME month, NUMERIC powellReleaseMade, NUMERIC previousPowellStorage )
RETURN_TYPE LIST;
SCALE_UNITS "acre-ft";
DESCRIPTION "Computes Powell's storage considering all possible operations excluding Equalization and
a spike flow release. The storage is first set by the basic operations procedure and then
adjusted, if need be, based on the Limit Outflow, Smooth July Operation or Minimum
Objective Release policies. This function returns a list that contains, at INDEX 0, the
resulting storage and at INDEX 1, an integer representing which operation set the storage.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
WITH NUMERIC operationsStorage = "Operations"( month, previousPowellStorage ) DO
IF ( month >= @"24:00:00 July 31, Current Year" AND ( "PowellComputeStorageAtGivenOutflow"( 25000.00000000 "cfs", previousPowellStorage, month ) < 23822000.00000000 "acre-ft" AND "ComputeOutflowAtGivenStorage"( % "Powell", $ "PowellMonthly.Inflow" [month], operationsStorage, previousPowellStorage, month ) > 25000.00000000 "cfs" ) )
THEN
"MakeListWithPolicyFlag"( "LimitOutflow"( previousPowellStorage, month ), 4.00000000 )
ELSE
IF ( month == @"24:00:00 July 31, Current Year" AND operationsStorage > 23000000.00000000 "acre-feet" AND "ComputeOutflowAtGivenStorage"( % "Powell", $ "PowellMonthly.Inflow" [month], operationsStorage, previousPowellStorage, month ) < 1000000.00000000 "acre-feet/month" )
THEN
"MakeListWithPolicyFlag"( "SmoothJulyOperation"( previousPowellStorage, month ), 5.00000000 )
ELSE
WITH NUMERIC minObjRelease = "PowellMinObjRelforCurrentMonth"( month, powellReleaseMade ) DO
IF ( "ComputeOutflowAtGivenStorage"( % "Powell", $ "PowellMonthly.Inflow" [month], operationsStorage, previousPowellStorage, month ) < minObjRelease )
THEN
"MakeListWithPolicyFlag"( "MeetMinimumObjectiveRelease"( minObjRelease, previousPowellStorage, month ), 6.00000000 )
ELSE
"MakeListWithPolicyFlag"( operationsStorage, 7.00000000 )
ENDIF
ENDWITH
ENDIF
ENDIF
ENDWITH;
END;
FUNCTION "ComputeMeadStorage" ( DATETIME month, NUMERIC previousPowellStorage, NUMERIC powellStorage, NUMERIC previousMeadStorage, NUMERIC floodControlReleaseMonthIndex )
RETURN_TYPE LIST;
SCALE_UNITS "";
DESCRIPTION "Computes Mead's monthly storage by calling the pre-defined function MeadFloodControl().
MeadFloodControl() calls the method Mead Flood Control on the computational subbasin,
MeadFloodControl. The method Mead Flood Control first computes the release needed to
meet downstream demands. In the case that that release is not sufficient in meeting the
release needed for flood control, the release is set to the flood control release. The flood
control release is computed using algorithm derived by the USACE. The required arguments
are the subbasin name, the current month, Powell's previous storage, Powell's current
storage, Mead's previous storage, and an integer indicating the month (if any) of the
current year in which a flood control release was made. Both Mead's monthly storage and
an integer indicating whether or not a flood control release was made are returned.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"MeadFloodControl"( "MeadFloodControl", month, previousPowellStorage, powellStorage, previousMeadStorage, floodControlReleaseMonthIndex );
END;
FUNCTION "ComputeStorageWithEqualization" ( DATETIME month, NUMERIC powellReleaseMade, NUMERIC previousPowellStorage, NUMERIC previousMeadStorage, BOOLEAN floodControlReleaseMade )
RETURN_TYPE LIST;
SCALE_UNITS "acre-ft";
DESCRIPTION "This function first determines if the criteria for Equalization is met, and if so, computes
Powell's storage based on Equalization. If the criteria not met, Powell'e storage is
computed without Equalization. If Equalization occurs a check is made to ensure that, if it
2016 or earlier, that the Equalization release did not cause Powell's end of the water year
storage to drop below 14.85 MAF. In the case that it did drop below 14.85 MAF, the storage
is set to a minimum of 14.85 MAF and the storage resulting from Powell making the
minimum objective release for that month.
The criteria for Equalization is 1. that the end of the water year storage for Powell
(EOWYStoragePowell) computed with Powell's forecasted release from the current month
through Sept. (powellForecastRelease) must be greater than or equal to the end of the
water year storage for Mead (EOWYStorageMead) computed with Mead's forecasted
outflow from the current month through Sept. (meadForecastRelease) 2. the Upper Basin
Storage, computed with EOWYStoragePowell is greater than or equal the 602a storag
computed in Rule 1 602a Storage. 3. The current year is greater than 2016 or
EOWYStoragePowell is greater than or equal to 14.85 MAF.
";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
WITH NUMERIC powellForecastRelease = "ForecastPowellRelease"( month, powellReleaseMade, previousPowellStorage ) DO
WITH NUMERIC meadForecastRelease = "ForecastMeadRelease"( month, floodControlReleaseMade ) DO
WITH NUMERIC EOWYStoragePowell = "EOWYStorage"( % "Powell", powellForecastRelease, meadForecastRelease, previousPowellStorage, previousMeadStorage, month, floodControlReleaseMade ) DO
WITH NUMERIC UpperBasinStorage = "SumUpperBasinStorage"( month, EOWYStoragePowell ) DO
IF ( UpperBasinStorage >= "602aStorageValue"( ) )
THEN
WITH NUMERIC EOWYStorageMead = "EOWYStorage"( % "Mead", powellForecastRelease, meadForecastRelease, previousPowellStorage, previousMeadStorage, month, floodControlReleaseMade ) DO
IF ( EOWYStoragePowell >= EOWYStorageMead AND ( @"t" > @"24:00:00 December 31, 2016" OR EOWYStoragePowell >= 14850000.00000000 "acre-ft" ) )
THEN
WITH NUMERIC equalizationStorage = "Equalization"( EOWYStoragePowell, EOWYStorageMead, UpperBasinStorage, meadForecastRelease, powellForecastRelease, powellReleaseMade, previousPowellStorage, previousMeadStorage, floodControlReleaseMade, month ) DO
IF ( equalizationStorage < 14850000.00000000 "acre-ft" AND @"t" <= @"24:00:00 December 31, 2016" AND month == @"24:00:00 September 30, Current Year" )
THEN
"MakeListWithPolicyFlag"( "Min"( 14850000.00000000 "acre-ft", "PowellComputeStorageAtGivenOutflow"( "PowellMinObjRelforCurrentMonth"( month, powellReleaseMade ), previousPowellStorage, month ) ), 2.00000000 )
ELSE
"MakeListWithPolicyFlag"( equalizationStorage, 3.00000000 )
ENDIF
ENDWITH
ELSE
"ComputeStorageWithNOEqualization"( month, powellReleaseMade, previousPowellStorage )
ENDIF
ENDWITH
ELSE
"ComputeStorageWithNOEqualization"( month, powellReleaseMade, previousPowellStorage )
ENDIF
ENDWITH
ENDWITH
ENDWITH
ENDWITH;
END;
END;
UTILITY_GROUP "Spike Flow Functions";
DESCRIPTION "";
ACTIVE TRUE;
BEGIN
FUNCTION "CheckSpikeFlowCriteria" ( DATETIME month, NUMERIC previousPowellStorage )
RETURN_TYPE BOOLEAN;
SCALE_UNITS "";
DESCRIPTION "Determines whether or not the conditions are met that will trigger a spike flow release
and returns a BOOLEAN (TRUE for conditions are met, FALSE for conditions are not met).
In January, if the unregulated inflow forecast is greater than the trigger volume, a spike
flow is triggered. In Jan - July, if the outflow volume based on the spring operation
procedures is greater than a trigger volume, a spike flow is triggered. Also in Jan - July if
the average release, also based on the spring operation procedures, is greater than the
release trigger, a spike flow is triggered. Only one spike flow is to be released per year, so
this function is only called if the spike flow release has not been made at any time during
the current year. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( month == @"24:00:00 January 31, Current Year" AND "UnRegRunoffForecastWithError"( month ) > $ "Powell Spike Flow Data.January Volume Trigger" [0.00000000, 0.00000000] )
THEN
TRUE
ELSE
IF ( "ComputeOutflowAtGivenStorage"( % "Powell", $ "PowellMonthly.Inflow" [month], "Operations"( month, previousPowellStorage ), previousPowellStorage, month ) > $ "Powell Spike Flow Data.Outflow Trigger" [0.00000000, 0.00000000] )
THEN
TRUE
ELSE
WITH NUMERIC powellSpringOutflowVolume = "PowellSpringOutflowVolume"( month, previousPowellStorage ) DO
IF ( "PowellSpringOutflowAverage"( powellSpringOutflowVolume, month ) > $ "Powell Spike Flow Data.Outflow Trigger" [0.00000000, 0.00000000] )
THEN
TRUE
ELSE
FALSE
ENDIF
ENDWITH
ENDIF
ENDIF;
END;
FUNCTION "UnRegRunoffForecastWithError" ( DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "Returns the unregulated runoff forecast (including the forecast error) into Powell.
This value is the same as the regulated runoff forecast computed in Rule 5 (Powell
Spring Runoff Forecast) but does not include the potential reservoir regulation.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "GainsAndLosses_MeadFloodControl.QSum_Powell" [month] - $ "Powell Forecast Data.ForecastError" [month] * 1000000.00000000 "acre-ft" - "UBDepletionsRange"( month, @"24:00:00 July 31, Current Year" );
END;
FUNCTION "PowellMinSpikeOutflow" ( DATETIME month, NUMERIC powellStorage, NUMERIC previousPowellStorage )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft/month";
DESCRIPTION "Computes the outflow that mass balances Powell given with the given
storage. This outflow is constrained to be at least the spike flow outflow
trigger.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT $ "Powell Spike Flow Data.Outflow Trigger" [0.00000000, 0.00000000];
BEGIN
"ComputeOutflowAtGivenStorage"( % "Powell", $ "PowellMonthly.Inflow" [month], powellStorage, previousPowellStorage, month );
END;
END;
UTILITY_GROUP "Equalization Functions";
DESCRIPTION "";
ACTIVE TRUE;
BEGIN
FUNCTION "Equalization" ( NUMERIC EOWYStoragePowell, NUMERIC EOWYStorageMead, NUMERIC UpperBasinStorage, NUMERIC meadForecastRelease, NUMERIC powellForecastRelease, NUMERIC powellReleaseMade, NUMERIC previousPowellStorage, NUMERIC previousMeadStorage, BOOLEAN floodControlReleaseMade, DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "This function returns Powell's Equalization (EQ) storage and requires the following
arguments: EOWYStoragePowell, EOWYStorageMead, UpperBasinStorage,
meadForecastRelease, powellForecastRelease, powellReleaseMade,
previousPowellStorage, previousMeadStorage, floodControlReleaseMade (boolean) and the
current month.
ComputeEqualizationReleaseList() returns the total release volume need for EQ.
ConvertPowellRelease() subtracts powellForecastRelease from the total volume; this is
the change in release necessary to Equalize. The converted release is then checked in
CheckEqualizationRelease602a() to ensure that it does not cause a violation of the 602a
storage. ComputePowellRelease() divides the EQ release by the number of months
remaining to the EOWY and adds this to Powell's current outflow.
PowellComputeStorageAtGivenOutflow() then computes the storage required to make the
compute EQ release for that month.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"PowellComputeStorageAtGivenOutflow"( "ComputePowellRelease"( "CheckEqualizationRelease602a"( "ConvertPowellRelease"( "ComputeEqualizationReleaseList"( EOWYStoragePowell, EOWYStorageMead, UpperBasinStorage, meadForecastRelease, powellForecastRelease, previousPowellStorage, previousMeadStorage, floodControlReleaseMade, month ), powellForecastRelease ), IF ( @"t" <= @"24:00:00 December 31, 2026" AND @"t" >= @"24:00:00 December 31, 2008" )
THEN
EOWYStoragePowell
ELSE
UpperBasinStorage
ENDIF ), powellReleaseMade, previousPowellStorage, month ), previousPowellStorage, month ) COMMENTED_BY "0 passed as UpperBasinStorage if between 2008 and 2025 because Powell Portion of 602a is used for EQ release constraint in BS6.v2 operation";
END;
FUNCTION "CheckERMeadExclusiveFCS" ( NUMERIC EOWYSMead, NUMERIC equalizationRelease )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "This function is used in conjuction with ComputeEqualizationRelease(). It is called to check
if the computed EQ release will cause Mead to violate its exclusive flood control
space. If the release will cause this violation, a new EQ release is computed as the live
capacity of Mead minus the minimum flood control space minus the estimated EOWY
storage for Mead. Otherwise no changes to the equalization release are made. Also note
that this function is contrained to have a minumum value of 0.0.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT 0.00000000 "acre-feet";
BEGIN
IF ( ( EOWYSMead + equalizationRelease ) > ( "LiveCapacity"( % "Mead" ) - $ "MeadFloodControl.Minimum Required Space" [] ) )
THEN
"LiveCapacity"( % "Mead" ) - $ "MeadFloodControl.Minimum Required Space" [] - EOWYSMead
ELSE
equalizationRelease
ENDIF;
END;
FUNCTION "InitialEOWYStoragePowell" ( NUMERIC powellForecastRelease, NUMERIC previousPowellStorage, DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes Powell's initial EOWY storage using the regulated inflow forecast (includes
the forecast error for the spring months), the previous month's storage and the outflow
volume assuming regular spring/fall operation procedures (powellRelease). It is then
constrained to be at least 0.0 acre-ft. This is called the initialEOWYstorage because it has
yet to be adjusted for evaporation and bank storage. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT 0.00000000 "acre-feet";
BEGIN
previousPowellStorage + $ "EqualizationData.PowellInflowForecast" [month] - powellForecastRelease;
END;
FUNCTION "InitialEOWYStorageMead" ( NUMERIC powellForecastRelease, NUMERIC meadForecastRelease, NUMERIC previousMeadStorage, DATETIME month, BOOLEAN floodControl )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes Mead's initial EOWY storage by subtracting Mead's forecasted release and
SNWP's depletions (the current month through September) from the previous month's
storage and adding Powell's forecasted release and the gains between Powell and Mead.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT 0.00000000 "acre-feet";
BEGIN
IF ( month == @"24:00:00 September 30, Current Year" )
THEN
previousMeadStorage + powellForecastRelease - meadForecastRelease - "SumDemandsOverTime"( "SNWP", month, @"24:00:00 September 30, Current Year", floodControl ) + $ "EqualizationData.GlenToHoover" [0.00000000, "GetMonthAsString"( month )]
ELSE
previousMeadStorage + powellForecastRelease - meadForecastRelease - "SumDemandsOverTime"( "SNWP", month, @"24:00:00 September 30, Current Year", floodControl ) + ( $ "EqualizationData.GlenToHoover" [0.00000000, "GetMonthAsString"( month )] + "SumTableRow"( $ "EqualizationData.GlenToHoover", 0.00000000, "Max"( "GetMonth"( month ), 7.00000000 ), 8.00000000 ) )
ENDIF;
END;
FUNCTION "TotalPowellRelease" ( LIST results )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Adds the estimated EQ release volume to the current estimate of Powell's release volume
from the current month through the end of the water year.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
( GET @INDEX 0.00000000 FROM results ) + "EstimateEqualizationRelease"( GET @INDEX 1.00000000 FROM results, GET @INDEX 2.00000000 FROM results );
END;
FUNCTION "CheckEqualizationRelease" ( LIST results, NUMERIC variable602aCheck )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "This function checks the EQ release for both 602a violation and Mead's exclusive flood
control space. First, the EQ release is checked for 602a violation in
CheckEqualizationRelease602a(). The result is then used, along with the current estimate
of Mead's EOWY Storage in CheckERMeadExclusiveFCS() to ensure that Mead's
exclusive flood control space is not violated.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"CheckERMeadExclusiveFCS"( GET @INDEX 2.00000000 FROM results, "CheckEqualizationRelease602a"( "EstimateEqualizationRelease"( GET @INDEX 1.00000000 FROM results, GET @INDEX 2.00000000 FROM results ), variable602aCheck ) ) COMMENTED_BY "If after 2025 or before 2008, variable602aCheck is UpperBasinStorage. Otherwise, EOWYSPowell.";
END;
FUNCTION "EqualizationRuleCurveStorage" ( OBJECT reservoir, DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Estimates the reservoir regulation for either Mohave or Havasu from the current month
through September. This value is used in forecasting Mead's release for Equalization.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"RuleCurveStorage"( reservoir, @"24:00:00 September 30, Current Year" ) - ( STRINGIFY reservoir ) CONCAT ".Monthly Storage" ["OffsetDate"( month, - 1.00000000, "1 months" )];
END;
FUNCTION "CheckEqualizationRelease602a" ( NUMERIC equalizationRelease, NUMERIC variable602aCheck )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "This function does a final check on the EQ release from Powell to ensure that making this
release will not violate the Upper Basin 602a Storage. This check is computed by
subtracting the EQ release from the current month through the EOWY, from the amount of
storage in the Upper Basin (UpperBasinStorage). This value is then compared to the value
of 602a storage that has already been set by Rule 1 602a Storage. Also note that the
results of this check are also constrained by a minimum value of 0.0. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT 0.00000000 "acre-feet";
BEGIN
IF ( @"t" <= @"24:00:00 December 31, 2026" )
THEN
IF ( variable602aCheck - equalizationRelease < $ "EqualizationData.Powell Portion of 602a" [@"24:00:00 December 31, Current Year"] )
THEN
variable602aCheck - $ "EqualizationData.Powell Portion of 602a" [@"24:00:00 December 31, Current Year"]
ELSE
equalizationRelease
ENDIF
ELSE
IF ( variable602aCheck - equalizationRelease < "602aStorageValue"( ) )
THEN
variable602aCheck - "602aStorageValue"( )
ELSE
equalizationRelease
ENDIF
ENDIF COMMENTED_BY "If after 2025 or before 2008, variable602aCheck is UpperBasinStorage. Otherwise, EOWYSPowell.";
END;
FUNCTION "ComputeEqualizationEvaporation" ( OBJECT reservoir, LIST dates )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Sums the evaporation of the reservoir (Mohave and Havasu) for all dates in the
LIST dates. This is used in estimating Mead's release to compute the end of the
water year storage in Mead for Equalization.
";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
FOR ( DATETIME date IN dates ) WITH NUMERIC sum = 0.00000000 "acre-feet" DO
sum + "EstimateEvaporation"( reservoir, "RuleCurveStorage"( reservoir, "OffsetDate"( date, - 1.00000000, "1 months" ) ), "RuleCurveStorage"( reservoir, date ), date, date )
ENDFOR;
END;
FUNCTION "EstimateEqualizationRelease" ( NUMERIC EOWYSPowell, NUMERIC EOWYSMead )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes the EQ release as half the difference between Powell and Mead's
EOWY storage.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
( EOWYSPowell - EOWYSMead ) * 0.50000000;
END;
FUNCTION "NumberMonthsRemaining" ( DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "Returns the number of months remaining to the end of the water year.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( month < @"October" )
THEN
10.00000000 - "GetMonth"( month )
ELSE
22.00000000 - "GetMonth"( month )
ENDIF;
END;
FUNCTION "ComputeEqualizationReleaseList" ( NUMERIC EOWYSPowell, NUMERIC EOWYSMead, NUMERIC UpperBasinStorage, NUMERIC meadForecastRelease, NUMERIC powellForecastRelease, NUMERIC previousPowellStorage, NUMERIC previousMeadStorage, BOOLEAN floodControlReleaseMade, DATETIME month )
RETURN_TYPE LIST;
SCALE_UNITS "";
DESCRIPTION "This function is an iterative computation of the total Powell release volume needed from
the current month through Sept to for Equalization (EQ) of Powell and Mead. An iterative
computation is required to account for evaporation and bank storage losses. A four
element list, named result, is returned by this function with the order: Total Equalization
Release (EQ release plus Powell's forecasted release), EOWYStoragePowell,
EOWYStorageMead, iteration count.
The list is first initialized with the function InitializedEqualizationReleaseList(). The next
step is to add 1.0 to the iteration count which is at INDEX 3 (or 4th element) in the list.
Then EOWYStorageMead is recomputed with EQ release computed in TotalPowellRelease()
and is stored at INDEX 2. Next, the EQ release is checked to ensure that it doesn't
violate 602aStorage or Mead's flood control space and if it does, it is adjusted properly
in ComputeNewPowellRelease(). Then EOWYStoragePowell is computed with the checked
EQ release and is stored at INDEX 1. Lastly, the EQ release is inserted the list position
INDEX 0.
The computation described above is repeated until 1. the absolute difference of
EOWYStoragePowell and EOWYStorageMead is less that the EQ tolerance (currently set
to 2,000 AF), or 2. the iteration count exceeds 30.0";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
WHILE ( "Abs"( ( GET @INDEX 1.00000000 FROM result ) - GET @INDEX 2.00000000 FROM result ) > $ "EqualizationData.EqualizationTolerance" [0.00000000, 0.00000000] AND ( GET @INDEX 3.00000000 FROM result ) < 30.00000000 ) WITH LIST result = "InitialEqualizationReleaseList"( EOWYSPowell, EOWYSMead, powellForecastRelease ) DO
INSERT "TotalPowellRelease"( result ) INTO INSERT "EOWYStorage"( % "Powell", "ComputeNewPowellRelease"( result, IF ( @"t" <= @"24:00:00 December 31, 2026" AND @"t" >= @"24:00:00 December 31, 2008" )
THEN
EOWYSPowell
ELSE
UpperBasinStorage
ENDIF ), meadForecastRelease, previousPowellStorage, previousMeadStorage, month, floodControlReleaseMade ) INTO INSERT "EOWYStorage"( % "Mead", "TotalPowellRelease"( result ), meadForecastRelease, previousPowellStorage, previousMeadStorage, month, floodControlReleaseMade ) INTO INSERT ( GET @INDEX 3.00000000 FROM result ) + 1.00000000 INTO result
ENDWHILE;
END;
FUNCTION "InitialEqualizationReleaseList" ( NUMERIC EOWYSPowell, NUMERIC EOWYSMead, NUMERIC powellRelease )
RETURN_TYPE LIST;
SCALE_UNITS "";
DESCRIPTION "Returns a list containing the 4 elements.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
{ powellRelease , EOWYSPowell , EOWYSMead , 0.00000000 };
END;
FUNCTION "ComputeNewPowellRelease" ( LIST results, NUMERIC variable602aCheck )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Compute the new Powell release if the EQ release will cause Powell to violate the 602a
storage or Mead to violate its exclusive flood control space.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
( "TotalPowellRelease"( results ) + "CheckEqualizationRelease"( results, variable602aCheck ) ) COMMENTED_BY "If after 2025 or before 2008, variable602aCheck is UpperBasinStorage. Otherwise, EOWYSPowell.";
END;
FUNCTION "ConvertPowellRelease" ( LIST equalizationReleaseList, NUMERIC powellForecastRelease )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Subtracts the forecasted Powell release from the current month through the end of the
water year from the EQ release computed in ComputeEqualizationReleaseList(). The EQ
release at INDEX 0 is the most recently computed value. Recall that this EQ release is the
total volumetric release from Powell. It's necessary to subtract the forecasted release to
compute the extra release needed for EQ. Also note that the result of this function is
constrained to a minimum of 0.0 acre-ft.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT 0.00000000 "acre-feet";
BEGIN
( GET @INDEX 0.00000000 FROM equalizationReleaseList ) - powellForecastRelease;
END;
FUNCTION "SumUpperBasinStorage" ( DATETIME month, NUMERIC EOWYStoragePowell )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes the available water in the Upper Basin by summing the previous month's storage
in Flaming Gorge, Blue Mesa and Navajo and adding Powell's EOWY storage.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
EOWYStoragePowell + FOR ( STRING reservoir IN { "FlamingGorge" , "BlueMesa" , "Navajo" } ) WITH NUMERIC sum = 0.00000000 "acre-feet" DO
sum + "Upper Basin Effective Reservoir Storages." CONCAT reservoir ["OffsetDate"( month, - 1.00000000, "1 months" )]
ENDFOR;
END;
FUNCTION "ComputePowellRelease" ( NUMERIC equalizationRelease, NUMERIC powellReleaseMade, NUMERIC previousPowellStorage, DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet/month";
DESCRIPTION "Adds the current outflow from Powell to the estimated additional release needed to equalize
Powell and Mead by the end of the water year. To get the current outflow from Powell, the
storage must first be computed based on the the operation procedures other than
Equalization or Spike Flow. Recall that ComputeStorageWithNoEqualization() returns a list
that includes both the storage and policy flag. Here only the storage is of interest which is
the first element in the returned list (INDEX 0). GetListElement() retrieves the element at
one greater than the index argument. Also note that the result of this function is
constrained to a minimum of Powell's min release and maximum of Powell's max release.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT "MinRelease"( % "Powell" );
MAX_CONSTRAINT $ "Coordinated Operation.PowellMaxRODRelease" [];
BEGIN
"ComputeOutflowAtGivenStorage"( % "Powell", $ "PowellMonthly.Inflow" [month], "GetListElement"( - 1.00000000, "ComputeStorageWithNOEqualization"( month, powellReleaseMade, previousPowellStorage ) ), previousPowellStorage, month ) + equalizationRelease / ( "NumberMonthsRemaining"( month ) * "GetDaysInMonth"( month ) );
END;
FUNCTION "ForecastPowellInflow" ( )
RETURN_TYPE LIST;
SCALE_UNITS "acre-feet";
DESCRIPTION "Returns a list of Powell's regulated inflow forecast from Jan - Sept.
In Jan - July, the forecast error is included in the forecast.
";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
MAPLIST ( DATETIME month IN "JanuaryToSeptember"( ) ) DO
IF ( month <= @"24:00:00 July 31, Current Year" )
THEN
$ "Powell Forecast Data.Reg Inflow with Error" [month] + "PowellRegulatedInflowVolume"( @"24:00:00 August 31, Current Year", @"24:00:00 September 30, Current Year", month )
ELSE
IF ( month == @"24:00:00 August 31, Current Year" )
THEN
$ "PowellMonthly.Inflow" [month] * "GetDaysInMonth"( month ) + "PowellRegulatedInflowVolume"( @"24:00:00 September 30, Current Year", @"24:00:00 September 30, Current Year", month )
ELSE
$ "PowellMonthly.Inflow" [month] * "GetDaysInMonth"( month )
ENDIF
ENDIF
ENDMAPLIST;
END;
FUNCTION "ForecastPowellJulyStorage" ( DATETIME month, NUMERIC powellSpringOutflowVolConstrained, NUMERIC previousPowellStorage )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Forecasts the Powell July storage at the current month by using the spring operation,
execpt that the forecasted outflow volume is contrainied by the min release volume, min
objective release volume, and the max release volume. If the springOutflowVolConstrained
was not constrained, the resulting storage is the July target storage. This resulting
storage is then constrained by Powell's inactive and live capacities.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT "InactiveCapacity"( % "Powell" );
MAX_CONSTRAINT "LiveCapacity"( % "Powell" );
BEGIN
WITH NUMERIC endStorage = "UBTargetStorage"( "Powell", @"24:00:00 July 31, Current Year" ) DO
previousPowellStorage + $ "Powell Forecast Data.Reg Inflow with Error" [month] - powellSpringOutflowVolConstrained - "EstimateEvaporation"( % "Powell", previousPowellStorage, endStorage, month, @"24:00:00 July 31, Current Year" ) - "Estimate Bank Storage without Evap"( % "Powell", previousPowellStorage, endStorage )
ENDWITH;
END;
FUNCTION "PowellSpringOutflowVolConstrained" ( DATETIME month, NUMERIC powellReleaseMade, NUMERIC previousPowellStorage )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes the spring outflow volume and constrains it to a max of Powell's max release
volume and a min of the max of Powell's min release volume and the minimum objective
release for the current month through July. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT "Max"( "MinReleaseVolume"( % "Powell", month, @"24:00:00 July 31, Current Year" ), "PowellMinObjRelVolumeSpring"( month, @"24:00:00 July 31, Current Year", powellReleaseMade, previousPowellStorage ) );
MAX_CONSTRAINT "MaxReleaseVolume"( % "Powell", month, @"24:00:00 July 31, Current Year" );
BEGIN
"PowellSpringOutflowVolume"( month, previousPowellStorage );
END;
FUNCTION "ForecastPowellFallRangeOutflowVolume" ( NUMERIC initialStorage, NUMERIC powellReleaseMade, DATETIME startDate, DATETIME endDate, DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Estimates Powell's outflow volume for Aug-Sept or Aug by using an estimated July
storage as the initial storage. The min constraint on the outflow volume is the max of the
min release volume and the remaining objective release. The max constraint is the max
release volume. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT "Max"( "PowellMinObjRelVolRemaining"( month, powellReleaseMade ) * ( "PowellSumReleaseWeights"( startDate, endDate ) / "PowellSumReleaseWeights"( month, endDate ) ), "MinReleaseVolume"( % "Powell", startDate, endDate ) );
MAX_CONSTRAINT "MaxReleaseVolume"( % "Powell", startDate, endDate );
BEGIN
"PowellFallOutflowVolume"( initialStorage, startDate, @"24:00:00 December 31, Current Year", month ) * ( "PowellSumReleaseWeights"( startDate, endDate ) / "PowellSumReleaseWeights"( startDate, @"24:00:00 December 31, Current Year" ) );
END;
FUNCTION "ForecastPowellRelease" ( DATETIME month, NUMERIC powellReleaseMade, NUMERIC previousPowellStorage )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "This function forecasts Powell's release which is used to determine Powell's EOWYstorage
for Equalization. The estimated release is based on the spring operation through July and
the fall operation for Aug and Sept. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( month <= @"24:00:00 July 31, Current Year" )
THEN
WITH NUMERIC powellSpringOutflowVolConstrained = "PowellSpringOutflowVolConstrained"( month, powellReleaseMade, previousPowellStorage ) DO
powellSpringOutflowVolConstrained + "ForecastPowellFallRangeOutflowVolume"( "ForecastPowellJulyStorage"( month, powellSpringOutflowVolConstrained, previousPowellStorage ), powellReleaseMade, @"24:00:00 August 31, Current Year", @"24:00:00 September 30, Current Year", month )
ENDWITH
ELSE
"ForecastPowellFallRangeOutflowVolume"( previousPowellStorage, powellReleaseMade, month, @"24:00:00 September 30, Current Year", month )
ENDIF;
END;
FUNCTION "EOWYStorage" ( OBJECT reservoir, NUMERIC powellForecastRelease, NUMERIC meadForecastRelease, NUMERIC previousPowellStorage, NUMERIC previousMeadStorage, DATETIME month, BOOLEAN floodControlReleaseMade )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Estimates the end of water year storage for Powell and Mead using their forecasted
releases. First their initial EOWY storages are computed. Next, the evaporation and bank
storage by is calculated using the initial estimate of the EOWY storage and the previous
month's storage. The evaporation and bank storage is then subtracted from the initial
EOWY storage. This function is used in conjunction with Equalization.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( ( STRINGIFY reservoir ) == "Powell" )
THEN
WITH NUMERIC initEOWYStoragePowell = "InitialEOWYStoragePowell"( powellForecastRelease, previousPowellStorage, month ) DO
initEOWYStoragePowell - "EstimateEvaporation"( reservoir, previousPowellStorage, "Min"( initEOWYStoragePowell, "LiveCapacity"( reservoir ) ), month, @"24:00:00 September 30, Current Year" ) - "EstimateBankStorage"( reservoir, previousPowellStorage, initEOWYStoragePowell, month )
ENDWITH
ELSE
WITH NUMERIC initEOWYStorageMead = "InitialEOWYStorageMead"( powellForecastRelease, meadForecastRelease, previousMeadStorage, month, floodControlReleaseMade ) DO
initEOWYStorageMead - "EstimateEvaporation"( reservoir, previousMeadStorage, "Min"( initEOWYStorageMead, "LiveCapacity"( reservoir ) ), month, @"24:00:00 September 30, Current Year" ) - "EstimateBankStorage"( reservoir, previousMeadStorage, initEOWYStorageMead, month )
ENDWITH
ENDIF;
END;
END;
UTILITY_GROUP "Coordinated Operation Hybrid Functions";
DESCRIPTION "";
ACTIVE TRUE;
BEGIN
FUNCTION "ComputePowellAndMeadStoragesDD1" ( )
RETURN_TYPE LIST;
SCALE_UNITS "acre-ft";
DESCRIPTION "Returns a list with the following format: (Spike Flow Boolean, Flood Control Release Month Index, P0, PF0,
M0, P1, PF1, M1, P2, PF2, M2, . . ., P12, PF12, M12) where Spike Flow Boolean indicates whether or not a
Spike Flow release was made, Flood Control Release Month Index represents the month of the first flood
control release (if any), P1 represents Powell's January storage (P0 is Powell's storage at December of
the previous year), PF1 represents the operational policy used to set Powell's storage for the corresponding
month, and M1 represents Mead's January storage. Powell and Mead's storages are computed from January
to December.
";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
FOR ( DATETIME month IN "JanuaryToDecember"( ) ) WITH LIST storages = { FALSE , 0.00000000 , $ "Powell.Storage" [@"t - 1"] , 0.00000000 , $ "Mead.Storage" [@"t - 1"] } COMMENTED_BY "[spikeFlowCheck, floodControlReleaseMonthIndex, powellCurrentMonthStorage, powellCurrentMonthPolicyFlag, meadCurrentMonthStorage]" DO
WITH NUMERIC monthIndex = "GetMonth"( month ) DO
WITH NUMERIC previousPowellStorage = "GetListElement"( ( 3.00000000 * monthIndex - 2.00000000 ), storages ) DO
WITH NUMERIC previousMeadStorage = "GetListElement"( ( 3.00000000 * monthIndex ), storages ) DO
WITH NUMERIC powellReleaseMade = "ComputePowellReleaseMade"( month, storages ) DO
WITH BOOLEAN floodControlReleaseMade = IF ( ( GET @INDEX 1.00000000 FROM storages ) != 0.00000000 )
THEN
TRUE
ELSE
FALSE
ENDIF DO
IF ( ( NOT GET @INDEX 0.00000000 FROM storages ) AND month <= @"24:00:00 July 31, Current Year" )
THEN
WITH BOOLEAN spikeFlowCheck = "CheckSpikeFlowCriteria"( month, previousPowellStorage ) DO
WITH LIST powellStorage = "ComputePowellStorageSpikeFlowDD1"( month, powellReleaseMade, previousPowellStorage, previousMeadStorage, spikeFlowCheck, storages, floodControlReleaseMade ) DO
WITH LIST meadStorage = "ComputeMeadStorage"( month, previousPowellStorage, ( GET @INDEX 0.00000000 FROM powellStorage ), previousMeadStorage, ( GET @INDEX 1.00000000 FROM storages ) ) COMMENTED_BY "Arguments (month, previousPowellStorage, currentPowellStorage, previousMeadStorage, floodControlReleaseMonthIndex)
" DO
"CreateList"( storages, powellStorage, meadStorage, spikeFlowCheck )
ENDWITH
ENDWITH
ENDWITH
ELSE
WITH LIST powellStorage = "ComputePowellStorageHybrid"( month, powellReleaseMade, previousPowellStorage, previousMeadStorage, storages, floodControlReleaseMade ) DO
WITH LIST meadStorage = "ComputeMeadStorage"( month, previousPowellStorage, ( GET @INDEX 0.00000000 FROM powellStorage ), previousMeadStorage, ( GET @INDEX 1.00000000 FROM storages ) ) DO
"CreateList"( storages, powellStorage, meadStorage, GET @INDEX 0.00000000 FROM storages )
ENDWITH
ENDWITH
ENDIF
ENDWITH
ENDWITH
ENDWITH
ENDWITH
ENDWITH
ENDFOR;
END;
FUNCTION "ComputePowellStorageHybrid" ( DATETIME month, NUMERIC powellReleaseMade, NUMERIC previousPowellStorage, NUMERIC previousMeadStorage, LIST storages, BOOLEAN floodControlReleaseMade )
RETURN_TYPE LIST;
SCALE_UNITS "acre-ft";
DESCRIPTION "In Jan - Sept, this function computes Powell's storage by first checking whether or not
the criteria is met for Equalization, ComputeStorageWithEqualization(). In Oct - Dec,
Powell's storage is computed without the check for Equalization,
ComputeStorageWithNOEqualization().";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
WITH NUMERIC operationsStorage = "Operations"( month, previousPowellStorage ) DO
IF ( month <= @"24:00:00 September 30, Current Year" )
THEN
WITH NUMERIC powellForecastRelease = "ForecastPowellRelease"( month, powellReleaseMade, previousPowellStorage ) DO
WITH NUMERIC EOWYStoragePowell = "EOWYStorage"( % "Powell", powellForecastRelease, 0.00000000 "acre-ft", previousPowellStorage, previousMeadStorage, month, floodControlReleaseMade ) COMMENTED_BY "0.0 passed as meadForecastRelease, because not needed to for EOWYStoragePowell." DO
WITH NUMERIC meadForecastRelease = "ForecastMeadRelease"( month, floodControlReleaseMade ) DO
WITH NUMERIC EOWYStorageMead = "EOWYStorage"( % "Mead", powellForecastRelease, meadForecastRelease, previousPowellStorage, previousMeadStorage, month, floodControlReleaseMade ) DO
WITH NUMERIC UpperBasinStorage = "SumUpperBasinStorage"( month, EOWYStoragePowell ) DO
IF ( ( ( @"t" <= @"24:00:00 December 31, 2016" AND ( EOWYStoragePowell < $ "EqualizationData.Powell Portion of 602a" [@"24:00:00 December 31, Current Year"] AND "StorageToElevation"( % "Powell", EOWYStoragePowell ) < 3630.00000000 "ft" ) ) OR ( EOWYStoragePowell < $ "EqualizationData.Powell Portion of 602a" [@"24:00:00 December 31, Current Year"] ) ) AND EOWYStoragePowell >= "ElevationToStorage"( % "Powell", $ "Coordinated Operation.Hybrid_PowellUpperTierElevation" [] ) AND EOWYStorageMead < "ElevationToStorage"( % "Mead", $ "Coordinated Operation.Hybrid_MeadMinBalancingElevation" [] ) OR EOWYStoragePowell < "ElevationToStorage"( % "Powell", $ "Coordinated Operation.Hybrid_PowellLowerTierElevation" [] ) )
THEN
"ComputeStorageWithEqualizationDD1"( month, powellReleaseMade, previousPowellStorage, previousMeadStorage, EOWYStoragePowell, powellForecastRelease, EOWYStorageMead, meadForecastRelease, operationsStorage, floodControlReleaseMade )
ELSE
"ComputeStorageWithNormalEqualization_Hybrid"( month, powellReleaseMade, previousPowellStorage, previousMeadStorage, powellForecastRelease, meadForecastRelease, EOWYStoragePowell, EOWYStorageMead, floodControlReleaseMade, operationsStorage )
ENDIF
ENDWITH
ENDWITH
ENDWITH
ENDWITH
ENDWITH
ELSE
"ComputeStorageWithNOEqualizationDD1"( month, powellReleaseMade, operationsStorage, previousPowellStorage, previousMeadStorage, 0.00000000 "acre-ft", 0.00000000 "acre-ft", storages ) COMMENTED_BY "0.0 acre-ft passed as Powell and Mead EOWY storage b/c these are not needed for Oct-Dec release decisions"
ENDIF
ENDWITH;
END;
FUNCTION "ComputeStorageWithNormalEqualization_Hybrid" ( DATETIME month, NUMERIC powellReleaseMade, NUMERIC previousPowellStorage, NUMERIC previousMeadStorage, NUMERIC powellForecastRelease, NUMERIC meadForecastRelease, NUMERIC EOWYStoragePowell, NUMERIC EOWYStorageMead, BOOLEAN floodControlReleaseMade, NUMERIC operationsStorage )
RETURN_TYPE LIST;
SCALE_UNITS "acre-ft";
DESCRIPTION "This function first determines if the criteria for Equalization is met, and if so, computes
Powell's storage based on Equalization. If the criteria not met, Powell'e storage is
computed without Equalization. If Equalization occurs a check is made to ensure that, if it
2016 or earlier, that the Equalization release did not cause Powell's end of the water year
storage to drop below 14.85 MAF. In the case that it did drop below 14.85 MAF, the storage
is set to a minimum of 14.85 MAF and the storage resulting from Powell making the
minimum objective release for that month.
The criteria for Equalization is 1. that the end of the water year storage for Powell
(EOWYStoragePowell) computed with Powell's forecasted release from the current month
through Sept. (powellForecastRelease) must be greater than or equal to the end of the
water year storage for Mead (EOWYStorageMead) computed with Mead's forecasted
outflow from the current month through Sept. (meadForecastRelease) 2. the Upper Basin
Storage, computed with EOWYStoragePowell is greater than or equal the 602a storag
computed in Rule 1 602a Storage. 3. The current year is greater than 2016 or
EOWYStoragePowell is greater than or equal to 14.85 MAF.
";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( EOWYStoragePowell >= $ "EqualizationData.Powell Portion of 602a" [@"24:00:00 December 31, Current Year"] )
THEN
IF ( EOWYStoragePowell >= EOWYStorageMead AND ( @"t" > @"24:00:00 December 31, 2016" OR EOWYStoragePowell >= "ElevationToStorage"( % "Powell", 3630.00000000 "ft" ) ) )
THEN
WITH NUMERIC equalizationStorage = "Equalization"( EOWYStoragePowell, EOWYStorageMead, 0.00000000 "acre-ft", meadForecastRelease, powellForecastRelease, powellReleaseMade, previousPowellStorage, previousMeadStorage, floodControlReleaseMade, month ) COMMENTED_BY "0 passed as Upper Basin Storage b/c Powell Portion of 602a is EQ release constraint" DO
IF ( equalizationStorage < "ElevationToStorage"( % "Powell", 3630.00000000 "ft" ) AND @"t" <= @"24:00:00 December 31, 2016" AND month == @"24:00:00 September 30, Current Year" )
THEN
"MakeListWithPolicyFlag"( "Min"( "ElevationToStorage"( % "Powell", 3630.00000000 "ft" ), "PowellComputeStorageAtGivenOutflow"( "PowellMinObjRelforCurrentMonth"( month, powellReleaseMade ), previousPowellStorage, month ) ), 2.00000000 )
ELSE
"MakeListWithPolicyFlag"( equalizationStorage, 3.00000000 )
ENDIF
ENDWITH
ELSE
"ComputeStorageWithNOEqualizationDD1"( month, powellReleaseMade, operationsStorage, previousPowellStorage, previousMeadStorage, EOWYStoragePowell, EOWYStorageMead, { 0.00000000 } ) COMMENTED_BY "0.0 passed as LIST storages because Jan-Sept use EOWYStoragePowell"
ENDIF
ELSE
"ComputeStorageWithNOEqualizationDD1"( month, powellReleaseMade, operationsStorage, previousPowellStorage, previousMeadStorage, EOWYStoragePowell, EOWYStorageMead, { 0.00000000 } ) COMMENTED_BY "0.0 passed as LIST storages because Jan-Sept use EOWYStoragePowell"
ENDIF;
END;
FUNCTION "ComputeStorageWithNOEqualizationDD1" ( DATETIME month, NUMERIC powellReleaseMade, NUMERIC operationsStorage, NUMERIC previousPowellStorage, NUMERIC previousMeadStorage, NUMERIC EOWYSPowell, NUMERIC EOWYSMead, LIST storages )
RETURN_TYPE LIST;
SCALE_UNITS "acre-ft";
DESCRIPTION "Computes Powell's storage considering all possible operations excluding Equalization and
a spike flow release. The storage is first set by the basic operations procedure and then
adjusted, if need be, based on the Limit Outflow, Smooth July Operation or Minimum
Objective Release policies. This function returns a list that contains, at INDEX 0, the
resulting storage and at INDEX 1, an integer representing which operation set the storage.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( month >= @"24:00:00 July 31, Current Year" AND ( "PowellComputeStorageAtGivenOutflow"( 25000.00000000 "cfs", previousPowellStorage, month ) < 23822000.00000000 "acre-ft" AND "ComputeOutflowAtGivenStorage"( % "Powell", $ "PowellMonthly.Inflow" [month], operationsStorage, previousPowellStorage, month ) > 25000.00000000 "cfs" ) )
THEN
"MakeListWithPolicyFlag"( "LimitOutflow"( previousPowellStorage, month ), 4.00000000 )
ELSE
IF ( month == @"24:00:00 July 31, Current Year" AND operationsStorage > 23000000.00000000 "acre-feet" AND "ComputeOutflowAtGivenStorage"( % "Powell", $ "PowellMonthly.Inflow" [month], operationsStorage, previousPowellStorage, month ) < 1000000.00000000 "acre-feet/month" )
THEN
"MakeListWithPolicyFlag"( "SmoothJulyOperation"( previousPowellStorage, month ), 5.00000000 )
ELSE
WITH LIST minObjRelease = "DetermineTieredReleaseDD2"( month, powellReleaseMade, EOWYSPowell, EOWYSMead, storages ) DO
IF ( "ComputeOutflowAtGivenStorage"( % "Powell", $ "PowellMonthly.Inflow" [month], operationsStorage, previousPowellStorage, month ) < GET @INDEX 0.00000000 FROM minObjRelease )
THEN
"MakeListWithPolicyFlag"( "MeetMinimumObjectiveRelease"( GET @INDEX 0.00000000 FROM minObjRelease, previousPowellStorage, month ), GET @INDEX 1.00000000 FROM minObjRelease )
ELSE
"MakeListWithPolicyFlag"( operationsStorage, 7.00000000 )
ENDIF
ENDWITH
ENDIF
ENDIF;
END;
FUNCTION "ComputePowellStorageSpikeFlowDD1" ( DATETIME month, NUMERIC powellReleaseMade, NUMERIC previousPowellStorage, NUMERIC previousMeadStorage, BOOLEAN spikeFlowCheck, LIST storages, BOOLEAN floodControlReleaseMade )
RETURN_TYPE LIST;
SCALE_UNITS "acre-ft";
DESCRIPTION "Given that the spikeFlowCheck is TRUE, a spike flow is made. If Powell is going to spill anyway,
the spike flow comes from the spill, i.e. Powell's release is not increased. If Powell is not going
to spill, the release needs to be increased for the spike flow. Determine the total release by
computing the outflow based on the regular spring operation procedures (constrained to be at
least the outflow trigger) plus the additional volume needed for the spike flow. If the spikeFlowCheck
is FALSE, compute Powell's storage without spike flow consideration.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( spikeFlowCheck )
THEN
WITH NUMERIC powellStorage = "Operations"( month, previousPowellStorage ) DO
IF ( "ComputePowellSpill"( month, powellStorage, previousPowellStorage ) > 0.00000000 "acre-ft/month" )
THEN
"MakeListWithPolicyFlag"( powellStorage, 1.00000000 )
ELSE
"MakeListWithPolicyFlag"( "PowellComputeStorageAtGivenOutflow"( ( "PowellMinSpikeOutflow"( month, powellStorage, previousPowellStorage ) + $ "Powell Spike Flow Data.Additional Bypass Volume" [0.00000000, 0.00000000] / "GetDaysInMonth"( month ) ), previousPowellStorage, month ), 1.00000000 )
ENDIF
ENDWITH
ELSE
"ComputePowellStorageHybrid"( month, powellReleaseMade, previousPowellStorage, previousMeadStorage, storages, floodControlReleaseMade )
ENDIF;
END;
FUNCTION "ComputeStorageNOEqualizationNOminObjRelDD1" ( DATETIME month, NUMERIC powellReleaseMade, NUMERIC operationsStorage, NUMERIC previousPowellStorage )
RETURN_TYPE LIST;
SCALE_UNITS "acre-ft";
DESCRIPTION "Computes Powell's storage considering all possible operations excluding Equalization and
a spike flow release. The storage is first set by the basic operations procedure and then
adjusted, if need be, based on the Limit Outflow, Smooth July Operation or Minimum
Objective Release policies. This function returns a list that contains, at INDEX 0, the
resulting storage and at INDEX 1, an integer representing which operation set the storage.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( month >= @"24:00:00 July 31, Current Year" AND ( "PowellComputeStorageAtGivenOutflow"( 1500000.00000000 "acre-ft/month", previousPowellStorage, month ) < 23822000.00000000 "acre-ft" AND "ComputeOutflowAtGivenStorage"( % "Powell", $ "PowellMonthly.Inflow" [month], operationsStorage, previousPowellStorage, month ) > 1500000.00000000 "acre-feet/month" ) )
THEN
"MakeListWithPolicyFlag"( "LimitOutflow"( previousPowellStorage, month ), 4.00000000 )
ELSE
IF ( month == @"24:00:00 July 31, Current Year" AND operationsStorage > 23000000.00000000 "acre-feet" AND "ComputeOutflowAtGivenStorage"( % "Powell", $ "PowellMonthly.Inflow" [month], operationsStorage, previousPowellStorage, month ) < 1000000.00000000 "acre-feet/month" )
THEN
"MakeListWithPolicyFlag"( "SmoothJulyOperation"( previousPowellStorage, month ), 5.00000000 )
ELSE
"MakeListWithPolicyFlag"( operationsStorage, 7.00000000 )
ENDIF
ENDIF;
END;
FUNCTION "ComputeStorageWithEqualizationDD1" ( DATETIME month, NUMERIC powellReleaseMade, NUMERIC previousPowellStorage, NUMERIC previousMeadStorage, NUMERIC EOWYStoragePowell, NUMERIC powellForecastRelease, NUMERIC EOWYStorageMead, NUMERIC meadForecastRelease, NUMERIC operationsStorage, BOOLEAN floodControlReleaseMade )
RETURN_TYPE LIST;
SCALE_UNITS "acre-ft";
DESCRIPTION "This function first determines if the criteria for Equalization is met, and if so, computes
Powell's storage based on Equalization. If the criteria not met, Powell'e storage is
computed without Equalization. If Equalization occurs a check is made to ensure that, if it
2016 or earlier, that the Equalization release did not cause Powell's end of the water year
storage to drop below 14.85 MAF. In the case that it did drop below 14.85 MAF, the storage
is set to a minimum of 14.85 MAF and the storage resulting from Powell making the
minimum objective release for that month.
The criteria for Equalization is 1. that the end of the water year storage for Powell
(EOWYStoragePowell) computed with Powell's forecasted release from the current month
through Sept. (powellForecastRelease) must be greater than or equal to the end of the
water year storage for Mead (EOWYStorageMead) computed with Mead's forecasted
outflow from the current month through Sept. (meadForecastRelease) 2. the Upper Basin
Storage, computed with EOWYStoragePowell is greater than or equal the 602a storag
computed in Rule 1 602a Storage. 3. The current year is greater than 2016 or
EOWYStoragePowell is greater than or equal to 14.85 MAF.
";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"MakeListWithPolicyFlag"( "EqualizationDD1"( EOWYStoragePowell, EOWYStorageMead, meadForecastRelease, powellForecastRelease, powellReleaseMade, previousPowellStorage, previousMeadStorage, floodControlReleaseMade, month ), IF ( EOWYStorageMead > EOWYStoragePowell )
THEN
1010.00000000
ELSE
999.00000000
ENDIF );
END;
FUNCTION "ComputeStorageWithMOR" ( DATETIME month, NUMERIC operationsStorage, NUMERIC previousPowellStorage, NUMERIC powellReleaseMade )
RETURN_TYPE LIST;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
WITH NUMERIC minObjRelease = "PowellMinObjRelforCurrentMonth"( month, powellReleaseMade ) DO
IF ( "ComputeOutflowAtGivenStorage"( % "Powell", $ "PowellMonthly.Inflow" [month], operationsStorage, previousPowellStorage, month ) < minObjRelease )
THEN
"MakeListWithPolicyFlag"( "PowellComputeStorageAtGivenOutflow"( minObjRelease, previousPowellStorage, month ), 6.00000000 )
ELSE
"MakeListWithPolicyFlag"( operationsStorage, 7.00000000 )
ENDIF
ENDWITH;
END;
FUNCTION "EqualizationDD1" ( NUMERIC EOWYStoragePowell, NUMERIC EOWYStorageMead, NUMERIC meadForecastRelease, NUMERIC powellForecastRelease, NUMERIC powellReleaseMade, NUMERIC previousPowellStorage, NUMERIC previousMeadStorage, BOOLEAN floodControlReleaseMade, DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "This function returns Powell's Equalization (EQ) storage and requires the following
arguments: EOWYStoragePowell, EOWYStorageMead, UpperBasinStorage,
meadForecastRelease, powellForecastRelease, powellReleaseMade,
previousPowellStorage, previousMeadStorage, floodControlReleaseMade (boolean) and the
current month.
ComputeEqualizationReleaseList() returns the total release volume need for EQ.
ConvertPowellRelease() subtracts powellForecastRelease from the total volume; this is
the change in release necessary to Equalize. The converted release is then checked in
CheckEqualizationRelease602a() to ensure that it does not cause a violation of the 602a
storage. ComputePowellRelease() divides the EQ release by the number of months
remaining to the EOWY and adds this to Powell's current outflow.
PowellComputeStorageAtGivenOutflow() then computes the storage required to make the
compute EQ release for that month.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"PowellComputeStorageAtGivenOutflow"( "ComputePowellReleaseDD1"( "CheckEqualizationReleaseMPP"( "ConvertPowellReleaseHybrid"( "ComputeEqualizationReleaseListDD1"( EOWYStoragePowell, EOWYStorageMead, meadForecastRelease, powellForecastRelease, previousPowellStorage, previousMeadStorage, floodControlReleaseMade, month ), powellForecastRelease ), EOWYStoragePowell, EOWYStorageMead ), previousPowellStorage, powellReleaseMade, EOWYStoragePowell, month ), previousPowellStorage, month );
END;
FUNCTION "ComputePowellReleaseDD1" ( NUMERIC equalizationRelease, NUMERIC previousPowellStorage, NUMERIC powellReleaseMade, NUMERIC EOWYStoragePowell, DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet/month";
DESCRIPTION "Adds the current outflow from Powell to the estimated additional release needed to equalize
Powell and Mead by the end of the water year. To get the current outflow from Powell, the
storage must first be computed based on the the operation procedures other than
Equalization or Spike Flow. Recall that ComputeStorageWithNoEqualization() returns a list
that includes both the storage and policy flag. Here only the storage is of interest which is
the first element in the returned list (INDEX 0). GetListElement() retrieves the element at
one greater than the index argument. Also note that the result of this function is
constrained to a minimum of Powell's min release and maximum of Powell's max release.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT "AdjustedReleaseforCurrentMonth"( month, powellReleaseMade, $ "Powell Tiered Release.Monthly Release Pattern", "GetRowIndex"( $ "Powell Tiered Release.Monthly Release Pattern", STRINGIFY "700" ) );
MAX_CONSTRAINT IF ( EOWYStoragePowell < "ElevationToStorage"( % "Powell", $ "Coordinated Operation.Hybrid_PowellUpperTierElevation" [] ) )
THEN
"AdjustedReleaseforCurrentMonth"( month, powellReleaseMade, $ "Powell Tiered Release.Monthly Release Pattern", "GetRowIndex"( $ "Powell Tiered Release.Monthly Release Pattern", STRINGIFY "950" ) )
ELSE
"AdjustedReleaseforCurrentMonth"( month, powellReleaseMade, $ "Powell Tiered Release.Monthly Release Pattern", "GetRowIndex"( $ "Powell Tiered Release.Monthly Release Pattern", STRINGIFY "900" ) )
ENDIF;
BEGIN
"ComputeOutflowAtGivenStorage"( % "Powell", $ "PowellMonthly.Inflow" [month], GET @INDEX 0.00000000 FROM "ComputeStorageWithNOEqualization"( month, powellReleaseMade, previousPowellStorage ), previousPowellStorage, month ) + equalizationRelease / ( "NumberMonthsRemaining"( month ) * "GetDaysInMonth"( month ) );
END;
FUNCTION "ConvertPowellReleaseHybrid" ( LIST equalizationReleaseList, NUMERIC powellForecastRelease )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Subtracts the forecasted Powell release from the current month through the end of the
water year from the EQ release computed in ComputeEqualizationReleaseList(). The EQ
release at INDEX 0 is the most recently computed value. Recall that this EQ release is the
total volumetric release from Powell. It's necessary to subtract the forecasted release to
compute the extra release needed for EQ. Also note that the result of this function is
constrained to a minimum of 0.0 acre-ft.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
( ( GET @INDEX 0.00000000 FROM equalizationReleaseList ) - powellForecastRelease ) COMMENTED_BY "Min constraint (0) removed because reverse balancing is possible";
END;
FUNCTION "ForecastPowellReleaseDD1" ( DATETIME month, NUMERIC previousPowellStorage, NUMERIC powellReleaseMade, NUMERIC previousReleaseInt )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "This function forecasts Powell's release which is used to determine Powell's EOWYstorage
for Equalization. The estimated release is based on the spring operation through July and
the fall operation for Aug and Sept. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( month <= @"24:00:00 July 31, Current Year" )
THEN
WITH NUMERIC powellSpringOutflowVolConstrained = "SpringOutflowVolConstrainedDD1"( month, previousPowellStorage, powellReleaseMade, previousReleaseInt ) COMMENTED_BY "Outflow constrained by Powell's min and max releases." DO
powellSpringOutflowVolConstrained + "ForecastFallRangeOutflowVolumeDD1"( "ForecastPowellJulyStorage"( month, powellSpringOutflowVolConstrained, previousPowellStorage ), powellReleaseMade, @"24:00:00 August 31, Current Year", @"24:00:00 September 30, Current Year", month, previousReleaseInt ) COMMENTED_BY "Outflow also constrained by Powell's min and max releases."
ENDWITH
ELSE
"ForecastFallRangeOutflowVolumeDD1"( previousPowellStorage, powellReleaseMade, month, @"24:00:00 September 30, Current Year", month, previousReleaseInt )
ENDIF;
END;
FUNCTION "ComputeEqualizationReleaseListDD1" ( NUMERIC EOWYSPowell, NUMERIC EOWYSMead, NUMERIC meadForecastRelease, NUMERIC powellForecastRelease, NUMERIC previousPowellStorage, NUMERIC previousMeadStorage, BOOLEAN floodControlReleaseMade, DATETIME month )
RETURN_TYPE LIST;
SCALE_UNITS "";
DESCRIPTION "This function is an iterative computation of the total Powell release volume needed from
the current month through Sept to for Equalization (EQ) of Powell and Mead. An iterative
computation is required to account for evaporation and bank storage losses. A four
element list, named result, is returned by this function with the order: Total Equalization
Release (EQ release plus Powell's forecasted release), EOWYStoragePowell,
EOWYStorageMead, iteration count.
The list is first initialized with the function InitializedEqualizationReleaseList(). The next
step is to add 1.0 to the iteration count which is at INDEX 3 (or 4th element) in the list.
Then EOWYStorageMead is recomputed with EQ release computed in TotalPowellRelease()
and is stored at INDEX 2. Next, the EQ release is checked to ensure that it doesn't
violate 602aStorage or Mead's flood control space and if it does, it is adjusted properly
in ComputeNewPowellRelease(). Then EOWYStoragePowell is computed with the checked
EQ release and is stored at INDEX 1. Lastly, the EQ release is inserted the list position
INDEX 0.
The computation described above is repeated until 1. the absolute difference of
EOWYStoragePowell and EOWYStorageMead is less that the EQ tolerance (currently set
to 2,000 AF), or 2. the iteration count exceeds 30.0";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
WHILE ( "Abs"( ( GET @INDEX 1.00000000 FROM result ) - GET @INDEX 2.00000000 FROM result ) > $ "EqualizationData.EqualizationTolerance" [0.00000000, 0.00000000] AND ( GET @INDEX 3.00000000 FROM result ) < 30.00000000 ) WITH LIST result = "InitialEqualizationReleaseList"( EOWYSPowell, EOWYSMead, powellForecastRelease ) DO
INSERT "TotalPowellRelease"( result ) INTO INSERT "EOWYStorage"( % "Powell", "ComputeNewPowellReleaseDD1"( result, GET @INDEX 1.00000000 FROM result ), meadForecastRelease, previousPowellStorage, previousMeadStorage, month, floodControlReleaseMade ) INTO INSERT "EOWYStorage"( % "Mead", "TotalPowellRelease"( result ), meadForecastRelease, previousPowellStorage, previousMeadStorage, month, floodControlReleaseMade ) INTO INSERT ( GET @INDEX 3.00000000 FROM result ) + 1.00000000 INTO result
ENDWHILE;
END;
FUNCTION "ComputeNewPowellReleaseDD1" ( LIST results, NUMERIC EOWYSPowell )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Compute the new Powell release if the EQ release will cause Powell to violate the 602a
storage or Mead to violate its exclusive flood control space.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"TotalPowellRelease"( results ) + "CheckEqualizationReleaseDD1"( results, EOWYSPowell );
END;
FUNCTION "CheckEqualizationReleaseDD1" ( LIST results, NUMERIC EOWYSPowell )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "This function checks the EQ release for both 602a violation and Mead's exclusive flood
control space. First, the EQ release is checked for 602a violation in
CheckEqualizationRelease602a(). The result is then used, along with the current estimate
of Mead's EOWY Storage in CheckERMeadExclusiveFCS() to ensure that Mead's
exclusive flood control space is not violated.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"CheckERMeadExclusiveFCS"( GET @INDEX 2.00000000 FROM results, "EstimateEqualizationRelease"( GET @INDEX 1.00000000 FROM results, GET @INDEX 2.00000000 FROM results ) );
END;
FUNCTION "CheckEqualizationReleaseMPP" ( NUMERIC equalizationRelease, NUMERIC EOWYSPowell, NUMERIC EOWYSMead )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "This function does a final check on the EQ release from Powell to ensure that making this
release will not violate the Upper Basin 602a Storage. This check is computed by
subtracting the EQ release from the current month through the EOWY, from the amount of
storage in the Upper Basin (UpperBasinStorage). This value is then compared to the value
of 602a storage that has already been set by Rule 1 602a Storage. Also note that the
results of this check are also constrained by a minimum value of 0.0. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( EOWYSPowell - equalizationRelease < "ElevationToStorage"( % "Powell", $ "Coordinated Operation.Hybrid_PowellUpperTierElevation" [] ) AND EOWYSMead + equalizationRelease > "ElevationToStorage"( % "Mead", $ "Coordinated Operation.Hybrid_MeadMinBalancingElevation" [] ) )
THEN
"ElevationToStorage"( % "Mead", $ "Coordinated Operation.Hybrid_MeadMinBalancingElevation" [] ) - EOWYSMead
ELSE
equalizationRelease
ENDIF COMMENTED_BY "Constrains the equalization release to keep Mead above min balance elevation if release will drop Powell below upper tier AND Mead below min balance elevation. Constraint for lower tier at Powell needed because balancing occurs down to dead pool if possible.";
END;
FUNCTION "SpringOutflowVolConstrainedDD1" ( DATETIME month, NUMERIC previousPowellStorage, NUMERIC powellReleaseMade, NUMERIC previousReleaseInt )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes the spring outflow volume and constrains it to a max of Powell's max release
volume and a min of Powell's min release volume.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT IF ( previousReleaseInt == 999.00000000 )
THEN
"PowellMinObjRelVolumeSpringDD2"( month, @"24:00:00 July 31, Current Year", powellReleaseMade, previousPowellStorage, "700" )
ELSE
"Max"( "MinReleaseVolume"( % "Powell", month, @"24:00:00 July 31, Current Year" ), IF ( previousReleaseInt == 748.00000000 )
THEN
"PowellMinObjRelVolumeSpringDD2"( month, @"24:00:00 July 31, Current Year", powellReleaseMade, previousPowellStorage, "748" )
ELSE
"PowellMinObjRelVolumeSpringDD2"( month, @"24:00:00 July 31, Current Year", powellReleaseMade, previousPowellStorage, "823" )
ENDIF )
ENDIF;
MAX_CONSTRAINT IF ( previousReleaseInt == 999.00000000 )
THEN
"PowellMinObjRelVolumeSpringDD2Max"( month, @"24:00:00 July 31, Current Year", powellReleaseMade, previousPowellStorage )
ELSE
"MaxReleaseVolume"( % "Powell", month, @"24:00:00 July 31, Current Year" )
ENDIF;
BEGIN
"PowellSpringOutflowVolume"( month, previousPowellStorage );
END;
FUNCTION "ForecastFallRangeOutflowVolumeDD1" ( NUMERIC initialStorage, NUMERIC powellReleaseMade, DATETIME startDate, DATETIME endDate, DATETIME month, NUMERIC previousReleaseInt )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Estimates Powell's outflow volume for Aug-Sept or Aug by using an estimated July
storage as the initial storage. The min constraint on the outflow volume is the
min release volume. The max constraint is the max release volume. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT IF ( previousReleaseInt == 999.00000000 )
THEN
"PowellMinObjRelVolRemainingDD2"( month, powellReleaseMade, "700" ) * ( "PowellSumReleaseWeights"( startDate, endDate ) / "PowellSumReleaseWeights"( month, endDate ) )
ELSE
"Max"( "MinReleaseVolume"( % "Powell", startDate, endDate ), IF ( previousReleaseInt == 748.00000000 )
THEN
"PowellMinObjRelVolRemainingDD2"( month, powellReleaseMade, "748" ) * ( "PowellSumReleaseWeights"( startDate, endDate ) / "PowellSumReleaseWeights"( month, endDate ) )
ELSE
"PowellMinObjRelVolRemainingDD2"( month, powellReleaseMade, "823" ) * ( "PowellSumReleaseWeights"( startDate, endDate ) / "PowellSumReleaseWeights"( month, endDate ) )
ENDIF )
ENDIF;
MAX_CONSTRAINT IF ( previousReleaseInt == 999.00000000 )
THEN
"PowellMinObjRelVolRemainingDD2Max"( month, powellReleaseMade ) * ( "PowellSumReleaseWeights"( startDate, endDate ) / "PowellSumReleaseWeights"( month, endDate ) )
ELSE
"MaxReleaseVolume"( % "Powell", startDate, endDate )
ENDIF;
BEGIN
"PowellFallOutflowVolume"( initialStorage, startDate, @"24:00:00 December 31, Current Year", month ) * ( "PowellSumReleaseWeights"( startDate, endDate ) / "PowellSumReleaseWeights"( startDate, @"24:00:00 December 31, Current Year" ) );
END;
FUNCTION "fallConstraint" ( DATETIME month, DATETIME startDate, DATETIME endDate, NUMERIC powellReleaseMade, NUMERIC previousReleaseInt )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( previousReleaseInt == 999.00000000 )
THEN
"PowellMinObjRelVolRemainingDD2Max"( month, powellReleaseMade ) * ( "PowellSumReleaseWeights"( startDate, endDate ) / "PowellSumReleaseWeights"( month, endDate ) )
ELSE
"MaxReleaseVolume"( % "Powell", startDate, endDate )
ENDIF;
END;
FUNCTION "springConstraint" ( DATETIME month, DATETIME startDate, DATETIME endDate, NUMERIC powellReleaseMade, NUMERIC previousReleaseInt, NUMERIC previousPowellStorage )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( previousReleaseInt == 999.00000000 )
THEN
"PowellMinObjRelVolumeSpringDD2Max"( month, @"24:00:00 July 31, Current Year", powellReleaseMade, previousPowellStorage )
ELSE
"MaxReleaseVolume"( % "Powell", month, @"24:00:00 July 31, Current Year" )
ENDIF;
END;
FUNCTION "PowellMinObjRelVolumeSpringDD2" ( DATETIME month, DATETIME endDate, NUMERIC powellReleaseMade, NUMERIC previousPowellStorage, STRING release )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Estimates the volume of minimum objective release remaining from the current month
through the endDate and scales it by the ratio of the amount remaining through the EOWY
to the annual value. The volume is constrained to be at least 0.0 acre-ft.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT 0.00000000 "acre-feet";
BEGIN
"SumTableRow"( $ "Powell Tiered Release.Monthly Release Pattern", "GetRowIndex"( $ "Powell Tiered Release.Monthly Release Pattern", release ), "GetColumnIndex"( $ "Powell Tiered Release.Monthly Release Pattern", "GetMonthAsString"( month ) ), "GetColumnIndex"( $ "Powell Tiered Release.Monthly Release Pattern", "GetMonthAsString"( endDate ) ) ) * ( ( "SumTableRow"( $ "Powell Tiered Release.Monthly Release Pattern", "GetRowIndex"( $ "Powell Tiered Release.Monthly Release Pattern", release ), 0.00000000, 11.00000000 ) - powellReleaseMade ) / "SumTableRow"( $ "Powell Tiered Release.Monthly Release Pattern", "GetRowIndex"( $ "Powell Tiered Release.Monthly Release Pattern", release ), 0.00000000, 11.00000000 ) );
END;
FUNCTION "PowellMinObjRelVolumeSpringDD2Max" ( DATETIME month, DATETIME endDate, NUMERIC powellReleaseMade, NUMERIC previousPowellStorage )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Estimates the volume of minimum objective release remaining from the current month
through the endDate and scales it by the ratio of the amount remaining through the EOWY
to the annual value. The volume is constrained to be at least 0.0 acre-ft.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT 0.00000000 "acre-feet";
BEGIN
"SumTableRow"( $ "Powell Tiered Release.Monthly Release Pattern", "GetRowIndex"( $ "Powell Tiered Release.Monthly Release Pattern", "950" ), "GetColumnIndex"( $ "Powell Tiered Release.Monthly Release Pattern", "GetMonthAsString"( month ) ), "GetColumnIndex"( $ "Powell Tiered Release.Monthly Release Pattern", "GetMonthAsString"( endDate ) ) ) * ( ( "SumTableRow"( $ "Powell Tiered Release.Monthly Release Pattern", "GetRowIndex"( $ "Powell Tiered Release.Monthly Release Pattern", "950" ), 0.00000000, 11.00000000 ) - powellReleaseMade ) / "SumTableRow"( $ "Powell Tiered Release.Monthly Release Pattern", "GetRowIndex"( $ "Powell Tiered Release.Monthly Release Pattern", "950" ), 0.00000000, 11.00000000 ) );
END;
FUNCTION "PowellMinObjRelVolRemainingDD2" ( DATETIME month, NUMERIC powellReleaseMade, STRING release )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes the outflow volume remaining that Powell must release to meet its minimum
objective release by the end of the water year by taking into account the actual releases
already made. The outflow volume is constrained to a minimum of 0.0 acre-ft.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT 0.00000000 "acre-feet";
BEGIN
"SumTableRow"( $ "Powell Tiered Release.Monthly Release Pattern", "GetRowIndex"( $ "Powell Tiered Release.Monthly Release Pattern", release ), 0.00000000, 11.00000000 ) - powellReleaseMade;
END;
FUNCTION "PowellMinObjRelVolRemainingDD2Max" ( DATETIME month, NUMERIC powellReleaseMade )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes the outflow volume remaining that Powell must release to meet its minimum
objective release by the end of the water year by taking into account the actual releases
already made. The outflow volume is constrained to a minimum of 0.0 acre-ft.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT 0.00000000 "acre-feet";
BEGIN
"SumTableRow"( $ "Powell Tiered Release.Monthly Release Pattern", "GetRowIndex"( $ "Powell Tiered Release.Monthly Release Pattern", "950" ), 0.00000000, 11.00000000 ) - powellReleaseMade;
END;
FUNCTION "GetPreviousMonthReleaseDD2" ( DATETIME month, LIST storages )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( "PolicyFlagListElement"( month, storages ) == 999.00000000 )
THEN
999.00000000 COMMENTED_BY "999 is DD2 Equalization"
ELSE
IF ( "PolicyFlagListElement"( month, storages ) == 748.00000000 )
THEN
748.00000000
ELSE
IF ( "PolicyFlagListElement"( month, storages ) == 823.00000000 )
THEN
823.00000000
ELSE
0.00000000
ENDIF
ENDIF
ENDIF;
END;
FUNCTION "PolicyFlagListElement" ( DATETIME month, LIST storages )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"GetListElement"( "GetMonth"( month ) * 3.00000000 - 1.00000000, storages );
END;
FUNCTION "AdjustedReleaseforCurrentMonth" ( DATETIME month, NUMERIC powellReleaseMade, SLOT monthlyReleasePattern, NUMERIC rowIndex )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft/month";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT "MinRelease"( % "Powell" );
BEGIN
"AdjustedRelVolRemaining"( month, powellReleaseMade, monthlyReleasePattern, rowIndex ) * ( "MonthlyRelPatternReducedRelease"( monthlyReleasePattern, rowIndex, month ) / "ComputeAdjustedReleaseRemaining"( month, monthlyReleasePattern, rowIndex ) ) / "GetDaysInMonth"( month );
END;
FUNCTION "AdjustedReleaseforCurrentMonth1" ( DATETIME month, NUMERIC powellReleaseMade, SLOT monthlyReleasePattern, NUMERIC rowIndex )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft/month";
DESCRIPTION "";
ACTIVE FALSE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT "MinRelease"( % "Powell" );
BEGIN
( "MonthlyRelPatternReducedRelease"( monthlyReleasePattern, rowIndex, month ) / "ComputeAdjustedReleaseRemaining"( month, monthlyReleasePattern, rowIndex ) ) * "AdjustedRelVolRemaining"( month, powellReleaseMade, monthlyReleasePattern, rowIndex ) / "GetDaysInMonth"( month );
END;
FUNCTION "ComputeAdjustedReleaseRemaining" ( DATETIME month, SLOT monthlyReleasePattern, NUMERIC rowIndex )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( month == @"24:00:00 October 31, Current Year" )
THEN
"SumAnnualRelease"( monthlyReleasePattern, rowIndex )
ELSE
"SumTableRow"( monthlyReleasePattern, rowIndex, "GetColumnIndex"( monthlyReleasePattern, "GetMonthAsString"( month ) ), "GetColumnIndex"( monthlyReleasePattern, "GetMonthAsString"( @"24:00:00 September 30, Current Year" ) ) )
ENDIF;
END;
FUNCTION "AdjustedRelVolRemaining" ( DATETIME month, NUMERIC powellReleaseMade, SLOT monthlyReleasePattern, NUMERIC rowIndex )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"SumAnnualRelease"( monthlyReleasePattern, rowIndex ) - powellReleaseMade;
END;
FUNCTION "DetermineTieredReleaseDD2" ( DATETIME month, NUMERIC powellReleaseMade, NUMERIC EOWYSPowell, NUMERIC EOWYSMead, LIST storages )
RETURN_TYPE LIST;
SCALE_UNITS "acre-ft";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( month <= @"24:00:00 September 30, Current Year" )
THEN
WITH NUMERIC EOWYEPowell = "StorageToElevation"( % "Powell", EOWYSPowell ) DO
IF ( EOWYEPowell < $ "Coordinated Operation.Hybrid_PowellUpperTierElevation" [] AND EOWYEPowell >= $ "Coordinated Operation.Hybrid_PowellLowerTierElevation" [] )
THEN
IF ( "StorageToElevation"( % "Mead", EOWYSMead ) <= $ "Coordinated Operation.Hybrid_Mead823Trigger" [] )
THEN
"MakeListWithPolicyFlag"( "AdjustedReleaseforCurrentMonth"( month, powellReleaseMade, $ "Powell Tiered Release.Monthly Release Pattern", "GetRowIndex"( $ "Powell Tiered Release.Monthly Release Pattern", STRINGIFY "823" ) ), 823.00000000 )
ELSE
"MakeListWithPolicyFlag"( "AdjustedReleaseforCurrentMonth"( month, powellReleaseMade, $ "Powell Tiered Release.Monthly Release Pattern", "GetRowIndex"( $ "Powell Tiered Release.Monthly Release Pattern", STRINGIFY "748" ) ), 748.00000000 )
ENDIF
ELSE
"MakeListWithPolicyFlag"( "AdjustedReleaseforCurrentMonth"( month, powellReleaseMade, $ "Powell Tiered Release.Monthly Release Pattern", "GetRowIndex"( $ "Powell Tiered Release.Monthly Release Pattern", STRINGIFY "823" ) ), 823.00000000 )
ENDIF
ENDWITH
ELSE
WITH NUMERIC SeptPowellElev = "StorageToElevation"( % "Powell", "GetSeptemberCurrentYearStorage"( % "Powell", storages ) ) DO
IF ( SeptPowellElev < $ "Coordinated Operation.Hybrid_PowellUpperTierElevation" [] AND SeptPowellElev >= $ "Coordinated Operation.Hybrid_PowellLowerTierElevation" [] )
THEN
IF ( "StorageToElevation"( % "Mead", "GetSeptemberCurrentYearStorage"( % "Mead", storages ) ) <= $ "Coordinated Operation.Hybrid_Mead823Trigger" [] )
THEN
"MakeListWithPolicyFlag"( "AdjustedReleaseforCurrentMonth"( month, powellReleaseMade, $ "Powell Tiered Release.Monthly Release Pattern", "GetRowIndex"( $ "Powell Tiered Release.Monthly Release Pattern", STRINGIFY "823" ) ), 823.00000000 )
ELSE
"MakeListWithPolicyFlag"( "AdjustedReleaseforCurrentMonth"( month, powellReleaseMade, $ "Powell Tiered Release.Monthly Release Pattern", "GetRowIndex"( $ "Powell Tiered Release.Monthly Release Pattern", STRINGIFY "748" ) ), 748.00000000 )
ENDIF
ELSE
"MakeListWithPolicyFlag"( "AdjustedReleaseforCurrentMonth"( month, powellReleaseMade, $ "Powell Tiered Release.Monthly Release Pattern", "GetRowIndex"( $ "Powell Tiered Release.Monthly Release Pattern", STRINGIFY "823" ) ), 823.00000000 )
ENDIF
ENDWITH
ENDIF;
END;
FUNCTION "GetSeptemberCurrentYearStorage" ( OBJECT reservoir, LIST storages )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( ( STRINGIFY reservoir ) == "Powell" )
THEN
"GetListElement"( 28.00000000, storages )
ELSE
"GetListElement"( 30.00000000, storages )
ENDIF;
END;
FUNCTION "ComputePowellPortion602aStorage" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "EqualizationData.value602a" [] - ( $ "UBRuleCurveData.ReservoirData" ["GetRowIndex"( $ "UBRuleCurveData.ReservoirData", "FlamingGorge" ), "GetColumnIndex"( $ "UBRuleCurveData.ReservoirData", "liveCapacityStorage" )] + $ "UBRuleCurveData.ReservoirData" ["GetRowIndex"( $ "UBRuleCurveData.ReservoirData", "BlueMesa" ), "GetColumnIndex"( $ "UBRuleCurveData.ReservoirData", "liveCapacityStorage" )] + $ "UBRuleCurveData.ReservoirData" ["GetRowIndex"( $ "UBRuleCurveData.ReservoirData", "Navajo" ), "GetColumnIndex"( $ "UBRuleCurveData.ReservoirData", "liveCapacityStorage" )] );
END;
FUNCTION "MonthlyRelPatternReducedRelease" ( SLOT monthlyReleasePattern, NUMERIC rowIndex, DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
monthlyReleasePattern [rowIndex, "GetMonthAsString"( month )];
END;
END;
UTILITY_GROUP "Limit Outflow Function";
DESCRIPTION "";
ACTIVE TRUE;
BEGIN
FUNCTION "LimitOutflow" ( NUMERIC previousPowellStorage, DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "Returns Powell's storage with the outflow limited to 1.5 MAF/mo. This function should only
be called under the following pre-existing conditions: 1. The current month is July-Dec
2. Powell's current release is greater than 1.5 MAF/mo. 3. It has been determined that a
release of 1.5 MAF/mo. will result in a storage of less than 23.822 MAF.
";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"PowellComputeStorageAtGivenOutflow"( 25000.00000000 "cfs", previousPowellStorage, month );
END;
END;
UTILITY_GROUP "Smooth July Operation Function";
DESCRIPTION "";
ACTIVE TRUE;
BEGIN
FUNCTION "SmoothJulyOperation" ( NUMERIC previousPowellStorage, DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "Returns Powell's storage with an outflow of 1.0 MAF/mo. This function should only be
called under the following pre-existing conditions: 1. The current month is July 2. Powell's
current outflow is less than 1.0 MAF/mo. 3. Powell's current storage is greater than
23 MAF";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"PowellComputeStorageAtGivenOutflow"( 1000000.00000000 "acre-ft/month", previousPowellStorage, month );
END;
END;
UTILITY_GROUP "MOR Functions";
DESCRIPTION "";
ACTIVE TRUE;
BEGIN
FUNCTION "MeetMinimumObjectiveRelease" ( NUMERIC outflow, NUMERIC previousPowellStorage, DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "This function constrains Powell's storage to be at least that required for a minimum
objective release for the current month. This function is called from
ComputeStorageWithNOEqualization and the outflow passed to this function was computed
in PowellMinObjRelforCurrentMonth().";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"PowellComputeStorageAtGivenOutflow"( outflow, previousPowellStorage, month );
END;
FUNCTION "ComputePowellReleaseMade" ( DATETIME month, LIST storages )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "Determines the release made from Powell from the start of the WY to the
previous month. This quantity is used to determine whether or not Powell
has met its minimum objective release for the current month.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( month == @"24:00:00 January 31, Current Year" )
THEN
"PowellFallRelease"( )
ELSE
IF ( month > @"24:00:00 January 31, Current Year" AND month < @"24:00:00 October 31, Current Year" )
THEN
"PowellFallRelease"( ) + "PowellReleaseJanToPreviousMonth"( month, storages )
ELSE
IF ( month == @"24:00:00 October 31, Current Year" )
THEN
0.00000000 "acre-ft"
ELSE
"PowellReleaseOctToPreviousMonth"( month, storages )
ENDIF
ENDIF
ENDIF;
END;
FUNCTION "PowellFallRelease" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "Returns Powell's fall release by solving for outflow with the previous year's
fall storages stored on the reservoir object (Powell.Monthly Storage). If it is
the start of the run, fall storages of the previous year do not exist. The fall
release is computed by summing the input values for Powell's release for the
previous fall.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( @"t" == @"Start Timestep" )
THEN
"SumFlowsToVolume"( $ "PowellData.PowellFallRelease", @"24:00:00 October 31, Previous Year", @"24:00:00 December 31, Previous Year" )
ELSE
( "ComputeOutflowAtGivenStorageNoConstraint"( % "Powell", $ "PowellMonthly.Inflow" [@"24:00:00 October 31, Previous Year"], $ "Powell.Monthly Storage" [@"24:00:00 October 31, Previous Year"], $ "Powell.Monthly Storage" [@"24:00:00 September 30, Previous Year"], @"24:00:00 October 31, Previous Year" ) * "GetDaysInMonth"( @"24:00:00 October 31, Previous Year" ) ) + ( "ComputeOutflowAtGivenStorageNoConstraint"( % "Powell", $ "PowellMonthly.Inflow" [@"24:00:00 November 30, Previous Year"], $ "Powell.Monthly Storage" [@"24:00:00 November 30, Previous Year"], $ "Powell.Monthly Storage" [@"24:00:00 October 31, Previous Year"], @"24:00:00 November 30, Previous Year" ) * "GetDaysInMonth"( @"24:00:00 November 30, Previous Year" ) ) + ( "ComputeOutflowAtGivenStorageNoConstraint"( % "Powell", $ "PowellMonthly.Inflow" [@"24:00:00 December 31, Previous Year"], $ "Powell.Monthly Storage" [@"24:00:00 December 31, Previous Year"], $ "Powell.Monthly Storage" [@"24:00:00 November 30, Previous Year"], @"24:00:00 December 31, Previous Year" ) * "GetDaysInMonth"( @"24:00:00 December 31, Previous Year" ) )
ENDIF;
END;
FUNCTION "ComputeMinObjReleaseRemaining" ( DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Returns the sum of the remaining scheduled minimum objective releases from the current
month through the end of the water year.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( month < @"24:00:00 October 31, Current Year" )
THEN
"SumTableRow"( $ "UBRuleCurveData.PowellMinObjectiveRelease", 0.00000000, "GetMonth"( month ) - 1.00000000, 8.00000000 )
ELSE
IF ( month == @"24:00:00 October 31, Current Year" )
THEN
"AnnualMinObjectiveRelease"( )
ELSE
"AnnualMinObjectiveRelease"( ) - "SumTableRow"( $ "UBRuleCurveData.PowellMinObjectiveRelease", 0.00000000, 9.00000000, ( "GetMonth"( month ) - 2.00000000 ) )
ENDIF
ENDIF;
END;
FUNCTION "PowellMinObjRelVolumeSpring" ( DATETIME month, DATETIME endDate, NUMERIC powellReleaseMade, NUMERIC previousPowellStorage )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Estimates the volume of minimum objective release remaining from the current month
through the endDate and scales it by the ratio of the amount remaining through the EOWY
to the annual value. The volume is constrained to be at least 0.0 acre-ft.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT 0.00000000 "acre-feet";
BEGIN
"SumTableRow"( $ "UBRuleCurveData.PowellMinObjectiveRelease", 0.00000000, "GetMonth"( month ) - 1.00000000, "GetMonth"( endDate ) - 1.00000000 ) * ( "PowellMinObjRelVolRemaining"( month, powellReleaseMade ) / "AnnualMinObjectiveRelease"( ) );
END;
FUNCTION "ComputeOutflowAtGivenStorageNoConstraint" ( OBJECT reservoir, NUMERIC inflow, NUMERIC storage, NUMERIC previousStorage, DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft/month";
DESCRIPTION "Returns the resulting outflow that given the above values will mass balance the
reservoir. The resulting outflow is not constrained because this is simulating the
actual dispatch method on the reservoir which, in the case of a negative outflow,
issues a warning and sets the slot with the negative value. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"SolveMonthlyOutflowAnnualTimestep"( reservoir, inflow, storage, previousStorage, month );
END;
FUNCTION "PowellMinObjRelforCurrentMonth" ( DATETIME month, NUMERIC powellReleaseMade )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft/month";
DESCRIPTION "Computes the minimum objective release for the current month by multiplying the volume
remaining to meet 8.23 MAF by the end of the water year by a release fraction. The release
fraction is computed as the scheduled min obj rel for the current month (stored in the
data obj UBRuleCurveData) divided by the sum of the remaining scheduled min obj
releases. The result of this function is contrained to a minimum of 0.0 acre-ft/mo.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT 0.00000000 "acre-feet/month";
BEGIN
( "PowellMinObjRelVolRemaining"( month, powellReleaseMade ) * ( $ "UBRuleCurveData.PowellMinObjectiveRelease" [0.00000000, "GetMonth"( month ) - 1.00000000] / "ComputeMinObjReleaseRemaining"( month ) ) ) / "GetDaysInMonth"( month );
END;
FUNCTION "PowellMinObjRelVolRemaining" ( DATETIME month, NUMERIC powellReleaseMade )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes the outflow volume remaining that Powell must release to meet its minimum
objective release by the end of the water year by taking into account the actual releases
already made. The outflow volume is constrained to a minimum of 0.0 acre-ft.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT 0.00000000 "acre-feet";
BEGIN
"AnnualMinObjectiveRelease"( ) - powellReleaseMade;
END;
FUNCTION "PowellReleaseOctToPreviousMonth" ( DATETIME month, LIST storages )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "Sums Powell's release from October to the previous month. Using the month's
storage, the release is solved for in ComputeOutflowAtGivenStorageNoConstraint().
The FLOW value returned is converted to a VOLUME by multiplying by the days in
the month. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
FOR ( DATETIME date IN "GetDates"( @"24:00:00 October 31, Current Year", "OffsetDate"( month, - 1.00000000, "1 months" ), "1 months" ) ) WITH NUMERIC sum = 0.00000000 "acre-feet" DO
sum + "ComputeOutflowAtGivenStorageNoConstraint"( % "Powell", $ "PowellMonthly.Inflow" [date], "GetListElement"( ( "GetMonth"( date ) * 3.00000000 ) + 1.00000000, storages ), "GetListElement"( ( "GetMonth"( date ) * 3.00000000 - 2.00000000 ), storages ), date ) * "GetDaysInMonth"( date )
ENDFOR;
END;
FUNCTION "PowellReleaseJanToPreviousMonth" ( DATETIME month, LIST storages )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "Sums Powell's release from January to the previous month. Using the month's
storage, the release is solved for in ComputeOutflowAtGivenStorageNoConstraint().
The FLOW value returned is converted to a VOLUME by multiplying by the days in
the month.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
FOR ( DATETIME date IN "GetDates"( @"24:00:00 January 31, Current Year", "OffsetDate"( month, - 1.00000000, "1 months" ), "1 months" ) ) WITH NUMERIC sum = 0.00000000 "acre-feet" DO
sum + "ComputeOutflowAtGivenStorageNoConstraint"( % "Powell", $ "PowellMonthly.Inflow" [date], "GetListElement"( ( "GetMonth"( date ) * 3.00000000 ) + 1.00000000, storages ), "GetListElement"( ( "GetMonth"( date ) * 3.00000000 - 2.00000000 ), storages ), date ) * "GetDaysInMonth"( date )
ENDFOR;
END;
END;
UTILITY_GROUP "Operations Functions";
DESCRIPTION "";
ACTIVE TRUE;
BEGIN
FUNCTION "Operations" ( DATETIME month, NUMERIC previousPowellStorage )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "This function computes Powell's storage based on the assumption that Powell
will meet a July target storage in the spring (Jan - July) or a December target in
the fall (Aug - Dec) and the regulated infow forecast computed in Rule 5 Powell
Spring Runoff Forecast. The inflow forecast for the spring includes the forecast
error while the inflow forecast for the fall does not. The outflow volume required
to meet the target storage is multiplied by a release fraction to determine the
outflow for the current month.
";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( month <= @"24:00:00 July 31, Current Year" )
THEN
"PowellRunoffSeasonStorage"( previousPowellStorage, month )
ELSE
"PowellFallSeasonStorage"( previousPowellStorage, month )
ENDIF;
END;
FUNCTION "PowellRunoffSeasonStorage" ( NUMERIC previousPowellStorage, DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "This function takes the computed runoff season release and computes the
resulting storage given the inflow at the current month.
PowellComputeStorageAtGivenOutflow constrains the resulting storage to be
within inactive and live capacity.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT "InactiveCapacity"( % "Powell" );
MAX_CONSTRAINT "LiveCapacity"( % "Powell" );
BEGIN
"PowellComputeStorageAtGivenOutflow"( "PowellComputeRunoffSeasonRelease"( previousPowellStorage, month ), previousPowellStorage, month );
END;
FUNCTION "PowellComputeRunoffSeasonRelease" ( NUMERIC previousPowellStorage, DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "cfs";
DESCRIPTION "This function computes the release for the month based on the spring outflow volume and the release
weights. It is constrained by the minimum and maximum release. It also checks to see if the outflow
volume average (equally distributed over the remaining months) exceeds a check (currently 1 MAF/mo).
If so, the outflow is equally weighted for the remaining months. This was added to account for high
forecast years, where real operation would require releasing the water quicker than what the current
weights allow.
";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT "MinRelease"( % "Powell" );
MAX_CONSTRAINT "MaxRelease"( % "Powell" );
BEGIN
WITH NUMERIC powellSpringOutflowVolume = "PowellSpringOutflowVolume"( month, previousPowellStorage ) DO
WITH NUMERIC powellSpringOutflowAverage = "PowellSpringOutflowAverage"( powellSpringOutflowVolume, month ) DO
IF ( powellSpringOutflowAverage > $ "UBRuleCurveData.Powell Outflow Check" [0.00000000, 0.00000000] )
THEN
powellSpringOutflowAverage
ELSE
powellSpringOutflowVolume * "PowellReleaseFraction"( month, @"24:00:00 July 31, Current Year" ) / "GetDaysInMonth"( month )
ENDIF
ENDWITH
ENDWITH;
END;
FUNCTION "PowellSpringOutflowVolume" ( DATETIME month, NUMERIC previousPowellStorage )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "This function computes the total outflow volume from Powell (current month through July)
required to meet the July target storage. The regulated inflow forecast includes a forecast
error and was computed in Rule 5, Powell Spring Runoff Forecast. This value is allowed to
be negative. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
WITH NUMERIC endStorage = "UBTargetStorage"( "Powell", @"24:00:00 July 31, Current Year" ) DO
previousPowellStorage - endStorage + $ "Powell Forecast Data.Reg Inflow with Error" [month] - "EstimateEvaporation"( % "Powell", previousPowellStorage, endStorage, month, @"24:00:00 July 31, Current Year" ) - "Estimate Bank Storage without Evap"( % "Powell", previousPowellStorage, endStorage )
ENDWITH;
END;
FUNCTION "PowellSpringOutflowAverage" ( NUMERIC powellSpringOutflowVolume, DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet/month";
DESCRIPTION "Computes the average spring outflow by equally distributing the spring outflow
volume over the remaining months to July. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
powellSpringOutflowVolume / ( ( "GetMonth"( @"24:00:00 July 31, Current Year" ) - "GetMonth"( month ) ) + 1.00000000 ) / "GetDaysInMonth"( month );
END;
FUNCTION "PowellFallSeasonStorage" ( NUMERIC previousPowellStorage, DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "This function takes the computed fall season release and computes the
resulting storage given the inflow for the current month.
PowellComputeStorageAtGivenOutflow constrains the resulting storage to be
within inactive and live capacity.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"PowellComputeStorageAtGivenOutflow"( "PowellComputeFallSeasonRelease"( previousPowellStorage, month ), previousPowellStorage, month );
END;
FUNCTION "PowellComputeFallSeasonRelease" ( NUMERIC previousPowellStorage, DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet/month";
DESCRIPTION "This function computes the release for the month based on the outflow volume required from the
current month through December for Powell to meet a December target storage and the current
month's release fraction. The release is constrained by Powell's minimum and maximum releases.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT "MinRelease"( % "Powell" );
MAX_CONSTRAINT "MaxRelease"( % "Powell" );
BEGIN
"PowellFallOutflowVolume"( previousPowellStorage, month, @"24:00:00 December 31, Current Year", month ) * "PowellReleaseFraction"( month, @"24:00:00 December 31, Current Year" ) / "GetDaysInMonth"( month );
END;
FUNCTION "PowellFallOutflowVolume" ( NUMERIC startStorage, DATETIME startDate, DATETIME endDate, DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "This function computes the outflow volume from Powell from the current month
through December necessary to meet the December target.
It assumes a perfect forecast, i.e. no forecast error is applied to the inflow forecast.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
WITH NUMERIC endStorage = "UBTargetStorage"( "Powell", endDate ) DO
startStorage - endStorage + "PowellRegulatedInflowVolume"( startDate, endDate, month ) - "EstimateEvaporation"( % "Powell", startStorage, endStorage, startDate, endDate ) - "Estimate Bank Storage without Evap"( % "Powell", startStorage, endStorage )
ENDWITH;
END;
FUNCTION "PowellSumReleaseWeights" ( DATETIME startDate, DATETIME endDate )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "Sums the monthly outflow weights for Powell's minimum objective release from the
startDate to endDate.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"SumTableRow"( $ "UBRuleCurveData.Outflow Weights", 0.00000000, "GetMonth"( startDate ) - 1.00000000, "GetMonth"( endDate ) - 1.00000000 );
END;
FUNCTION "PowellReleaseFraction" ( DATETIME startDate, DATETIME endDate )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "This function computes the release fraction for the current month by dividing the current
month's weight by the sum of the weights from the current month through July or December.
Since the tables are indexed from zero, subtract 1 from the numeric month. This function
should only be called with an endDate of either July or December.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "UBRuleCurveData.Outflow Weights" [0.00000000, "GetMonth"( startDate ) - 1.00000000] / "SumTableRow"( $ "UBRuleCurveData.Outflow Weights", 0.00000000, "GetMonth"( startDate ) - 1.00000000, "GetMonth"( endDate ) - 1.00000000 );
END;
FUNCTION "PowellRegulatedInflowVolume" ( DATETIME startDate, DATETIME endDate, DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Returns Powell's regulated inflow forecast from the startDate through the
endDate. No forecast error is used. The natural inflow is adjusted for Upper
Basin depletions and potential reservoir regulation. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT 0.00000000 "acre-ft";
BEGIN
"PowellNaturalInflowVolume"( startDate, endDate ) - "UBDepletionsRange"( startDate, endDate ) - "UBRegulation"( startDate, endDate, month );
END;
FUNCTION "PowellNaturalInflowVolume" ( DATETIME startDate, DATETIME endDate )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Sums the natural flows above Powell over startDate through endDate and
converts to a volume.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"SumFlowsToVolume"( $ "TotVal.Powell_ByTrace", startDate, endDate );
END;
FUNCTION "UBDepletionsRange" ( DATETIME startDate, DATETIME endDate )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Returns the Upper Basin depletions from the startDate to the endDate. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "EqualizationData.UBDepletion" [] * "SumTableRow"( $ "MeadFloodControl.Upper Basin Distribution", 0.00000000, "GetMonth"( startDate ) - 1.00000000, "GetMonth"( endDate ) - 1.00000000 );
END;
FUNCTION "UBRegulation" ( DATETIME startDate, DATETIME endDate, DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Returns the total amount of storage in the Upper Basin Effective Reservoirs
from one month prior to the startDate through the endDate. This value is used to
compute PowellRegulatedInflowVolume() during the fall months, meaning the
total regulation is essentially the total amount of drawdown. For fall drawdown,
this returns a negative number.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
FOR ( STRING reservoir IN { "FlamingGorge" , "Fontenelle" , "BlueMesa" , "Navajo" } ) WITH NUMERIC sum = 0.00000000 "acre-feet" DO
sum + "UBDrawDown"( reservoir, startDate, endDate, month )
ENDFOR;
END;
FUNCTION "UBTargetStorage" ( STRING reservoir, DATETIME date )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes the reservoir's target storage as the difference between the live
capacity and target space for that month. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "UBRuleCurveData.ReservoirData" [reservoir, "liveCapacityStorage"] - $ "UBRuleCurveData.targetSpace" [reservoir, "GetMonth"( date ) - 1.00000000];
END;
FUNCTION "UBDrawDown" ( STRING reservoir, DATETIME startDate, DATETIME endDate, DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Returns the reservoir's drawdown between one month prior to the startDate and the
endDate. Returns a negative number because the reservoir is being drawn down to
make room for spring runoff. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"UBTargetStorage"( reservoir, endDate ) - "UBInitialStorage"( reservoir, startDate, month );
END;
FUNCTION "UBInitialStorage" ( STRING reservoir, DATETIME startDate, DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Returns the reservoir's initial storage at a specified startDate. If the current month is
earlier than the startDate, the initial storage is set to the reservoir's target storage for one
month prior to the startDate. Otherwise, the initial storage is just the reservoir's previous
month's storage. If this function is being called from UBDrawDown(), then this value is to
be subtracted from the reservoir's target storage to compute the draw down.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( startDate > month )
THEN
"UBTargetStorage"( reservoir, "OffsetDate"( startDate, - 1.00000000, "1 Months" ) )
ELSE
"Upper Basin Effective Reservoir Storages." CONCAT reservoir ["OffsetDate"( month, - 1.00000000, "1 months" )]
ENDIF;
END;
END;
UTILITY_GROUP "Step Shortage Functions";
DESCRIPTION "";
ACTIVE TRUE;
BEGIN
FUNCTION "ComputeTier1Diversion" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( diversion == "CAP" )
THEN
diversion CONCAT " Schedule.AnnualNormalDiversionSchedule" [] - ( $ "Shortage.LowerBasinMexicoShortageAmount" [0.00000000, 0.00000000] * "CAPShortagePercent"( ) )
ELSE
IF ( diversion == "SNWP" )
THEN
"SNWPStep1ShortageRatio"( ) * diversion CONCAT " Schedule.AnnualNormalDiversionSchedule" []
ELSE
( diversion CONCAT " Schedule.AnnualNormalDiversionSchedule" [] - ( $ "Shortage.LowerBasinMexicoShortageAmount" [0.00000000, 0.00000000] * $ "Shortage.MexicoShortagePercent" [] ) ) COMMENTED_BY "diversion is Mexico
"
ENDIF
ENDIF;
END;
FUNCTION "ComputeTier1Depletion" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( diversion == "CAP" )
THEN
diversion CONCAT " Schedule.AnnualNormalDepletionSchedule" [] - ( $ "Shortage.LowerBasinMexicoShortageAmount" [0.00000000, 0.00000000] * "CAPShortagePercent"( ) )
ELSE
IF ( diversion == "SNWP" )
THEN
diversion CONCAT " Schedule.AnnualNormalDepletionSchedule" [] - "SNWPStep1ShortageAmount"( )
ELSE
( diversion CONCAT " Schedule.AnnualNormalDepletionSchedule" [] - ( $ "Shortage.LowerBasinMexicoShortageAmount" [0.00000000, 0.00000000] * $ "Shortage.MexicoShortagePercent" [] ) ) COMMENTED_BY "diversion is Mexico
"
ENDIF
ENDIF;
END;
FUNCTION "ComputeTier2Diversion" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( diversion == "CAP" )
THEN
diversion CONCAT " Schedule.AnnualNormalDiversionSchedule" [] - ( $ "Shortage.LowerBasinMexicoShortageAmount" [1.00000000, 0.00000000] * "CAPShortagePercent"( ) )
ELSE
IF ( diversion == "SNWP" )
THEN
"SNWPStep2ShortageRatio"( ) * diversion CONCAT " Schedule.AnnualNormalDiversionSchedule" []
ELSE
( diversion CONCAT " Schedule.AnnualNormalDiversionSchedule" [] - ( $ "Shortage.LowerBasinMexicoShortageAmount" [1.00000000, 0.00000000] * $ "Shortage.MexicoShortagePercent" [] ) ) COMMENTED_BY "diversion is Mexico
"
ENDIF
ENDIF;
END;
FUNCTION "ComputeTier2Depletion" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( diversion == "CAP" )
THEN
diversion CONCAT " Schedule.AnnualNormalDepletionSchedule" [] - ( $ "Shortage.LowerBasinMexicoShortageAmount" [1.00000000, 0.00000000] * "CAPShortagePercent"( ) )
ELSE
IF ( diversion == "SNWP" )
THEN
diversion CONCAT " Schedule.AnnualNormalDepletionSchedule" [] - "SNWPStep2ShortageAmount"( )
ELSE
( diversion CONCAT " Schedule.AnnualNormalDepletionSchedule" [] - ( $ "Shortage.LowerBasinMexicoShortageAmount" [1.00000000, 0.00000000] * $ "Shortage.MexicoShortagePercent" [] ) ) COMMENTED_BY "diversion is Mexico
"
ENDIF
ENDIF;
END;
FUNCTION "ComputeTier3Diversion" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( diversion == "CAP" )
THEN
diversion CONCAT " Schedule.AnnualNormalDiversionSchedule" [] - ( $ "Shortage.LowerBasinMexicoShortageAmount" [2.00000000, 0.00000000] * "CAPShortagePercent"( ) )
ELSE
IF ( diversion == "SNWP" )
THEN
"SNWPStep3ShortageRatio"( ) * diversion CONCAT " Schedule.AnnualNormalDiversionSchedule" []
ELSE
( diversion CONCAT " Schedule.AnnualNormalDiversionSchedule" [] - ( $ "Shortage.LowerBasinMexicoShortageAmount" [2.00000000, 0.00000000] * $ "Shortage.MexicoShortagePercent" [] ) ) COMMENTED_BY "diversion is Mexico
"
ENDIF
ENDIF;
END;
FUNCTION "ComputeTier3Depletion" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( diversion == "CAP" )
THEN
diversion CONCAT " Schedule.AnnualNormalDepletionSchedule" [] - ( $ "Shortage.LowerBasinMexicoShortageAmount" [2.00000000, 0.00000000] * "CAPShortagePercent"( ) )
ELSE
IF ( diversion == "SNWP" )
THEN
diversion CONCAT " Schedule.AnnualNormalDepletionSchedule" [] - "SNWPStep3ShortageAmount"( )
ELSE
( diversion CONCAT " Schedule.AnnualNormalDepletionSchedule" [] - ( $ "Shortage.LowerBasinMexicoShortageAmount" [2.00000000, 0.00000000] * $ "Shortage.MexicoShortagePercent" [] ) ) COMMENTED_BY "diversion is Mexico
"
ENDIF
ENDIF;
END;
FUNCTION "CAPShortagePercent" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG FALSE;
POST_EXEC_DIAG FALSE;
BEGIN
1.00000000 - ( $ "Shortage.NevadaShortagePercent" [] + $ "Shortage.MexicoShortagePercent" [] );
END;
FUNCTION "SNWPShortagePercent" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG FALSE;
POST_EXEC_DIAG FALSE;
BEGIN
$ "Computed State Depletions.Nevada Apportionment" [] / ( $ "Computed State Depletions.Nevada Apportionment" [] + $ "Computed State Depletions.California Apportionment" [] + $ "Computed State Depletions.Arizona Apportionment" [] );
END;
FUNCTION "MexicoShortagePercent" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG FALSE;
POST_EXEC_DIAG FALSE;
BEGIN
$ "Computed State Depletions.Mexico Apportionment" [] / ( $ "Computed State Depletions.Nevada Apportionment" [] + $ "Computed State Depletions.California Apportionment" [] + $ "Computed State Depletions.Arizona Apportionment" [] + $ "Computed State Depletions.Mexico Apportionment" [] );
END;
FUNCTION "SNWPStep1ShortageAmount" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG FALSE;
POST_EXEC_DIAG FALSE;
BEGIN
$ "Shortage.LowerBasinMexicoShortageAmount" [0.00000000, 0.00000000] * $ "Shortage.NevadaShortagePercent" [];
END;
FUNCTION "SNWPStep2ShortageAmount" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG FALSE;
POST_EXEC_DIAG FALSE;
BEGIN
$ "Shortage.LowerBasinMexicoShortageAmount" [1.00000000, 0.00000000] * $ "Shortage.NevadaShortagePercent" [];
END;
FUNCTION "SNWPStep3ShortageAmount" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG FALSE;
POST_EXEC_DIAG FALSE;
BEGIN
$ "Shortage.LowerBasinMexicoShortageAmount" [2.00000000, 0.00000000] * $ "Shortage.NevadaShortagePercent" [];
END;
FUNCTION "SNWPStep1ShortageRatio" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG FALSE;
POST_EXEC_DIAG FALSE;
BEGIN
1.00000000 - ( $ "SNWP Schedule.AnnualNormalDepletionSchedule" [] - ( $ "SNWP Schedule.AnnualNormalDepletionSchedule" [] - "SNWPStep1ShortageAmount"( ) ) ) / $ "SNWP Schedule.AnnualNormalDepletionSchedule" [];
END;
FUNCTION "SNWPStep2ShortageRatio" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG FALSE;
POST_EXEC_DIAG FALSE;
BEGIN
1.00000000 - ( $ "SNWP Schedule.AnnualNormalDepletionSchedule" [] - ( $ "SNWP Schedule.AnnualNormalDepletionSchedule" [] - "SNWPStep2ShortageAmount"( ) ) ) / $ "SNWP Schedule.AnnualNormalDepletionSchedule" [];
END;
FUNCTION "SNWPStep3ShortageRatio" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG FALSE;
POST_EXEC_DIAG FALSE;
BEGIN
1.00000000 - ( $ "SNWP Schedule.AnnualNormalDepletionSchedule" [] - ( $ "SNWP Schedule.AnnualNormalDepletionSchedule" [] - "SNWPStep3ShortageAmount"( ) ) ) / $ "SNWP Schedule.AnnualNormalDepletionSchedule" [];
END;
END;
UTILITY_GROUP "Level 2 Shortage Functions";
DESCRIPTION "";
ACTIVE TRUE;
BEGIN
FUNCTION "ComputeLevel2ShortageDepletion" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( diversion == "CAP" )
THEN
"ComputeCAPLevel2ShortageDiversion"( )
ELSE
IF ( diversion == "SNWP" )
THEN
"ComputeSNWPLevel2ShortageDepletion"( )
ELSE
IF ( diversion == "MWD" )
THEN
"ComputeMWDLevel2ShortageDiversion"( )
ELSE
"ComputeMexicoLevel2ShortageDiversion"( )
ENDIF
ENDIF
ENDIF;
END;
FUNCTION "ComputeLevel2ShortageDiversion" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes the volume to be diverted for the specified diversion under a Level 2
Shortage. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( diversion == "CAP" )
THEN
"ComputeCAPLevel2ShortageDiversion"( )
ELSE
IF ( diversion == "SNWP" )
THEN
"ComputeSNWPLevel2ShortageDiversion"( )
ELSE
IF ( diversion == "MWD" )
THEN
"ComputeMWDLevel2ShortageDiversion"( )
ELSE
"ComputeMexicoLevel2ShortageDiversion"( )
ENDIF
ENDIF
ENDIF;
END;
FUNCTION "ComputeSNWPLevel1AmountShorted" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes the shorted depletion volume for SNWP as a specified percent (currently 4%)
of CAP's shorted depletion volume.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "Shortage.NevadaShortagePercent" [] * "TotalShortage"( );
END;
FUNCTION "ComputeMexicoLevel1AmountShorted" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes the shorted depletion volume for SNWP as a specified percent (currently 4%)
of CAP's shorted depletion volume.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "Shortage.MexicoShortagePercent" [] * "TotalShortage"( );
END;
FUNCTION "CAPShortage" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "Computes the shorted depletion volume for CAP as its normal depletion minus
a specified shortage amount (currently 1.0 MAF).";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "CAP Schedule.AnnualNormalDepletionSchedule" [] - $ "Shortage.MinDiversionCAP" [0.00000000, 0.00000000];
END;
FUNCTION "ComputeCAPLevel2AmountShorted" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes the amount (volume) CAP is to be reduced in a Level 2 Shortage. This amount
is computed as the combined shorted amount for CAP and SNWP ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"ComputeCAP&SNWP&MexicoLevel2AmountShorted"( ) * ( 1.00000000 - ( $ "Shortage.NevadaShortagePercent" [] + $ "Shortage.MexicoShortagePercent" [] ) );
END;
FUNCTION "ComputeSNWPLevel2ShortageDiversion" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "This function computes the shorted diversion volume for SNWP as a percent of the shorted
depletion volume. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT 0.00000000 "acre-feet";
BEGIN
"ComputeSNWPLevel2ShortageDepletion"( ) * ( $ "SNWP Schedule.AnnualNormalDiversionSchedule" [] / $ "SNWP Schedule.AnnualNormalDepletionSchedule" [] );
END;
FUNCTION "ComputeCAP&SNWPNormalDepletionVol" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "CAP Schedule.AnnualNormalDepletionSchedule" [] + $ "SNWP Schedule.AnnualNormalDepletionSchedule" [];
END;
FUNCTION "ComputeCAP&SNWP&MexicoLevel2AmountShorted" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "CAP Schedule.AnnualNormalDepletionSchedule" [] + $ "SNWP Schedule.AnnualNormalDepletionSchedule" [] + $ "Mexico Schedule.AnnualNormalDepletionSchedule" [] - "ComputeWaterAvailableCAP&SNWP&Mexico"( );
END;
FUNCTION "ComputeMexicoLevel2ShortageDiversion" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT 0.00000000 "acre-feet";
BEGIN
IF ( "ComputeWaterAvailableCAP&SNWP&Mexico"( ) <= 0.00000000 "acre-feet" )
THEN
( $ "Mexico Schedule.AnnualNormalDepletionSchedule" [] - $ "Shortage.MexicoShortagePercent" [] * "TotalShortageLevel2Shortage"( ) )
ELSE
$ "Mexico Schedule.AnnualNormalDiversionSchedule" [] - "ComputeMexicoLevel2AmountShorted"( )
ENDIF;
END;
FUNCTION "ComputeMWDLevel2ShortageDiversion" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT 0.00000000 "acre-feet";
BEGIN
IF ( "ComputeWaterAvailableCAP&SNWP&Mexico"( ) < 0.00000000 "acre-feet" )
THEN
$ "MWD Schedule.AnnualNormalDiversionSchedule" [] + "ComputeWaterAvailableCAP&SNWP&Mexico"( ) * "ComputeLevel2MWD&MexcioRatio"( "MWD" )
ELSE
$ "MWD Schedule.AnnualNormalDiversionSchedule" []
ENDIF;
END;
FUNCTION "ComputeCAPLevel2ShortageDiversion" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "This function computes the shorted diversion volume for CAP. If water is currently
available, CAP's diversion is its normal depletion request reduced by its Level 2 Shortage
amount. The there is no water available, CAP's diversion is reduced to 0.0 acre-ft. Note
that there is a minimum constraint of 0.0 acre-ft for this function.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT $ "Shortage.CAP Native American Rights" [];
BEGIN
IF ( "ComputeWaterAvailableCAP&SNWP&Mexico"( ) <= 0.00000000 "acre-feet" )
THEN
$ "Shortage.CAP Native American Rights" [] COMMENTED_BY "72 kaf delivered to CAP for Native American rights"
ELSE
( $ "CAP Schedule.AnnualNormalDepletionSchedule" [] - "ComputeCAPLevel2AmountShorted"( ) )
ENDIF;
END;
FUNCTION "ComputeSNWPLevel2ShortageDepletion" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT 0.00000000 "acre-feet";
BEGIN
IF ( "ComputeWaterAvailableCAP&SNWP&Mexico"( ) <= 0.00000000 "acre-feet" )
THEN
( $ "SNWP Schedule.AnnualNormalDepletionSchedule" [] - $ "Shortage.NevadaShortagePercent" [] * "TotalShortageLevel2Shortage"( ) )
ELSE
( $ "SNWP Schedule.AnnualNormalDepletionSchedule" [] - "ComputeSNWPLevel2AmountShorted"( ) )
ENDIF;
END;
FUNCTION "ComputeCAP&SNWP&MexicoLevel1ShortageDepletionVol" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes the combined depletion volume for CAP and SNWP under a Level 1 Shortage.
";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "Shortage.MinDiversionCAP" [0.00000000, 0.00000000] + ( $ "SNWP Schedule.AnnualNormalDepletionSchedule" [] - "ComputeSNWPLevel1AmountShorted"( ) ) + ( $ "Mexico Schedule.AnnualNormalDepletionSchedule" [] - "ComputeMexicoLevel1AmountShorted"( ) );
END;
FUNCTION "ComputeWaterAvailableFromMeadwithoutShorts" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes the volume of water available for withdrawal from Mead, given some minimum
elevation threshold (currently set to 1000 ft) in Shortage.Level 2 Shortage Trigger.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "Mead.Storage" [@"t - 1"] - "ElevationToStorage"( % "Mead", $ "Shortage.Level 2 Shortage Trigger" [0.00000000, 0.00000000] ) + "ComputeMeadMinInflowVolume"( ) - "EstimateEvaporation"( % "Mead", $ "Mead.Storage" [@"t - 1"], "ElevationToStorage"( % "Mead", $ "Shortage.Level 2 Shortage Trigger" [0.00000000, 0.00000000] ), @"24:00:00 January 31, Current Year", @"24:00:00 December 31, Current Year" ) - "Estimate Bank Storage without Evap"( % "Mead", $ "Mead.Storage" [@"t - 1"], "ElevationToStorage"( % "Mead", $ "Shortage.Level 2 Shortage Trigger" [0.00000000, 0.00000000] ) );
END;
FUNCTION "ComputeDSDemandwithoutShorts" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes the annual demand volume below Mead, excluding CAP, MWD, and Mexico.
Includes the gains and the evap losses at Mohave and Havasu. Assumes that Mohave and
Havasu start and end the year at their rule curve storages, so there is net gain or loss.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"SumFlowsToVolume"( $ "GainsAndLosses_MeadFloodControl.MonthlyDepletionsBelowMead", @"24:00:00 January 31, Current Year", @"24:00:00 December 31, Current Year" ) + "EstimateEvaporation"( % "Havasu", "RuleCurveStorage"( % "Havasu", @"t - 1" ), "RuleCurveStorage"( % "Havasu", @"24:00:00 December 31, Current Year" ), @"24:00:00 January 31, Current Year", @"24:00:00 December 31, Current Year" ) + "EstimateEvaporation"( % "Mohave", "RuleCurveStorage"( % "Mohave", @"t - 1" ), "RuleCurveStorage"( % "Mohave", @"24:00:00 December 31, Current Year" ), @"24:00:00 January 31, Current Year", @"24:00:00 December 31, Current Year" ) - "SumFlowsToVolume"( $ "GainsAndLosses_MeadFloodControl.MonthlyGainsBelowMead", @"24:00:00 January 31, Current Year", @"24:00:00 December 31, Current Year" ) + $ "Coachella Schedule.AnnualNormalDepletionSchedule" [] + $ "IID Schedule.AnnualNormalDepletionSchedule" [];
END;
FUNCTION "ComputeMeadMinInflowVolume" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes the minimum inflow volume to Mead by adding the main stem gains
between Powell and Mead to Powell's outflow and subtracting the depletions
between Powell and Mead. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"ComputeMinPowellOutflowVolumeUnderLevel2Shortage"( ) + "SumFlowsToVolume"( $ "GainsAndLosses_MeadFloodControl.MonthlyGainsPowellToMead", @"24:00:00 January 31, Current Year", @"24:00:00 December 31, Current Year" ) - "SumDepletionsBelowVolume"( % "Powell", @"t", @"t" );
END;
FUNCTION "ComputeWaterAvailableForShortDiversions" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes the volume available for the shorted diversions (CAP, SNWP, MWD, and Mexico)
for a Level 2 Shortage (if Mead is kept above 1000 ft).";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"ComputeWaterAvailableFromMeadwithoutShorts"( ) - "ComputeDSDemandwithoutShorts"( );
END;
FUNCTION "ComputeMinPowellOutflowVolumeUnderLevel2Shortage" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes the minimum outflow volume from Powell. This is computed as the minimum of
Powell's minimum objective release and the outflow resulting from Powell dropping to
inactive capacity storage.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"Min"( "AnnualMinObjectiveRelease"( ), $ "Powell.Storage" [@"t - 1"] - $ "PowellData.MinimumContent" [] + "FlowToVolume"( $ "PowellInflow.Inflow" [@"t"], @"t" ) - "EstimateEvaporation"( % "Powell", $ "Powell.Storage" [@"t - 1"], $ "PowellData.MinimumContent" [], @"24:00:00 January 31, Current Year", @"24:00:00 December 31, Current Year" ) );
END;
FUNCTION "SumGainsBelowVolume" ( OBJECT reservoir, DATETIME startDate, DATETIME endDate )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"SumObjectsAggregatedOverTime"( "Below" CONCAT STRINGIFY reservoir, "Local Inflow", "SUM", "INPUT", TRUE, startDate, endDate );
END;
FUNCTION "PowellRegulatedInflowEstimateDuringLevel2Shortage" ( DATETIME startDate, DATETIME endDate )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "Computes the minumum regulated inflow to Powell during a Level 2 Shortage. Computed by
subtracting the depletions in the UB above Powell and adding water available from the UB
Reservoirs above Powell. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"PowellNaturalInflowVolume"( startDate, endDate ) - "UBDepletionsRange"( startDate, endDate ) + "WaterAvailablefromUBReservoirs"( startDate, endDate );
END;
FUNCTION "ComputeWaterAvailableForCAPandSNWP" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes the volume of water available for CAP and SNWP for the coming year.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"ComputeWaterAvailableForShortDiversions"( ) - $ "MWD Schedule.AnnualNormalDepletionSchedule" [] - $ "Mexico Schedule.AnnualNormalDepletionSchedule" [];
END;
FUNCTION "WaterAvailablefromUBReservoirs" ( DATETIME startDate, DATETIME endDate )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes the total volume of water available in the UB Effective reservoirs between a
range of dates. Available water is defined as the volume above inactive capacity for each
resevoir. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
FOR ( STRING reservoir IN { "FlamingGorge" , "Fontenelle" , "BlueMesa" , "Navajo" } ) WITH NUMERIC sum = 0.00000000 "acre-feet" DO
sum + "VolumeAboveInactiveCapacity"( reservoir, startDate, endDate )
ENDFOR;
END;
FUNCTION "VolumeAboveInactiveCapacity" ( STRING reservoir, DATETIME startDate, DATETIME endDate )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Determines the volume of water, above inactive capacity, in a specified
reservoir within a range of dates.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"UBInitialStorage"( reservoir, startDate, @"24:00:00 January 31, Current Year" ) - $ "UBRuleCurveData.ReservoirData" [reservoir, "inactiveCapacityStorage"];
END;
FUNCTION "ComputeSNWPLevel2AmountShorted" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "Shortage.NevadaShortagePercent" [] * "ComputeCAP&SNWP&MexicoLevel2AmountShorted"( );
END;
FUNCTION "ComputeMexicoLevel2AmountShorted" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "Shortage.MexicoShortagePercent" [] * "ComputeCAP&SNWP&MexicoLevel2AmountShorted"( );
END;
FUNCTION "ComputeLevel2MWD&MexcioRatio" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( diversion == "MWD" )
THEN
1.00000000 - $ "Shortage.MexicoShortagePercent" []
ELSE
$ "Shortage.MexicoShortagePercent" []
ENDIF;
END;
FUNCTION "TotalShortage" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG FALSE;
POST_EXEC_DIAG FALSE;
BEGIN
"CAPShortage"( ) / ( 1.00000000 - ( $ "Shortage.NevadaShortagePercent" [] + $ "Shortage.MexicoShortagePercent" [] ) );
END;
FUNCTION "TotalShortageLevel2Shortage" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG FALSE;
POST_EXEC_DIAG FALSE;
BEGIN
( $ "CAP Schedule.AnnualNormalDepletionSchedule" [] - $ "Shortage.CAP Native American Rights" [] ) / ( 1.00000000 - ( $ "Shortage.NevadaShortagePercent" [] + $ "Shortage.MexicoShortagePercent" [] ) );
END;
END;
UTILITY_GROUP "80P1050 600 Shortage Functions";
DESCRIPTION "";
ACTIVE TRUE;
BEGIN
FUNCTION "ComputeShortageDiversion600" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( diversion == "SNWP" )
THEN
"ComputeShortageDepletion600"( "SNWP" ) * ( $ "SNWP Schedule.AnnualNormalDiversionSchedule" [] / $ "SNWP Schedule.AnnualNormalDepletionSchedule" [] )
ELSE
IF ( diversion == "CAP" )
THEN
"ComputeShortageDepletion600"( "CAP" )
ELSE
"ComputeShortageDepletion600"( "Mexico" )
ENDIF
ENDIF;
END;
FUNCTION "ComputeShortageDepletion600" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( diversion == "SNWP" AND $ "Mead.Pool Elevation" [@"t - 1"] < $ "MeadData.SNWPMinPumpingElevation" [] )
THEN
0.00000000 "acre-ft"
ELSE
diversion CONCAT " Schedule.AnnualNormalDepletionSchedule" [] - "RemainingShortToAllocate"( ) * "ComputeProrationFactorDrought"( diversion )
ENDIF;
END;
FUNCTION "RemainingShortToAllocate" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( $ "Mead.Pool Elevation" [@"t - 1"] < $ "MeadData.SNWPMinPumpingElevation" [] )
THEN
$ "Shortage.TotalShortageVolume" [] - $ "SNWP Schedule.AnnualNormalDepletionSchedule" []
ELSE
$ "Shortage.TotalShortageVolume" []
ENDIF;
END;
FUNCTION "ComputeProrationFactorDrought" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( $ "Mead.Pool Elevation" [@"t - 1"] < $ "MeadData.SNWPMinPumpingElevation" [] )
THEN
IF ( diversion == "SNWP" )
THEN
0.00000000 "acre-ft"
ELSE
IF ( diversion == "CAP" )
THEN
2800000.00000000 "acre-ft" / ( 2800000.00000000 "acre-ft" + 1500000.00000000 "acre-ft" )
ELSE
( 1500000.00000000 "acre-ft" / ( 2800000.00000000 "acre-ft" + 1500000.00000000 "acre-ft" ) ) COMMENTED_BY "diversion is Mexico"
ENDIF COMMENTED_BY "SNWP is taking 0.0, therefore not included in total delivery (demoninator)"
ENDIF
ELSE
IF ( diversion == "SNWP" )
THEN
300000.00000000 "acre-ft" / ( 2800000.00000000 "acre-ft" + 1500000.00000000 "acre-ft" + 300000.00000000 "acre-ft" )
ELSE
IF ( diversion == "CAP" )
THEN
2800000.00000000 "acre-ft" / ( 2800000.00000000 "acre-ft" + 1500000.00000000 "acre-ft" + 300000.00000000 "acre-ft" )
ELSE
( 1500000.00000000 "acre-ft" / ( 2800000.00000000 "acre-ft" + 1500000.00000000 "acre-ft" + 300000.00000000 "acre-ft" ) ) COMMENTED_BY "diversion is Mexico"
ENDIF
ENDIF
ENDIF;
END;
FUNCTION "ComputeCAP&SNWP&MexicoLevel1_600ShortageDepVol" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes the combined depletion volume for CAP and SNWP under a Level 1 Shortage.
";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "CAP Schedule.AnnualNormalDepletionSchedule" [] - $ "Shortage.TotalShortageVolume" [] * ( 2800000.00000000 "acre-ft" / ( 2800000.00000000 "acre-ft" + 1500000.00000000 "acre-ft" + 300000.00000000 "acre-ft" ) ) + ( ( $ "SNWP Schedule.AnnualNormalDepletionSchedule" [] - $ "Shortage.TotalShortageVolume" [] * ( 300000.00000000 "acre-ft" / ( 2800000.00000000 "acre-ft" + 1500000.00000000 "acre-ft" + 300000.00000000 "acre-ft" ) ) ) + ( $ "Mexico Schedule.AnnualNormalDepletionSchedule" [] - $ "Shortage.TotalShortageVolume" [] * ( 1500000.00000000 "acre-ft" / ( 2800000.00000000 "acre-ft" + 1500000.00000000 "acre-ft" + 300000.00000000 "acre-ft" ) ) ) );
END;
FUNCTION "ComputeWaterAvailableCAP&SNWP&Mexico" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes the volume of water available for CAP and SNWP for the coming year.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"ComputeWaterAvailableForShortDiversions"( ) - $ "MWD Schedule.AnnualNormalDepletionSchedule" [];
END;
END;
UTILITY_GROUP "80P1083 Shortage Functions";
DESCRIPTION "";
ACTIVE TRUE;
BEGIN
FUNCTION "ComputeShortageDepletion" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( diversion == "SNWP" )
THEN
diversion CONCAT " Schedule.AnnualNormalDepletionSchedule" [] - "SNWPAnnualDepletionShortage"( )
ELSE
IF ( diversion == "CAP" )
THEN
$ "Shortage.MinDiversionCAP" [0.00000000, 0.00000000]
ELSE
IF ( diversion == "Mexico" )
THEN
diversion CONCAT " Schedule.AnnualNormalDepletionSchedule" [] - "MexicoAnnualDepletionShortage"( )
ELSE
diversion CONCAT " Schedule.AnnualNormalDepletionSchedule" []
ENDIF
ENDIF
ENDIF;
END;
FUNCTION "ComputeShortageDiversion" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( diversion == "SNWP" )
THEN
"SNWPShortageRatio"( ) * diversion CONCAT " Schedule.AnnualNormalDiversionSchedule" []
ELSE
IF ( diversion == "CAP" )
THEN
$ "Shortage.MinDiversionCAP" [0.00000000, 0.00000000]
ELSE
IF ( diversion == "Mexico" )
THEN
diversion CONCAT " Schedule.AnnualNormalDepletionSchedule" [] - "MexicoAnnualDepletionShortage"( )
ELSE
diversion CONCAT " Schedule.AnnualNormalDiversionSchedule" []
ENDIF
ENDIF
ENDIF;
END;
FUNCTION "MWDAnnualDepletionShortage" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "MWD Schedule.AnnualNormalDepletionSchedule" [] - ( "Max"( "AnnualCaliforniaDepletion"( ), $ "Shortage.AllotmentCalifornia" [0.00000000, 0.00000000] ) - $ "Shortage.AllotmentCalifornia" [0.00000000, 0.00000000] );
END;
FUNCTION "MexicoAnnualDepletionShortage" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "Shortage.MexicoShortagePercent" [] * ( ( $ "CAP Schedule.AnnualNormalDepletionSchedule" [] - $ "Shortage.MinDiversionCAP" [0.00000000, 0.00000000] ) / ( 1.00000000 - ( $ "Shortage.NevadaShortagePercent" [] + $ "Shortage.MexicoShortagePercent" [] ) ) );
END;
FUNCTION "SNWPAnnualDepletionShortage" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "Shortage.NevadaShortagePercent" [] * ( ( $ "CAP Schedule.AnnualNormalDepletionSchedule" [] - $ "Shortage.MinDiversionCAP" [0.00000000, 0.00000000] ) / ( 1.00000000 - ( $ "Shortage.NevadaShortagePercent" [] + $ "Shortage.MexicoShortagePercent" [] ) ) );
END;
FUNCTION "AnnualCaliforniaDepletion" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "This function has a hard wired number of 14,000 acre-feet in it. This was to match the old version of CRSS. I believe that if the diversions that are replaced with this hard wired number are greater than
14,000 acre-feet which tends to artifically lower the effect of shortage on MWD.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
FOR ( OBJECT diversion IN "ListSubbasin"( "CaliforniaDiversions" ) ) WITH NUMERIC result = 0.00000000 "acre-feet" DO
result + diversion CONCAT ".Total Depletion Requested" []
ENDFOR + $ "MWD Schedule.AnnualNormalDepletionSchedule" [] + 14000.00000000 "acre-feet";
END;
FUNCTION "SNWPShortageRatio" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
1.00000000 - ( $ "SNWP Schedule.AnnualNormalDepletionSchedule" [] - ( $ "SNWP Schedule.AnnualNormalDepletionSchedule" [] - "SNWPAnnualDepletionShortage"( ) ) ) / $ "SNWP Schedule.AnnualNormalDepletionSchedule" [];
END;
END;
UTILITY_GROUP "SNWP Shortage Function";
DESCRIPTION "";
ACTIVE TRUE;
BEGIN
FUNCTION "ComputeTier4DepletionSNWAcut" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( diversion == "CAP" )
THEN
diversion CONCAT " Schedule.AnnualNormalDepletionSchedule" [] - ( $ "Shortage.LowerBasinMexicoShortageAmount" [2.00000000, 0.00000000] * "CAPShortagePercent"( ) )
ELSE
IF ( diversion == "SNWP" )
THEN
"ComputeSNWPShortageDepletion"( )
ELSE
( diversion CONCAT " Schedule.AnnualNormalDepletionSchedule" [] - ( $ "Shortage.LowerBasinMexicoShortageAmount" [2.00000000, 0.00000000] * $ "Shortage.MexicoShortagePercent" [] ) ) COMMENTED_BY "diversion is Mexico
"
ENDIF
ENDIF;
END;
FUNCTION "ComputeTier4DiversionSNWAcut" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( diversion == "CAP" )
THEN
diversion CONCAT " Schedule.AnnualNormalDiversionSchedule" [] - ( $ "Shortage.LowerBasinMexicoShortageAmount" [2.00000000, 0.00000000] * "CAPShortagePercent"( ) )
ELSE
IF ( diversion == "SNWP" )
THEN
"ComputeSNWPShortageDepletion"( ) * ( $ "SNWP Schedule.AnnualNormalDiversionSchedule" [] / $ "SNWP Schedule.AnnualNormalDepletionSchedule" [] )
ELSE
( diversion CONCAT " Schedule.AnnualNormalDiversionSchedule" [] - ( $ "Shortage.LowerBasinMexicoShortageAmount" [2.00000000, 0.00000000] * $ "Shortage.MexicoShortagePercent" [] ) ) COMMENTED_BY "diversion is Mexico
"
ENDIF
ENDIF;
END;
FUNCTION "ComputeSNWPShortageDiversion" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG FALSE;
POST_EXEC_DIAG FALSE;
BEGIN
"ComputeSNWPShortageDepletion"( ) * ( $ "SNWP Schedule.AnnualNormalDiversionSchedule" [] / $ "SNWP Schedule.AnnualNormalDepletionSchedule" [] );
END;
FUNCTION "ComputeWaterAvailableForSNWP" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes the volume of water available for CAP and SNWP for the coming year.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"ComputeWaterAvailableForShortDiversions"( ) - $ "MWD Schedule.AnnualNormalDepletionSchedule" [] - ( $ "Mexico Schedule.AnnualNormalDepletionSchedule" [] - ( $ "Shortage.LowerBasinMexicoShortageAmount" [2.00000000, 0.00000000] * $ "Shortage.MexicoShortagePercent" [] ) ) - ( $ "CAP Schedule.AnnualNormalDepletionSchedule" [] - ( $ "Shortage.LowerBasinMexicoShortageAmount" [2.00000000, 0.00000000] * "CAPShortagePercent"( ) ) );
END;
FUNCTION "ComputeSNWPShortageDepletion" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG FALSE;
POST_EXEC_DIAG FALSE;
BEGIN
IF ( "ComputeWaterAvailableForSNWP"( ) <= 0.00000000 "acre-ft" )
THEN
0.00000000 "acre-ft"
ELSE
"ComputeWaterAvailableForSNWP"( )
ENDIF;
END;
END;
UTILITY_GROUP "Flood Control Surplus Functions";
DESCRIPTION "";
ACTIVE TRUE;
BEGIN
FUNCTION "ComputeFCSurplusDiversion" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( diversion == "SNWP" )
THEN
$ "SNWP Schedule.AnnualNormalDiversionSchedule" [] + ( "ComputeFCSurplusDepletion"( diversion ) - $ "SNWP Schedule.AnnualNormalDepletionSchedule" [] )
ELSE
"ComputeFCSurplusDepletion"( diversion )
ENDIF;
END;
FUNCTION "ComputeFCSurplusDepletion" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
WITH DATETIME firstFloodControlRelease = "OffsetDate"( @"24:00:00 January 31, Current Year", ( $ "MeadFloodControl.Flood Control Release Month Index" [] - 1.00000000 ), "1 Months" ) DO
IF ( firstFloodControlRelease == @"24:00:00 January 31, Current Year" )
THEN
"No Action Annual Surplus Schedules." CONCAT diversion CONCAT " Surplus Schedule" []
ELSE
IF ( firstFloodControlRelease > @"24:00:00 June 30, Current Year" )
THEN
"SumDemandsOverTime"( diversion, @"24:00:00 January 31, Current Year", "OffsetDate"( firstFloodControlRelease, - 1.00000000, "1 Months" ), FALSE ) + "SumDemandsOverTime"( diversion, firstFloodControlRelease, @"24:00:00 December 31, Current Year", TRUE )
ELSE
"SumDemandsOverTime"( diversion, @"24:00:00 January 31, Current Year", "OffsetDate"( firstFloodControlRelease, - 1.00000000, "1 Months" ), FALSE ) + "SumDemandsOverTime"( diversion, firstFloodControlRelease, @"24:00:00 December 31, Current Year", TRUE )
ENDIF
ENDIF
ENDWITH;
END;
END;
UTILITY_GROUP "7 State Plan Functions";
DESCRIPTION "";
ACTIVE TRUE;
BEGIN
FUNCTION "ComputeSurplusDiv7StatePlanLevel3" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( diversion == "SNWP" )
THEN
$ "SNWP Schedule.AnnualNormalDiversionSchedule" [] + ( "ComputeSurplusDepl7StatePlanLevel3"( diversion ) - $ "SNWP Schedule.AnnualNormalDepletionSchedule" [] )
ELSE
"ComputeSurplusDepl7StatePlanLevel3"( diversion )
ENDIF;
END;
FUNCTION "ComputeSurplusDepl7StatePlanLevel3" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"7 State Plan Surplus Schedules." CONCAT diversion CONCAT " Level 3" [];
END;
FUNCTION "ComputeSurplusDiv7StatePlanLevel2" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( diversion == "SNWP" )
THEN
$ "SNWP Schedule.AnnualNormalDiversionSchedule" [] + ( "ComputeSurplusDepl7StatePlanLevel2"( diversion ) - $ "SNWP Schedule.AnnualNormalDepletionSchedule" [] )
ELSE
"ComputeSurplusDepl7StatePlanLevel2"( diversion )
ENDIF;
END;
FUNCTION "ComputeSurplusDepl7StatePlanLevel2" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"7 State Plan Surplus Schedules." CONCAT diversion CONCAT " Level 2" [];
END;
FUNCTION "ComputeSurplusDiv7StatePlanLevel1" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( diversion == "SNWP" )
THEN
$ "SNWP Schedule.AnnualNormalDiversionSchedule" [] + ( "ComputeSurplusDepl7StatePlanLevel1"( diversion ) - $ "SNWP Schedule.AnnualNormalDepletionSchedule" [] )
ELSE
"ComputeSurplusDepl7StatePlanLevel1"( diversion )
ENDIF;
END;
FUNCTION "ComputeSurplusDepl7StatePlanLevel1" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "MWD and SNWP are guaranteed to get at least their Level 2 amounts (Full Domestic Surplus)";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( diversion == "MWD" OR diversion == "SNWP" )
THEN
diversion CONCAT " Schedule.AnnualNormalDepletionSchedule" [] + "Max"( "ComputeLevel2RequestedAboveNormal"( diversion ), "ComputeQuantifiedLevel1Volume"( diversion ) )
ELSE
diversion CONCAT " Schedule.AnnualNormalDepletionSchedule" [] + "ComputeQuantifiedLevel1Volume"( diversion )
ENDIF;
END;
FUNCTION "ComputeLevel1RequestedAboveNormal" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"7 State Plan Surplus Schedules." CONCAT diversion CONCAT " Level 1" [] - diversion CONCAT " Schedule.AnnualNormalDepletionSchedule" [];
END;
FUNCTION "ComputeQuantifiedLevel1Volume" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "This function takes the computed amount available and limits it to the Level 1 requested
amount. ComputeLevel1VolumeAvailable() is constrained to a minimum of 0.0 acre-ft.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"Min"( "ComputeLevel1RequestedAboveNormal"( diversion ), "ComputeLevel1VolumeAvailable"( diversion ) );
END;
FUNCTION "ComputeLevel1VolumeAvailable" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "This function computes the amount of water available for each diversion under the
Quantified Level 1 Surplus of the 7 State Plan and is constrained to a minimum of 0.0
acre-ft.
The total amount of surplus water is divided between the states and then is divided up
within the states. It is assumed that only Arizona will have unused water and gave 50%
each to California and Nevada. Once MWD gets its full allowance, any remaining water is
given to Coachella and IID by percentages used in computing the Level 1 scheduels for
them. Those were 128533/300000 = 0.4284 for Coachella and 171467/300000 = 0.5716
All of these percentages are on the data object, 7 State Plan Data.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT 0.00000000 "acre-feet";
BEGIN
IF ( diversion == "MWD" )
THEN
"ComputeQuantifiedSurplusVolumeByState"( "California" ) + "ComputeUnusedSurplusApportionment"( "Arizona" ) * $ "7 State Plan Data.Share of AZ Unused Surplus" ["Fraction", "California"]
ELSE
IF ( diversion == "Coachella" )
THEN
( "ComputeLevel1VolumeAvailable"( "MWD" ) - "ComputeLevel1RequestedAboveNormal"( "MWD" ) ) * $ "7 State Plan Data.Share of CA Ag Surplus" ["Fraction", "Coachella"]
ELSE
IF ( diversion == "IID" )
THEN
( "ComputeLevel1VolumeAvailable"( "MWD" ) - "ComputeLevel1RequestedAboveNormal"( "MWD" ) ) * $ "7 State Plan Data.Share of CA Ag Surplus" ["Fraction", "IID"]
ELSE
IF ( diversion == "SNWP" )
THEN
"ComputeQuantifiedSurplusVolumeByState"( "Nevada" ) + "ComputeUnusedSurplusApportionment"( "Arizona" ) * $ "7 State Plan Data.Share of AZ Unused Surplus" ["Fraction", "Nevada"]
ELSE
"ComputeQuantifiedSurplusVolumeByState"( "Arizona" )
ENDIF
ENDIF
ENDIF
ENDIF;
END;
FUNCTION "ComputeLevel2RequestedAboveNormal" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"7 State Plan Surplus Schedules." CONCAT diversion CONCAT " Level 2" [] - diversion CONCAT " Schedule.AnnualNormalDepletionSchedule" [];
END;
FUNCTION "ComputeQuantifiedSurplusVolumeByState" ( STRING state )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "Surplus.SurplusRelease" [] * $ "7 State Plan Data.Share of Surplus by State" ["Fraction", state];
END;
FUNCTION "ComputeUnusedSurplusApportionment" ( STRING state )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "As of 10/26/2000, we are assuming that only Arizona will have unused surplus apportionment.
Also, this function must be constrained to be >= 0 for the calling function to work (ComputeLevel1VolumeAvailable)";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT 0.00000000 "acre-feet";
BEGIN
IF ( state == "Arizona" )
THEN
"ComputeQuantifiedSurplusVolumeByState"( "Arizona" ) - "ComputeLevel1RequestedAboveNormal"( "CAP" )
ELSE
0.00000000 "acre-feet"
ENDIF;
END;
END;
UTILITY_GROUP "Assurance Level Surplus Functions";
DESCRIPTION "";
ACTIVE TRUE;
BEGIN
FUNCTION "ComputeSurplusDiversion" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Function to compute the diversion surplus amount. For SNWP, we assume that they will consume 100% of the extra
surplus volume. So we compute a surplus delta (surplus depletion - normal depletion) and add that to the normal diversion.
For the other diversions (MWD, CAP, Coachella, IID), they consume what they divert.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( diversion == "SNWP" )
THEN
$ "SNWP Schedule.AnnualNormalDiversionSchedule" [] + ( "ComputeSurplusDepletion"( diversion ) - $ "SNWP Schedule.AnnualNormalDepletionSchedule" [] )
ELSE
"ComputeSurplusDepletion"( diversion )
ENDIF;
END;
FUNCTION "ComputeSurplusDepletion" ( STRING diversion )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"No Action Annual Surplus Schedules." CONCAT diversion CONCAT " Surplus Schedule" [];
END;
FUNCTION "ComputeInflowAtProbability" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Returns the runoff at a specified assurance probability. For example, a 70R
strategy assumes a runoff corresponding to the 70th percentile. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( $ "Surplus.AssuranceProb" [0.00000000, 0.00000000] > 0.50000000 )
THEN
$ "Surplus.AnnualAvgLeesFerryFlow" [0.00000000, 0.00000000] + ( "GetT"( ) - "GetNumerator"( ) / "GetDenominator"( ) ) * $ "Surplus.StdDevLeesFerryFlow" [0.00000000, 0.00000000]
ELSE
$ "Surplus.AnnualAvgLeesFerryFlow" [0.00000000, 0.00000000] - ( ( "GetT"( ) - "GetNumerator"( ) / "GetDenominator"( ) ) * $ "Surplus.StdDevLeesFerryFlow" [0.00000000, 0.00000000] )
ENDIF;
END;
FUNCTION "SurplusMaxStorage" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes the surplus max storage. This is the max combined storage of Powell and
Mead that will meet the system space requirement at the beginning of the year. It is
assumed that 30% of the requirement will be fulfilled by UB reservoirs above Powell.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"LiveCapacity"( % "Mead" ) + "LiveCapacity"( % "Powell" ) - 0.70000000 * $ "MeadFloodControl.Required System Space" [0.00000000, "GetMonthAsString"( @"24:00:00 December 31, Current Year" )];
END;
FUNCTION "GetDenominator" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "Surplus.probabilityCoeff2" [0.00000000, 0.00000000] + ( $ "Surplus.probabilityCoeff2" [0.00000000, 1.00000000] * "GetT"( ) + $ "Surplus.probabilityCoeff2" [0.00000000, 2.00000000] * "GetT"( ) ^ 2.00000000 ) + $ "Surplus.probabilityCoeff2" [0.00000000, 3.00000000] * "GetT"( ) ^ 3.00000000;
END;
FUNCTION "GetNumerator" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "Surplus.probabilityCoeff1" [0.00000000, 0.00000000] + ( $ "Surplus.probabilityCoeff1" [0.00000000, 1.00000000] * "GetT"( ) + $ "Surplus.probabilityCoeff1" [0.00000000, 2.00000000] * "GetT"( ) ^ 2.00000000 );
END;
FUNCTION "GetT" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( $ "Surplus.AssuranceProb" [0.00000000, 0.00000000] > 0.50000000 )
THEN
"Exp"( - 2.00000000 * "Ln"( 1.00000000 - $ "Surplus.AssuranceProb" [0.00000000, 0.00000000], 0.00000000 ), 0.50000000 )
ELSE
"Exp"( - 2.00000000 * "Ln"( $ "Surplus.AssuranceProb" [0.00000000, 0.00000000], 0.00000000 ), 0.50000000 )
ENDIF;
END;
FUNCTION "SumLBDemands" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Returns the LB demands as the sum of the depletions downstream of Powell and
the evaporation losses in Mohave, Havasu and Mead minus the average gains
downstream of Powell.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"SumDemandsDownstreamOfPowell"( ) + ( "AnnualEvaporation"( % "Havasu", "JanuaryToDecember"( ) ) + "AnnualEvaporation"( % "Mohave", "JanuaryToDecember"( ) ) ) + $ "Surplus.AverageMeadEvaporation" [0.00000000, 0.00000000] - $ "Surplus.AverageAnnualGainPowellToMead" [0.00000000, 0.00000000] - $ "Surplus.AverageAnnualGainBelowMead" [0.00000000, 0.00000000];
END;
FUNCTION "SumDemandsDownstreamOfPowell" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "The original CRSS did not include CAP and MWD in this calculation, SumDepletionsBelowVolume with Mead includes every diversion below Mead with the exception of SNWP, CAP, MWD,
and Mexico. therefore the annual volume of SNWP and Mexico depletion schedules are added to match CRSS results. This seems to be a very bad calculation and I would recommend that
it be examined closely in conjuction with all of the functions that sum demands into the future such as SumDemandsDownstreamOfMead, and SumDemandsBelowMead and
SumCurrentDemandsBelowMead, to see if a common function could replace all of these. It is not possible now in order to match CRSS results.
The above comments was due to Brad Vickers, Wave Eng. On Feb 26, 2000, Terry Fulp changed this function to include MWD, CAP, and Coachella and IID, as they are now
beiing surplused.
5/17 cj - SumFlowsToVolume() returns a value that is about 6000 acre-ft more, during
leap years, than what CRSS gets when it uses SumObjectsAggregatedOverTime() for
the BelowMead subbasin to get this annual volume.
7/22 cj - The value in BelowMeadOtherSchedule.MonthlyDepletion represents
the sum of the 'Total Depletion Requested' slot in each agg diversion site in the
BelowMead subbasin which is what CRSS uses.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"SumFlowsToVolume"( $ "GainsAndLosses_MeadFloodControl.MonthlyDepletionsBelowMead", @"24:00:00 January 31, Current Year", @"24:00:00 December 31, Current Year" ) + $ "SNWP Schedule.AnnualNormalDepletionSchedule" [] + $ "Mexico Schedule.AnnualNormalDepletionSchedule" [] + $ "CAP Schedule.AnnualNormalDepletionSchedule" [] + $ "Coachella Schedule.AnnualNormalDepletionSchedule" [] + $ "IID Schedule.AnnualNormalDepletionSchedule" [] + $ "MWD Schedule.AnnualNormalDepletionSchedule" [];
END;
FUNCTION "SumUBDemands" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Returns the UB demands for the year as the sum of the scheduled depletions
and evaporation losses.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "EqualizationData.UBDepletion" [@"24:00:00 December 31, Current Year"] + $ "EqualizationData.UBEvaporation" [0.00000000, 0.00000000];
END;
END;
UTILITY_GROUP "Compute 602a Storage Functions";
DESCRIPTION "";
ACTIVE TRUE;
BEGIN
FUNCTION "602aStorage" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Calculation of the 602a storage. Used as a decision variable in Equalization. If
the Upper Basin storage is less than the 602a storage, Equalization does not
occur.
It is computed by multiplying the sum of the shorted UB depletion and the min
objective release minus the average annual natural inflow into the UB over the
critical period, by the critical period and adding the amount of min power pool to
be preserved in the UB reservoirs. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
( "ShortedUBDepletion"( ) + "AnnualMinObjectiveRelease"( ) - $ "EqualizationData.CPNaturalFlowLeesFerry" [0.00000000, 0.00000000] ) * $ "EqualizationData.CriticalPeriod" [0.00000000, 0.00000000] + $ "EqualizationData.MinPowerPoolUB" [0.00000000, 0.00000000];
END;
FUNCTION "ShortedUBDepletion" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Returns the shorted UB depletion. Computed as the sum of the average over the next
12 years of the UB scheduled depletions and the average annual evaporation loss in the
UB multiplied by a percent shortage applied to the UB depletions during the critical period.
The critical period is currently set to 12 years. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
( "CriticalPeriodUBDepletion"( ) / $ "EqualizationData.CriticalPeriod" [0.00000000, 0.00000000] + $ "EqualizationData.UBEvaporation" [0.00000000, 0.00000000] ) * ( 1.00000000 - $ "EqualizationData.PercentShortage" [0.00000000, 0.00000000] );
END;
FUNCTION "AnnualMinObjectiveRelease" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Calculates Powell's annual minimum objective release by summing the monthly
objective releases.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"SumTableRow"( $ "UBRuleCurveData.PowellMinObjectiveRelease", 0.00000000, 0.00000000, 11.00000000 );
END;
FUNCTION "CriticalPeriodUBDepletion" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "Sums the UB Depletions from the current year into the future as many years as
the the critical period.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"SumSlot"( $ "EqualizationData.UBDepletion", @"24:00:00 December 31, Current Year", "OffsetDate"( @"24:00:00 December 31, Previous Year", $ "EqualizationData.CriticalPeriod" [0.00000000, 0.00000000], "1 years" ) );
END;
FUNCTION "602aStorageValue" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Returns the 602a Storage for the current year. This was computed in Rule 1,
602a Storage.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "EqualizationData.value602a" [@"24:00:00 December 31, Current Year"];
END;
END;
UTILITY_GROUP "Powell Forecast Error Functions";
DESCRIPTION "";
ACTIVE TRUE;
BEGIN
FUNCTION "ConstructPowellForecastErrorList" ( )
RETURN_TYPE LIST;
SCALE_UNITS "";
DESCRIPTION "Constructs a list of the monthly forecast errors by calling ComputePowellForecastError()
at each month and appending the result onto the previous months' compute errors. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
FOR ( DATETIME date IN "JanuaryToDecember"( ) ) WITH LIST errors = { 0.00000000 } DO
APPEND "ComputePowellForecastError"( date, errors ) ONTO errors
ENDFOR;
END;
FUNCTION "ComputePowellForecastError" ( DATETIME date, LIST errors )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "Computes the forecast error according to the following conditions. In Aug - Dec the forecast
error is 0.0. The July forecast error is equal to a quarter of the June forecast error. The absolute
value of the June forecast error is not to exceed half of May's forecast error. When these
conditions are met, the forecast error is computed in the function ComputeInitialForecastError()
based on the previous forecast error, regression coefficients, Powell's runoff and the random
deviation. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( date > @"24:00:00 July 31, Current Year" )
THEN
0.00000000
ELSE
WITH NUMERIC previousForecastError = "GetPreviousForecastError"( date, errors ) DO
IF ( date == @"24:00:00 July 31, Current Year" )
THEN
previousForecastError / 4.00000000
ELSE
WITH NUMERIC forecastError = "ComputeInitialForecastError"( date, errors ) DO
IF ( date == @"24:00:00 June 30, Current Year" )
THEN
IF ( "Abs"( forecastError ) > "Abs"( previousForecastError / 2.00000000 ) )
THEN
previousForecastError / 2.00000000
ELSE
forecastError
ENDIF
ELSE
forecastError
ENDIF
ENDWITH
ENDIF
ENDWITH
ENDIF;
END;
FUNCTION "ComputeInitialForecastError" ( DATETIME date, LIST errors )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "Computes the monthly forecast error based on the previous forecast error,
regression coefficients, Powell's runoff and the random deviation. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"RegressionCoefficient"( "c1", date ) * ( $ "GainsAndLosses_MeadFloodControl.QSum_Powell" [date] / 1000000.00000000 "acre-feet" ) + "RegressionCoefficient"( "c2", date ) * "GetPreviousForecastError"( date, errors ) + "RegressionCoefficient"( "c3", date ) + "RegressionCoefficient"( "sde", date ) * "SetRandomDeviation"( date );
END;
FUNCTION "SetRandomDeviation" ( DATETIME date )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "Returns a random deviation by calling the predefined function RanDev().
In July - Dec, the random deviation is 0.0. The argument being passed to
RanDev() refers to the units that the random deviation is to be returned in, in
this case, none. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( date >= @"24:00:00 July 31, Current Year" )
THEN
0.00000000
ELSE
"RanDev"( 1.00000000 )
ENDIF;
END;
FUNCTION "RegressionCoefficient" ( STRING col, DATETIME date )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "Returns the regression coeffients based on the column title specified and month.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "Powell Forecast Data.RegressionCoefficients" ["GetMonthAsString"( date ), col];
END;
FUNCTION "GetPreviousForecastError" ( DATETIME date, LIST errors )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "Returns the previous month's forecast error. Recall that the list is zero-based, meaning the
index 0 refers to the first element in the list (January's forecast error). Zero is returned if the
month is January because at this point the list is empty. There is no forecast error in Aug -
Dec, so in January, the previous month's forecast error is in fact 0.0. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( date == @"24:00:00 January 31, Current Year" )
THEN
0.00000000
ELSE
GET @INDEX "GetMonth"( date ) - 1.00000000 FROM errors
ENDIF;
END;
FUNCTION "SetRewindYear" ( )
RETURN_TYPE DATETIME;
SCALE_UNITS "";
DESCRIPTION "Returns a year to ResetRanDev() and corresponds to the first line from where
the first random number should be retrieved. This function essentially converts
the NUMERIC the slot MeadFloodControlData.HydroloyStartYear[0,0] to a
DATETIME.
";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"OffsetDate"( @"24:00:00 January 1, 2000", "GetIncrementForRewindYear"( ), "1 Years" );
END;
FUNCTION "GetIncrementForRewindYear" ( )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "The result of this function, NUMERIC, is passed to SetRewindYear() which uses
the pre-defined function OffsetDate() to compute the rewind year as a DATETIME.
This increment is added to the arbitrary year in OffsetDate(), January 1, 2000
(hence, the 2000 in this expression) and the result is the HydrologyStartYear. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
- 1.00000000 * ( 2000.00000000 - ( $ "Powell Forecast Data.HydrologyStartYear" [] + ( $ "Powell Forecast Data.HydrologyIncrement" [] - 1.00000000 ) ) );
END;
END;
UTILITY_GROUP "Powell Runoff Forecast Functions";
DESCRIPTION "";
ACTIVE TRUE;
BEGIN
FUNCTION "ConstructSpringRunoffForecastList" ( )
RETURN_TYPE LIST;
SCALE_UNITS "";
DESCRIPTION "Constructs a list of the runoff forecasts in Jan - July by appending each month's
result onto that of the previous months. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
MAPLIST ( DATETIME month IN "JanuaryToJuly"( ) ) DO
"ComputePowellSpringRunoffForecast"( month )
ENDMAPLIST;
END;
FUNCTION "ComputePowellSpringRunoffForecast" ( DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes the regulated spring runoff into Powell, from the current month
through July. This is done by adjusting the natural inflow for the estimated
Upper Basin depletions and potential reservoir regulation above Powell and
applying a forecast error. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "GainsAndLosses_MeadFloodControl.QSum_Powell" [month] - $ "Powell Forecast Data.ForecastError" [month] * 1000000.00000000 "acre-ft" - "UBDepletionsRange"( month, @"24:00:00 July 31, Current Year" ) - "UBEffectiveStorage"( month );
END;
FUNCTION "AvailableSpace" ( STRING reservoir, DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Returns the available space in an UB Effective Reservoir for the current month
by subtracting that reservoir's previous month's storage from its live capacity
storage.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "UBRuleCurveData.ReservoirData" [reservoir, "liveCapacityStorage"] - "Upper Basin Effective Reservoir Storages." CONCAT reservoir ["OffsetDate"( month, - 1.00000000, "1 months" )];
END;
FUNCTION "UBEffectiveStorage" ( DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Returns the potential reservoir regulation in the Upper Basin above Powell by
summing the available space (live capacity - previous month's storage) for
each reservoir. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
FOR ( STRING reservoir IN { "FlamingGorge" , "Fontenelle" , "BlueMesa" , "Navajo" } ) WITH NUMERIC sum = 0.00000000 "acre-feet" DO
sum + "AvailableSpace"( reservoir, month )
ENDFOR;
END;
END;
UTILITY_GROUP "Forecast Mead Release Functions";
DESCRIPTION "";
ACTIVE TRUE;
BEGIN
FUNCTION "ForecastMeadRelease" ( DATETIME month, BOOLEAN floodControl )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "This function forecasts Mead's release from the current month through Sept. as the sum
of the depletions downstream of Mead and Mohave and Havasu regulation, including
evaporation, minus the gains below Mead.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"SumDemandsDownstreamofMead"( month, floodControl ) - "SumInflowBelowMead"( month ) + "ComputeEqualizationEvaporation"( % "Mohave", "GetDates"( month, @"24:00:00 September 30, Current Year", "1 months" ) ) + "ComputeEqualizationEvaporation"( % "Havasu", "GetDates"( month, @"24:00:00 September 30, Current Year", "1 months" ) ) + "EqualizationRuleCurveStorage"( % "Havasu", month ) + "EqualizationRuleCurveStorage"( % "Mohave", month );
END;
FUNCTION "SumDemandsDownstreamofMead" ( DATETIME month, BOOLEAN floodControl )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Sums the depletions below Mead from the current month through September.
The BOOLEAN floodControl indicates whether or not a flood control release was made prior
to the current month. If a flood control release was made, the depletions for MWD, CAP,
Coachella, IID and Mexico are based on their flood control surplus schedules.
";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"SumFlowsToVolume"( $ "GainsAndLosses_MeadFloodControl.MonthlyDepletionsBelowMead", month, @"24:00:00 September 30, Current Year" ) + "SumDemandsOverTime"( "MWD", month, @"24:00:00 September 30, Current Year", floodControl ) + "SumDemandsOverTime"( "CAP", month, @"24:00:00 September 30, Current Year", floodControl ) + "SumDemandsOverTime"( "Coachella", month, @"24:00:00 September 30, Current Year", floodControl ) + "SumDemandsOverTime"( "IID", month, @"24:00:00 September 30, Current Year", floodControl ) + "SumDemandsOverTime"( "Mexico", month, @"24:00:00 September 30, Current Year", floodControl );
END;
FUNCTION "SumDemandsOverTime" ( STRING diversion, DATETIME startDate, DATETIME endDate, BOOLEAN floodControl )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "This function sums the demands for a diversion, meant to be either MWD, IID, CAP, Mexico,
SNWP or Coachella, from the startDate to endDate. In order to do this the annual
schedules are first disaggregated using monthly percentages and then summed for the
given date range. If a floodControl release was made that year (floodControl = TRUE) the
demands are based on the diversion's surplus schedule and therefore the surplus percent is
used. Otherwise, DetermineSchedulePercent() is called to determine the disaggregation
percent by checking to see if the diversion was scheduled for a normal, shortage or surplus
year. DetermineSchedulePercent() returns the slot where the appropriate percent is
stored, either SchedulePercent.Normal, SchedulePercent.Shortage, or
SchedulePercent.Surplus.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( floodControl )
THEN
"SumTableColumn"( $ "Schedule Percents.Surplus", "GetColumnIndex"( $ "Schedule Percents.Surplus", STRINGIFY diversion ), ( "GetMonth"( startDate ) - 1.00000000 ), ( "GetMonth"( endDate ) - 1.00000000 ) ) * "No Action Annual Surplus Schedules." CONCAT diversion CONCAT " Surplus Schedule" []
ELSE
WITH SLOT SchedulePercent = "DetermineSchedulePercent"( ) DO
"SumTableColumn"( SchedulePercent, "GetColumnIndex"( SchedulePercent, STRINGIFY diversion ), ( "GetMonth"( startDate ) - 1.00000000 ), ( "GetMonth"( endDate ) - 1.00000000 ) ) * "FlowToVolume"( diversion CONCAT "Diversion.Total Depletion Requested" [], @"t" )
ENDWITH
ENDIF;
END;
FUNCTION "DetermineSchedulePercent" ( )
RETURN_TYPE SLOT;
SCALE_UNITS "";
DESCRIPTION "Used with SumDemandsOverTime() and returns the slot that contains the monthly
percents based on whether the year is normal, surplus or shortage. This function is not
specific to each diversion. For example, if an 80P1083 Shortage is in effect, the shortage
percent will be used to disaggregate the annual schedules for all diversions even though
only CAP and SNWP are only affected by an 80P1083 Shortage. This is acceptable, for
now, because only CAP's percents actually differ based on shortage, surplus or normal.
";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( NOT IsNaN $ "Shortage.Level 2 Shortage Flag" [] )
THEN
$ "Schedule Percents.Surplus"
ELSE
IF ( NOT IsNaN $ "Shortage.Shortage Flag" [] )
THEN
$ "Schedule Percents.Shortage"
ELSE
IF ( NOT IsNaN $ "Surplus.Surplus Flag" [] )
THEN
$ "Schedule Percents.Surplus"
ELSE
$ "Schedule Percents.Normal"
ENDIF
ENDIF
ENDIF;
END;
FUNCTION "SumInflowBelowMead" ( DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Sums the inflows below Mead from the current month through September.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"SumFlowsToVolume"( $ "TotVal.Mohave_ByTrace", month, @"24:00:00 September 30, Current Year" ) + "SumFlowsToVolume"( $ "TotVal.Havasu_ByTrace", month, @"24:00:00 September 30, Current Year" ) + "SumFlowsToVolume"( $ "TotVal.Imperial_ByTrace", month, @"24:00:00 September 30, Current Year" );
END;
END;
UTILITY_GROUP "Powell Spill Functions";
DESCRIPTION "";
ACTIVE TRUE;
BEGIN
FUNCTION "ComputePowellPeakPowerFlow" ( DATETIME month, NUMERIC powellStorage, NUMERIC previousPowellStorage, NUMERIC powellOutflow )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft/month";
DESCRIPTION "Compute the peaking flow value which is the most efficient flow through the
turbines for the current operating head. The operating head is a function of the pool
and tailwater elevations. Before computing the peak flow, the operating head must
be within the min and max operating head. If it is less than the minimum, the peak
flow is set to 0. If it is greater than the max, the peak flow is set to 34000.32 cfs
which is the greatest possible peak flow based on the PeakPowerCalc. After the
operating head check is made, the peak flow is found through 2D table interpolation
with the average pool elevation.
";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
WITH NUMERIC averagePoolElevation = "AveragePoolElevation"( % "Powell", previousPowellStorage, powellStorage ) DO
WITH NUMERIC tailwaterElevation = "GetPowellTailwaterElevation"( month, powellOutflow ) DO
WITH NUMERIC operatingHead = averagePoolElevation - tailwaterElevation DO
IF ( operatingHead < $ "Powell.Min and Max Operating Head" [0.00000000, 0.00000000] )
THEN
0.00000000 "cfs"
ELSE
IF ( operatingHead > $ "Powell.Min and Max Operating Head" [0.00000000, 1.00000000] )
THEN
34000.32000000 "cfs"
ELSE
"TableInterpolation"( $ "PowellData.PeakPowerFlowTable", 0.00000000, 1.00000000, averagePoolElevation, month )
ENDIF
ENDIF
ENDWITH
ENDWITH
ENDWITH;
END;
FUNCTION "ComputePowellSpill" ( DATETIME month, NUMERIC powellStorage, NUMERIC previousPowellStorage )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft/month";
DESCRIPTION "This function estimates Powell's spill. It is based on the reservoir user-method for
power calculation, PeakPowerCalc. With a given storage, an outflow is determined.
With that outflow, the corresponding tailwater elevation and best generator flow, a
peaking flow value (peakPowerFlow) is determined. If the outflow is greater than
the peakPowerFlow, Powell is assumed to spill the difference. If not, then all the
outflow is released through the turbines and there is no spill.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
WITH NUMERIC powellOutflow = "ComputeOutflowGivenStorageForSpill"( month, previousPowellStorage, powellStorage ) DO
WITH NUMERIC peakPowerFlow = "ComputePowellPeakPowerFlow"( month, powellStorage, previousPowellStorage, powellOutflow ) DO
IF ( powellOutflow > peakPowerFlow )
THEN
powellOutflow - peakPowerFlow
ELSE
0.00000000 "cfs"
ENDIF
ENDWITH
ENDWITH;
END;
FUNCTION "ComputeOutflowGivenStorageForSpill" ( DATETIME month, NUMERIC previousPowellStorage, NUMERIC powellStorage )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft/month";
DESCRIPTION "Computes the outflow by mass balancing the reservoir with the given values.
The max outflow is constrained by Powell's max controlled release.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MAX_CONSTRAINT $ "Powell.Maximum Controlled Release" [0.00000000, 0.00000000];
BEGIN
"SolveMonthlyOutflowAnnualTimestep"( % "Powell", $ "PowellMonthly.Inflow" [month], powellStorage, previousPowellStorage, month );
END;
FUNCTION "GetPowellTailwaterElevation" ( DATETIME month, NUMERIC powellOutflow )
RETURN_TYPE NUMERIC;
SCALE_UNITS "ft";
DESCRIPTION "Using a given outflow, interpolates to find Powell's tailwater elevation using its
Tailwater Table.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"TableInterpolation"( $ "Powell.Tailwater Table", 0.00000000, 1.00000000, powellOutflow, month );
END;
END;
UTILITY_GROUP "General Functions";
DESCRIPTION "";
ACTIVE TRUE;
BEGIN
FUNCTION "MakeListWithPolicyFlag" ( NUMERIC powellStorage, NUMERIC policyFlag )
RETURN_TYPE LIST;
SCALE_UNITS "";
DESCRIPTION "Returns a 2 element list that includes Powell's storage and an integer indicating
the governing operation.
";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
{ powellStorage , policyFlag };
END;
FUNCTION "CreateList" ( LIST storages, LIST powellStorage, LIST meadStorage, BOOLEAN spikeFlowCheck )
RETURN_TYPE LIST;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( spikeFlowCheck )
THEN
APPEND "GetListElement"( - 1.00000000, meadStorage ) ONTO APPEND "GetListElement"( 0.00000000, powellStorage ) ONTO APPEND "GetListElement"( - 1.00000000, powellStorage ) ONTO SUB spikeFlowCheck @INDEX 0.00000000 OF ( SUB IF ( ( GET @INDEX 1.00000000 FROM storages ) == 0.00000000 )
THEN
"GetListElement"( 0.00000000, meadStorage )
ELSE
GET @INDEX 1.00000000 FROM storages
ENDIF @INDEX 1.00000000 OF storages )
ELSE
APPEND "GetListElement"( - 1.00000000, meadStorage ) ONTO APPEND "GetListElement"( 0.00000000, powellStorage ) ONTO APPEND "GetListElement"( - 1.00000000, powellStorage ) ONTO SUB IF ( ( GET @INDEX 1.00000000 FROM storages ) == 0.00000000 )
THEN
"GetListElement"( 0.00000000, meadStorage )
ELSE
GET @INDEX 1.00000000 FROM storages
ENDIF @INDEX 1.00000000 OF storages
ENDIF;
END;
FUNCTION "PowellComputeStorageAtGivenOutflow" ( NUMERIC outflow, NUMERIC previousPowellStorage, DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "Given a monthly outflow, this function computes the storage that will mass balance
Powell. This function will return a storage of 0.0 acre-ft if the given outflow volume
is less that the mass balanced storage with zero outflow, meaning that the given
outflow would cause the storage to go negative. This condition would be possible
during runs where Powell's min power pool is not protected. In this case, the
constraints that the storage is to be within inactive and live capacities should be
removed. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT $ "PowellData.MinimumContent" [];
MAX_CONSTRAINT "LiveCapacity"( % "Powell" );
BEGIN
IF ( "SolveMonthlyStorageAnnualTimestep"( % "Powell", $ "PowellMonthly.Inflow" [month], 0.00000000 "acre-ft/month", previousPowellStorage, month ) < ( outflow * "GetDaysInMonth"( month ) ) )
THEN
0.00000000 "acre-ft"
ELSE
"SolveMonthlyStorageAnnualTimestep"( % "Powell", $ "PowellMonthly.Inflow" [month], outflow, previousPowellStorage, month )
ENDIF;
END;
FUNCTION "ComputeOutflowAtGivenStorage" ( OBJECT reservoir, NUMERIC inflow, NUMERIC storage, NUMERIC previousStorage, DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft/month";
DESCRIPTION "Solves for the outflow by mass balancing the reservoir with the given input.
The result is constrained by the reservoir's min and max release.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT "MinRelease"( reservoir );
MAX_CONSTRAINT "MaxRelease"( reservoir );
BEGIN
"SolveMonthlyOutflowAnnualTimestep"( reservoir, inflow, storage, previousStorage, month );
END;
FUNCTION "ComputeStorageAtGivenOutflow" ( OBJECT reservoir, NUMERIC inflow, NUMERIC outflow, NUMERIC previousPowellStorage, DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
MIN_CONSTRAINT "InactiveCapacity"( reservoir );
MAX_CONSTRAINT "LiveCapacity"( reservoir );
BEGIN
"SolveMonthlyStorageAnnualTimestep"( % "Powell", inflow, outflow, previousPowellStorage, month );
END;
FUNCTION "Estimate Bank Storage without Evap" ( OBJECT reservoir, NUMERIC startStorage, NUMERIC endStorage )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Estimates the change in bank storage, given a starting and ending storage and
the reservoir's bank storage coefficient. This value may be negative.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
( endStorage - startStorage ) * reservoir & "Bank Storage Coefficient" [0.00000000, 0.00000000];
END;
FUNCTION "EstimateBankStorage" ( OBJECT reservoir, NUMERIC startStorage, NUMERIC endStorage, DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Estimates the change in bank storage from the current month through September by
applying the reservoir's bank storage coefficient to the change in storage from the current
month through September. The calculation of the change in storage includes loss due to
evaporation during that time.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
( endStorage - "EstimateEvaporation"( reservoir, startStorage, "Min"( endStorage, "LiveCapacity"( reservoir ) ), month, @"24:00:00 September 30, Current Year" ) - startStorage ) * reservoir & "Bank Storage Coefficient" [0.00000000, 0.00000000];
END;
FUNCTION "EstimateEvaporation" ( OBJECT reservoir, NUMERIC startStorage, NUMERIC endStorage, DATETIME startDate, DATETIME endDate )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes the reservoir's evaporation between the start and end dates. The sum of the
monthly evaporation coefficients over the date range is applied to the average surface
area. The evaporation is converted to a volume using the endDate. ";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
( ( "StorageToArea"( reservoir, startStorage ) + "StorageToArea"( reservoir, endStorage ) ) / 2.00000000 * "SumEvapCoeff"( reservoir, "GetMonth"( startDate ) - 1.00000000, "GetMonth"( endDate ) - 1.00000000 ) ) * "GetDaysInMonth"( endDate );
END;
FUNCTION "AnnualEvaporation" ( OBJECT reservoir, LIST dates )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
FOR ( DATETIME date IN dates ) WITH NUMERIC sum = 0.00000000 "acre-feet" DO
sum + "EstimateEvaporation"( reservoir, "RuleCurveStorage"( reservoir, date ), "RuleCurveStorage"( reservoir, date ), date, date )
ENDFOR;
END;
FUNCTION "SumEvapCoeff" ( OBJECT reservoir, NUMERIC startRow, NUMERIC endRow )
RETURN_TYPE NUMERIC;
SCALE_UNITS "ft/month";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"SumTableColumn"( reservoir & "Evaporation Coefficients", 0.00000000, startRow, endRow );
END;
FUNCTION "SumDepletionsBelowVolume" ( OBJECT reservoir, DATETIME startDate, DATETIME endDate )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Sums the depletion volume (diversion.Total Depletion Requested) over a date range within
a subbasin. The subbasin name is 'Below' and the name of the reservoir that was passed
to this function.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"SumObjectsAggregatedOverTime"( "Below" CONCAT STRINGIFY reservoir, "Total Depletion Requested", "SUM", "ALL", TRUE, startDate, endDate );
END;
FUNCTION "RuleCurveStorage" ( OBJECT reservoir, DATETIME date )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Returns the reservoir's monthly rule curve storage.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "UBRuleCurveData.BaseRuleCurves" [STRINGIFY reservoir, "GetMonthAsString"( date )];
END;
FUNCTION "InactiveCapacity" ( OBJECT reservoir )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Returns the reservoir's inactive capacity. Usually used as a minimum constraint.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "UBRuleCurveData.ReservoirData" [STRINGIFY reservoir, "inactiveCapacityStorage"];
END;
FUNCTION "LiveCapacity" ( OBJECT reservoir )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Returns the reservoir's live capacity storage. Ususally used as maximum
constraint.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "UBRuleCurveData.ReservoirData" [STRINGIFY reservoir, "liveCapacityStorage"];
END;
FUNCTION "MaxRelease" ( OBJECT reservoir )
RETURN_TYPE NUMERIC;
SCALE_UNITS "cfs";
DESCRIPTION "Returns the reservoir's maximum controlled release. This value is stored in a
slot on the reservoir object. Used as a maximum outflow constraint.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
reservoir & "Maximum Controlled Release" [0.00000000, 0.00000000];
END;
FUNCTION "MinRelease" ( OBJECT reservoir )
RETURN_TYPE NUMERIC;
SCALE_UNITS "cfs";
DESCRIPTION "Returns the reservoir's minimum release. Usually used as a minimum constraint.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
$ "UBRuleCurveData.ReservoirData" [STRINGIFY reservoir, "minRelease"];
END;
FUNCTION "MaxReleaseVolume" ( OBJECT reservoir, DATETIME startDate, DATETIME endDate )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-feet";
DESCRIPTION "Computes the outflow volume if the reservoir releases the max release from the startDate
to the endDate.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"Sum"( MAPLIST ( DATETIME date IN "GetDates"( startDate, endDate, "1 MONTHS" ) ) DO
"MaxRelease"( reservoir ) * "GetDaysInMonth"( date )
ENDMAPLIST );
END;
FUNCTION "MinReleaseVolume" ( OBJECT reservoir, DATETIME startDate, DATETIME endDate )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "Computes the outflow volume if the reservoir releases the minimum release from the
startDate to the endDate.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"Sum"( MAPLIST ( DATETIME date IN "GetDates"( startDate, endDate, "1 MONTHS" ) ) DO
"MinRelease"( reservoir ) * "GetDaysInMonth"( date )
ENDMAPLIST );
END;
FUNCTION "AveragePoolElevation" ( OBJECT reservoir, NUMERIC previousStorage, NUMERIC storage )
RETURN_TYPE NUMERIC;
SCALE_UNITS "ft";
DESCRIPTION "Returns the average pool elevation based on 2 storages.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
( "StorageToElevation"( reservoir, previousStorage ) + "StorageToElevation"( reservoir, storage ) ) / 2.00000000;
END;
FUNCTION "PreviousStorage" ( OBJECT reservoir )
RETURN_TYPE NUMERIC;
SCALE_UNITS "acre-ft";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
IF ( @"t" == @"Start Timestep" )
THEN
"ElevationToStorage"( reservoir, reservoir & "Pool Elevation" [@"t - 1"] )
ELSE
reservoir & "Storage" [@"t - 1"]
ENDIF;
END;
FUNCTION "AdjustFlowForDaysInMonth" ( DATETIME month )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"GetDaysInMonth"( month ) / 31.00000000 "day";
END;
FUNCTION "JanuaryToDecember" ( )
RETURN_TYPE LIST;
SCALE_UNITS "";
DESCRIPTION "Returns a list of months, from January to December.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"GetDates"( @"24:00:00 January Max DayOfMonth, Current Year", @"24:00:00 December Max DayOfMonth, Current Year", "1 months" );
END;
FUNCTION "JanuaryToJuly" ( )
RETURN_TYPE LIST;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"GetDates"( @"24:00:00 January Max DayOfMonth, Current Year", @"24:00:00 July Max DayOfMonth, Current Year", "1 months" );
END;
FUNCTION "JanuaryToSeptember" ( )
RETURN_TYPE LIST;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"GetDates"( @"24:00:00 January Max DayOfMonth, Current Year", @"24:00:00 September Max DayOfMonth, Current Year", "1 months" );
END;
FUNCTION "GetListElement" ( NUMERIC number, LIST result )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "Returns the element from the list at an index one greater than the index passed
to the function.";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
GET @INDEX number + 1.00000000 FROM result;
END;
FUNCTION "getDateAdjustedForTrace" ( DATETIME month )
RETURN_TYPE DATETIME;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"OffsetDate"( month, $ "MonthlyHydrology.TraceNumber" [@"Start Timestep"] * 12.00000000, "1 months" );
END;
FUNCTION "SumAnnualRelease" ( SLOT monthlyReleasePattern, NUMERIC rowIndex )
RETURN_TYPE NUMERIC;
SCALE_UNITS "";
DESCRIPTION "";
ACTIVE TRUE;
PRE_EXEC_DIAG TRUE;
POST_EXEC_DIAG TRUE;
BEGIN
"SumTableRow"( monthlyReleasePattern, rowIndex, 0.00000000, 11.00000000 );
END;
END;
END