Source code for ppf.cement.elementary

# -*- coding: utf-8 -*-
"""
Created on Wed Oct 25 09:39:57 2023

This file is intended to contain all elementary equations that will be used in the
cement PPF model that are not part of the IPCC. Beware, some functions will be have to
be moved at the "Collect" or "Clean" stage at a later point in time.

@author: mathi
"""

import sys

import numpy as np
import pandas as pd

####################################################################################
# ---------------------- Equations for cement production ------------------------- #
####################################################################################


[docs] def mass_clinker(mass_cement, clink_on_cem): """ This function calculates the mass of clinker, derived from the mass of cement. Parameters ---------- mass_cement : float The mass of cement that is considered (in tonnes). clink_on_cem : float The fraction of clinker needed to produce cement (in kg of clinker/kg of cement). Returns ------- mass_clinker : float The mass of clinker that is needed to produce the cement considered (in tonnes). """ mass_clinker = mass_cement * clink_on_cem return mass_clinker
[docs] def energy_need_cement(mass_cement, energy_cement): """ This function calculates the energy need (heat) for the production of cement. Parameters ---------- mass_cement : float Mass of cement that is considered in tonnes. energy_cement : float the energy needed to produce cement (in GJ/tonne). Returns ------- energy_need_cement : float The amount of energy that is needed to produce cement (in GJ). """ energy_need_cement = mass_cement * energy_cement return energy_need_cement
[docs] def elec_use_cement(mass_cement, elec_intensity): """ This function calculates the amount of electricity needed for the calcination and cement mill. It corresponds to Equation 3.5 from the technical documentation. Parameters ---------- mass_cement : float mass of cement produced in tonnes. elec_intensity : float Electricity needed per tonne of cement in the calcination and mill cement processes (in kWh/tonne). Returns ------- elec_use_cement : float Total electricity consumption in the calcination and cement mill processes (in kWh). """ elec_use_cement = mass_cement * elec_intensity return elec_use_cement
[docs] def gypsum_use_cement_mill(mass_cement, gyp_intensity): """ This function calculates the amount of gypsum needed for the cement mill and corresponds to Equation 3.6 from the technical documentation. Parameters ---------- mass_cement : float mass of cement produced in tonnes. gyp_intensity : float Gypsum needed per tonne of cement in the cement mill process (in tonne gypsum/tonne cement). Returns ------- gyp_use_cement_mill : float Total gypsum consumption in the cement mill process (in tonnes). """ gyp_use_cement_mill = mass_cement * gyp_intensity return gyp_use_cement_mill
[docs] def ckd_landfill(mass_clinker, ckd_on_clinker, coeff_ckd_landfill): """ This function calculates the amount of CKD (Cement Kiln Dust) that is sent to a landfill. Parameters ---------- mass_clinker : float Mass of clinker that is considered (in tonnes). ckd_on_clinker : float Fraction of CKD that is derived from clinker (fraction). coeff_ckd_landfill : float Fraction of CKD tha issent into landfill (frcation). Returns ------- ckd_landfill : float The mass of CKD sent to landfill (in tonnes). """ ckd_landfill = mass_clinker * ckd_on_clinker * coeff_ckd_landfill return ckd_landfill
[docs] def waste_cement_construction(mass_cement, loss_coeff): """ This function calculates the amount of cement waste genertated during contruction processes (of buildings, walls, etc...). Parameters ---------- mass_cement : float The mass of cement that is used for the construction (in tonnes). loss_coeff : float Coefficient of the material losses occuring from cement use in the construction phase (frcction). Returns ------- waste_cement_construction : float The mass of cement waste generated during the construction process (in tonnes). """ waste_cement_construction = mass_cement * loss_coeff return waste_cement_construction
#################################################################################### # -------------------- Equations for mass & carbon balances ---------------------- # ####################################################################################
[docs] def mass_carbon_balance(mass_clinker, f_cao_on_clinker): """ This function verifies the mass and carbon balances for the production of clinker. Parameters ---------- mass_clinker : float mass of clinker produced in tonnes. f_cao_on_clinker : float Fraction of CaO on clinker (fraction). Returns ------- delta_mass : float Mass difference between input and output, in tonnes. delta_c : float Mass difference between input and output, in tonnes. """ # As the mass of clinker is provided in tonnes, we need to multiply it by 1E6 to get # the value in g. # The denominator is the division of the molecular weight of calcium oxide # (56.0774 g/mol) by the molecular weigth of Calcium carbonate (100.0869 g/mol). m_caco3_supply = f_cao_on_clinker * mass_clinker * 1e6 / (56.0774 / 100.0869) # Division by the molecular weigth of Calcium carbonate (100.0869 g/mol). n_caco3_in = m_caco3_supply / 100.0869 # Multiplication by the molar weigth of carbon: 12.0096 g/mol mass_carbon_in = n_caco3_in * 12.0096 # Multiplication by the molecular weigth of CaO (56.0774 g/mol). mass_cao_out = n_caco3_in * 56.0774 # Multiplication by the molecular weigth of CO2 (44.009 g/mol). mass_co2_out = n_caco3_in * 44.009 # Multiplication by the fraction of molar weigth of Carbon (12.0096 g/mol) on # molecular weigth of CO2 (44.009 g/mol). mass_carbon_out = mass_co2_out * 12.0096 / 44.009 # The final results are divided by 1E6 to convert from g to tonnes. delta_mass = (m_caco3_supply - mass_cao_out - mass_co2_out) / 1e6 delta_c = (mass_carbon_in - mass_carbon_out) / 1e6 return m_caco3_supply, delta_mass, delta_c
#################################################################################### # -------------- Equations for carbonation (concrete and mortar) ----------------- # ####################################################################################
[docs] def carbonation_rate(carb_coeff_env, carb_coeff_add, carb_coeff_co2, carb_coeff_cc): """ This function calculates the carbonation rate of concrete. It is based on Equation (1) from the supplement of Zi Huang et al. (2023) and corresponds to Equation 3.1 from the technical documentation. Parameters ---------- carb_coeff_env : float Carbonated coefficient under different environments. carb_coeff_add : float Carbonated coefficients of cement additives. carb_coeff_co2 : float Carbonated coefficients from the CO2 concentration. carb_coeff_cc : float Carbonated coefficient from the coating and cover. Returns ------- carbonation_rate : float Carbonation rate coefficient of a particular strength class of concrete (in mm/(year)^(1/2)). """ carbonation_rate = carb_coeff_env * carb_coeff_add * carb_coeff_co2 * carb_coeff_cc return carbonation_rate
[docs] def carbonation_depth(carbonation_rate, react_time): """ This function calculates the concrete carbonation depth, based on equation (2) from the supplement of Zi Huang et al. (2023) and corresponds to Equation 3.2 from the technical documentation. Parameters ---------- carbonation_rate : float Carbonation rate coefficient of a particular strength class of concrete. react_time : float Reaction time where the carbonation is taking place (most usually in years). Returns ------- carbonation_depth : float Concrete carbonation depth in mm. """ carbonation_depth = carbonation_rate * (react_time) ** (1 / 2) return carbonation_depth
[docs] def concrete_carbonated(carbonation_depth, cement_on_concrete, thick): """ This function calculates the amount of carbonated concrete over a certain period of time. It is based on equation (3) from the supplement of Zi Huang et al. (2023) and corresponds to Equation 3.3 from the technical documentation. Parameters ---------- carbonation_depth : float Concrete carbonation depth in mm. cement_on_concrete : float Cement content in concrete (fraction). thick : float Thickness of the concrete structure in mm. Returns ------- concrete_carbonated : float Amount coefficient of carbonated concrete (fraction). """ concrete_carbonated = cement_on_concrete * carbonation_depth / thick return concrete_carbonated
[docs] def co2_carbonated_concrete( cement_on_concrete, carbonation_rate, clink_on_cem, cao_in_clinker, cao_to_caco3, thick, react_time, mass_cement, cement_distrib, ): """ This function calculates the amount of CO2 that has been absorbed after a certain reaction time of use (lifetime) of concrete, based on the carbonation effect. Derived from equation (6) from the supplement of Zi Huang et al. (2023) and corresponds to Equation 3.4 from the technical documentation. The final results is given per year. Parameters ---------- cement_on_concrete : float Fraction content of cement in concrete (in kg/m3). carbonation_rate : float Carbonation rate coefficient of a particular strength class of concrete ) (in mm/(year)^(0.5)). clink_on_cem : float Fraction of clinker on cement (fraction). cao_in_clinker : float Fraction of CaO in clinker (fraction). cao_to_caco3 : float Percentage of CaO converted to CaCO3 (fraction). thick : float Average thickness of the cement-product under consideration (in mm). react_time : integer Lifetime of the cement-product's use (in years). mass_cement : float Mass of cement produced (in tonnes). cement_distrib : float Fraction of cement used in the respective product type (concrete, mortar...) (fraction). Returns ------- co2_carbonated : float Amount of CO2 that has been carbonated from the concrete structure (in tonnes). """ # Based on literature data, the volumic mass of cement is on average 0.002162 # tonnes/m3. This value is needed to convert the cement_on_concrete into tonnes. co2_carbonated = ( ( cement_on_concrete * carbonation_rate * clink_on_cem * cao_in_clinker * cao_to_caco3 * mass_cement * cement_distrib / (0.002162) * ((react_time) ** (1 / 2)) ) / thick * 44.0095 / 56.0774 ) return co2_carbonated
[docs] def co2_carbonated_mortar( mass_cement, coeff_mortar_on_cement, ratio_mortar_type, carb_coeff_mortar, react_time, thick, clink_on_cem, cao_in_clinker, cao_to_caco3, ): """ This function calculates the amount of CO2 that has been absorbed after a certain reaction time of use (lifetime) of rendering mortar, based on the carbonation effect. Derived from equation (XXX) from the supplement of Zi Huang et al. (2023) and corresponds to Equation XXX from the technical documentation. The final results is given as a total value (not per year). ---------- mass_cement : float Amount of cement produced (in tonnes). coeff_mortar_on_cement : float Fraction of cement used as a mortar (fraction). ratio_mortar_type : float Fraction of rendering mortar on total mortar cement (fraction). carb_coeff_mortar : float Carbonation diffusion rate of mortar (in mm/((year)^0.5)). react_time : float Lifetime of mortar use (in years). thick : float Average thickness of the cement-product under consideration (in mm). clink_on_cem : float Fraction of clinker on cement (fraction). cao_in_clinker : float Fraction of CaO in clinker (fraction). cao_to_caco3 : float Percentage of CaO converted to CaCO3 (fraction). Returns ------- co2_carbonated : float Amount of CO2 that has been carbonated from the concrete structure (in tonnes). """ # The last factor of the multiplication is a division of the molecular weigt of CO2 # (44.0095 g/mol) by the molecular weigth of CaO (56.0774 g/mol) both constants. # Based on literature data, the volumic mass of cement is on average 2.162 kg/m3 co2_carbonated_mortar = ( mass_cement * coeff_mortar_on_cement * ratio_mortar_type * carb_coeff_mortar * (react_time) ** (1 / 2) / (thick) * clink_on_cem * cao_in_clinker * cao_to_caco3 * 44.0095 / 56.0774 ) return co2_carbonated_mortar
#################################################################################### # ----------------------- Loading elementary functions --------------------------- # #################################################################################### # The functions below are left as comments (so they can be used as comparisons, back-up, # etc...). However, they will be deleted once the carbonation model with all equations # is deemed satisfying. # def calculate_relative_average_sponge_effect( # cement_production_sponge_effect, sponge_effect_1930_2021 # ): # """ # This function calculates the relative carbonation effect per tonne of cement, taking # into account the lifetime of the cement (i.e. a proportion of the carbonated CO2 is # affected to the cement produced XX years ago). # Parameters # ---------- # cement_production_sponge_effect : dataframe # The daraframe contains all mass production values of cement (in million tonnes) # for different large regions/continents or countries, through the years. # sponge_effect_1930_2021 : dataframe # The dataframe contains data for the estimated worldwide sponge effect through # the years (in million tonnes of CO2). # Returns # ------- # sponge_effect_relative : dataframe # The dataframe contains the relative carbonation effect per tonne of cement, # calculated through the years. # The unit of values is tonne of CO2 absorbed/tonne of cement (proprotional). # """ # cement_production_sponge_effect_temp = cement_production_sponge_effect.reset_index( # ["cement_type", "property"] # ) # sponge_effect_relative = sponge_effect_1930_2021.copy() # sponge_effect_relative = sponge_effect_relative.reset_index() # for i in sponge_effect_relative.index: # sponge_effect_relative.loc[i, "value"] = sponge_effect_relative.loc[ # i, "value" # ] / ( # cement_production_sponge_effect_temp.loc[ # ("World total", sponge_effect_relative.loc[i, "year_of_production"]), # "value", # ] # ) # sponge_effect_relative["unit"] = "tonnes of CO2-eq/tonne of cement" # sponge_effect_relative = sponge_effect_relative.set_index( # ["year_of_production", "year_of_use", "cement_type", "property"] # ) # return sponge_effect_relative # def calculate_average_sponge_effect_through_time( # sponge_effect_relative, # ): # """ # This function calculates the average of the sponge effect per tonne of cement and # takes into account its lifetime (the absorbed CO2 is allocated to the different # fractions of cement, based on their age). # Parameters # ---------- # sponge_effect_relative : dataframe # The dataframe contains the relative values of carbonation per tonne of cement, # through the years. # Returns # ------- # average_co2_uptake : dataframe # The dataframe contains the average values for the arbonation effect per tonne of # cement and through its lifetime years. # """ # # We take the averages # sponge_effect_relative_temp = sponge_effect_relative.set_index( # ["unit", "region"], append=True # ) # sponge_effect_relative_temp = sponge_effect_relative_temp.unstack( # level="year_of_use" # ) # # We prepare an empty table # list_col = [] # for i in range(1, len(sponge_effect_relative_temp) + 1): # list_col.append(i) # average_co2_uptake = pd.DataFrame(index=["Average value"], columns=list_col) # for n in average_co2_uptake.columns: # # We get the average values of the CO2 uptake amount after n-years of use # # ("1" being the year it is produced). # # The values are taken in the diagonal since we want to know "on average, how # # much carbonation takes during the 1st year? And in the 2nd year? etc. But # # it's not cumulated! # average_co2_uptake.loc["Average value", n] = np.diag( # sponge_effect_relative_temp, k=n - 1 # ).mean() # return average_co2_uptake # def calculate_sponge_effect( # mass_cement, year, average_co2_uptake, lifetime_use_cement=10 # ): # """ # This function calculates the total CO2 absorbed by a mass of cement defined as a # parameter, after a certain years of lifetime (defined as a paramater). # Parameters # ---------- # mass_cement : float # The amount of cement from which we would like to calculate the CO2-absorbed # after a certain number of years. The unit is in tonnes. # average_co2_uptake : dataframe # The dataframe contains the average value for CO2 absorbed through the lifetime # years. Theunit of values are in tonnes of CO2-absrobed/tonne of cement. # lifetime_use_cement : integer, optional # The lifetime of cement on which we would like to calculate the amount of CO2 # absorbed. The default value is 1, N.B.: the default value considers the first # year as it in the first year that most of the carbonation takes place. # Returns # ------- # co2_uptake_var : float # The amount of CO2 absorbed by the cement defined, after the lifetime defined. # The unit is tonnes of CO2 absorbed. # """ # # Calculation of CO2-uptake for a certain amount of cement (case-study) # # The maximum possible value of the lifetime of cement use is constrained only by # # the data available (1930-2021). # if lifetime_use_cement > 92: # print("The lifetime is too long and cannot be properly modelled.") # sys.exit() # co2_uptake_var = [] # list_years = [] # for y in range(1, lifetime_use_cement + 1): # co2_uptake_var.append( # round(average_co2_uptake.loc["Average value", y] * mass_cement, 2) # ) # list_years.append(year + (y - 1)) # return co2_uptake_var, list_years