5.2 Implementation of the Initialize method

The SimpleRiverEngineWrapper has two private field variables:

ArrayList _inputExchangaItems;

ArrayList _outputExchangeItems;

The _inputExchangeItems is a list of Oatc.OpenMI.Sdk.Backbone.InputExchangeItem objects and the _outputExchangeItems is a list of Oatc.OpenMI.Sdk.Backbone.OutputExchangeItem objects. These arraylists are populated in the Initialize method.

The Simple River wrapper must fulfill the requirements defined by the use cases described in section 2.1. This means that the input and output exchange items are based on the list of items in Table 1.

The source code for implementation of the Initialize method in the SimpleRiverEngineWrapper is shown below.

// From class: Oatc.OpenMI.Examples.ModelComponents.SimpleRiver.Wrapper.SimpleRiverEngineWrapper : Oatc.OpenMI.Sdk.Wrapper.IEngine
	public void Initialize(System.Collections.Hashtable properties)
		{
			
			_inputExchangeItems = new ArrayList();
			_outputExchangeItems = new ArrayList();

			// -- Create and initialize the engine --
			_simpleRiverEngine = new SimpleRiverEngineDotNetAccess();
            if (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 the location of the OMI files. It is assumed that the data files are
                //located in the same directory.
            }
			// -- Time horizon --
			char [] delimiter = new char[]{'-',' ',':'};
			string[] strings = _simpleRiverEngine.GetSimulationStartDate().Split(delimiter);
			int StartYear   = Convert.ToInt32(strings[0]);
			int StartMonth  = Convert.ToInt32(strings[1]);
			int StartDay    = Convert.ToInt32(strings[2]);
			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");
			
			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++)
			{
				OutputExchangeItem flowFromBrach  = new OutputExchangeItem();
				InputExchangeItem inFlowToBranch = new InputExchangeItem();

				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.GetXCoordinate(i),_simpleRiverEngine.GetYCoordinate(i),0));
				branch.Elements[0].AddVertex(new Vertex(_simpleRiverEngine.GetXCoordinate(i+1),_simpleRiverEngine.GetYCoordinate(i+1),0));
			
				flowFromBrach.ElementSet = branch;
				flowFromBrach.Quantity = flowQuantity;

				inFlowToBranch.ElementSet = branch;
				inFlowToBranch.Quantity = inFlowQuantity;
		
				_outputExchangeItems.Add(flowFromBrach);
				_inputExchangeItems.Add(inFlowToBranch);
		    }
			for (int i = 0; i < numberOfNodes; i++)
			{
				InputExchangeItem inflowToNode = new InputExchangeItem();
				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++)
			{
				Element branch = new Element("Branch: " + i.ToString());
				branch.AddVertex(new Vertex(_simpleRiverEngine.GetXCoordinate(i),_simpleRiverEngine.GetYCoordinate(i),0));
				branch.AddVertex(new Vertex(_simpleRiverEngine.GetXCoordinate(i+1),_simpleRiverEngine.GetYCoordinate(i+1),0));
				Branches.AddElement(branch);
			}
			InputExchangeItem inFlowToBraches    = new InputExchangeItem();

			inFlowToBraches.ElementSet = Branches;
			inFlowToBraches.Quantity = inFlowQuantity;
			_inputExchangeItems.Add(inFlowToBraches);

		}

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 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.


Fig. 14 Calling sequence for the initialize method

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.

  • No labels