private void AddExchangeItem(string inOrOut, string inputItemId) { string[] quantAndElementSet = inputItemId.Split('.'); if (quantAndElementSet.Length != 2) { throw new Exception("No \".\" specified in \"" + inputItemId + "\"" + ", component " + Id); } string elementSetId = quantAndElementSet[0]; string quantId = quantAndElementSet[1]; if (!_quantities.ContainsKey(quantId)) { throw new Exception("Quantity \"" + quantId + "\" does not exist in component " + Id); } if (!_elementSets.ContainsKey(elementSetId)) { throw new Exception("ElementSet \"" + elementSetId + "\" does not exist in component " + Id); } if (inOrOut.Equals("inputitem")) { foreach (EngineInputItem inputItem in EngineInputItems) { if (inputItem.Id.Equals(inputItemId)) { throw new Exception("InputItem \"" + inputItemId + "\" already exists in component " + Id); } } EngineInputItem newInputItem = new InputItem(inputItemId, _quantities[quantId], _elementSets[elementSetId], this); newInputItem.StoreValuesInExchangeItem = true; EngineInputItems.Add(newInputItem); } else if (inOrOut.Equals("outputitem")) { foreach (EngineOutputItem outputItem in EngineOutputItems) { if (outputItem.Id.Equals(inputItemId)) { throw new Exception("OutputItem \"" + inputItemId + "\" already exists in component " + Id); } } EngineOutputItem newOutputItem = new OutputItem(inputItemId, _quantities[quantId], _elementSets[elementSetId], this); newOutputItem.StoreValuesInExchangeItem = true; EngineOutputItems.Add(newOutputItem); } else { throw new Exception("Unknown inOrOutOption: " + inOrOut); } }
public override void Initialize() { var properties = new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase); foreach (IArgument argument in Arguments) { properties.Add(argument.Id, argument.Value); } string simFileName = "SimpleRiver.sim"; object value; if (properties.TryGetValue("SimFileName", out value) && value != null && value.ToString().Length > 1) { simFileName = value.ToString(); } // -- Create and initialize the engine -- if (properties.TryGetValue("FilePath", out value) && value != null && value.ToString().Length > 1) { _simpleRiverEngine.Initialize(value.ToString(), simFileName); } else { string currentDir = System.IO.Directory.GetCurrentDirectory(); _simpleRiverEngine.Initialize(currentDir, simFileName); //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. } if (properties.TryGetValue("TimeStepLength", out value) && value != null && ((double)value) > 0.0) { _simpleRiverEngine.SetTimeStepLength(Convert.ToDouble(value)); } if (properties.TryGetValue("ModelId", out value) && value != null) { // Note: This does strictly not set the id to the fortran engine (no setter available) Id = value.ToString(); } else { Id = _simpleRiverEngine.GetModelID(); } Description = _simpleRiverEngine.GetModelDescription(); // -- 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 = new Time(startDate).StampAsModifiedJulianDay; // -- Build exchange items --- Dimension flowDimension = new Dimension(); flowDimension.SetPower(DimensionBase.Length, 3); flowDimension.SetPower(DimensionBase.Time, -1); Unit flowUnit = new Unit("m3/sec", 1, 0, "m3/sec"); flowUnit.Dimension = flowDimension; Quantity flowQuantity = new Quantity(flowUnit, "Flow description", "Flow"); Quantity inFlowQuantity = new Quantity(flowUnit, "Inflow description", "InFlow"); // ADH: Might not be unreasonable to set double as default in backbone constructor flowQuantity.ValueType = typeof(double); inFlowQuantity.ValueType = typeof(double); int numberOfNodes = _simpleRiverEngine.GetNumberOfNodes(); TimeSet timeset = new TimeSet(); timeset.TimeHorizon = GetTimeHorizon(); TimeSet extentTimeSet = new TimeSet(); extentTimeSet.TimeHorizon = GetTimeHorizon(); extentTimeSet.Times.Add(GetTimeHorizon()); _timeExtent = extentTimeSet; int nCount = 0; for (int i = 0; i < numberOfNodes - 1; i++) { ElementSet branch = new ElementSet("description", "Branch:" + i, ElementType.PolyLine, ""); branch.AddElement(new Element("Branch:" + i.ToString())); branch.Elements[0].AddVertex(new Coordinate(_simpleRiverEngine.GetXCoordinate(i), _simpleRiverEngine.GetYCoordinate(i), 0)); branch.Elements[0].AddVertex(new Coordinate(_simpleRiverEngine.GetXCoordinate(i + 1), _simpleRiverEngine.GetYCoordinate(i + 1), 0)); EngineEOutputItem flowFromBrach = new EngineEOutputItem("Branch:" + i + ":Flow", flowQuantity, branch, this); int branchIndex = i; EngineDInputItem inflowToBranch = new EngineDInputItem("Branch:" + i + ":InFlow", inFlowQuantity, branch, this); inflowToBranch.ValueSetter = delegate(ITimeSpaceValueSet values) { _simpleRiverEngine.AddInflow(branchIndex, (double)values.GetValue(0, 0)); }; flowFromBrach.TimeSet = timeset; EngineOutputItems.Add(flowFromBrach); EngineInputItems.Add(inflowToBranch); } for (int i = 0; i < numberOfNodes; i++) { ElementSet node = new ElementSet("description", "Node:" + i.ToString(), ElementType.IdBased, ""); node.AddElement(new Element("Node:" + i.ToString())); int nodeIndex = i; EngineDInputItem inflowToNode = new EngineDInputItem(node.Caption + ":InFlow", inFlowQuantity, node, this); inflowToNode.ValueSetter = delegate(ITimeSpaceValueSet values) { _simpleRiverEngine.AddInflow(nodeIndex, (double)values.GetValue(0, 0)); }; Inputs.Add(inflowToNode); } ElementSet branches = new ElementSet("description", "AllBranches", ElementType.PolyLine, ""); for (int i = 0; i < numberOfNodes - 1; i++) { Element branch = new Element("Branch: " + i.ToString()); branch.AddVertex(new Coordinate(_simpleRiverEngine.GetXCoordinate(i), _simpleRiverEngine.GetYCoordinate(i), 0)); branch.AddVertex(new Coordinate(_simpleRiverEngine.GetXCoordinate(i + 1), _simpleRiverEngine.GetYCoordinate(i + 1), 0)); branches.AddElement(branch); } EngineEInputItem inFlowToBraches = new EngineEInputItem(branches.Caption + ":inFlow", inFlowQuantity, branches, this); Inputs.Add(inFlowToBraches); Status = LinkableComponentStatus.Initialized; }
public override void Initialize() { Status = LinkableComponentStatus.Initializing; Hashtable hashtable = new Hashtable(); for (int i = 0; i < Arguments.Count; i++) { hashtable.Add(Arguments[i].Caption, Arguments[i].Value); } if (_engineApiAccess == null) { throw new Exception("Failed to assign the engine"); } _engineApiAccess.Initialize(hashtable); //foreach (InputItem inputItem in inputItems) //{ // TimeSet timeset = new TimeSet(); // timeset.Times.Add(TimeHelper.ConvertTime(_engineApiAccess.GetCurrentTime())); // inputItem.TimeSet = timeset; // // TODO inputItem.TimeSet = TimeSet for input item; //} //foreach (OutputItem outputItem in outputItems) //{ // TimeSet timeset = new TimeSet(); // timeset.Times.Add(TimeHelper.ConvertTime(_engineApiAccess.GetCurrentTime())); // outputItem.TimeSet = timeset; //} Id = _engineApiAccess.GetModelID(); Description = _engineApiAccess.GetModelDescription(); for (int i = 0; i < _engineApiAccess.GetOutputExchangeItemCount(); i++) { OutputExchangeItem output = _engineApiAccess.GetOutputExchangeItem(i); IQuantity quantity = output.Quantity; IElementSet elementSet = output.ElementSet(); String outputItemId = string.IsNullOrEmpty(output.Id) ? elementSet.Caption + ":" + quantity.Caption : output.Id; EngineOutputItem outputItem = new EngineEOutputItem(outputItemId, quantity, elementSet, this); outputItem.TimeSet.SetSingleTime(TimeHelper.ConvertTime(_engineApiAccess.GetTimeHorizon().Start)); outputItem.TimeSet.SetTimeHorizon(TimeHelper.ConvertTime(_engineApiAccess.GetTimeHorizon())); EngineOutputItems.Add(outputItem); } for (int i = 0; i < _engineApiAccess.GetInputExchangeItemCount(); i++) { InputExchangeItem input = _engineApiAccess.GetInputExchangeItem(i); IQuantity quantity = input.Quantity; IElementSet elementSet = input.ElementSet(); String inputItemId = string.IsNullOrEmpty(input.Id) ? elementSet.Caption + ":" + quantity.Caption : input.Id; EngineInputItem inputItem = new EngineEInputItem(inputItemId, quantity, elementSet, this); inputItem.TimeSet.SetSingleTime(TimeHelper.ConvertTime(_engineApiAccess.GetTimeHorizon().Start)); inputItem.TimeSet.SetTimeHorizon(TimeHelper.ConvertTime(_engineApiAccess.GetTimeHorizon())); EngineInputItems.Add(inputItem); } Status = LinkableComponentStatus.Initialized; _initializeWasInvoked = true; }
public override void Initialize() { Status = LinkableComponentStatus.Initializing; // Handle arguments IDictionary <string, IArgument> argDict = Arguments.Dictionary(); Id = argDict.GetValue <string>("ModelId"); this.Caption = "RiverModel Default Model"; _flowItemsAsSpan = argDict.GetValue <bool>("FlowItemsAsSpan"); _storeValuesInItem = argDict.GetValue <bool>("StoreValuesInExchangeitems"); _timeStepLengthInSeconds = argDict.GetValue <double>("TimestepLength"); _timeStepLengthInDays = _timeStepLengthInSeconds / (24.0 * 3600.0); double xyscale = argDict.GetValue <double>("xyscale"); double xOffset = argDict.GetValue <double>("xoffset"); double yOffset = argDict.GetValue <double>("yoffset"); for (int i = 0; i < _numberOfNodes; i++) { _xCoordinate[i] = xyscale * _xCoordinate[i] + xOffset; _yCoordinate[i] = xyscale * _yCoordinate[i] + yOffset; } // -- create a flow quantity -- Dimension flowDimension = new Dimension(); flowDimension.SetPower(DimensionBase.Length, 3); flowDimension.SetPower(DimensionBase.Time, -1); Unit literPrSecUnit = new Unit("LiterPrSecond", 0.001, 0, "Liters pr Second"); Quantity flowQuantity = new Quantity(literPrSecUnit, "Flow", "Flow"); Quantity leakageQuantity = new Quantity(literPrSecUnit, "Leakage", "Leakage"); // -- create a ground water level quantity -- Dimension levelDimension = new Dimension(); levelDimension.SetPower(DimensionBase.Length, 1); Unit levelUnit = new Unit("GroundWaterLevel", 1, 0, "Ground water level"); levelUnit.Dimension = levelDimension; Quantity levelQuantity = new Quantity(levelUnit, "Ground water level", "Ground Water level"); // -- Time settings for input and output exchange items -- ITime timeHorizon = new Time(StartTime, EndTime); // -- create and populate elementset to represent all branches, links betwen nodes in the river network -- LineString fullRiverLineString = new LineString { Coordinates = GeometryFactory.CreateCoordinateList(_xCoordinate, _yCoordinate), Caption = "WholeRiver", Description = "WholeRiver", IsClosed = false, IsNodeBased = false, }; IElementSet fullRiverElementSet = new LineStringWrapper(fullRiverLineString); // --- populate input exchange items for flow to individual nodes, id-based --- for (int i = 0; i < _numberOfNodes; i++) { string id = "Node:" + i; ElementSet elementSet = new ElementSet(id, id, ElementType.IdBased); elementSet.AddElement(new Element(id)); EngineInputItem inputExchangeItem = CreateInputInflowToOneNode(i, id, flowQuantity, elementSet); inputExchangeItem.StoreValuesInExchangeItem = true; // Item is adding up, therefor store in item inputExchangeItem.TimeSet.SetTimeHorizon(timeHorizon); EngineInputItems.Add(inputExchangeItem); } // --- Populate input exchange item for flow into the whole river --- EngineInputItem wholeRiverFlowInputItem = CreateInputInflowToRiver(flowQuantity, fullRiverElementSet); wholeRiverFlowInputItem.TimeSet.SetTimeHorizon(timeHorizon); EngineInputItems.Add(wholeRiverFlowInputItem); // --- Populate input exchange item for ground water level of the whole river --- EngineDInputItem gwLevelInputItem = CreateInputGwLevel(levelQuantity, fullRiverElementSet); gwLevelInputItem.TimeSet.SetTimeHorizon(timeHorizon); EngineInputItems.Add(gwLevelInputItem); // --- Populate output exchange items for flow in river branches, id based --- for (int i = 0; i < _numberOfNodes - 1; i++) { string id = "Branch:" + i; ElementSet elementSet = new ElementSet(id, id, ElementType.IdBased); elementSet.AddElement(new Element(id)); EngineOutputItem outputExchangeItem = CreateOutputFlowInBranch(i, id, flowQuantity, elementSet); EngineOutputItems.Add(outputExchangeItem); } // --- populate output exchange items for leakage for individual branches -- for (int i = 0; i < _numberOfNodes - 1; i++) { string id = "Branch:" + i; ElementSet elementSet = new ElementSet(id, id, ElementType.IdBased); elementSet.AddElement(new Element(id)); EngineOutputItem outputExchangeItem = CreateOutputLeakageInBranch(i, id, leakageQuantity, elementSet); EngineOutputItems.Add(outputExchangeItem); } // --- Populate output exchange item for leakage from the whole georeferenced river --- EngineOutputItem wholeRiverOutputExchangeItem = CreateOuputLeakageInRiver(leakageQuantity, fullRiverElementSet); EngineOutputItems.Add(wholeRiverOutputExchangeItem); // --- Populate output exchange item for flow from the whole georeferenced river --- EngineOutputItem wholeRiverFlowOutputExchangeItem = CreateOutputFlowInRiver(flowQuantity, fullRiverElementSet); EngineOutputItems.Add(wholeRiverFlowOutputExchangeItem); // --- populate with initial state variables --- for (int i = 0; i < _numberOfNodes - 1; i++) { _flow[i] = 7; } foreach (EngineInputItem engineInputItem in EngineInputItems) { // TODO: Overwrites existing timeset, which has already had the time horizon set? engineInputItem.TimeSet = new TimeSet() { HasDurations = _flowItemsAsSpan }; } foreach (EngineOutputItem engineOutputItem in EngineOutputItems) { // TODO: Overwrites existing timeset, which has already had the time horizon set? engineOutputItem.TimeSet = new TimeSet() { HasDurations = _flowItemsAsSpan }; } Status = LinkableComponentStatus.Initialized; }
public override void Initialize() { Status = LinkableComponentStatus.Initializing; ReadArguments(); // Initialize storage vector _storage = new double[NumberOfElements]; for (int i = 0; i < NumberOfElements; i++) { _storage[i] = 0; } // -- Populate Exchange Items --- // Element set for a grid based (polygons) item Spatial2DRegularGrid regularGrid = new Spatial2DRegularGrid() { Description = "RegularGrid", Caption = "RegularGrid", Dx = _dx, Dy = _dy, X0 = _x0, Y0 = _y0, XCount = _xCount, YCount = _yCount, Orientation = _orientation, IsNodeBased = false, }; Spatial2DGridWrapper regularElmtSet = new Spatial2DGridWrapper(regularGrid); // Element set for a Polygon based item, of the lower left cell in the grid Element element0 = new Element("element:0"); element0.AddVertex(new Coordinate(_x0, _y0, 0)); element0.AddVertex(new Coordinate(_x0 + _dx, _y0, 0)); element0.AddVertex(new Coordinate(_x0 + _dx, _y0 + _dy, 0)); element0.AddVertex(new Coordinate(_x0, _y0 + _dy, 0)); // Element set for an ID based item, of the lower left cell in the grid ElementSet idSet = new ElementSet("FirstElement", "FirstElement", ElementType.IdBased); idSet.AddElement(element0); // is an IdBased set required to have elements? // Dimensions Dimension dimVolume = new Dimension(); dimVolume.SetPower(DimensionBase.Length, 3); Dimension dimLength = new Dimension(); dimLength.SetPower(DimensionBase.Length, 1); Dimension dimDischarge = new Dimension(); dimDischarge.SetPower(DimensionBase.Length, 3); dimDischarge.SetPower(DimensionBase.Time, -1); // Units Unit unitLiterStorage = new Unit("Storage", 0.001, 0.0, "Storage"); unitLiterStorage.Dimension = dimVolume; Unit unitGwLevel = new Unit("gw level", 1.0, 0.0, "Ground water level"); unitGwLevel.Dimension = dimLength; Unit unitDischarge = new Unit("Discharge", 0.001, 0, "Discharge into ground water model, [L/s]"); unitDischarge.Dimension = dimDischarge; // Quantities Quantity quantityStorage = new Quantity(unitLiterStorage, "Storage", "Storage"); Quantity quantityGwLevel = new Quantity(unitGwLevel, "Ground water level", "Ground water level"); Quantity quantityInflow = new Quantity(unitDischarge, "Inflow into ground water model", "Inflow"); // Storage input on the grid _storageInput = new EngineEInputItem("Grid.Storage", quantityStorage, regularElmtSet, this); _firstElementStorageInput = new EngineEInputItem("FirstElement.Storage", quantityStorage, idSet, this); // Storage output on the grid _storageOutput = new EngineEOutputItem("Grid.Storage", quantityStorage, regularElmtSet, this); _storageOutput.TimeSet.SetSingleTime(StartTime); _storageOutput.TimeSet.SetTimeHorizon(new Time(StartTime, EndTime)); // Storage output in the first element of the grid _firstElementStorageOutput = new EngineEOutputItem("FirstElement.Storage", quantityStorage, idSet, this); _firstElementStorageOutput.TimeSet.SetSingleTime(StartTime); _firstElementStorageOutput.TimeSet.SetTimeHorizon(new Time(StartTime, EndTime)); // Ground water level output. Calculated as (_gwBaseLevel + 0.1*storage height), assuming that the // water can populate 10% of the ground volume. EngineDOutputItem gwLevelOutput = new EngineDOutputItem("Grid.gwLevel", quantityGwLevel, regularElmtSet, this); gwLevelOutput.StoreValuesInExchangeItem = false; gwLevelOutput.ValueGetter = delegate() { IList <double> res = new List <double>(NumberOfElements); for (int i = 0; i < NumberOfElements; i++) { // Convert storage from liters to m3 and find the height. double storageHeight = 0.001 * _storage[i] / (_dx * _dy); res.Add(_gwBaseLevel + 10 * storageHeight); } return(new ValueSet(new List <IList> { (IList)res })); }; // Ground water inflow in the grid EngineDInputItem gwInflow = new EngineDInputItem("Grid.Inflow", quantityInflow, regularElmtSet, this); gwInflow.ValueSetter = delegate(ITimeSpaceValueSet values) { IList elmtValues = values.GetElementValuesForTime(0); for (int i = 0; i < NumberOfElements; i++) { // Values arrive in [L/s], storage is in liters. _storage[i] += (double)elmtValues[i] * _timeStepLengthInSeconds; if (_storage[i] < 0) // inflow can be negative, but storage can not be zero. Mass error here :-( { _storage[i] = 0; } } }; EngineOutputItems.Add(_storageOutput); EngineOutputItems.Add(_firstElementStorageOutput); EngineOutputItems.Add(gwLevelOutput); EngineInputItems.Add(_storageInput); EngineInputItems.Add(_firstElementStorageInput); if (_useMultiInput) { EngineInputItems.Add(new EngineMultiInputItemWrapper(gwInflow, this)); } else { EngineInputItems.Add(gwInflow); } Status = LinkableComponentStatus.Initialized; }