Guided exercise: add a new impact sector
In this exercise, you will add a fictional impact sector: heat-related damage to outdoor equipment. Imagine that hotter conditions increase the cost of repairing and replacing equipment. We will represent these extra costs with a simple relation between temperature and economic damages.
The sector and its coefficient are invented for this exercise. The purpose is to practise adding a model relationship, rather than reproduce an existing impact study.
You will learn how to:
- add a variable and an equation to a prepared component;
- include the new sector in total damages, so it affects GDP;
- make the damage coefficient configurable and compare different assumptions.
Ideas for your own extension
The equipment-damage example below shows the basic steps. For your own project, you could apply them to one of these questions. Some ideas start with changing existing assumptions; others require a new variable or equation. Choose one small change and compare its results with the original model.
-
Mitigation and fairness
- Who pays? Compare fairness rules or propose a different way to share mitigation costs between regions.
- Act now or later? Explore delayed mitigation or pathways that temporarily exceed a temperature target before returning below it (overshoot).
- Reduce demand? Represent lower energy or material demand and its effect on emissions and mitigation costs.
How it works now: Mitigation costs and learning, effort-sharing, emission trading and emissions and temperature limits.
-
Impacts and adaptation
- A new impact sector? Add a simple damage relationship for a sector such as infrastructure or ecosystem services, or explore biodiversity loss.
- Who is affected? Explore how the same warming causes different damages across regions, or how impacts are shared between population groups.
- Thresholds and protection? Explore damages that rise sharply beyond a warming threshold, or add a measure that reduces a sector's damages.
How it works now: COACCH damage functions, ACCREU sectors and adaptation and welfare and inequality.
-
Climate and sea-level rise
- Different warming responses? Explore how strongly temperature responds to cumulative emissions, or propose an alternative relationship.
- Long-lasting consequences? Investigate how sea-level rise continues after temperature stabilises.
- Climate tipping points? Add a simplified feedback that starts above a temperature threshold, such as extra emissions or faster ice loss.
How it works now: Emissions and temperature and sea-level-rise contributions.
-
Economy and development pathways
- A different future? Compare Shared Socioeconomic Pathways (SSPs), or supply your own population, GDP or baseline emissions assumptions.
- Lower growth or degrowth? Explore alternative economic trajectories and their consequences for emissions, consumption and welfare.
- A different economy? Change how investment, productivity or production affects GDP, starting with one relationship in the economic module.
How it works now: GDP, investment and consumption, welfare and time- and region-dependent input data.
Where to work
Your course branch already contains mimosa/components/new_component.py, with the
empty get_constraints(m, inputs) function. It is already connected in
model_builder.py, so MIMOSA will include your additions automatically.
You will use these files:
mimosa/
├── components/
│ ├── new_component.py # Add the new sector here
│ └── damages/
│ └── coacch.py # Include it in total damages
└── inputdata/
└── config/
└── config_default.yaml # Define the new parameter here
run_extension.py # Create this script to run the exercise
All paths start from MIMOSA's main directory: the folder containing the mimosa
folder and pyproject.toml.
This exercise uses the COACCH damage module and assumes your editable copy of MIMOSA
is ready to run.
Inside get_constraints, m is the model. A variable holds a model result, a
parameter supplies an assumption, and an equation describes how to calculate
one variable from other model quantities.
Our fictional damage function
We assume that each additional degree of warming causes extra equipment damage costs equal to 0.2% of gross GDP:
Here \(T_t\) is the temperature at timestep \(t\), and \(T_0\) is the temperature at the model start. Subtracting \(T_0\) makes extra damages zero in the initial year. Under this simple linear relation, cooling below the initial temperature would give a benefit, represented by a negative damage value.
We store damages as a fraction, so 0.002 means 0.2%. For example, one degree
of additional warming gives 0.002, and two degrees give 0.004, or 0.4% of GDP.
We use the same damage fraction in every region for this exercise.
1. Add a variable
Open mimosa/components/new_component.py. The names used below, including Var,
Param and RegionalEquation, are already imported in your starter file.
Inside get_constraints, add the following code to define a new variable:
# Add your variables and parameters here
m.equipment_damage_costs = Var(
m.t,
m.regions,
doc="Fictional extra damage costs from heat-sensitive outdoor equipment, as a fraction of gross GDP, relative to the model start.",
)
| Part | Meaning |
|---|---|
m.equipment_damage_costs |
The name of the new variable on the model |
Var(m.t, m.regions, ...) |
Store a value for every timestep and region |
doc=... |
A short description of the variable |
See Variables for more ways to define variables.
2. Add the damage equation
In the same file, replace the empty constraints = [...] block with:
constraints = [
RegionalEquation(
m.equipment_damage_costs,
lambda m, t, r: 0.002 * (m.temperature[t] - m.T0),
),
]
Keep the existing return constraints line below it. This returns your equation to
MIMOSA so it can be used when running the model.
Read lambda m, t, r: ... as: “For this timestep and region, calculate the expression
after the colon.” MIMOSA applies it to every timestep and region for you.
tidentifies a timestep andridentifies a region.m.temperature[t]is the global temperature at that timestep; it has no region index.m.T0is the initial temperature, which is the same for all timesteps and regions.- The first argument,
m.equipment_damage_costs, names the result being calculated and is written without[t, r].
See Equations for more detail on
RegionalEquation and the lambda notation.
Save new_component.py before continuing.
3. Run the model and check your calculation
Create run_extension.py in MIMOSA's main directory and paste in:
from mimosa import MIMOSA, load_params
params = load_params()
model = MIMOSA(params)
simulation = model.run_simulation()
model.save_simulation(simulation, "guided_exercise")
This is a no-policy simulation using all default parameters, regions and timesteps.
Calling run_simulation() without control values sets mitigation to zero. This
exercise uses simulation and does not need IPOPT.
Run the script from MIMOSA's main directory:
The results are saved to output/guided_exercise.csv. You can open this file in
Excel, or open the MIMOSA Dashboard
and drag and drop the CSV file onto it to explore the results.
In the CSV, the Variable and Region columns identify each row, and the year
columns contain the results. Your new variable is included automatically. Look for:
| Variable | Region | What to check |
|---|---|---|
equipment_damage_costs |
USA |
Extra damages are zero in 2025 and positive in 2050. Values are fractions of GDP, so 0.002 means 0.2%. |
temperature |
Global |
The temperature values in 2025 and 2050 show how much additional warming has occurred. |
GDP_net |
USA |
Write down the value in the 2050 column to compare after the next step. |
To check your equation using the CSV, subtract the 2025 temperature from the 2050
temperature and multiply by 0.002. This should match the equipment damage
fraction in the 2050 column, allowing for rounding in the saved values.
At this stage, the new damage variable is calculated and saved. The next step makes it part of the damages deducted from GDP.
4. Include the new sector in total damages
Open mimosa/components/damages/coacch.py. Inside get_constraints, find the
RegionalEquation for m.damage_costs. It currently adds m.non_slr_damage_costs
and m.slr_damage_costs.
Replace only that equation with the version below, which adds your new sector. Keep the other equations and the surrounding list in place:
RegionalEquation(
m.damage_costs,
lambda m, t, r: (
m.non_slr_damage_costs[t, r]
+ m.slr_damage_costs[t, r]
+ m.equipment_damage_costs[t, r]
),
),
The total damage fraction now includes the new equipment damages. The existing COACCH equations convert total damages to currency units and calculate the global total. The economic module deducts the total damage costs from GDP, which affects consumption and welfare as well.
Save coacch.py and run run_extension.py again. Reopen the CSV in Excel or load
the new file into the dashboard. Check the equipment damage value and compare
GDP_net for the USA in 2050 with the value you wrote down. It should be lower
when the extra damages are included. Each run replaces the previous
output/guided_exercise.csv file.
For this exercise, we treat the fictional equipment sector as an additional impact that is not already included in the COACCH damage functions.
5. Make the damage coefficient configurable
The value 0.002 is currently written directly in the equation. We will turn it
into a parameter so you can choose a different value from your run script.
Open mimosa/inputdata/config/config_default.yaml. Find economics:, then the
existing damages: section beneath it. Add equipment_damage_coefficient at the
same indentation level as scale factor:
economics:
damages:
equipment_damage_coefficient:
descr: Fictional equipment damage fraction per degree of additional warming
type: float
min: 0
default: 0.002
Keep the existing economics: and damages: headings and all their other entries.
Only add the new parameter entry.
type: float means the value is a decimal number, and min: 0 prevents a negative
coefficient. We interpret the number as the damage fraction per additional degree
of warming. The default remains 0.002.
See Adding parameters from configuration for more detail on defining a new configuration entry.
In new_component.py, add this declaration above constraints = [...], alongside
your variable declaration:
m.equipment_damage_coefficient = Param(
initialize=inputs.config("economics.damages.equipment_damage_coefficient"),
doc="Fictional equipment damage fraction per degree of warming above the model's initial temperature.",
)
inputs.config(...) reads the value from the configuration. Its name on the model
is m.equipment_damage_coefficient, and it has the same value for every timestep
and region.
Finally, replace the constraints = [...] block in new_component.py with:
constraints = [
RegionalEquation(
m.equipment_damage_costs,
lambda m, t, r: m.equipment_damage_coefficient * (m.temperature[t] - m.T0),
),
]
Save both files and run the script again. The results should match your previous
run when you open the new CSV in Excel or the dashboard: you have changed where
the coefficient comes from, while keeping its value at 0.002 per degree.
6. Try a stronger damage assumption
Replace the contents of run_extension.py with the complete script below. The
highlighted lines change the coefficient and save this run with a different filename:
from mimosa import MIMOSA, load_params
params = load_params()
params["economics"]["damages"]["equipment_damage_coefficient"] = 0.004
model = MIMOSA(params)
simulation = model.run_simulation()
model.save_simulation(simulation, "guided_exercise_stronger_damages")
This doubles the damage fraction assigned to a given amount of additional warming:
from 0.2% to 0.4% of GDP per degree. Save and rerun the script. The new results
are saved to output/guided_exercise_stronger_damages.csv, keeping the original
output/guided_exercise.csv available for comparison.
Open both files in Excel, or drag and drop both into the
MIMOSA Dashboard. Compare
equipment_damage_costs and GDP_net for the same region and year. You can now
change this assumption without editing the component or its configuration defaults.
As a second check, set the coefficient to 0 in the parameter line and rerun. In
the new CSV, equipment_damage_costs should be zero in every year.
For more ways to supply parameter values, including regional data, see Adding parameters and data.
Check your completed component
Your completed mimosa/components/new_component.py should look like this:
from mimosa.common import (
ConcreteModel,
RegionalEquation,
GlobalEquation,
Var,
Param,
)
from mimosa.core.model_inputs import ModelInputs
def get_constraints(m: ConcreteModel, inputs: ModelInputs):
"""Fictional heat-related equipment damages for the guided exercise."""
m.equipment_damage_costs = Var(
m.t,
m.regions,
doc="Fictional extra damage costs from heat-sensitive outdoor equipment, as a fraction of gross GDP, relative to the model start.",
)
m.equipment_damage_coefficient = Param(
initialize=inputs.config("economics.damages.equipment_damage_coefficient"),
doc="Fictional equipment damage fraction per degree of warming above the model's initial temperature.",
)
constraints = [
RegionalEquation(
m.equipment_damage_costs,
lambda m, t, r: m.equipment_damage_coefficient * (m.temperature[t] - m.T0),
),
]
return constraints