/// <summary> /// Returns an array of T's from the <paramref name="values"/>, extracting /// data from the <paramref name="timeIndex"/> - in principle a typed version /// of <see cref="ITimeSpaceValueSet.GetElementValuesForTime"/> returning /// an array. /// </summary> /// <example> /// <code> /// ITimeSpaceValueSet values = ... /// double[] doubleArray = values.GetElementValuesForTime<double>(0); /// </code> /// </example> /// <param name="values">Values to retrieve</param> /// <param name="timeIndex">Index to retrieve data from.</param> /// <returns>Array of T</returns> public static T[] GetElementValuesForTime <T>(this ITimeSpaceValueSet values, int timeIndex) { IList elmtValues = values.GetElementValuesForTime(timeIndex); // Check if it is already an array T[] tArray = elmtValues as T[]; if (tArray != null) { return(tArray); } // Check if it is a generic list, and use C# build in extension method IList <T> tList = elmtValues as IList <T>; if (tList != null) { return(tList.ToArray()); } // Do a manual copy (an IList which is not an IList<T>) tArray = new T[elmtValues.Count]; for (int i = 0; i < elmtValues.Count; i++) { tArray[i] = (T)elmtValues[i]; } return(tArray); }
/// <summary> /// MapValues calculates for each set of timestep data /// a resulting IValueSet through multiplication of an inputValues IValueSet /// vector with the mapping maprix. /// <para> /// This version can be used if the output value set is to be reused (performance or for /// adding up) /// </para> /// </summary> /// <param name="outputValues">IValueset of mapped values, of the correct size</param> /// <param name="inputValues">IValueSet of values to be mapped.</param> public void MapValues(ref ITimeSpaceValueSet <double> outputValues, ref ITimeSpaceValueSet inputValues) { for (int i = 0; i < inputValues.Values2D.Count; i++) { _mappingMatrix.Product(outputValues.Values2D[i], inputValues.GetElementValuesForTime <double>(i)); } }
public void SetValues(ITimeSpaceValueSet values) { double invScaleFactor = 1.0 / _scaleFactor; // Assuming elsewhere is taken care of that the sizes are correct. IList elementValues = values.GetElementValuesForTime(0); for (int i = 0; i < _vector.Count; i++) { _vector[i] = ((double)elementValues[i]) * invScaleFactor; } }
public void SetValues(ITimeSpaceValueSet values) { // Assuming elsewhere is taken care of that the sizes are correct. // i.e. one time step and same number of elements IList elementValues = values.GetElementValuesForTime(0); for (int i = 0; i < _vector.Count; i++) { _vector[i] = (T)elementValues[i]; } }
private static double SumTimeStep(ITimeSpaceValueSet values, int timestepIndex) { IList <double> vals = (IList <double>)values.GetElementValuesForTime(timestepIndex); double sum = 0; foreach (double d in vals) { sum += d; } return(sum); }
private void AddInflow(ITimeSpaceValueSet values) { // values are numberOfNodes-1 long (input for each branch. // Put inflow at "upstream" node/storage IList elementValues = values.GetElementValuesForTime(0); for (int i = 0; i < _inflowStorage.Length - 1; i++) { _inflowStorage[i] += ((double)elementValues[i]) * _timeStepLengthInSeconds; } }
/// <summary> /// Adds the content of the source values to the target values. Assumes the two /// are equally big. /// </summary> /// <param name="targetValues">Target set, where values are added to</param> /// <param name="sourceValues">Source set, containing values to add</param> private static void AddSourceToTarget(ITimeSpaceValueSet <double> targetValues, ITimeSpaceValueSet sourceValues) { for (int i = 0; i < targetValues.TimesCount(); i++) { double[] sourceTimeValues = sourceValues.GetElementValuesForTime <double>(i); IList <double> targetTimeValues = targetValues.Values2D[i]; for (int j = 0; j < targetValues.ElementCount(); j++) { targetTimeValues[j] += sourceTimeValues[j]; } } }
private void CheckBuffer() { if (_buffer == null) { _buffer = new SmartBuffer(); ITimeSpaceValueSet outputItemValues = _adaptee.Values; IList <ITime> outputItemTimes = _adaptee.TimeSet.Times; for (int t = 0; t < outputItemTimes.Count; t++) { ITime time = outputItemTimes[t]; _buffer.AddValues(time, outputItemValues.GetElementValuesForTime(0)); } } }
public void GetValues(ITimeSpaceValueSet <double> targetSet, IBaseExchangeItem querySpecifier) { // Copy values from the adaptee to the targetSet ITimeSpaceValueSet sourceValues = _adaptee.GetValues(querySpecifier); for (int i = 0; i < targetSet.TimesCount(); i++) { double[] sourceTimeValues = sourceValues.GetElementValuesForTime <double>(i); for (int j = 0; j < targetSet.ElementCount(); j++) { targetSet.Values2D[i][j] += sourceTimeValues[j]; } } }
private void AddNewValuesToBuffer() { ITimeSpaceValueSet decoratedOutputItemValues = (ITimeSpaceValueSet)Adaptee.Values; if (decoratedOutputItemValues == null) { throw new Exception("AdaptedOutput \"" + Id + "\" did not receive values from Decorated OutputItem \"" + Adaptee.Id + "\""); } for (int t = 0; t < _adaptee.TimeSet.Times.Count; t++) { ITime time = _adaptee.TimeSet.Times[t]; IList elementSetValues = decoratedOutputItemValues.GetElementValuesForTime(t); _buffer.SetOrAddValues(time, elementSetValues); } }
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"); } }
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); } }
[Test] // testing the Initialise method public void MapValues() { ElementSet gridElementSet = new ElementSet("RegularGrid", "RegularGrid", ElementType.Polygon); ElementSet fourPointsElementSet = new ElementSet("4 points", "4P", ElementType.Point); Coordinate v_0_20 = new Coordinate(0, 20, 0); Coordinate v_0_10 = new Coordinate(0, 10, 0); Coordinate v_0_0 = new Coordinate(0, 0, 0); Coordinate v_5_15 = new Coordinate(5, 15, 0); Coordinate v_10_20 = new Coordinate(10, 20, 0); Coordinate v_10_15 = new Coordinate(10, 15, 0); Coordinate v_10_10 = new Coordinate(10, 10, 0); Coordinate v_10_0 = new Coordinate(10, 0, 0); Coordinate v_15_15 = new Coordinate(15, 15, 0); Coordinate v_15_5 = new Coordinate(15, 5, 0); Coordinate v_20_20 = new Coordinate(20, 20, 0); Coordinate v_20_10 = new Coordinate(20, 10, 0); Element square1 = new Element("square1"); Element square2 = new Element("square2"); Element square3 = new Element("square3"); square1.AddVertex(v_0_20); square1.AddVertex(v_0_10); square1.AddVertex(v_10_10); square1.AddVertex(v_10_20); square2.AddVertex(v_10_20); square2.AddVertex(v_10_10); square2.AddVertex(v_20_10); square2.AddVertex(v_20_20); square3.AddVertex(v_0_10); square3.AddVertex(v_0_0); square3.AddVertex(v_10_0); square3.AddVertex(v_10_10); gridElementSet.AddElement(square1); gridElementSet.AddElement(square2); gridElementSet.AddElement(square3); Element point_5_15 = new Element("point 5, 15"); Element point_10_15 = new Element("point 10, 15"); Element point_15_15 = new Element("point 15, 15"); Element point_15_5 = new Element("point 15, 5"); point_5_15.AddVertex(v_5_15); point_10_15.AddVertex(v_10_15); point_15_15.AddVertex(v_15_15); point_15_5.AddVertex(v_15_5); fourPointsElementSet.AddElement(point_5_15); fourPointsElementSet.AddElement(point_10_15); fourPointsElementSet.AddElement(point_15_15); fourPointsElementSet.AddElement(point_15_5); ElementMapper elementMapper = new ElementMapper(); // point to polygon IIdentifiable[] methods = SpatialAdaptedOutputFactory.GetAvailableMethods(fourPointsElementSet.ElementType, gridElementSet.ElementType); elementMapper.Initialise(methods[0], fourPointsElementSet, gridElementSet); IList values = new List <double>(); values.Add(0d); values.Add(10d); values.Add(20d); values.Add(30d); ITimeSpaceValueSet fourPointsScalarSet = new ValueSet(new List <IList> { values }); ITimeSpaceValueSet gridScalarSet = elementMapper.MapValues(fourPointsScalarSet); IList elementValuesForTime = gridScalarSet.GetElementValuesForTime(0); Assert.AreEqual(5, elementValuesForTime[0]); Assert.AreEqual(20, elementValuesForTime[1]); Assert.AreEqual(0, elementValuesForTime[2]); // polygon to point methods = SpatialAdaptedOutputFactory.GetAvailableMethods(gridElementSet.ElementType, fourPointsElementSet.ElementType); elementMapper.Initialise(methods[0], gridElementSet, fourPointsElementSet); fourPointsScalarSet = elementMapper.MapValues(gridScalarSet); elementValuesForTime = fourPointsScalarSet.GetElementValuesForTime(0); Assert.AreEqual(5, elementValuesForTime[0]); Assert.AreEqual(5, elementValuesForTime[1]); Assert.AreEqual(20, elementValuesForTime[2]); Assert.AreEqual(0, elementValuesForTime[3]); }
/// <summary> /// MapValues calculates for each set of timestep data /// a resulting IValueSet through multiplication of an inputValues IValueSet /// vector with the mapping maprix. /// <para> /// This version can be used if the output value set is to be reused (performance or for /// adding up) /// </para> /// </summary> /// <param name="outputValues">IValueset of mapped values, of the correct size</param> /// <param name="inputValues">IValueSet of values to be mapped.</param> public void MapValues(ITimeSpaceValueSet<double> outputValues, ITimeSpaceValueSet inputValues) { for (int i = 0; i < inputValues.Values2D.Count; i++) { _mappingMatrix.Product(outputValues.Values2D[i], inputValues.GetElementValuesForTime<double>(i)); } }