{ "cells": [ { "cell_type": "code", "execution_count": null, "id": "b517d663", "metadata": {}, "outputs": [], "source": [ "# Préparation commune des TP Python\n", "# Le notebook utilise uniquement les ressources fournies dans le dossier codes/.\n", "from pathlib import Path\n", "import importlib.util\n", "import subprocess\n", "import sys\n", "\n", "REQUIRED_PACKAGES = {'numpy': 'numpy', 'pandas': 'pandas', 'matplotlib': 'matplotlib'}\n", "missing = [package for module, package in REQUIRED_PACKAGES.items()\n", " if importlib.util.find_spec(module) is None]\n", "if missing:\n", " print(\"Installation des paquets manquants :\", \", \".join(missing))\n", " subprocess.check_call([sys.executable, \"-m\", \"pip\", \"install\", *missing])\n", "\n", "WORKDIR = Path.cwd().resolve()\n", "CODES_DIR = WORKDIR.parent if WORKDIR.name == \"correction\" else WORKDIR\n", "TOOLBOX_DIR = CODES_DIR / \"toolbox\"\n", "DATA_DIR = CODES_DIR / \"data\"\n", "if not CODES_DIR.is_dir():\n", " raise FileNotFoundError(\"Exécutez le notebook depuis le dossier codes/.\" )\n", "if TOOLBOX_DIR.is_dir():\n", " sys.path.insert(0, str(TOOLBOX_DIR))\n", "\n", "DICE_FILE = TOOLBOX_DIR / \"DICE.py\"\n", "if not DICE_FILE.is_file():\n", " raise FileNotFoundError(\n", " f\"Module du cours introuvable : {DICE_FILE}. \"\n", " \"Téléchargez le dossier codes complet, avec toolbox/.\"\n", " )\n", "\n", "DATA_FILE = DATA_DIR / \"ngfs_scenarios.csv\"\n", "if not DATA_FILE.is_file():\n", " raise FileNotFoundError(\n", " f\"Donnée du cours introuvable : {DATA_FILE}. \"\n", " \"Téléchargez le dossier codes complet, avec data/.\"\n", " )\n", "\n", "print(\"Environnement prêt :\", CODES_DIR)\n" ] }, { "cell_type": "markdown", "id": "34cecbb0", "metadata": {}, "source": [ "# TP4 — Scénarios de transition et prix du carbone\n", "\n", "**Date de la séance :** mercredi 9 septembre 2026, 10:45–12:45\n", "\n", "**Objectifs**\n", "- Simuler des politiques climatiques contrastées avec DICE (variable de contrôle `mu`)\n", "- Comparer transition précoce et transition tardive\n", "- Manipuler les scénarios NGFS (prix du carbone, émissions, température)\n", "\n", "**Prérequis** : TP2, TP3." ] }, { "cell_type": "markdown", "id": "e3cc186f", "metadata": {}, "source": [ "## Partie 1 — Scénarios de transition" ] }, { "cell_type": "markdown", "id": "343ffaf6", "metadata": {}, "source": [ "**Question 1.** Simulez trois scénarios de politique climatique :\n", "- Aucune action : mu=0.03 (baseline)\n", "- Transition modérée : mu=0.3 dès 2025\n", "- Transition forte : mu=0.7 dès 2025" ] }, { "cell_type": "code", "execution_count": null, "id": "fb4059f1", "metadata": {}, "outputs": [], "source": [ "import DICE, numpy as np, pandas as pd, matplotlib.pyplot as plt\n", "\n", "p_base = DICE.Params()\n", "nT = p_base.nT\n", "\n", "scenarios_mu = {\n", " 'Aucune action (mu=0.03)': 0.03,\n", " 'Transition modérée (mu=0.3)': 0.3,\n", " 'Transition forte (mu=0.7)': 0.7\n", "}\n", "paths_transition = {}\n", "for name, mu_val in scenarios_mu.items():\n", " p = DICE.Params()\n", " path = DICE.init_states(p)\n", " path[1:, p.i_mu] = mu_val\n", " timevec = range(1, p.nT)\n", " path = DICE.update_path(path, timevec, p)\n", " paths_transition[name] = (p, path)" ] }, { "cell_type": "code", "execution_count": null, "id": "e52c6053", "metadata": {}, "outputs": [], "source": [ "# Expected output: les émissions et la température baissent avec l'intensité de l'abattement mu\n", "fig, axes = plt.subplots(1, 2, figsize=(13, 5))\n", "for name, (p, path) in paths_transition.items():\n", " axes[0].plot(path[:, p.i_time], path[:, p.i_E], label=name, linewidth=2)\n", " axes[1].plot(path[:, p.i_time], path[:, p.i_T_AT], label=name, linewidth=2)\n", "axes[0].set_title('Émissions E'); axes[0].set_xlabel('Année'); axes[0].legend(); axes[0].grid(True)\n", "axes[1].set_title('Température T_AT'); axes[1].set_xlabel('Année'); axes[1].legend(); axes[1].grid(True)\n", "plt.tight_layout()\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "f05b06ee", "metadata": {}, "source": [ "**Question 2.** Calculez la réduction d'émissions cumulées entre 2025 et 2100 pour chaque scénario par rapport au scénario de référence." ] }, { "cell_type": "code", "execution_count": null, "id": "0ddf4a7e", "metadata": {}, "outputs": [], "source": [ "# Expected output: la réduction cumulée croît avec mu ; la transition forte réduit fortement les émissions cumulées\n", "ref_name = 'Aucune action (mu=0.03)'\n", "p_ref, path_ref = paths_transition[ref_name]\n", "mask_2025 = path_ref[:, p_ref.i_time] >= 2025\n", "E_ref_cum = np.nansum(path_ref[mask_2025, p_ref.i_E])\n", "\n", "for name, (p, path) in paths_transition.items():\n", " mask = path[:, p.i_time] >= 2025\n", " E_cum = np.nansum(path[mask, p.i_E])\n", " reduction = E_ref_cum - E_cum\n", " print(f\"{name}: émissions cumulées 2025-2100 = {E_cum:.0f} GtCO2, réduction vs référence = {reduction:.0f} GtCO2\")" ] }, { "cell_type": "markdown", "id": "6ed0e376", "metadata": {}, "source": [ "## Partie 2 — Transition ordonnée vs désordonnée" ] }, { "cell_type": "markdown", "id": "5a8e61f7", "metadata": {}, "source": [ "**Question 3.** Comparez deux politiques :\n", "- Action précoce : mu=0.5 dès 2025\n", "- Action tardive : mu=0.5 seulement à partir de 2040" ] }, { "cell_type": "code", "execution_count": null, "id": "db915cf8", "metadata": {}, "outputs": [], "source": [ "# Expected output: l'action tardive conduit à une température plus élevée en 2100 malgré le même niveau final de mu\n", "p_early = DICE.Params()\n", "path_early = DICE.init_states(p_early)\n", "path_early[1:, p_early.i_mu] = 0.5\n", "path_early = DICE.update_path(path_early, range(1, p_early.nT), p_early)\n", "\n", "p_late = DICE.Params()\n", "path_late = DICE.init_states(p_late)\n", "year_col = p_late.t0 + p_late.Delta * (np.arange(1, p_late.nT))\n", "idx_2040 = np.where(year_col >= 2040)[0][0] + 1\n", "path_late[1:idx_2040, p_late.i_mu] = 0.03\n", "path_late[idx_2040:, p_late.i_mu] = 0.5\n", "path_late = DICE.update_path(path_late, range(1, p_late.nT), p_late)\n", "\n", "plt.figure(figsize=(9, 5))\n", "plt.plot(path_early[:, p_early.i_time], path_early[:, p_early.i_T_AT], label='Action précoce (dès 2025)', linewidth=2)\n", "plt.plot(path_late[:, p_late.i_time], path_late[:, p_late.i_T_AT], label='Action tardive (dès 2040)', linewidth=2, linestyle='--')\n", "plt.xlabel('Année'); plt.ylabel('T_AT (°C)')\n", "plt.title('Transition ordonnée vs transition retardée')\n", "plt.legend(); plt.grid(True)\n", "plt.show()\n", "\n", "print(f\"T_AT 2100 (action précoce) : {path_early[-1, p_early.i_T_AT]:.2f}°C\")\n", "print(f\"T_AT 2100 (action tardive) : {path_late[-1, p_late.i_T_AT]:.2f}°C\")" ] }, { "cell_type": "markdown", "id": "8c72fb4f", "metadata": {}, "source": [ "## Partie 3 — Scénarios NGFS" ] }, { "cell_type": "markdown", "id": "c07bdc5b", "metadata": {}, "source": [ "**Question 4.** Chargez les données NGFS et tracez les trajectoires de prix du carbone et d'émissions pour les trois scénarios." ] }, { "cell_type": "code", "execution_count": null, "id": "cf3a3bca", "metadata": {}, "outputs": [], "source": [ "# Expected output: NetZero2050 a le prix du carbone le plus élevé et les émissions les plus basses en fin de période ;\n", "# CurrentPolicies n'a pas de prix du carbone et des émissions quasi stables\n", "df_ngfs = pd.read_csv(DATA_DIR / \"ngfs_scenarios.csv\")\n", "fig, axes = plt.subplots(1, 2, figsize=(13, 5))\n", "for name, grp in df_ngfs.groupby('scenario'):\n", " axes[0].plot(grp['year'], grp['carbon_price_usd'], label=name, linewidth=2)\n", " axes[1].plot(grp['year'], grp['emissions_gtco2'], label=name, linewidth=2)\n", "axes[0].set_title('Prix du carbone (USD/tCO2)'); axes[0].set_xlabel('Année'); axes[0].legend(); axes[0].grid(True)\n", "axes[1].set_title('Émissions (GtCO2/an)'); axes[1].set_xlabel('Année'); axes[1].legend(); axes[1].grid(True)\n", "plt.tight_layout()\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "b1c03b14", "metadata": {}, "source": [ "## Interprétation" ] }, { "cell_type": "markdown", "id": "cc3b98b5", "metadata": {}, "source": [ "### Éléments de réponse\n", "\n", "- Plus l'abattement `mu` est élevé et précoce, plus les émissions cumulées et la température finale sont réduites : il existe un arbitrage direct entre effort de transition et réchauffement évité.\n", "- Retarder l'action climatique au même niveau d'ambition finale (`mu=0.5`) conduit à une température plus élevée en 2100 : le carbone déjà émis reste dans l'atmosphère pendant des siècles, donc chaque année de retard a un coût cumulatif irréversible sur la trajectoire de température.\n", "- Les scénarios NGFS structurent ce même arbitrage en 4 familles utilisées par les superviseurs financiers : une transition ordonnée et précoce limite le risque physique mais implique un prix du carbone élevé (risque de transition) ; une transition désordonnée ou retardée combine les deux risques." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "name": "python", "version": "3.10" } }, "nbformat": 4, "nbformat_minor": 5 }