public void GetValuesFromTimeSeries() { ITimeSpaceComponent timeSeries = new TimeSeriesComponent(); // initialize model timeSeries.Initialize(); ITimeSpaceOutput output = (ITimeSpaceOutput)timeSeries.Outputs[0]; // specify query times Time startTime = new Time(new DateTime(2005, 1, 1, 0, 0, 0)); double firstTriggerGetValuesTime = startTime.StampAsModifiedJulianDay; double secondTriggerGetValuesTime = firstTriggerGetValuesTime + 12.1; double thirdTriggerGetValuesTime = firstTriggerGetValuesTime + 16.7; // get values for specified query times - initial time, will return initial value queryItem1.TimeSet.SetSingleTimeStamp(firstTriggerGetValuesTime); ITimeSpaceValueSet values = output.GetValues(queryItem1); Assert.AreEqual(1, values.GetValue(0, 0), "value for first query time"); // 12.1 days from 01-01 queryItem1.TimeSet.SetSingleTimeStamp(secondTriggerGetValuesTime); values = output.GetValues(queryItem1); Assert.AreEqual(13, values.GetValue(0, 0), "value for second query time"); // 16.7 days from 01-01 queryItem1.TimeSet.SetSingleTimeStamp(thirdTriggerGetValuesTime); values = output.GetValues(queryItem1); Assert.AreEqual(17, values.GetValue(0, 0), "value for third query time"); }
public void GetValues1A() { LinkableEngine riverModelLE = CreateRiverModel(); ITimeSpaceComponent riverModelLC = riverModelLE; // initialize model List <IArgument> riverArguments = CreateRiverModelArguments(riverModelLC); riverArguments.Add(Argument.Create("ModelID", "RiverModel", true, "argument")); riverArguments.Add(Argument.Create("TimeStepLength", 3600)); riverModelLC.Arguments.ApplyArguments(riverArguments); riverModelLC.Initialize(); // Link output and trigger with a time buffer ITimeSpaceOutput output = (ITimeSpaceOutput)riverModelLC.Outputs[2]; IAdaptedOutputFactory adaptedOutputFactory = riverModelLC.AdaptedOutputFactories[0]; IIdentifiable[] adaptedOutputIds = adaptedOutputFactory.GetAvailableAdaptedOutputIds(output, _queryItem1); ITimeSpaceAdaptedOutput adaptedOutput = (ITimeSpaceAdaptedOutput) adaptedOutputFactory.CreateAdaptedOutput(adaptedOutputIds[0], output, _queryItem1); adaptedOutput.AddConsumer(_queryItem1); riverModelLC.Validate(); Assert.IsTrue(riverModelLC.Status == LinkableComponentStatus.Valid); riverModelLC.Prepare(); Assert.IsTrue(riverModelLC.Status == LinkableComponentStatus.Updated); // specify query times double firstTriggerGetValuesTime = riverModelLE.CurrentTime.StampAsModifiedJulianDay; double secondTriggerGetValuesTime = firstTriggerGetValuesTime + 2; double thirdTriggerGetValuesTime = firstTriggerGetValuesTime + 4.3; // check initial values Assert.AreEqual(1, output.Values.Values2D[0].Count, "#values for " + output.Id); Assert.AreEqual(7.0, (double)output.Values.GetValue(0, 0), "Value[0] as property"); // get values for specified query times _queryItem1.TimeSet.SetSingleTimeStamp(firstTriggerGetValuesTime); ITimeSpaceValueSet values = adaptedOutput.GetValues(_queryItem1); Assert.AreEqual(7.0, values.GetValue(0, 0), "value for first query time"); // only runoff inflow, 10 L/s _queryItem1.TimeSet.SetSingleTimeStamp(secondTriggerGetValuesTime); values = adaptedOutput.GetValues(_queryItem1); Assert.AreEqual(35.0 / 4.0, values.GetValue(0, 0), "value for second query time"); // still only runoff inflow, 10 L/s _queryItem1.TimeSet.SetSingleTimeStamp(thirdTriggerGetValuesTime); values = adaptedOutput.GetValues(_queryItem1); Assert.AreEqual(35.0 / 4.0, values.GetValue(0, 0), "value for third query time"); riverModelLC.Finish(); }
public override void SetEngineValues(EngineInputItem inputItem, ITimeSpaceValueSet values) { int elementCount = ValueSet.GetElementCount(values); double[] avalues = new double[elementCount]; for (int i = 0; i < elementCount; i++) { avalues[i] = (double)values.GetValue(0, i); } ScalarSet scalarSet = new ScalarSet(avalues); _engineApiAccess.SetValues(inputItem.ValueDefinition.Caption, inputItem.SpatialDefinition.Caption, scalarSet); }
private void FillLocalValues() { if (_Values == null) { ITimeSpaceValueSet temp = _openMIOutputItem.Values; int nVals = temp.Values2D[0].Count; _Values = new double[nVals]; for (int i = 0; i < temp.Values2D[0].Count; i++) { _Values[i] = (double)temp.GetValue(0, i); } } }
public List <double> ApxyLinearly(ITimeSpaceValueSet data, double[] apxValue) { int size = data.Values2D[0].Count; double incrementV = apxValue[0] / size; List <double> dvalues = new List <double>(); for (int i = 0; i < size; i++) { dvalues.Add((double)data.GetValue(0, i) + incrementV * i); } return(dvalues); }
private void StoreInputValuesInComputationalCore(EngineInputItem inputItem, ITimeSpaceValueSet values) { char[] separator = new[] { ':' }; string[] subStrings = inputItem.SpatialDefinition.Caption.Split(separator); if (inputItem.Id.Equals("WholeRiver.Flow")) { // values are numberOfNodes-1 long (input for each branch. // Put inflow at "upstream" node/storage for (int i = 0; i < _inflowStorage.Length - 1; i++) { _inflowStorage[i] += ((double)values.GetValue(0, i)) * _timeStepLengthInSeconds; } } else if (subStrings[0] == "Node") { int nodeIndex = Convert.ToInt32(subStrings[1]); _inflowStorage[nodeIndex] += ((double)values.GetValue(0, 0)) * _timeStepLengthInSeconds; } else { throw new ArgumentException("Unknown Input Item Id: \"" + inputItem.Id + "\"", "inputItem"); } }
public override void SetEngineValues(EngineInputItem inputItem, ITimeSpaceValueSet values) { if (inputItem == _storageInput) { IList elementValues = values.GetElementValuesForTime(0); for (int i = 0; i < _storage.Length; i++) { _storage[i] = (double)elementValues[i]; } } else if (inputItem == _firstElementStorageInput) { _storage[0] = (double)values.GetValue(0, 0); } else { throw new ArgumentException("Unknown Input Item Id: \"" + inputItem.Id + "\"", "inputItem"); } }
override public void ValidValue(ITimeSpaceValueSet valueSet) { // TODO Standard move ValidValue into IExchangeItem? if (valueSet == null) { throw new ArgumentException("value == null"); } if (ValueSet.GetElementCount(valueSet) != 1) { throw new ArgumentException("valueSet.ElementCount != 1"); } if (ValueSet.GetTimesCount(valueSet) != 1) { throw new ArgumentException("valueSet.TimesCount != 1"); } if (!(valueSet.GetValue(0, 0) is double)) { throw new ArgumentException("!(valueSet.GetValue(0,0) is double)"); } }
public override void SetEngineValues(EngineInputItem inputItem, ITimeSpaceValueSet values) { IQuantity quantity = inputItem.ValueDefinition as IQuantity; if (quantity == null) { throw new ArgumentException("Can only accept quantity as valuedefinition", "inputItem"); } if (quantity.Caption == "InFlow" && inputItem.SpatialDefinition.Caption == "AllBranches") { for (int i = 0; i < _simpleRiverEngine.GetNumberOfNodes(); i++) { _simpleRiverEngine.AddInflow(i, (double)values.GetValue(0, i)); } } else { throw new ArgumentException("Unknown quantity/elementSet combination", "inputItem"); } }
public void SetValues(ITimeSpaceValueSet values) { // Assuming elsewhere is taken care of that the sizes are correct. _vector[_index] = (T)values.GetValue(0, 0); }
public void GetValuesFromGwModel() { Quantity dischargeQuantity = new Quantity(new Unit(PredefinedUnits.CubicMeterPerSecond), null, "Discharge"); Quantity waterlevelQuantity = new Quantity(new Unit(PredefinedUnits.Meter), null, "Water Level"); ElementSet idBasedElementSetA = new ElementSet(null, "ElmSet-A", ElementType.IdBased); idBasedElementSetA.AddElement(new Element("elm-1")); Input queryItem1 = new Input("discharge, to be retrieved from some output item", dischargeQuantity, idBasedElementSetA); queryItem1.TimeSet = new TimeSet(); Input queryItem2 = new Input("water level, to be retrieved from some output item", waterlevelQuantity, idBasedElementSetA); queryItem2.TimeSet = new TimeSet(); // Connect query item(s) to output item(s) // Take care that component becomes valid (and has produced initial output for connected items) ITimeSpaceComponent gwModel = new GWModelLC(); gwModel.Initialize(); ITimeSpaceOutput storageOnGrid = UTHelper.FindOutputItem(gwModel, "Grid.Storage"); storageOnGrid.AddConsumer(queryItem1); gwModel.Validate(); Assert.IsTrue(gwModel.Status == LinkableComponentStatus.Valid); gwModel.Prepare(); Assert.IsTrue(gwModel.Status == LinkableComponentStatus.Updated); // check initial values Assert.AreEqual(4, ValueSet.GetElementCount(storageOnGrid.Values), "#values for " + storageOnGrid.Id); Assert.AreEqual(0.0, (double)storageOnGrid.Values.GetValue(0, 0), "Value[0] as property"); // get values for specified query times queryItem1.TimeSet.SetSingleTimeStamp(new DateTime(2005, 1, 3, 0, 0, 0)); ITimeSpaceValueSet values = storageOnGrid.GetValues(queryItem1); Assert.IsNotNull(values, "values != null"); Assert.AreEqual(0.0, (double)values.GetValue(0, 0), "value[0] from GetValues 1"); // set next query time queryItem1.TimeSet.SetSingleTimeStamp(new DateTime(2005, 2, 4, 0, 0, 0)); values = storageOnGrid.GetValues(queryItem1); Assert.IsNotNull(values, "values != null"); Assert.AreEqual(0.0, (double)values.GetValue(0, 0), "value[0] from GetValues 1"); // ask for same time again values = storageOnGrid.GetValues(queryItem1); Assert.IsNotNull(values, "values != null"); Assert.AreEqual(0.0, (double)values.GetValue(0, 0), "value[0] from GetValues 1"); try { // set query time back in time queryItem1.TimeSet.SetSingleTimeStamp(new DateTime(2005, 2, 3, 0, 0, 0)); storageOnGrid.GetValues(queryItem1); } catch (Exception e) { Assert.IsTrue(e.Message.StartsWith("Could not update engine \"")); } try { // set query time beyond time horizon queryItem1.TimeSet.SetSingleTimeStamp(new DateTime(2005, 2, 28, 0, 0, 0)); storageOnGrid.GetValues(queryItem1); } catch (Exception e) { Assert.IsTrue(e.Message.StartsWith("Could not update engine \"")); } }
public void GetValues() { // Connect query item(s) to output item(s) // Take care that component becomes valid (and has produced initial output for connected items) ITimeSpaceComponent riverModel = CreateRiverModel(); List <IArgument> arguments = CreateRiverModelArguments(riverModel); arguments.Add(new ArgumentBool("flowItemsAsSpan", _flowItemsAsSpan)); riverModel.Arguments.ApplyArguments(arguments); riverModel.Initialize(); ITimeSpaceOutput flowOnBranch = UTHelper.FindOutputItem(riverModel, "Branch:2:Flow"); flowOnBranch.AddConsumer(_queryItem1); riverModel.Validate(); Assert.IsTrue(riverModel.Status == LinkableComponentStatus.Valid); riverModel.Prepare(); Assert.IsTrue(riverModel.Status == LinkableComponentStatus.Updated); // check initial values Assert.AreEqual(1, ValueSet.GetElementCount(flowOnBranch.Values), "#values for " + flowOnBranch.Id); Assert.AreEqual(7.0, (double)flowOnBranch.Values.GetValue(0, 0), "Value[0] as property"); // get values for specified query times _queryItem1.TimeSet.SetSingleTimeStamp(new DateTime(2005, 1, 3, 0, 0, 0)); ITimeSpaceValueSet values = flowOnBranch.GetValues(_queryItem1); Assert.IsNotNull(values, "values != null"); double flow3 = 35.0 / 4.0; // = 10 * (1.0 / 2.0 + 1.0 / 4.0 + 1.0 / 8.0) = 8.75 Assert.AreEqual(flow3, (double)values.GetValue(0, 0), "value[0] from GetValues 1"); // set next query time _queryItem1.TimeSet.SetSingleTimeStamp(new DateTime(2005, 2, 4, 0, 0, 0)); values = flowOnBranch.GetValues(_queryItem1); Assert.IsNotNull(values, "values != null"); flow3 = 10 * (1.0 / 2.0 + 1.0 / 4.0 + 1.0 / 8.0); // = 8.75 Assert.AreEqual(flow3, (double)values.GetValue(0, 0), "value[0] from GetValues 1"); // ask for same time again values = flowOnBranch.GetValues(_queryItem1); Assert.IsNotNull(values, "values != null"); Assert.AreEqual(flow3, (double)values.GetValue(0, 0), "value[0] from GetValues 1"); try { // set query time back in time _queryItem1.TimeSet.SetSingleTimeStamp(new DateTime(2005, 2, 3, 0, 0, 0)); flowOnBranch.GetValues(_queryItem1); } catch (Exception e) { Assert.IsTrue(e.Message.StartsWith("Could not update engine \"")); } try { // set query time beyond time horizon _queryItem1.TimeSet.SetSingleTimeStamp(new DateTime(2005, 2, 28, 0, 0, 0)); flowOnBranch.GetValues(_queryItem1); } catch (Exception e) { Assert.IsTrue(e.Message.StartsWith("Could not update engine \"")); } }
public void GetValues1B() { ITimeSpaceComponent timeSeries = new TimeSeriesComponent(); LinkableEngine riverModelLE = CreateRiverModel(); ITimeSpaceComponent riverModelLC = riverModelLE; // initialize model timeSeries.Initialize(); List <IArgument> riverArguments = CreateRiverModelArguments(riverModelLC); riverArguments.Add(Argument.Create("ModelID", "upperRiverModel", true, "argument")); riverArguments.Add(new ArgumentBool("flowItemsAsSpan", true)); riverArguments.Add(Argument.Create("TimeStepLength", 3600)); riverModelLC.Arguments.ApplyArguments(riverArguments); riverModelLC.Initialize(); // Connect time series component and river IBaseOutput tsOutput = timeSeries.Outputs[0]; IBaseInput riverInput = riverModelLC.Inputs[0]; tsOutput.AddConsumer(riverInput); // Connect tigger to river ITimeSpaceOutput output = (ITimeSpaceOutput)riverModelLC.Outputs[2]; IAdaptedOutputFactory adaptedOutputFactory = riverModelLC.AdaptedOutputFactories[0]; IIdentifiable[] adaptedOutputIds = adaptedOutputFactory.GetAvailableAdaptedOutputIds(output, _queryItem1); ITimeSpaceAdaptedOutput adaptedOutput = (ITimeSpaceAdaptedOutput) adaptedOutputFactory.CreateAdaptedOutput(adaptedOutputIds[0], output, _queryItem1); adaptedOutput.AddConsumer(_queryItem1); // Validate and prepare riverModelLC.Validate(); Assert.IsTrue(riverModelLC.Status == LinkableComponentStatus.Valid); riverModelLC.Prepare(); Assert.IsTrue(riverModelLC.Status == LinkableComponentStatus.Updated); // specify query times double firstTriggerGetValuesTime = riverModelLE.CurrentTime.StampAsModifiedJulianDay; double secondTriggerGetValuesTime = firstTriggerGetValuesTime + 12.1; double thirdTriggerGetValuesTime = firstTriggerGetValuesTime + 16.7; // check initial values Assert.AreEqual(1, output.Values.Values2D[0].Count, "#values for " + output.Id); Assert.AreEqual(7.0, (double)output.Values.GetValue(0, 0), "Value[0] as property"); // get values for specified query times - initial time, will return initial value _queryItem1.TimeSet.SetSingleTimeStamp(firstTriggerGetValuesTime); ITimeSpaceValueSet values = adaptedOutput.GetValues(_queryItem1); Assert.AreEqual(7.0, values.GetValue(0, 0), "value for first query time"); // 12.1 days from 01-01, 10 L/s runoff + 13 L/s inflow on first node _queryItem1.TimeSet.SetSingleTimeStamp(secondTriggerGetValuesTime); values = adaptedOutput.GetValues(_queryItem1); Assert.AreEqual(35.0 / 4.0 + 13.0 / 8.0, values.GetValue(0, 0), "value for second query time"); // 16.7 days from 01-01, 10 L/s runoff + 17 L/s inflow on first node _queryItem1.TimeSet.SetSingleTimeStamp(thirdTriggerGetValuesTime); values = adaptedOutput.GetValues(_queryItem1); Assert.AreEqual(35.0 / 4.0 + 17.0 / 8.0, values.GetValue(0, 0), "value for third query time"); riverModelLC.Finish(); }
public void CouplingGwRiver2() { /// runNumber 0: Using MultiInput /// runNumber 1: Using MultiInputAdaptor /// runNumber 2: Using MultiInputAdaptorFactory for (int runNumber = 0; runNumber < 3; runNumber++) { Console.Out.WriteLine("runNumber: " + runNumber); // Create trigger inputs Input queryDischargeItem = CreateDischargeInput(); Input queryVolume = CreateVolumeInput(); // Create models LinkableEngine riverModel = CreateRiverModel(); LinkableEngine riverModel2 = CreateRiverModel(); ITimeSpaceComponent gwModel = CreateGwModel(); // Add arguments and initialize IDictionary <string, IArgument> gwArgs = gwModel.Arguments.Dictionary(); // Increasing model grid size (otherwise GW model runs full too fast) gwArgs.UpdateValue("dx", 50.0); gwArgs.UpdateValue("dy", 50.0); gwArgs.UpdateValue("x0", 0.0); gwArgs.UpdateValue("y0", 200.0); gwArgs.UpdateValue("XCount", 24); gwArgs.UpdateValue("ycount", 16); if (runNumber == 0) { gwArgs.UpdateValue("UseMultiInput", true); } gwModel.Initialize(); int gwGridSize = 24 * 16; IDictionary <string, IArgument> riverArgs = riverModel.Arguments.Dictionary(); // Increasing model grid size (otherwise GW model runs full too fast) riverArgs.UpdateValue("xyscale", 100.0); riverModel.Initialize(); IDictionary <string, IArgument> river2Args = riverModel2.Arguments.Dictionary(); // Increasing model grid size (otherwise GW model runs full too fast) river2Args.UpdateValue("xyscale", 100.0); // Move river2 sligthly away from river1 river2Args.UpdateValue("xoffset", -220.0); river2Args.UpdateValue("yoffset", 180.0); riverModel2.Initialize(); // Connect triggering inputs ITimeSpaceOutput flowOnBranch = UTHelper.FindOutputItem(riverModel, "Branch:2:Flow"); TimeInterpolator flowOnBranch2 = new TimeInterpolator(flowOnBranch); flowOnBranch.AddAdaptedOutput(flowOnBranch2); flowOnBranch2.AddConsumer(queryDischargeItem); ITimeSpaceOutput storageInGw = UTHelper.FindOutputItem(gwModel, "Grid.Storage"); TimeInterpolator storageInGw2 = new TimeInterpolator(storageInGw); storageInGw.AddAdaptedOutput(storageInGw2); storageInGw2.AddConsumer(queryVolume); //========== Couple leakage items ========== ITimeSpaceInput gwInflowInput = UTHelper.FindInputItem(gwModel, "Grid.Inflow"); //========== IBaseMultiInput linking ========== if (runNumber == 0) { /// Example of adding up two outputs into one input, by the use of /// an IBaseMultiInput implementation Assert.IsTrue(gwInflowInput is IBaseMultiInput); Assert.IsTrue(gwInflowInput is ITimeSpaceMultiInput); // put leakage from river1 into ground water model { ITimeSpaceOutput riverLeakageOutput = UTHelper.FindOutputItem(riverModel, "WholeRiver:Leakage"); // Two adaptors are added: Time buffer and line-to-grid adaptor // they can be added in any order (though time buffer first will use less memory) // Time interpolator TimeInterpolator riverLeakageOutput2 = new TimeInterpolator(riverLeakageOutput); riverLeakageOutput.AddAdaptedOutput(riverLeakageOutput2); // Element mapper from polyline to polygon, weighted sum version ElementMapperAdaptedOutput riverLeakageOutputGrid = new ElementMapperAdaptedOutput(new Identifier("ElementMapper501"), riverLeakageOutput2, gwInflowInput.ElementSet()); riverLeakageOutput2.AddAdaptedOutput(riverLeakageOutputGrid); // Note !!!: No special action riverLeakageOutputGrid.AddConsumer(gwInflowInput); } // put leakage from river2 into ground water model { ITimeSpaceOutput riverLeakageOutput = UTHelper.FindOutputItem(riverModel2, "WholeRiver:Leakage"); // Two adaptors are added: Time buffer and line-to-grid adaptor // they can be added in any order (though time buffer first will use less memory) // Time interpolator TimeInterpolator riverLeakageOutput2 = new TimeInterpolator(riverLeakageOutput); riverLeakageOutput.AddAdaptedOutput(riverLeakageOutput2); // Element mapper from polyline to polygon, weighted sum version ElementMapperAdaptedOutput riverLeakageOutputGrid = new ElementMapperAdaptedOutput(new Identifier("ElementMapper501"), riverLeakageOutput2, gwInflowInput.ElementSet()); riverLeakageOutput2.AddAdaptedOutput(riverLeakageOutputGrid); // Note !!!: No special action riverLeakageOutputGrid.AddConsumer(gwInflowInput); } } //========== MultiInputAdaptor linking ========== if (runNumber == 1) { /// Example of adding up two outputs into one input, by the use of /// a MultiInputAdaptor class // Note !!!: Creating a MultiInputAdaptor MultiInputAdaptor sourceAdder = new MultiInputAdaptor("SomeId") { SpatialDefinition = gwInflowInput.SpatialDefinition }; // put leakage from river1 into ground water model // Two adaptors are added: Time buffer and line-to-grid adaptor { ITimeSpaceOutput riverLeakageOutput = UTHelper.FindOutputItem(riverModel, "WholeRiver:Leakage"); // Time interpolator TimeInterpolator riverLeakageOutput2 = new TimeInterpolator(riverLeakageOutput); riverLeakageOutput.AddAdaptedOutput(riverLeakageOutput2); // Element mapper from polyline to polygon, weighted sum version ElementMapperAdaptedOutput riverLeakageOutputGrid = new ElementMapperAdaptedOutput(new Identifier("ElementMapper501"), riverLeakageOutput2, gwInflowInput.ElementSet()); riverLeakageOutput2.AddAdaptedOutput(riverLeakageOutputGrid); // Note !!!: Adding to the list of adaptees sourceAdder.Adaptees.Add(riverLeakageOutputGrid); riverLeakageOutputGrid.AddAdaptedOutput(sourceAdder); } // put leakage from river2 into ground water model // Two adaptors are added: Time buffer and line-to-grid adaptor { ITimeSpaceOutput riverLeakageOutput = UTHelper.FindOutputItem(riverModel2, "WholeRiver:Leakage"); // Time interpolator TimeInterpolator riverLeakageOutput2 = new TimeInterpolator(riverLeakageOutput); riverLeakageOutput.AddAdaptedOutput(riverLeakageOutput2); // Element mapper from polyline to polygon, weighted sum version ElementMapperAdaptedOutput riverLeakageOutputGrid = new ElementMapperAdaptedOutput(new Identifier("ElementMapper501"), riverLeakageOutput2, gwInflowInput.ElementSet()); riverLeakageOutput2.AddAdaptedOutput(riverLeakageOutputGrid); // Note !!!: Adding to the list of adaptees sourceAdder.Adaptees.Add(riverLeakageOutputGrid); riverLeakageOutputGrid.AddAdaptedOutput(sourceAdder); } // Note !!!: Connect the gwInflowInput and the multiInputAdaptor sourceAdder.AddConsumer(gwInflowInput); } //========== MultiInputAdaptorFactory linking ========== if (runNumber == 2) { /// Example of adding up two outputs into one input, by the use of /// an MultiInputAdaptorFactory implementation var factory = new MultiInputAdaptorFactory(gwModel); // put leakage from river1 into ground water model // Two adaptors are added: Time buffer and line-to-grid adaptor { ITimeSpaceOutput riverLeakageOutput = UTHelper.FindOutputItem(riverModel, "WholeRiver:Leakage"); // Time interpolator TimeInterpolator riverLeakageOutput2 = new TimeInterpolator(riverLeakageOutput); riverLeakageOutput.AddAdaptedOutput(riverLeakageOutput2); // Element mapper from polyline to polygon, weighted sum version ElementMapperAdaptedOutput riverLeakageOutputGrid = new ElementMapperAdaptedOutput(new Identifier("ElementMapper501"), riverLeakageOutput2, gwInflowInput.ElementSet()); riverLeakageOutput2.AddAdaptedOutput(riverLeakageOutputGrid); // Note !!!: Creating a new AdaptedOutput and adding it IIdentifiable[] identifiables = factory.GetAvailableAdaptedOutputIds(riverLeakageOutputGrid, gwInflowInput); IBaseAdaptedOutput myOutput = factory.CreateAdaptedOutput(identifiables[0], riverLeakageOutputGrid, gwInflowInput); myOutput.AddConsumer(gwInflowInput); } // put leakage from river2 into ground water model // Two adaptors are added: Time buffer and line-to-grid adaptor { ITimeSpaceOutput riverLeakageOutput = UTHelper.FindOutputItem(riverModel2, "WholeRiver:Leakage"); // Time interpolator TimeInterpolator riverLeakageOutput2 = new TimeInterpolator(riverLeakageOutput); riverLeakageOutput.AddAdaptedOutput(riverLeakageOutput2); // Element mapper from polyline to polygon, weighted sum version ElementMapperAdaptedOutput riverLeakageOutputGrid = new ElementMapperAdaptedOutput(new Identifier("ElementMapper501"), riverLeakageOutput2, gwInflowInput.ElementSet()); riverLeakageOutput2.AddAdaptedOutput(riverLeakageOutputGrid); // Note !!!: Creating a new AdaptedOutput and adding it IIdentifiable[] identifiables = factory.GetAvailableAdaptedOutputIds(riverLeakageOutputGrid, gwInflowInput); IBaseAdaptedOutput myOutput = factory.CreateAdaptedOutput(identifiables[0], riverLeakageOutputGrid, gwInflowInput); myOutput.AddConsumer(gwInflowInput); } } //========== Run ========== // Validate riverModel.Validate(); Assert.IsTrue(riverModel.Status == LinkableComponentStatus.Valid); riverModel2.Validate(); Assert.IsTrue(riverModel2.Status == LinkableComponentStatus.Valid); gwModel.Validate(); Assert.IsTrue(gwModel.Status == LinkableComponentStatus.Valid); // Prepare riverModel.Prepare(); Assert.IsTrue(riverModel.Status == LinkableComponentStatus.Updated); riverModel2.Prepare(); Assert.IsTrue(riverModel2.Status == LinkableComponentStatus.Updated); gwModel.Prepare(); Assert.IsTrue(gwModel.Status == LinkableComponentStatus.Updated); // specify query times double triggerTime0 = riverModel.CurrentTime.StampAsModifiedJulianDay; double triggerTime1 = triggerTime0 + 1; double triggerTime2 = triggerTime0 + 2; double triggerTime3 = triggerTime0 + 12.1; double triggerTime4 = triggerTime0 + 16.7; /// Properties of the river, without gw-level input /// Inflow into each node from rainfall runoff is 10 L/s /// Inflow to node 1: 10 L/s - leaking 5 L/s on branch 1 /// Inflow to node 2: 10 + 5 L/s - leaking 15/2 L/s on branch 2 /// Inflow to node 3: 10 + 15/2 L/s - leaking 35/4 L/s on branch 3 /// Total leakage 5+15/2+35/4 = (20+30+35)/4 = 85/4 L/s /// /// Number of seconds in a day: 60*60*24 = 86400 // check initial values Assert.AreEqual(1, ValueSet.GetElementCount(flowOnBranch.Values), "#values for " + flowOnBranch.Id); Assert.AreEqual(7.0, (double)flowOnBranch.Values.GetValue(0, 0), "Value[0] as property"); Assert.AreEqual(gwGridSize, ValueSet.GetElementCount(storageInGw.Values), "#values for " + storageInGw.Id); Assert.AreEqual(0, SumTimeStep(storageInGw.Values, 0)); // get values for specified query times, 1 days // Totally leaking: 86400 * 85/4 = 1.836e6 // For the bi-directional coupling: // the entire first day the river uses extrapolated values from the // gwModel, which gives a gwLevel of -10, hence same value as for the uni-directional queryDischargeItem.TimeSet.SetSingleTimeStamp(triggerTime1); ITimeSpaceValueSet valuesV = storageInGw2.GetValues(queryDischargeItem); ITimeSpaceValueSet valuesQ = flowOnBranch2.GetValues(queryDischargeItem); Assert.AreEqual(35.0 / 4.0, (double)valuesQ.GetValue(0, 0)); Assert.AreEqual(2 * 1.836e6, SumTimeStep(valuesV, 0), 1e-4); // Print out, to load in a plotting program for verification StringBuilder b = new StringBuilder(); IList valV = valuesV.GetElementValuesForTime(0); int ivalvV = 0; for (int i = 0; i < 16; i++) { for (int j = 0; j < 24; j++) { b.Append(((double)valV[ivalvV++]).ToString(NumberFormatInfo.InvariantInfo)); b.Append(" "); } b.AppendLine(); } //Console.Out.WriteLine(b.ToString()); // get values for specified query times, 2 days // 2 * 86400 * 85/4 = 3.672e6 queryDischargeItem.TimeSet.SetSingleTimeStamp(triggerTime2); valuesV = storageInGw2.GetValues(queryDischargeItem); valuesQ = flowOnBranch2.GetValues(queryDischargeItem); Assert.AreEqual(35.0 / 4.0, (double)valuesQ.GetValue(0, 0)); Assert.AreEqual(2 * 3.672e6, SumTimeStep(valuesV, 0), 1e-4); // get values for specified query times, 12.1 days // 12.1 * 86400 * 85/4 = 2.22156e7 queryDischargeItem.TimeSet.SetSingleTimeStamp(triggerTime3); valuesV = storageInGw2.GetValues(queryDischargeItem); valuesQ = flowOnBranch2.GetValues(queryDischargeItem); Assert.AreEqual(35.0 / 4.0, (double)valuesQ.GetValue(0, 0)); Assert.AreEqual(2 * 2.22156e7, SumTimeStep(valuesV, 0), 1e-4); // get values for specified query times, 16.7 days // 16.7 * 86400 * 85/4 = 3.06612e7 queryDischargeItem.TimeSet.SetSingleTimeStamp(triggerTime4); valuesV = storageInGw2.GetValues(queryDischargeItem); valuesQ = flowOnBranch2.GetValues(queryDischargeItem); Assert.AreEqual(35.0 / 4.0, (double)valuesQ.GetValue(0, 0)); Assert.AreEqual(2 * 3.06612e7, SumTimeStep(valuesV, 0), 1e-4); } }
public void CouplingGwRiver() { /// bit 1: Decides whether the timeInterpolator or grid-to-line adaptor comes first /// bit 2: when true, using a 16x16 gw grid (instead of 2x2) /// bit 3: when true, bi-directinal: adds a link from gwModel to river, with the gw-level for (int runNumber = 0; runNumber < 8; runNumber++) { //if (runNumber != 3) // continue; Console.Out.WriteLine("runNumber: " + runNumber); // Create trigger inputs Input queryDischargeItem = CreateDischargeInput(); Input queryVolume = CreateVolumeInput(); // Create models LinkableEngine riverModel = CreateRiverModel(); ITimeSpaceComponent gwModel = CreateGwModel(); // Add arguments and initialize IDictionary <string, IArgument> gwArgs = gwModel.Arguments.Dictionary(); // Increasing model grid size (otherwise GW model runs full too fast) gwArgs.UpdateValue("dx", 400.0); gwArgs.UpdateValue("dy", 400.0); gwArgs.UpdateValue("x0", 200.0); gwArgs.UpdateValue("y0", 200.0); int gwGridSize = 2 * 2; if ((runNumber & 2) == 2) // set 16 x 16 grid { gwArgs.UpdateValue("dx", 50.0); gwArgs.UpdateValue("dy", 50.0); gwArgs.UpdateValue("XCount", 16); gwArgs.UpdateValue("ycount", 16); gwGridSize = 16 * 16; } gwModel.Initialize(); IDictionary <string, IArgument> riverArgs = riverModel.Arguments.Dictionary(); // Increasing model grid size (otherwise GW model runs full too fast) riverArgs.UpdateValue("xyscale", 100.0); riverModel.Initialize(); // Connect triggering inputs ITimeSpaceOutput flowOnBranch = UTHelper.FindOutputItem(riverModel, "Branch:2:Flow"); TimeInterpolator flowOnBranch2 = new TimeInterpolator(flowOnBranch); flowOnBranch.AddAdaptedOutput(flowOnBranch2); flowOnBranch2.AddConsumer(queryDischargeItem); ITimeSpaceOutput storageInGw = UTHelper.FindOutputItem(gwModel, "Grid.Storage"); TimeInterpolator storageInGw2 = new TimeInterpolator(storageInGw); storageInGw.AddAdaptedOutput(storageInGw2); storageInGw2.AddConsumer(queryVolume); //========== Couple leakage items ========== // put leakage from river into ground water model { ITimeSpaceOutput riverLeakageOutput = UTHelper.FindOutputItem(riverModel, "WholeRiver:Leakage"); ITimeSpaceInput gwInflowInput = UTHelper.FindInputItem(gwModel, "Grid.Inflow"); // Two adaptors are added: Time buffer and line-to-grid adaptor // they can be added in any order (though time buffer first will use less memory) if ((runNumber & 1) == 1) { // Time interpolator TimeInterpolator riverLeakageOutput2 = new TimeInterpolator(riverLeakageOutput); riverLeakageOutput.AddAdaptedOutput(riverLeakageOutput2); // Element mapper from polyline to polygon, weighted sum version ElementMapperAdaptedOutput riverLeakageOutputGrid = new ElementMapperAdaptedOutput(new Identifier("ElementMapper501"), riverLeakageOutput2, gwInflowInput.ElementSet()); riverLeakageOutput2.AddAdaptedOutput(riverLeakageOutputGrid); riverLeakageOutputGrid.AddConsumer(gwInflowInput); } else { // Element mapper from polyline to polygon, weighted sum version ElementMapperAdaptedOutput riverLeakageOutputGrid = new ElementMapperAdaptedOutput(new Identifier("ElementMapper501"), riverLeakageOutput, gwInflowInput.ElementSet()); riverLeakageOutput.AddAdaptedOutput(riverLeakageOutputGrid); // Time interpolator TimeInterpolator riverLeakageOutput2 = new TimeInterpolator(riverLeakageOutputGrid); riverLeakageOutputGrid.AddAdaptedOutput(riverLeakageOutput2); riverLeakageOutput2.AddConsumer(gwInflowInput); } } //========== Couple ground water level items ========== if ((runNumber & 4) == 4) { // put ground water level from ground water model into river ITimeSpaceInput riverGwleveInput = UTHelper.FindInputItem(riverModel, "WholeRiver:GroundWaterLevel"); ITimeSpaceOutput gwLevelOutput = UTHelper.FindOutputItem(gwModel, "Grid.gwLevel"); // Two adaptors are added: Time buffer and grid-to-line adaptor // they can be added in any order (though time buffer last will use less memory) if ((runNumber & 1) == 1) { // Time interpolator var gwLevelOutput2 = new TimeExtrapolator(gwLevelOutput); gwLevelOutput.AddAdaptedOutput(gwLevelOutput2); // Element mapper from polyline to polygon, weighted sum version var gwLevelOutputLine = new ElementMapperAdaptedOutput(new Identifier("ElementMapper700"), gwLevelOutput2, riverGwleveInput.ElementSet()); gwLevelOutput2.AddAdaptedOutput(gwLevelOutputLine); gwLevelOutputLine.AddConsumer(riverGwleveInput); } else { // Element mapper from polyline to polygon, weighted sum version var gwLevelOutputLine = new ElementMapperAdaptedOutput(new Identifier("ElementMapper700"), gwLevelOutput, riverGwleveInput.ElementSet()); gwLevelOutput.AddAdaptedOutput(gwLevelOutputLine); // Time interpolator var gwLevelOutput2 = new TimeExtrapolator(gwLevelOutputLine); gwLevelOutputLine.AddAdaptedOutput(gwLevelOutput2); gwLevelOutput2.AddConsumer(riverGwleveInput); } } //========== Run ========== // Validate riverModel.Validate(); Assert.IsTrue(riverModel.Status == LinkableComponentStatus.Valid); gwModel.Validate(); Assert.IsTrue(gwModel.Status == LinkableComponentStatus.Valid); // Prepare riverModel.Prepare(); Assert.IsTrue(riverModel.Status == LinkableComponentStatus.Updated); gwModel.Prepare(); Assert.IsTrue(gwModel.Status == LinkableComponentStatus.Updated); // specify query times double triggerTime0 = riverModel.CurrentTime.StampAsModifiedJulianDay; double triggerTime1 = triggerTime0 + 1; double triggerTime2 = triggerTime0 + 2; double triggerTime3 = triggerTime0 + 12.1; double triggerTime4 = triggerTime0 + 16.7; /// Properties of the river, without gw-level input /// Inflow into each node from rainfall runoff is 10 L/s /// Inflow to node 1: 10 L/s - leaking 5 L/s on branch 1 /// Inflow to node 2: 10 + 5 L/s - leaking 15/2 L/s on branch 2 /// Inflow to node 3: 10 + 15/2 L/s - leaking 35/4 L/s on branch 3 /// Total leakage 5+15/2+35/4 = (20+30+35)/4 = 85/4 L/s /// /// Number of seconds in a day: 60*60*24 = 86400 // check initial values Assert.AreEqual(1, ValueSet.GetElementCount(flowOnBranch.Values), "#values for " + flowOnBranch.Id); Assert.AreEqual(7.0, (double)flowOnBranch.Values.GetValue(0, 0), "Value[0] as property"); Assert.AreEqual(gwGridSize, ValueSet.GetElementCount(storageInGw.Values), "#values for " + storageInGw.Id); Assert.AreEqual(0, SumTimeStep(storageInGw.Values, 0)); // get values for specified query times, 1 days // Totally leaking: 86400 * 85/4 = 1.836e6 // For the bi-directional coupling: // the entire first day the river uses extrapolated values from the // gwModel, which gives a gwLevel of -10, hence same value as for the uni-directional queryDischargeItem.TimeSet.SetSingleTimeStamp(triggerTime1); ITimeSpaceValueSet valuesV = storageInGw2.GetValues(queryDischargeItem); ITimeSpaceValueSet valuesQ = flowOnBranch2.GetValues(queryDischargeItem); Assert.AreEqual(35.0 / 4.0, (double)valuesQ.GetValue(0, 0)); Assert.AreEqual(1.836e6, SumTimeStep(valuesV, 0), 1e-4); // Print out, to load in a plotting program for verification //StringBuilder b = new StringBuilder(); //foreach (double val in valuesV.GetElementValuesForTime(0)) // b.AppendLine(val.ToString(NumberFormatInfo.InvariantInfo)); //Console.Out.WriteLine(b.ToString()); // get values for specified query times, 2 days // 2 * 86400 * 85/4 = 3.672e6 queryDischargeItem.TimeSet.SetSingleTimeStamp(triggerTime2); valuesV = storageInGw2.GetValues(queryDischargeItem); valuesQ = flowOnBranch2.GetValues(queryDischargeItem); if ((runNumber & 4) != 4) // unidirectional { Assert.AreEqual(35.0 / 4.0, (double)valuesQ.GetValue(0, 0)); Assert.AreEqual(3.672e6, SumTimeStep(valuesV, 0), 1e-4); } else if ((runNumber & 2) != 2) // bi-directional 2x2 grid { Assert.AreEqual(8.843648, (double)valuesQ.GetValue(0, 0), 1e-4); Assert.AreEqual(3.66390879366e6, SumTimeStep(valuesV, 0), 1e-4); } else // bi-directional 16x16 grid { Assert.AreEqual(9.65307, (double)valuesQ.GetValue(0, 0), 1e-4); Assert.AreEqual(3.59397465219e6, SumTimeStep(valuesV, 0), 1e-4); } // get values for specified query times, 12.1 days // 12.1 * 86400 * 85/4 = 2.22156e7 queryDischargeItem.TimeSet.SetSingleTimeStamp(triggerTime3); valuesV = storageInGw2.GetValues(queryDischargeItem); valuesQ = flowOnBranch2.GetValues(queryDischargeItem); if ((runNumber & 4) != 4) // unidirectional { Assert.AreEqual(35.0 / 4.0, (double)valuesQ.GetValue(0, 0)); Assert.AreEqual(2.22156e7, SumTimeStep(valuesV, 0), 1e-4); } else if ((runNumber & 2) != 2) // bi-directional 2x2 grid { Assert.AreEqual(9.87828, (double)valuesQ.GetValue(0, 0), 1e-4); Assert.AreEqual(2.16704019338e7, SumTimeStep(valuesV, 0), 1e-4); } else // bi-directional 16x16 grid { Assert.AreEqual(18.546999, (double)valuesQ.GetValue(0, 0), 1e-4); Assert.AreEqual(1.722400002557e7, SumTimeStep(valuesV, 0), 1e-4); } // get values for specified query times, 16.7 days // 16.7 * 86400 * 85/4 = 3.06612e7 queryDischargeItem.TimeSet.SetSingleTimeStamp(triggerTime4); valuesV = storageInGw2.GetValues(queryDischargeItem); valuesQ = flowOnBranch2.GetValues(queryDischargeItem); if ((runNumber & 4) != 4) // unidirectional { Assert.AreEqual(35.0 / 4.0, (double)valuesQ.GetValue(0, 0)); Assert.AreEqual(3.06612e7, SumTimeStep(valuesV, 0), 1e-4); } else if ((runNumber & 2) != 2) // bi-directional 2x2 grid { Assert.AreEqual(10.255535, (double)valuesQ.GetValue(0, 0), 1e-4); Assert.AreEqual(2.9595872035072e7, SumTimeStep(valuesV, 0), 1e-4); } else // bi-directional 16x16 grid { Assert.AreEqual(20.98699, (double)valuesQ.GetValue(0, 0), 1e-4); Assert.AreEqual(2.12991179998e7, SumTimeStep(valuesV, 0), 1e-4); } } }
public void GetValues2A() { //TODO: 1: The RiverModelEngine should change the inflow over time. As it is now the inflow is the same // in all time steps. Another idea would be to have a output exchange item that hold the accumulated // inflow, this could be useful when testing the manage state interface. // // 2: Make this test run with the two river using different timesteps and with the source river // starting ealier that the target river. // // 3: In this test also events could be tested. Simply test if all the required events are // thrown during the simulations. ITimeSpaceComponent upperRiver = CreateRiverModel(); ITimeSpaceComponent lowerRiver = CreateRiverModel(); // The ModelID is passed in order to make it easier to debug, otherwise you cannot se the difference between the two istances of RiverModelLC List <IArgument> upperRiverArguments = CreateRiverModelArguments(upperRiver); upperRiverArguments.Add(Argument.Create("ModelID", "upperRiverModel", true, "argument")); upperRiverArguments.Add(new ArgumentBool("flowItemsAsSpan", false)); upperRiver.Arguments.ApplyArguments(upperRiverArguments); upperRiver.Initialize(); // The ModelID is passed in order to make it easier to debug, otherwise you cannot se the difference between the two istances of RiverModelLC List <IArgument> lowerRiverArguments = CreateRiverModelArguments(lowerRiver); lowerRiverArguments.Add(Argument.Create("ModelID", "lowerRiverModel", true, "argument")); lowerRiverArguments.Add(new ArgumentBool("flowItemsAsSpan", false)); lowerRiver.Initialize(lowerRiverArguments); Assert.AreEqual("upperRiverModel", upperRiver.Id); Assert.AreEqual("lowerRiverModel", lowerRiver.Id); // Link upper river outflow to lower river inflow IBaseOutput upperRiverOutput = upperRiver.Outputs[2]; IBaseInput lowerRiverInput = lowerRiver.Inputs[0]; upperRiverOutput.AddConsumer(lowerRiverInput); // Link some lower river output item to the 'triggering' query item // Put a time interpolator in between, to take care that any required time stamp can be provided ITimeSpaceOutput flowOnBranch = UTHelper.FindOutputItem(lowerRiver, "Branch:2:Flow"); IAdaptedOutputFactory adaptedOutputFactory = lowerRiver.AdaptedOutputFactories[0]; IIdentifiable[] adaptedOutputIds = adaptedOutputFactory.GetAvailableAdaptedOutputIds(flowOnBranch, _queryItem1); ITimeSpaceAdaptedOutput adaptedOutput = (ITimeSpaceAdaptedOutput) adaptedOutputFactory.CreateAdaptedOutput(adaptedOutputIds[0], flowOnBranch, _queryItem1); adaptedOutput.AddConsumer(_queryItem1); // Connections have been established, validate and prepare the models lowerRiver.Validate(); Assert.IsTrue(lowerRiver.Status == LinkableComponentStatus.Valid); lowerRiver.Prepare(); Assert.IsTrue(lowerRiver.Status == LinkableComponentStatus.Updated); upperRiver.Validate(); Assert.IsTrue(upperRiver.Status == LinkableComponentStatus.Valid); upperRiver.Prepare(); Assert.IsTrue(upperRiver.Status == LinkableComponentStatus.Updated); // check initial values Assert.AreEqual(1, flowOnBranch.Values.Values2D[0].Count, "#values for " + flowOnBranch.Id); Assert.AreEqual(7.0, (double)flowOnBranch.Values.GetValue(0, 0), "Value[0] as property"); // specify query times double firstTriggerGetValuesTime = ((LinkableEngine)lowerRiver).CurrentTime.StampAsModifiedJulianDay; double secondTriggerGetValuesTime = firstTriggerGetValuesTime + 3; double thirdTriggerGetValuesTime = firstTriggerGetValuesTime + 4.3; // check initial values Assert.AreEqual(1, flowOnBranch.Values.Values2D[0].Count, "#values for " + flowOnBranch.Id); Assert.AreEqual(7.0, (double)flowOnBranch.Values.GetValue(0, 0), "Value[0] as property"); // get values for specified query times, same as initial time, therefor intial values _queryItem1.TimeSet.SetSingleTimeStamp(firstTriggerGetValuesTime); ITimeSpaceValueSet values = adaptedOutput.GetValues(_queryItem1); Assert.AreEqual(7.0, values.GetValue(0, 0), "value for first query time"); // upper river provides 35/4 inflow to lower river. Lower river last branch flow: // 35/4 (from own runoff) + 35/4/8 (from first node inflow) = 315/32 _queryItem1.TimeSet.SetSingleTimeStamp(secondTriggerGetValuesTime); values = adaptedOutput.GetValues(_queryItem1); Assert.AreEqual(315.0 / 32.0, values.GetValue(0, 0), "value for second query time"); // upper river provides 35/4 inflow to lower river. Lower river last branch flow: // 35/4 (from own runoff) + 35/4/8 (from first node inflow) = 315/32 _queryItem1.TimeSet.SetSingleTimeStamp(thirdTriggerGetValuesTime); values = adaptedOutput.GetValues(_queryItem1); Assert.AreEqual(315.0 / 32.0, values.GetValue(0, 0), "value for third query time"); upperRiver.Finish(); lowerRiver.Finish(); }
private void RunGetValues2CTest(bool inputTimesAsSpans, bool storeValuesInItems) { ITimeSpaceComponent timeSeries = new TimeSeriesComponent(); ITimeSpaceComponent upperRiver = CreateRiverModel(); ITimeSpaceComponent lowerRiver = CreateRiverModel(); _flowItemsAsSpan = true; timeSeries.Initialize(); IArgument flowAsStampsArgument = new ArgumentBool("flowItemsAsSpan", inputTimesAsSpans); IArgument storeInItemsArgument = new ArgumentBool("storeValuesInExchangeItems", storeValuesInItems); // The ModelID is passed in order to make it easier to debug, otherwise you cannot se the difference between the two istances of RiverModelLC List <IArgument> upperRiverArguments = CreateRiverModelArguments(upperRiver); upperRiverArguments.Add(Argument.Create("ModelID", "upperRiverModel", true, "argument")); upperRiverArguments.Add(flowAsStampsArgument); upperRiverArguments.Add(Argument.Create("TimeStepLength", 21600)); upperRiverArguments.Add(storeInItemsArgument); upperRiver.Arguments.ApplyArguments(upperRiverArguments); upperRiver.Initialize(); // The ModelID is passed in order to make it easier to debug, otherwise you cannot se the difference between the two istances of RiverModelLC List <IArgument> lowerRiverArguments = CreateRiverModelArguments(lowerRiver); lowerRiverArguments.Add(Argument.Create("ModelID", "lowerRiverModel", true, "argument")); lowerRiverArguments.Add(flowAsStampsArgument); lowerRiverArguments.Add(Argument.Create("TimeStepLength", 86400)); lowerRiverArguments.Add(storeInItemsArgument); lowerRiver.Arguments.ApplyArguments(lowerRiverArguments); lowerRiver.Initialize(); Assert.AreEqual("upperRiverModel", upperRiver.Id); Assert.AreEqual("lowerRiverModel", lowerRiver.Id); // Link upper river outflow to lower river inflow IBaseInput upperRiverInput = upperRiver.Inputs[0]; IBaseOutput timeSeriesOutput = timeSeries.Outputs[0]; timeSeriesOutput.AddConsumer(upperRiverInput); // Link upper river outflow to lower river inflow // Put a time interpolator in between, to handle the non equal time steps IBaseOutput upperRiverOutput = upperRiver.Outputs[2]; IBaseInput lowerRiverInput = lowerRiver.Inputs[0]; IAdaptedOutputFactory adaptedOutputFactory = upperRiver.AdaptedOutputFactories[0]; IIdentifiable[] adaptedOutputIds = adaptedOutputFactory.GetAvailableAdaptedOutputIds(upperRiverOutput, lowerRiverInput); ITimeSpaceAdaptedOutput adaptedOutput = (ITimeSpaceAdaptedOutput) adaptedOutputFactory.CreateAdaptedOutput(adaptedOutputIds[0], upperRiverOutput, lowerRiverInput); adaptedOutput.AddConsumer(lowerRiverInput); // Link some lower river output item to the 'triggering' query item // Put a time interpolator in between, to take care that any required time stamp can be provided ITimeSpaceOutput flowOnBranch = UTHelper.FindOutputItem(lowerRiver, "Branch:2:Flow"); adaptedOutputFactory = lowerRiver.AdaptedOutputFactories[0]; adaptedOutputIds = adaptedOutputFactory.GetAvailableAdaptedOutputIds(flowOnBranch, _queryItem1); adaptedOutput = (ITimeSpaceAdaptedOutput) adaptedOutputFactory.CreateAdaptedOutput(adaptedOutputIds[0], flowOnBranch, _queryItem1); adaptedOutput.AddConsumer(_queryItem1); // Connections have been established, validate the models timeSeries.Validate(); Assert.IsTrue(timeSeries.Status == LinkableComponentStatus.Valid); timeSeries.Prepare(); lowerRiver.Validate(); Assert.IsTrue(lowerRiver.Status == LinkableComponentStatus.Valid); lowerRiver.Prepare(); Assert.IsTrue(lowerRiver.Status == LinkableComponentStatus.Updated); upperRiver.Validate(); Assert.IsTrue(upperRiver.Status == LinkableComponentStatus.Valid); upperRiver.Prepare(); Assert.IsTrue(upperRiver.Status == LinkableComponentStatus.Updated); // specify query times double startTime = ((LinkableEngine)lowerRiver).CurrentTime.StampAsModifiedJulianDay; double firstTriggerGetValuesTime = startTime + 12.5; double secondTriggerGetValuesTime = startTime + 16.2; // check initial values Assert.AreEqual(1, flowOnBranch.Values.Values2D[0].Count, "#values for " + flowOnBranch.Id); Assert.AreEqual(7.0, (double)flowOnBranch.Values.GetValue(0, 0), "Value[0] as property"); // get values for specified query times _queryItem1.TimeSet.SetSingleTimeStamp(firstTriggerGetValuesTime); ITimeSpaceValueSet values = adaptedOutput.GetValues(_queryItem1); if (inputTimesAsSpans) { Assert.AreEqual(315.0 / 32.0 + 13.0 / 64.0, values.GetValue(0, 0), "value for second query time"); } else { Assert.AreEqual(10.0546875, values.GetValue(0, 0), "value for second query time"); } _queryItem1.TimeSet.SetSingleTimeStamp(secondTriggerGetValuesTime); values = adaptedOutput.GetValues(_queryItem1); if (inputTimesAsSpans) { Assert.AreEqual(315.0 / 32.0 + 17.0 / 64.0, values.GetValue(0, 0), "value for second query time"); } else { Assert.AreEqual(10.112499999999955, values.GetValue(0, 0), "value for third query time"); } timeSeries.Finish(); upperRiver.Finish(); lowerRiver.Finish(); }
private void RunGetValues2BTest(bool inputTimesAsSpans) { ITimeSpaceComponent timeSeries = new TimeSeriesComponent(); ITimeSpaceComponent upperRiver = CreateRiverModel(); ITimeSpaceComponent lowerRiver = CreateRiverModel(); timeSeries.Initialize(); IArgument flowAsStampsArgument = new ArgumentBool("flowItemsAsSpan", inputTimesAsSpans); // The ModelID is passed in order to make it easier to debug, otherwise you cannot se the difference between the two istances of RiverModelLC List <IArgument> upperRiverArguments = CreateRiverModelArguments(upperRiver); upperRiverArguments.Add(Argument.Create("ModelID", "upperRiverModel", true, "argument")); upperRiverArguments.Add(flowAsStampsArgument); upperRiver.Initialize(upperRiverArguments); // The ModelID is passed in order to make it easier to debug, otherwise you cannot se the difference between the two istances of RiverModelLC List <IArgument> lowerRiverArguments = CreateRiverModelArguments(lowerRiver); lowerRiverArguments.Add(Argument.Create("ModelID", "lowerRiverModel", true, "argument")); lowerRiverArguments.Add(flowAsStampsArgument); lowerRiver.Initialize(lowerRiverArguments); Assert.AreEqual("upperRiverModel", upperRiver.Id); Assert.AreEqual("lowerRiverModel", lowerRiver.Id); // Link upper river inflow to timeseries IBaseInput upperRiverInput = upperRiver.Inputs[0]; IBaseOutput timeSeriesOutput = timeSeries.Outputs[0]; timeSeriesOutput.AddConsumer(upperRiverInput); // Link upper river outflow to lower river inflow IBaseOutput upperRiverOutput = upperRiver.Outputs[2]; IBaseInput lowerRiverInput = lowerRiver.Inputs[0]; upperRiverOutput.AddConsumer(lowerRiverInput); // Link some lower river output item to the 'triggering' query item // Put a time interpolator in between, to take care that any required time stamp can be provided ITimeSpaceOutput flowOnBranch = UTHelper.FindOutputItem(lowerRiver, "Branch:2:Flow"); IAdaptedOutputFactory adaptedOutputFactory = lowerRiver.AdaptedOutputFactories[0]; IIdentifiable[] adaptedOutputIds = adaptedOutputFactory.GetAvailableAdaptedOutputIds(flowOnBranch, _queryItem1); ITimeSpaceAdaptedOutput adaptedOutput = (ITimeSpaceAdaptedOutput) adaptedOutputFactory.CreateAdaptedOutput(adaptedOutputIds[0], flowOnBranch, _queryItem1); adaptedOutput.AddConsumer(_queryItem1); // Connections have been established, validate the models timeSeries.Validate(); Assert.IsTrue(timeSeries.Status == LinkableComponentStatus.Valid); timeSeries.Prepare(); lowerRiver.Validate(); Assert.IsTrue(lowerRiver.Status == LinkableComponentStatus.Valid); lowerRiver.Prepare(); Assert.IsTrue(lowerRiver.Status == LinkableComponentStatus.Updated); upperRiver.Validate(); Assert.IsTrue(upperRiver.Status == LinkableComponentStatus.Valid); upperRiver.Prepare(); Assert.IsTrue(upperRiver.Status == LinkableComponentStatus.Updated); // specify query times double startTime = ((LinkableEngine)lowerRiver).CurrentTime.StampAsModifiedJulianDay; double firstTriggerGetValuesTime = startTime + 12.5; double secondTriggerGetValuesTime = startTime + 16.2; // check initial values Assert.AreEqual(1, flowOnBranch.Values.Values2D[0].Count, "#values for " + flowOnBranch.Id); Assert.AreEqual(7.0, (double)flowOnBranch.Values.GetValue(0, 0), "Value[0] as property"); // get values for specified query times, 12.5 days after 01-01 (13 L/s inflow from timeseries) // Upper river provides 35/4 (runoff) + 13/8) to lower river // Lower river last branch flow: 35/4 (own runoff) + 35/4/8 (upper runoff) + 13/8/8 (upper inflow) = 315/32 + 13/64 _queryItem1.TimeSet.SetSingleTimeStamp(firstTriggerGetValuesTime); ITimeSpaceValueSet values = adaptedOutput.GetValues(_queryItem1); if (inputTimesAsSpans) { Assert.AreEqual(315.0 / 32.0 + 13.0 / 64.0, values.GetValue(0, 0), "value for second query time"); } else { double vala = 315.0 / 32.0 + 13.0 / 64.0; // value at 12/01 double valb = 315.0 / 32.0 + 14.0 / 64.0; // value at 13/01 double val = 0.5 * vala + 0.5 * valb; // interpolate Assert.AreEqual(val, values.GetValue(0, 0), "value for second query time"); } // get values for specified query times, 16.2 days after 01-01 (17 L/s inflow from timeseries) // Upper river provides 35/4 (runoff) + 17/8) to lower river // Lower river last branch flow: 35/4 (own runoff) + 35/4/8 (upper runoff) + 17/8/8 (upper inflow) = 315/32 + 17/64 _queryItem1.TimeSet.SetSingleTimeStamp(secondTriggerGetValuesTime); values = adaptedOutput.GetValues(_queryItem1); if (inputTimesAsSpans) { Assert.AreEqual(315.0 / 32.0 + 17.0 / 64.0, values.GetValue(0, 0), "value for third query time"); } else { double vala = 315.0 / 32.0 + 17.0 / 64.0; // value at 16/01 double valb = 315.0 / 32.0 + 18.0 / 64.0; // value at 17/01 double val = 0.8 * vala + 0.2 * valb; // interpolate Assert.AreEqual(val, (double)values.GetValue(0, 0), 1e-10, "value for third query time"); } timeSeries.Finish(); upperRiver.Finish(); lowerRiver.Finish(); }