Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Increase HP awareness over time #143

Merged
merged 6 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions k8s/job.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,18 @@ local job(name, args_excl_output) = {
'--price-gbp-per-kwh-electricity',
'0.182',
]),
job('03g-%s-awareness-intervention-policy' % std.extVar('SHORT_SHA'), [
'--intervention',
'heat_pump_awareness',
'--air-source-heat-pump-price-discount-date',
'2026-01-01:0.3',
'--price-gbp-per-kwh-gas',
'0.0682',
'--price-gbp-per-kwh-electricity',
'0.182',
'--heat-pump-awareness-intervention-factor',
'0.05',
]),
job('04a-%s-max-policy' % std.extVar('SHORT_SHA'), [
'--intervention',
'boiler_upgrade_scheme',
Expand Down Expand Up @@ -158,6 +170,29 @@ local job(name, args_excl_output) = {
'0.182',
'--include-new-builds'
]),
job('04d-%s-max-policy-awareness-intervention' % std.extVar('SHORT_SHA'), [
'--intervention',
'boiler_upgrade_scheme',
'--intervention',
'heat_pump_awareness',
'--intervention',
'gas_oil_boiler_ban',
'--gas-oil-boiler-ban-date',
'2035-01-01',
'--gas-oil-boiler-ban-announce-date',
'2025-01-01',
'--heat-pump-awareness',
'0.5',
'--air-source-heat-pump-price-discount-date',
'2026-01-01:0.3',
'--price-gbp-per-kwh-gas',
'0.0682',
'--price-gbp-per-kwh-electricity',
'0.182',
'--heat-pump-awareness-intervention-factor',
'0.05',
'--include-new-builds',
]),
job('05-%s-max-industry' % std.extVar('SHORT_SHA'), [
'--heat-pump-awareness',
'0.5',
Expand Down
8 changes: 8 additions & 0 deletions simulation/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,13 @@ def format_uuid(str):
help="Include new build projections (from constants.py). Installers will also build heat pumps in new builds from 2025.",
)

parser.add_argument(
"--heat-pump-awareness-intervention-factor",
type=float_between_0_and_1,
default=0.1,
help="A value between 0 and 1 which determines how quickly heat pump awareness increases over time with the heat pump awareness intervention. A value of 0 is equivalent to not applying the heat pump awareness intervention.",
)

def check_string_is_isoformat_datetime(string) -> str:
datetime.datetime.fromisoformat(string)
return string
Expand Down Expand Up @@ -226,6 +233,7 @@ def validate_args(args):
args.heat_pump_installer_count,
args.heat_pump_installer_annual_growth_rate,
ENGLAND_WALES_ANNUAL_NEW_BUILDS if args.include_new_builds else None,
args.heat_pump_awareness_intervention_factor,
)

with smart_open.open(args.history_file, "w") as file:
Expand Down
20 changes: 20 additions & 0 deletions simulation/agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ def reverse_sigmoid(x: float, k: float = SIGMOID_K, offset: float = SIGMOID_OFFS
return 1 / (1 + math.exp(k * (x + offset)))


def heat_pump_awareness_intervention(x: float, m: float):

return min(m * x, 1)


class Household(Agent):
def __init__(
self,
Expand Down Expand Up @@ -416,6 +421,14 @@ def get_proba_rule_out_banned_heating_systems(self, model):

return reverse_sigmoid(years_to_ban)

def get_proba_becomes_heat_pump_aware(self, model):

years_since_start = (model.current_datetime - model.start_datetime).days / 365

return heat_pump_awareness_intervention(
years_since_start, model.heat_pump_awareness_intervention_factor
)

def get_heating_system_options(
self, model: "DomesticHeatingABM", event_trigger: EventTrigger
) -> Set[HeatingSystem]:
Expand All @@ -440,6 +453,13 @@ def get_heating_system_options(
[HeatingSystem.BOILER_GAS, HeatingSystem.BOILER_OIL]
)

if InterventionType.HEAT_PUMP_AWARENESS in model.interventions:
# if awareness intervention used, allow for more agents to become aware of heat pumps
if not self.is_heat_pump_aware:
self.is_heat_pump_aware = true_with_probability(
self.get_proba_becomes_heat_pump_aware(model)
)

if not is_gas_oil_boiler_ban_announced:
# if a gas/boiler ban is announced, we assume all households are aware of heat pumps
if not self.is_heat_pump_aware:
Expand Down
1 change: 1 addition & 0 deletions simulation/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ class InterventionType(enum.Enum):
BOILER_UPGRADE_SCHEME = 1
GAS_OIL_BOILER_BAN = 2
EXTENDED_BOILER_UPGRADE_SCHEME = 3
HEAT_PUMP_AWARENESS = 4


# Source: https://www.ons.gov.uk/peoplepopulationandcommunity/birthsdeathsandmarriages/families/datasets/householdsbytypeofhouseholdandfamilyregionsofenglandandukconstituentcountries
Expand Down
4 changes: 2 additions & 2 deletions simulation/costs.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ def estimate_boiler_upgrade_scheme_grant(
return 0

model_population_scale = ENGLAND_WALES_HOUSEHOLD_COUNT_2020 / model.household_count
boiler_upgrade_funding_cap_gbp = 450_000_000 / model_population_scale
boiler_upgrade_funding_cap_gbp = 237_500_000 / model_population_scale
if (
model.boiler_upgrade_scheme_cumulative_spend_gbp
>= boiler_upgrade_funding_cap_gbp
Expand Down Expand Up @@ -345,7 +345,7 @@ def estimate_extended_boiler_upgrade_scheme_grant(
return 0

model_population_scale = ENGLAND_WALES_HOUSEHOLD_COUNT_2020 / model.household_count
boiler_upgrade_funding_cap_gbp = 1_650_000_000 / model_population_scale
boiler_upgrade_funding_cap_gbp = 5_400_000_000 / model_population_scale
if (
model.boiler_upgrade_scheme_cumulative_spend_gbp
>= boiler_upgrade_funding_cap_gbp
Expand Down
6 changes: 6 additions & 0 deletions simulation/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ def __init__(
heat_pump_installer_count: int,
heat_pump_installer_annual_growth_rate: float,
annual_new_builds: Optional[Dict[int, int]],
heat_pump_awareness_intervention_factor: float,
):
self.start_datetime = start_datetime
self.step_interval = step_interval
Expand Down Expand Up @@ -74,6 +75,9 @@ def __init__(
)
self.heat_pump_installations_at_current_step = 0
self.annual_new_builds = annual_new_builds
self.heat_pump_awareness_intervention_factor = (
heat_pump_awareness_intervention_factor
)

super().__init__(UnorderedSpace())

Expand Down Expand Up @@ -263,6 +267,7 @@ def create_and_run_simulation(
heat_pump_installer_count: int,
heat_pump_installer_annual_growth_rate: float,
annual_new_builds: Dict[int, int],
heat_pump_awareness_intervention_factor: float,
):

model = DomesticHeatingABM(
Expand All @@ -282,6 +287,7 @@ def create_and_run_simulation(
heat_pump_installer_count=heat_pump_installer_count,
heat_pump_installer_annual_growth_rate=heat_pump_installer_annual_growth_rate,
annual_new_builds=annual_new_builds,
heat_pump_awareness_intervention_factor=heat_pump_awareness_intervention_factor,
)

households = create_household_agents(
Expand Down
1 change: 1 addition & 0 deletions simulation/tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ def model_factory(**model_attributes):
"heat_pump_installer_count": 2_800,
"heat_pump_installer_annual_growth_rate": 0,
"annual_new_builds": None,
"heat_pump_awareness_intervention_factor": 0.0,
}

return DomesticHeatingABM(**{**default_values, **model_attributes})
2 changes: 1 addition & 1 deletion simulation/tests/household_population.csv
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ id,location,property_value_gbp,total_floor_area_m2,is_off_gas_grid,construction_
5,BIRMINGHAM,500000,100,True,BUILT_PRE_1900,BUNGALOW,MID_TERRACE,BOILER_OIL,F,B,RENTED_SOCIAL,False,3,4,4,False
6,BIRMINGHAM,400000,190,False,BUILT_1900_1929,FLAT,END_TERRACE,BOILER_ELECTRIC,E,C,RENTED_PRIVATE,False,1,4,4,False
7,LONDON,300000,50,True,BUILT_1900_1929,FLAT,SEMI_DETACHED,BOILER_GAS,F,E,OWNER_OCCUPIED,True,2,1,3,True
8,MANCHESTER,600000,80,False,BUILT_PRE_1900,BUNGALOW,MID_TERRACE,BOILER_OIL,B,B,RENTED_PRIVATE,True,2,3,2,False
8,MANCHESTER,600000,80,False,BUILT_PRE_1900,BUNGALOW,MID_TERRACE,BOILER_OIL,B,B,RENTED_PRIVATE,True,2,3,2,False
37 changes: 37 additions & 0 deletions simulation/tests/test_agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,43 @@ def test_household_ability_to_choose_heat_pump_as_option_depends_on_model_heat_p

assert all(heat_pump in heating_system_options for heat_pump in HEAT_PUMPS)

def test_households_increasingly_likely_to_become_heat_pump_aware(
self,
):
household = household_factory()
model = model_factory(
start_datetime=datetime.datetime(2025, 1, 1),
interventions=[InterventionType.HEAT_PUMP_AWARENESS],
heat_pump_awareness_intervention_factor=0.1,
)

proba_becomes_heat_pump_aware = household.get_proba_becomes_heat_pump_aware(
model
)

model.increment_timestep()
proba_becomes_heat_pump_aware_updated = (
household.get_proba_becomes_heat_pump_aware(model)
)

assert proba_becomes_heat_pump_aware < proba_becomes_heat_pump_aware_updated

def test_heat_pump_awareness_increase_is_zero_in_first_year(
self,
):
household = household_factory()
model = model_factory(
start_datetime=datetime.datetime(2024, 1, 1),
interventions=[InterventionType.HEAT_PUMP_AWARENESS],
heat_pump_awareness_intervention_factor=0.1,
)

proba_becomes_heat_pump_aware = household.get_proba_becomes_heat_pump_aware(
model
)

assert proba_becomes_heat_pump_aware == 0


class TestAgentsWithBoilerBan:
def test_households_increasingly_likely_to_rule_out_heating_systems_that_will_be_banned_as_time_to_ban_decreases(
Expand Down
4 changes: 2 additions & 2 deletions simulation/tests/test_costs.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ def test_boiler_upgrade_scheme_grant_is_zero_when_grant_cap_exceeded(
model_population_scale = (
ENGLAND_WALES_HOUSEHOLD_COUNT_2020 / model.household_count
)
boiler_upgrade_scheme_budget_scaled = 450_000_000 / model_population_scale
boiler_upgrade_scheme_budget_scaled = 237_500_000 / model_population_scale

model.boiler_upgrade_scheme_cumulative_spend_gbp = (
boiler_upgrade_scheme_budget_scaled * 0.8
Expand Down Expand Up @@ -338,7 +338,7 @@ def test_extended_boiler_upgrade_scheme_grant_is_zero_when_grant_cap_exceeded(
model_population_scale = (
ENGLAND_WALES_HOUSEHOLD_COUNT_2020 / model.household_count
)
boiler_upgrade_scheme_budget_scaled = 1_650_000_000 / model_population_scale
boiler_upgrade_scheme_budget_scaled = 5_400_000_000 / model_population_scale

model.boiler_upgrade_scheme_cumulative_spend_gbp = (
boiler_upgrade_scheme_budget_scaled * 0.8
Expand Down
21 changes: 21 additions & 0 deletions simulation/tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,24 @@ def test_rented_heating_system_hassle_factor_must_be_between_0_and_1(
[*mandatory_local_args, "--rented-heating-system-hassle-factor", "10"]
)

def test_heat_pump_awareness_intervention_factor(self, mandatory_local_args):
args = parse_args(
[*mandatory_local_args, "--rented-heating-system-hassle-factor", "0.05"]
)
assert args.rented_heating_system_hassle_factor == 0.05

def test_heat_pump_awareness_intervention_factor_must_be_between_0_and_1(
self, mandatory_local_args
):
with pytest.raises(SystemExit):
parse_args(
[
*mandatory_local_args,
"--heat-pump-awareness-intervention-factor",
"10.0",
]
)

def test_help_flag(self):
with pytest.raises(SystemExit):
parse_args(["-h"])
Expand Down Expand Up @@ -158,13 +176,16 @@ def test_intervention_argument(self, mandatory_local_args):
"boiler_upgrade_scheme",
"--intervention",
"extended_boiler_upgrade_scheme",
"--intervention",
"heat_pump_awareness",
]
)

assert args.intervention == [
InterventionType.RHI,
InterventionType.BOILER_UPGRADE_SCHEME,
InterventionType.EXTENDED_BOILER_UPGRADE_SCHEME,
InterventionType.HEAT_PUMP_AWARENESS,
]

def test_gas_oil_boiler_ban_date_returns_datetime(self, mandatory_local_args):
Expand Down
Loading