Beispiel #1
0
        /// <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);
        }
Beispiel #2
0
 /// <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));
     }
 }
Beispiel #3
0
        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;
            }
        }
Beispiel #4
0
        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];
            }
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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];
                    }
                }
            }
Beispiel #10
0
        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);
            }
        }
Beispiel #11
0
 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");
     }
 }
Beispiel #12
0
        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);
            }
        }
Beispiel #13
0
        [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));
     }
 }