Model module
The main MESA model for the agent-based simulation of heating system adoption.
This module defines the Prototype_Model class, which handles the entire agent-based simulation. It is responsible for initialising the environment, creating all agents (Houses, Houseowners, Plumbers, Energy Advisors), managing the simulation schedule, collecting data, and running the simulation loop. It also handles dynamic updates to the environment, such as changes in fuel costs or subsidy availability.
- Authors:
Ivan Digel <ivan.digel@uni-kassel.de>
Sascha Holzhauer <sascha.holzhauer@uni-kassel.de>
Dmytro Mykhailiuk <dmytromykhailiuk6@gmail.com>
Sören Lohr
- class Prototype_Model(*args: Any, **kwargs: Any)[source]
Bases:
ModelThe main MESA model for simulating heating system replacement decisions.
This class sets up and runs the agent-based simulation. It initialises the geographical space (GeoSpace), creates and populates it with agents based on input data (e.g., GeoJSON), and manages their interactions through a scheduler. The model also handles scenario-specific interventions, dynamic environmental changes, and comprehensive data collection.
- Attributes:
- spacemesa_geo.GeoSpace
The geographical environment where agents are located.
- schedulemesa.time.RandomActivationByType
The scheduler that controls the order of agent activation.
- scenarioScenario
The scenario object defining interventions and targets for the simulation run.
- datacollectormesa.DataCollector
The MESA object responsible for collecting model- and agent-level data.
- gridshobnetpy.SHoBNetworkGrid
The social network grid managing interactions between Houseowner agents.
- num_plumbersint
The number of Plumber agents in the model.
- num_energy_advisorsint
The number of EnergyAdvisor agents in the model.
- dropout_counterpd.DataFrame
A DataFrame tracking the reasons why houseowners did not choose certain heating systems.
- obstaclesdict
A dictionary for tracking agents at various stages of the decision-making process for target heating systems.
Initializes the simulation model.
This method orchestrates the complete setup of the simulation environment. It involves creating the geographical space, loading and processing building data from a GeoJSON file, and instantiating all agent populations: Houses, Houseowners with specific milieu and economic profiles, Plumbers, and Energy Advisors. It also establishes the social network between houseowners, configures scenario-specific parameters, and prepares a comprehensive data collector for tracking simulation outputs.
- Parameters:
- Pint
The number of Plumber agents to create.
- scenariostr
The name of the scenario class to be used for the simulation.
- Eint
The number of Energy Advisor agents to create.
- subsidy_to_observestr, optional
A specific subsidy to observe for visualization purposes. Defaults to None.
- known_hs_to_observestr, optional
A specific heating system to observe for visualization. Defaults to None.
- verbosebool, optional
If True, enables print statements during initialization. Defaults to True.
- geojson_pathstr, optional
The file path to the GeoJSON file containing house data.
- heating_distribution
Agent creator
- step()[source]
Executes a single time step in the simulation.
This method advances the model by one step. It first updates dynamic environmental variables (like fuel costs and subsidy availability), then applies any scenario-specific impacts, activates all scheduled agents to perform their actions, and finally collects all specified data for this step.
- run(steps, run_id, config_id)[source]
Runs the simulation for a specified number of steps and saves the results.
This method iterates through the step() method for the given number of steps. After the simulation is complete, it processes the data collected by the DataCollector and saves it to output files (e.g., CSV, Pickle).
- Parameters:
- stepsint
The total number of steps to run the simulation.
- run_idstr or int
A unique identifier for this specific simulation run, used for file naming.
- config_idstr or int
An identifier for the configuration used in this run.
- update_ownership()[source]
NOTE: Needs to be finalised by generating a social network for the new agent, otherwise it will not have any connections, including spatial neighbours. Then the method should be called at the very beginning of every model step. Also needs testing. Also refactor cognitive resource, it should not be random. —————— Simulates the change of house ownership for each houseowner.
Iterates through all Houseowner agents and, based on a small probability, replaces an existing houseowner with a new one. The new houseowner is generated with a fresh set of socio-demographic and psychological attributes, but inherits the same house. The old agent is removed from the model schedule and space, and the new one is added.
- update_availability()[source]
Updates the availability of heating systems based on the current step.
If a heating system’s availability term has expired, it is added to the list of globally infeasible options for all agents.
- update_contracts()[source]
Updates the remaining term of fixed-price fuel contracts for houseowners.
- update_emissions()[source]
Updates the emissions factors for heating systems based on dynamic data.
If the current step corresponds to a scheduled change in emissions, this method updates the heating_params_table and recalculates the emissions for all installed systems of that type.
- update_fuel_costs()[source]
Updates fuel costs for heating systems based on dynamic data.
If the current step corresponds to a scheduled change in fuel price, this method updates the heating_params_table and recalculates the fuel costs for all installed systems not under a fixed-price contract. It may also trigger a Trigger_fuel_price for affected houseowners.
- create_information_sources()[source]
Creates and returns a list of all available information source objects.
- map_milieus(row)[source]
Maps a milieu group number to its corresponding string label.
- Parameters:
- rowpd.Series
A row from the GeoJSON DataFrame containing milieu group data.
- Returns:
- str
The string label for the milieu (e.g., ‘Leading’).
- generate_heating_system(oil, gas, heat, elec, pellet)[source]
Generates a random heating system instance based on a given probability distribution.
- Parameters:
- oil, gas, heat, elec, pelletfloat
The probabilities for each respective heating system type.
- Returns:
- Heating_system
An instance of a randomly chosen heating system with a generated age.
- generate_clipped_age(min_val, max_val, mean, sd)[source]
Generates a system age from a truncated normal distribution.
- Returns:
- int
The generated age in simulation steps (weeks).
- distribute_heating_systems()[source]
Assigns initial heating systems to houses based on milieu-specific distributions.
- define_income(milieu: str)[source]
Generates a weekly income for a houseowner from a milieu-specific distribution. This time truncated normal.
- Parameters:
- milieustr
The milieu type of the houseowner.
- Returns:
- int
The generated weekly income.
- define_risk_tolerance(milieu: str)[source]
Defines a risk tolerance value for a houseowner based on their milieu.
- Parameters:
- milieustr
The milieu type of the houseowner.
- Returns:
- float
The agent’s risk tolerance value.
- define_cognitive_resource(milieu: str)[source]
Produces milieu-specific cognitive resource values
- Parameters:
- milieustr
The milieu type of the houseowner.
- Returns:
- int
The agent’s cognitive resource value.
- initial_meetings(agent, share=1.0)[source]
Performs initial knowledge spread to populate social norm-related memory parts of the Houseowner agents
- Parameters:
- agentHouseowner
The agent to perform meetings.
- share: float
The share of predecessor neighbours to meet
- calculate_total_expenses()[source]
Calculates the mean Levelized Cost of Heat (LCOH) across all houses.
- get_replacements_counter()[source]
Returns a copy of the dictionary counting heating system replacements.
- get_changes_counter()[source]
Returns a copy of the dictionary counting changes in heating technology.
- get_information_source_calls()[source]
Returns a dictionary summarising the calls to different information sources.
- get_dropouts()[source]
Returns a dictionary summarising the reasons agents dropped certain HS options.
- get_heating_distribution()[source]
Returns a copy of the dictionary tracking the distribution of installed heating systems.
- get_subsidised_hs()[source]
Returns a number indicating the amount of houses with a subsidised heating system.
- get_evaluation_quartiles()[source]
Computes quartiles of differences for each evaluation stored in evaluation_factors for all agents.
For each agent that has evaluation_factors, for each outer key (system type), this method computes, for each evaluation column, the difference between the evaluation of an inner key (target system) and the evaluation of the outer key (representative). Differences are collected from all agents. Finally, for each outer key and inner key, quartiles (Q1, median, Q3) are computed for each attribute.
- Returns:
- quartile_dictdict
- A nested dictionary where:
The first-level keys are the outer system types.
The second-level keys are the inner system types (all keys from the inner dictionary except the outer key).
Each inner value is a dictionary mapping each attribute to a tuple of quartiles (Q1, median, Q3) representing the distribution of differences (inner - outer) for that attribute.
- get_attribute_ratings()[source]
Creates a nested dictionary of quartiles of differences of opinions of all owners of non-target systems towards target systems relative to their owned system.
- Returns:
- quartile_dictdict
- A nested dictionary where:
The first-level keys are non-target systems (i.e. the owned system of the agent).
The second-level keys are target systems.
Each inner value is a dictionary mapping each attribute to a tuple of quartiles (Q1, median, Q3) representing the distribution of differences between the target system’s ratings and the owned system’s ratings.
- count_known_subsidies()[source]
Counts the total number of times each subsidy is known by a houseowner.
- count_known_hs()[source]
Counts the total number of times each heating system is known by a houseowner.
- calculate_target_fulfilment(scenario)[source]
Calculate the fulfilment percentages for each heating system in the scenario.
- Parameters:
- scenarioobject
The scenario object containing the target distribution of heating systems.
- Returns:
- float
The total fulfillment percentage.