public void GroundWaterTest()
    {
      WaterPacket GroundWater = new WaterPacket(1);
//      GroundWater.AddChemical(ChemicalFactory.Instance.GetChemical(ChemicalNames.Radon), 0.01);
      GroundWater.IDForComposition = 4;

      Lake Vedsted= LakeFactory.GetLake("Vedsted Sø");
      Vedsted.Depth = 5;
      Vedsted.WaterLevel = 45.7;

      //Create and add a discharge boundary
      TimestampSeries Discharge = new TimestampSeries();
      Discharge.AddSiValue(new DateTime(2007, 3, 12), 6986 / TimeSpan.FromDays(365).TotalSeconds);
      Discharge.AddSiValue(new DateTime(2007, 4, 3), 5894 / TimeSpan.FromDays(365).TotalSeconds);
      Discharge.AddSiValue(new DateTime(2007, 4, 25), 1205 / TimeSpan.FromDays(365).TotalSeconds);
      Discharge.RelaxationFactor = 1;
      Discharge.AllowExtrapolation = true;
      Assert.AreEqual(Discharge.GetValue(new DateTime(2007, 4, 25)), Discharge.GetValue(new DateTime(2007, 6, 25)), 0.0000001);
      SinkSourceBoundary Kilde = new SinkSourceBoundary(Discharge);
      Kilde.Name = "Small spring";
      Kilde.ID = 3;
      Kilde.WaterSample.IDForComposition = 3;
      Vedsted.Sources.Add(Kilde);


      Vedsted.Output.LogAllChemicals = true;
      Vedsted.Output.LogComposition = true;

      //Add to an engine
      Model Engine = new Model();
      Engine.Name = "Vedsted-opsætning";
      Engine._waterBodies.Add(Vedsted);

      //Set initial state
      WaterPacket InitialStateWater = new WaterPacket(1);
      InitialStateWater.IDForComposition = 1;
      DateTime Start = new DateTime(2007, 1, 1);
      DateTime End = new DateTime(2007, 12, 31);
      Engine.SetState("Initial", Start, InitialStateWater);
      Engine.SimulationEndTime = End;
      Engine.TimeStep = TimeSpan.FromDays(30);

      Engine.MoveInTime(End, TimeSpan.FromDays(30));
      Vedsted.Name = "Vedsted step 1";
      Engine.Save(testDataPath + Vedsted.Name + ".xml");
      Engine.RestoreState("Initial");

      //Create and add precipitation boundary
      TimespanSeries Precipitation = new TimespanSeries();
      Precipitation.ExtrapolationMethod = ExtrapolationMethods.RecycleYear;
      Precipitation.AllowExtrapolation = true;
      double[] values = new double[] { 108, 83, 73, 52, 61, 86, 99, 101, 75, 108, 85, 101 };
      AddMonthlyValues(Precipitation, 2007, values);
      SinkSourceBoundary Precip = new SinkSourceBoundary(Precipitation);
      Precip.ContactGeometry = Vedsted.SurfaceArea;
      Precip.Name = "Precipitation";
      Precip.ID = 2;
      Precip.WaterSample.IDForComposition = 2;
      Vedsted.Precipitation.Add(Precip);

      //Create and add evaporation boundary
      TimespanSeries Evaporation = new TimespanSeries();
      Evaporation.AllowExtrapolation = true;
      Evaporation.ExtrapolationMethod = ExtrapolationMethods.RecycleYear;
      double[] values2 = new double[] {4,11,34,66,110,118,122,103,61,26,7,1 };
      AddMonthlyValues(Evaporation, 2007, values2);
      EvaporationRateBoundary eva = new EvaporationRateBoundary(Evaporation);
      eva.ContactGeometry = Vedsted.SurfaceArea;
      eva.Name = "Evapo";
      
      Vedsted.EvaporationBoundaries.Add(eva);

      Engine.MoveInTime(End, TimeSpan.FromDays(30));
      Vedsted.Name = "Vedsted step 2";
      Engine.Save(testDataPath + Vedsted.Name + ".xml");
      Engine.RestoreState("Initial");


      //To be used by other tests
      Engine.Save(testDataPath + "VedstedNoGroundwater.xml");

      XYPolygon ContactArea = XYPolygon.GetSquare(Vedsted.Area/10);

      #region Groundwater boundaries
      //Add groundwater boundaries
      GroundWaterBoundary B1 = new GroundWaterBoundary(Vedsted, 1.3e-4, 1, 45.47, ContactArea);
      B1.Name = "B1";
      B1.ID = 4;
      B1.WaterSample = GroundWater;
      Vedsted.GroundwaterBoundaries.Add(B1);

      GroundWaterBoundary B2 = new GroundWaterBoundary(Vedsted, 1e-6, 1, 44.96, ContactArea);
      B2.Name = "B2";
      B2.ID = 5;
      B2.WaterSample = GroundWater;
      Vedsted.GroundwaterBoundaries.Add(B2);

      GroundWaterBoundary B3 = new GroundWaterBoundary(Vedsted, 2e-6, 1, 44.63, ContactArea);
      B3.Name = "B3";
      B3.ID = 6;
      B3.WaterSample = GroundWater;
      Vedsted.GroundwaterBoundaries.Add(B3);

      GroundWaterBoundary B4 = new GroundWaterBoundary(Vedsted, 4.9e-7, 1, 44.75, ContactArea);
      B4.Name = "B4";
      B4.ID = 7;
      B4.WaterSample = GroundWater;
      Vedsted.GroundwaterBoundaries.Add(B4);

      GroundWaterBoundary B5 = new GroundWaterBoundary(Vedsted, 1.5e-8, 1, 44.27, ContactArea);
      B5.Name = "B5";
      B5.ID = 8;
      B5.WaterSample = GroundWater;
      Vedsted.GroundwaterBoundaries.Add(B5);

      GroundWaterBoundary B6 = new GroundWaterBoundary(Vedsted, 1.5e-8, 1, 44.16, ContactArea);
      B6.Name = "B6";
      B6.ID = 9;
      B6.WaterSample = GroundWater;
      Vedsted.GroundwaterBoundaries.Add(B6);

      GroundWaterBoundary B7 = new GroundWaterBoundary(Vedsted, 1.1e-6, 1, 45.15, ContactArea);
      B7.Name = "B7";
      B7.ID = 10;
      B7.WaterSample = GroundWater;
      Vedsted.GroundwaterBoundaries.Add(B7);

      GroundWaterBoundary B8 = new GroundWaterBoundary(Vedsted, 1.1e-6, 1, 44.54, ContactArea);
      B8.Name = "B8";
      B8.ID = 11;
      B8.WaterSample = GroundWater;
      Vedsted.GroundwaterBoundaries.Add(B8);

      GroundWaterBoundary B9 = new GroundWaterBoundary(Vedsted, 2.1e-8, 1, 45.4, ContactArea);
      B9.Name = "B9";
      B9.ID = 12;
      B9.WaterSample = GroundWater;
      Vedsted.GroundwaterBoundaries.Add(B9);

      GroundWaterBoundary B10 = new GroundWaterBoundary(Vedsted, 3.5e-6, 1, 45.16, ContactArea);
      B10.Name = "B10";
      B10.ID = 13;
      B10.WaterSample = GroundWater;
      Vedsted.GroundwaterBoundaries.Add(B10);

      #endregion

      Engine.MoveInTime(End, TimeSpan.FromDays(30));
      Vedsted.Name = "Vedsted step 3";
      Engine.Save(testDataPath + Vedsted.Name + ".xml");
      Engine.RestoreState("Initial");

      Vedsted.GroundwaterBoundaries.Clear();

      var cl =ChemicalFactory.Instance.GetChemical(ChemicalNames.IsotopeFraction);

      GroundWaterBoundary Inflow = new GroundWaterBoundary(Vedsted, 1e-7,1,46.7,XYPolygon.GetSquare(Vedsted.Area/2));
      Inflow.Name = "Inflow";
      GroundWater.AddChemical(cl, 3);
      Inflow.WaterSample = GroundWater;

      Vedsted.RealData.AddChemicalTimeSeries(cl);
      Vedsted.RealData.ChemicalConcentrations[cl].AddSiValue(new DateTime(2007, 8, 7), 2.5);

      ((WaterPacket)InitialStateWater).AddChemical(cl, 2.5 * InitialStateWater.Volume);
      Engine.SetState("Initial", Start, InitialStateWater);

      GroundWaterBoundary Outflow = new GroundWaterBoundary(Vedsted, 1e-7,1,44.7,XYPolygon.GetSquare(Vedsted.Area/2));
      Outflow.Name = "Outflow";

      Vedsted.GroundwaterBoundaries.Add(Inflow);
      Vedsted.GroundwaterBoundaries.Add(Outflow);

      Engine.MoveInTime(End, TimeSpan.FromDays(30));
      Vedsted.Name = "Vedsted step 4";
      Engine.Save(testDataPath + Vedsted.Name + ".xml");
      Engine.RestoreState("Initial");



      #region ////Add seepage meter boundaries
      //GroundWaterBoundary S1 = new GroundWaterBoundary(Vedsted, 4e-5, 1, 2, 46);
      //Vedsted.SinkSources.Add(S1);
      //GroundWaterBoundary S2 = new GroundWaterBoundary(Vedsted, 4e-5, 1, 2, 46);
      //Vedsted.SinkSources.Add(S2);
      //GroundWaterBoundary S3 = new GroundWaterBoundary(Vedsted, 4e-5, 1, 2, 46);
      //Vedsted.SinkSources.Add(S3);
      //GroundWaterBoundary I1 = new GroundWaterBoundary(Vedsted, 4e-5, 1, 2, 46);
      //Vedsted.SinkSources.Add(I1);
      //GroundWaterBoundary I2 = new GroundWaterBoundary(Vedsted, 4e-5, 1, 2, 46);
      //Vedsted.SinkSources.Add(I2);
      //GroundWaterBoundary I3 = new GroundWaterBoundary(Vedsted, 4e-5, 1, 2, 46);
      //Vedsted.SinkSources.Add(I3);

#endregion


      Assert.AreEqual(Evaporation.EndTime, Engine.MaximumEndTime);
      Engine.Save(testDataPath + "Vedsted.xml");

      Engine.MoveInTime(End, TimeSpan.FromDays(30));

      double outflow2 = Vedsted.Output.Outflow.GetValue(Start, End.Subtract(TimeSpan.FromDays(5)));
      double evapo2 = Vedsted.Output.Evaporation.GetValue(Start, End.Subtract(TimeSpan.FromDays(5)));

      Engine.Save(testDataPath + "Vedsted2.xml");

    }
 public void GetValue04()  //GetValue(DateTime fromTime, DateTime toTime, Unit toUnit)
 {
     TimestampSeries timestampSeries = new TimestampSeries();
     timestampSeries.Items.Add(new TimestampValue(new DateTime(2010, 1, 1, 0, 0, 0), 3000.0));
     timestampSeries.Unit = new HydroNumerics.Core.Unit("Liters pr. second", 0.001, 0.0);
     HydroNumerics.Core.Unit toUnit = new HydroNumerics.Core.Unit("Hectoliters pr sec", 0.1, 0.0);
     Assert.AreEqual(30.0, timestampSeries.GetValue(new DateTime(2010, 1, 2, 0, 0, 0), new DateTime(2010, 1, 3, 0, 0, 0), toUnit));
 }
        public void Getvalue3()
        {
            TimestampSeries ts = new TimestampSeries("Test", new DateTime(1999, 1, 1), 400, 1, TimestepUnit.Days, 0);
            ts.ExtrapolationMethod = ExtrapolationMethods.RecycleYear;
            ts.AllowExtrapolation = true;
            for (int i = 0; i < ts.Items.Count; i++)
            {
                ts.Items[i].Value = i;
            }

            Assert.AreEqual(7, ts.GetValue(new DateTime(1999, 1, 8)));
            Assert.AreEqual(7, ts.GetValue(new DateTime(1995, 1, 8)));
            Assert.AreEqual(365 + 7, ts.GetValue(new DateTime(2010, 1, 8)));
            Assert.AreEqual(7.5, ts.GetValue(new DateTime(1995, 1, 8, 12, 0, 0)));

            Assert.AreEqual(7.5, ts.GetValue(new DateTime(1999, 1, 8), new DateTime(1999, 1, 9)));
            Assert.AreEqual(7.5, ts.GetValue(new DateTime(1995, 1, 8), new DateTime(1995, 1, 9)));
            Assert.AreEqual(365 + 7 + 0.5, ts.GetValue(new DateTime(2010, 1, 8), new DateTime(2010, 1, 9)));
            Assert.AreEqual(365 + 8, ts.GetValue(new DateTime(2010, 1, 8), new DateTime(2010, 1, 10)));

        }
        public void GetValue02() // GetValue(DateTime fromTime, DateTime toTime)
        {
            //-- Expected exception when GetValues is invoked on an empty timeseries. --
            TimestampSeries timeSeries = new TimestampSeries();
           
            try
            {
                timeSeries.GetValue(new DateTime(2010, 1, 1, 0, 0, 0), new DateTime(2010, 1, 2, 0, 0, 0));
            }
            catch (Exception ex)
            {
                Assert.IsTrue(ex.GetType() == typeof(Exception));
            }

            timeSeries.Items.Add(new TimestampValue(new DateTime(2010, 1, 1, 0, 0, 0), 3.0));

            //Testing when only one record in timeseries
            Assert.AreEqual(3.0, timeSeries.GetValue(new DateTime(2010, 11, 1, 0, 0, 0), new DateTime(2010, 12, 1, 0, 0, 0)));

            timeSeries.Items.Add(new TimestampValue(new DateTime(2010, 1, 2, 0, 0, 0), 6.0));
            timeSeries.Items.Add(new TimestampValue(new DateTime(2010, 1, 3, 0, 0, 0), 6.0));
            timeSeries.Items.Add(new TimestampValue(new DateTime(2010, 1, 4, 0, 0, 0), 4.0));

            timeSeries.RelaxationFactor = 1.0;

            try
            {
                timeSeries.GetValue(new DateTime(2010, 1, 1, 0, 0, 0), new DateTime(2010, 1, 1, 0, 0, 0));

            }
            catch (Exception ex)
            {
                //Testing invalid argument for timespan
                Assert.IsTrue(ex.GetType() == typeof(Exception));
            }

            try
            {
                timeSeries.GetValue(new DateTime(2010, 1, 2, 0, 0, 0), new DateTime(2010, 1, 1, 0, 0, 0));

            }
            catch (Exception ex)
            {
                //Testing invalid argument for timespan
                Assert.IsTrue(ex.GetType() == typeof(Exception));
            }

            timeSeries.RelaxationFactor = 0.0;

            // v--------------------------------------V
            // |------------|------------|------------|
            // 3            6            6            4 
            Assert.AreEqual(15.5 / 3.0, timeSeries.GetValue(new DateTime(2010, 1, 1, 0, 0, 0), new DateTime(2010, 1, 4, 0, 0, 0))); //interval same as the full timeseries

            //        v-----------v
            // |------------|------------|------------|
            Assert.AreEqual(5.625, timeSeries.GetValue(new DateTime(2010, 1, 1, 12, 0, 0), new DateTime(2010, 1, 2, 12, 0, 0)));

            //        v-------------------------v
            // |------------|------------|------------|
            Assert.AreEqual(11.375 / 2.0, timeSeries.GetValue(new DateTime(2010, 1, 1, 12, 0, 0), new DateTime(2010, 1, 3, 12, 0, 0)));

            //     v----v
            // |------------|------------|------------|
            Assert.AreEqual(4.5, timeSeries.GetValue(new DateTime(2010, 1, 1, 6, 0, 0), new DateTime(2010, 1, 1, 18, 0, 0)));

            // v--------------------------------------------------------------v
            // ------------|------------|------------|------------|------------
            Assert.AreEqual(4.0, timeSeries.GetValue(new DateTime(2009, 12, 31, 0, 0, 0), new DateTime(2010, 1, 5, 0, 0, 0)));  //Extrapolating outside timeseries
        }
        public void GetValue01()  //GetValue(DateTime time)
        {
            TimestampSeries timeSeries = new TimestampSeries();

            try
            {
                timeSeries.GetValue(new DateTime(2010, 1, 1, 0, 0, 0));
            }
            catch (Exception ex)
            {
                //-- Expected exception when GetValues is invoked on an empty timeseries. --
                Assert.IsTrue(ex.GetType() == typeof(Exception));
            }

            //-- When only one record in time series --
            timeSeries.Items.Add(new TimestampValue(new DateTime(2010, 1, 1, 0, 0, 0), 3.0));
            Assert.AreEqual(3.0, timeSeries.GetValue(new DateTime(2011, 1, 1, 0, 0, 0)));
            Assert.AreEqual(3.0, timeSeries.GetValue(new DateTime(2010, 1, 1, 0, 0, 0)));
            Assert.AreEqual(3.0, timeSeries.GetValue(new DateTime(2009, 1, 1, 0, 0, 0)));

            //-- timeseries with two records ---
            timeSeries.Items.Add(new TimestampValue(new DateTime(2010, 1, 2, 0, 0, 0), 6.0));
            timeSeries.RelaxationFactor = 1.0;
            Assert.AreEqual(4.5, timeSeries.GetValue(new DateTime(2010, 1, 1, 12, 0, 0))); //Inbetween
            Assert.AreEqual(3.0, timeSeries.GetValue(new DateTime(2010, 1, 1, 0, 0, 0)));  //Hit first time
            Assert.AreEqual(6.0, timeSeries.GetValue(new DateTime(2010, 1, 2, 0, 0, 0)));  // Hit last time
            Assert.AreEqual(3.0, timeSeries.GetValue(new DateTime(2009, 12, 31, 0, 0, 0)));  // one day before 
            Assert.AreEqual(6.0, timeSeries.GetValue(new DateTime(2010, 1, 3, 0, 0, 0)));  // one day after 
            timeSeries.RelaxationFactor = 0.0;
            Assert.AreEqual(4.5, timeSeries.GetValue(new DateTime(2010, 1, 1, 12, 0, 0))); //Inbetween
            Assert.AreEqual(3.0, timeSeries.GetValue(new DateTime(2010, 1, 1, 0, 0, 0)));  // Hit first time
            Assert.AreEqual(6.0, timeSeries.GetValue(new DateTime(2010, 1, 2, 0, 0, 0)));  // Hit last time
            Assert.AreEqual(0.0, timeSeries.GetValue(new DateTime(2009, 12, 31, 0, 0, 0)));  // one day before 
            Assert.AreEqual(9.0, timeSeries.GetValue(new DateTime(2010, 1, 3, 0, 0, 0)));  // one day after 
            timeSeries.RelaxationFactor = 0.5;
            Assert.AreEqual(4.5, timeSeries.GetValue(new DateTime(2010, 1, 1, 12, 0, 0))); //Inbetween
            Assert.AreEqual(3.0, timeSeries.GetValue(new DateTime(2010, 1, 1, 0, 0, 0)));  // Hit first time
            Assert.AreEqual(6.0, timeSeries.GetValue(new DateTime(2010, 1, 2, 0, 0, 0)));  // Hit last time
            Assert.AreEqual(1.5, timeSeries.GetValue(new DateTime(2009, 12, 31, 0, 0, 0)));  // one day before 
            Assert.AreEqual(7.5, timeSeries.GetValue(new DateTime(2010, 1, 3, 0, 0, 0)));  // one day after

            // -- timeseries with 4 records ---
            timeSeries.Items.Add(new TimestampValue(new DateTime(2010, 1, 3, 0, 0, 0), 6.0));
            timeSeries.Items.Add(new TimestampValue(new DateTime(2010, 1, 4, 0, 0, 0), 4.0));
            timeSeries.RelaxationFactor = 0.0;
            Assert.AreEqual(4.5, timeSeries.GetValue(new DateTime(2010, 1, 1, 12, 0, 0))); //Inbetween
            Assert.AreEqual(6.0, timeSeries.GetValue(new DateTime(2010, 1, 2, 12, 0, 0))); //Inbetween
            Assert.AreEqual(5.0, timeSeries.GetValue(new DateTime(2010, 1, 3, 12, 0, 0))); //Inbetween
            Assert.AreEqual(3.0, timeSeries.GetValue(new DateTime(2010, 1, 1, 0, 0, 0)));  //Hit first time
            Assert.AreEqual(6.0, timeSeries.GetValue(new DateTime(2010, 1, 2, 0, 0, 0)));  // Hit Second
            Assert.AreEqual(6.0, timeSeries.GetValue(new DateTime(2010, 1, 3, 0, 0, 0)));  // Hit third time
            Assert.AreEqual(4.0, timeSeries.GetValue(new DateTime(2010, 1, 4, 0, 0, 0)));  // Hit last time
            Assert.AreEqual(0.0, timeSeries.GetValue(new DateTime(2009, 12, 31, 0, 0, 0)));  // one day before 
            Assert.AreEqual(2.0, timeSeries.GetValue(new DateTime(2010, 1, 5, 0, 0, 0)));  // one day after 
        }
    public void TestMethod1()
    {
      Lake Vedsted = LakeFactory.GetLake("Vedsted Sø");
      Vedsted.Depth = 5;
      Vedsted.WaterLevel = 45.7;
      

      //Create and add precipitation boundary
      TimespanSeries Precipitation = new TimespanSeries();
      double[] values = new double[] { 108, 83, 73, 52, 61, 86, 99, 101, 75, 108, 85, 101 };
      LakeVedsted.AddMonthlyValues(Precipitation, 2007, values);
      SinkSourceBoundary Precip = new SinkSourceBoundary(Precipitation);
      Precip.ContactGeometry = Vedsted.SurfaceArea;
      Vedsted.Sources.Add(Precip);

      //Create and add evaporation boundary
      TimespanSeries Evaporation = new TimespanSeries();
      double[] values2 = new double[] { 4, 11, 34, 66, 110, 118, 122, 103, 61, 26, 7, 1 };
      LakeVedsted.AddMonthlyValues(Evaporation, 2007, values2);
      EvaporationRateBoundary eva = new EvaporationRateBoundary(Evaporation);
      eva.ContactGeometry = Vedsted.SurfaceArea;
      Vedsted.EvaporationBoundaries.Add(eva);
       
      //Create and add a discharge boundary
      TimestampSeries Discharge = new TimestampSeries();
      Discharge.AddSiValue(new DateTime(2007, 3, 12), 6986 / TimeSpan.FromDays(365).TotalSeconds);
      Discharge.AddSiValue(new DateTime(2007, 4, 3), 5894 / TimeSpan.FromDays(365).TotalSeconds);
      Discharge.AddSiValue(new DateTime(2007, 4, 25), 1205 / TimeSpan.FromDays(365).TotalSeconds);
      Discharge.RelaxationFactor = 1;
      Discharge.AllowExtrapolation = true;
      Assert.AreEqual(Discharge.GetValue(new DateTime(2007, 4, 25)), Discharge.GetValue(new DateTime(2007, 6, 25)), 0.0000001);
      SinkSourceBoundary Kilde = new SinkSourceBoundary(Discharge);
      Vedsted.Sources.Add(Kilde);

      //Add a groundwater boundary
      GroundWaterBoundary gwb = new GroundWaterBoundary(Vedsted, 1e-5, 1, 46, (XYPolygon)Vedsted.Geometry);

      DateTime Start = new DateTime(2007, 1, 1);

      //Add the chemicals
      Chemical cl = ChemicalFactory.Instance.GetChemical(ChemicalNames.Cl);
      
      //Tell the lake to log the chemicals
      Vedsted.Output.LogChemicalConcentration(ChemicalFactory.Instance.GetChemical(ChemicalNames.IsotopeFraction));
      Vedsted.Output.LogChemicalConcentration(cl);

      IsotopeWater Iw = new IsotopeWater(1);
      Iw.SetIsotopeRatio(10);
      Iw.AddChemical(cl, 0.1);
      Precip.WaterSample = Iw.DeepClone();

      //Evaporate some of the water to get realistic initial conditions
      Iw.Evaporate(Iw.Volume / 2);
      Vedsted.SetState("Initial", Start, Iw.DeepClone());
      Kilde.WaterSample = Iw.DeepClone();

      Iw.Evaporate(Iw.Volume / 2);
      gwb.WaterSample = Iw.DeepClone();

      //Add to an engine
      Model Engine = new Model();
      Engine.Name = "Vedsted-opsætning";
      Engine._waterBodies.Add(Vedsted);

      //Set initial state
      Engine.SetState("Initial", Start, new WaterPacket(1));

      Engine.Save(@"c:\temp\setup.xml");


    }