feat: add embodied carbon calculation fields to objets
This commit is contained in:
@@ -224,6 +224,119 @@ class RevitCarbonAnalyzer:
|
||||
# Calculate carbon
|
||||
try:
|
||||
carbon_results = self.carbon_calculator.calculate_carbon(processed_element)
|
||||
|
||||
# Initialize Embodied Carbon Calculation dictionary
|
||||
embodied_carbon_data = {}
|
||||
|
||||
for material_name, result in carbon_results.items():
|
||||
# Create a dictionary for each material instead of an array
|
||||
material_data = {}
|
||||
|
||||
if result.category == "Wood":
|
||||
# For timber - use name/value/units format as dictionary entries
|
||||
material_data = {
|
||||
"volume": {
|
||||
"name": "volume",
|
||||
"value": result.quantity,
|
||||
"units": "m³",
|
||||
},
|
||||
"database": {
|
||||
"name": "database",
|
||||
"value": result.database,
|
||||
"units": None,
|
||||
},
|
||||
"ecf": {
|
||||
"name": "ecf",
|
||||
"value": result.factor,
|
||||
"units": "kgCO₂e/m³",
|
||||
},
|
||||
"embodied carbon": {
|
||||
"name": "embodied carbon",
|
||||
"value": result.total_carbon,
|
||||
"units": "kgCO₂e",
|
||||
},
|
||||
}
|
||||
elif result.category == "Concrete":
|
||||
# For concrete (include both concrete and reinforcement)
|
||||
material_data = {
|
||||
"volume": {
|
||||
"name": "volume",
|
||||
"value": result.concrete_volume,
|
||||
"units": "m³",
|
||||
},
|
||||
"database": {
|
||||
"name": "database",
|
||||
"value": result.database,
|
||||
"units": None,
|
||||
},
|
||||
"ecf": {
|
||||
"name": "ecf",
|
||||
"value": result.factor,
|
||||
"units": "kgCO₂e/m³",
|
||||
},
|
||||
"concrete carbon": {
|
||||
"name": "concrete carbon",
|
||||
"value": result.concrete_carbon,
|
||||
"units": "kgCO₂e",
|
||||
},
|
||||
"reinforcement mass": {
|
||||
"name": "reinforcement mass",
|
||||
"value": result.reinforcement_mass,
|
||||
"units": "kg",
|
||||
},
|
||||
"reinforcement rate": {
|
||||
"name": "reinforcement rate",
|
||||
"value": result.reinforcement_rate,
|
||||
"units": "kg/m³",
|
||||
},
|
||||
"reinforcement ecf": {
|
||||
"name": "reinforcement ecf",
|
||||
"value": result.reinforcement_factor,
|
||||
"units": "kgCO₂e/kg",
|
||||
},
|
||||
"reinforcement carbon": {
|
||||
"name": "reinforcement carbon",
|
||||
"value": result.reinforcement_carbon,
|
||||
"units": "kgCO₂e",
|
||||
},
|
||||
"embodied carbon": {
|
||||
"name": "embodied carbon",
|
||||
"value": result.total_carbon,
|
||||
"units": "kgCO₂e",
|
||||
},
|
||||
}
|
||||
elif result.category == "Metal":
|
||||
# For metal
|
||||
material_data = {
|
||||
"mass": {
|
||||
"name": "mass",
|
||||
"value": result.quantity,
|
||||
"units": "kg",
|
||||
},
|
||||
"database": {
|
||||
"name": "database",
|
||||
"value": result.database,
|
||||
"units": None,
|
||||
},
|
||||
"ecf": {
|
||||
"name": "ecf",
|
||||
"value": result.factor,
|
||||
"units": "kgCO₂e/kg",
|
||||
},
|
||||
"embodied carbon": {
|
||||
"name": "embodied carbon",
|
||||
"value": result.total_carbon,
|
||||
"units": "kgCO₂e",
|
||||
},
|
||||
}
|
||||
|
||||
# Add this material's data to the main dictionary
|
||||
embodied_carbon_data[material_name] = material_data
|
||||
|
||||
# Attach the data to the original element
|
||||
if hasattr(element, "properties"):
|
||||
element.properties["Embodied Carbon Calculation"] = embodied_carbon_data
|
||||
|
||||
return {
|
||||
"id": element_id,
|
||||
"status": "processed",
|
||||
@@ -234,7 +347,6 @@ class RevitCarbonAnalyzer:
|
||||
"name": m.properties.name,
|
||||
"type": m.type.value,
|
||||
"volume": m.properties.volume,
|
||||
# Add other material properties as needed
|
||||
}
|
||||
for m in processed_element.materials
|
||||
],
|
||||
@@ -371,6 +483,11 @@ def automate_function(
|
||||
"\nNOTE: All materials successfully matched with emission factors."
|
||||
)
|
||||
|
||||
# Upload mutated model
|
||||
automate_context.create_new_version_in_project(
|
||||
model_root, f"{commit_root.branchName}_embodied_carbon"
|
||||
)
|
||||
|
||||
# Mark success with detailed message
|
||||
automate_context.mark_run_success(success_message)
|
||||
|
||||
|
||||
@@ -12,9 +12,9 @@ class ConcreteEmissionDatabase(EmissionFactorDatabase):
|
||||
super().__init__()
|
||||
self._database_name = database_name
|
||||
self._factors = {}
|
||||
self._init_factors()
|
||||
self._load_emission_factors_from_database()
|
||||
|
||||
def _init_factors(self):
|
||||
def _load_emission_factors_from_database(self):
|
||||
"""Initialize factors based on the specific database."""
|
||||
# Define mappings from database type to strength values
|
||||
database_strength_values = {
|
||||
|
||||
@@ -14,14 +14,3 @@ class EmissionFactor:
|
||||
valid_until: Optional[str] = None
|
||||
manufacturer: Optional[str] = None
|
||||
plant_location: Optional[str] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class CarbonResult:
|
||||
"""Result of a carbon calculation"""
|
||||
|
||||
material_name: str
|
||||
emission_factor: EmissionFactor
|
||||
quantity: float
|
||||
total_carbon: float
|
||||
category: str
|
||||
|
||||
+14
-1
@@ -37,8 +37,21 @@ class BuildingElement:
|
||||
materials: List[Material]
|
||||
carbon_data: Optional[Dict] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class CarbonResult:
|
||||
factor: float # kgCO2e/kg for metals, kgCO2e/m3 for wood
|
||||
total_carbon: float # kgCO2e
|
||||
category: str
|
||||
category: str
|
||||
|
||||
# Additional fields for detailed output
|
||||
quantity: float = None # volume (m³) for concrete/wood, mass (kg) for metal
|
||||
database: str = None # database source
|
||||
|
||||
# Concrete-specific fields
|
||||
concrete_volume: float = None # m³
|
||||
concrete_carbon: float = None # kgCO2e
|
||||
reinforcement_mass: float = None # kg
|
||||
reinforcement_rate: float = None # kg/m³
|
||||
reinforcement_factor: float = None # kgCO2e/kg
|
||||
reinforcement_carbon: float = None # kgCO2e
|
||||
@@ -121,6 +121,8 @@ class CarbonCalculator:
|
||||
factor=factor.value,
|
||||
total_carbon=material.mass * factor.value,
|
||||
category="Metal",
|
||||
quantity=material.mass,
|
||||
database=self._steel_database,
|
||||
)
|
||||
|
||||
def _calculate_wood_carbon(self, material: Material) -> CarbonResult:
|
||||
@@ -148,6 +150,8 @@ class CarbonCalculator:
|
||||
factor=factor.value,
|
||||
total_carbon=material.properties.volume * factor.value,
|
||||
category="Wood",
|
||||
quantity=material.properties.volume,
|
||||
database=self._timber_database,
|
||||
)
|
||||
|
||||
def _calculate_concrete_carbon(
|
||||
@@ -220,19 +224,20 @@ class CarbonCalculator:
|
||||
total_carbon = concrete_carbon + reinforcement_carbon
|
||||
|
||||
# Create result with additional metadata
|
||||
result = CarbonResult(
|
||||
return CarbonResult(
|
||||
factor=concrete_factor.value,
|
||||
total_carbon=total_carbon,
|
||||
category="Concrete",
|
||||
quantity=concrete_volume,
|
||||
database=self._concrete_database,
|
||||
concrete_volume=concrete_volume,
|
||||
concrete_carbon=concrete_carbon,
|
||||
reinforcement_mass=reinforcement_mass,
|
||||
reinforcement_rate=reinforcement_rate,
|
||||
reinforcement_factor=rebar_factor.value,
|
||||
reinforcement_carbon=reinforcement_carbon,
|
||||
)
|
||||
|
||||
# TODO: Add extra metadata (not in original CarbonResult class, would need extension)
|
||||
# TODO: result.concrete_carbon = concrete_carbon
|
||||
# TODO: result.reinforcement_carbon = reinforcement_carbon
|
||||
# TODO: result.reinforcement_rate = reinforcement_rate
|
||||
|
||||
return result
|
||||
|
||||
@staticmethod
|
||||
def _map_element_category_to_concrete_type(
|
||||
element_category: ElementCategory,
|
||||
|
||||
Reference in New Issue
Block a user