To extend types of values that can be exchanged using OpenMI.
Feedback from Steve (HEC):
All of the exchange information in OpenMI looks like it time based. That is, the information is exchanged over the entire simulation. However, I can think of lots of situations where there is some exchange information that is only needed for the initial (time = 0.0) conditions. For example, someone might have an OpenMI program that controls the discharge from a dam/lake and they want to use RAS to compute the lake level and also route the flow upstream and downstream of the lake. When the two programs start running, they would want to specify the initial lake level at the dam and the initial discharge (or gate settings) from the lake. However, from that point on, their program would only specify the discharge (or gate settings), allowing RAS to compute the lake level as it performs the stream routing. The initial lake level can, of course, be specified by using the RAS GUI, but then there would be the issue of how to automate this process. Alternately, I could structure the OpenMI RAS program so that it used the lake level exchange data at time zero, but ignored it after that. This would work, but it would be awkward and confusing for the user. You might consider adding exchange items to OpenMI that are only intended to be used for the initial conditions.
I have been experimenting with a RAS model connected to a RAS model and I have additional concerns about how the initial conditions are handled. If the upstream RAS model is a single reach, or a dendritic system (there is
only one location that has a downstream outflow), then the upstream model can compute the outgoing flow (by adding up all the incoming flows) even without knowing the downstream water surface. This flow can be passed to the downstream model and the downstream model can then compute the flows and water surfaces for all the nodes at time zero (by assuming a steady state solution). I would like to have the downstream model (before it performs any
timesteps) then pass the water surface back to the upstream model, and have the upstream model also compute all the flows and water surfaces at time zero
(by assuming a steady state solution). I have not been able to figure out how to do this. I'm not sure whether it is because OpenMI is not structured to be able to do this, or if it is because I haven't figured out how to correctly modify the engine wrapper. In either case, I would like to see the OpenMI/engine wrapper changed so that this is a standard feature in the generic engine wrapper.
This use case should be posed on the WIKI with a description for how it can be solved with version 1.4 and some suggestions for improvement in version 2.0 that will make thing easier. (TASK: Gena / Stef).
How to address in Version 1
How to address in Version 2
Make time dependent types of values as optional feature. See ideas below.
Disadvantages of the current approach:
- Information that is exchanged is always related to time and link id
- Type of information that is exchanged should implement IValueSet
- IValueSet interface is not self-descriptive: you can ask number of values in a set but in order to ask real values you have to check if object is of type IScalarSet or IVectorSet, derive it to that type and then ask for real values.
- Values can be asked only from component and not from exchange item: ILinkableComponent.GetValues().
- Values can be asked for a given links assuming that it should search for corresponding exchange item and return values for output exchange item related to that link - very implicit. What if there are 2 exchange items with the same quantity and element set but with different name.
- It is not possible to connect 2 components without having some Backbone implementation of ILink. In other words you have to implement something in order to use OpenMI components in your system instead of simple: link to OpenMI.Standard.dll and run OpenMI-compliant components.
- Separate time-dependency concept from value
- Move link-related functionality into exchange item instead of component
- Add additional ValueType property to exchange item returning type of value being exchanges.
- Make it possible for developers to extend types of exchangeable value objects by use of object based values instead of IValueSet-based.
- Use enumeration instead of polymorphisms to identify if exchange item is input or output - will simplify implementation of backbones.
- Make time-dependent runnable components as one of the component types
- Use IDiscreteTimes-like approach in order to identify time-dependency of exchange items.
- Separate concepts of getting values and running / updating component. Currently GetValues() implicitly triggers run of component. Actually in backbone methods used to run component are defined using IRunEngine - this interface can be pulled up into OpenMI interface and defined as extension of ILinkableComponent (see below). See also use case 4. Value as a property in IExchangeItem, TimeRunnableComponent.
- ILinkableComponent - only properties / methods related to linkage (exchange items, meta info)
- IRunEngineComponent - time-dependent runs
How to address time-dependency of exchange items
Object type for exchange item values sounds quite generic, however providing a little of meta info may help. A solution may be also to define a set of exchangeable value objects mostly-used in OpenMI community and include them into Standard, e.g.:
- One-dimensional element-based IScalarSet containing array of (Double) values and reference to IElementSet.
- Time-dependent series ITimeSeries containing pairs of (DateTime, ValueObject) where ValueObject can be primitive type of above mentioned IScalarSet
- Elements or ElementSets can be also exchangeable values.
- Primitive values like String, Double, Integer, Enumerations ...