Unlike policy levers, control levers affect both the BAU case and the Policy case in Vensim. In the web app, the BAU case is frozen, so toggling a control lever changes the policy case but not the BAU case. This is an annoyance for many graph types, but is more serious for wedge diagrams and cost curves, which break. Here's an example of the wedge diagram for the built-in "Example scenario" with the “Use 20-Year GWP Values” control lever enabled:
The solution is that instead of having a static BAU case, the BAU case is recalculated any time a control setting (but not a policy lever) changes. Some ways that a control lever can change include:
The user moves the control lever
The user changes the control lever's implementation schedule (but not that the GWP timeframe control lever doesn't have an implementation schedule, so it doesn't apply to that lever)
The user uses the "revert to saved" button to undo a change to the control lever
The user switches the active scenario to a saved scenario that has a different setting for the control lever
When one of these things happens, the web app should invalidate the BAU scenario in the cache. It should re-run the BAU scenario if it is being displayed or its values are needed for a wedge diagram or cost curve.
Changes to the control lever should never generate the "(unsaved changes)" flag for the BAU scenario. If the BAU scenario is activated, it should only show "(unsaved changes)" if a policy lever has been changed. The idea is that the control levers represent different ways of visualizing the BAU scenario, not meaningful changes to the BAU scenario.
The one wrinkle is identifying which levers are control levers vs. policy levers. Here are three approaches:
We could treat all levers with a blank "Policy Group" in WebAppData as control levers. However, the GRA levers don't have a policy group and don't affect the BAU case, so this will improperly flag those levers. It won't result in wrong output but will result in unnecessary model runs, which we try to avoid. And it's possible we might introduce some policy lever in the future that doesn't have a group, I suppose.
We could treat all levers under the header named "Control Settings" as control levers. We'd need to ensure this works even when the header is translated into a non-English language.
We could introduce a new column in WebAppData to explicitly flag which levers are control levers.
I somewhat lean against the first approach because it causes unnecessary model runs and might end up needing to be changed in the future. The latter two approaches both seem good to me. The one based on the header name is simpler.
Unlike policy levers, control levers affect both the BAU case and the Policy case in Vensim. In the web app, the BAU case is frozen, so toggling a control lever changes the policy case but not the BAU case. This is an annoyance for many graph types, but is more serious for wedge diagrams and cost curves, which break. Here's an example of the wedge diagram for the built-in "Example scenario" with the “Use 20-Year GWP Values” control lever enabled:
The solution is that instead of having a static BAU case, the BAU case is recalculated any time a control setting (but not a policy lever) changes. Some ways that a control lever can change include:
When one of these things happens, the web app should invalidate the BAU scenario in the cache. It should re-run the BAU scenario if it is being displayed or its values are needed for a wedge diagram or cost curve.
Changes to the control lever should never generate the "(unsaved changes)" flag for the BAU scenario. If the BAU scenario is activated, it should only show "(unsaved changes)" if a policy lever has been changed. The idea is that the control levers represent different ways of visualizing the BAU scenario, not meaningful changes to the BAU scenario.
The one wrinkle is identifying which levers are control levers vs. policy levers. Here are three approaches:
I somewhat lean against the first approach because it causes unnecessary model runs and might end up needing to be changed in the future. The latter two approaches both seem good to me. The one based on the header name is simpler.