{ "cells": [ { "cell_type": "code", "execution_count": null, "id": "e7477e84", "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", "print(\"Environnement prêt :\", CODES_DIR)\n" ] }, { "cell_type": "markdown", "id": "d74df63f", "metadata": {}, "source": [ "# TP2 — Modèle climatique simplifié et sensibilité\n", "\n", "**Date de la séance :** mercredi 2 septembre 2026, 10:45–12:45\n", "\n", "**Objectifs**\n", "- Prendre en main le modèle climat-économie DICE\n", "- Simuler une trajectoire de référence 2015-2100\n", "- Étudier l'effet de la sensibilité climatique (T2XCO2) sur la température\n", "- Comprendre l'inertie du système climatique\n", "\n", "**Prérequis** : TP1, notions de base sur les modèles climatiques simplifiés (bloc carbone / bloc température)." ] }, { "cell_type": "code", "execution_count": null, "id": "5321a4f5", "metadata": {}, "outputs": [], "source": [ "import numpy as np, pandas as pd, matplotlib.pyplot as plt\n", "import DICE" ] }, { "cell_type": "markdown", "id": "f8e38317", "metadata": {}, "source": [ "## Partie 1 — Prise en main du modèle DICE" ] }, { "cell_type": "markdown", "id": "17cb9a73", "metadata": {}, "source": [ "**Question 1.** Importez DICE, créez les paramètres par défaut et lancez une simulation de référence.\n", "\n", "*Note technique* : `DICE.update_path` s'utilise avec la signature `update_path(sim, timevec, p)`, où `timevec` est la liste des indices de temps à simuler (typiquement `range(1, p.nT)`, car l'indice 0 correspond à l'état initial 2015)." ] }, { "cell_type": "code", "execution_count": null, "id": "bb9dc594", "metadata": {}, "outputs": [], "source": [ "p = DICE.Params()\n", "path = DICE.init_states(p)\n", "timevec = range(1, p.nT)\n", "path = DICE.update_path(path, timevec, p)\n", "print(f\"Simulation de {p.t0} à {p.tT} — {p.nT} périodes de {p.Delta} ans\")" ] }, { "cell_type": "markdown", "id": "5ad2ff91", "metadata": {}, "source": [ "**Question 2.** Tracez les trajectoires de T_AT (température), E (émissions), M_AT (CO2 atmosphérique) de 2015 à 2100." ] }, { "cell_type": "code", "execution_count": null, "id": "d00d6b0b", "metadata": {}, "outputs": [], "source": [ "# Expected output: T_AT croît d'environ 0.85°C (2015) à ~3-4°C (2100) dans ce scénario sans politique climatique\n", "fig, axes = plt.subplots(1, 3, figsize=(15, 4))\n", "axes[0].plot(path[:, p.i_time], path[:, p.i_T_AT], color='tab:red')\n", "axes[0].set_title('Température atmosphérique T_AT (°C)')\n", "axes[0].set_xlabel('Année'); axes[0].grid(True)\n", "\n", "axes[1].plot(path[:, p.i_time], path[:, p.i_E], color='tab:orange')\n", "axes[1].set_title('Émissions de CO2 E (GtCO2/période)')\n", "axes[1].set_xlabel('Année'); axes[1].grid(True)\n", "\n", "axes[2].plot(path[:, p.i_time], path[:, p.i_M_AT], color='tab:brown')\n", "axes[2].set_title('Carbone atmosphérique M_AT (GtC)')\n", "axes[2].set_xlabel('Année'); axes[2].grid(True)\n", "plt.tight_layout()\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "b15d1a72", "metadata": {}, "source": [ "## Partie 2 — Sensibilité climatique" ] }, { "cell_type": "markdown", "id": "9b1335fe", "metadata": {}, "source": [ "**Question 3.** La sensibilité climatique T2XCO2 mesure le réchauffement à l'équilibre pour un doublement du CO2. Simulez le modèle avec T2XCO2 = 1.5, 3.1 (référence), 4.5. Tracez les trajectoires de T_AT pour les trois cas." ] }, { "cell_type": "code", "execution_count": null, "id": "ac10ffc3", "metadata": {}, "outputs": [], "source": [ "sensitivities = [1.5, 3.1, 4.5]\n", "labels = ['T2XCO2 = 1.5°C (faible)', 'T2XCO2 = 3.1°C (référence)', 'T2XCO2 = 4.5°C (élevée)']\n", "paths = []\n", "for T2X in sensitivities:\n", " p_s = DICE.Params(T2XCO2=T2X)\n", " path_s = DICE.init_states(p_s)\n", " timevec_s = range(1, p_s.nT)\n", " path_s = DICE.update_path(path_s, timevec_s, p_s)\n", " paths.append(path_s)" ] }, { "cell_type": "code", "execution_count": null, "id": "557269fc", "metadata": {}, "outputs": [], "source": [ "# Expected output: écart net en 2100 entre les trois courbes, l'écart s'accroît avec l'horizon temporel\n", "plt.figure(figsize=(9, 5))\n", "for path_s, label in zip(paths, labels):\n", " plt.plot(path_s[:, p.i_time], path_s[:, p.i_T_AT], label=label, linewidth=2)\n", "plt.xlabel('Année')\n", "plt.ylabel('T_AT (°C)')\n", "plt.title(\"Sensibilité climatique et trajectoire de température\")\n", "plt.legend()\n", "plt.grid(True)\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "fc9c2406", "metadata": {}, "source": [ "**Question 4.** Calculez l'écart de température en 2100 entre le cas le plus favorable et le plus défavorable. Que représente cet écart pour la gestion des risques ?" ] }, { "cell_type": "code", "execution_count": null, "id": "dedc2d31", "metadata": {}, "outputs": [], "source": [ "# Expected output: écart de l'ordre de 2 à 3°C en 2100 entre T2XCO2=1.5 et T2XCO2=4.5\n", "T_2100_low = paths[0][-1, p.i_T_AT]\n", "T_2100_high = paths[-1][-1, p.i_T_AT]\n", "print(f\"T_AT en 2100, sensibilité faible (1.5) : {T_2100_low:.2f}°C\")\n", "print(f\"T_AT en 2100, sensibilité élevée (4.5) : {T_2100_high:.2f}°C\")\n", "print(f\"Écart : {T_2100_high - T_2100_low:.2f}°C\")" ] }, { "cell_type": "markdown", "id": "c691f921", "metadata": {}, "source": [ "## Partie 3 — Inertie climatique" ] }, { "cell_type": "markdown", "id": "3ae9e697", "metadata": {}, "source": [ "**Question 5.** Simulez un scénario où les émissions tombent à 0 en 2030 (mu=1 à partir de 2030). La température continue-t-elle de monter ? Pourquoi ?" ] }, { "cell_type": "code", "execution_count": null, "id": "5ea67ea1", "metadata": {}, "outputs": [], "source": [ "# Expected output: T_AT continue à croître légèrement après 2030 malgré des émissions nettes nulles,\n", "# du fait de l'inertie thermique de l'océan (T_LO qui rattrape T_AT) et du stock de CO2 déjà accumulé\n", "p_zero = DICE.Params()\n", "path_zero = DICE.init_states(p_zero)\n", "# 2030 correspond à l'indice t tel que time = 2030 -> t = (2030-2015)/5 = 3\n", "year_col = p_zero.t0 + p_zero.Delta * (np.arange(1, p_zero.nT))\n", "idx_2030 = np.where(year_col >= 2030)[0][0] + 1\n", "path_zero[1:idx_2030, p_zero.i_mu] = 0.03\n", "path_zero[idx_2030:, p_zero.i_mu] = 1.0\n", "timevec_zero = range(1, p_zero.nT)\n", "path_zero = DICE.update_path(path_zero, timevec_zero, p_zero)\n", "\n", "plt.figure(figsize=(9, 5))\n", "plt.plot(path_zero[:, p_zero.i_time], path_zero[:, p_zero.i_T_AT], color='tab:red', label='T_AT')\n", "plt.axvline(2030, color='grey', linestyle='--', label='Arrêt des émissions nettes')\n", "plt.xlabel('Année'); plt.ylabel('T_AT (°C)')\n", "plt.title(\"Inertie climatique : la température continue de monter après l'arrêt des émissions\")\n", "plt.legend(); plt.grid(True)\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "f11a3d3b", "metadata": {}, "source": [ "## Interprétation\n", "\n", "Répondez en quelques phrases :\n", "1. Quelle est la température atmosphérique prévue en 2100 dans le scénario de référence ?\n", "2. Pourquoi la sensibilité climatique est-elle une source d'incertitude majeure ?\n", "3. Qu'est-ce que l'inertie climatique et quelles sont ses implications pour les risques à long terme ?\n", "4. Dans quel sens cette incertitude affecte-t-elle la tarification d'un produit d'assurance catastrophe ?" ] }, { "cell_type": "markdown", "id": "da8023f1", "metadata": {}, "source": [ "### Éléments de réponse\n", "\n", "1. Dans le scénario de référence (T2XCO2=3.1, pas de politique climatique), T_AT atteint environ 3 à 4°C en 2100.\n", "2. La sensibilité climatique n'est pas connue avec précision : le GIEC AR6 l'estime dans une fourchette probable de 2,5 à 4°C (intervalle *likely*), avec des scénarios extrêmes crédibles en dehors de cette plage. Cette incertitude irréductible se traduit directement en incertitude sur les températures futures pour un même scénario d'émissions.\n", "3. L'inertie climatique désigne le décalage entre la stabilisation des émissions/concentrations et la stabilisation de la température, dû à la capacité thermique de l'océan profond. Cela implique qu'un stock de réchauffement est déjà « engagé » même après l'arrêt des émissions, ce qui a des conséquences directes sur l'horizon d'exposition aux risques physiques pour un assureur.\n", "4. Cette incertitude doit conduire à intégrer une marge de prudence dans la tarification et à ne pas se limiter à un scénario central : il est nécessaire de raisonner en distribution de scénarios (cf. TP5) plutôt qu'en projection déterministe unique." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "name": "python", "version": "3.10" } }, "nbformat": 4, "nbformat_minor": 5 }