CO2 Estimation for Construction
Overview
Based on DDC methodology (Chapter 3.3), this skill provides comprehensive CO2 and carbon footprint calculations for construction projects. Sustainability is no longer optional - clients and regulations demand accurate environmental impact assessments.
Book Reference: "4D, 6D-8D и расчет CO2" / "4D-8D BIM and CO2 Calculation"
"Расчет углеродного следа становится обязательным требованием для многих проектов. BIM-модель содержит все необходимые данные для автоматизации этого процесса." — DDC Book, Chapter 3.3
Quick Start
import pandas as pd
# Load BIM elements with materials
df = pd.read_excel("bim_elements.xlsx")
# CO2 emission factors (kg CO2 per unit)
emission_factors = {
'Concrete': 0.13, # kg CO2 per kg
'Steel': 1.85, # kg CO2 per kg
'Brick': 0.24, # kg CO2 per kg
'Timber': -1.6, # negative = carbon sink
'Glass': 0.85, # kg CO2 per kg
'Aluminum': 8.14 # kg CO2 per kg
}
# Calculate emissions
df['CO2_kg'] = df.apply(
lambda row: row['Weight_kg'] * emission_factors.get(row['Material'], 0),
axis=1
)
total_co2 = df['CO2_kg'].sum()
print(f"Total Carbon Footprint: {total_co2:,.0f} kg CO2")
print(f"Equivalent: {total_co2/1000:,.1f} tonnes CO2")
Emission Factors Database
Material Emission Factors (Embodied Carbon)
# Comprehensive emission factors database (kg CO2e per kg material)
EMISSION_FACTORS_KG = {
# Concrete and cement
'Concrete_C20': 0.10,
'Concrete_C30': 0.13,
'Concrete_C40': 0.16,
'Concrete_C50': 0.19,
'Cement_Portland': 0.83,
'Mortar': 0.20,
# Metals
'Steel_Reinforcing': 1.85,
'Steel_Structural': 1.55,
'Steel_Recycled': 0.47,
'Aluminum_Primary': 8.14,
'Aluminum_Recycled': 0.52,
'Copper': 2.71,
# Masonry
'Brick_Clay': 0.24,
'Brick_Concrete': 0.12,
'Stone_Natural': 0.06,
'Block_Concrete': 0.10,
# Wood (negative = carbon sequestration)
'Timber_Softwood': -1.60,
'Timber_Hardwood': -1.40,
'Plywood': 0.45,
'CLT': -1.20, # Cross-Laminated Timber
'Glulam': -1.10,
# Insulation
'Insulation_Mineral': 1.20,
'Insulation_EPS': 3.29,
'Insulation_XPS': 3.45,
'Insulation_Cellulose': 0.10,
# Glass
'Glass_Float': 0.85,
'Glass_Double': 1.30,
'Glass_Triple': 1.80,
# Plastics
'PVC': 2.61,
'HDPE': 1.93,
'Polycarbonate': 5.00,
# Other
'Gypsum_Board': 0.39,
'Ceramic_Tile': 0.78,
'Asphalt': 0.05
}
# Emission factors per volume (kg CO2e per m³)
EMISSION_FACTORS_M3 = {
'Concrete_C30': 312, # ~2400 kg/m³ * 0.13
'Steel': 14430, # ~7800 kg/m³ * 1.85
'Timber': -800, # ~500 kg/m³ * -1.6
'Brick': 432, # ~1800 kg/m³ * 0.24
'Glass': 2125 # ~2500 kg/m³ * 0.85
}
Carbon Footprint Calculator
Basic Calculator
class CarbonCalculator:
"""Calculate carbon footprint for construction projects"""
def __init__(self, emission_factors=None):
self.factors = emission_factors or EMISSION_FACTORS_KG
self.results = {}
def calculate_embodied_carbon(self, df, material_col='Material',
weight_col='Weight_kg'):
"""Calculate embodied carbon from materials"""
df = df.copy()
# Map materials to emission factors
df['Emission_Factor'] = df[material_col].map(self.factors).fillna(0)
df['CO2_kg'] = df[weight_col] * df['Emission_Factor']
# Summary by material
summary = df.groupby(material_col).agg({
weight_col: 'sum',
'CO2_kg': 'sum'
}).round(2)
self.results['embodied'] = {
'total_kg': df['CO2_kg'].sum(),
'by_material': summary,
'details': df
}
return df
def calculate_transport_carbon(self, df, distance_col='Distance_km',
weight_col='Weight_kg',
transport_type='truck'):
"""Calculate transport emissions"""
# Transport emission factors (kg CO2 per tonne-km)
transport_factors = {
'truck': 0.062,
'rail': 0.022,
'ship': 0.016,
'air': 0.602
}
factor = transport_factors.get(transport_type, 0.062)
df = df.copy()
df['Transport_CO2_kg'] = (df[weight_col] / 1000) * df[distance_col] * factor
self.results['transport'] = {
'total_kg': df['Transport_CO2_kg'].sum(),
'factor_used': factor,
'transport_type': transport_type
}
return df
def calculate_construction_carbon(self, df,
equipment_hours=None,
fuel_consumption=None):
"""Calculate construction phase emissions"""
# Equipment emission factors (kg CO2 per hour)
equipment_factors = {
'excavator': 25.0,
'crane': 18.5,
'concrete_pump': 22.0,
'loader': 15.0,
'compactor': 8.0,
'generator': 12.0
}
if equipment_hours:
construction_co2 = sum(
hours * equipment_factors.get(equip, 15.0)
for equip, hours in equipment_hours.items()
)
elif fuel_consumption:
# Diesel: 2.68 kg CO2 per liter
construction_co2 = fuel_consumption * 2.68
else:
construction_co2 = 0
self.results['construction'] = {
'total_kg': construction_co2
}
return construction_co2
def get_total_footprint(self):
"""Get total carbon footprint"""
total = sum(
r.get('total_kg', 0)
for r in self.results.values()
)
return {
'total_kg': total,
'total_tonnes': total / 1000,
'breakdown': {k: v.get('total_kg', 0) for k, v in self.results.items()}
}
def generate_report(self):
"""Generate carbon footprint report"""
footprint = self.get_total_footprint()
report = []
report.append("=" * 50)
report.append("CARBON FOOTPRINT REPORT")
report.append("=" * 50)
report.append("")
report.append(f"Total Carbon Footprint: {footprint['total_tonnes']:,.2f} tonnes CO2e")
report.append("")
report.append("Breakdown:")
for category, value in footprint['breakdown'].items():
pct = (value / footprint['total_kg'] * 100) if footprint['total_kg'] > 0 else 0
report.append(f" {category.capitalize():15s}: {value:>12,.0f} kg ({pct:>5.1f}%)")
report.append("")
report.append("=" * 50)
return "\n".join(report)
Usage Example
# Load project data
elements = pd.read_excel("bim_export.xlsx")
# Initialize calculator
calc = CarbonCalculator()
# Calculate embodied carbon
elements = calc.calculate_embodied_carbon(
elements,
material_col='Material',
weight_col='Weight_kg'
)
# Add transport emissions
elements['Distance_km'] = 50 # Average transport distance
elements = calc.calculate_transport_carbon(
elements,
distance_col='Distance_km',
weight_col='Weight_kg',
transport_type='truck'
)
# Construction phase
equipment_usage = {
'excavator': 120,
'crane': 500,
'concrete_pump': 80,
'loader': 200
}
calc.calculate_construction_carbon(equipment_hours=equipment_usage)
# Generate report
print(calc.generate_report())
# Get detailed breakdown
footprint = calc.get_total_footprint()
Life Cycle Assessment (LCA)
Full LCA Calculation
class ConstructionLCA:
"""Life Cycle Assessment for construction projects"""
def __init__(self, building_lifespan=50):
self.lifespan = building_lifespan
self.phases = {}
def ca