# RiverWare_Ruleset 6.6.3 Patch
# Created 13:09 March 20, 2015
# 
RULESET
AGENDA_ORDER DESCENDING;
DESCRIPTION "For use with Lite1.12.mdl.gz or higher<br>2008-2025 Basin States' Proposal<br>Shortage -  Step Short Original<br>Powell - BS6.v2 with the Upper Equalization line in place of the 602a storage<br>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).<br><br>2006,2007,2026-2060<br>Shortage - 80P1050 AbsPro1000<br>Powell - Normal<br>Surplus - None (2006) ISG (2007) 70R (2026-2060)<br><br>";
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<br>set to execute once per timestep, only when the value is NaN or hasn't<br>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<br>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.<br><br>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. <br>";
    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. <br><br>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. <br><br>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.<br>";
    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.  <br><br>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.  <br><br>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 "ToCelcius"( 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. <br><br>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.<br><br>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 &quot;No Protect&quot; 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. <br><br>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.<br><br>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. <br><br>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.<br><br>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. <br><br>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.<br><br>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. <br><br>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,<br>M0, P1, PF1, M1, P2, PF2, M2, . . ., P12, PF12, M12) where Spike Flow Boolean indicates whether or not a<br>Spike Flow release was made, Flood Control Release Month Index represents the month of the first flood <br>control release (if any), P1 represents Powell's January storage (P0 is Powell's storage at December of <br>the previous year), PF1 represents the operational policy used to set Powell's storage for the corresponding<br>month, and M1 represents Mead's January storage. Powell and Mead's storages are computed from January<br>to December. <br><br><br>";
    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)<br>" 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<br>the criteria is met for Equalization, ComputeStorageWithEqualization(). In Oct - Dec, <br>Powell's storage is computed without the check for Equalization, <br>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,<br>the spike flow comes from the spill, i.e. Powell's release is not increased. If Powell is not going <br>to spill, the release needs to be increased for the spike flow. Determine the total release by <br>computing the outflow based on the regular spring operation procedures (constrained to be at <br>least the outflow trigger) plus the additional volume needed for the spike flow. If the spikeFlowCheck<br>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<br>a spike flow release. The storage is first set by the basic operations procedure and then<br>adjusted, if need be, based on the Limit Outflow, Smooth July Operation or Minimum <br>Objective Release policies.  This function returns a list that contains, at INDEX 0, the <br>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(). <br>MeadFloodControl() calls the method Mead Flood Control on the computational subbasin,<br>MeadFloodControl. The method Mead Flood Control first computes the release needed to <br>meet downstream demands. In the case that that release is not sufficient in meeting the <br>release needed for flood control, the release is set to the flood control release. The flood <br>control release is computed using algorithm derived by the USACE. The required arguments<br>are the subbasin name, the current month, Powell's previous storage, Powell's current <br>storage, Mead's previous storage, and an integer indicating the month (if any) of the <br>current year in which a flood control release was made.  Both Mead's monthly storage and<br>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<br>Powell's storage based on Equalization. If the criteria not met, Powell'e storage is<br>computed without Equalization. If Equalization occurs a check is made to ensure that, if it <br>2016 or earlier, that the Equalization release did not cause Powell's end of the water year <br>storage to drop below 14.85 MAF. In the case that it did drop below 14.85  MAF, the storage<br>is set to a minimum of 14.85 MAF and the storage resulting from Powell making the <br>minimum objective release for that month.<br><br><br>The criteria for Equalization is 1. that the end of the water year storage for Powell <br>(EOWYStoragePowell) computed with Powell's forecasted release from the current month <br>through Sept. (powellForecastRelease) must be greater than or equal to the end of the <br>water year storage for Mead (EOWYStorageMead) computed with Mead's forecasted <br>outflow from the current month through Sept. (meadForecastRelease) 2. the Upper Basin<br>Storage, computed with EOWYStoragePowell is greater than or equal the 602a storag<br>computed in Rule 1 602a Storage.  3. The current year is greater than 2016 or <br>EOWYStoragePowell is greater than or equal to 14.85 MAF.<br>";
    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 <br>and returns a BOOLEAN (TRUE for conditions are met, FALSE for conditions are not met).<br><br>In January, if the unregulated inflow forecast is greater than the trigger volume, a spike<br>flow is triggered. In Jan - July, if the outflow volume based on the spring operation<br>procedures is greater than a trigger volume, a spike flow is triggered.  Also in Jan - July if<br>the average release, also based on the spring operation procedures, is greater than the <br>release trigger, a spike flow is triggered.  Only one spike flow is to be released per year, so<br>this function is only called if the spike flow release has not been made at any time during <br>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.<br>This value is the same as the regulated runoff forecast computed in Rule 5 (Powell<br>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 <br>storage. This outflow is constrained to be at least the spike flow outflow<br>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 <br>arguments: EOWYStoragePowell, EOWYStorageMead, UpperBasinStorage, <br>meadForecastRelease, powellForecastRelease, powellReleaseMade, <br>previousPowellStorage, previousMeadStorage, floodControlReleaseMade (boolean) and the <br>current month.<br><br>ComputeEqualizationReleaseList() returns the total release volume need for EQ. <br>ConvertPowellRelease() subtracts powellForecastRelease from the total volume; this is <br>the change in release necessary to Equalize. The converted release is then checked in <br>CheckEqualizationRelease602a() to ensure that it does not cause a violation of the 602a<br>storage. ComputePowellRelease() divides the EQ release by the number of months <br>remaining to the EOWY and adds this to Powell's current outflow. <br>PowellComputeStorageAtGivenOutflow() then computes the storage required to make the<br>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 <br>if the computed EQ release will cause Mead to violate its exclusive flood control <br>space.  If the release will cause this violation, a new EQ release is computed as the live <br>capacity of Mead minus the minimum flood control space minus the estimated EOWY <br>storage for Mead.  Otherwise no changes to the equalization release are made.  Also note <br>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<br>the forecast error for the spring months), the previous month's storage and the outflow<br>volume assuming regular spring/fall operation procedures (powellRelease). It is then <br>constrained to be at least 0.0 acre-ft. This is called the initialEOWYstorage because it has <br>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 <br>SNWP's depletions (the current month through September) from the previous month's <br>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<br>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 <br>control space. First, the EQ release is checked for 602a violation in<br>CheckEqualizationRelease602a(). The result is then used, along with the current estimate<br>of Mead's EOWY Storage in CheckERMeadExclusiveFCS() to ensure that Mead's <br>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<br>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 <br>release will not violate the Upper Basin 602a Storage.  This check is computed by<br>subtracting the EQ release from the current month through the EOWY, from the amount of <br>storage in the Upper Basin (UpperBasinStorage). This value is then compared to the value <br>of 602a storage that has already been set by Rule 1 602a Storage.  Also note that the <br>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 <br>LIST dates. This is used in estimating Mead's release to compute the end of the <br>water year storage in Mead for Equalization.<br>";
    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<br>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<br>the current month through Sept to for Equalization (EQ) of Powell and Mead. An iterative <br>computation is required to account for evaporation and bank storage losses.  A four <br>element list, named result, is returned by this function with the order:  Total Equalization <br>Release (EQ release plus Powell's forecasted release), EOWYStoragePowell, <br>EOWYStorageMead, iteration count. <br><br>The list is first initialized with the function InitializedEqualizationReleaseList(). The next <br>step is to add 1.0 to the iteration count which is at INDEX 3 (or 4th element) in the list. <br>Then EOWYStorageMead is recomputed with EQ release computed in TotalPowellRelease()<br>and is stored at INDEX 2. Next, the EQ release is checked to ensure that it doesn't <br>violate 602aStorage or Mead's flood control space and if it does, it is adjusted properly <br>in ComputeNewPowellRelease(). Then EOWYStoragePowell is computed with the checked <br>EQ release and is stored at INDEX 1. Lastly, the EQ release is inserted the list position <br>INDEX 0. <br><br>The computation described above is repeated until 1. the absolute difference of <br>EOWYStoragePowell and EOWYStorageMead is less that the EQ tolerance (currently set<br>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<br>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<br>water year from the EQ release computed in ComputeEqualizationReleaseList(). The EQ<br>release at INDEX 0 is the most recently computed value. Recall that this EQ release is the <br>total volumetric release from Powell. It's necessary to subtract the forecasted release to <br>compute the extra release needed for EQ. Also note that the result of this function is <br>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<br>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<br>Powell and Mead by the end of the water year. To get the current outflow from Powell, the<br>storage must first be computed based on the the operation procedures other than <br>Equalization or Spike Flow. Recall that ComputeStorageWithNoEqualization() returns a list<br>that includes both the storage and policy flag. Here only the storage is of interest which is<br>the first element in the returned list (INDEX 0). GetListElement() retrieves the element at <br>one greater than the index argument. Also note that the result of this function is <br>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.  <br>In Jan - July, the forecast error is included in the forecast. <br>";
    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, <br>execpt that the forecasted outflow volume is contrainied by the min release volume, min <br>objective release volume, and the max release volume.  If the springOutflowVolConstrained<br>was not constrained, the resulting storage is the July target storage.  This resulting <br>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<br>volume and a min of the max of Powell's min release volume and the minimum objective<br>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 <br>storage as the initial storage. The min constraint on the outflow volume is the max of the<br>min release volume and the remaining objective release. The max constraint is the max<br>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<br>for Equalization.  The estimated release is based on the spring operation through July and <br>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 <br>releases. First their initial EOWY storages are computed. Next, the evaporation and bank <br>storage by is calculated using the initial estimate of the EOWY storage and the previous <br>month's storage. The evaporation and bank storage is then subtracted from the initial <br>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,<br>M0, P1, PF1, M1, P2, PF2, M2, . . ., P12, PF12, M12) where Spike Flow Boolean indicates whether or not a<br>Spike Flow release was made, Flood Control Release Month Index represents the month of the first flood <br>control release (if any), P1 represents Powell's January storage (P0 is Powell's storage at December of <br>the previous year), PF1 represents the operational policy used to set Powell's storage for the corresponding<br>month, and M1 represents Mead's January storage. Powell and Mead's storages are computed from January<br>to December. <br><br><br>";
    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)<br>" 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<br>the criteria is met for Equalization, ComputeStorageWithEqualization(). In Oct - Dec, <br>Powell's storage is computed without the check for Equalization, <br>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<br>Powell's storage based on Equalization. If the criteria not met, Powell'e storage is<br>computed without Equalization. If Equalization occurs a check is made to ensure that, if it <br>2016 or earlier, that the Equalization release did not cause Powell's end of the water year <br>storage to drop below 14.85 MAF. In the case that it did drop below 14.85  MAF, the storage<br>is set to a minimum of 14.85 MAF and the storage resulting from Powell making the <br>minimum objective release for that month.<br><br><br>The criteria for Equalization is 1. that the end of the water year storage for Powell <br>(EOWYStoragePowell) computed with Powell's forecasted release from the current month <br>through Sept. (powellForecastRelease) must be greater than or equal to the end of the <br>water year storage for Mead (EOWYStorageMead) computed with Mead's forecasted <br>outflow from the current month through Sept. (meadForecastRelease) 2. the Upper Basin<br>Storage, computed with EOWYStoragePowell is greater than or equal the 602a storag<br>computed in Rule 1 602a Storage.  3. The current year is greater than 2016 or <br>EOWYStoragePowell is greater than or equal to 14.85 MAF.<br>";
    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<br>a spike flow release. The storage is first set by the basic operations procedure and then<br>adjusted, if need be, based on the Limit Outflow, Smooth July Operation or Minimum <br>Objective Release policies.  This function returns a list that contains, at INDEX 0, the <br>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,<br>the spike flow comes from the spill, i.e. Powell's release is not increased. If Powell is not going <br>to spill, the release needs to be increased for the spike flow. Determine the total release by <br>computing the outflow based on the regular spring operation procedures (constrained to be at <br>least the outflow trigger) plus the additional volume needed for the spike flow. If the spikeFlowCheck<br>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<br>a spike flow release. The storage is first set by the basic operations procedure and then<br>adjusted, if need be, based on the Limit Outflow, Smooth July Operation or Minimum <br>Objective Release policies.  This function returns a list that contains, at INDEX 0, the <br>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<br>Powell's storage based on Equalization. If the criteria not met, Powell'e storage is<br>computed without Equalization. If Equalization occurs a check is made to ensure that, if it <br>2016 or earlier, that the Equalization release did not cause Powell's end of the water year <br>storage to drop below 14.85 MAF. In the case that it did drop below 14.85  MAF, the storage<br>is set to a minimum of 14.85 MAF and the storage resulting from Powell making the <br>minimum objective release for that month.<br><br><br>The criteria for Equalization is 1. that the end of the water year storage for Powell <br>(EOWYStoragePowell) computed with Powell's forecasted release from the current month <br>through Sept. (powellForecastRelease) must be greater than or equal to the end of the <br>water year storage for Mead (EOWYStorageMead) computed with Mead's forecasted <br>outflow from the current month through Sept. (meadForecastRelease) 2. the Upper Basin<br>Storage, computed with EOWYStoragePowell is greater than or equal the 602a storag<br>computed in Rule 1 602a Storage.  3. The current year is greater than 2016 or <br>EOWYStoragePowell is greater than or equal to 14.85 MAF.<br>";
    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 <br>arguments: EOWYStoragePowell, EOWYStorageMead, UpperBasinStorage, <br>meadForecastRelease, powellForecastRelease, powellReleaseMade, <br>previousPowellStorage, previousMeadStorage, floodControlReleaseMade (boolean) and the <br>current month.<br><br>ComputeEqualizationReleaseList() returns the total release volume need for EQ. <br>ConvertPowellRelease() subtracts powellForecastRelease from the total volume; this is <br>the change in release necessary to Equalize. The converted release is then checked in <br>CheckEqualizationRelease602a() to ensure that it does not cause a violation of the 602a<br>storage. ComputePowellRelease() divides the EQ release by the number of months <br>remaining to the EOWY and adds this to Powell's current outflow. <br>PowellComputeStorageAtGivenOutflow() then computes the storage required to make the<br>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<br>Powell and Mead by the end of the water year. To get the current outflow from Powell, the<br>storage must first be computed based on the the operation procedures other than <br>Equalization or Spike Flow. Recall that ComputeStorageWithNoEqualization() returns a list<br>that includes both the storage and policy flag. Here only the storage is of interest which is<br>the first element in the returned list (INDEX 0). GetListElement() retrieves the element at <br>one greater than the index argument. Also note that the result of this function is <br>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<br>water year from the EQ release computed in ComputeEqualizationReleaseList(). The EQ<br>release at INDEX 0 is the most recently computed value. Recall that this EQ release is the <br>total volumetric release from Powell. It's necessary to subtract the forecasted release to <br>compute the extra release needed for EQ. Also note that the result of this function is <br>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<br>for Equalization.  The estimated release is based on the spring operation through July and <br>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<br>the current month through Sept to for Equalization (EQ) of Powell and Mead. An iterative <br>computation is required to account for evaporation and bank storage losses.  A four <br>element list, named result, is returned by this function with the order:  Total Equalization <br>Release (EQ release plus Powell's forecasted release), EOWYStoragePowell, <br>EOWYStorageMead, iteration count. <br><br>The list is first initialized with the function InitializedEqualizationReleaseList(). The next <br>step is to add 1.0 to the iteration count which is at INDEX 3 (or 4th element) in the list. <br>Then EOWYStorageMead is recomputed with EQ release computed in TotalPowellRelease()<br>and is stored at INDEX 2. Next, the EQ release is checked to ensure that it doesn't <br>violate 602aStorage or Mead's flood control space and if it does, it is adjusted properly <br>in ComputeNewPowellRelease(). Then EOWYStoragePowell is computed with the checked <br>EQ release and is stored at INDEX 1. Lastly, the EQ release is inserted the list position <br>INDEX 0. <br><br>The computation described above is repeated until 1. the absolute difference of <br>EOWYStoragePowell and EOWYStorageMead is less that the EQ tolerance (currently set<br>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<br>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 <br>control space. First, the EQ release is checked for 602a violation in<br>CheckEqualizationRelease602a(). The result is then used, along with the current estimate<br>of Mead's EOWY Storage in CheckERMeadExclusiveFCS() to ensure that Mead's <br>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 <br>release will not violate the Upper Basin 602a Storage.  This check is computed by<br>subtracting the EQ release from the current month through the EOWY, from the amount of <br>storage in the Upper Basin (UpperBasinStorage). This value is then compared to the value <br>of 602a storage that has already been set by Rule 1 602a Storage.  Also note that the <br>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<br>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 <br>storage as the initial storage. The min constraint on the outflow volume is the<br>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 <br>through the endDate and scales it by the ratio of the amount remaining through the EOWY <br>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 <br>through the endDate and scales it by the ratio of the amount remaining through the EOWY <br>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 <br>objective release by the end of the water year by taking into account the actual releases<br>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 <br>objective release by the end of the water year by taking into account the actual releases<br>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<br>be called under the following pre-existing conditions: 1. The current month is July-Dec <br>2. Powell's current release is greater than 1.5 MAF/mo.  3. It has been determined that a <br>release of 1.5 MAF/mo. will result in a storage of less than 23.822 MAF.<br>";
    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 <br>called under the following pre-existing conditions: 1. The current month is July  2. Powell's<br>current outflow is less than 1.0 MAF/mo.  3. Powell's current storage is greater than <br>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 <br>objective release for the current month.  This function is called from <br>ComputeStorageWithNOEqualization and the outflow passed to this function was computed<br>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 <br>previous month.  This quantity is used to determine whether or not Powell<br>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<br>fall storages stored on the reservoir object (Powell.Monthly Storage). If it is <br>the start of the run, fall storages of the previous year do not exist. The fall <br>release is computed by summing the input values for Powell's release for the <br>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<br>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 <br>through the endDate and scales it by the ratio of the amount remaining through the EOWY <br>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<br>reservoir. The resulting outflow is not constrained because this is simulating the<br>actual dispatch method on the reservoir which, in the case of a negative outflow,<br>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<br>remaining to meet 8.23 MAF by the end of the water year by a release fraction. The release <br>fraction is computed as the scheduled min obj rel for the current month (stored in the <br>data obj UBRuleCurveData) divided by the sum of the remaining scheduled min obj <br>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 <br>objective release by the end of the water year by taking into account the actual releases<br>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<br>storage, the release is solved for in ComputeOutflowAtGivenStorageNoConstraint().<br>The FLOW value returned is converted to a VOLUME by multiplying by the days in<br>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<br>storage, the release is solved for in ComputeOutflowAtGivenStorageNoConstraint(). <br>The FLOW value returned is converted to a VOLUME by multiplying by the days in <br>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 <br>will meet a July target storage in the spring (Jan - July) or a December target in<br>the fall (Aug - Dec) and the regulated infow forecast computed in Rule 5 Powell<br>Spring Runoff Forecast. The inflow forecast for the spring includes the forecast<br>error while the inflow forecast for the fall does not. The outflow volume required<br>to meet the target storage is multiplied by a release fraction to determine the <br>outflow for the current month. <br>";
    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 <br>resulting storage given the inflow at the current month. <br>PowellComputeStorageAtGivenOutflow constrains the resulting storage to be <br>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<br>weights. It is constrained by the minimum and maximum release. It also checks to see if the outflow <br>volume average (equally distributed over the remaining months) exceeds a check (currently 1 MAF/mo).  <br>If so, the outflow is equally weighted for the remaining months. This was added to account for high <br>forecast years, where real operation would require releasing the water quicker than what the current <br>weights allow.<br>";
    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) <br>required to meet the July target storage. The regulated inflow forecast includes a forecast<br>error and was computed in Rule 5, Powell Spring Runoff Forecast. This value is allowed to<br>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<br>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 <br>resulting storage given the inflow for the current month. <br>PowellComputeStorageAtGivenOutflow constrains the resulting storage to be <br>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<br>current month through December for Powell to meet a December target storage and the current<br>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 <br>through December necessary to meet the December target.<br>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 <br>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<br>month's weight by the sum of the weights from the current month through July or December. <br>Since the tables are indexed from zero, subtract 1 from the numeric month. This function <br>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<br>endDate. No forecast error is used. The natural inflow is adjusted for Upper <br>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 <br>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 <br>from one month prior to the startDate through the endDate. This value is used to<br>compute PowellRegulatedInflowVolume() during the fall months, meaning the <br>total regulation is essentially the total amount of drawdown. For fall drawdown, <br>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 <br>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<br>endDate. Returns a negative number because the reservoir is being drawn down to <br>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<br>earlier than the startDate, the initial storage is set to the reservoir's target storage for one<br>month prior to the startDate. Otherwise, the initial storage is just the reservoir's previous <br>month's storage. If this function is being called from UBDrawDown(), then this value is to <br>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<br>"
      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<br>"
      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<br>"
      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<br>"
      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<br>"
      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<br>"
      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<br>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%)<br>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%)<br>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<br>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<br>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<br>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 <br>available, CAP's diversion is its normal depletion request reduced by its Level 2 Shortage<br>amount. The there is no water available, CAP's diversion is reduced to 0.0 acre-ft. Note<br>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. <br>";
    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 <br>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.  <br>Includes the gains and the evap losses at Mohave and Havasu. Assumes that Mohave and <br>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<br>between Powell and Mead to Powell's outflow and subtracting the depletions<br>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)<br>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 <br>Powell's minimum objective release and the outflow resulting from Powell dropping to <br>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<br>subtracting the depletions in the UB above Powell and adding water available from the UB <br>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 <br>range of dates.  Available water is defined as the volume above inactive capacity for each <br>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 <br>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. <br>";
    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<br>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<br>"
      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<br>"
      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 <br>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 <br>Quantified Level 1 Surplus of the 7 State Plan and is constrained to a minimum of 0.0 <br>acre-ft. <br><br>The total amount of surplus water is divided between the states and then is divided up <br>within the states. It is assumed that only Arizona will have unused water and gave 50% <br>each to California and Nevada. Once MWD gets its full allowance, any remaining water is <br>given to Coachella and IID by percentages used in computing the Level 1 scheduels for <br>them. Those were 128533/300000 = 0.4284 for Coachella and 171467/300000 = 0.5716<br>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.<br><br>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<br>surplus volume.  So we compute a surplus delta (surplus depletion - normal depletion) and add that to the normal diversion.<br><br>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<br>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<br>Mead that will meet the system space requirement at the beginning of the year. It is<br>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<br>the evaporation losses in Mohave, Havasu and Mead minus the average gains<br>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, <br>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<br>it be examined closely in conjuction with all of the functions that sum demands into the future such as SumDemandsDownstreamOfMead, and SumDemandsBelowMead and <br>SumCurrentDemandsBelowMead, to see if a common function could replace all of these.  It is not possible now in order to match CRSS results.<br><br>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<br>beiing surplused.<br><br>5/17 cj - SumFlowsToVolume() returns a value that is about 6000 acre-ft more, during<br>leap years, than what CRSS gets when it uses SumObjectsAggregatedOverTime() for <br>the BelowMead subbasin to get this annual volume.  <br><br>7/22 cj - The value in BelowMeadOtherSchedule.MonthlyDepletion represents<br>the sum of the 'Total Depletion Requested' slot in each agg diversion site in the<br>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<br>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<br>the Upper Basin storage is less than the 602a storage, Equalization does not <br>occur. <br><br>It is computed by multiplying the sum of the shorted UB depletion and the min <br>objective release minus the average annual natural inflow into the UB over the <br>critical period, by the critical period and adding the amount of min power pool to <br>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 <br>12 years of the UB scheduled depletions� and the average annual evaporation loss in the<br>UB multiplied by a percent shortage applied to the UB depletions during the critical period.<br>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<br>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<br>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,<br>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()<br>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 <br>error is 0.0. The July forecast error is equal to a quarter of the June forecast error. The absolute <br>value of the June forecast error is not to exceed half of May's forecast error.  When these <br>conditions are met, the forecast error is computed in the function ComputeInitialForecastError()<br>based on the previous forecast error, regression coefficients, Powell's runoff and the random <br>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, <br>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().<br>In July - Dec, the random deviation is 0.0. The argument being passed to <br>RanDev() refers to the units that the random deviation is to be returned in, in<br>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<br>index 0 refers to the first element in the list (January's forecast error). Zero is returned if the <br>month is January because at this point the list is empty. There is no forecast error in Aug -<br>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<br>the first random number should be retrieved. This function essentially converts <br>the NUMERIC the slot MeadFloodControlData.HydroloyStartYear[0,0] to a <br>DATETIME.<br>";
    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 <br>the pre-defined function OffsetDate() to compute the rewind year as a DATETIME.<br>This increment is added to the arbitrary year in OffsetDate(), January 1, 2000 <br>(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<br>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<br>through July.  This is done by adjusting the natural inflow for the estimated <br>Upper Basin depletions and potential reservoir regulation above Powell and <br>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<br>by subtracting that reservoir's previous month's storage from its live capacity<br>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 <br>summing the available space (live capacity - previous month's storage) for<br>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 <br>of the depletions downstream of Mead and Mohave and Havasu regulation, including <br>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. <br>The BOOLEAN floodControl indicates whether or not a flood control release was made prior<br>to the current month. If a flood control release was made, the depletions for MWD, CAP, <br>Coachella, IID and Mexico are based on their flood control surplus schedules. <br>";
    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,<br>SNWP or Coachella, from the startDate to endDate.  In order to do this the annual <br>schedules are first disaggregated using monthly percentages and then summed for the <br>given date range. If a floodControl release was made that year (floodControl = TRUE) the <br>demands are based on the diversion's surplus schedule and therefore the surplus percent is<br>used. Otherwise, DetermineSchedulePercent() is called to determine the disaggregation<br>percent by checking to see if the diversion was scheduled for a normal, shortage or surplus<br>year. DetermineSchedulePercent() returns the slot where the appropriate percent is <br>stored, either SchedulePercent.Normal, SchedulePercent.Shortage, or <br>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 <br>percents based on whether the year is normal, surplus or shortage. This function is not <br>specific to each diversion. For example, if an 80P1083 Shortage is in effect, the shortage <br>percent will be used to disaggregate the annual schedules for all diversions even though <br>only CAP and SNWP are only affected by an 80P1083 Shortage. This is acceptable, for <br>now, because only CAP's percents actually differ based on shortage, surplus or normal.<br><br> ";
    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 <br>turbines for the current operating head. The operating head is a function of the pool <br>and tailwater elevations. Before computing the peak flow, the operating head must <br>be within the min and max operating head. If it is less than the minimum, the peak <br>flow is set to 0. If it is greater than the max, the peak flow is set to 34000.32 cfs<br>which is the greatest possible peak flow based on the PeakPowerCalc. After the <br>operating head check is made, the peak flow is found through 2D table interpolation <br>with the average pool elevation.<br>";
    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<br>power calculation, PeakPowerCalc. With a given storage, an outflow is determined.<br>With that outflow, the corresponding tailwater elevation and best generator flow, a<br>peaking flow value (peakPowerFlow) is determined. If the outflow is greater than<br>the peakPowerFlow, Powell is assumed to spill the difference.  If not, then all the <br>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.<br>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 <br>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<br>the governing operation.<br>";
    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 <br>Powell. This function will return a storage of 0.0 acre-ft if the given outflow volume <br>is less that the mass balanced storage with zero outflow, meaning that the given <br>outflow would cause the storage to go negative. This condition would be possible <br>during runs where Powell's min power pool is not protected. In this case, the <br>constraints that the storage is to be within inactive and live capacities should be <br>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. <br>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 <br>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 <br>applying the reservoir's bank storage coefficient to the change in storage from the current<br>month through September. The calculation of the change in storage includes loss due to<br>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 <br>monthly evaporation coefficients over the date range is applied to the average surface <br>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 <br>a subbasin. The subbasin name is 'Below' and the name of the reservoir that was passed<br>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<br>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 <br>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<br>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 <br>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<br>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