Source code for ppf.cement.sequence

# -*- coding: utf-8 -*-
"""

Created on Wed Oct 25 09:18:25 2023

@author: mathi

Sequences to determine GHG emissions' from cement industry (combination of IPCC
equations and extensions added to them.
"""

from logging import getLogger

import bonsai_ipcc

from . import elementary
from ._data import concordance, dimension, parameter

logger = getLogger("root")


####################################################################################
# --------------------- Sequence on cement production ---------------------------- #
####################################################################################


[docs] def production_cement( year=2011, region="US", cement_type="portland", uncertainty="def", ): """ This function calculates different factors related to the production of cement, namely: the mass of clinker needed to produce the cement considered (in tonnes), the electricity needed in kWh, the energy (heat) needed in GJ, the gypsum needed (in tonne), the production of CKD (Cwement Kiln Dust, in tonnes), and of cement waste during construction (in tonnes). Parameters ---------- year : integer, optional Year of the cement production. The default is 2011. region : string, optional Region of the cement production. The default is "US". cement_type : string, optional Type of cement that is produced. The default is "portland". uncertainty : string, optional Defined the type of uncertianty that we want to consider in the calculation. The default is "def". Returns ------- Python object A Python object os created with different attrobutes that contain the results mentioned in the description above. """ # Initalize variable instance seq = bonsai_ipcc.industry.mineral.sequence.Sequence( dimension, parameter, elementary, concordance, uncert=uncertainty ) logger.info("cement-production sequence started --->") seq.store_signature(locals()) seq.read_parameter( name="mass_cement", table="cement_prod_world", coords=[year, region], ) seq.read_parameter( name="clink_on_cem", table="c_cl", coords=[year, region, cement_type], ) # Mass clinker mass_clinker = seq.elementary.mass_clinker( mass_cement=seq.step.mass_cement.value, clink_on_cem=seq.step.clink_on_cem.value ) seq.store_result( name="mass_clinker", value=mass_clinker, unit="tonnes", year=year, ) seq.read_parameter( name="elec_cement", table="elec_use", coords=[year, region], ) # Electricity consumption for cement production (combining # calcination + cement mill): elec_use_cement = seq.elementary.elec_use_cement( mass_cement=seq.step.mass_cement.value, elec_intensity=seq.step.elec_cement.value, ) seq.store_result( name="elec_use_cement", value=elec_use_cement, unit="kWh", year=year, ) # Energy needs for the cement production (heat) seq.read_parameter( name="energy_cement", table="energy_cement", coords=[year, region, cement_type], ) # energy_need_cement = seq.step.energy_cement.value * seq.step.mass_cement.value energy_need_cement = seq.elementary.energy_need_cement( mass_cement=seq.step.mass_cement.value, energy_cement=seq.step.energy_cement.value, ) seq.store_result( name="energy_need_cement", value=energy_need_cement, unit="GJ", year=year, ) # Gypsum consumption in the cement mill process seq.read_parameter( name="gypsum_coeff", table="gypsum_coeff", coords=[year, region], ) gypsum_use_cement = seq.elementary.gypsum_use_cement_mill( mass_cement=seq.step.mass_cement.value, gyp_intensity=seq.step.gypsum_coeff.value, ) seq.store_result( name="gypsum_use_cement", value=gypsum_use_cement, unit="tonnes", year=year, ) # Production of CKD that will be sent to landfill seq.read_parameter( name="ckd_on_clinker", table="ckd_on_clinker", coords=[year, region], ) seq.read_parameter( name="coeff_ckd_landfill", table="coeff_ckd_landfill", coords=[year, region], ) ckd_landfill = seq.elementary.ckd_landfill( mass_clinker=seq.step.mass_clinker.value, ckd_on_clinker=seq.step.ckd_on_clinker.value, coeff_ckd_landfill=seq.step.coeff_ckd_landfill.value, ) seq.store_result( name="ckd_landfill", value=ckd_landfill, unit="tonnes", year=year, ) # Waste production from cement during construction seq.read_parameter( name="loss_coeff", table="cement_loss_construction", coords=[year, region], ) waste_cement_construction = seq.elementary.waste_cement_construction( mass_cement=seq.step.mass_cement.value, loss_coeff=seq.step.loss_coeff.value ) seq.store_result( name="waste_cement_construction", value=waste_cement_construction, unit="tonnes", year=year, ) logger.info("---> cement model finished.") return seq.step
#################################################################################### # --------------- Sequence on mass & carbon balances on cement ------------------- # ####################################################################################
[docs] def mass_carbon_balance_cement( year=2011, region="US", cement_type="portland", uncertainty="def", ): """ This sequence function checks the carbon and mass balance of the cement production. More details can be found in the technical documentation on cement. Parameters ---------- year : integer, optional Year of the cement production. The default is 2011. region : string, optional Region of the cement production. The default is "US". cement_type : string, optional Type of cement that is produced. The default is "portland". uncertainty : string, optional Defined the type of uncertianty that we want to consider in the calculation. The default is "def". Returns ------- Python object A Python object os created with different attrobutes that contain the results mentioned in the description above. """ # Initalize variable instance seq = bonsai_ipcc.industry.mineral.sequence.Sequence( dimension, parameter, elementary, concordance, uncert=uncertainty ) logger.info("mass_carbon_balance_cement sequence started --->") seq.store_signature(locals()) seq.read_parameter( name="mass_cement", table="cement_prod_world", coords=[year, region], ) seq.read_parameter( name="clink_on_cem", table="c_cl", coords=[year, region, cement_type], ) seq.read_parameter( name="cao_in_clinker", table="cao_in_clinker", coords=[year, region], ) # Mass and carbon balances: m_caco3_supply, delta_mass, delta_c = seq.elementary.mass_carbon_balance( mass_clinker=seq.step.mass_cement.value * seq.step.clink_on_cem.value, f_cao_on_clinker=seq.step.cao_in_clinker.value, ) seq.store_result( name="m_caco3_supply", value=m_caco3_supply, unit="tonnes", year=year, ) seq.store_result( name="carbon_balance", value=delta_c, unit="tonnes", year=year, ) seq.store_result( name="mass_balance", value=delta_mass, unit="tonnes", year=year, ) logger.info("---> cement model finished.") return seq.step
#################################################################################### # --------------------- Sequence on carbonation on cement ------------------------ # ####################################################################################
[docs] def carbonation_cement_concrete( year=2011, lifetime_use_cement=10, region="US", cement_type="portland", uncertainty="def", exposure_condition="Exposed outdoor", compressive_strength="16-23 Mpa", structure="Wall", cement_product="concrete", ): """ This sequence function calculates the amount of carbonation that takes place in concrete, depending on the lifetime of use. A global result (over the whole lifetime) and a yearly result (for each year) is calculated in tonnes of CO2-absorbed. Parameters ---------- year : integer, optional Year of cement production (and by assumption concrete). The default is 2011. lifetime_use_cement : integer, optional Number of years that the concrete is used. The default is 10. region : string, optional Region where the concrete is used. The default is "US". cement_type : string, optional Type of cement that is used to later produce concrete. The default is "portland". uncertainty : string, optional Defines the type of uncertainty we want to consider. The default is "def". exposure_condition : string, optional Defines the exposure condition of concrete. The default is "Exposed outdoor". compressive_strength : string, optional Defines the compressive stremght of concrete. The default is "16-23 Mpa". structure : string, optional Defines the type of structure in which the concrete is used. The default is "Wall". cement_product : string, optional Defined the type of cement-product that is considered (in this case, concrete). The default is "concrete". Returns ------- Python object The Python object contains attributes with the results mentioned in the description above. """ # Initalize variable instance seq = bonsai_ipcc.industry.mineral.sequence.Sequence( dimension, parameter, elementary, concordance, uncert=uncertainty ) logger.info("cement-test sequence started --->") seq.store_signature(locals()) seq.read_parameter( name="mass_cement", table="cement_prod_world", coords=[year, region], ) seq.read_parameter( name="cao_in_clinker", table="cao_in_clinker", coords=[year, region], ) seq.read_parameter( name="clink_on_cem", table="c_cl", coords=[year, region, cement_type], ) seq.read_parameter( name="cement_distrib", table="cement_distrib", coords=[year, region, cement_product], ) seq.read_parameter( name="amount_of_addition", table="amount_of_addition", coords=[year, region, cement_type], ) # Mass clinker mass_clinker = seq.elementary.mass_clinker( mass_cement=seq.step.mass_cement.value, clink_on_cem=seq.step.clink_on_cem.value ) seq.store_result( name="mass_clinker", value=mass_clinker, unit="tonnes", year=year, ) # # Calculation of the sponge effect - Option 1: averaged data # sponge_effect_relative = seq.elementary.calculate_relative_average_sponge_effect( # cement_production_sponge_effect=seq.parameter.cement_production_sponge_effect, # sponge_effect_1930_2021=seq.parameter.sponge_effect_1930_2021, # ) # seq.store_result( # name="sponge_effect_relative", # value=sponge_effect_relative, # unit="none", # year=year, # ) # average_co2_uptake = seq.elementary.calculate_average_sponge_effect_through_time( # sponge_effect_relative=sponge_effect_relative # ) # seq.store_result( # name="average_co2_uptake", value=average_co2_uptake, unit="none", year=year # ) # co2_uptake_var, list_years = seq.elementary.calculate_sponge_effect( # mass_cement=seq.step.mass_cement.value, # year=year, # average_co2_uptake=average_co2_uptake, # lifetime_use_cement=lifetime_use_cement, # ) # seq.store_result( # name="CO2_carbonated", # value=co2_uptake_var, # unit="tonnes CO2-eq", # year=list_years, # ) # Calculation of the sponge effect - Option 2: Approach with detailed equations seq.read_parameter( name="carb_coeff_env", table="carb_coeff_env", coords=[year, region, exposure_condition, compressive_strength], ) seq.read_parameter( name="carb_coeff_add", table="carb_coeff_add", coords=[year, region, seq.step.amount_of_addition.value], ) seq.read_parameter( name="carb_coeff_co2", table="carb_coeff_co2", coords=[year, region], ) seq.read_parameter( name="carb_coeff_cc", table="carb_coeff_cc", coords=[year, region], ) carbonation_rate_concrete = seq.elementary.carbonation_rate( carb_coeff_env=seq.step.carb_coeff_env.value, carb_coeff_add=seq.step.carb_coeff_add.value, carb_coeff_co2=seq.step.carb_coeff_co2.value, carb_coeff_cc=seq.step.carb_coeff_cc.value, ) seq.store_result( name="carbonation_rate_concrete", value=carbonation_rate_concrete, unit="mm/year", year=year, ) seq.read_parameter( name="expo_use_life", table="expo_use_life", coords=[year, region], ) carbonation_depth = seq.elementary.carbonation_depth( carbonation_rate=seq.step.carbonation_rate_concrete.value, react_time=lifetime_use_cement, ) seq.store_result( name="carbonation_depth", value=carbonation_depth, unit="mm", year=year, ) seq.read_parameter( name="cement_on_concrete", table="cement_on_concrete", coords=[year, region, compressive_strength], ) seq.read_parameter( name="thickness", table="thickness_concrete", coords=[year, region, structure], ) concrete_carbonated = seq.elementary.concrete_carbonated( carbonation_depth=seq.step.carbonation_depth.value, cement_on_concrete=seq.step.cement_on_concrete.value, thick=seq.step.thickness.value, ) seq.store_result( name="concrete_carbonated", value=concrete_carbonated, unit="kg", year=year, ) seq.read_parameter( name="cao_converted_to_caco3", table="cao_converted_to_caco3", coords=[year, region], ) # Option 1: global value over the full lifetime of concrete co2_carbonated_concrete = seq.elementary.co2_carbonated_concrete( cement_on_concrete=seq.step.cement_on_concrete.value, carbonation_rate=seq.step.carbonation_rate_concrete.value, clink_on_cem=seq.step.clink_on_cem.value, cao_in_clinker=seq.step.cao_in_clinker.value, cao_to_caco3=seq.step.cao_converted_to_caco3.value, thick=seq.step.thickness.value, react_time=lifetime_use_cement, mass_cement=seq.step.mass_cement.value, cement_distrib=seq.step.cement_distrib.value, ) seq.store_result( name="co2_carbonated_concrete_global", value=co2_carbonated_concrete, unit="kg", year=year, ) # Option 2: we want the values for each year over the cement's lifetime # loop over the lifetime years: co2_carbonated_concrete_per_year = [] year_list = [] # lifetime_use_cement = seq.step.expo_use_life.value for y in list(range(1, lifetime_use_cement + 1)): # Calculation of the CO2 absorbed for the current year co2_carbonated_concrete_y1 = seq.elementary.co2_carbonated_concrete( cement_on_concrete=seq.step.cement_on_concrete.value, carbonation_rate=seq.step.carbonation_rate_concrete.value, clink_on_cem=seq.step.clink_on_cem.value, cao_in_clinker=seq.step.cao_in_clinker.value, cao_to_caco3=seq.step.cao_converted_to_caco3.value, thick=seq.step.thickness.value, react_time=y, mass_cement=seq.step.mass_cement.value, cement_distrib=seq.step.cement_distrib.value, ) # Calculation of the CO2 absorbed for the previous year (so we can make the # difference and get the value for each year and not the accumulated value). co2_carbonated_concrete_y0 = seq.elementary.co2_carbonated_concrete( cement_on_concrete=seq.step.cement_on_concrete.value, carbonation_rate=seq.step.carbonation_rate_concrete.value, clink_on_cem=seq.step.clink_on_cem.value, cao_in_clinker=seq.step.cao_in_clinker.value, cao_to_caco3=seq.step.cao_converted_to_caco3.value, thick=seq.step.thickness.value, react_time=y - 1, mass_cement=seq.step.mass_cement.value, cement_distrib=seq.step.cement_distrib.value, ) co2_carbonated_concrete_per_year.append( round(co2_carbonated_concrete_y1 - co2_carbonated_concrete_y0, 2) ) year_list.append(year + (y - 1)) seq.store_result( name="co2_carbonated_concrete_per_year", value=co2_carbonated_concrete_per_year, unit="kg", year=year_list, ) logger.info("---> cement model finished.") return seq.step
[docs] def carbonation_cement_mortar( year=2011, lifetime_use_cement=10, region="US", cement_type="portland", uncertainty="def", mortar_type="rendering", exposure_condition="Exposed outdoor", compressive_strength="16-23 Mpa", structure="Wall", cement_product="mortar", ): """ This sequence function calculates the amount of carbonation that takes place in mortar, depending on the lifetime of use. A global result (over the whole lifetime) and a yearly result (for each year) is calculated in tonnes of CO2-absorbed. Parameters ---------- year : integer, optional Year of cement production (and by assumption concrete). The default is 2011. lifetime_use_cement : integer, optional Number of years that the concrete is used. The default is 10. region : string, optional Region where the concrete is used. The default is "US". cement_type : string, optional Type of cement that is used to later produce concrete. The default is "portland". uncertainty : string, optional Defines the type of uncertainty we want to consider. The default is "def". mortar_type : string, optional Defined the type of mortar that is considered. The default is "rendering". exposure_condition : string, optional Defines the exposure condition of mortar. The default is "Exposed outdoor". compressive_strength : string, optional Defines the compressive stremght of mortar. The default is "16-23 Mpa". structure : string, optional Defines the type of structure in which the mortar is used. The default is "Wall". cement_product : string, optional Defined the type of cement-product that is considered (in this case, mortar). The default is "mortar". Returns ------- Python object The Python object contains attributes with the results mentioned in the description above """ # Initalize variable instance seq = bonsai_ipcc.industry.mineral.sequence.Sequence( dimension, parameter, elementary, concordance, uncert=uncertainty ) logger.info("cement-carbonation-rendering-mortar sequence started --->") seq.store_signature(locals()) seq.read_parameter( name="mass_cement", table="cement_prod_world", coords=[year, region], ) seq.read_parameter( name="cao_in_clinker", table="cao_in_clinker", coords=[year, region], ) seq.read_parameter( name="clink_on_cem", table="c_cl", coords=[year, region, cement_type], ) seq.read_parameter( name="coeff_mortar_on_cement", table="cement_distrib", coords=[year, region, cement_product], ) seq.read_parameter( name="type_mortar_use", table="type_mortar_use", coords=[year, region, mortar_type], ) seq.read_parameter( name="carbonation_rate_rendering_mortar", table="carb_coeff_mortar", coords=[year, region, cement_type, compressive_strength, exposure_condition], ) seq.read_parameter( name="thickness", table="thickness_mortar", coords=[year, region, mortar_type], ) seq.read_parameter( name="cao_converted_to_caco3", table="cao_converted_to_caco3", coords=[year, region], ) seq.read_parameter( name="expo_use_life", table="expo_use_life", coords=[year, region], ) # Option 1: global value over the full lifetime of cement co2_carbonated_mortar = seq.elementary.co2_carbonated_mortar( mass_cement=seq.step.mass_cement.value, coeff_mortar_on_cement=seq.step.coeff_mortar_on_cement.value, ratio_mortar_type=seq.step.type_mortar_use.value, carb_coeff_mortar=seq.step.carbonation_rate_rendering_mortar.value, react_time=lifetime_use_cement, thick=seq.step.thickness.value, clink_on_cem=seq.step.clink_on_cem.value, cao_in_clinker=seq.step.cao_in_clinker.value, cao_to_caco3=seq.step.cao_converted_to_caco3.value, ) seq.store_result( name="co2_carbonated_mortar_global", value=co2_carbonated_mortar, unit="kg", year=year, ) # Option 2: we want the values for each year over the cement's lifetime # loop over the lifetime years: co2_carbonated_mortar_per_year = [] year_list = [] # lifetime_use_cement = seq.step.expo_use_life.value for y in list(range(1, lifetime_use_cement + 1)): # Calculation of the CO2 absorbed for the current year co2_carbonated_mortar_y1 = seq.elementary.co2_carbonated_mortar( mass_cement=seq.step.mass_cement.value, coeff_mortar_on_cement=seq.step.coeff_mortar_on_cement.value, ratio_mortar_type=seq.step.type_mortar_use.value, carb_coeff_mortar=seq.step.carbonation_rate_rendering_mortar.value, react_time=y, thick=seq.step.thickness.value, clink_on_cem=seq.step.clink_on_cem.value, cao_in_clinker=seq.step.cao_in_clinker.value, cao_to_caco3=seq.step.cao_converted_to_caco3.value, ) # Calculation of the CO2 absorbed for the previous year (so we can make the # difference and get the value for each year and not the accumulated value). co2_carbonated_mortar_y0 = seq.elementary.co2_carbonated_mortar( mass_cement=seq.step.mass_cement.value, coeff_mortar_on_cement=seq.step.coeff_mortar_on_cement.value, ratio_mortar_type=seq.step.type_mortar_use.value, carb_coeff_mortar=seq.step.carbonation_rate_rendering_mortar.value, react_time=y - 1, thick=seq.step.thickness.value, clink_on_cem=seq.step.clink_on_cem.value, cao_in_clinker=seq.step.cao_in_clinker.value, cao_to_caco3=seq.step.cao_converted_to_caco3.value, ) co2_carbonated_mortar_per_year.append( round( co2_carbonated_mortar_y1 - co2_carbonated_mortar_y0, 2, ) ) year_list.append(year + (y - 1)) seq.store_result( name="co2_carbonated_mortar_per_year", value=co2_carbonated_mortar_per_year, unit="kg", year=year_list, ) logger.info("---> cement model finished.") return seq.step