5.2 Implementation of the Initialize method
The SimpleRiverEngineWrapper has two private field variables:
...
The _inputExchangeItems is a list of orgOatc.OpenMI.Sdk.Backbone.InputExchangeItem objects and the _outputExchangeItems is a list of orgOatc.OpenMI.Sdk.Backbone.OutputExchangeItem objects. These arraylists are populated in the Initialize method.
The Simple River wrapper must fulfil fulfill the requirements defined by the use cases described in section 4. 2.1. This means that the input and output exchange items are based on the list of items in Table 4- 1.
The source code for implementation of the Initialize method in the SimpleRiverEngineWrapper is shown below.
Code Block |
---|
// From class: Oatc.OpenMI.Examples.ModelComponents.SimpleRiver.Wrapper.SimpleRiverEngineWrapper : Oatc.OpenMI.Sdk.Wrapper.IEngine public void Initialize(System.Collections.Hashtable properties) { \_inputExchangeItems { _inputExchangeItems = new ArrayList(); _outputExchangeItems = new ArrayList(); //ArrayList of-- Create and Oatc.OpenMI.Sdk.Backbone.InputExchangeItem objects \_outputExchangeItemsinitialize the engine -- _simpleRiverEngine = new ArrayListSimpleRiverEngineDotNetAccess(); //ArrayList of Oatc.OpenMI.Sdk.Backbone.OutputExchangeItem objects // \-\\- Create and initialize the engine \-\\- \_simpleRiverEngine = new SimpleRiverEngineDotNetAccess(); \_simpleRiverEngine.Initialize((string)properties\['FilePath'\]); // \-\\- Simulation start time - // The start time is obtained from the engine core as a string. This string isif (properties["FilePath"].ToString().Length > 1) { _simpleRiverEngine.Initialize(properties["FilePath"].ToString()); } else { string currentDir = System.IO.Directory.GetCurrentDirectory(); _simpleRiverEngine.Initialize(currentDir); //When running from the GUI, the assembly is started with the current dir //to passedthe andlocation convertedof tothe aOMI System.DateTime. Thenfiles. It is assumed that the data files // Oatc.OpenMI.Sdk.DevelopmentSupport.CalendarConverter class is used to convertare // this time into the ModifiedJulianDay (this is the OpenMI standard time) char \[\located in the same directory. } // -- Time horizon -- char [] delimiter = new char\[\]{'-',' ',':'}; string\[\ string[] strings = \_simpleRiverEngine.GetSimulationStartDate().Split(delimiter); int StartYear int StartYear = Convert.ToInt32(strings\[0\]); int StartMonth = Convert.ToInt32(strings\[1\]); int StartDay int StartDay = Convert.ToInt32(strings\[2\]); int StartHour int StartHour = Convert.ToInt32(strings\[3\]); int StartMinute = Convert.ToInt32(strings\[4\]); int StartSecond = Convert.ToInt32(strings\[5\]); DateTime startDate = new DateTime(StartYear,StartMonth,StartDay,StartHour,StartMinute,StartSecond); \ _simulationStartTime = Oatc.OpenMI.Sdk.DevelopmentSupport.CalendarConverter.Gregorian2ModifiedJulian(startDate); // \-\\- Build exchange items \--\\- - Dimension flowDimension = new Dimension(); Unit flowUnit = new Unit('"m3/sec'",1,0,'"m3/sec'"); //The Simple River only uses // quantities with the unit m3/sec. Quantity flowQuantity Quantity flowQuantity = new Quantity(flowUnit,'"description'",'"Flow', ",global::OpenMI.Standard.ValueType.Scalar,flowDimension); Quantity inFlowQuantity = new Quantity(flowUnit,'"description'",'"InFlow', ",global::OpenMI.Standard.ValueType.Scalar,flowDimension); int numberOfNodes = \_simpleRiverEngine.GetNumberOfNodes(); for (int i = 0; i < numberOfNodes \-1; i++) //For each branch { OutputExchangeItem flowFromBranch { OutputExchangeItem flowFromBrach = new OutputExchangeItem(); InputExchangeItem inFlowToBranch = new InputExchangeItem(); // One ElementSet is created for each branch. The ElementID's are // Branch:<Branch number>. E.g. 'Branch:3' ElementSet branch ElementSet branch = new ElementSet('"description'",'"Branch:'" + i.ToString(),ElementType.XYPolyLine,new SpatialReference('"ref'")); branch.AddElement(new Element('"Branch:'" + i.ToString())); branch.Elements\[0\].AddVertex(new Vertex(_simpleRiverEngine. GetXCo-ordinateGetXCoordinate(i),_simpleRiverEngine.GetYCo-ordinateGetYCoordinate(i),0)); branch.Elements\[0\].AddVertex(new Vertex(_simpleRiverEngine. GetXCo-ordinateGetXCoordinate(i+1),_simpleRiverEngine.GetYCo-ordinateGetYCoordinate(i+1),0)); flowFromBranch flowFromBrach.ElementSet = branch; flowFromBranch flowFromBrach.Quantity = flowQuantity; inFlowToBranch.ElementSet = branch; inFlowToBranch.Quantity = inFlowQuantity; \ _outputExchangeItems.Add(flowFromBranchflowFromBrach); \ _inputExchangeItems.Add(inFlowToBranch); } for (int i = 0; i < numberOfNodes; i++) //For all nodes { { InputExchangeItem inflowToNode = new InputExchangeItem(); // Each node is a ID-based ElementSet. The ElementSet ID are // Node:<node number>. E.g. 'Node:3' ElementSet node = new ElementSet('"description'",'"Node:'" + i.ToString(),ElementType.IDBased,new SpatialReference('"ref'")); node.AddElement(new Element('"Node:'" + i.ToString())); inflowToNode.Quantity = inFlowQuantity; inflowToNode.ElementSet = node; \ _inputExchangeItems.Add(inflowToNode); } } ElementSet Branches = new ElementSet('"description'",'"AllBranches'", ElementType.XYPolyLine,new SpatialReference('"ref'")); for (int i = 0; i < numberOfNodes - 1;i++) //Create an InputExchangeItem that // has all branches in one ElementSet { { Element branch = new Element('"Branch: '" + i.ToString()); branch.AddVertex(new Vertex(_simpleRiverEngine. GetXCo-ordinateGetXCoordinate(i),_simpleRiverEngine.GetYCo-ordinateGetYCoordinate(i),0)); branch.AddVertex(new Vertex(_simpleRiverEngine. GetXCo-ordinateGetXCoordinate(i+1),_simpleRiverEngine.GetYCo-ordinateGetYCoordinate(i+1),0)); Branches.AddElement(branch); } } InputExchangeItem inFlowToBraches InputExchangeItem inFlowToBranches = new InputExchangeItem(); inFlowToBranches inFlowToBraches.ElementSet = Branches; inFlowToBranches inFlowToBraches.Quantity = inFlowQuantity; \ _inputExchangeItems.Add(inFlowToBranchesinFlowToBraches); } |
As you can see from the implementation of the Initialize method, some methods need to be implemented in the MyEngineDotNetAccess class, the MyEngineDLLAccess class and the engine core.
The sequence diagram in Figure 4-23 14 illustrates the communication with the other wrapper classes when the Initialize method is invoked. The EngineDLL is not included in the diagram since there is a one-to-one communication between the EngineDLL and the EngineDLLAccess classes. In other words, each time a method is called in the EngineDLLAccess the corresponding function is called in the EngineDLL.
...
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.