示例#1
0
        protected override void RunActualProcess([NotNull] ScenarioSliceParameters slice)
        {
            var dbSrcHouses = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Houses, slice.PreviousSliceNotNull);
            var dbDstHouses = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Houses, slice);

            dbDstHouses.RecreateTable <DHWHeaterEntry>();
            var srcdhwsystems = dbSrcHouses.Fetch <DHWHeaterEntry>();

            dbDstHouses.BeginTransaction();
            WeightedRandomAllocator <DHWHeaterEntry> dhwAllocator = new WeightedRandomAllocator <DHWHeaterEntry>(Services.Rnd, Services.Logger);
            int numberOfObjects = (int)slice.DHWSystemConversionNumber;
            var electricBoilers = srcdhwsystems.Where(x => x.DhwHeatingSystemType == DhwHeatingSystem.Electricity).ToList();

            if (electricBoilers.Count == 0 && numberOfObjects > 0)
            {
                throw new FlaException("No electric boilers left when trying to allocate " + numberOfObjects);
            }

            bool failOnOversubscribe = slice.DstYear != 2050;
            var  systemsToChange     = dhwAllocator.PickNumberOfObjects(srcdhwsystems, x => x.EffectiveEnergyDemand, numberOfObjects, failOnOversubscribe);

            foreach (var entry in systemsToChange)
            {
                entry.DhwHeatingSystemType  = DhwHeatingSystem.Heatpump;
                entry.EffectiveEnergyDemand = entry.EffectiveEnergyDemand / 3;
            }

            foreach (var dhw in srcdhwsystems)
            {
                dhw.ID = 0;
                dbDstHouses.Save(dhw);
            }

            dbDstHouses.CompleteTransaction();
        }
示例#2
0
        private void ApplyDeathsIncludingPersistence([NotNull] ScenarioSliceParameters slice,
                                                     [NotNull][ItemNotNull]
                                                     List <Household> srcHouseholds,
                                                     [NotNull][ItemNotNull]
                                                     IReadOnlyCollection <Occupant> allOccupants)
        {
            WeightedRandomAllocator <Occupant> wra = new WeightedRandomAllocator <Occupant>(Services.Rnd, Services.Logger);
            var dbDstHousePersistence = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Houses, slice, DatabaseCode.Persistence);

            dbDstHousePersistence.CreateTableIfNotExists <PersistenceDeathEntry>();
            int numberOfDeathsLeft = (int)slice.NumberOfDeaths;
            var deathEntries       = dbDstHousePersistence.Fetch <PersistenceDeathEntry>();
            var peopleToRemove     = new List <Occupant>();

            Info("Number of planned deaths: " + numberOfDeathsLeft);
            dbDstHousePersistence.BeginTransaction();
            foreach (var de in deathEntries)
            {
                var hh = srcHouseholds.FirstOrDefault(x => x.HouseholdKey == de.HouseholdKey);
                if (hh == null)
                {
                    dbDstHousePersistence.Delete(de);
                    continue;
                }

                var srcocc = allOccupants.FirstOrDefault(x => x.HouseholdGuid == hh.Guid && x.Age == de.Age && x.Gender == de.Gender);
                if (srcocc == null)
                {
                    dbDstHousePersistence.Delete(de);
                    continue;
                }

                numberOfDeathsLeft--;
                peopleToRemove.Add(srcocc);
                if (numberOfDeathsLeft == 0)
                {
                    break;
                }
            }

            Info("Deaths after applying persistent deaths from db: " + numberOfDeathsLeft);
            List <Occupant> randomRemovedPeople = new List <Occupant>();

            if (numberOfDeathsLeft > 0)
            {
                randomRemovedPeople = wra.PickNumberOfObjects(allOccupants, (x => x.Age * x.Age), numberOfDeathsLeft, true);
                Info("Randomly picked additional people: " + randomRemovedPeople.Count);
            }

            peopleToRemove.AddRange(randomRemovedPeople);
            Info("People dying: " + peopleToRemove.Count);
            foreach (var deadocc in peopleToRemove)
            {
                Household             hh = srcHouseholds.First(x => x.Guid == deadocc.HouseholdGuid);
                PersistenceDeathEntry de = new PersistenceDeathEntry(hh.HouseholdKey, deadocc.Age, deadocc.Gender);
                dbDstHousePersistence.Save(de);
                hh.Occupants.Remove(deadocc);
            }

            dbDstHousePersistence.CompleteTransaction();
        }
示例#3
0
        protected override void RunActualProcess([NotNull] ScenarioSliceParameters slice)
        {
            var dbSrcHouses = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Houses, slice.PreviousSliceNotNull);
            var dbDstHouses = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Houses, slice);
            var households  = dbDstHouses.FetchAsRepo <Household>();

            dbDstHouses.RecreateTable <Car>();
            var srcCars = dbSrcHouses.FetchAsRepo <Car>();

            CheckCarsPerHousehold(srcCars);
            //filter cars for eliminated households
            var householdGuids = households.ToGuidHashset();

            if (srcCars.Count == 0)
            {
                throw new Exception("No cars were found in the scenario " + slice.DstScenario + " - " + slice.DstYear);
            }

            var yearsToAge = slice.DstYear - slice.PreviousSlice?.DstYear ?? throw new FlaException("Previous scenario was not set");

            dbDstHouses.BeginTransaction();
            WeightedRandomAllocator <Car> allocator = new WeightedRandomAllocator <Car>(Services.Rnd, Services.Logger);
            var  carsToPickFrom              = srcCars.Where(x => x.CarType == CarType.Gasoline).ToList();
            bool failOnOversubscribe         = slice.DstYear == 2050 ? false : true;
            int  numberOfTargetElectricCars  = (int)(slice.TotalPercentageOfElectricCars * srcCars.Count);
            int  numberOfCurrentElectricCars = srcCars.Count - carsToPickFrom.Count;
            int  numberOfNewElectricCars     = numberOfTargetElectricCars - numberOfCurrentElectricCars;

            if (numberOfNewElectricCars < 0)
            {
                throw new FlaException("Negative target electric cars in slice " + slice);
            }

            var        carsToChange = allocator.PickNumberOfObjects(carsToPickFrom, x => x.Age, numberOfNewElectricCars, failOnOversubscribe);
            int        carsSaved    = 0;
            List <Car> carsToDelete = new List <Car>();

            foreach (var car in srcCars)
            {
                if (!householdGuids.Contains(car.HouseholdGuid))
                {
                    var otherhouseholds = households.GetByReferenceGuidWithEmptyReturns(car.HouseGuid, "houseguid", x => x.HouseGuid);
                    if (otherhouseholds.Count == 0)
                    {
                        carsToDelete.Add(car);
                        continue;
                    }

                    var otherCars             = srcCars.GetByReferenceGuidWithEmptyReturns(car.HouseGuid, "houseguid", x => x.HouseGuid);
                    var hhswithCarGuids       = otherCars.Select(x => x.HouseholdGuid).ToList();
                    var householdsWithoutCars = otherhouseholds.Where(x => !hhswithCarGuids.Contains(x.Guid)).ToList();
                    if (householdsWithoutCars.Count > 0)
                    {
                        car.HouseholdGuid = householdsWithoutCars[Services.Rnd.Next(householdsWithoutCars.Count)].Guid;
                    }
                    else
                    {
                        car.HouseholdGuid = otherhouseholds[Services.Rnd.Next(householdsWithoutCars.Count)].Guid;
                    }
                }
            }

            var carsToSave = srcCars.GetValueList();

            foreach (var car in carsToDelete)
            {
                carsToSave.Remove(car);
            }

            CheckCarsPerHousehold(carsToSave);
            int targetCarCount = (int)(households.SelectMany(x => x.Occupants).Count() * slice.CarOwnershipPercentage);

            if (carsToSave.Count > targetCarCount)
            {
                //clear excess cars
                int excessCars = carsToSave.Count - targetCarCount;
                var carsToSell = allocator.PickNumberOfObjects(carsToSave, x => x.Age, excessCars, false);
                foreach (var sellcar in carsToSell)
                {
                    carsToSave.Remove(sellcar);
                }
            }
            else
            {
                int carsToCreate = targetCarCount - carsToSave.Count;
                while (carsToCreate > 0)
                {
                    var dict          = CheckCarsPerHousehold(carsToSave);
                    var householdGuid = dict.First().Key;
                    if (dict.First().Value > 2)
                    {
                        throw new FlaException("more than 2 cars per household");
                    }

                    string  houseguid     = households.GetByGuid(householdGuid).HouseGuid;
                    CarType targetCarType = CarType.Gasoline;
                    if (carsToSave.Count(x => x.CarType == CarType.Electric) < (slice.TotalPercentageOfElectricCars * carsToSave.Count))
                    {
                        targetCarType = CarType.Electric;
                    }

                    Car newcar = new Car(householdGuid, Guid.NewGuid().ToString(), 0, targetCarType, houseguid);
                    carsToCreate--;
                    carsToSave.Add(newcar);
                }
            }

            CheckCarsPerHousehold(carsToSave);
            foreach (var car in carsToSave)
            {
                car.ID   = 0;
                car.Age += yearsToAge;
                if (carsToChange.Contains(car))
                {
                    car.CarType = CarType.Electric;
                    car.Age     = 0;
                }

                carsSaved++;
                dbDstHouses.Save(car);
            }

            //make new Cars
            Info("Converted " + carsToChange.Count + " cars, out of a total of " + carsSaved);
            //convert cars to electric
            dbDstHouses.CompleteTransaction();
        }
        protected override void RunActualProcess([NotNull] ScenarioSliceParameters slice)
        {
            var dbSrcHouses = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Houses, slice.PreviousSliceNotNull);
            var dbDstHouses = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Houses, slice);

            dbDstHouses.RecreateTable <HeatingSystemEntry>();
            var srcHeatingSystems = dbSrcHouses.Fetch <HeatingSystemEntry>();
            var srcHouses         = dbSrcHouses.Fetch <House>();
            var dstHouses         = dbDstHouses.FetchAsRepo <House>();

            if (srcHeatingSystems.Count == 0)
            {
                throw new FlaException("No heating systems were found");
            }

            double totalHeatingDemand = srcHeatingSystems.Sum(x => x.HeatDemand);
            double totalEbf           = srcHouses.Sum(x => x.EnergieBezugsFläche);
            double averageEnergyIntensityForNewAppartments = totalHeatingDemand / totalEbf * 0.5;

            //add heating demand from new appartments
            foreach (var hse in srcHeatingSystems)
            {
                var house = dstHouses.GetByGuid(hse.HouseGuid);
                foreach (var expansion in house.Appartments)
                {
                    var hseExpansion = hse.HeatDemands.FirstOrDefault(x => x.HouseExpansionGuid == expansion.Guid);
                    if (hseExpansion == null)
                    {
                        AppartmentHeatingDemand hsex = new AppartmentHeatingDemand(expansion.Guid,
                                                                                   expansion.EnergieBezugsFläche,
                                                                                   averageEnergyIntensityForNewAppartments * expansion.EnergieBezugsFläche,
                                                                                   slice.DstYear);
                        hse.HeatDemands.Add(hsex);
                    }
                }
            }

            var dstHousesByGuid = dstHouses.ToDictionary(x => x.Guid, x => x);

            DumpHeatingSystemsToXlsx(slice, srcHeatingSystems, dstHousesByGuid);

            //building renovations
            WeightedRandomAllocator <HeatingSystemEntry> wra = new WeightedRandomAllocator <HeatingSystemEntry>(Services.Rnd, MyLogger);

            var potentialRenovationHeatingSystems = srcHeatingSystems
                                                    .Where(x => x.Age > 10 && x.HeatDemand > 0 && Math.Abs(x.HeatDemand - x.OriginalHeatDemand2017) < 0.1).ToList();

            if (potentialRenovationHeatingSystems.Count == 0)
            {
                throw new FlaException("Not a single heating system found");
            }

            double averageRenovationFactor = slice.AverageHouseRenovationFactor;

            if (Math.Abs(averageRenovationFactor) < 0.000001)
            {
                throw new FlaException("Renovation factor was 0 for scenario " + slice);
            }

            int numberOfBuildingRenovations = (int)(slice.RenovationRatePercentage * srcHouses.Count);

            Info("renovating houses, target number " + numberOfBuildingRenovations + " GWh, renovation factor " + averageRenovationFactor);
            bool failOnOversubscribe = slice.DstYear != 2050;
            var  systemsToRenovate   = wra.PickNumberOfObjects(potentialRenovationHeatingSystems,
                                                               WeighingFunctionForRenovation,
                                                               numberOfBuildingRenovations,
                                                               failOnOversubscribe);

            Info("Renovating " + systemsToRenovate.Count + " houses with a total heat demand of " + systemsToRenovate.Sum(x => x.HeatDemand));
            foreach (var entry in systemsToRenovate)
            {
                entry.RenovateAllHeatDemand(averageRenovationFactor);
            }


            //change heating systems
            var changeableHeatingSystems = srcHeatingSystems.ToList();
            int elapsedTime = slice.DstYear - slice.PreviousSliceNotNull.DstYear;

            foreach (var heatingSystemEntry in srcHeatingSystems)
            {
                heatingSystemEntry.Age += elapsedTime;
            }


            int           yearsToAge             = slice.DstYear - slice.PreviousSliceNotNull.DstYear;
            RowCollection rc                     = new RowCollection("Changes", "Changes");
            double        totalOilHeatDemand2017 = changeableHeatingSystems.Where(x => x.HeatingSystemType2017 == HeatingSystemType.Öl)
                                                   .Sum(x => x.OriginalHeatDemand2017);
            double oilenergyAmountToChange = totalOilHeatDemand2017 * slice.Energy2017PercentageFromOilToHeatpump;

            ChangeHeatingSystemsForOneType(slice, changeableHeatingSystems, HeatingSystemType.Öl, oilenergyAmountToChange, rc, dstHousesByGuid);
            double totalGasHeatDemand2017 = changeableHeatingSystems.Where(x => x.HeatingSystemType2017 == HeatingSystemType.Gas)
                                            .Sum(x => x.OriginalHeatDemand2017);
            double gasEnergyAmountToChange = totalGasHeatDemand2017 * slice.Energy2017PercentageFromGasToHeatpump;

            ChangeHeatingSystemsForOneType(slice, changeableHeatingSystems, HeatingSystemType.Gas, gasEnergyAmountToChange, rc, dstHousesByGuid);
            double totalOtherHeatDemand = changeableHeatingSystems.Where(x => x.HeatingSystemType2017 == HeatingSystemType.Other)
                                          .Sum(x => x.OriginalHeatDemand2017);
            double otherDemandToChange = slice.Energy2017PercentageFromOtherToHeatpump * totalOtherHeatDemand;

            ChangeHeatingSystemsForOneType(slice, changeableHeatingSystems, HeatingSystemType.Other, otherDemandToChange, rc, dstHousesByGuid);
            var fn = MakeAndRegisterFullFilename("HeatingChangeLog.xlsx", slice);

            if (rc.Rows.Count > 0)
            {
                XlsxDumper.WriteToXlsx(fn, rc);
            }

            dbDstHouses.BeginTransaction();
            foreach (HeatingSystemEntry heatingSystemEntry in srcHeatingSystems)
            {
                heatingSystemEntry.Age += yearsToAge;
                heatingSystemEntry.ID   = 0;

                dbDstHouses.Save(heatingSystemEntry);
            }

            dbDstHouses.CompleteTransaction();
            var srcHouseGuids = srcHouses.Select(x => x.Guid).ToHashSet();
            var dstHouseGuids = dstHouses.Select(x => x.Guid).ToHashSet();

            foreach (var heatingSystem in srcHeatingSystems)
            {
                srcHouseGuids.Should().Contain(heatingSystem.HouseGuid);
                dstHouseGuids.Should().Contain(heatingSystem.HouseGuid);
            }
        }