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(); }
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 <AirConditioningEntry>(); var srcAirconditioningEntries = dbSrcHouses.Fetch <AirConditioningEntry>(); var srcHouses = dbSrcHouses.Fetch <House>(); var airConGuids = srcAirconditioningEntries.Select(x => x.HouseGuid).ToList(); var hausanschlusess = dbSrcHouses.Fetch <Hausanschluss>(); var businesses = dbDstHouses.Fetch <BusinessEntry>(); var housesWithoutAirconditioning1 = srcHouses.Where(x => !airConGuids.Contains(x.Guid)).ToList(); if (housesWithoutAirconditioning1.Count == 0) { throw new FlaException("no houses left without airconditioning"); } foreach (var conditioningEntry in srcAirconditioningEntries) { conditioningEntry.HausAnschlussGuid.Should().NotBeNullOrWhiteSpace(); var ha = hausanschlusess.First(x => x.Guid == conditioningEntry.HausAnschlussGuid); if (ha.ObjectID.ToLower().Contains("kleinanschluss")) { throw new FlaException("No ac at kleinanschluss"); } } // ReSharper disable once ArrangeLocalFunctionBody double CalculateYearlyAirConditioningEnergyConsumption(House h) => h.EnergieBezugsFläche * slice.AirConditioningEnergyIntensityInKWhPerSquareMeter; double totalEbf = srcHouses.Sum(x => x.EnergieBezugsFläche); double totalTargetAirConditioning = totalEbf * slice.PercentageOfAreaWithAirConditioning * slice.AirConditioningEnergyIntensityInKWhPerSquareMeter; double currentAirConditioning = srcAirconditioningEntries.Sum(x => x.EffectiveEnergyDemand); double newlyInstealledEnergyForAirconditioning = totalTargetAirConditioning - currentAirConditioning; if (newlyInstealledEnergyForAirconditioning < 0) { throw new FlaException("Negative air conditioning target. Currently installed in " + slice + " are " + currentAirConditioning / (totalEbf * slice.AirConditioningEnergyIntensityInKWhPerSquareMeter)); } bool failOnOver = slice.DstYear != 2050; WeightedRandomAllocator <House> allocator = new WeightedRandomAllocator <House>(Services.Rnd, Services.Logger); var housesForAirConditioning = allocator.PickObjectUntilLimit(housesWithoutAirconditioning1, x => x.EnergieBezugsFläche, CalculateYearlyAirConditioningEnergyConsumption, newlyInstealledEnergyForAirconditioning, failOnOver); var dstAirConditioningEntries = new List <AirConditioningEntry>(); foreach (var house in housesForAirConditioning) { var businessesInHouse = businesses.Where(x => x.HouseGuid == house.Guid).ToList(); AirConditioningType act = AirConditioningType.Commercial; if (businessesInHouse.Count == 0) { act = AirConditioningType.Residential; } foreach (var entry in businessesInHouse) { if (entry.BusinessType == BusinessType.Industrie) { act = AirConditioningType.Industrial; } } Hausanschluss ha = house.GetHausanschlussByIsn(new List <int>(), null, hausanschlusess, MyLogger, false); if (ha != null && ha.ObjectID.ToLower().Contains("kleinanschluss")) { ha = null; } if (ha != null) { var ace = new AirConditioningEntry(house.Guid, Guid.NewGuid().ToString(), CalculateYearlyAirConditioningEnergyConsumption(house), 1, act, ha.Guid, house.ComplexName + " - Air Conditioning", ""); dstAirConditioningEntries.Add(ace); } } foreach (var airconditioningEntry in srcAirconditioningEntries) { airconditioningEntry.ID = 0; dstAirConditioningEntries.Add(airconditioningEntry); } //final checks foreach (var dstAirConditioningEntry in dstAirConditioningEntries) { dstAirConditioningEntry.HausAnschlussGuid.Should().NotBeNullOrWhiteSpace(); var ha = hausanschlusess.First(x => x.Guid == dstAirConditioningEntry.HausAnschlussGuid); if (ha.ObjectID.ToLower().Contains("kleinanschluss")) { throw new FlaException("No ac at kleinanschluss"); } } dbDstHouses.BeginTransaction(); foreach (var airConditioningEntry in dstAirConditioningEntries) { dbDstHouses.Save(airConditioningEntry); } dbDstHouses.CompleteTransaction(); }
protected override void RunActualProcess([NotNull] ScenarioSliceParameters parameters) { Services.SqlConnection.RecreateTable <HeatingSystemEntry>(Stage.Houses, parameters); var dbSrcHouses = Services.SqlConnection.GetDatabaseConnection(Stage.Houses, parameters.PreviousScenarioNotNull).Database; var dbDstHouses = Services.SqlConnection.GetDatabaseConnection(Stage.Houses, parameters).Database; var srcHeatingSystems = dbSrcHouses.Fetch <HeatingSystemEntry>(); if (srcHeatingSystems.Count == 0) { throw new FlaException("No heating systems were found"); } int elapsedTime = parameters.DstYear - parameters.PreviousScenarioNotNull.DstYear; foreach (var heatingSystemEntry in srcHeatingSystems) { heatingSystemEntry.Age += elapsedTime; } int yearsToAge = parameters.DstYear - parameters.PreviousScenarioNotNull.DstYear; var potentialSystemsToChange = srcHeatingSystems.Where(x => x.SynthesizedHeatingSystemType == HeatingSystemType.Öl || x.SynthesizedHeatingSystemType == HeatingSystemType.Gas).ToList(); WeightedRandomAllocator <HeatingSystemEntry> wra = new WeightedRandomAllocator <HeatingSystemEntry>(Services.Rnd); double WeighingFunction(HeatingSystemEntry heatingSystemEntry) { double ageWeight = heatingSystemEntry.Age / 30.0; double energyWeight = 1 - heatingSystemEntry.AverageHeatingEnergyDemandDensity / 200; if (energyWeight <= 0) { energyWeight = 0.000001; } double combinedWeight = 1 / (ageWeight * energyWeight); if (double.IsInfinity(combinedWeight)) { throw new Exception("Invalid weight"); } return(combinedWeight); } /* * double SumFunction(HeatingSystemEntry heatingSystemEntry) * { * return heatingSystemEntry.YearlyEnergyDemand; * } */ var pickedHeatingSystems = wra.PickObjects(potentialSystemsToChange, WeighingFunction, (int)parameters.ConversionToHeatPumpNumber); if (potentialSystemsToChange.Count < parameters.ConversionToHeatPumpNumber) { throw new Exception("not enough other heating systems left for heat pump conversion demand"); } foreach (var pickedHeatingSystem in pickedHeatingSystems) { pickedHeatingSystem.Age = 0; pickedHeatingSystem.SynthesizedHeatingSystemType = HeatingSystemType.Heatpump; } dbDstHouses.BeginTransaction(); foreach (HeatingSystemEntry heatingSystemEntry in srcHeatingSystems) { heatingSystemEntry.Age += yearsToAge; heatingSystemEntry.HeatingSystemID = 0; dbDstHouses.Save(heatingSystemEntry); } dbDstHouses.CompleteTransaction(); }
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(); }
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); } }
private void ChangeHeatingSystemsForOneType([NotNull] ScenarioSliceParameters slice, [NotNull][ItemNotNull] List <HeatingSystemEntry> allPotentialSystemsToChange, HeatingSystemType heatingSystemType, double sumToSwitch, [NotNull] RowCollection rc, [NotNull] Dictionary <string, House> housesByGuid) { if (Math.Abs(sumToSwitch) < 0.1) { return; } var rb = RowBuilder.Start("Type to Change", heatingSystemType.ToString()); rc.Add(rb); var matchingPotentialSystemsToChange = allPotentialSystemsToChange.Where(x => x.SynthesizedHeatingSystemType == heatingSystemType).ToList(); rb.Add("Planned Sum", sumToSwitch); rb.Add("Energy Demand before across all systems", matchingPotentialSystemsToChange.Select(x => x.OriginalHeatDemand2017).Sum()); WeightedRandomAllocator <HeatingSystemEntry> wra = new WeightedRandomAllocator <HeatingSystemEntry>(Services.Rnd, MyLogger); var pickedHeatingSystems = wra.PickObjectUntilLimit(matchingPotentialSystemsToChange, WeighingFunctionForSwitchingToHeatpump, x => x.OriginalHeatDemand2017, sumToSwitch, false); double changedEnergy = 0; foreach (var pickedHeatingSystem in pickedHeatingSystems) { pickedHeatingSystem.Age = 0; pickedHeatingSystem.SynthesizedHeatingSystemType = HeatingSystemType.Heatpump; pickedHeatingSystem.ProvideProfile = true; changedEnergy += pickedHeatingSystem.OriginalHeatDemand2017; House house = housesByGuid[pickedHeatingSystem.HouseGuid]; var rb1 = RowBuilder.Start("House", house.ComplexName); rb1.Add("Changed Energy", pickedHeatingSystem.EffectiveEnergyDemand); rb1.Add("Heating System", heatingSystemType); rc.Add(rb1); } rb.Add("Changed Sum", changedEnergy); Info("Changed " + pickedHeatingSystems.Count + " from " + heatingSystemType + " to heatpump for a total of " + changedEnergy / 1_000_000 + " gwh"); double overSubscribed = sumToSwitch - changedEnergy; rb.Add("Oversubscribed", overSubscribed); if (slice.DstYear != 2050) { if (overSubscribed > 0) { throw new FlaException("Problem: tried to allocate " + sumToSwitch / Constants.GWhFactor + "gwh to heat pumps, but could only switch " + changedEnergy / Constants.GWhFactor + " gwh in the year " + slice.DstYear + " and scenario " + slice.DstScenario + " from type " + heatingSystemType); } //im letzten jahr ist oversubscribe ok. //overSubscribed.Should().BeLessOrEqualTo(0); } var leftoveroldSystems = matchingPotentialSystemsToChange.Where(x => x.SynthesizedHeatingSystemType == heatingSystemType).ToList(); rb.Add("Energy Demand after across all systems", leftoveroldSystems.Select(x => x.EffectiveEnergyDemand).Sum()); }