skip to main content
Rulebased Simulation
Solution Approaches
Rulebased Simulation
Rulebased simulation is an extension of the RiverWare basic Simulation feature, in which some of the data to solve an underdetermined model is provided by a set of user-defined rules. Rule execution alternates with dispatching to simulate the effects of the rules in the model.
Simulation Review
Rulebased Simulation can only be understood once the fundamentals of basic Simulation have been mastered. This section assumes that you have a familiarity with simulation; see “Simulation” for details. However, we will briefly review some key concepts to ensure that everyone’s knowledge is current.
Dispatch Slots
Each object has a set of slots for which new values will cause the object to try to solve. These are the object’s dispatch slots. All dispatch slots are time series slots. All slots which can be linked to slots on other objects are dispatch slots, and all slots which are included in the dispatch conditions of any dispatch method are dispatch slots. Whenever a value is set on a dispatch slot, the object on which the slot resides must examine its state to determine if it needs to solve; i.e., execute a dispatch method.
Dispatch Methods
Dispatch methods are the algorithms for solving the physical process equations of RiverWare objects. There is one dispatch method for each combination of inputs and outputs for which a solution is possible.
Dispatching
If an object determines that it can execute a dispatch method, it notifies the controller of the method it will execute. The controller adds the object to a queue of objects waiting to execute their methods. When a dispatch method on an object is executed, we say that the object has dispatched. The objects dispatch in the order they are added to the queue.
Dispatch Conditions
Each dispatch method has a set of dispatch conditions which must be met for that dispatch method to be executed during a timestep. The dispatch conditions specify the input/output data combination required for that method to successfully execute. The dispatch conditions for each method are made up of two slot lists called the knowns and the unknowns. If all of the required knowns are known and all of the required unknowns are not known, the object may solve using that dispatch method. The dispatch conditions are checked whenever a value is set on a dispatch slot and no dispatch method has yet executed at that timestep.
Redispatching
After an object has dispatched once, if one or more of its dispatch slots gets a new value (for example by link propagation from another object), the object must resolve. In pure simulation, the object simply redispatches with the same dispatch method as the first time it dispatched in the timestep. In other words, an object may solve using only one combination of input/output data on any given timestep.
Over/Underdetermination
Each object has a conflict list which lists a combination of slots which, if all are known, result in too many knowns and not enough unknowns for the object to solve. If this situation is detected during a run, an over-determination error is posted, and the simulation is halted. Also, each slot keeps track of where its values originate: user input, link propagation, or set by the object’s methods. At each timestep, each slot can receive information from only one of these three sources. If a slot is set by one source, and subsequently reset by another source, an over-determination error is posted, and the simulation is halted. As a result, values may only propagate across a link in one direction during a single timestep.
How Rulebased Simulation Works
Rulebased Simulation is a variation of RiverWare basic Simulation, in which an underdetermined model is provided additional information from user-specified rules that represent the operating policy of the basin. A Rulebased Simulation model does not contain enough inputs for all objects to solve. Instead, it relies on the rules to provide additional information needed to fully solve the model. Rules provide this information by setting slot values in the model. The information provided by the rules, together with the input data, results in an exactly specified model.
The rules are logical statements formulated by the modeler and written within RiverWare, in a special language which is interpreted at runtime. Thus, the rules are data which can be saved and modified without having to recompile a program.
Rulebased Simulation works by alternating between executing rules and dispatching objects on the queue. The rules set values in slots. As a result of these values, objects may have enough information to dispatch. The ensuing dispatching simulates the effects of the rules in the model.
The Rulebased Simulation controller is available in RiverWare as an alternative controller to the Simulation controller. The Rulebased Simulation controller uses the same physical process algorithms as the Simulation controller, so the same user methods and slots are available regardless of which controller is active. You do not need to modify a model built for basic Simulation to run it under the Rulebased Simulation controller, other than setting slots to “output” which will be set by the rules. Data specific to User Methods do not need to change. This allows the same model to be used for what-if scenario runs using Simulation and for policy-driven model runs with Rulebased Simulation.
Rules and Rulesets
A single rule consists of one or more logical statements which assign values to one or more slots in the model. The rule is written in a special language, the RiverWare Policy Language (RPL). The rule’s logic may reference the current state of the model—determined from the values in slots—to decide if, and to what value, slots are assigned.
 
Rule
A rule is a statement, formulated in the RiverWare Policy Language, which assigns values to one or more series slots in the model based on logic within the statement and possibly based on the values of slots in the model.
Note:  Rules can assign values on series slots only. If you wish to set values on table slots, use Initialization Rules; see “Initialization Rules Set” in RiverWare Policy Language (RPL) for details.
Rules are designed and constructed by modelers to mimic policy and decisions which would normally be implemented in scheduling river and reservoir operations. Ideally, each rule represents a specific operating policy. The set of rules represents the entire operating policy for the basin. In order to resolve conflicting policy in rules, the modeler gives each rule a unique priority relative to the other rules. Higher priority is indicated by a smaller number; i.e., priority #1 is higher than priority #2.
 
Ruleset
A ruleset is a set of prioritized rules which together constitute the operating policy for the modeled basin and which, along with user inputs, provide the information needed to solve the simulation.
A simple guide curve rule for a reservoir is shown below. This rule looks at the Spill slot on the Hoover Dam object at the current timestep. If there is no spill, the rule reads the Guide Curve Elevation from a data slot and sets Hoover Dam’s Pool Elevation equal to it. If, however, Hoover Dam is spilling, then the rule has no effect.
 
Example 2.1   
HooverDam.Pool Elevation = IF (HooverDam.Spill = 0.0 [cfs]) THEN
HooverDamData.Guide Curve Elevation[]
The format of the rule may look unusual if you are accustomed to programming in languages such as FORTRAN and C++. In those languages, it is normal to put the assignment statement within the logic (inside the THEN clause of the IF statement). In RPL, all slot value assignments are made at the top level of the rule. The slot being assigned a value appears on the left-hand side (LHS). The right-hand side (RHS) is a logical construct which evaluates to a single value or to nothing.
Rule Execution
When a rule executes, or fires, the rule is interpreted and logic of the rule is executed. Firing a rule does not imply that a slot value necessarily will be set. In the example above, if HooverDam.Spill is zero, the RHS evaluates to the Guide Curve Elevation. If, however, the spill is greater than zero, the RHS does not result in a value, and no assignment is made. It is also possible that the HooverDam.Spill slot does not have a value, in which case there is not enough information for the RHS to result in a value.
Firing of a rule only means that the rule’s logical expressions will be evaluated and that the evaluation may result in a slot value being set. There are three possible outcomes when a rule fires.
Early termination
A rule execution which terminates early is one in which there is not enough information to evaluate all of the rule logic. This happens when a referenced slot (a slot on the RHS), is NaN; i.e., it does not currently have a value. If this is the case in at least one of the slot assignments, the rule terminates and no attempt is made to set any slot. This is considered a normal termination and does not stop the run or generate any errors. If you wish the rule to stop the run when a NaN slot is found, use the Stop on NaN functionality; see “Stop On NaN” in RiverWare Policy Language (RPL) for details.
Ineffective
An ineffective rule execution is one in which the rule logic is completely evaluated (all referenced slot values are known), but no slot values are set. This can happen for the following reasons:
• The logic determines that no slot assignment is necessary because no value is returned by the RHS.
• A value is returned by the RHS, but the slot assignment fails because the slot has already been set by a higher-priority rule. If the rule contains multiple slot assignments and if at least one assignment fails due this reason, then none of the assignments are made.
Successful
A successful rule execution is one in which at least one slot value in the model is set by the rule. To be successful requires that all the following conditions are met:
• All the information needed to evaluate all of the assignments is available; i.e., no NaNs are encountered in reference slots.
• At least one of the assignments is effective (evaluates to a number).
• None of the assignments fails due to priorities.
Rule Dependencies
A rule’s dependencies are all the slots that the rule’s logic referenced the last time the rule fired during the current timestep. These are the slots on which the rule’s outcome depends. As a rule’s logic is executed, the rule processor keeps track of all slots referenced in the logic. In practice, any slot whose value at the current timestep is used during a rule firing is automatically added to the dependency list for that rule.
If any of the values of the dependencies subsequently change during the rest of the timestep, the rule must refire. When it refires, the RHS may evaluate to a different value — resulting in a different slot assignments—and perhaps a different outcome, than during its previous firing.
 
Rule dependencies
A rule’s dependencies is a list of dependent slots—slots that the rule referenced the last time it fired during the current timestep. These are the slots upon which the outcome of the rule execution depended. A new value in a dependent slot causes the rule to be refired.
The dependency list is generated anew each time a rule fires.
 
Example 2.2  Rule firing
Consider the following rule:
Object.SlotToBeAssigned = IF (Object.SlotA > Object.SlotB) THEN
IF (Object.SlotA > Object.SlotC) THEN
Object.SlotA
1. The first time the rule fires, the slot values are as follows:
SlotA = 30
SlotB = 20
SlotC = 10
2. The rule firing starts by clearing the dependency list.
3. The first IF evaluates to true, and both SlotA and SlotB are added to the dependency list. The second IF also evaluates to true, and SlotC is added to the dependency list.
4. The rule assigns 30 to the SlotToBeAssigned, finishes successfully, and the dependency list is now: SlotA, SlotB and SlotC.
5. Now assume that during the ensuing dispatching, SlotB is recalculated to be 40, requiring that the rule fire again.
6. The second time the rule fires, the slot values are as follows:
SlotA = 30
SlotB = 40
SlotC = 10
7. The rule firing starts by clearing the dependency list.
8. The first IF evaluates to false, and both SlotA and SlotB are added to the dependency list.
9. There is no ELSE clause, so there is no RHS value. The rule finished ineffectually, and the dependency list is now: SlotA and SlotB.
10. Now assume that during the ensuing dispatch, SlotC is recalculated to be 50.
11. The rule is not fired again because SlotC is not a dependency; the result of firing the rule again would not be different.
12. When a rule terminates early because one of the slots it references is a NaN, that slot is put on the rule’s dependency list. This ensures that the rule will refire whenever the slot value becomes known. If the slot does not get a value during the current timestep, the rule is not put back on the agenda, and it will not refire at the current timestep.
Rules Agenda
The agenda is a list of rules eligible to be fired. The user can select whether the list is in order of priority from the highest eligible rule at the top to the lowest eligible rule at the bottom or vice versa.
 
Agenda
The agenda is the prioritized list of rules eligible to be fired at a given time. A rule is taken off the agenda when it fires and added back to the agenda when one of its dependencies gets a new value.
At the start of each timestep, all rules in the ruleset are added to the agenda. This ensures that each rule will be fired at least once before the end of the timestep. When the rules processor is ready to execute a rule, it fires either the highest or lowest priority rule on the agenda (depending on the selection the user has made). After a rule fires, it is removed from the agenda. Whenever any of its dependencies gets a new value, the rule is added back onto the agenda in its appropriate place according to priority. Therefore, rules always fire in the priority order specified by the user.
Note:  Compare the rules agenda with the Simulation dispatch queue: both are lists of items to be processed. The Simulation dispatch queue, however, processes the dispatches in the order in which they were added; whereas the rules agenda processes rules in priority order, independent of the order in which they were added to the agenda.
Example 2.3   
Consider a ruleset with five rules, numbered 1 through 5. The user has selected the option to execute the agenda in descending priority order (i.e. 1, 2, 3, ... ). After the start of the first timestep, three rules are executed and finish ineffectually. The next rule to be executed finishes successfully. During the ensuing dispatch, one of rule #2’s dependent slots gets a new value, so rule #2 is put back on the agenda.
What rules are now on the agenda? What is the minimum number of rules which will fire before the end of the timestep? What is the maximum?
Answers:
• After the start of the timestep, the agenda is: #1, #2, #3, #4, #5.
• After three rules are executed ineffectually, the agenda is: #4, #5.
• After the next rule executes successfully, the agenda is: #5.
• After the dispatch changes a dependency of rule #2, the agenda is: #2, #5.
• At least two rules (#2 and #5) must fire before the end of the timestep.
• The maximum number of rules which will fire cannot be determined.
Rulebased Simulation Controller
The rulebased simulation controller orchestrates the alternation between execution of rules and solving of the simulation during a rulebased simulation run. It manages the dispatching of objects on the dispatch queue, just as the simulation controller does. When no objects can dispatch, the controller invokes the rule processor. The rule processor fires rules on the agenda, in the priority order specified by the user, until a rule is successful. Then, the controller again processes the dispatch queue.
Controller Priority
An additional function of the rulebased simulation controller is to track the controller priority when objects are dispatching. The purpose of the controller priority is to track the priority of the effects of rules as they are simulated in the model.
 
Controller priority
The controller priority during simulation (dispatching) is the priority of the data which is driving the current simulation. The controller priority is zero at each timestep until a rule succeeds, after which it is the priority of the last rule to succeed.
The controller priority during object dispatching reflects the priority of the information driving the dispatching. During Initialization, Beginning of Run, End of Run and each Beginning and End of Timestep, the controller priority is set to 0. During Initialization, user inputs are “set” in the slots. During Beginning of Run and Beginning of Timestep, default values are set where user input has deliberately been left out. Any slots set during these times are considered in rulebased simulation as if they had been directly input by the user. The controller priority of 0 remains in effect during the dispatching which occurs immediately after Beginning of Timestep. Since no rules have fired yet, all of these dispatches result from user input.
After a rule successfully fires and sets one or more slot values, the controller priority is set to the priority of the successful rule. As a result of these slot values, one or more objects may be ready to dispatch. Since the impending dispatch and any subsequent dispatches are a direct result of the rule’s slot assignment, these calculations are performed at the priority of the rule.
Simulation/Rules Interaction
The rulebased simulation controller behaves similarly to the simulation controller. (See “Simulation” for details of the simulation controller.) During the Initialization, Beginning of Run and Beginning of Timestep method executions, the rulebased simulation controller behaves much like the basic simulation controller: outputs are cleared, inputs set, links are propagated, expression slots are evaluated, and objects are initialized.
This section describes the timestep specific inline rulebased simulation steps in more detail. First, the steps are presented in paragraph format, then they are presented in bullet format. During the timestep-specific inner loop of the rulebased simulation controller, control alternates between dispatching objects and the rule processor as described in the following steps:
1. Processing the object dispatch queue. Objects check their dispatch conditions and may try to dispatch (or redispatch) after a “dispatch slot” on the object changes value. An object maintains a list of its dispatch slots and dispatching only occurs if it has sufficient known values.
2. Executing rules from the agenda one at a time. When a rule is successful, all its slot assignments are made. If it is not successful, none of its assignments are made, i.e. never are some, but not all of the assignments made. When the rule succeeds, the slot cell whose value was changed is given the priority of the rule and the “R” flag. These values show up in the rules analysis dialogs. Each rule maintains a list of the slots on which the outcome of the rule is “dependent”, namely those slots that were read during the rule execution. A rule will re-execute after one or more of its dependency slots changes value. Thus, objects that are dispatching can cause rules to re-execute by changing the values of slots upon which the rules depend, while rules that change dispatch slot values can cause simulation objects to dispatch.
At the start of the timestep (after beginning of timestep behavior has occurred), the dispatch queue (step 1) is fully processed until empty. This simulates the effects of user inputs. In this processing of the dispatch queue, objects may dispatch one or more times or may not dispatch at all depending on the dispatch slots that are set or changed throughout the course of the dispatching.
Once the queue is empty, the rules controller moves to the second step and starts with the full set of enabled rules on its “agenda” in priority order. This ensures that each enabled rule gets at least one chance to execute. The controller tries to execute the first rule on the agenda, in user specified order, at which time the controller removes the rule from its agenda. A successful rule may put objects on the simulation dispatch queue. After a rule succeeds and sets a value, the controller returns to step 1 and dispatches all objects on the queue.
When the dispatch queue is again empty, the controller returns to Step 2. and executes the next rule on its agenda. Once a rule succeeds, it returns to step one and processes the dispatch queue. It continues alternating until both the dispatch queue and the rules agenda are empty.
The rulebased simulation controller follows the procedure outlined below:
1. Initialization
– Clear all output and values set by rules from previous runs for all timesteps in all series slots.
– Set the controller priority to 0.
– Set user inputs
– Propagate user inputs across links for all timesteps.
– Determine first dispatch timestep. See “Initialization” for details.
1. Execute rules in the Initialization Rules RPL set. See “Initialization Rules Set” in RiverWare Policy Language (RPL) for details.
2. Beginning of Run
– Execute Beginning of Run methods for all objects.
– Evaluate Beginning of Run expression slots for all timesteps.
3. For each timestep:
a. Set the controller clock to the timestep time.
b. Set controller priority to 0.
c. Execute Beginning of Timestep methods for all objects.
d. Evaluate expression slots that have evaluate-at-beginning-of-timestep selected
e. Put all rules on the agenda (in priority order - whether 3,2,1 or 1,2,3 is user-selectable)
f. Do the following two processes until both the dispatch queue and the rules agenda are empty
1. Process 1. Process the Dispatch Queue: Dispatch objects (as in basic Simulation) until the queue is empty, simulating the effects of any user inputs and default values and any recent changes to slots by rules. For each slot changed by this dispatch:
Put all rules that depend on the changed slot on the agenda, if it's not already there.
If the slot is a dispatch slot, check dispatch conditions and if necessary put the object containing the slot on the simulation dispatch queue
If the Queue is empty, move on to process 2.
2. Process 2. Execute a Rule on the agenda: Set the controller priority to the priority of the next rule on the agenda (either in order 3,2,1 or 1,2,3 based on user-selection), and fire this rule. If not successful, continue firing one rule at a time until a rule is successful and at least one slot is set in the model. Each rule is removed from the agenda after it fires. Once a rule is successful:
Apply the slot changes, giving the changed slot cell the priority of the controller (i.e. the last rule that fired)
Add to this rule’s dependency’s list each slot that was read by this rule.
For each slot set by this rule, put all rules that depend on the changed slot on the agenda if the rule is not already there.
For each slot changed by this rule, if the slot is a dispatch slot, check dispatch conditions and if necessary, place the object containing the slot on the simulation dispatch queue.
3. Return to Process 1 and repeat until the Agenda and the Queue are empty.
g. Set controller priority to zero, and execute End of Timestep methods on all objects.
h. Evaluate end of timestep, current timestep only expression slots
4. If the number of run cycles performed is less than the number of run cycles specified, return to Step 3. and loop through each timestep again. See “Run Cycles” for details.
5. Execute End of Run methods on all objects including evaluating end of run expression slots.
Timestep Dependence of Rules
In RiverWare Simulation, solutions are possible forward and backwards in time. For example, reaches can solve upstream and backwards in time for some routing methods, and target operations on reservoirs solve previous timestep operations to meet a current target. In Rulebased Simulation, however, the rules should set only current values; i.e., values at the current controller timestep. The simulation should move forward in time, completely solving each timestep, then moving forward to the next.
Run Cycles
Rulebased simulations can also cycle through the timesteps multiple times; each pass through the run timesteps is referred to as a Run Cycle.
Traditionally (and by default) rulebased simulations cycle through the timesteps a single time, i.e., the default number of Run Cycles is 1. You may adjust this value upwards in the Rulebased Simulation Run Parameters dialog, which is accessed from the Run Control dialog's View menu (when a rulebased controller is selected). See “Rulebased Simulation Run Parameters” in User Interface for details.
To illustrate one use of this feature, consider a model consisting of two subbasins, where the policy of the lower basin requires knowledge of the upstream basin’s output for all timestep. A natural way to model this situation is to configure the simulation to cycle through the timesteps twice, solving for the upstream basin on the first run cycle and the downstream basin on the second. To do this, you would add execution constraints to the rules governing the upper basin which constrain them to execute only if the current run cycle is 1, and, similarly, the remaining rules that apply to the lower basin would be constrained to execute only on the second cycle. Execution constraints (and RPL expressions in general) can access the current run cycle using the predefined function GetRunCycleIndex. See “GetRunCycleIndex” in RiverWare Policy Language (RPL) for details.
Together these features (the ability to configure an RBS run for multiple cycles and the predefined function to access the current cycle) allow you to control which aspects of the policy apply to which portion of the run, which in turn allows parts of the model to solve fully before other parts—rules have access to slot values computed at all timesteps on previous run cycles.
More complex logic than that used in the previous example could allow rules/objects to solve on multiple cycles. Much like the way in which iterative MRM allows logic to control the number of runs, user logic could control the number of cycles. To do so, you would set the Number of Run Cycles parameter to a larger number, and then use logic and the STOP RUN statement to stop the run when the simulation goal had been achieved.
Why might this feature by used instead of Iterative MRM? Because run cycles are executed within a single run, you can run a model that is using multiple run cycles within a concurrent MRM to evaluate different hydrologies or policies.
Slot Priorities and Flags
Whenever a slot value is set in rulebased simulation, a priority is assigned to the value. This is termed the slot priority and can be displayed on the slot using the View, then Show Priorities menu. It indicates the priority associated with a specific value in a single timestep of a slot. The slot priority is the controller priority in effect when the slot is set. Thus, slots that are set during simulation have the priority of the last rule that succeeded. Slots that are set by rules have the priority of the rule that set them.
 
Slot priority
The slot priority at each timestep is the priority associated with the value in the slot. It is the priority of the controller when the slot value is set in simulation, or of the rule that set the slot value, if the slot is set directly by a rule.
In simulating the effects of a rule, the slot priorities propagate the rule priority along with the values which result from the rule’s slot assignment. Slot priorities are used to determine how an object will solve and whether or not the slot value may be overwritten by values at other priorities.
User Input Flags and Priorities.
User input values are assigned the highest priority of 0. These values may never be overwritten during a run. In rulebased simulation, just as in simulation, user inputs are displayed with an I flag. Default slot values set in Beginning of Run and Beginning of Timestep also have a priority of 0, the controller priority when these methods execute. This priority is assigned because default values (usually 0.0) are filled in as a convenience where a user has deliberately chosen not to input a required value.
R Flag
Slot values set by a rule are assigned the priority of the rule which set them (an integer greater than zero). In addition to a numerical priority, slots which are directly set by a rule are displayed with a special flag, the R flag. It is indicated by the letter R next to the slot value in the Open Slot dialog. If a linked slot is set by a rule and gets an R flag, the propagated value on the other side of the link also displays the R flag.
Slots which have an R flag are more important than slots at the same priority without an R flag. This difference is discussed in more detail below.
Equivalent Slots
Some slots in RiverWare have an equivalence relationship with another slot. This means that the values of both slots are related by a function which does not change during the run. For a given value in one slot, there can be only one value in its equivalent slot. Knowing the value of one slot is tantamount to knowing the value of both slots. Pool Elevation and Storage are equivalent slots. The values of Pool Elevation and Storage are related via the Elevation Volume Table.
When a rule sets a value on a slot which is part of an equivalent slot pair, it is essentially determining the value of the equivalent slot as well. For this reason, both slots are assigned the priority of the rule. The slot whose value is being set is assigned an R flag, but the equivalent slot is not. This is because the value of the equivalent slot will not be known until it is solved for during the dispatch. The equivalent slot’s value was not truly set, so it is not assigned an R flag.
When dispatching, if a value is set on a slot which is part of an equivalent slot pair, the slot is assigned the priority of the equivalent slot, regardless of the controller priority. For example, if Pool Elevation is a user input it will have a 0 priority and an I flag. If rule 1 sets Inflow, then the object can dispatch given Inflow (at a priority of 1) and Pool Elevation (at a priority of 0). All slots set as a result of dispatching will receive a priority of 1 because that is the controller priority (the priority of the last rule that successfully fired). However, the Storage slot will not receive a priority of 1. It will receive a priority of 0 because that is the priority of the Pool Elevation slot, which is the equivalent slot.
To summarize, slot priorities and flags are assigned to slot values as follows:
• 0 priority and I flag for slots set by user input.
• 0 priority for equivalent slots of slots set by user input.
• 0 priority for slots set in Beginning of Run and Beginning of Timestep (defaults).
• # priority and R flag for slots set by a rule (where # is the rule’s priority).
• # priority for equivalent slots of a slot set by a rule (where # is the rule’s priority).
• # priority for slots set during a dispatch (where # is the controller priority).
Resetting Slot Values
In simulation, if a slot is reset, the value must come from the same source as the previous value. (The three possible sources are user input, link propagation, or the object’s dispatch method.) This is required in simulation because when objects resolve due to inter-object iterations, they must solve for the same set of known and unknowns each time. Violation results in an over-determination error.
In rulebased simulation, however, the objects need the flexibility to solve with different sets of inputs and outputs in response to new values which may be set by the rules. To accomplish this, slot values in rulebased simulation may be reset from any source.
There are, however, restrictions on the setting of a slot value in rulebased simulation. The criteria used to determine whether a slot assignment can be made are as follows:
• Values with an I flag (user input) can never be overwritten.
• Values that have neither an I flag nor an R flag can always be overwritten.
• Values that have an R flag but not an I flag can be overwritten depending on the new value and new priority.
– If the new value does not have an R flag, the existing value can be overwritten if the priority of the new value is higher than the existing one.
– If the new value has an R flag, the existing value can be overwritten if the priority of the new value is higher than or equal to the existing priority.
Note:  If the slot is part of an equivalent slot pair, the equivalent slot must also satisfy the requirement. If either slot fails the logical test, the new value is not assigned.
Table 2.1 summarizes this logic, and Table 2.2 provides examples.
 
Table 2.1  Rules for resetting an existing value in a slot
Existing Value Rules Flag = I
Existing Value Rules Flag = R
Slot Can be Reset
Rule Logic
Yes
No
Never
Never reset slot IF:
old value rules flag* = I
No
No
Always
Always reset slot IF:
old value rules flag* !=R
No
Yes
Depends on new value and priority
Reset slot IF:
old value rules flag* = R AND
new value rules flag !=R AND
new value priority is higher than old value priority
No
Yes
Depends on new value and priority
Reset slot IF:
old value flag* = R AND
new value flag = R AND
new value priority is higher than or equal to old value priority
Example 2.4   
 
Table 2.2  Example slot value reset attempts
Existing Value Priority
Proposed Value Priority
Result of Attempted Assignment
3
1
Successful
1
3
Successful
6R
4
Successful
4R
6
Unsuccessful
4R
4
Unsuccessful
6R
4R
Successful
4R
6R
Unsuccessful
4R
4R
Successful
0
7
Unsuccessful
0
7R
Unsuccessful
Multi Slot Behavior
In addition to the Series Slot logic described above, Multi Slots have special logic for handling the solution of their subslots. Remember that a multislot adds a subslot for each link and that the multislot is always the total of the subslots, as in the diagram below. A single unknown, either the multislot or one of the subslots, may be solved for from the known information.
In the sample multislot in Table 2.3, the Total column could be solved for if both of the Link columns have values. Likewise, either of the Link columns could be solved for if the Total column and the other Link column have values.
 
Table 2.3   
Total (Multislot)
Link #1 (Subslot 1)
Link #2 (Subslot 2)
NaN
15
NaN
NaN
NaN
10
25
15
10
When there is only one unknown among the multislot and the subslots, it is solved. Once all subslots and the multislot are known and one of them gets a new value, a decision must be made as to which values to retain and what value to recalculate. That decision is based on which slot was solved for the last time and the priorities of each subslot:
1. If the subslot which receives a new value is not the subslot which was solved for the last time, the multislot resolves for the same subslot as the last time.
2. If the subslot which receives a new value is the subslot which was solved for the last time, the multislot resolves for the subslot with the lowest priority.
3. If there are several subslots at the lowest priority, and these slots cannot be further prioritized by the presence of R flags, the multislot is overdetermined. In this case, an error is posted and the run stops.
In all cases where a subslot is solved for, this subslot is assigned the same priority and R flag status as the subslot which originally received a new value.
Example 2.5   
Consider the following multislot, with priorities of values in parentheses.
 
Total (Multislot)
Link #1 (Subslot 1)
Link #2 (Subslot 2)
NaN
15 (3)
NaN
Rule #2 sets a new value on the other side of link #2. The new value propagates across the link to Subslot 2.
 
Total (Multislot)
Link #1 (Subslot 1)
Link #2 (Subslot 2)
NaN
15 (3)
10 (2R)
There is only one unknown (the Total column), so the multislot solves and sets the same priority on the solved-for slot as the slot which received a new value.
 
Total (Multislot)
Link #1 (Subslot 1)
Link #2 (Subslot 2)
25 (2R)
15 (3)
10 (2R)
If a new value were to come across either Link #1 or Link #2, the multislot would simply solve for a new value in the Total column and assign it the same priority and R flag status as the new value.
Imagine instead, that Rule #1 sets a new value on the multislot Total column.
 
Total (Multislot)
Link #1(Subslot 1)
Link #2 (Subslot 2)
20 (1R)
15 (3)
10 (2R)
Since the new value is on the slot which was last solved for, the multislot must solve for the lowest priority subslot. In this case, Subslot 1 would be solved for, and the priority and R flag status of the Total would be assigned to it.
 
Total (Multislot)
Link #1 (Subslot 1)
Link #2 (Subslot 2)
20 (1R)
10 (1R)
10 (2R)
Link Behavior
Priorities and R flags are maintained across links. Whenever a value is set on one end of a linked slot, the value, priority, and R flag (if present) are assigned to the slot on the other side of the link. Likewise, multislots propagate their priorities and R flags across their links when they solve.
Dispatching
Unlike basic simulation, an object in rulebased simulation may dispatch with different dispatch methods in a single timestep. The complication for the objects is determining which dispatch method to use whenever it gets a new slot value. Until an object dispatches for the first time during a timestep, it checks its knowns and unknowns against the dispatch conditions of its dispatch methods. This is the same process used in basic simulation. When the required knowns and unknowns are met, the object dispatches for the first time.
After the object has dispatched once at a given timestep, all of its dispatch slots should be known. If a new value is later set on a dispatch slot, the object must redispatch. But checking required knowns and unknowns is no longer a useful mechanism for determining the method with which to redispatch. In basic simulation, because slot values at a timestep are always set from the same source, the object simply redispatches with the same dispatch method used in the first dispatch.
In rulebased simulation, however, values may be set from different sources. The priorities of the dispatching slots must be used to determine the dispatch method. The dispatch method used for redispatches is the one who’s required knowns have the highest priority slot values.
Governing Slots
The slots in a dispatch method’s required knowns list are divided into potential governing slots and non-governing slots. Potential governing slots may determine with which dispatch method an object can solve. Non-governing slots are simply a requirement for every dispatch method. For example: Inflow and Outflow are potential governing slots, Diversion is not. Let’s explore the reasons why. A river Reach object may solve upstream or downstream, depending on whether Inflow or Outflow are known. Inflow and Outflow are potential governing slots. If the object solves upstream in response to a known Outflow, the governing slot is Outflow. If, however, the object solves downstream in response to a known Inflow, the governing slot is Inflow. While both Inflow and Outflow are potential governing slots in this scenario, only one can be the actual governing slot. Diversion is a non-governing slot. A Storage Reservoir object may solve for its Inflow, Outflow, Storage, or Pool Elevation. In all cases, Diversion must be known for the Reservoir to mass balance. If Diversion is known, this only means that the Reservoir can dispatch, it tells us nothing about which of the dispatch methods the object can solve with. In general, the Governing slots are the slots which uniquely determine the dispatch method an object can solve with. The governing slots determine in which “direction” an object solves.
 
Potential governing slot
A potential governing slot is a slot which, by virtue of being known or unknown, will influence with which dispatch method an object can solve.
The potential governing slots for each object are listed below. All other dispatch slots are considered non-governing slots.
 
Table 2.4   
Object
Potential Governing Slots
Aggregate Distribution Canal
Downstream Delivery Request
Aggregate Diversion Site
Total Available Water,
Total Diversion Requested
Total Diversion
Total Depletion
Total Unused Water
Aggregate Reach
Inflow,
Outflow
Bifurcation
Inflow,
Outflow1
Outflow2
Canal
Elevation 1,
Elevation 2
Confluence
Inflow1,
Inflow2,
Outflow
Distribution Canal
Inflow
Diversion Object
Diversion Request,
Diversion Intake Elevation
Ground Water Storage
Inflow
Inline Power Plant
Inflow,
Outflow
Level Power Reservoir
Inflow,
Outflow,
Turbine Release,
Pool Elevation,
Storage,
Hydrologic Inflow,
Energy
Pumped Storage Reservoir
Inflow,
Outflow,
Pool Elevation,
Storage,
Energy,
Pumps Used,
Pump Power,
PumpEnergy
Reach
Inflow,
Outflow,
Local Inflow
Slope Power Reservoir
Inflow,
Outflow,
Turbine Release,
Pool Elevation,
Storage,
Energy
Storage Reservoir
Inflow,
Outflow,
Release,
Pool Elevation,
Storage,
Hydrologic Inflow
Stream Gage
None
Water User
Incoming Available Water
Diversion Requested
Diversion
Depletion
Outgoing Available Water
Once the knowns and unknowns of an object have uniquely identified a dispatch method, the actual governing slots can be identified. The actual governing slot(s) is (are) the slots which are in the potential governing slots list and are a required known for the dispatch method. The actual governing slot(s) may be one or two, depending on the object. For Reservoir objects, there are two governing slots, selected from the list of potential governing slots. For Reach objects, there can be only one governing slot.
 
Governing slot
A governing slot is a slot which is:
1) in the potential governing slots list and
2) is a required known in the selected dispatch method. Governing slots provide insight into the direction in which the solution is propagating.
Example 2.6   
A Storage Reservoir may solve downstream due to Inflow and Storage or Inflow and Elevation, upstream due to Outflow and Storage or Outflow and Elevation, or it may solve for its own Storage and Pool Elevation due to Inflow and Outflow. The intersection of the required knowns of the dispatch method and the potential governing slot(s) of the object, determine the actual governing slot(s).
• Question: What are the governing slots if a Storage Reservoir solves for its Release and Outflow?
• Answer: There are two dispatch methods which will result in a Storage Reservoir solving for both Release and Outflow:
solveMB_givenInflowStorage
and solveMB_givenInflowHW
The intersection of the required knowns for these dispatch method with the potential governing slots for the Storage Reservoir yields the following solutions:
Case 1: Inflow and Storage
Case 2: Inflow and Pool Elevation
Determination of Dispatch Method
The determination of a dispatch method for redispatching is based on the priorities of the slots. Once the object has dispatched once, all dispatch slots will be known, so checking knowns and unknowns is ineffectual. To determine the dispatch method, it is necessary to construct an alternate known slot list using the highest priority slots. RiverWare begins with an empty known slot list, then adds slots in priority order until a set of dispatch conditions is met. Since the non-governing slots are all known and they do not influence the choice of which dispatch method to solve, there is no point in prioritizing them; all non-governing slots are added to this list first. Then, the governing slots are added to the known list in priority order to determine the dispatch method.
The algorithm to determine the correct dispatch method for redispatching is as follows.
1. Begin with an empty set of known slots (pretend nothing is known).
2. Add all non-governing slots to the known slot set.
3. Add all of the object’s potential governing slots with priority 0 to the known slot set.
a. Check the known set against the required knowns of each dispatch method. If a match is found, put the object on the queue with this dispatch method, and exit the algorithm.
b. Check the known set against the conflict list.If the known set contains all of the slots of a conflict, put the object on the queue with the same dispatch method as the last time it dispatched, and exit the algorithm.
4. Loop through all priority levels starting with the highest priority (1,2,3...) until a dispatch method is determined. For each priority level:
a. If there are any potential governing slots at the priority level that have an R flag, add the R-flagged slots to the known set and defer the other slots.
b. If no potential governing slots at the priority level have an R flag, add all potential governing slots at that priority to the known set.
c. Check the known set against the required knowns of each dispatch method. If a match is found, put the object on the queue with this dispatch method and exit the algorithm.
d. Check the known set against the conflict list. If the known set contains all the slots of a conflict, put the object on the queue with the same dispatch method as the last time it dispatched and exit the algorithm.
5. Loop through all priority levels again in order (1,2,3...), and for each:
a. Add any non-R-flagged slots that were deferred in Step 4. to the known set.
b. Check the known set against the required knowns of each dispatch method. If a match is found, put the object on the queue with this dispatch method and exit the algorithm.
c. Check the known set against the conflict list. If the known set contains all the slots of a conflict, put the object on the queue with the same dispatch method as the last time it dispatched and exit the loop.
This algorithm always results in the identification of a dispatch method or an error and terminated run.
 
Example 2.7   
A Level Power Reservoir, named ResA, has no diversions and a user input Hydrologic Inflow. The following sequence of events take place.
1. A low priority rule (#4) sets an Outflow on a reservoir directly upstream of the ResA. The value and the R flag propagate across the link to this ResA’s Inflow slot.
2. A higher priority rule (#3) sets the ResA’s Storage.
3. ResA can now dispatch for the first time with the solveMB_givenInflowStorage dispatch method at a priority of 3.
After the dispatch, all of the reservoir’s dispatch slots are known at the following priorities.
 
Slot
Priority
Inflow
4R
Hydrologic Inflow
0
Storage
3R
Pool Elevation
3
Diversion
0
Return Flow
0
Outflow
3
Now suppose that the highest priority flood control rule (#1) has to overwrite the ResA’s Outflow to prevent flooding downstream. The reservoir must redispatch.
• Question: What slots does the ResA’s known set contain after each step of the logic to determine the dispatch method? Do any of these known sets match a dispatch method? Which one?
Answer: The logic is as follows:
1. Start with an empty known set.
2. Add all of the non-governing slots to the known set.
 
Slot
Priority
Diversion
0
Return Flow
0
3. Hydrologic Inflow (a potential governing slot) was user input and has a priority of 0. Add this slot to the known set.
 
Slot
Priority
Diversion
0
Return Flow
0
Hydrologic Inflow
0
These three slots alone do not satisfy any of the dispatch conditions. Continue.
These three slots alone are not a conflict. Continue.
4. Loop through the priorities:
• Priority 1: Outflow is known at priority 1R. Add it to the known set. Hydrologic Inflow, Diversion, Return Flow, and Outflow do not satisfy any dispatch conditions. Hydrologic Inflow, Diversion, Return Flow, and Outflow are not a conflict. Continue.
 
Slot
Priority
Diversion
0
Return Flow
0
Hydrologic Inflow
0
Outflow
1R
• Priority 2: There are no slots at this priority.
No changes are made to the known set. Continue.
 
Slot
Priority
Diversion
0
Return Flow
0
Hydrologic Inflow
0
Outflow
1R
• Priority 3:
Both Storage and Pool Elevation are at priority 3, but Storage has an R flag. Add Storage to the known set and defer Pool Elevation.
Diversion, Return Flow, Hydrologic Inflow, Outflow, and Storage satisfy the conditions for the solveMB_givenOutflowStorage dispatch method. Add this object to the queue with this dispatch method, and exit.
 
Slot
Priority
Diversion
0
Return Flow
0
Hydrologic Inflow
0
Outflow
1R
Storage
3R
Note:  The Pool Elevation and Inflow slots are never added to the known set. It is not necessary to consider them because we satisfied a dispatch method’s conditions with higher priority slots and R flags.
• Question: Once the object redispatches, a new value will be computed for two of the slots. Which slots? What will their priorities be after the dispatch completes?
Answer: The object will redispatch using the solveMB_givenOutflowStorage dispatch method at a controller priority of 1 (because the last rule to succeed was rule #1). During the dispatch, the object will solve for new Inflow and Pool Elevation values. These values will be set on the Inflow and Pool Elevation slots at a priority of 1 and 3, respectively. (The Pool Elevation slot is an equivalent slot to Storage which has a priority of 3R.)
 
Revised: 06/03/2019