/// <summary>
    /// Initializes the model by reading all files and building the leaching time series to and from each catchment
    /// </summary>
    /// <param name="Start"></param>
    /// <param name="End"></param>
    /// <param name="Catchments"></param>
    public override void Initialize(DateTime Start, DateTime End, IEnumerable<Catchment> Catchments)
    {
      base.Initialize(Start, End, Catchments);

      this.Start = Start;
      LoadSoilCodesGrid(SoilCodes.FileName);

        foreach (var item in UnsatAgeFiles)
        {
          item.Initialize();
        }

      foreach (var parfile in DaisyFiles)
      {
        LoadDaisyData(parfile.FileName);
      }

      leachdata.BuildLeachData(Start, End, Catchments, RecycleStart, RecycleEnd, RecycleScale);

      ParticleReader pr = new ParticleReader();
      pr.Catchments = Catchments;

      List<Particle> AllParticles = new List<Particle>();

      IEnumerable<Particle> particles;

      foreach (var parfile in ParticleFiles)
      {
        if(UseUnsatFilter)  
          particles = pr.ReadParticleFile(parfile.FileName, pr.UnSatFilter, DrainToBoundaryOption);
        else
          particles = pr.ReadParticleFile(parfile.FileName, null, DrainToBoundaryOption);

        AllParticles.AddRange(particles);


        if (ExtraOutput)
          pr.Distribute(particles.Where(p => p.SinkType != SinkType.Removed_by_Well));
        else
          pr.Distribute(particles.Where(p => p.SinkType != SinkType.Removed_by_Well & p.Registration != 1));
      }

      //Now scale the leaching data with the number of particles in each grid cell.
      leachdata.ScaleWithFactor(0.01);

      foreach (var p in AllParticles)
      {
        //Adjust traveltime from dfs2
        foreach (var dfs in UnsatAgeFiles)
        {
          if (p.HorizontalTravelDistance >= dfs.MinHorizontalTravelDistance & p.TravelTime >= dfs.MinTravelTime)
          {
            int col = dfs.dfs.GetColumnIndex(p.X);
            int row = dfs.dfs.GetRowIndex(p.Y);

            if (col >= 0 & row >= 0)
              p.TravelTime += Math.Max(0, dfs.Data[row, col]);
          }
        }
      }

      BuildInputConcentration(Start, End, Catchments);

      if (ExtraOutput)
        pr.DebugPrint(MainModel.OutputDirectory);

      //Now clear memory
      leachdata.ClearMemory();

      foreach (var c in Catchments)
        c.EndParticles.Clear();
    }
    public void MakeMap(Dictionary<int, Catchment> AllCatchments, IEnumerable<Catchment> EndCatchments, DataTable StateVariables, IEnumerable<INitrateModel> SourceModels, IEnumerable<INitrateModel> InternalSinkModels, IEnumerable<INitrateModel> MainSinkModels)
    {
      this.StateVariables = StateVariables;

      NewMessage("Creating reduction maps");

      ParticleReader pr = new ParticleReader();
      pr.Catchments = AllCatchments.Values;

      foreach (var s in ParticleFiles)
      {
        var particles = pr.ReadParticleFile(s.FileName, null, DrainToBoundaryOption);

        NewMessage("Reading particles from: " + s.FileName);


        NewMessage("Distributing " + particles.Count() + " particles on catchments");
        pr.Distribute(particles);
      }

      Dictionary<int, double> GroundwaterReduction = new Dictionary<int, double>();

      foreach (var v in AllCatchments.Values)
      {
        var row = GetReductionRow(v.ID);

        int TotalParticles = v.StartParticles.Count;
        int TotalRedoxedParticles = v.StartParticles.Count(p => p.Registration == 1);;

        if(ParticlesPrSquareMeter!=-1)
        {
          int n = (int) (v.Geometry.GetArea()*ParticlesPrSquareMeter);
          TotalRedoxedParticles += (n - TotalParticles);
          TotalParticles =n;
        }
        row["Particles"] = TotalParticles;
        row["RedoxedParticles"] = TotalRedoxedParticles;


        if (v.StartParticles.Count > 0)
          row["GWDischarge"] = 1.0 - (double)TotalRedoxedParticles / ((double)TotalParticles);
        else
          row["GWDischarge"] = 1;

      }

      NewMessage("Calculated discharge percentage");

      //<ID15<ID15,no of particles>> For each ID15 there is a list of ID15s where the particles exit.
      Dictionary<int, Dictionary<int, int>> CatchmentPartCounts = new Dictionary<int, Dictionary<int, int>>();
      Dictionary<int, int> NonRedoxedSea = new Dictionary<int, int>();

      foreach (var v in AllCatchments.Values)
      {
        List<double> reductions = new List<double>();
        //Distribute the particles infiltrating on the cathcments where they exit
        Dictionary<int, int> partcounts = new Dictionary<int, int>();
        CatchmentPartCounts.Add(v.ID, partcounts);
        NonRedoxedSea.Add(v.ID, 0);
        partcounts.Add(v.ID, 0);
        //Only take the non redoxed
        Parallel.ForEach(v.StartParticles.Where(p => p.Registration != 1), p =>
        {
          if (v.Geometry.Contains(p.X, p.Y))
            lock (Lock)
              partcounts[v.ID]++;
          else
          {
            bool found = false;
            foreach (var c in AllCatchments.Values)
            {
              if (c.Geometry.Contains(p.X, p.Y))
              {

                lock (Lock)
                {
                  found=true;
                  if (partcounts.ContainsKey(c.ID))
                    partcounts[c.ID]++;
                  else
                    partcounts.Add(c.ID, 1);
                }
                break;
              }
            }
            if (!found)
              NonRedoxedSea[v.ID]++;
          }
        });

      }

      BuildReduction(AllCatchments, EndCatchments, SourceModels, InternalSinkModels, MainSinkModels);
      foreach (var v in AllCatchments.Values)
      {
        double totalSurface = 0;
        double totalConceptual = 0;

        var row = GetReductionRow(v.ID);
        row["OutsideParticles"] = CatchmentPartCounts[v.ID].Skip(1).Sum(k => k.Value);
        row["SeaParticles"] = v.StartParticles.Count(p => p.Registration != 1) - CatchmentPartCounts[v.ID].Sum(k => k.Value);
        int totalparticlesNotSea = CatchmentPartCounts[v.ID].Sum(k => k.Value);


        //Loop all the catchments where particles exit. This includes the actual catchment
        foreach (var kvp in CatchmentPartCounts[v.ID]) 
        {
          var temprow = GetReductionRow(kvp.Key);
          totalSurface += (double)temprow["SurfaceDischarge"] * kvp.Value; //Multiply the particles entering a particular catchment with the reductions of that catchment
          totalConceptual += (double)temprow["ConceptualGWDischarge"] * kvp.Value; //Multiply the particles entering a particular catchment with the reductions of that catchment
        }
        totalSurface /= totalparticlesNotSea;
        totalConceptual /= totalparticlesNotSea;
          
        row["ConcExitDischarge"]=totalConceptual;
        row["TotalDischarge"] = totalSurface * totalConceptual * (double)row["GWDischarge"];
      }


      Print(AllCatchments,"");

    }
        /// <summary>
        /// Initializes the model by reading all files and building the leaching time series to and from each catchment
        /// </summary>
        /// <param name="Start"></param>
        /// <param name="End"></param>
        /// <param name="Catchments"></param>
        public override void Initialize(DateTime Start, DateTime End, IEnumerable <Catchment> Catchments)
        {
            base.Initialize(Start, End, Catchments);

            this.Start = Start;
            LoadSoilCodesGrid(SoilCodes.FileName);

            foreach (var item in UnsatAgeFiles)
            {
                item.Initialize();
            }

            foreach (var parfile in DaisyFiles)
            {
                LoadDaisyData(parfile.FileName);
            }

            leachdata.BuildLeachData(Start, End, Catchments, RecycleStart, RecycleEnd, RecycleScale);

            ParticleReader pr = new ParticleReader();

            pr.Catchments = Catchments;

            List <Particle> AllParticles = new List <Particle>();

            IEnumerable <Particle> particles;

            foreach (var parfile in ParticleFiles)
            {
                if (UseUnsatFilter)
                {
                    particles = pr.ReadParticleFile(parfile.FileName, pr.UnSatFilter, DrainToBoundaryOption);
                }
                else
                {
                    particles = pr.ReadParticleFile(parfile.FileName, null, DrainToBoundaryOption);
                }

                AllParticles.AddRange(particles);


                if (ExtraOutput)
                {
                    pr.Distribute(particles.Where(p => p.SinkType != SinkType.Removed_by_Well));
                }
                else
                {
                    pr.Distribute(particles.Where(p => p.SinkType != SinkType.Removed_by_Well & p.Registration != 1));
                }
            }

            //Now scale the leaching data with the number of particles in each grid cell.
            leachdata.ScaleWithFactor(0.01);

            foreach (var p in AllParticles)
            {
                //Adjust traveltime from dfs2
                foreach (var dfs in UnsatAgeFiles)
                {
                    if (p.HorizontalTravelDistance >= dfs.MinHorizontalTravelDistance & p.TravelTime >= dfs.MinTravelTime)
                    {
                        int col = dfs.dfs.GetColumnIndex(p.X);
                        int row = dfs.dfs.GetRowIndex(p.Y);

                        if (col >= 0 & row >= 0)
                        {
                            p.TravelTime += Math.Max(0, dfs.Data[row, col]);
                        }
                    }
                }
            }

            BuildInputConcentration(Start, End, Catchments);

            if (ExtraOutput)
            {
                pr.DebugPrint(MainModel.OutputDirectory);
            }

            //Now clear memory
            leachdata.ClearMemory();

            foreach (var c in Catchments)
            {
                c.EndParticles.Clear();
            }
        }
Beispiel #4
0
        public void MakeMap(Dictionary <int, Catchment> AllCatchments, IEnumerable <Catchment> EndCatchments, DataTable StateVariables, IEnumerable <INitrateModel> SourceModels, IEnumerable <INitrateModel> InternalSinkModels, IEnumerable <INitrateModel> MainSinkModels)
        {
            this.StateVariables = StateVariables;

            NewMessage("Creating reduction maps");

            ParticleReader pr = new ParticleReader();

            pr.Catchments = AllCatchments.Values;

            foreach (var s in ParticleFiles)
            {
                var particles = pr.ReadParticleFile(s.FileName, null, DrainToBoundaryOption);

                NewMessage("Reading particles from: " + s.FileName);


                NewMessage("Distributing " + particles.Count() + " particles on catchments");
                pr.Distribute(particles);
            }

            Dictionary <int, double> GroundwaterReduction = new Dictionary <int, double>();

            foreach (var v in AllCatchments.Values)
            {
                var row = GetReductionRow(v.ID);

                int TotalParticles        = v.StartParticles.Count;
                int TotalRedoxedParticles = v.StartParticles.Count(p => p.Registration == 1);;

                if (ParticlesPrSquareMeter != -1)
                {
                    int n = (int)(v.Geometry.GetArea() * ParticlesPrSquareMeter);
                    TotalRedoxedParticles += (n - TotalParticles);
                    TotalParticles         = n;
                }
                row["Particles"]        = TotalParticles;
                row["RedoxedParticles"] = TotalRedoxedParticles;


                if (v.StartParticles.Count > 0)
                {
                    row["GWDischarge"] = 1.0 - (double)TotalRedoxedParticles / ((double)TotalParticles);
                }
                else
                {
                    row["GWDischarge"] = 1;
                }
            }

            NewMessage("Calculated discharge percentage");

            //<ID15<ID15,no of particles>> For each ID15 there is a list of ID15s where the particles exit.
            Dictionary <int, Dictionary <int, int> > CatchmentPartCounts = new Dictionary <int, Dictionary <int, int> >();
            Dictionary <int, int> NonRedoxedSea = new Dictionary <int, int>();

            foreach (var v in AllCatchments.Values)
            {
                List <double> reductions = new List <double>();
                //Distribute the particles infiltrating on the cathcments where they exit
                Dictionary <int, int> partcounts = new Dictionary <int, int>();
                CatchmentPartCounts.Add(v.ID, partcounts);
                NonRedoxedSea.Add(v.ID, 0);
                partcounts.Add(v.ID, 0);
                //Only take the non redoxed
                Parallel.ForEach(v.StartParticles.Where(p => p.Registration != 1), p =>
                {
                    if (v.Geometry.Contains(p.X, p.Y))
                    {
                        lock (Lock)
                            partcounts[v.ID]++;
                    }
                    else
                    {
                        bool found = false;
                        foreach (var c in AllCatchments.Values)
                        {
                            if (c.Geometry.Contains(p.X, p.Y))
                            {
                                lock (Lock)
                                {
                                    found = true;
                                    if (partcounts.ContainsKey(c.ID))
                                    {
                                        partcounts[c.ID]++;
                                    }
                                    else
                                    {
                                        partcounts.Add(c.ID, 1);
                                    }
                                }
                                break;
                            }
                        }
                        if (!found)
                        {
                            NonRedoxedSea[v.ID]++;
                        }
                    }
                });
            }

            BuildReduction(AllCatchments, EndCatchments, SourceModels, InternalSinkModels, MainSinkModels);
            foreach (var v in AllCatchments.Values)
            {
                double totalSurface    = 0;
                double totalConceptual = 0;

                var row = GetReductionRow(v.ID);
                row["OutsideParticles"] = CatchmentPartCounts[v.ID].Skip(1).Sum(k => k.Value);
                row["SeaParticles"]     = v.StartParticles.Count(p => p.Registration != 1) - CatchmentPartCounts[v.ID].Sum(k => k.Value);
                int totalparticlesNotSea = CatchmentPartCounts[v.ID].Sum(k => k.Value);


                //Loop all the catchments where particles exit. This includes the actual catchment
                foreach (var kvp in CatchmentPartCounts[v.ID])
                {
                    var temprow = GetReductionRow(kvp.Key);
                    totalSurface    += (double)temprow["SurfaceDischarge"] * kvp.Value;      //Multiply the particles entering a particular catchment with the reductions of that catchment
                    totalConceptual += (double)temprow["ConceptualGWDischarge"] * kvp.Value; //Multiply the particles entering a particular catchment with the reductions of that catchment
                }
                totalSurface    /= totalparticlesNotSea;
                totalConceptual /= totalparticlesNotSea;

                row["ConcExitDischarge"] = totalConceptual;
                row["TotalDischarge"]    = totalSurface * totalConceptual * (double)row["GWDischarge"];
            }


            Print(AllCatchments, "");
        }