Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Note that no DataOperations are added to the OutputExchangeItems. The LinkableEngine class will complete the OutputExchangeItems for you by adding
spatial and temporal data operations to your OutputExchangeItems. You can still add your own data operations as well.

Implementing the SetValues method

The calling sequence for the SetValues method is shown on figure 15 below.

Image Added
Fig. 15. Calling sequence for the SetValues method

The EngineWrapper class decides what has to be done, based on the QuantityID and the ElementSetID. In the Simple River engine core there is only one possible variable that can act as input, which is the storage of water in the nodes. For the Simple River model, inflow is interpreted as additional inflow, which means that the inflow already received from other sources (the boundary inflow) is not overwritten. The inflow is added to the current storage in the nodes. The ElementSetID is parsed and the node number to which the water is going is determined.


If the inflow is going to the branches, the water is added to the downstream node for each branch. If the inflow is going to the nodes, the water is simply added to the storage of the node. Understanding the role of the QuantityID and the ElementSetID is very important when you are migrating your model. For each ExchangeItem you define your ElementSetID and QuantityID. These IDs will be included in the link when a user is configuring a system with your model. When the system is running, the same ElementSetID and QuantityID will get back to the ModelComponent when the GetValues method is invoked. Your component will then use this information to navigate to the correct variables in the engine.


You can use any convention for naming these IDs. In the Simple River ElementSetID, the convention used was Branch:<branch number> (e.g. ´Branch:3' ) or 'AllBranches', and the Quantity IDs were 'Flow' and 'InFlow'.

Implementing the GetValues method

The source code for the IEngine GetValues implementation is shown below.

Code Block

public org.OpenMI.Standard.IValueSet GetValues(string QuantityID, string ElementSetID)
{
   double[] returnValues;
   Char[] separator = new char[]{':'};
   if (QuantityID == 'Flow')
   {
      int index = Convert.ToInt32((ElementSetID.Split(separator))[1]);
      returnValues = new double[1];
      returnValues[0] = _simpleRiverEngine.GetFlow(index);
   }
   else
   {
      throw new Exception('Illegal QuantityID in GetValues method in SimpleRiverEngine');
   }
}

The branch number is extracted from the ElementSetID and used as an index in the GetValues call to the SimpleRiverDotNetAccess class.


The calling sequence for the GetValues method is shown in Figure 16.

Image Added
Fig. 16. Calling sequence for the GetValues method

Implementation of the remaining methods

Implementation of the remaining methods in the IEngine interface is not complicated. On the sequence diagram in Figure 4-27 you can see how each method is accessing the other engine wrapper classes.

Image Added
Fig. 17. Calling sequence for Simple River

The calling sequence for methods not shown in Figure 17 is given in Figure 14, Figure 15 and Figure 15. Note that for some of the methods the full implementation is done in the SimpleRiverEngineWrapper class. The methods GetCurrentTime, GetInputTime and GetEarliestNeededTime are all invoking the GetCurrentTime method in the SimpleRiverDotNetAccess class. The returned time is the engine local time. This time is converted to the ModifiedJulianTime in the SimpleRiverEngineWrapper (see code below).

Code Block

public OpenMI.Standard.ITime GetCurrentTime()
{
   double time = _simulationStartTime + _simpleRiverEngine.GetCurrentTime() / ((double)(24*3600));
   return new Oatc.OpenMI.Sdk.Backbone.TimeStamp(time);
}