From 8c1cd4bc7fc2db223c14ce2a9912832b57608122 Mon Sep 17 00:00:00 2001 From: mosc5 Date: Mon, 13 Feb 2023 09:54:14 +0100 Subject: [PATCH] create new function to run multiprocesing on #98 --- simbev/simbev_class.py | 176 +++++++++++++++++++++-------------------- 1 file changed, 89 insertions(+), 87 deletions(-) diff --git a/simbev/simbev_class.py b/simbev/simbev_class.py index 2083c93..4e59534 100644 --- a/simbev/simbev_class.py +++ b/simbev/simbev_class.py @@ -245,95 +245,17 @@ def run(self, region): region_directory.mkdir(parents=True, exist_ok=True) cars_simulated = 0 - exception_count = 0 + # exception_count = 0 for car_type_name, car_count in region.car_dict.items(): for car_number in range(car_count): - # Create new car - car_type = self.car_types[car_type_name] - # create new car objects - # TODO: parking parameters that change by region - work_parking = ( - self.work_parking[region.region_type.rs7_type] >= self.rng.random() - ) - home_parking = ( - self.home_parking[region.region_type.rs7_type] >= self.rng.random() - ) - - work_power = ( - self.get_charging_capacity("work") if work_parking else None - ) - home_power = ( - self.get_charging_capacity("home") if home_parking else None - ) - # SOC init value for the first monday - # formula from Kilian, TODO maybe not needed anymore - soc_init = ( - self.rng.random() ** (1 / 3) * 0.8 + 0.2 - if self.rng.random() < 0.12 - else 1 - ) - car = Car( - car_type, - car_number, - work_parking, - home_parking, - work_power, - home_power, - region, - soc_init, - ) - - if self.num_threads == 1: - print( - "\r{}% {} {} / {}".format( - round( - (cars_simulated + car_number + 1) - * 100 - / region.car_amount - ), - car.car_type.name, - (car.number + 1), - region.car_dict[car.car_type.name], - ), - end="", - flush=True, - ) - - # TODO profiles: add profiles to car on creation? or apply profiles during simulation? - # idea: create a list of trips that get simulated. code where? - - # if private run, check if private charging infrastructure is available - if self.private_only_run and (work_power or home_power): - # TODO catch error, then run again - try: - private_car = copy.copy(car) - private_car.private_only = True - self.simulate_car(private_car, region) - car = private_car - except SoCError: - exception_count += 1 - self.simulate_car(car, region) - else: - self.simulate_car(car, region) - - # export vehicle csv - if self.output_options["analyze"]: - car_array = car.export(region_directory, self) - if region.analyze_array is None: - region.analyze_array = car_array - else: - region.analyze_array = np.vstack( - (region.analyze_array, car_array) - ) - else: - car.export(region_directory, self) - cars_simulated += car_count - if self.private_only_run: - print( - "\nNumber of cars that couldn't run private only: {}/{}".format( - exception_count, cars_simulated - ) - ) + self.run_car(car_type_name, car_number, region, cars_simulated, region_directory) + cars_simulated += car_number + 1 + # if self.private_only_run: + # print( + # "\nNumber of cars that couldn't run private only: {}/{}".format( + # exception_count, cars_simulated + # ) + # ) region.export_grid_timeseries(region_directory) if self.output_options["analyze"]: @@ -346,6 +268,86 @@ def run(self, region): ) print(f" - done (Region {region.number + 1}) at {datetime.datetime.now()}") return region.grid_data_frame, region.analyze_array + + def run_car(self, car_type_name, car_number, region, cars_simulated, region_directory): + # Create new car + car_type = self.car_types[car_type_name] + # create new car objects + # TODO: parking parameters that change by region + work_parking = ( + self.work_parking[region.region_type.rs7_type] >= self.rng.random() + ) + home_parking = ( + self.home_parking[region.region_type.rs7_type] >= self.rng.random() + ) + + work_power = ( + self.get_charging_capacity("work") if work_parking else None + ) + home_power = ( + self.get_charging_capacity("home") if home_parking else None + ) + # SOC init value for the first monday + # formula from Kilian, TODO maybe not needed anymore + soc_init = ( + self.rng.random() ** (1 / 3) * 0.8 + 0.2 + if self.rng.random() < 0.12 + else 1 + ) + car = Car( + car_type, + car_number, + work_parking, + home_parking, + work_power, + home_power, + region, + soc_init, + ) + + if self.num_threads == 1: + print( + "\r{}% {} {} / {}".format( + round( + (cars_simulated + car_number + 1) + * 100 + / region.car_amount + ), + car.car_type.name, + (car.number + 1), + region.car_dict[car.car_type.name], + ), + end="", + flush=True, + ) + + # TODO profiles: add profiles to car on creation? or apply profiles during simulation? + # idea: create a list of trips that get simulated. code where? + + # if private run, check if private charging infrastructure is available + if self.private_only_run and (work_power or home_power): + try: + private_car = copy.copy(car) + private_car.private_only = True + self.simulate_car(private_car, region) + car = private_car + except SoCError: + exception_count += 1 + self.simulate_car(car, region) + else: + self.simulate_car(car, region) + + # export vehicle csv + if self.output_options["analyze"]: + car_array = car.export(region_directory, self) + if region.analyze_array is None: + region.analyze_array = car_array + else: + region.analyze_array = np.vstack( + (region.analyze_array, car_array) + ) + else: + car.export(region_directory, self) def get_charging_capacity(self, location=None, distance=None, distance_limit=50): """Determines charging capacity for specific charging event