diff --git a/dev/Untitled1.ipynb b/dev/Untitled1.ipynb index ac4135e3..a582c1d9 100644 --- a/dev/Untitled1.ipynb +++ b/dev/Untitled1.ipynb @@ -26,7 +26,7 @@ { "cell_type": "code", "execution_count": 3, - "id": "36f6ad96-f512-48c5-80e8-b36276d42b43", + "id": "eaf5bc31-826a-440f-bace-0138b3f1cdb9", "metadata": {}, "outputs": [ { @@ -43,7 +43,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "id": "bee86950-ac96-49e0-8a9c-43920ae26096", "metadata": {}, "outputs": [ @@ -87,6 +87,566 @@ "NewDatabase(..., quiet=True)\n", "- Extracting source database\n", "- Extracting inventories\n", + "Cannot find cached inventories. Will create them now for next time...\n", + "Importing default inventories...\n", + "\n", + "Extracted 1 worksheets in 0.10 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.01 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.01 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.02 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.01 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.01 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 7 worksheets in 0.03 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.02 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.01 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.02 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.03 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.02 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.03 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Could not find a biosphere flow for ('Iron, 72% in magnetite, 14% in crude ore', 'natural resource', 'in ground', 'kilogram') in lci-vanadium.xlsx. Exchange deleted.\n", + "Could not find a biosphere flow for ('TiO2, 54% in ilmenite, 18% in crude ore, in ground', 'natural resource', 'in ground', 'kilogram') in lci-vanadium.xlsx. Exchange deleted.\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.02 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.01 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.01 seconds\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.39 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "The following datasets to import already exist in the source database. They will not be imported\n", + "+--------------------------------+--------------------------------+----------+-------------+\n", + "| Name | Reference product | Location | File |\n", + "+--------------------------------+--------------------------------+----------+-------------+\n", + "| fluorspar production, 97% puri | fluorspar, 97% purity | GLO | lci-PV.xlsx |\n", + "| metallization paste production | metallization paste, back side | RER | lci-PV.xlsx |\n", + "| metallization paste production | metallization paste, back side | RER | lci-PV.xlsx |\n", + "| metallization paste production | metallization paste, front sid | RER | lci-PV.xlsx |\n", + "| photovoltaic module production | photovoltaic module, building- | RER | lci-PV.xlsx |\n", + "| photovoltaic module production | photovoltaic module, building- | RER | lci-PV.xlsx |\n", + "| photovoltaic mounting system p | photovoltaic mounting system, | RER | lci-PV.xlsx |\n", + "| photovoltaic mounting system p | photovoltaic mounting system, | RER | lci-PV.xlsx |\n", + "| photovoltaic mounting system p | photovoltaic mounting system, | RER | lci-PV.xlsx |\n", + "| photovoltaic panel factory con | photovoltaic panel factory | GLO | lci-PV.xlsx |\n", + "| polyvinylfluoride production | polyvinylfluoride | US | lci-PV.xlsx |\n", + "| polyvinylfluoride production, | polyvinylfluoride, dispersion | US | lci-PV.xlsx |\n", + "| polyvinylfluoride, film produc | polyvinylfluoride, film | US | lci-PV.xlsx |\n", + "| silicon production, metallurgi | silicon, metallurgical grade | NO | lci-PV.xlsx |\n", + "| vinyl fluoride production | vinyl fluoride | US | lci-PV.xlsx |\n", + "| wafer factory construction | wafer factory | DE | lci-PV.xlsx |\n", + "+--------------------------------+--------------------------------+----------+-------------+\n", + "Extracted 1 worksheets in 0.05 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.01 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.02 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.02 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.01 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "The following datasets to import already exist in the source database. They will not be imported\n", + "+--------------------------------+--------------------------------+----------+--------------------------------+\n", + "| Name | Reference product | Location | File |\n", + "+--------------------------------+--------------------------------+----------+--------------------------------+\n", + "| carbon dioxide, captured at ce | carbon dioxide, captured and r | RER | lci-synfuels-from-methanol-fro |\n", + "+--------------------------------+--------------------------------+----------+--------------------------------+\n", + "Extracted 1 worksheets in 0.01 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "The following datasets to import already exist in the source database. They will not be imported\n", + "+--------------------------------+--------------------------------+----------+--------------------------------+\n", + "| Name | Reference product | Location | File |\n", + "+--------------------------------+--------------------------------+----------+--------------------------------+\n", + "| hydrogen production, coal gasi | hydrogen, gaseous, low pressur | RoW | lci-hydrogen-coal-gasification |\n", + "| methanol production, coal gasi | methanol | RoW | lci-hydrogen-coal-gasification |\n", + "+--------------------------------+--------------------------------+----------+--------------------------------+\n", + "Extracted 1 worksheets in 0.00 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.02 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.01 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.02 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.01 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.01 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "The following datasets to import already exist in the source database. They will not be imported\n", + "+--------------------------------+--------------------------------+----------+--------------------------------+\n", + "| Name | Reference product | Location | File |\n", + "+--------------------------------+--------------------------------+----------+--------------------------------+\n", + "| hydrogen production, steam met | hydrogen, gaseous, low pressur | RER | lci-hydrogen-smr-atr-natgas.xl |\n", + "+--------------------------------+--------------------------------+----------+--------------------------------+\n", + "Extracted 1 worksheets in 0.01 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.00 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.01 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.02 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "The following datasets to import already exist in the source database. They will not be imported\n", + "+--------------------------------+--------------------------------+----------+--------------------------------+\n", + "| Name | Reference product | Location | File |\n", + "+--------------------------------+--------------------------------+----------+--------------------------------+\n", + "| methanol production facility, | methanol production facility, | RER | lci-synfuels-from-methanol-fro |\n", + "+--------------------------------+--------------------------------+----------+--------------------------------+\n", + "Extracted 1 worksheets in 0.02 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.01 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 5 worksheets in 0.14 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.02 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.01 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.01 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.01 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.01 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.01 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.03 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.00 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.48 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.01 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.01 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.02 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.01 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.02 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.01 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.01 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.04 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.01 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.01 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 19 worksheets in 0.29 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.21 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.17 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Extracted 1 worksheets in 0.81 seconds\n", + "Migrating to 3.8 first\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Applying strategy: migrate_datasets\n", + "Applying strategy: migrate_exchanges\n", + "Remove uncertainty data.\n", + "Data cached. It is advised to restart your workflow at this point.\n", + "This allows premise to use the cached data instead, which results in\n", + "a faster workflow.\n", "- Fetching IAM data\n", "Done!\n" ] @@ -99,8 +659,6 @@ " #{\"model\":\"remind\", \"pathway\":\"SSP2-Base\", \"year\":2010},\n", " #{\"model\":\"image\", \"pathway\":\"SSP2-Base\", \"year\":2020},\n", " #{\"model\":\"remind\", \"pathway\":\"SSP2-Base\", \"year\":2050},\n", - " {\"model\":\"remind\", \"pathway\":\"SSP2-PkBudg1150\", \"year\":2020},\n", - " {\"model\":\"remind\", \"pathway\":\"SSP2-PkBudg1150\", \"year\":2035},\n", " {\"model\":\"remind\", \"pathway\":\"SSP2-PkBudg1150\", \"year\":2050},\n", " #{\"model\":\"image\", \"pathway\":\"SSP2-RCP26\", \"year\":2040},\n", " #{\"model\":\"image\", \"pathway\":\"SSP2-RCP26\", \"year\":2060},\n", @@ -116,7 +674,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "id": "0c80994c-cbac-4143-81ee-1de1531a6f95", "metadata": {}, "outputs": [ @@ -124,7 +682,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "Processing scenarios: 100%|█████████████| 3/3 [04:27<00:00, 89.29s/it]" + "Processing scenarios: 100%|█████████████| 1/1 [00:06<00:00, 6.51s/it]" ] }, { @@ -144,61 +702,7 @@ } ], "source": [ - "ndb.update()" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "76ccb07e-9e8c-4295-9e10-7d0753d8c62a", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Running all checks...\n", - "Minor anomalies found: check the change report.\n", - "Running all checks...\n", - "Minor anomalies found: check the change report.\n", - "Running all checks...\n", - "Minor anomalies found: check the change report.\n", - "Building superstructure database...\n", - "Dropped 0 duplicate(s).\n", - "Scenario difference file exported to /Users/romain/GitHub/premise/dev/export/scenario diff files!\n", - "Running all checks...\n", - "Minor anomalies found: check the change report.\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Writing activities to SQLite3 database:\n", - "0% [##############################] 100% | ETA: 00:00:00\n", - "Total time elapsed: 00:00:40\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Title: Writing activities to SQLite3 database:\n", - " Started: 07/14/2024 21:00:21\n", - " Finished: 07/14/2024 21:01:01\n", - " Total time elapsed: 00:00:40\n", - " CPU %: 89.10\n", - " Memory %: 19.82\n", - "Created database: battery 4\n", - "Generate scenario report.\n", - "Report saved under /Users/romain/GitHub/premise/dev/export/scenario_report.\n", - "Generate change report.\n", - "Report saved under /Users/romain/GitHub/premise/dev.\n" - ] - } - ], - "source": [ - "ndb.write_superstructure_db_to_brightway(\"battery 4\")" + "ndb.update(\"battery\")" ] }, { @@ -212,7 +716,7 @@ "output_type": "stream", "text": [ "Generate change report.\n", - "Report saved under /Users/romain/GitHub/premise/dev.\n" + "Report saved under /Users/romain/Github/premise/dev.\n" ] } ], @@ -11358,7 +11862,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.8" + "version": "3.10.13" } }, "nbformat": 4, diff --git a/premise/battery.py b/premise/battery.py index a31094c6..a1df9b5f 100644 --- a/premise/battery.py +++ b/premise/battery.py @@ -9,6 +9,7 @@ from .filesystem_constants import DATA_DIR from .logger import create_logger from .transformation import BaseTransformation, IAMDataCollection, List, np, ws +from .utils import rescale_exchanges logger = create_logger("battery") @@ -97,7 +98,7 @@ def adjust_battery_mass(self) -> None: energy_density = load_cell_energy_density() - filters = [ws.contains("name", x) for x in energy_density] + filters = [ws.contains("name", x) for x in energy_density if "battery capacity" not in x] for ds in ws.get_many( self.database, @@ -110,6 +111,7 @@ def adjust_battery_mass(self) -> None: "battery production", "battery cell production", "cell module production", + "battery capacity" ] ] ) @@ -143,27 +145,29 @@ def adjust_battery_mass(self) -> None: self.database, ws.contains("name", "market for battery capacity"), ): - - for exc in ws.technosphere(ds, ws.either(*filters)): - name = [x for x in energy_density if x in exc["name"]][0] - - scaling_factor = energy_density[name][2020] / np.clip( + if ds["name"] in energy_density: + scaling_factor = energy_density[ds["name"]][2020] / np.clip( np.interp( self.year, - list(energy_density[name].keys()), - list(energy_density[name].values()), + list(energy_density[ds["name"]].keys()), + list(energy_density[ds["name"]].values()), ), - 0.1, + 0, 0.5, ) if "log parameters" not in ds: ds["log parameters"] = {} - ds["log parameters"]["battery input"] = exc["name"] - ds["log parameters"]["old battery mass"] = exc["amount"] - exc["amount"] *= scaling_factor - ds["log parameters"]["new battery mass"] = exc["amount"] + ds["log parameters"]["battery input"] = [e["name"] for e in ws.technosphere(ds, ws.contains("name", "market for battery"))][0] + ds["log parameters"]["old battery mass"] = sum(e["amount"] for e in ws.technosphere(ds, ws.contains("name", "market for battery"))) + + rescale_exchanges( + ds, + scaling_factor + ) + + ds["log parameters"]["new battery mass"] = sum(e["amount"] for e in ws.technosphere(ds, ws.contains("name", "market for battery"))) self.write_log(ds, status="modified") diff --git a/premise/cement.py b/premise/cement.py index 9b10aac2..34410f39 100644 --- a/premise/cement.py +++ b/premise/cement.py @@ -7,16 +7,16 @@ """ -from collections import defaultdict +import copy +import uuid +from .export import biosphere_flows_dictionary from .logger import create_logger from .transformation import ( BaseTransformation, - Dict, IAMDataCollection, InventorySet, List, - calculate_input_energy, np, ws, ) @@ -119,349 +119,555 @@ def __init__( for v in list(value): self.fuel_map_reverse[v] = key - def fetch_current_energy_details(self, dataset): - # Fetches the current energy consumption per ton of clinker - - d_fuels = defaultdict( - lambda: {"amount": 0, "energy": 0, "fossil CO2": 0, "biogenic CO2": 0} - ) - - for exc in ws.technosphere(dataset): - fuel_name = exc["name"] - - if fuel_name in self.cement_fuels_map["cement, dry feed rotary kiln"]: - fuel_data = self.fuels_specs[self.fuel_map_reverse[fuel_name]] - co2_emission = fuel_data["co2"] - biogenic_share = fuel_data["biogenic_share"] - - # Calculate the energy once for the given exc - input_energy = ( - calculate_input_energy( - fuel_name=exc["name"], - fuel_amount=exc["amount"], - fuel_unit=exc["unit"], - fuels_specs=self.fuels_specs, - fuel_map_reverse=self.fuel_map_reverse, - ) - * 1000 - ) - - # Update the dictionary in one go - d_fuels[fuel_name]["amount"] += exc["amount"] - d_fuels[fuel_name]["energy"] += input_energy - d_fuels[fuel_name]["fossil CO2"] += ( - co2_emission * input_energy * (1 - biogenic_share) - ) - d_fuels[fuel_name]["biogenic CO2"] += ( - co2_emission * input_energy * biogenic_share - ) - - return d_fuels - - def fetch_bio_ratio(self, dataset: dict) -> float: - """ - Return teh ratio between bio and non-bio CO2 emissions - in the dataset. - - :param dataset: clinker production dataset - :return: ratio between bio and non-bio CO2 emissions - """ - - bio_co2 = sum( - e["amount"] - for e in dataset["exchanges"] - if e["name"] == "Carbon dioxide, non-fossil" - ) - non_bio_co2 = sum( - e["amount"] - for e in dataset["exchanges"] - if e["name"] == "Carbon dioxide, fossil" - ) - - return bio_co2 / (bio_co2 + non_bio_co2) - - def rescale_fuel_inputs(self, dataset, scaling_factor, energy_details): - if scaling_factor != 1 and scaling_factor > 0: - for exc in dataset["exchanges"]: - if exc["name"] in self.cement_fuels_map["cement, dry feed rotary kiln"]: - exc["amount"] *= scaling_factor - - # update energy_details - energy_details[exc["name"]]["amount"] *= scaling_factor - energy_details[exc["name"]]["energy"] *= scaling_factor - energy_details[exc["name"]]["fossil CO2"] *= scaling_factor - energy_details[exc["name"]]["biogenic CO2"] *= scaling_factor - - new_energy_input = sum(d["energy"] for d in energy_details.values()) - - dataset["log parameters"].update( - { - "new energy input per ton clinker": new_energy_input, - } - ) + self.biosphere_dict = biosphere_flows_dictionary(self.version) + + def build_CCS_datasets(self): + ccs_datasets = { + "cement, dry feed rotary kiln, efficient, with on-site CCS": { + "name": "carbon dioxide, captured at cement production plant, using direct separation", + "reference product": "carbon dioxide, captured at cement plant", + }, + "cement, dry feed rotary kiln, efficient, with oxyfuel CCS": { + "name": "carbon dioxide, captured at cement production plant, using oxyfuel", + "reference product": "carbon dioxide, captured at cement plant", + }, + "cement, dry feed rotary kiln, efficient, with MEA CCS": { + "name": "carbon dioxide, captured at cement production plant, using monoethanolamine", + "reference product": "carbon dioxide, captured at cement plant", + }, + } + + for variable in ccs_datasets: + datasets = self.fetch_proxies( + name=ccs_datasets[variable]["name"], + ref_prod=ccs_datasets[variable]["reference product"], + ) - return dataset + if variable == "cement, dry feed rotary kiln, efficient, with MEA CCS": + # we adjust the heat needs by subtraction 3.66 MJ with what + # the plant is expected to produce as excess heat - def rescale_emissions(self, dataset: dict, energy_details: dict) -> dict: - for exc in ws.biosphere(dataset, ws.contains("name", "Carbon dioxide")): - if "non-fossil" in exc["name"].lower(): - dataset["log parameters"].update( - { - "initial biogenic CO2": exc["amount"], - } - ) - # calculate total biogenic CO2 from energy_details - total_biogenic_CO2 = sum( - [d["biogenic CO2"] for d in energy_details.values()] - ) + # Heat, as steam: 3.66 MJ/kg CO2 captured in 2020, + # decreasing to 2.6 GJ/t by 2050, by looking at + # the best-performing state-of-the-art technologies today + # https://www.globalccsinstitute.com/wp-content/uploads/2022/05/State-of-the-Art-CCS-Technologies-2022.pdf + # minus excess heat generated on site + # the contribution of excess heat is assumed to be + # 30% of heat requirement. - exc["amount"] = total_biogenic_CO2 / 1000 - dataset["log parameters"].update( - { - "new biogenic CO2": total_biogenic_CO2 / 1000, - } - ) - else: - # calculate total fossil CO2 from energy_details - total_fossil_CO2 = sum( - [d["fossil CO2"] for d in energy_details.values()] + heat_input = np.clip( + np.interp(self.year, [2020, 2050], [3.66, 2.6]), 2.6, 3.66 ) + excess_heat_generation = 0.3 # 30% + fossil_heat_input = heat_input - (excess_heat_generation * heat_input) - dataset["log parameters"].update( - { - "initial fossil CO2": exc["amount"], - } - ) + for region, dataset in datasets.items(): + for exc in ws.technosphere( + dataset, ws.contains("unit", "megajoule") + ): + exc["amount"] = fossil_heat_input + + for dataset in datasets.values(): + self.add_to_index(dataset) + self.write_log(dataset) + self.database.append(dataset) + + # also create region-specific air separation datasets + datasets_to_regionalize = [ + ( + "industrial gases production, cryogenic air separation" + if self.version == "3.10" + else "air separation, cryogenic" + ), + "market for oxygen, liquid", + ] + + for ds_to_regionlaize in datasets_to_regionalize: + + air_separation = self.fetch_proxies( + name=ds_to_regionlaize, + ref_prod="oxygen, liquid", + ) - # remove 525 kg for calcination - exc["amount"] = 0.525 + (total_fossil_CO2 / 1000) - dataset["log parameters"].update( - { - "new fossil CO2": exc["amount"], - } - ) - return dataset + for dataset in air_separation.values(): + self.add_to_index(dataset) + self.write_log(dataset) + self.database.append(dataset) - def build_clinker_production_datasets(self) -> Dict[str, dict]: + def build_clinker_production_datasets(self) -> list: """ Builds clinker production datasets for each IAM region. Adds CO2 capture and Storage, if needed. - :return: a dictionary with IAM regions as keys and clinker production datasets as values. + :return: a dictionary with IAM regions as keys + and clinker production datasets as values. """ + variables = [ + "cement, dry feed rotary kiln", + "cement, dry feed rotary kiln, efficient", + "cement, dry feed rotary kiln, efficient, with on-site CCS", + "cement, dry feed rotary kiln, efficient, with oxyfuel CCS", + "cement, dry feed rotary kiln, efficient, with MEA CCS", + ] + + datasets = [] + # Fetch clinker production activities # and store them in a dictionary - d_act_clinker = self.fetch_proxies( + clinker = self.fetch_proxies( name="clinker production", ref_prod="clinker", production_variable="cement, dry feed rotary kiln", + geo_mapping={r: "Europe without Switzerland" for r in self.regions}, ) - for region, dataset in d_act_clinker.items(): - # calculate current thermal energy consumption per kg clinker - energy_details = self.fetch_current_energy_details(dataset) - - current_energy_input_per_ton_clinker = sum( - d["energy"] for d in energy_details.values() - ) - - # fetch the amount of biogenic CO2 emissions - bio_CO2 = sum( - e["amount"] - for e in ws.biosphere( - dataset, ws.contains("name", "Carbon dioxide, non-fossil") - ) - ) - - # back-calculate the amount of waste fuel from - # the biogenic CO2 emissions - # biogenic CO2 / MJ for waste fuel - - waste_fuel_biogenic_co2_emission_factor = ( - self.fuels_specs["waste"]["co2"] - * self.fuels_specs["waste"]["biogenic_share"] - ) - - waste_fuel_fossil_co2_emission_factor = self.fuels_specs["waste"]["co2"] * ( - 1 - self.fuels_specs["waste"]["biogenic_share"] - ) - - # energy input of waste fuel in MJ - energy_input_waste_fuel = bio_CO2 / waste_fuel_biogenic_co2_emission_factor - # amount waste fuel, in kg - amount_waste_fuel = ( - energy_input_waste_fuel / self.fuels_specs["waste"]["lhv"] - ) - - # add waste fuel to the energy details - energy_details["market for waste plastic, mixture"] = { - "amount": amount_waste_fuel, - "energy": energy_input_waste_fuel * 1000, - "fossil CO2": waste_fuel_fossil_co2_emission_factor - * energy_input_waste_fuel, - "biogenic CO2": bio_CO2, - } - - # add the waste fuel energy input - # to the total energy input - current_energy_input_per_ton_clinker += energy_input_waste_fuel * 1000 - - # add the waste fuel input to the dataset - if amount_waste_fuel != 0: - dataset["exchanges"].append( - { - "uncertainty type": 0, - "loc": 0, - "amount": amount_waste_fuel * -1, - "type": "technosphere", - "production volume": 0, - "name": "clinker production", - "unit": "kilogram", - "location": "RoW", - "product": "waste plastic, mixture", - } - ) - - if "log parameters" not in dataset: - dataset["log parameters"] = {} - - dataset["log parameters"].update( - { - "initial energy input per ton clinker": current_energy_input_per_ton_clinker, - } - ) - - # calculate the scaling factor - # the correction factor applied to all fuel/electricity input is - # equal to the ratio fuel/output in the year in question - # divided by the ratio fuel/output in 2020 - - scaling_factor = 1 / self.find_iam_efficiency_change( - data=self.iam_data.cement_efficiencies, - variable="cement, dry feed rotary kiln", - location=dataset["location"], - ) - - new_energy_input_per_ton_clinker = 0 - - if not np.isnan(scaling_factor) and scaling_factor > 0.0: - # calculate new thermal energy - # consumption per kg clinker - new_energy_input_per_ton_clinker = ( - current_energy_input_per_ton_clinker * scaling_factor - ) - - # put a floor value of 3100 kj/kg clinker - if new_energy_input_per_ton_clinker < 3100: - new_energy_input_per_ton_clinker = 3100 - # and a ceiling value of 5000 kj/kg clinker - elif new_energy_input_per_ton_clinker > 5000: - new_energy_input_per_ton_clinker = 5000 - - scaling_factor = ( - new_energy_input_per_ton_clinker - / current_energy_input_per_ton_clinker - ) - - # rescale fuel consumption and emissions - # rescale the fuel and electricity input - dataset = self.rescale_fuel_inputs( - dataset, scaling_factor, energy_details - ) - - # rescale combustion-related CO2 emissions - dataset = self.rescale_emissions(dataset, energy_details) - - # Carbon capture rate: share of capture of total CO2 emitted - carbon_capture_rate = self.get_carbon_capture_rate( - loc=dataset["location"], sector="cement" - ) - - # add 10% loss - carbon_capture_rate *= 0.9 - - dataset["log parameters"].update( - { - "carbon capture rate": float(carbon_capture_rate), - } - ) - - # add CCS-related dataset - if not np.isnan(carbon_capture_rate) and carbon_capture_rate > 0: - # total CO2 emissions = bio CO2 emissions - # + fossil CO2 emissions - # + calcination emissions - - total_co2_emissions = dataset["log parameters"].get( - "new fossil CO2", 0 - ) + dataset["log parameters"].get("new biogenic CO2", 0) - # share bio CO2 stored = sum of biogenic fuel emissions / total CO2 emissions - bio_co2_stored = ( - dataset["log parameters"].get("new biogenic CO2", 0) - / total_co2_emissions - ) + for variable in variables: + if variable in self.iam_data.cement_markets.coords["variables"].values: + + d_act_clinker = copy.deepcopy(clinker) + # remove `code` field + for region, dataset in d_act_clinker.items(): + dataset["code"] = uuid.uuid4().hex + for exc in ws.production(dataset): + if "input" in exc: + del exc["input"] + + if variable != "cement, dry feed rotary kiln": + # rename datasets + for region, dataset in d_act_clinker.items(): + dataset["name"] = ( + f"{dataset['name']}, {variable.replace('cement, dry feed rotary kiln, ', '')}" + ) + for e in dataset["exchanges"]: + if e["type"] == "production": + e["name"] = ( + f"{e['name']}, {variable.replace('cement, dry feed rotary kiln, ', '')}" + ) + + for region, dataset in d_act_clinker.items(): + + # from Kellenberger at al. 2007, the total energy + # input per ton of clinker is 3.4 GJ/ton clinker + current_energy_input_per_ton_clinker = 3400 + + # calculate the scaling factor + # the correction factor applied to hard coal input + # we assume that any fuel use reduction would in priority + # affect hard coal use + + scaling_factor = 1 / self.find_iam_efficiency_change( + data=self.iam_data.cement_efficiencies, + variable=variable, + location=dataset["location"], + ) - # 0.11 kg CO2 leaks per kg captured - # we need to align the CO2 composition with - # the CO2 composition of the cement plant - bio_co2_leaked = bio_co2_stored * 0.11 - - # create the CCS dataset to fit this clinker production dataset - # and add it to the database - self.create_ccs_dataset( - region, - bio_co2_stored, - bio_co2_leaked, - ) + new_energy_input_per_ton_clinker = 3400 + + if "log parameters" not in dataset: + dataset["log parameters"] = {} + + dataset["log parameters"][ + "initial energy input per ton clinker" + ] = current_energy_input_per_ton_clinker + + if not np.isnan(scaling_factor): + # calculate new thermal energy + # consumption per kg clinker + new_energy_input_per_ton_clinker = ( + current_energy_input_per_ton_clinker * scaling_factor + ) + # put a floor value of 3100 kj/kg clinker + if new_energy_input_per_ton_clinker < 3100: + new_energy_input_per_ton_clinker = 3100 + # and a ceiling value of 5000 kj/kg clinker + elif new_energy_input_per_ton_clinker > 5000: + new_energy_input_per_ton_clinker = 5000 + + # but if efficient kiln, + # set the energy input to 3000 kJ/kg clinker + if variable.startswith( + "cement, dry feed rotary kiln, efficient" + ): + new_energy_input_per_ton_clinker = 3000 + + dataset["log parameters"][ + "new energy input per ton clinker" + ] = int(new_energy_input_per_ton_clinker) + + scaling_factor = ( + new_energy_input_per_ton_clinker + / current_energy_input_per_ton_clinker + ) + + dataset["log parameters"][ + "energy scaling factor" + ] = scaling_factor + + # rescale hard coal consumption and related emissions + coal_specs = self.fuels_specs["hard coal"] + old_coal_input, new_coal_input = 0, 0 + for exc in ws.technosphere( + dataset, + ws.contains("name", "hard coal"), + ): + # in kJ + old_coal_input = float(exc["amount"] * coal_specs["lhv"]) + # in MJ + new_coal_input = old_coal_input - ( + ( + current_energy_input_per_ton_clinker + - new_energy_input_per_ton_clinker + ) + / 1000 + ) + exc["amount"] = np.clip( + new_coal_input / coal_specs["lhv"], 0, None + ) - # add an input from this CCS dataset in the clinker dataset - ccs_exc = { - "uncertainty type": 0, - "loc": 0, - "amount": float(total_co2_emissions * carbon_capture_rate), - "type": "technosphere", - "production volume": 0, - "name": "carbon dioxide, captured at cement production plant, with underground storage, post, 200 km", - "unit": "kilogram", - "location": dataset["location"], - "product": "carbon dioxide, captured and stored", - } - dataset["exchanges"].append(ccs_exc) - - # Update CO2 exchanges - for exc in dataset["exchanges"]: - if ( - exc["name"].lower().startswith("carbon dioxide") - and exc["type"] == "biosphere" + # rescale combustion-related fossil CO2 emissions + for exc in ws.biosphere( + dataset, + ws.contains("name", "Carbon dioxide"), + ): + if exc["name"] == "Carbon dioxide, fossil": + dataset["log parameters"]["initial fossil CO2"] = exc[ + "amount" + ] + co2_reduction = ( + old_coal_input - new_coal_input + ) * coal_specs["co2"] + exc["amount"] -= co2_reduction + dataset["log parameters"]["new fossil CO2"] = exc[ + "amount" + ] + + if exc["name"] == "Carbon dioxide, non-fossil": + dataset["log parameters"]["initial biogenic CO2"] = exc[ + "amount" + ] + + # add 0.005 kg/kg clinker of ammonia use for NOx removal + # according to Muller et al., 2024 + for exc in ws.technosphere( + dataset, + ws.contains("name", "market for ammonia"), ): - exc["amount"] *= 1 - carbon_capture_rate + if ( + variable + == "cement, dry feed rotary kiln, efficient, with MEA CCS" + ): + exc["amount"] = 0.00662 + else: + exc["amount"] = 0.005 - if "non-fossil" in exc["name"].lower(): - dataset["log parameters"].update( - { - "new biogenic CO2": exc["amount"], - } - ) + # reduce NOx emissions + # according to Muller et al., 2024 + for exc in ws.biosphere( + dataset, + ws.contains("name", "Nitrogen oxides"), + ): + if variable in [ + "cement, dry feed rotary kiln, efficient, with on-site CCS", + "cement, dry feed rotary kiln, efficient, with oxyfuel CCS", + ]: + exc["amount"] = 1.22e-5 + elif ( + variable + == "cement, dry feed rotary kiln, efficient, with MEA CCS" + ): + exc["amount"] = 3.8e-4 else: - dataset["log parameters"].update( - { - "new fossil CO2": exc["amount"], - } + exc["amount"] = 7.6e-4 + + # reduce Mercury and SOx emissions + # according to Muller et al., 2024 + if variable in [ + "cement, dry feed rotary kiln, efficient, with on-site CCS", + "cement, dry feed rotary kiln, efficient, with oxyfuel CCS", + "cement, dry feed rotary kiln, efficient, with MEA CCS", + ]: + for exc in ws.biosphere( + dataset, + ws.either( + *[ + ws.contains("name", name) + for name in [ + "Mercury", + "Sulfur dioxide", + ] + ] + ), + ): + exc["amount"] *= 1 - 0.999 + + if self.model == "image": + # add CCS datasets + ccs_datasets = { + "cement, dry feed rotary kiln, efficient, with on-site CCS": { + "name": "carbon dioxide, captured at cement production plant, using direct separation", + "reference product": "carbon dioxide, captured at cement plant", + "capture share": 0.95, # 95% of process emissions (calcination) are captured + }, + "cement, dry feed rotary kiln, efficient, with oxyfuel CCS": { + "name": "carbon dioxide, captured at cement production plant, using oxyfuel", + "reference product": "carbon dioxide, captured at cement plant", + "capture share": 0.9, + }, + "cement, dry feed rotary kiln, efficient, with MEA CCS": { + "name": "carbon dioxide, captured at cement production plant, using monoethanolamine", + "reference product": "carbon dioxide, captured at cement plant", + "capture share": 0.9, + }, + } + + if variable in ccs_datasets: + CO2_amount = sum( + e["amount"] + for e in ws.biosphere( + dataset, + ws.contains("name", "Carbon dioxide"), + ) + ) + if ( + variable + == "cement, dry feed rotary kiln, efficient, with on-site CCS" + ): + # only 95% of process emissions (calcination) are captured + CCS_amount = ( + 0.543 * ccs_datasets[variable]["capture share"] + ) + else: + CCS_amount = ( + CO2_amount * ccs_datasets[variable]["capture share"] + ) + + dataset["log parameters"]["carbon capture rate"] = ( + CCS_amount / CO2_amount ) - dataset["exchanges"] = [v for v in dataset["exchanges"] if v] - - # update comment - dataset["comment"] = ( - "Dataset modified by `premise` based on IAM projections " - + " for the cement industry.\n" - + f"Calculated energy input per kg clinker: {np.round(new_energy_input_per_ton_clinker, 1) / 1000}" - f" MJ/kg clinker.\n" - + f"Rate of carbon capture: {int(carbon_capture_rate * 100)} pct.\n" - ) + dataset["comment"] + ccs_exc = { + "uncertainty type": 0, + "loc": CCS_amount, + "amount": CCS_amount, + "type": "technosphere", + "production volume": 0, + "name": ccs_datasets[variable]["name"], + "unit": "kilogram", + "location": dataset["location"], + "product": ccs_datasets[variable]["reference product"], + } + dataset["exchanges"].append(ccs_exc) + + # Update CO2 exchanges + for exc in ws.biosphere( + dataset, + ws.contains("name", "Carbon dioxide, fossil"), + ): + if ( + variable + != "cement, dry feed rotary kiln, efficient, with on-site CCS" + ): + exc["amount"] *= ( + CO2_amount - CCS_amount + ) / CO2_amount + else: + exc["amount"] -= CCS_amount + + # make sure it's not negative + if exc["amount"] < 0: + exc["amount"] = 0 + + dataset["log parameters"]["new fossil CO2"] = exc[ + "amount" + ] + + # Update biogenic CO2 exchanges + if ( + variable + != "cement, dry feed rotary kiln, efficient, with on-site CCS" + ): + for exc in ws.biosphere( + dataset, + ws.contains("name", "Carbon dioxide, non-fossil"), + ): + dataset["log parameters"][ + "initial biogenic CO2" + ] = exc["amount"] + exc["amount"] *= ( + CO2_amount - CCS_amount + ) / CO2_amount + + # make sure it's not negative + if exc["amount"] < 0: + exc["amount"] = 0 + + dataset["log parameters"]["new biogenic CO2"] = exc[ + "amount" + ] + + biogenic_CO2_reduction = ( + dataset["log parameters"][ + "initial biogenic CO2" + ] + - dataset["log parameters"]["new biogenic CO2"] + ) + # add a flow of "Carbon dioxide, in air" to reflect + # the permanent storage of biogenic CO2 + dataset["exchanges"].append( + { + "uncertainty type": 0, + "loc": biogenic_CO2_reduction, + "amount": biogenic_CO2_reduction, + "type": "biosphere", + "name": "Carbon dioxide, in air", + "unit": "kilogram", + "categories": ( + "natural resource", + "in air", + ), + "comment": "Permanent storage of biogenic CO2", + "input": ( + "biosphere3", + self.biosphere_dict[ + ( + "Carbon dioxide, in air", + "natural resource", + "in air", + "kilogram", + ) + ], + ), + } + ) + + else: + # Carbon capture rate: share of capture of total CO2 emitted + carbon_capture_rate = self.get_carbon_capture_rate( + loc=dataset["location"], sector="cement" + ) + + # add 10% loss + carbon_capture_rate *= 0.9 + + dataset["log parameters"].update( + { + "carbon capture rate": float(carbon_capture_rate), + } + ) + + # add CCS-related dataset + if ( + not np.isnan(carbon_capture_rate) + and carbon_capture_rate > 0 + ): + # total CO2 emissions = bio CO2 emissions + # + fossil CO2 emissions + # + calcination emissions + + total_co2_emissions = dataset["log parameters"].get( + "new fossil CO2", 0 + ) + dataset["log parameters"].get("new biogenic CO2", 0) + # share bio CO2 stored = sum of biogenic fuel emissions / total CO2 emissions + bio_co2_stored = ( + dataset["log parameters"].get("new biogenic CO2", 0) + / total_co2_emissions + ) - return d_act_clinker + # 0.11 kg CO2 leaks per kg captured + # we need to align the CO2 composition with + # the CO2 composition of the cement plant + bio_co2_leaked = bio_co2_stored * 0.11 + + # add an input from this CCS dataset in the clinker dataset + ccs_exc = { + "uncertainty type": 0, + "loc": 0, + "amount": float( + total_co2_emissions * carbon_capture_rate + ), + "type": "technosphere", + "production volume": 0, + "name": "carbon dioxide, captured at cement production plant, using monoethanolamine", + "unit": "kilogram", + "location": dataset["location"], + "product": "carbon dioxide, captured at cement plant", + } + + # add an input from the CCS dataset in the clinker dataset + # and add it to the database + dataset["exchanges"].append(ccs_exc) + + # Update CO2 exchanges + for exc in ws.biosphere( + dataset, + ws.contains("name", "Carbon dioxide"), + ): + if exc["name"] == "Carbon dioxide, fossil": + exc["amount"] *= 1 - carbon_capture_rate + + dataset["log parameters"].update( + { + "new fossil CO2": exc["amount"], + } + ) + + if exc["name"] == "Carbon dioxide, non-fossil": + exc["amount"] *= 1 - carbon_capture_rate + + dataset["log parameters"].update( + { + "new biogenic CO2": exc["amount"], + } + ) + + # add a flow of "Carbon dioxide, in air" to reflect + # the permanent storage of biogenic CO2 + biogenic_CO2_reduction = ( + dataset["log parameters"]["initial biogenic CO2"] + - dataset["log parameters"]["new biogenic CO2"] + ) + dataset["exchanges"].append( + { + "uncertainty type": 0, + "loc": biogenic_CO2_reduction, + "amount": biogenic_CO2_reduction, + "type": "biosphere", + "name": "Carbon dioxide, in air", + "unit": "kilogram", + "categories": ( + "natural resource", + "in air", + ), + "comment": "Permanent storage of biogenic CO2", + "input": ( + "biosphere3", + self.biosphere_dict[ + ( + "Carbon dioxide, in air", + "natural resource", + "in air", + "kilogram", + ) + ], + ), + } + ) + + dataset["exchanges"] = [v for v in dataset["exchanges"] if v] + + # update comment + dataset["comment"] = ( + "Dataset modified by `premise` based on IAM projections " + + " for the cement industry.\n" + + f"Calculated energy input per kg clinker: {np.round(new_energy_input_per_ton_clinker, 1) / 1000}" + f" MJ/kg clinker.\n" + + f"Rate of carbon capture: {int(carbon_capture_rate * 100)} pct.\n" + ) + dataset["comment"] + + datasets.append(dataset) + + return datasets def add_datasets_to_database(self) -> None: """ @@ -470,7 +676,9 @@ def add_datasets_to_database(self) -> None: :return: Does not return anything. Modifies in place. """ - clinker_prod_datasets = list(self.build_clinker_production_datasets().values()) + # create CCS datasets + self.build_CCS_datasets() + clinker_prod_datasets = self.build_clinker_production_datasets() self.database.extend(clinker_prod_datasets) # add to log @@ -479,22 +687,116 @@ def add_datasets_to_database(self) -> None: # add it to list of created datasets self.add_to_index(new_dataset) - clinker_market_datasets = list( - self.fetch_proxies( - name="market for clinker", - ref_prod="clinker", - production_variable="cement, dry feed rotary kiln", - ).values() + variables = [ + "cement, dry feed rotary kiln", + "cement, dry feed rotary kiln, efficient", + "cement, dry feed rotary kiln, efficient, with on-site CCS", + "cement, dry feed rotary kiln, efficient, with oxyfuel CCS", + "cement, dry feed rotary kiln, efficient, with MEA CCS", + ] + + clinker_market_datasets = self.fetch_proxies( + name="market for clinker", + ref_prod="clinker", + production_variable=[ + v + for v in variables + if v in self.iam_data.cement_markets.coords["variables"].values + ], ) - self.database.extend(clinker_market_datasets) + clinker_market_datasets = { + k: v + for k, v in clinker_market_datasets.items() + if self.iam_data.cement_markets.sel(region=k) + .sum(dim="variables") + .interp(year=self.year) + > 0 + } + + for region, ds in clinker_market_datasets.items(): + ds["exchanges"] = [ + v + for v in ds["exchanges"] + if v["type"] == "production" or v["unit"] == "ton kilometer" + ] + for variable in variables: + if variable in self.iam_data.cement_markets.coords["variables"].values: + if self.year in self.iam_data.cement_markets.coords["year"].values: + share = self.iam_data.cement_markets.sel( + variables=variable, region=region, year=self.year + ).values + else: + share = ( + self.iam_data.cement_markets.sel( + variables=variable, region=region + ) + .interp(year=self.year) + .values + ) + + if share > 0: + if variable == "cement, dry feed rotary kiln": + name = "clinker production" + else: + name = f"clinker production, {variable.replace('cement, dry feed rotary kiln, ', '')}" + ds["exchanges"].append( + { + "uncertainty type": 0, + "loc": float(share), + "amount": float(share), + "type": "technosphere", + "production volume": 0, + "name": name, + "unit": "kilogram", + "location": region, + "product": "clinker", + } + ) + + self.database.extend(clinker_market_datasets.values()) # add to log - for new_dataset in clinker_market_datasets: + for new_dataset in clinker_market_datasets.values(): self.write_log(new_dataset) # add it to list of created datasets self.add_to_index(new_dataset) + # exclude the regionalization of these datasets + # because they are very rarely used in the database + excluded = [ + "factory", + "tile", + "sulphate", + "plaster", + "Portland Slag", + "CP II-Z", + "CP IV", + "CP V RS", + "Portland SR3", + "CEM II/A-S", + "CEM II/A-V", + "CEM II/B-L", + "CEM II/B-S", + "type I (SM)", + "type I-PM", + "type IP/P", + "type IS", + "type S", + "CEM III/C", + "CEM V/A", + "CEM V/B", + "CEM II/A-L", + "CEM III/B", + "Pozzolana Portland", + "ART", + "type IP", + "CEM IV/A", + "CEM IV/B", + "type ICo", + "carbon", + ] + # cement markets markets = list( ws.get_many( @@ -502,7 +804,8 @@ def add_datasets_to_database(self) -> None: ws.contains("name", "market for cement"), ws.contains("reference product", "cement"), ws.doesnt_contain_any( - "name", ["factory", "tile", "sulphate", "plaster"] + "name", + excluded, ), ws.doesnt_contain_any("location", self.regions), ) @@ -538,9 +841,7 @@ def add_datasets_to_database(self) -> None: self.database, ws.contains("name", "cement production"), ws.contains("reference product", "cement"), - ws.doesnt_contain_any( - "name", ["factory", "tile", "sulphate", "plaster"] - ), + ws.doesnt_contain_any("name", excluded), ) ) @@ -579,6 +880,7 @@ def write_log(self, dataset, status="created"): f"{status}|{self.model}|{self.scenario}|{self.year}|" f"{dataset['name']}|{dataset['location']}|" f"{dataset.get('log parameters', {}).get('initial energy input per ton clinker', '')}|" + f"{dataset.get('log parameters', {}).get('energy scaling factor', '')}|" f"{dataset.get('log parameters', {}).get('new energy input per ton clinker', '')}|" f"{dataset.get('log parameters', {}).get('carbon capture rate', '')}|" f"{dataset.get('log parameters', {}).get('initial fossil CO2', '')}|" diff --git a/premise/data/additional_inventories/lci-battery-capacity.xlsx b/premise/data/additional_inventories/lci-battery-capacity.xlsx index 588f7115..ed0b2a67 100644 Binary files a/premise/data/additional_inventories/lci-battery-capacity.xlsx and b/premise/data/additional_inventories/lci-battery-capacity.xlsx differ diff --git a/premise/data/additional_inventories/lci-buses.xlsx b/premise/data/additional_inventories/lci-buses.xlsx index 4779474b..37b720d9 100644 Binary files a/premise/data/additional_inventories/lci-buses.xlsx and b/premise/data/additional_inventories/lci-buses.xlsx differ diff --git a/premise/data/additional_inventories/lci-carbon-capture.xlsx b/premise/data/additional_inventories/lci-carbon-capture.xlsx index 9a93d895..df758712 100644 Binary files a/premise/data/additional_inventories/lci-carbon-capture.xlsx and b/premise/data/additional_inventories/lci-carbon-capture.xlsx differ diff --git a/premise/data/additional_inventories/lci-pass_cars.xlsx b/premise/data/additional_inventories/lci-pass_cars.xlsx index 9edf1ac4..d86e0136 100644 Binary files a/premise/data/additional_inventories/lci-pass_cars.xlsx and b/premise/data/additional_inventories/lci-pass_cars.xlsx differ diff --git a/premise/data/additional_inventories/lci-synfuels-from-methanol-from-electrolysis.xlsx b/premise/data/additional_inventories/lci-synfuels-from-methanol-from-electrolysis.xlsx index 2c1b0305..53b0828d 100644 Binary files a/premise/data/additional_inventories/lci-synfuels-from-methanol-from-electrolysis.xlsx and b/premise/data/additional_inventories/lci-synfuels-from-methanol-from-electrolysis.xlsx differ diff --git a/premise/data/additional_inventories/lci-trucks.xlsx b/premise/data/additional_inventories/lci-trucks.xlsx index 7c529fd5..19322599 100644 Binary files a/premise/data/additional_inventories/lci-trucks.xlsx and b/premise/data/additional_inventories/lci-trucks.xlsx differ diff --git a/premise/data/additional_inventories/lci-two_wheelers.xlsx b/premise/data/additional_inventories/lci-two_wheelers.xlsx index 3c572af9..b0d0394e 100644 Binary files a/premise/data/additional_inventories/lci-two_wheelers.xlsx and b/premise/data/additional_inventories/lci-two_wheelers.xlsx differ diff --git a/premise/data/battery/energy_density.yaml b/premise/data/battery/energy_density.yaml index 47a4dffa..27c33687 100644 --- a/premise/data/battery/energy_density.yaml +++ b/premise/data/battery/energy_density.yaml @@ -6,6 +6,7 @@ NMC111: name: - market for battery cell, Li-ion, NMC111 - market for battery, Li-ion, NMC111, rechargeable, prismatic + - market for battery capacity, Li-ion, NMC111 target: 2020: 0.150 2050: 0.200 @@ -15,6 +16,7 @@ NMC622: name: - market for battery cell, Li-ion, NMC622 - market for battery, Li-ion, NMC622, rechargeable, prismatic + - market for battery capacity, Li-ion, NMC622 target: 2020: 0.200 2050: 0.350 @@ -24,6 +26,7 @@ NMC811: name: - market for battery cell, Li-ion, NMC811 - market for battery, Li-ion, NMC811, rechargeable, prismatic + - market for battery capacity, Li-ion, NMC811 target: 2020: 0.220 2050: 0.500 @@ -33,6 +36,7 @@ NCA: name: - market for battery cell, Li-ion, NCA - market for battery, Li-ion, NCA, rechargeable, prismatic + - market for battery capacity, Li-ion, NCA target: 2020: 0.250 2050: 0.350 @@ -42,6 +46,7 @@ LFP: name: - market for battery cell, Li-ion, LFP - market for battery, Li-ion, LFP, rechargeable, prismatic + - market for battery capacity, Li-ion, LFP target: 2020: 0.140 2050: 0.250 @@ -51,6 +56,7 @@ LTO: name: - market for battery cell, Li-ion, LTO - market for battery, Li-ion, LTO + - market for battery capacity, Li-ion, LTO target: 2020: 0.080 2050: 0.150 @@ -60,6 +66,7 @@ LMO: name: - market for battery cell, Li-ion, LiMn2O4 - market for battery, Li-ion, LiMn2O4, rechargeable, prismatic + - market for battery capacity, Li-ion, LiMn2O4 target: 2020: 0.130 @@ -67,28 +74,35 @@ LMO: Li-O2: ecoinvent_aliases: - name: market for battery, Li-oxygen, Li-O2 + name: + - market for battery, Li-oxygen, Li-O2 + - market for battery capacity, Li-ion, Li-O2 target: 2020: 0.360 2050: 0.500 Li-S: ecoinvent_aliases: - name: market for battery, Li-sulfur, Li-S + name: + - market for battery, Li-sulfur, Li-S + - market for battery capacity, Li-sulfur, Li-S target: 2020: 0.150 2050: 0.500 SiB: ecoinvent_aliases: - name: market for battery, Sodium-ion, SiB + name: + - market for battery, Sodium-ion, SiB + - market for battery capacity, Sodium-ion, SiB target: 2020: 0.160 2050: 0.220 BoP: ecoinvent_aliases: - name: market for battery management system + name: + - market for battery management system target: 2020: 0.200 2050: 0.500 diff --git a/premise/iam_variables_mapping/cement_variables.yaml b/premise/iam_variables_mapping/cement_variables.yaml index 3bc7df00..614dbc40 100644 --- a/premise/iam_variables_mapping/cement_variables.yaml +++ b/premise/iam_variables_mapping/cement_variables.yaml @@ -77,4 +77,188 @@ cement, dry feed rotary kiln: - vehicle - ash - briquettes - - period \ No newline at end of file + - period + + +cement, dry feed rotary kiln, efficient: + iam_aliases: + image: Production|Industry|Cement|Efficient dry feed rotary kiln + energy_use_aliases: + image: + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln|Coal + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln|Electricity + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln|Hydrogen + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln|Modern Biomass + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln|Natural Gas + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln|Oil + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln|Secondary Heat + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln|Traditional Biomass + ecoinvent_fuel_aliases: + fltr: + name: + - market for diesel, low-sulfur + - market for natural gas, high pressure + - market for liquefied petroleum gas + - market for petroleum coke + - market for petrol, unleaded + - market for hard coal + - market for wood chips, wet, measured as dry mass + - market for diesel + - market for heavy fuel oil + - market for lignite + - market for charcoal + - market for natural gas, low pressure + - market for pulverised lignite + - market for light fuel oil + - market for meat and bone meal + - market group for natural gas, high pressure + mask: + name: + - factory + - generating + - furnace + - burned + - plant + - charcoal + - vehicle + - ash + - briquettes + - period + +cement, dry feed rotary kiln, efficient, with on-site CCS: + iam_aliases: + image: Production|Industry|Cement|Efficient dry feed rotary kiln + On-site CCS + energy_use_aliases: + image: + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln + On-site CCS|Coal + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln + On-site CCS|Electricity + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln + On-site CCS|Hydrogen + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln + On-site CCS|Modern Biomass + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln + On-site CCS|Natural Gas + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln + On-site CCS|Oil + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln + On-site CCS|Secondary Heat + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln + On-site CCS|Traditional Biomass + ecoinvent_fuel_aliases: + fltr: + name: + - market for diesel, low-sulfur + - market for natural gas, high pressure + - market for liquefied petroleum gas + - market for petroleum coke + - market for petrol, unleaded + - market for hard coal + - market for wood chips, wet, measured as dry mass + - market for diesel + - market for heavy fuel oil + - market for lignite + - market for charcoal + - market for natural gas, low pressure + - market for pulverised lignite + - market for light fuel oil + - market for meat and bone meal + - market group for natural gas, high pressure + mask: + name: + - factory + - generating + - furnace + - burned + - plant + - charcoal + - vehicle + - ash + - briquettes + - period + +cement, dry feed rotary kiln, efficient, with oxyfuel CCS: + iam_aliases: + image: Production|Industry|Cement|Efficient dry feed rotary kiln + Oxy-combustion CCS + energy_use_aliases: + image: + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln + Oxy-combustion CCS|Coal + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln + Oxy-combustion CCS|Electricity + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln + Oxy-combustion CCS|Hydrogen + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln + Oxy-combustion CCS|Modern Biomass + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln + Oxy-combustion CCS|Natural Gas + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln + Oxy-combustion CCS|Oil + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln + Oxy-combustion CCS|Secondary Heat + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln + Oxy-combustion CCS|Traditional Biomass + ecoinvent_fuel_aliases: + fltr: + name: + - market for diesel, low-sulfur + - market for natural gas, high pressure + - market for liquefied petroleum gas + - market for petroleum coke + - market for petrol, unleaded + - market for hard coal + - market for wood chips, wet, measured as dry mass + - market for diesel + - market for heavy fuel oil + - market for lignite + - market for charcoal + - market for natural gas, low pressure + - market for pulverised lignite + - market for light fuel oil + - market for meat and bone meal + - market group for natural gas, high pressure + mask: + name: + - factory + - generating + - furnace + - burned + - plant + - charcoal + - vehicle + - ash + - briquettes + - period + +cement, dry feed rotary kiln, efficient, with MEA CCS: + iam_aliases: + image: Production|Industry|Cement|Efficient dry feed rotary kiln + MEA CCS + energy_use_aliases: + image: + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln + MEA CCS|Coal + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln + MEA CCS|Electricity + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln + MEA CCS|Hydrogen + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln + MEA CCS|Modern Biomass + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln + MEA CCS|Natural Gas + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln + MEA CCS|Oil + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln + MEA CCS|Secondary Heat + - Final Energy|Industry|Cement|Efficient dry feed rotary kiln + MEA CCS|Traditional Biomass + ecoinvent_fuel_aliases: + fltr: + name: + - market for diesel, low-sulfur + - market for natural gas, high pressure + - market for liquefied petroleum gas + - market for petroleum coke + - market for petrol, unleaded + - market for hard coal + - market for wood chips, wet, measured as dry mass + - market for diesel + - market for heavy fuel oil + - market for lignite + - market for charcoal + - market for natural gas, low pressure + - market for pulverised lignite + - market for light fuel oil + - market for meat and bone meal + - market group for natural gas, high pressure + mask: + name: + - factory + - generating + - furnace + - burned + - plant + - charcoal + - vehicle + - ash + - briquettes + - period + + + diff --git a/premise/iam_variables_mapping/extract_mapping.py b/premise/iam_variables_mapping/extract_mapping.py index 3685ad6f..d37a7077 100644 --- a/premise/iam_variables_mapping/extract_mapping.py +++ b/premise/iam_variables_mapping/extract_mapping.py @@ -186,7 +186,7 @@ def create_refined_pivot_v2(df): refined_pivot_tables_v2[sheet] = create_refined_pivot_v2(df) # Create a new Excel writer for the refined pivot tables -refined_output_path_v2 = "mapping_overview.xlsx" +refined_output_path_v2 = "mapping_overview2.xlsx" with pd.ExcelWriter(refined_output_path_v2) as writer: for sheet, pivot_df in refined_pivot_tables_v2.items(): if not pivot_df.empty: diff --git a/premise/transformation.py b/premise/transformation.py index 6d82e8fa..716e42ce 100644 --- a/premise/transformation.py +++ b/premise/transformation.py @@ -1128,6 +1128,105 @@ def get_exchange_from_cache(self, exc, loc): return self.cache.get(loc, {}).get(self.model, {}).get(key) + def create_ccs_dataset( + self, + loc: str, + bio_co2_stored: float, + bio_co2_leaked: float, + sector: str = "cement", + ) -> None: + """ + Create a CCS dataset, reflecting the share of fossil vs. biogenic CO2. + + Source for CO2 capture and compression: + https://www.sciencedirect.com/science/article/pii/S1750583613001230?via%3Dihub#fn0040 + + :param loc: location of the dataset to create + :param bio_co2_stored: share of biogenic CO2 over biogenic + fossil CO2 + :param bio_co2_leaked: share of biogenic CO2 leaked back into the atmosphere + :param sector: name of the sector to look capture rate for + :return: Does not return anything, but adds the dataset to the database. + + """ + + # select the dataset + # it is initially made for a cement plant, but it should be possible to + # use it for any plant with a similar flue gas composition (CO2 concentration + # and composition of the flue gas). + dataset = ws.get_one( + self.database, + ws.equals( + "name", + "carbon dioxide, captured at cement production plant, with underground storage, post, 200 km", + ), + ws.equals("location", "RER"), + ) + + # duplicate the dataset + ccs = wt.copy_to_new_location(dataset, loc) + ccs["code"] = str(uuid.uuid4().hex) + + if sector != "cement": + ccs["name"] = ccs["name"].replace("cement", sector) + for e in ws.production(ccs): + e["name"] = e["name"].replace("cement", sector) + + if not self.is_in_index(ccs): + if "input" in ccs: + ccs.pop("input") + + # we first fix the biogenic CO2 permanent storage + # this corresponds to the share of biogenic CO2 + # in the fossil + biogenic CO2 emissions of the plant + + for exc in ws.biosphere( + ccs, + ws.equals("name", "Carbon dioxide, in air"), + ): + exc["amount"] = bio_co2_stored + + if bio_co2_leaked > 0: + # then the biogenic CO2 leaked during the capture process + for exc in ws.biosphere( + ccs, + ws.equals("name", "Carbon dioxide, non-fossil"), + ): + exc["amount"] = bio_co2_leaked + + # the rest of CO2 leaked is fossil + for exc in ws.biosphere(ccs, ws.equals("name", "Carbon dioxide, fossil")): + exc["amount"] = 0.11 - bio_co2_leaked + + # we adjust the heat needs by subtraction 3.66 MJ with what + # the plant is expected to produce as excess heat + + # Heat, as steam: 3.66 MJ/kg CO2 captured in 2020, + # decreasing to 2.6 GJ/t by 2050, by looking at + # the best-performing state-of-the-art technologies today + # https://www.globalccsinstitute.com/wp-content/uploads/2022/05/State-of-the-Art-CCS-Technologies-2022.pdf + # minus excess heat generated on site + # the contribution of excess heat is assumed to be + # 30% of heat requirement. + + heat_input = np.clip( + np.interp(self.year, [2020, 2050], [3.66, 2.6]), 2.6, 3.66 + ) + excess_heat_generation = 0.3 # 30% + fossil_heat_input = heat_input - (excess_heat_generation * heat_input) + + for exc in ws.technosphere(ccs, ws.contains("name", "steam production")): + exc["amount"] = fossil_heat_input + + if sector != "cement": + ccs["comment"] = ccs["comment"].replace("cement", sector) + + # then, we need to find local suppliers of electricity, water, steam, etc. + ccs = self.relink_technosphere_exchanges(ccs) + self.add_to_index(ccs) + + # finally, we add this new dataset to the database + self.database.append(ccs) + def find_alternative_locations(self, act, exc, alt_names): """ Find alternative locations for an exchange, trying "market for" and "market group for" @@ -1345,106 +1444,6 @@ def get_carbon_capture_rate(self, loc: str, sector: str) -> float: return rate - def create_ccs_dataset( - self, - loc: str, - bio_co2_stored: float, - bio_co2_leaked: float, - sector: str = "cement", - ) -> None: - """ - Create a CCS dataset, reflecting the share of fossil vs. biogenic CO2. - - Source for CO2 capture and compression: - https://www.sciencedirect.com/science/article/pii/S1750583613001230?via%3Dihub#fn0040 - - :param loc: location of the dataset to create - :param bio_co2_stored: share of biogenic CO2 over biogenic + fossil CO2 - :param bio_co2_leaked: share of biogenic CO2 leaked back into the atmosphere - :param sector: name of the sector to look capture rate for - :return: Does not return anything, but adds the dataset to the database. - - """ - - # select the dataset - # it is initially made for a cement plant, but it should be possible to - # use it for any plant with a similar flue gas composition (CO2 concentration - # and composition of the flue gas). - dataset = ws.get_one( - self.database, - ws.equals( - "name", - "carbon dioxide, captured at cement production plant, " - "with underground storage, post, 200 km", - ), - ws.equals("location", "RER"), - ) - - # duplicate the dataset - ccs = wt.copy_to_new_location(dataset, loc) - ccs["code"] = str(uuid.uuid4().hex) - - if sector != "cement": - ccs["name"] = ccs["name"].replace("cement", sector) - for e in ws.production(ccs): - e["name"] = e["name"].replace("cement", sector) - - if not self.is_in_index(ccs): - if "input" in ccs: - ccs.pop("input") - - # we first fix the biogenic CO2 permanent storage - # this corresponds to the share of biogenic CO2 - # in the fossil + biogenic CO2 emissions of the plant - - for exc in ws.biosphere( - ccs, - ws.equals("name", "Carbon dioxide, in air"), - ): - exc["amount"] = bio_co2_stored - - if bio_co2_leaked > 0: - # then the biogenic CO2 leaked during the capture process - for exc in ws.biosphere( - ccs, - ws.equals("name", "Carbon dioxide, non-fossil"), - ): - exc["amount"] = bio_co2_leaked - - # the rest of CO2 leaked is fossil - for exc in ws.biosphere(ccs, ws.equals("name", "Carbon dioxide, fossil")): - exc["amount"] = 0.11 - bio_co2_leaked - - # we adjust the heat needs by subtraction 3.66 MJ with what - # the plant is expected to produce as excess heat - - # Heat, as steam: 3.66 MJ/kg CO2 captured in 2020, - # decreasing to 2.6 GJ/t by 2050, by looking at - # the best-performing state-of-the-art technologies today - # https://www.globalccsinstitute.com/wp-content/uploads/2022/05/State-of-the-Art-CCS-Technologies-2022.pdf - # minus excess heat generated on site - # the contribution of excess heat is assumed to be - # 30% of heat requirement. - - heat_input = np.clip( - np.interp(self.year, [2020, 2050], [3.66, 2.6]), 2.6, 3.66 - ) - excess_heat_generation = 0.3 # 30% - fossil_heat_input = heat_input - (excess_heat_generation * heat_input) - - for exc in ws.technosphere(ccs, ws.contains("name", "steam production")): - exc["amount"] = fossil_heat_input - - if sector != "cement": - ccs["comment"] = ccs["comment"].replace("cement", sector) - - # then, we need to find local suppliers of electricity, water, steam, etc. - ccs = self.relink_technosphere_exchanges(ccs) - self.add_to_index(ccs) - - # finally, we add this new dataset to the database - self.database.append(ccs) - def find_iam_efficiency_change( self, data: xr.DataArray,