Merge remote-tracking branch 'origin/master' into heat_pump

# Conflicts:
#	city_model_structure/city.py
#	city_model_structure/energy_system.py
#	city_model_structure/fuel.py
#	city_model_structure/machine.py
#	city_model_structure/vehicle.py
#	data/life_cycle_assessment/lca_data.xml
#	exports/energy_systems_factory.py
#	helpers/constants.py
#	helpers/yearly_from_daily_schedules.py
#	imports/energy_systems/air_source_hp_parameters.py
#	imports/geometry/rhino.py
#	imports/geometry_factory.py
#	imports/life_cycle_assessment/lca_fuel.py
#	imports/life_cycle_assessment/lca_machine.py
#	imports/life_cycle_assessment/lca_vehicle.py
#	imports/life_cycle_assessment_factory.py
#	requirements.txt
#	unittests/test_life_cycle_assessment_factory.py
This commit is contained in:
Guille Gutierrez 2022-03-17 14:34:11 -04:00
commit f2ff10ad47
64 changed files with 3613 additions and 1507 deletions

32
catalogs/catalog.py Normal file
View File

@ -0,0 +1,32 @@
"""
Catalog base class
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
"""
class Catalog:
"""
Catalog name
"""
@property
def names(self):
"""
Base property to return the catalog entries names
:return: not implemented error
"""
raise NotImplementedError
def entries(self, category=None):
"""
Base property to return the catalog entries
:return: not implemented error
"""
raise NotImplementedError
def get_entry(self, name):
"""
Base property to return the catalog entry matching the given name
:return: not implemented error
"""
raise NotImplementedError

View File

@ -0,0 +1,33 @@
"""
Greenery catalog content
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
"""
class GreeneryContent:
def __init__(self, vegetations, plants, soils):
self._vegetations = vegetations
self._plants = plants
self._soils = soils
@property
def vegetations(self):
"""
All vegetation in the catalog
"""
return self._vegetations
@property
def plants(self):
"""
All plants in the catalog
"""
return self._plants
@property
def soils(self):
"""
All soils in the catalog
"""
return self._soils

View File

@ -0,0 +1,85 @@
"""
Greenery catalog data model Plant class
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
"""
from catalogs.data_model.greenery.soil import Soil as libs_soil
class Plant:
def __init__(self, category, plant):
self._name = plant.name
self._category = category
self._height = plant.height
self._leaf_area_index = plant.leafAreaIndex
self._leaf_reflectivity = plant.leafReflectivity
self._leaf_emissivity = plant.leafEmissivity
self._minimal_stomatal_resistance = plant.minimalStomatalResistance
self._co2_sequestration = plant.co2Sequestration
self._grows_on = []
for soil in plant.growsOn:
self._grows_on.append(libs_soil(soil))
@property
def name(self):
"""
Get plant name
"""
return self._name
@property
def category(self):
"""
Get plant category name
"""
return self._category
@property
def height(self):
"""
Get plant height
"""
return self._height
@property
def leaf_area_index(self):
"""
Get plant leaf area index
"""
return self._leaf_area_index
@property
def leaf_reflectivity(self):
"""
Get plant leaf area index
"""
return self._leaf_reflectivity
@property
def leaf_emissivity(self):
"""
Get plant leaf emissivity
"""
return self._leaf_emissivity
@property
def minimal_stomatal_resistance(self):
"""
Get plant minimal stomatal resistance
"""
return self._minimal_stomatal_resistance
@property
def co2_sequestration(self):
"""
Get plant co2 sequestration capacity
"""
return self._co2_sequestration
@property
def grows_on(self) -> [libs_soil]:
"""
Get plant compatible soils
"""
return self._grows_on

View File

@ -0,0 +1,17 @@
"""
Greenery catalog data model Plant percentage class
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
"""
from catalogs.data_model.greenery.plant import Plant as libs_plant
class PlantPercentage(libs_plant):
def __init__(self, percentage, plant_category, plant):
super().__init__(plant_category, plant)
self._percentage = percentage
@property
def percentage(self):
return self._percentage

View File

@ -0,0 +1,96 @@
"""
Greenery catalog data model Soil class
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
"""
class Soil:
def __init__(self, soil):
self._name = soil.name
self._roughness = soil.roughness
self._dry_conductivity = soil.conductivityOfDrySoil
self._dry_density = soil.densityOfDrySoil
self._dry_specific_heat = soil.specificHeatOfDrySoil
self._thermal_absorptance = soil.thermalAbsorptance
self._solar_absorptance = soil.solarAbsorptance
self._visible_absorptance = soil.visibleAbsorptance
self._saturation_volumetric_moisture_content = soil.saturationVolumetricMoistureContent
self._residual_volumetric_moisture_content = soil.residualVolumetricMoistureContent
self._initial_volumetric_moisture_content = soil.initialVolumetricMoistureContent
@property
def name(self):
"""
Get soil name
"""
return self._name
@property
def roughness(self):
"""
Get soil roughness
"""
return self._roughness
@property
def dry_conductivity(self):
"""
Get soil dry conductivity
"""
return self._dry_conductivity
@property
def dry_density(self):
"""
Get soil dry density
"""
return self._dry_density
@property
def dry_specific_heat(self):
"""
Get soil dry specific heat
"""
return self._dry_specific_heat
@property
def thermal_absorptance(self):
"""
Get soil thermal absortance
"""
return self._thermal_absorptance
@property
def solar_absorptance(self):
"""
Get soil solar absortance
"""
return self._solar_absorptance
@property
def visible_absorptance(self):
"""
Get soil visible absortance
"""
return self._visible_absorptance
@property
def saturation_volumetric_moisture_content(self):
"""
Get soil saturation volumetric moisture content
"""
return self._saturation_volumetric_moisture_content
@property
def residual_volumetric_moisture_content(self):
"""
Get soil residual volumetric moisture content
"""
return self._residual_volumetric_moisture_content
@property
def initial_volumetric_moisture_content(self):
"""
Get soil initial volumetric moisture content
"""
return self._initial_volumetric_moisture_content

View File

@ -0,0 +1,151 @@
"""
Greenery catalog data model Vegetation class
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
"""
from catalogs.data_model.greenery.plant_percentage import PlantPercentage
class Vegetation:
def __init__(self, category, vegetation, plant_percentages):
self._name = vegetation.name
self._category = category
self._soil_thickness = vegetation.thicknessOfSoil
self._management = vegetation.management
self._air_gap = vegetation.airGap
self._soil_name = vegetation.soil.name
self._soil_roughness = vegetation.soil.roughness
self._dry_soil_conductivity = vegetation.soil.conductivityOfDrySoil
self._dry_soil_density = vegetation.soil.densityOfDrySoil
self._dry_soil_specific_heat = vegetation.soil.specificHeatOfDrySoil
self._soil_thermal_absorptance = vegetation.soil.thermalAbsorptance
self._soil_solar_absorptance = vegetation.soil.solarAbsorptance
self._soil_visible_absorptance = vegetation.soil.visibleAbsorptance
self._soil_saturation_volumetric_moisture_content = vegetation.soil.saturationVolumetricMoistureContent
self._soil_residual_volumetric_moisture_content = vegetation.soil.residualVolumetricMoistureContent
self._soil_initial_volumetric_moisture_content = vegetation.soil.initialVolumetricMoistureContent
self._plant_percentages = plant_percentages
@property
def name(self):
"""
Get vegetation name
"""
return self._name
@property
def category(self):
"""
Get vegetation category
"""
return self._category
@property
def soil_thickness(self):
"""
Get soil thickness
"""
return self._soil_thickness
@property
def management(self):
"""
Get management
"""
return self._management
@property
def air_gap(self):
"""
Get air gap
"""
return self._air_gap
@property
def plant_percentages(self) -> [PlantPercentage]:
"""
Get plant percentages
"""
percentage = 0.0
for plant_percentage in self._plant_percentages:
percentage += float(plant_percentage.percentage)
if percentage > 100:
raise ValueError('the plant percentage in this vegetation is over 100%')
return self._plant_percentages
@property
def soil_name(self):
"""
Get soil name
"""
return self._soil_name
@property
def soil_roughness(self):
"""
Get soil roughness
"""
return self._soil_roughness
@property
def dry_soil_conductivity(self):
"""
Get soil dry conductivity
"""
return self._dry_soil_conductivity
@property
def dry_soil_density(self):
"""
Get soil dry density
"""
return self._dry_soil_density
@property
def dry_soil_specific_heat(self):
"""
Get soil dry specific heat
"""
return self._dry_soil_specific_heat
@property
def soil_thermal_absorptance(self):
"""
Get soil thermal absortance
"""
return self._soil_thermal_absorptance
@property
def soil_solar_absorptance(self):
"""
Get soil solar absortance
"""
return self._soil_solar_absorptance
@property
def soil_visible_absorptance(self):
"""
Get soil visible absortance
"""
return self._soil_visible_absorptance
@property
def soil_saturation_volumetric_moisture_content(self):
"""
Get soil saturation volumetric moisture content
"""
return self._soil_saturation_volumetric_moisture_content
@property
def soil_residual_volumetric_moisture_content(self):
"""
Get soil residual volumetric moisture content
"""
return self._soil_residual_volumetric_moisture_content
@property
def soil_initial_volumetric_moisture_content(self):
"""
Get soil initial volumetric moisture content
"""
return self._soil_initial_volumetric_moisture_content

View File

@ -0,0 +1,268 @@
<?xml version="1.0" encoding="UTF-8"?>
<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="greenerycatalog" nsURI="http://ca.concordia/greenerycatalog"
nsPrefix="greenery">
<eClassifiers xsi:type="ecore:EClass" name="Soil">
<eAnnotations source="http://www.eclipse.org/emf/2002/Ecore">
<details key="constraints" value="nonNegative"/>
</eAnnotations>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
defaultValueLiteral=""/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="roughness" eType="#//Roughness"
defaultValueLiteral="MediumRough">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="defines the relative roughness of a particular material layer. This parameter only influences the convection coefficients, more specifically the exterior convection coefficient. A nominal value is expected in with the options being &quot;VeryRough&quot;, &quot;Rough&quot;, &quot;MediumRough&quot;, &quot;MediumSmooth&quot;, &quot;Smooth&quot;, and &quot;VerySmooth&quot; in order of roughest to smoothest options."/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="conductivityOfDrySoil"
lowerBound="1" eType="ecore:EDataType platform:/plugin/de.hftstuttgart.cityunits.model/model/Quantities.ecore#//Quantity"
defaultValueLiteral="1.0 W/(m*K)">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Thermal conductivity W/(m-K). Range: 0.2 to 1.5"/>
</eAnnotations>
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0.2"/>
<details key="max" value="1.5"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="densityOfDrySoil" eType="ecore:EDataType platform:/plugin/de.hftstuttgart.cityunits.model/model/Quantities.ecore#//Quantity"
defaultValueLiteral="1100 kg/m³">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Density in kg/m³. "/>
</eAnnotations>
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0.1"/>
<details key="max" value="10000"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="specificHeatOfDrySoil"
eType="ecore:EDataType platform:/plugin/de.hftstuttgart.cityunits.model/model/Quantities.ecore#//Quantity"
defaultValueLiteral="1200 J/(kg*K)">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="in units of J/(kg-K). Range(300 to 2000)"/>
</eAnnotations>
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0.2"/>
<details key="max" value="2000"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="thermalAbsorptance" eType="ecore:EDataType platform:/plugin/de.hftstuttgart.cityunits.model/model/Quantities.ecore#//Quantity"
defaultValueLiteral="0.9">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="the fraction of incident long wavelength (>2.5 microns) radiation that is absorbed by the material. This parameter is used when calculating the long wavelength radiant exchange between various surfaces and affects the surface heat balances (both inside and outside as appropriate). For long wavelength radiant exchange, thermal emissivity and thermal emittance are equal to thermal absorptance. Range: 0 to 1"/>
</eAnnotations>
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0.0"/>
<details key="max" value="1.0"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="solarAbsorptance" eType="ecore:EDataType platform:/plugin/de.hftstuttgart.cityunits.model/model/Quantities.ecore#//Quantity"
defaultValueLiteral="0.7">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="the fraction of incident solar radiation that is absorbed by the material.&#xA;Solar radiation (0.3 to 2.537 microns) includes the visible spectrum as well as infrared and ultraviolet wavelengths. This parameter is used when calculating the amount of incident solar radiation absorbed by various surfaces and affects the surface heat balances (both inside and outside as appropriate). If solar reflectance (or reflectivity) data is available, then absorptance is equal to 1.0 minus reflectance (for opaque materials).&#xA;Range: 0 to 1"/>
</eAnnotations>
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0.0"/>
<details key="max" value="1.0"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="visibleAbsorptance" eType="ecore:EDataType platform:/plugin/de.hftstuttgart.cityunits.model/model/Quantities.ecore#//Quantity"
defaultValueLiteral="0.75">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="The visible absorptance field in the Material input syntax represents the fraction of incident visible wavelength radiation that is absorbed by the material.&#xA;Visible wavelength radiation (0.37 to 0.78 microns weighted by photopic response) is slightly different than solar radiation in that the visible band of wavelengths is much more narrow while solar radiation includes the visible spectrum as well as infrared and ultraviolet wavelengths.&#xA;This parameter is used when calculating the amount of incident visible radiation absorbed by various surfaces and affects the surface heat balances (both inside and outside as appropriate) as well as the daylighting calculations. If visible reflectance (or reflectivity) data is available, then absorptance is equal to 1.0 minus reflectance (for opaque materials).&#xA;Range: 0.5 to 1.0"/>
</eAnnotations>
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0.5"/>
<details key="max" value="1.0"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="saturationVolumetricMoistureContent"
eType="ecore:EDataType platform:/plugin/de.hftstuttgart.cityunits.model/model/Quantities.ecore#//Quantity"
defaultValueLiteral="0.0">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="input of the saturation moisture content of the soil layer. Range: 0.1 to 0.5"/>
</eAnnotations>
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0.1"/>
<details key="max" value="0.5"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="residualVolumetricMoistureContent"
eType="ecore:EDataType platform:/plugin/de.hftstuttgart.cityunits.model/model/Quantities.ecore#//Quantity"
defaultValueLiteral="0.05">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Input of the residual moisture content of the soil layer. Range: 0.01 to 0.1"/>
</eAnnotations>
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0.01"/>
<details key="max" value="0.1"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="initialVolumetricMoistureContent"
eType="ecore:EDataType platform:/plugin/de.hftstuttgart.cityunits.model/model/Quantities.ecore#//Quantity"
defaultValueLiteral="0.1">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Range: 0.05 to 0.5"/>
</eAnnotations>
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0.05"/>
<details key="max" value="0.5"/>
</eAnnotations>
</eStructuralFeatures>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="Plant">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="name" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="height" lowerBound="1"
eType="ecore:EDataType platform:/plugin/de.hftstuttgart.cityunits.model/model/Quantities.ecore#//Quantity"
defaultValueLiteral="0.1 m">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Maximum height of plants. Range: 0.005 to 1 m"/>
</eAnnotations>
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0.005"/>
<details key="max" value="1.0"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="leafAreaIndex" lowerBound="1"
eType="ecore:EDataType platform:/plugin/de.hftstuttgart.cityunits.model/model/Quantities.ecore#//Quantity"
defaultValueLiteral="2.5">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Leaf area per unit area of soil surface. Range: 0.001 to 5.0 m²/m²"/>
</eAnnotations>
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0.001"/>
<details key="max" value="5.0"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="leafReflectivity" lowerBound="1"
eType="ecore:EDataType platform:/plugin/de.hftstuttgart.cityunits.model/model/Quantities.ecore#//Quantity"
defaultValueLiteral="0.1">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Represents the fraction of incident solar radiation that is reflected by the individual leaf surfaces (albedo).&#xA;Range: 0.05 to 0.5"/>
</eAnnotations>
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0.05"/>
<details key="max" value="0.5"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="leafEmissivity" lowerBound="1"
eType="ecore:EDataType platform:/plugin/de.hftstuttgart.cityunits.model/model/Quantities.ecore#//Quantity"
defaultValueLiteral="0.9">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Ratio of thermal radiation emitted from leaf surfaces to that emitted by an ideal black body at the same temperature.&#xA;This parameter is used when calculating the long wavelength radiant exchange at the leaf surfaces.&#xA;Range: 0.8 to 1"/>
</eAnnotations>
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0.8"/>
<details key="max" value="1.0"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="minimalStomatalResistance"
lowerBound="1" eType="ecore:EDataType platform:/plugin/de.hftstuttgart.cityunits.model/model/Quantities.ecore#//Quantity"
defaultValueLiteral="100.0 s/m">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Resistance of the plants to moisture transport.&#xA;Plants with low values of stomatal resistance will result in higher evapotranspiration rates than plants with high resistance.&#xA;Range: 50 to 300 m/s"/>
</eAnnotations>
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="50.0"/>
<details key="max" value="300.0"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EReference" name="growsOn" lowerBound="1"
upperBound="-1" eType="#//Soil"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="co2Sequestration" eType="ecore:EDataType platform:/plugin/de.hftstuttgart.cityunits.model/model/Quantities.ecore#//Quantity"
defaultValueLiteral="kgCO₂eq"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="SupportEnvelope">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="roughness" eType="#//Roughness"
defaultValueLiteral="MediumRough"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="solarAbsorptance" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EDouble"
defaultValueLiteral="0.0"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="conductivity" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EDouble"
defaultValueLiteral="0.0"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="visibleAbsorptance" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EDouble"
defaultValueLiteral="0.0"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="specificHeat" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EDouble"
defaultValueLiteral="0.0"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="density" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EDouble"
defaultValueLiteral="0.0"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="thermalAbsorptance" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EDouble"
defaultValueLiteral="0.0"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="GreeneryCatalog">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="source" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="plantCategories" lowerBound="1"
upperBound="-1" eType="#//PlantCategory" containment="true"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="vegetationCategories" lowerBound="1"
upperBound="-1" eType="#//VegetationCategory" containment="true"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="soils" upperBound="-1"
eType="#//Soil" containment="true"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="PlantCategory">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Excluding (that is non-overlapping) categories like Trees, Hedeges, Grasses that help users finding a specific biol. plant species."/>
</eAnnotations>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="plants" upperBound="-1"
eType="#//Plant" containment="true"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="IrrigationSchedule">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="Vegetation">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Plant life or total plant cover (as of an area)"/>
</eAnnotations>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="name" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="thicknessOfSoil" lowerBound="1"
eType="ecore:EDataType platform:/plugin/de.hftstuttgart.cityunits.model/model/Quantities.ecore#//Quantity"
defaultValueLiteral="20 cm">
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0"/>
<details key="max" value="1000"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EReference" name="soil" lowerBound="1" eType="#//Soil"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="plants" lowerBound="1"
upperBound="-1" eType="#//PlantPercentage" containment="true"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="management" lowerBound="1"
eType="#//Management" defaultValueLiteral="NA"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="airGap" lowerBound="1"
eType="ecore:EDataType platform:/plugin/de.hftstuttgart.cityunits.model/model/Quantities.ecore#//Quantity"
defaultValueLiteral="0.0 cm"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="VegetationCategory">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Excluding (that is non-overlapping) categories to help users finding a specific vegetation template."/>
</eAnnotations>
<eStructuralFeatures xsi:type="ecore:EReference" name="vegetationTemplates" upperBound="-1"
eType="#//Vegetation" containment="true"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EEnum" name="Management">
<eLiterals name="Intensive"/>
<eLiterals name="Extensive" value="1"/>
<eLiterals name="SemiIntensive" value="2"/>
<eLiterals name="NA" value="3"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="PlantPercentage">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="percentage" lowerBound="1"
eType="ecore:EDataType platform:/plugin/de.hftstuttgart.cityunits.model/model/Quantities.ecore#//Quantity"
defaultValueLiteral="100">
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0"/>
<details key="max" value="100"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EReference" name="plant" lowerBound="1" eType="#//Plant"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EEnum" name="Roughness">
<eLiterals name="VeryRough"/>
<eLiterals name="Rough" value="1"/>
<eLiterals name="MediumRough" value="2"/>
<eLiterals name="MediumSmooth" value="3"/>
<eLiterals name="Smooth" value="4"/>
<eLiterals name="VerySmooth" value="5"/>
</eClassifiers>
</ecore:EPackage>

View File

@ -0,0 +1,318 @@
"""Definition of meta model 'greenerycatalog'."""
from functools import partial
import pyecore.ecore as Ecore
from pyecore.ecore import *
name = 'greenerycatalog'
nsURI = 'http://ca.concordia/greenerycatalog'
nsPrefix = 'greenery'
eClass = EPackage(name=name, nsURI=nsURI, nsPrefix=nsPrefix)
eClassifiers = {}
getEClassifier = partial(Ecore.getEClassifier, searchspace=eClassifiers)
Management = EEnum('Management', literals=['Intensive', 'Extensive', 'SemiIntensive', 'NA'])
Roughness = EEnum('Roughness', literals=['VeryRough', 'Rough',
'MediumRough', 'MediumSmooth', 'Smooth', 'VerySmooth'])
class Soil(EObject, metaclass=MetaEClass):
name = EAttribute(eType=EString, unique=True, derived=False, changeable=True)
roughness = EAttribute(eType=Roughness, unique=True, derived=False,
changeable=True, default_value=Roughness.MediumRough)
conductivityOfDrySoil = EAttribute(
eType=EString, unique=True, derived=False, changeable=True, default_value='1.0 W/(m*K)')
densityOfDrySoil = EAttribute(eType=EString, unique=True, derived=False,
changeable=True, default_value='1100 kg/m³')
specificHeatOfDrySoil = EAttribute(
eType=EString, unique=True, derived=False, changeable=True, default_value='1200 J/(kg*K)')
thermalAbsorptance = EAttribute(eType=EString, unique=True,
derived=False, changeable=True, default_value='0.9')
solarAbsorptance = EAttribute(eType=EString, unique=True,
derived=False, changeable=True, default_value='0.7')
visibleAbsorptance = EAttribute(eType=EString, unique=True,
derived=False, changeable=True, default_value='0.75')
saturationVolumetricMoistureContent = EAttribute(
eType=EString, unique=True, derived=False, changeable=True, default_value='0.0')
residualVolumetricMoistureContent = EAttribute(
eType=EString, unique=True, derived=False, changeable=True, default_value='0.05')
initialVolumetricMoistureContent = EAttribute(
eType=EString, unique=True, derived=False, changeable=True, default_value='0.1')
def __init__(self, *, name=None, roughness=None, conductivityOfDrySoil=None, densityOfDrySoil=None, specificHeatOfDrySoil=None, thermalAbsorptance=None, solarAbsorptance=None, visibleAbsorptance=None, saturationVolumetricMoistureContent=None, residualVolumetricMoistureContent=None, initialVolumetricMoistureContent=None):
# if kwargs:
# raise AttributeError('unexpected arguments: {}'.format(kwargs))
super().__init__()
if name is not None:
self.name = name
if roughness is not None:
self.roughness = roughness
if conductivityOfDrySoil is not None:
self.conductivityOfDrySoil = conductivityOfDrySoil
if densityOfDrySoil is not None:
self.densityOfDrySoil = densityOfDrySoil
if specificHeatOfDrySoil is not None:
self.specificHeatOfDrySoil = specificHeatOfDrySoil
if thermalAbsorptance is not None:
self.thermalAbsorptance = thermalAbsorptance
if solarAbsorptance is not None:
self.solarAbsorptance = solarAbsorptance
if visibleAbsorptance is not None:
self.visibleAbsorptance = visibleAbsorptance
if saturationVolumetricMoistureContent is not None:
self.saturationVolumetricMoistureContent = saturationVolumetricMoistureContent
if residualVolumetricMoistureContent is not None:
self.residualVolumetricMoistureContent = residualVolumetricMoistureContent
if initialVolumetricMoistureContent is not None:
self.initialVolumetricMoistureContent = initialVolumetricMoistureContent
class Plant(EObject, metaclass=MetaEClass):
name = EAttribute(eType=EString, unique=True, derived=False, changeable=True)
height = EAttribute(eType=EString, unique=True, derived=False,
changeable=True, default_value='0.1 m')
leafAreaIndex = EAttribute(eType=EString, unique=True, derived=False,
changeable=True, default_value='2.5')
leafReflectivity = EAttribute(eType=EString, unique=True,
derived=False, changeable=True, default_value='0.1')
leafEmissivity = EAttribute(eType=EString, unique=True, derived=False,
changeable=True, default_value='0.9')
minimalStomatalResistance = EAttribute(
eType=EString, unique=True, derived=False, changeable=True, default_value='100.0 s/m')
co2Sequestration = EAttribute(eType=EString, unique=True, derived=False,
changeable=True, default_value='kgCO₂eq')
growsOn = EReference(ordered=True, unique=True, containment=False, derived=False, upper=-1)
def __init__(self, *, name=None, height=None, leafAreaIndex=None, leafReflectivity=None, leafEmissivity=None, minimalStomatalResistance=None, growsOn=None, co2Sequestration=None):
# if kwargs:
# raise AttributeError('unexpected arguments: {}'.format(kwargs))
super().__init__()
if name is not None:
self.name = name
if height is not None:
self.height = height
if leafAreaIndex is not None:
self.leafAreaIndex = leafAreaIndex
if leafReflectivity is not None:
self.leafReflectivity = leafReflectivity
if leafEmissivity is not None:
self.leafEmissivity = leafEmissivity
if minimalStomatalResistance is not None:
self.minimalStomatalResistance = minimalStomatalResistance
if co2Sequestration is not None:
self.co2Sequestration = co2Sequestration
if growsOn:
self.growsOn.extend(growsOn)
class SupportEnvelope(EObject, metaclass=MetaEClass):
roughness = EAttribute(eType=Roughness, unique=True, derived=False,
changeable=True, default_value=Roughness.MediumRough)
solarAbsorptance = EAttribute(eType=EDouble, unique=True,
derived=False, changeable=True, default_value=0.0)
conductivity = EAttribute(eType=EDouble, unique=True, derived=False,
changeable=True, default_value=0.0)
visibleAbsorptance = EAttribute(eType=EDouble, unique=True,
derived=False, changeable=True, default_value=0.0)
specificHeat = EAttribute(eType=EDouble, unique=True, derived=False,
changeable=True, default_value=0.0)
density = EAttribute(eType=EDouble, unique=True, derived=False,
changeable=True, default_value=0.0)
thermalAbsorptance = EAttribute(eType=EDouble, unique=True,
derived=False, changeable=True, default_value=0.0)
def __init__(self, *, roughness=None, solarAbsorptance=None, conductivity=None, visibleAbsorptance=None, specificHeat=None, density=None, thermalAbsorptance=None):
# if kwargs:
# raise AttributeError('unexpected arguments: {}'.format(kwargs))
super().__init__()
if roughness is not None:
self.roughness = roughness
if solarAbsorptance is not None:
self.solarAbsorptance = solarAbsorptance
if conductivity is not None:
self.conductivity = conductivity
if visibleAbsorptance is not None:
self.visibleAbsorptance = visibleAbsorptance
if specificHeat is not None:
self.specificHeat = specificHeat
if density is not None:
self.density = density
if thermalAbsorptance is not None:
self.thermalAbsorptance = thermalAbsorptance
class GreeneryCatalog(EObject, metaclass=MetaEClass):
name = EAttribute(eType=EString, unique=True, derived=False, changeable=True)
description = EAttribute(eType=EString, unique=True, derived=False, changeable=True)
source = EAttribute(eType=EString, unique=True, derived=False, changeable=True)
plantCategories = EReference(ordered=True, unique=True,
containment=True, derived=False, upper=-1)
vegetationCategories = EReference(ordered=True, unique=True,
containment=True, derived=False, upper=-1)
soils = EReference(ordered=True, unique=True, containment=True, derived=False, upper=-1)
def __init__(self, *, name=None, description=None, source=None, plantCategories=None, vegetationCategories=None, soils=None):
# if kwargs:
# raise AttributeError('unexpected arguments: {}'.format(kwargs))
super().__init__()
if name is not None:
self.name = name
if description is not None:
self.description = description
if source is not None:
self.source = source
if plantCategories:
self.plantCategories.extend(plantCategories)
if vegetationCategories:
self.vegetationCategories.extend(vegetationCategories)
if soils:
self.soils.extend(soils)
class PlantCategory(EObject, metaclass=MetaEClass):
"""Excluding (that is non-overlapping) categories like Trees, Hedeges, Grasses that help users finding a specific biol. plant species."""
name = EAttribute(eType=EString, unique=True, derived=False, changeable=True)
plants = EReference(ordered=True, unique=True, containment=True, derived=False, upper=-1)
def __init__(self, *, name=None, plants=None):
# if kwargs:
# raise AttributeError('unexpected arguments: {}'.format(kwargs))
super().__init__()
if name is not None:
self.name = name
if plants:
self.plants.extend(plants)
class IrrigationSchedule(EObject, metaclass=MetaEClass):
name = EAttribute(eType=EString, unique=True, derived=False, changeable=True)
def __init__(self, *, name=None):
# if kwargs:
# raise AttributeError('unexpected arguments: {}'.format(kwargs))
super().__init__()
if name is not None:
self.name = name
class Vegetation(EObject, metaclass=MetaEClass):
"""Plant life or total plant cover (as of an area)"""
name = EAttribute(eType=EString, unique=True, derived=False, changeable=True)
thicknessOfSoil = EAttribute(eType=EString, unique=True, derived=False,
changeable=True, default_value='20 cm')
management = EAttribute(eType=Management, unique=True, derived=False,
changeable=True, default_value=Management.NA)
airGap = EAttribute(eType=EString, unique=True, derived=False,
changeable=True, default_value='0.0 cm')
soil = EReference(ordered=True, unique=True, containment=False, derived=False)
plants = EReference(ordered=True, unique=True, containment=True, derived=False, upper=-1)
def __init__(self, *, name=None, thicknessOfSoil=None, soil=None, plants=None, management=None, airGap=None):
# if kwargs:
# raise AttributeError('unexpected arguments: {}'.format(kwargs))
super().__init__()
if name is not None:
self.name = name
if thicknessOfSoil is not None:
self.thicknessOfSoil = thicknessOfSoil
if management is not None:
self.management = management
if airGap is not None:
self.airGap = airGap
if soil is not None:
self.soil = soil
if plants:
self.plants.extend(plants)
class VegetationCategory(EObject, metaclass=MetaEClass):
"""Excluding (that is non-overlapping) categories to help users finding a specific vegetation template."""
name = EAttribute(eType=EString, unique=True, derived=False, changeable=True)
vegetationTemplates = EReference(ordered=True, unique=True,
containment=True, derived=False, upper=-1)
def __init__(self, *, vegetationTemplates=None, name=None):
# if kwargs:
# raise AttributeError('unexpected arguments: {}'.format(kwargs))
super().__init__()
if name is not None:
self.name = name
if vegetationTemplates:
self.vegetationTemplates.extend(vegetationTemplates)
class PlantPercentage(EObject, metaclass=MetaEClass):
percentage = EAttribute(eType=EString, unique=True, derived=False,
changeable=True, default_value='100')
plant = EReference(ordered=True, unique=True, containment=False, derived=False)
def __init__(self, *, percentage=None, plant=None):
# if kwargs:
# raise AttributeError('unexpected arguments: {}'.format(kwargs))
super().__init__()
if percentage is not None:
self.percentage = percentage
if plant is not None:
self.plant = plant

View File

@ -0,0 +1,268 @@
<?xml version="1.0" encoding="UTF-8"?>
<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="greenerycatalog" nsURI="http://ca.concordia/greenerycatalog"
nsPrefix="greenery">
<eClassifiers xsi:type="ecore:EClass" name="Soil">
<eAnnotations source="http://www.eclipse.org/emf/2002/Ecore">
<details key="constraints" value="nonNegative"/>
</eAnnotations>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
defaultValueLiteral=""/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="roughness" eType="#//Roughness"
defaultValueLiteral="MediumRough">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="defines the relative roughness of a particular material layer. This parameter only influences the convection coefficients, more specifically the exterior convection coefficient. A nominal value is expected in with the options being &quot;VeryRough&quot;, &quot;Rough&quot;, &quot;MediumRough&quot;, &quot;MediumSmooth&quot;, &quot;Smooth&quot;, and &quot;VerySmooth&quot; in order of roughest to smoothest options."/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="conductivityOfDrySoil"
lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
defaultValueLiteral="1.0 W/(m*K)">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Thermal conductivity W/(m-K). Range: 0.2 to 1.5"/>
</eAnnotations>
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0.2"/>
<details key="max" value="1.5"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="densityOfDrySoil" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
defaultValueLiteral="1100 kg/m³">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Density in kg/m³. "/>
</eAnnotations>
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0.1"/>
<details key="max" value="10000"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="specificHeatOfDrySoil"
eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
defaultValueLiteral="1200 J/(kg*K)">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="in units of J/(kg-K). Range(300 to 2000)"/>
</eAnnotations>
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0.2"/>
<details key="max" value="2000"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="thermalAbsorptance" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
defaultValueLiteral="0.9">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="the fraction of incident long wavelength (>2.5 microns) radiation that is absorbed by the material. This parameter is used when calculating the long wavelength radiant exchange between various surfaces and affects the surface heat balances (both inside and outside as appropriate). For long wavelength radiant exchange, thermal emissivity and thermal emittance are equal to thermal absorptance. Range: 0 to 1"/>
</eAnnotations>
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0.0"/>
<details key="max" value="1.0"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="solarAbsorptance" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
defaultValueLiteral="0.7">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="the fraction of incident solar radiation that is absorbed by the material.&#xA;Solar radiation (0.3 to 2.537 microns) includes the visible spectrum as well as infrared and ultraviolet wavelengths. This parameter is used when calculating the amount of incident solar radiation absorbed by various surfaces and affects the surface heat balances (both inside and outside as appropriate). If solar reflectance (or reflectivity) data is available, then absorptance is equal to 1.0 minus reflectance (for opaque materials).&#xA;Range: 0 to 1"/>
</eAnnotations>
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0.0"/>
<details key="max" value="1.0"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="visibleAbsorptance" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
defaultValueLiteral="0.75">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="The visible absorptance field in the Material input syntax represents the fraction of incident visible wavelength radiation that is absorbed by the material.&#xA;Visible wavelength radiation (0.37 to 0.78 microns weighted by photopic response) is slightly different than solar radiation in that the visible band of wavelengths is much more narrow while solar radiation includes the visible spectrum as well as infrared and ultraviolet wavelengths.&#xA;This parameter is used when calculating the amount of incident visible radiation absorbed by various surfaces and affects the surface heat balances (both inside and outside as appropriate) as well as the daylighting calculations. If visible reflectance (or reflectivity) data is available, then absorptance is equal to 1.0 minus reflectance (for opaque materials).&#xA;Range: 0.5 to 1.0"/>
</eAnnotations>
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0.5"/>
<details key="max" value="1.0"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="saturationVolumetricMoistureContent"
eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
defaultValueLiteral="0.0">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="input of the saturation moisture content of the soil layer. Range: 0.1 to 0.5"/>
</eAnnotations>
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0.1"/>
<details key="max" value="0.5"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="residualVolumetricMoistureContent"
eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
defaultValueLiteral="0.05">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Input of the residual moisture content of the soil layer. Range: 0.01 to 0.1"/>
</eAnnotations>
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0.01"/>
<details key="max" value="0.1"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="initialVolumetricMoistureContent"
eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
defaultValueLiteral="0.1">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Range: 0.05 to 0.5"/>
</eAnnotations>
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0.05"/>
<details key="max" value="0.5"/>
</eAnnotations>
</eStructuralFeatures>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="Plant">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="name" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="height" lowerBound="1"
eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
defaultValueLiteral="0.1 m">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Maximum height of plants. Range: 0.005 to 1 m"/>
</eAnnotations>
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0.005"/>
<details key="max" value="1.0"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="leafAreaIndex" lowerBound="1"
eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
defaultValueLiteral="2.5">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Leaf area per unit area of soil surface. Range: 0.001 to 5.0 m²/m²"/>
</eAnnotations>
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0.001"/>
<details key="max" value="5.0"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="leafReflectivity" lowerBound="1"
eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
defaultValueLiteral="0.1">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Represents the fraction of incident solar radiation that is reflected by the individual leaf surfaces (albedo).&#xA;Range: 0.05 to 0.5"/>
</eAnnotations>
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0.05"/>
<details key="max" value="0.5"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="leafEmissivity" lowerBound="1"
eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
defaultValueLiteral="0.9">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Ratio of thermal radiation emitted from leaf surfaces to that emitted by an ideal black body at the same temperature.&#xA;This parameter is used when calculating the long wavelength radiant exchange at the leaf surfaces.&#xA;Range: 0.8 to 1"/>
</eAnnotations>
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0.8"/>
<details key="max" value="1.0"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="minimalStomatalResistance"
lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
defaultValueLiteral="100.0 s/m">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Resistance of the plants to moisture transport.&#xA;Plants with low values of stomatal resistance will result in higher evapotranspiration rates than plants with high resistance.&#xA;Range: 50 to 300 m/s"/>
</eAnnotations>
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="50.0"/>
<details key="max" value="300.0"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EReference" name="growsOn" lowerBound="1"
upperBound="-1" eType="#//Soil"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="co2Sequestration" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
defaultValueLiteral="kgCO₂eq"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="SupportEnvelope">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="roughness" eType="#//Roughness"
defaultValueLiteral="MediumRough"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="solarAbsorptance" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EDouble"
defaultValueLiteral="0.0"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="conductivity" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EDouble"
defaultValueLiteral="0.0"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="visibleAbsorptance" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EDouble"
defaultValueLiteral="0.0"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="specificHeat" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EDouble"
defaultValueLiteral="0.0"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="density" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EDouble"
defaultValueLiteral="0.0"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="thermalAbsorptance" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EDouble"
defaultValueLiteral="0.0"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="GreeneryCatalog">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="source" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="plantCategories" lowerBound="1"
upperBound="-1" eType="#//PlantCategory" containment="true"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="vegetationCategories" lowerBound="1"
upperBound="-1" eType="#//VegetationCategory" containment="true"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="soils" upperBound="-1"
eType="#//Soil" containment="true"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="PlantCategory">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Excluding (that is non-overlapping) categories like Trees, Hedeges, Grasses that help users finding a specific biol. plant species."/>
</eAnnotations>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="plants" upperBound="-1"
eType="#//Plant" containment="true"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="IrrigationSchedule">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="Vegetation">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Plant life or total plant cover (as of an area)"/>
</eAnnotations>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="name" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="thicknessOfSoil" lowerBound="1"
eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
defaultValueLiteral="20 cm">
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0"/>
<details key="max" value="1000"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EReference" name="soil" lowerBound="1" eType="#//Soil"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="plants" lowerBound="1"
upperBound="-1" eType="#//PlantPercentage" containment="true"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="management" lowerBound="1"
eType="#//Management" defaultValueLiteral="NA"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="airGap" lowerBound="1"
eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
defaultValueLiteral="0.0 cm"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="VegetationCategory">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Excluding (that is non-overlapping) categories to help users finding a specific vegetation template."/>
</eAnnotations>
<eStructuralFeatures xsi:type="ecore:EReference" name="vegetationTemplates" upperBound="-1"
eType="#//Vegetation" containment="true"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EEnum" name="Management">
<eLiterals name="Intensive"/>
<eLiterals name="Extensive" value="1"/>
<eLiterals name="SemiIntensive" value="2"/>
<eLiterals name="NA" value="3"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="PlantPercentage">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="percentage" lowerBound="1"
eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
defaultValueLiteral="100">
<eAnnotations source="http://www.hft-stuttgart.de/UomQuantities">
<details key="min" value="0"/>
<details key="max" value="100"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EReference" name="plant" lowerBound="1" eType="#//Plant"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EEnum" name="Roughness">
<eLiterals name="VeryRough"/>
<eLiterals name="Rough" value="1"/>
<eLiterals name="MediumRough" value="2"/>
<eLiterals name="MediumSmooth" value="3"/>
<eLiterals name="Smooth" value="4"/>
<eLiterals name="VerySmooth" value="5"/>
</eClassifiers>
</ecore:EPackage>

View File

@ -0,0 +1,115 @@
"""
Greenery catalog
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
"""
from pyecore.resources import ResourceSet, URI
from catalogs.greenery.ecore_greenery.greenerycatalog import GreeneryCatalog as gc
from catalogs.catalog import Catalog
from pathlib import Path
from catalogs.data_model.greenery.vegetation import Vegetation as libs_vegetation
from catalogs.data_model.greenery.plant import Plant as libs_plant
from catalogs.data_model.greenery.soil import Soil as libs_soil
from catalogs.data_model.greenery.plant_percentage import PlantPercentage as libs_pp
from catalogs.data_model.greenery.greenery_content import GreeneryContent
class GreeneryCatalog(Catalog):
def __init__(self, path):
base_path = Path(Path(__file__).parent / 'ecore_greenery' / 'greenerycatalog_no_quantities.ecore')
resource_set = ResourceSet()
data_model = resource_set.get_resource(URI(str(base_path)))
data_model_root = data_model.contents[0]
resource_set.metamodel_registry[data_model_root.nsURI] = data_model_root
resource = resource_set.get_resource(URI(str(path)))
catalog_data: gc = resource.contents[0]
plants = []
for plant_category in catalog_data.plantCategories:
name = plant_category.name
for plant in plant_category.plants:
plants.append(libs_plant(name, plant))
vegetations = []
for vegetation_category in catalog_data.vegetationCategories:
name = vegetation_category.name
for vegetation in vegetation_category.vegetationTemplates:
plant_percentages = []
for plant_percentage in vegetation.plants:
plant_category = "Unknown"
for plant in plants:
if plant.name == plant_percentage.plant.name:
plant_category = plant.category
break
plant_percentages.append(libs_pp(plant_percentage.percentage,plant_category, plant_percentage.plant))
vegetations.append(libs_vegetation(name, vegetation, plant_percentages))
plants = []
for plant_category in catalog_data.plantCategories:
name = plant_category.name
for plant in plant_category.plants:
plants.append(libs_plant(name, plant))
soils = []
for soil in catalog_data.soils:
soils.append(libs_soil(soil))
self._data = GreeneryContent(vegetations, plants, soils)
def names(self, category=None):
"""
Get the catalog elements names
:parm: optional category filter
"""
if category is None:
_names = {'vegetations': [], 'plants': [], 'soils': []}
for vegetation in self._data.vegetations:
_names['vegetations'].append(vegetation.name)
for plant in self._data.plants:
_names['plants'].append(plant.name)
for soil in self._data.soils:
_names['soils'].append(soil.name)
else:
_names = {category: []}
if category.lower() == 'vegetations':
for vegetation in self._data.vegetations:
_names[category].append(vegetation.name)
elif category.lower() == 'plants':
for plant in self._data.plants:
_names[category].append(plant.name)
elif category.lower() == 'soils':
for soil in self._data.soils:
_names[category].append(soil.name)
else:
raise ValueError(f'Unknown category [{category}]')
return _names
def get_entry(self, name):
"""
Get one complete entry from the greenery catalog
"""
for entry in self._data.vegetations:
if entry.name.lower() == name.lower():
return entry
for entry in self._data.plants:
if entry.name.lower() == name.lower():
return entry
for entry in self._data.soils:
if entry.name.lower() == name.lower():
return entry
raise IndexError(f"{name} doesn't exists in the catalog")
def entries(self, category=None):
if category is None:
return self._data
else:
if category.lower() == 'vegetations':
return self._data.vegetations
elif category.lower() == 'plants':
return self._data.plants
elif category.lower() == 'soils':
return self._data.soils
else:
raise ValueError(f'Unknown category [{category}]')

View File

@ -0,0 +1,43 @@
"""
Greenery catalog publish the greenery information
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
"""
from pathlib import Path
from catalogs.greenery.greenery_catalog import GreeneryCatalog
class GreeneryCatalogFactory:
"""
GeometryFactory class
"""
def __init__(self, file_type, base_path=None):
if base_path is None:
base_path = Path(Path(__file__).parent.parent / 'data/greenery')
self._file_type = '_' + file_type.lower()
self._path = base_path
@property
def _nrel(self) -> GreeneryCatalog:
"""
Return a greenery catalog using ecore as datasource
:return: GreeneryCatalog
"""
return GreeneryCatalog((self._path / 'ecore_greenery_catalog.xml').resolve())
@property
def catalog(self) -> GreeneryCatalog:
"""
Enrich the city given to the class using the class given handler
:return: City
"""
return getattr(self, self._file_type, lambda: None)
@property
def catalog_debug(self) -> GreeneryCatalog:
"""
Enrich the city given to the class using the class given handler
:return: City
"""
return GreeneryCatalog((self._path / 'ecore_greenery_catalog.xml').resolve())

View File

@ -15,12 +15,13 @@ class Plane:
Plane class Plane class
""" """
def __init__(self, origin=None, normal=None): def __init__(self, origin, normal):
# todo: other options to define the plane: # todo: other options to define the plane:
# by two lines # by two lines
# by three points # by three points
self._origin = origin self._origin = origin
self._normal = normal self._normal = normal
self._equation = None
self._opposite_normal = None self._opposite_normal = None
@property @property
@ -29,8 +30,6 @@ class Plane:
Get plane origin point Get plane origin point
:return: Point :return: Point
""" """
if self._origin is None:
raise NotImplementedError
return self._origin return self._origin
@property @property
@ -39,10 +38,36 @@ class Plane:
Get plane normal [x, y, z] Get plane normal [x, y, z]
:return: np.ndarray :return: np.ndarray
""" """
if self._normal is None:
raise NotImplementedError
return self._normal return self._normal
@property
def equation(self) -> (float, float, float, float):
"""
Get the plane equation components Ax + By + Cz + D = 0
:return: (A, B, C, D)
"""
if self._equation is None:
a = self.normal[0]
b = self.normal[1]
c = self.normal[2]
d = ((-1 * self.origin.coordinates[0]) * self.normal[0])
d += ((-1 * self.origin.coordinates[1]) * self.normal[1])
d += ((-1 * self.origin.coordinates[2]) * self.normal[2])
self._equation = (a, b, c, d)
return self._equation
def distance(self, point):
"""
Distance between the given point and the plane
:return: float
"""
p = point
e = self.equation
denominator = np.abs((p[0] * e[0]) + (p[1] * e[1]) + (p[2] * e[2]) + e[3])
numerator = np.sqrt((e[0]**2) + (e[1]**2) + (e[2]**2))
return denominator/numerator
@property @property
def opposite_normal(self): def opposite_normal(self):
""" """

View File

@ -11,8 +11,10 @@ from typing import List
import numpy as np import numpy as np
from trimesh import Trimesh from trimesh import Trimesh
import trimesh.intersections import trimesh.intersections
from city_model_structure.attributes.point import Point
from city_model_structure.attributes.plane import Plane
from city_model_structure.attributes.point import Point
import helpers.constants as cte
class Polygon: class Polygon:
""" """
@ -20,7 +22,6 @@ class Polygon:
""" """
def __init__(self, coordinates): def __init__(self, coordinates):
self._area = None self._area = None
self._points = None self._points = None
self._points_list = None self._points_list = None
@ -31,6 +32,7 @@ class Polygon:
self._triangles = None self._triangles = None
self._vertices = None self._vertices = None
self._faces = None self._faces = None
self._plane = None
@property @property
def points(self) -> List[Point]: def points(self) -> List[Point]:
@ -44,6 +46,16 @@ class Polygon:
self._points.append(Point(coordinate)) self._points.append(Point(coordinate))
return self._points return self._points
@property
def plane(self) -> Plane:
"""
Get the polygon plane
:return: Plane
"""
if self._plane is None:
self._plane = Plane(normal=self.normal, origin=self.points[0])
return self._plane
@property @property
def coordinates(self) -> List[np.ndarray]: def coordinates(self) -> List[np.ndarray]:
""" """
@ -52,6 +64,20 @@ class Polygon:
""" """
return self._coordinates return self._coordinates
@staticmethod
def _module(vector):
x2 = vector[0] ** 2
y2 = vector[1] ** 2
z2 = vector[2] ** 2
return math.sqrt(x2+y2+z2)
@staticmethod
def _scalar_product(vector_0, vector_1):
x = vector_0[0] * vector_1[0]
y = vector_0[1] * vector_1[1]
z = vector_0[2] * vector_1[2]
return x+y+z
@property @property
def points_list(self) -> np.ndarray: def points_list(self) -> np.ndarray:
""" """
@ -223,7 +249,7 @@ class Polygon:
points_list = self.points_list points_list = self.points_list
normal = self.normal normal = self.normal
if np.linalg.norm(normal) == 0: if np.linalg.norm(normal) == 0:
sys.stderr.write('Not able to triangulate polygon\n') sys.stderr.write(f'Not able to triangulate polygon [normal length is 0]')
return [self] return [self]
# are points concave or convex? # are points concave or convex?
total_points_list, concave_points, convex_points = self._starting_lists(points_list, normal) total_points_list, concave_points, convex_points = self._starting_lists(points_list, normal)
@ -271,10 +297,10 @@ class Polygon:
continue continue
break break
if len(total_points_list) <= 3 and len(convex_points) > 0: if len(total_points_list) <= 3 and len(convex_points) > 0:
sys.stderr.write('Not able to triangulate polygon\n') sys.stderr.write('Not able to triangulate polygon [convex surface]\n')
return [self] return [self]
if j >= 100: if j >= 100:
sys.stderr.write('Not able to triangulate polygon\n') sys.stderr.write('Not able to triangulate polygon [infinite loop]\n')
return [self] return [self]
last_ear = self._triangle(points_list, total_points_list, concave_points[1]) last_ear = self._triangle(points_list, total_points_list, concave_points[1])
ears.append(last_ear) ears.append(last_ear)

View File

@ -114,7 +114,7 @@ class Polyhedron:
if self._trimesh is None: if self._trimesh is None:
for face in self.faces: for face in self.faces:
if len(face) != 3: if len(face) != 3:
sys.stderr.write('Not able to generate trimesh\n') sys.stderr.write(f'Not able to generate trimesh the face has {len(face)} vertices\n')
return None return None
self._trimesh = Trimesh(vertices=self.vertices, faces=self.faces) self._trimesh = Trimesh(vertices=self.vertices, faces=self.faces)
return self._trimesh return self._trimesh

View File

@ -14,14 +14,14 @@ from city_model_structure.building_demand.usage_zone import UsageZone
from city_model_structure.building_demand.storey import Storey from city_model_structure.building_demand.storey import Storey
from city_model_structure.city_object import CityObject from city_model_structure.city_object import CityObject
from city_model_structure.building_demand.household import Household from city_model_structure.building_demand.household import Household
from city_model_structure.attributes.polyhedron import Polyhedron
class Building(CityObject): class Building(CityObject):
""" """
Building(CityObject) class Building(CityObject) class
""" """
def __init__(self, name, lod, surfaces, year_of_construction, function, def __init__(self, name, lod, surfaces, year_of_construction, function, city_lower_corner, terrains=None):
city_lower_corner, terrains=None):
super().__init__(name, lod, surfaces, city_lower_corner) super().__init__(name, lod, surfaces, city_lower_corner)
self._households = None self._households = None
self._basement_heated = None self._basement_heated = None
@ -34,6 +34,7 @@ class Building(CityObject):
self._floor_area = None self._floor_area = None
self._roof_type = None self._roof_type = None
self._storeys = None self._storeys = None
self._geometrical_zones = None
self._thermal_zones = [] self._thermal_zones = []
self._thermal_boundaries = None self._thermal_boundaries = None
self._usage_zones = [] self._usage_zones = []
@ -60,6 +61,15 @@ class Building(CityObject):
else: else:
self._internal_walls.append(surface) self._internal_walls.append(surface)
@property
def geometrical_zones(self) -> List[Polyhedron]:
if self._geometrical_zones is None:
polygons = []
for surface in self.surfaces:
polygons.append(surface.perimeter_polygon)
self._geometrical_zones = [Polyhedron(polygons)]
return self._geometrical_zones
@property @property
def grounds(self) -> List[Surface]: def grounds(self) -> List[Surface]:
""" """
@ -256,10 +266,6 @@ class Building(CityObject):
if value is not None: if value is not None:
self._storeys_above_ground = int(value) self._storeys_above_ground = int(value)
@staticmethod
def _tuple_to_point(xy_tuple):
return [xy_tuple[0], xy_tuple[1], 0.0]
@property @property
def heating(self) -> dict: def heating(self) -> dict:
""" """

View File

@ -2,9 +2,10 @@
Material module Material module
SPDX - License - Identifier: LGPL - 3.0 - or -later SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
Contributor Atiya atiya.atiya@mail.concordia.ca
Contributor Mohammad Reza mohammad.seyedabadi@mail.concordia.ca
""" """
import ast
from typing import Union from typing import Union
@ -13,15 +14,34 @@ class Material:
Material class Material class
""" """
def __init__(self): def __init__(self):
self._id = None
self._name = None self._name = None
self._conductivity = None self._conductivity = None
self._specific_heat = None self._specific_heat = None
self._density = None self._density = None
self._density_unit = None
self._solar_absorptance = None self._solar_absorptance = None
self._thermal_absorptance = None self._thermal_absorptance = None
self._visible_absorptance = None self._visible_absorptance = None
self._no_mass = False self._no_mass = False
self._thermal_resistance = None self._thermal_resistance = None
self._lca_id = None
@property
def id(self):
"""
Get material id
:return: int
"""
return self._id
@id.setter
def id(self, value):
"""
Set material id
:param value: int
"""
self._id = int(value)
@property @property
def name(self): def name(self):
@ -84,12 +104,29 @@ class Material:
@density.setter @density.setter
def density(self, value): def density(self, value):
""" """
Set material density in kg/m3 Set material density
:param value: float :param value: float
""" """
if value is not None: if value is not None:
self._density = float(value) self._density = float(value)
@property
def density_unit(self) -> Union[None, str]:
"""
Get material density unit
:return: None or string
"""
return self._density_unit
@density_unit.setter
def density_unit(self, value):
"""
Set material density unit
:param value: string
"""
if value is not None:
self._density_unit = str(value)
@property @property
def solar_absorptance(self) -> Union[None, float]: def solar_absorptance(self) -> Union[None, float]:
""" """
@ -174,3 +211,12 @@ class Material:
""" """
if value is not None: if value is not None:
self._thermal_resistance = float(value) self._thermal_resistance = float(value)
@property
def lca_id(self):
return self._lca_id
@lca_id.setter
def lca_id(self, value):
self._lca_id = value

View File

@ -8,7 +8,7 @@ contributors Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
from __future__ import annotations from __future__ import annotations
import uuid import uuid
import numpy as np import numpy as np
from typing import Union from typing import List, Union
from city_model_structure.attributes.polygon import Polygon from city_model_structure.attributes.polygon import Polygon
from city_model_structure.attributes.plane import Plane from city_model_structure.attributes.plane import Plane
from city_model_structure.attributes.point import Point from city_model_structure.attributes.point import Point
@ -233,8 +233,16 @@ class Surface:
""" """
return self._solid_polygon return self._solid_polygon
@solid_polygon.setter
def solid_polygon(self, value):
"""
Set the solid surface
:return: Polygon
"""
self._solid_polygon = value
@property @property
def holes_polygons(self) -> Union[Polygon, None]: def holes_polygons(self) -> Union[List[Polygon], None]:
""" """
Get hole surfaces, a list of hole polygons found in the surface Get hole surfaces, a list of hole polygons found in the surface
:return: None, [] or [Polygon] :return: None, [] or [Polygon]
@ -244,6 +252,14 @@ class Surface:
""" """
return self._holes_polygons return self._holes_polygons
@holes_polygons.setter
def holes_polygons(self, value):
"""
Set the hole surfaces
:param value: [Polygon]
"""
self._holes_polygons = value
@property @property
def pv_system_installed(self) -> PvSystem: def pv_system_installed(self) -> PvSystem:
""" """

View File

@ -2,6 +2,7 @@
City module City module
SPDX - License - Identifier: LGPL - 3.0 - or -later SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
Contributor Peter Yefi peteryefi@gmail.com
""" """
from __future__ import annotations from __future__ import annotations
import sys import sys
@ -18,11 +19,10 @@ from city_model_structure.city_objects_cluster import CityObjectsCluster
from city_model_structure.buildings_cluster import BuildingsCluster from city_model_structure.buildings_cluster import BuildingsCluster
from city_model_structure.parts_consisting_building import PartsConsistingBuilding from city_model_structure.parts_consisting_building import PartsConsistingBuilding
from city_model_structure.subway_entrance import SubwayEntrance from city_model_structure.subway_entrance import SubwayEntrance
from city_model_structure.fuel import Fuel
from helpers.geometry_helper import GeometryHelper from helpers.geometry_helper import GeometryHelper
from helpers.location import Location from helpers.location import Location
from city_model_structure.energy_system import EnergySystem from city_model_structure.energy_system import EnergySystem
from city_model_structure.lca_material import LcaMaterial
class City: class City:
""" """
@ -51,6 +51,9 @@ class City:
self._city_objects = None self._city_objects = None
self._energy_systems = None self._energy_systems = None
self._fuels = None self._fuels = None
self._machines = None
self._stations = []
self._lca_materials = None
@property @property
def fuels(self) -> [Fuel]: def fuels(self) -> [Fuel]:
@ -60,6 +63,13 @@ class City:
def fuels(self, value): def fuels(self, value):
self._fuels = value self._fuels = value
@property
def machines(self) -> [Machine]:
return self._machines
@machines.setter
def machines(self, value):
self._machines = value
def _get_location(self) -> Location: def _get_location(self) -> Location:
if self._location is None: if self._location is None:
@ -186,7 +196,7 @@ class City:
:return: None or CityObject :return: None or CityObject
""" """
for city_object in self.buildings: for city_object in self.buildings:
if city_object.name == name: if str(city_object.name) == str(name):
return city_object return city_object
return None return None
@ -357,6 +367,14 @@ class City:
""" """
return self._energy_systems return self._energy_systems
@property
def stations(self) -> [Station]:
"""
Get the sensors stations belonging to the city
:return: [Station]
"""
return self._stations
@property @property
def city_objects_clusters(self) -> Union[List[CityObjectsCluster], None]: def city_objects_clusters(self) -> Union[List[CityObjectsCluster], None]:
""" """
@ -387,3 +405,29 @@ class City:
self._parts_consisting_buildings.append(new_city_objects_cluster) self._parts_consisting_buildings.append(new_city_objects_cluster)
else: else:
raise NotImplementedError raise NotImplementedError
@property
def lca_materials(self) -> Union[List[LcaMaterial], None]:
"""
Get life cycle materials for the city
:return: [LcaMaterial] or
"""
return self._lca_materials
@lca_materials.setter
def lca_materials(self, value):
"""
Set life cycle materials for the city
"""
self._lca_materials = value
def lca_material(self, lca_id) -> LcaMaterial:
"""
Get the lca materiol matching the given Id
:return: LcaMaterial or None
"""
for lca_material in self.lca_materials:
if str(lca_material.id) == str(lca_id):
return lca_material
return None

View File

@ -1,7 +1,8 @@
""" """
ConstructionFactory (before PhysicsFactory) retrieve the specific construction module for the given region ConstructionFactory (before PhysicsFactory) retrieve the specific construction module for the given region
SPDX - License - Identifier: LGPL - 3.0 - or -later SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Atiya Copyright © 2020 Project Author Atiya atiya.atiya@mail.concordia.ca
Contributor Mohammad Reza mohammad.seyedabadi@mail.concordia.ca
""" """
class Fuel: class Fuel:
@ -12,30 +13,34 @@ class Fuel:
self._unit = unit self._unit = unit
@property @property
def id(self): def id(self) -> int:
""" """
Get fuel id Get fuel id
:return: int
""" """
return self._fuel_id return self._fuel_id
@property @property
def name(self): def name(self) -> str:
""" """
Get fuel name Get fuel name
:return: str
""" """
return self._name return self._name
@property @property
def carbon_emission_factor(self): def carbon_emission_factor(self) -> float:
""" """
Get fuel carbon emission factor Get fuel carbon emission factor
:return: float
""" """
return self._carbon_emission_factor return self._carbon_emission_factor
@property @property
def unit(self): def unit(self) -> str:
""" """
Get fuel units Get fuel units
:return: str
""" """
return self._unit return self._unit

View File

@ -1,45 +0,0 @@
"""
Energy Sensor module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
"""
import pandas as pd
from city_model_structure.iot.sensor import Sensor
class ConcordiaEnergySensor(Sensor):
"""
Concordia energy sensor.
"""
def __init__(self, name):
super().__init__()
self._name = name
self._interval = 5
self._interval_units = 'minutes'
self._type = 'ConcordiaEnergySensor'
self._units = 'kW'
self._measures = pd.DataFrame(columns=["Date time", "Energy consumption"])
@property
def measures(self) -> pd.DataFrame:
"""
Get sensor measures [yyyy-mm-dd, hh:mm:ss kW]
:return: DataFrame["Date time", "Energy consumption"]
"""
return self._measures
@measures.deleter
def measures(self):
"""
Delete sensor measures
"""
self._measures.drop = None
def add_period(self, measures):
"""
Add or update a period measures to the dataframe
"""
measures = self._measures.append(measures, ignore_index=True)
self._measures = measures.drop_duplicates('Date time', keep='last')

View File

@ -1,45 +0,0 @@
"""
Gas Flow Sensor module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
import pandas as pd
from city_model_structure.iot.sensor import Sensor
class ConcordiaGasFlowSensor(Sensor):
"""
Concordia gas flow sensor.
"""
def __init__(self, name):
super().__init__()
self._name = name
self._interval = 5
self._interval_units = 'minutes'
self._type = 'ConcordiaGasFlowSensor'
self._units = 'm3'
self._measures = pd.DataFrame(columns=["Date time", "Gas Flow Cumulative Monthly"])
@property
def measures(self) -> pd.DataFrame:
"""
Get sensor measures [yyyy-mm-dd, hh:mm:ss m3]
:return: DataFrame["Date time", "Gas Flow Cumulative Monthly"]
"""
return self._measures
@measures.deleter
def measures(self):
"""
Delete sensor measures
"""
self._measures.drop = None
def add_period(self, measures):
"""
Add or update a period measures to the dataframe
"""
measures = self._measures.append(measures, ignore_index=True)
self._measures = measures.drop_duplicates('Date time', keep='last')

View File

@ -1,45 +0,0 @@
"""
Temperature Sensor module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
import pandas as pd
from city_model_structure.iot.sensor import Sensor
class ConcordiaTemperatureSensor(Sensor):
"""
Concordia temperature sensor.
"""
def __init__(self, name):
super().__init__()
self._name = name
self._interval = 5
self._interval_units = 'minutes'
self._type = 'ConcordiaTemperatureSensor'
self._units = 'Celsius'
self._measures = pd.DataFrame(columns=["Date time", "Temperature"])
@property
def measures(self) -> pd.DataFrame:
"""
Get sensor measures [yyyy-mm-dd, hh:mm:ss Celsius]
:return: DataFrame["Date time", "Temperature"]
"""
return self._measures
@measures.deleter
def measures(self):
"""
Delete sensor measures
"""
self._measures.drop = None
def add_period(self, measures):
"""
Add or update a period measures to the dataframe
"""
measures = self._measures.append(measures, ignore_index=True)
self._measures = measures.drop_duplicates('Date time', keep='last')

View File

@ -1,76 +1,73 @@
""" """
Sensor module Sensor module
SPDX - License - Identifier: LGPL - 3.0 - or -later SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca Copyright © 2022 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
""" """
import uuid
from helpers.location import Location from city_model_structure.iot.sensor_measure import SensorMeasure
from city_model_structure.iot.sensor_type import SensorType
class Sensor: class Sensor:
""" """
Sensor abstract class Sensor abstract class
""" """
def __init__(self): def __init__(self, sensor_id=None, model=None, sensor_type=None, indoor=False, board=None):
self._name = None self._id = sensor_id
self._type = None self._model = model
self._units = None self._type = sensor_type
self._location = None self._indoor = indoor
self._board = board
self._measures = []
@property @property
def name(self): def id(self):
""" """
Get sensor name Get the sensor id a random uuid will be assigned if no ID was provided to the constructor
:return: str :return: Id
""" """
if self._name is None: if self._id is None:
raise ValueError('Undefined sensor name') self._id = uuid.uuid4()
return self._name return self._id
@name.setter
def name(self, value):
"""
Set sensor name
:param value: str
"""
if value is not None:
self._name = str(value)
@property @property
def type(self): def type(self) -> SensorType:
""" """
Get sensor type Get sensor type
:return: str :return: SensorTypeEnum or Error
""" """
if self._type is None:
raise ValueError('Unknown sensor type')
return self._type return self._type
@property @property
def units(self): def model(self):
""" """
Get sensor units Get sensor model is any
:return: str :return: str or None
""" """
return self._units return self._model
@property @property
def location(self) -> Location: def board(self):
""" """
Get sensor location Get sensor board if any
:return: Location :return: str or None
""" """
return self._location return self._model
@location.setter
def location(self, value):
"""
Set sensor location
:param value: Location
"""
self._location = value
@property @property
def measures(self): def indoor(self):
"""
Get is the sensor it's located indoor or outdoor
:return: boolean
"""
return self._indoor
@property
def measures(self) -> [SensorMeasure]:
""" """
Raises not implemented error Raises not implemented error
""" """
raise NotImplementedError return self._measures

View File

@ -0,0 +1,40 @@
"""
Sensor measure module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
"""
class SensorMeasure:
def __init__(self, latitude, longitude, utc_timestamp, value):
self._latitude = latitude
self._longitude = longitude
self._utc_timestamp = utc_timestamp
self._value = value
@property
def latitude(self):
"""
Get measure latitude
"""
return self._latitude
@property
def longitude(self):
"""
Get measure longitude
"""
return self._longitude
@property
def utc_timestamp(self):
"""
Get measure timestamp in utc
"""
return self._utc_timestamp
@property
def value(self):
"""
Get sensor measure value
"""
return self._value

View File

@ -0,0 +1,20 @@
"""
Sensor type module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
"""
from enum import Enum
class SensorType(Enum):
HUMIDITY = 0
TEMPERATURE = 1
CO2 = 2
NOISE = 3
PRESSURE = 4
DIRECT_RADIATION = 5
DIFFUSE_RADIATION = 6
GLOBAL_RADIATION = 7
AIR_QUALITY = 8
GAS_FLOW = 9
ENERGY = 10

View File

@ -0,0 +1,41 @@
"""
Station
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
"""
import uuid
from city_model_structure.iot.sensor import Sensor
class Station:
def __init__(self, station_id=None, _mobile=False):
self._id = station_id
self._mobile = _mobile
self._sensors = []
@property
def id(self):
"""
Get the station id a random uuid will be assigned if no ID was provided to the constructor
:return: Id
"""
if self._id is None:
self._id = uuid.uuid4()
return self._id
@property
def _mobile(self):
"""
Get if the station is mobile or not
:return: bool
"""
return self._mobile
@property
def sensors(self) -> [Sensor]:
"""
Get the sensors belonging to the station
:return: [Sensor]
"""
return self._sensors

View File

@ -0,0 +1,242 @@
"""
Material module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Atiya atiya.atiya@mail.concordia.ca
Contributor Mohammad Reza mohammad.seyedabadi@mail.concordia.ca
"""
from typing import Union
class LcaMaterial:
def __init__(self):
self._id = None
self._type = None
self._name = None
self._density = None
self._density_unit = None
self._embodied_carbon = None
self._embodied_carbon_unit = None
self._recycling_ratio = None
self._company_recycling_ratio = None
self._onsite_recycling_ratio = None
self._landfilling_ratio = None
self._cost = None
self._cost_unit = None
@property
def id(self):
"""
Get material id
:return: int
"""
return self._id
@id.setter
def id(self, value):
"""
Set material id
:param value: int
"""
self._id = int(value)
@property
def type(self):
"""
Get material type
:return: str
"""
return self._type
@type.setter
def type(self, value):
"""
Set material type
:param value: string
"""
self._type = str(value)
@property
def name(self):
"""
Get material name
:return: str
"""
return self._name
@name.setter
def name(self, value):
"""
Set material name
:param value: string
"""
self._name = str(value)
@property
def density(self) -> Union[None, float]:
"""
Get material density in kg/m3
:return: None or float
"""
return self._density
@density.setter
def density(self, value):
"""
Set material density
:param value: float
"""
if value is not None:
self._density = float(value)
@property
def density_unit(self) -> Union[None, str]:
"""
Get material density unit
:return: None or string
"""
return self._density_unit
@density_unit.setter
def density_unit(self, value):
"""
Set material density unit
:param value: string
"""
if value is not None:
self._density_unit = str(value)
@property
def embodied_carbon(self) -> Union[None, float]:
"""
Get material embodied carbon
:return: None or float
"""
return self._embodied_carbon
@embodied_carbon.setter
def embodied_carbon(self, value):
"""
Set material embodied carbon
:param value: float
"""
if value is not None:
self._embodied_carbon = float(value)
@property
def embodied_carbon_unit(self) -> Union[None, str]:
"""
Get material embodied carbon unit
:return: None or string
"""
return self._embodied_carbon
@embodied_carbon_unit.setter
def embodied_carbon_unit(self, value):
"""
Set material embodied carbon unit
:param value: string
"""
if value is not None:
self._embodied_carbon_unit = str(value)
@property
def recycling_ratio(self) -> Union[None, float]:
"""
Get material recycling ratio
:return: None or float
"""
return self._recycling_ratio
@recycling_ratio.setter
def recycling_ratio(self, value):
"""
Set material recycling ratio
:param value: float
"""
if value is not None:
self._recycling_ratio = float(value)
@property
def onsite_recycling_ratio(self) -> Union[None, float]:
"""
Get material onsite recycling ratio
:return: None or float
"""
return self._onsite_recycling_ratio
@onsite_recycling_ratio.setter
def onsite_recycling_ratio(self, value):
"""
Set material onsite recycling ratio
:param value: float
"""
if value is not None:
self._onsite_recycling_ratio = float(value)
@property
def company_recycling_ratio(self) -> Union[None, float]:
"""
Get material company recycling ratio
:return: None or float
"""
return self._company_recycling_ratio
@company_recycling_ratio.setter
def company_recycling_ratio(self, value):
"""
Set material company recycling ratio
:param value: float
"""
if value is not None:
self._company_recycling_ratio = float(value)
@property
def landfilling_ratio(self) -> Union[None, float]:
"""
Get material landfilling ratio
:return: None or float
"""
return self._landfilling_ratio
@landfilling_ratio.setter
def landfilling_ratio(self, value):
"""
Set material landfilling ratio
:param value: float
"""
if value is not None:
self._landfilling_ratio = float(value)
@property
def cost(self) -> Union[None, float]:
"""
Get material cost
:return: None or float
"""
return self._cost
@cost.setter
def cost(self, value):
"""
Set material cost
:param value: float
"""
if value is not None:
self._cost = float(value)
@property
def cost_unit(self) -> Union[None, str]:
"""
Get material cost unit
:return: None or string
"""
return self._cost_unit
@cost_unit.setter
def cost_unit(self, value):
"""
Set material cost unit
:param value: string
"""
if value is not None:
self._cost_unit = float(value)

View File

@ -1,7 +1,8 @@
""" """
LifeCycleAssessment retrieve the specific Life Cycle Assessment module for the given region LifeCycleAssessment retrieve the specific Life Cycle Assessment module for the given region
SPDX - License - Identifier: LGPL - 3.0 - or -later SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Atiya Copyright © 2020 Project Author Atiya atiya.atiya@mail.concordia.ca
Contributor Mohammad Reza mohammad.seyedabadi@mail.concordia.ca
""" """
class Machine: class Machine:
@ -21,58 +22,66 @@ class Machine:
self._carbon_emission_unit = carbon_emission_unit self._carbon_emission_unit = carbon_emission_unit
@property @property
def id(self): def id(self) -> int:
""" """
Get machine id Get machine id
:return: int
""" """
return self._machine_id return self._machine_id
@property @property
def name(self): def name(self) -> str:
""" """
Get machine name Get machine name
:return: str
""" """
return self._name return self._name
@property @property
def work_efficiency(self): def work_efficiency(self) -> float:
""" """
Get machine work efficiency Get machine work efficiency
:return: float
""" """
return self._work_efficiency return self._work_efficiency
@property @property
def work_efficiency_unit(self): def work_efficiency_unit(self) -> str:
""" """
Get machine work efficiency unit Get machine work efficiency unit
:return: str
""" """
return self._work_efficiency_unit return self._work_efficiency_unit
@property @property
def energy_consumption_rate(self): def energy_consumption_rate(self) -> float:
""" """
Get energy consumption rate Get energy consumption rate
:return: float
""" """
return self._energy_consumption_rate return self._energy_consumption_rate
@property @property
def energy_consumption_unit(self): def energy_consumption_unit(self) -> str:
""" """
Get energy consumption unit Get energy consumption unit
:return: str
""" """
return self._energy_consumption_unit return self._energy_consumption_unit
@property @property
def carbon_emission_factor(self): def carbon_emission_factor(self) -> float:
""" """
Get carbon emission factor Get carbon emission factor
:return: float
""" """
return self._carbon_emission_factor return self._carbon_emission_factor
@property @property
def carbon_emission_unit(self): def carbon_emission_unit(self) -> str:
""" """
Get carbon emission unit Get carbon emission unit
:return: str
""" """
return self._carbon_emission_unit return self._carbon_emission_unit

View File

@ -1,7 +1,8 @@
""" """
LifeCycleAssessment retrieve the specific Life Cycle Assessment module for the given region LifeCycleAssessment retrieve the specific Life Cycle Assessment module for the given region
SPDX - License - Identifier: LGPL - 3.0 - or -later SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Atiya Copyright © 2020 Project Author Atiya atiya.atiya@mail.concordia.ca
Contributor Mohammad Reza mohammad.seyedabadi@mail.concordia.ca
""" """
class Vehicle: class Vehicle:
@ -18,44 +19,50 @@ class Vehicle:
self._carbon_emission_factor_unit = carbon_emission_factor_unit self._carbon_emission_factor_unit = carbon_emission_factor_unit
@property @property
def id(self): def id(self) -> int:
""" """
Get vehicle id Get vehicle id
:return: int
""" """
return self._vehicle_id return self._vehicle_id
@property @property
def name(self): def name(self) -> str:
""" """
Get vehicle name Get vehicle name
:return: str
""" """
return self._name return self._name
@property @property
def fuel_consumption_rate(self): def fuel_consumption_rate(self) -> float:
""" """
Get vehicle fuel consumption rate Get vehicle fuel consumption rate
:return: float
""" """
return self._fuel_consumption_rate return self._fuel_consumption_rate
@property @property
def fuel_consumption_unit(self): def fuel_consumption_unit(self) -> str:
""" """
Get fuel consumption unit Get fuel consumption unit
:return: str
""" """
return self._fuel_consumption_unit return self._fuel_consumption_unit
@property @property
def carbon_emission_factor(self): def carbon_emission_factor(self) -> float:
""" """
Get vehicle carbon emission factor Get vehicle carbon emission factor
:return: float
""" """
return self._carbon_emission_factor return self._carbon_emission_factor
@property @property
def carbon_emission_unit(self): def carbon_emission_unit(self) -> str:
""" """
Get carbon emission units Get carbon emission units
:return: str
""" """
return self._carbon_emission_unit return self._carbon_emission_unit

View File

@ -39,7 +39,7 @@
</window> </window>
</windows> </windows>
<materials> <materials>
<material id="1" name="MAT-CC05 8 HW CONCRETE"> <material id="1" name="MAT-CC05 8 HW CONCRETE" lca_id="7">
<conductivity units="W/m K">1.311</conductivity> <conductivity units="W/m K">1.311</conductivity>
<density units="kg/m3">2240</density> <density units="kg/m3">2240</density>
<specific_heat units="J/kg K">836.8</specific_heat> <specific_heat units="J/kg K">836.8</specific_heat>
@ -47,14 +47,14 @@
<solar_absorptance units="-">0.7</solar_absorptance> <solar_absorptance units="-">0.7</solar_absorptance>
<visible_absorptance units="-">0.7</visible_absorptance> <visible_absorptance units="-">0.7</visible_absorptance>
</material> </material>
<material id="2" name="CP02 CARPET PAD"> <material id="2" name="CP02 CARPET PAD" lca_id="7">
<no_mass>true</no_mass> <no_mass>true</no_mass>
<thermal_resistance units="m2 K/W">0.21648</thermal_resistance> <thermal_resistance units="m2 K/W">0.21648</thermal_resistance>
<thermal_absorptance units="-">0.9</thermal_absorptance> <thermal_absorptance units="-">0.9</thermal_absorptance>
<solar_absorptance units="-">0.7</solar_absorptance> <solar_absorptance units="-">0.7</solar_absorptance>
<visible_absorptance units="-">0.8</visible_absorptance> <visible_absorptance units="-">0.8</visible_absorptance>
</material> </material>
<material id="3" name="Floor Insulation [4]"> <material id="3" name="Floor Insulation [4]" lca_id="7">
<conductivity units="W/m K">0.045</conductivity> <conductivity units="W/m K">0.045</conductivity>
<density units="kg/m3">265</density> <density units="kg/m3">265</density>
<specific_heat units="J/kg K">836.8</specific_heat> <specific_heat units="J/kg K">836.8</specific_heat>
@ -62,7 +62,7 @@
<solar_absorptance units="-">0.7</solar_absorptance> <solar_absorptance units="-">0.7</solar_absorptance>
<visible_absorptance units="-">0.7</visible_absorptance> <visible_absorptance units="-">0.7</visible_absorptance>
</material> </material>
<material id="4" name="1IN Stucco"> <material id="4" name="1IN Stucco" lca_id="7">
<conductivity units="W/m K">0.6918</conductivity> <conductivity units="W/m K">0.6918</conductivity>
<density units="kg/m3">1858</density> <density units="kg/m3">1858</density>
<specific_heat units="J/kg K">837</specific_heat> <specific_heat units="J/kg K">837</specific_heat>
@ -70,7 +70,7 @@
<solar_absorptance units="-">0.92</solar_absorptance> <solar_absorptance units="-">0.92</solar_absorptance>
<visible_absorptance units="-">0.92</visible_absorptance> <visible_absorptance units="-">0.92</visible_absorptance>
</material> </material>
<material id="5" name="8IN Concrete HW"> <material id="5" name="8IN Concrete HW" lca_id="7">
<conductivity units="W/m K">1.7296</conductivity> <conductivity units="W/m K">1.7296</conductivity>
<density units="kg/m3">2243</density> <density units="kg/m3">2243</density>
<specific_heat units="J/kg K">837</specific_heat> <specific_heat units="J/kg K">837</specific_heat>
@ -78,7 +78,7 @@
<solar_absorptance units="-">0.65</solar_absorptance> <solar_absorptance units="-">0.65</solar_absorptance>
<visible_absorptance units="-">0.65</visible_absorptance> <visible_absorptance units="-">0.65</visible_absorptance>
</material> </material>
<material id="6" name="Wall Insulation [37]"> <material id="6" name="Wall Insulation [37]" lca_id="7">
<conductivity units="W/m K">0.0432</conductivity> <conductivity units="W/m K">0.0432</conductivity>
<density units="kg/m3">91</density> <density units="kg/m3">91</density>
<specific_heat units="J/kg K">837</specific_heat> <specific_heat units="J/kg K">837</specific_heat>
@ -86,7 +86,7 @@
<solar_absorptance units="-">0.5</solar_absorptance> <solar_absorptance units="-">0.5</solar_absorptance>
<visible_absorptance units="-">0.5</visible_absorptance> <visible_absorptance units="-">0.5</visible_absorptance>
</material> </material>
<material id="7" name="1/2IN Gypsum"> <material id="7" name="1/2IN Gypsum" lca_id="7">
<conductivity units="W/m K">0.16</conductivity> <conductivity units="W/m K">0.16</conductivity>
<density units="kg/m3">784.9</density> <density units="kg/m3">784.9</density>
<specific_heat units="J/kg K">830</specific_heat> <specific_heat units="J/kg K">830</specific_heat>
@ -94,7 +94,7 @@
<solar_absorptance units="-">0.92</solar_absorptance> <solar_absorptance units="-">0.92</solar_absorptance>
<visible_absorptance units="-">0.92</visible_absorptance> <visible_absorptance units="-">0.92</visible_absorptance>
</material> </material>
<material id="8" name="Wood Siding"> <material id="8" name="Wood Siding" lca_id="7">
<conductivity units="W/m K">0.11</conductivity> <conductivity units="W/m K">0.11</conductivity>
<density units="kg/m3">544.62</density> <density units="kg/m3">544.62</density>
<specific_heat units="J/kg K">1210</specific_heat> <specific_heat units="J/kg K">1210</specific_heat>
@ -102,7 +102,7 @@
<solar_absorptance units="-">0.78</solar_absorptance> <solar_absorptance units="-">0.78</solar_absorptance>
<visible_absorptance units="-">0.78</visible_absorptance> <visible_absorptance units="-">0.78</visible_absorptance>
</material> </material>
<material id="9" name="Wood Shingles"> <material id="9" name="Wood Shingles" lca_id="7">
<conductivity units="W/m K">0.115</conductivity> <conductivity units="W/m K">0.115</conductivity>
<density units="kg/m3">513</density> <density units="kg/m3">513</density>
<specific_heat units="J/kg K">1255</specific_heat> <specific_heat units="J/kg K">1255</specific_heat>
@ -110,7 +110,7 @@
<solar_absorptance units="-">0.78</solar_absorptance> <solar_absorptance units="-">0.78</solar_absorptance>
<visible_absorptance units="-">0.78</visible_absorptance> <visible_absorptance units="-">0.78</visible_absorptance>
</material> </material>
<material id="10" name="1IN Wood Decking"> <material id="10" name="1IN Wood Decking" lca_id="7">
<conductivity units="W/m K">0.1211</conductivity> <conductivity units="W/m K">0.1211</conductivity>
<density units="kg/m3">593</density> <density units="kg/m3">593</density>
<specific_heat units="J/kg K">2510</specific_heat> <specific_heat units="J/kg K">2510</specific_heat>
@ -118,7 +118,7 @@
<solar_absorptance units="-">0.78</solar_absorptance> <solar_absorptance units="-">0.78</solar_absorptance>
<visible_absorptance units="-">0.78</visible_absorptance> <visible_absorptance units="-">0.78</visible_absorptance>
</material> </material>
<material id="11" name="Roof Insulation [23]"> <material id="11" name="Roof Insulation [23]" lca_id="7">
<conductivity units="W/m K">0.049</conductivity> <conductivity units="W/m K">0.049</conductivity>
<density units="kg/m3">265</density> <density units="kg/m3">265</density>
<specific_heat units="J/kg K">836.8</specific_heat> <specific_heat units="J/kg K">836.8</specific_heat>
@ -126,14 +126,14 @@
<solar_absorptance units="-">0.7</solar_absorptance> <solar_absorptance units="-">0.7</solar_absorptance>
<visible_absorptance units="-">0.7</visible_absorptance> <visible_absorptance units="-">0.7</visible_absorptance>
</material> </material>
<material id="12" name="MAT-SHEATH"> <material id="12" name="MAT-SHEATH" lca_id="7">
<no_mass>true</no_mass> <no_mass>true</no_mass>
<thermal_resistance units="m2 K/W">0.36256</thermal_resistance> <thermal_resistance units="m2 K/W">0.36256</thermal_resistance>
<thermal_absorptance units="-">0.9</thermal_absorptance> <thermal_absorptance units="-">0.9</thermal_absorptance>
<solar_absorptance units="-">0.7</solar_absorptance> <solar_absorptance units="-">0.7</solar_absorptance>
<visible_absorptance units="-">0.7</visible_absorptance> <visible_absorptance units="-">0.7</visible_absorptance>
</material> </material>
<material id="14" name="Metal Decking"> <material id="14" name="Metal Decking" lca_id="7">
<conductivity units="W/m K">45.006</conductivity> <conductivity units="W/m K">45.006</conductivity>
<density units="kg/m3">7680</density> <density units="kg/m3">7680</density>
<specific_heat units="J/kg K">418.4</specific_heat> <specific_heat units="J/kg K">418.4</specific_heat>
@ -141,7 +141,7 @@
<solar_absorptance units="-">0.7</solar_absorptance> <solar_absorptance units="-">0.7</solar_absorptance>
<visible_absorptance units="-">0.3</visible_absorptance> <visible_absorptance units="-">0.3</visible_absorptance>
</material> </material>
<material id="15" name="Roof Membrane"> <material id="15" name="Roof Membrane" lca_id="7">
<conductivity units="W/m K">0.16</conductivity> <conductivity units="W/m K">0.16</conductivity>
<density units="kg/m3">1121.29</density> <density units="kg/m3">1121.29</density>
<specific_heat units="J/kg K">1460</specific_heat> <specific_heat units="J/kg K">1460</specific_heat>
@ -149,28 +149,28 @@
<solar_absorptance units="-">0.7</solar_absorptance> <solar_absorptance units="-">0.7</solar_absorptance>
<visible_absorptance units="-">0.7</visible_absorptance> <visible_absorptance units="-">0.7</visible_absorptance>
</material> </material>
<material id="16" name="CP02 CARPET PAD"> <material id="16" name="CP02 CARPET PAD" lca_id="7">
<no_mass>true</no_mass> <no_mass>true</no_mass>
<thermal_resistance units="m2 K/W">0.21648</thermal_resistance> <thermal_resistance units="m2 K/W">0.21648</thermal_resistance>
<thermal_absorptance units="-">0.9</thermal_absorptance> <thermal_absorptance units="-">0.9</thermal_absorptance>
<solar_absorptance units="-">0.7</solar_absorptance> <solar_absorptance units="-">0.7</solar_absorptance>
<visible_absorptance units="-">0.8</visible_absorptance> <visible_absorptance units="-">0.8</visible_absorptance>
</material> </material>
<material id="18" name="CP02 CARPET PAD"> <material id="18" name="CP02 CARPET PAD" lca_id="7">
<no_mass>true</no_mass> <no_mass>true</no_mass>
<thermal_resistance units="m2 K/W">0.21648</thermal_resistance> <thermal_resistance units="m2 K/W">0.21648</thermal_resistance>
<thermal_absorptance units="-">0.9</thermal_absorptance> <thermal_absorptance units="-">0.9</thermal_absorptance>
<solar_absorptance units="-">0.7</solar_absorptance> <solar_absorptance units="-">0.7</solar_absorptance>
<visible_absorptance units="-">0.8</visible_absorptance> <visible_absorptance units="-">0.8</visible_absorptance>
</material> </material>
<material id="20" name="CP02 CARPET PAD"> <material id="20" name="CP02 CARPET PAD" lca_id="7">
<no_mass>true</no_mass> <no_mass>true</no_mass>
<thermal_resistance units="m2 K/W">0.21648</thermal_resistance> <thermal_resistance units="m2 K/W">0.21648</thermal_resistance>
<thermal_absorptance units="-">0.9</thermal_absorptance> <thermal_absorptance units="-">0.9</thermal_absorptance>
<solar_absorptance units="-">0.7</solar_absorptance> <solar_absorptance units="-">0.7</solar_absorptance>
<visible_absorptance units="-">0.8</visible_absorptance> <visible_absorptance units="-">0.8</visible_absorptance>
</material> </material>
<material id="21" name="Wall Insulation [38]"> <material id="21" name="Wall Insulation [38]" lca_id="7">
<conductivity units="W/m K">0.045</conductivity> <conductivity units="W/m K">0.045</conductivity>
<density units="kg/m3">265</density> <density units="kg/m3">265</density>
<specific_heat units="J/kg K">836.8</specific_heat> <specific_heat units="J/kg K">836.8</specific_heat>
@ -178,7 +178,7 @@
<solar_absorptance units="-">0.7</solar_absorptance> <solar_absorptance units="-">0.7</solar_absorptance>
<visible_absorptance units="-">0.7</visible_absorptance> <visible_absorptance units="-">0.7</visible_absorptance>
</material> </material>
<material id="22" name="metal siding"> <material id="22" name="metal siding" lca_id="7">
<conductivity units="W/m K">44.96</conductivity> <conductivity units="W/m K">44.96</conductivity>
<density units="kg/m3">7688.86</density> <density units="kg/m3">7688.86</density>
<specific_heat units="J/kg K">410</specific_heat> <specific_heat units="J/kg K">410</specific_heat>

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<greenery:GreeneryCatalog xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:greenery="http://ca.concordia/greenerycatalog">
<plantCategories name="Flowers">
<plants name="Camellia Sasanqua" height="0.4 m" leafAreaIndex="2.18" leafReflectivity="0.2" leafEmissivity="0.9" minimalStomatalResistance="288 s/m" growsOn="//@soils.0 //@soils.2 //@soils.4 //@soils.3 //@soils.1"/>
<plants name="Rhododendron" height="0.5 m" leafAreaIndex="1.85" minimalStomatalResistance="161 s/m" growsOn="//@soils.0 //@soils.3"/>
<plants name="Ligustrum Japonicum 'Howardii' " height="0.48 m" leafAreaIndex="4.93" minimalStomatalResistance="172 s/m" growsOn="//@soils.0 //@soils.3"/>
<plants name="Viburnum Dilatatum (Thunb)" height="0.7 m" leafAreaIndex="5" minimalStomatalResistance="212 s/m" growsOn="//@soils.0 //@soils.3 //@soils.2 //@soils.4 //@soils.1"/>
<plants name="Lorpetalum Chinense var. Rubrum" height="0.7 m" leafAreaIndex="2" leafReflectivity="0.1" minimalStomatalResistance="228 s/m" growsOn="//@soils.0 //@soils.2 //@soils.3 //@soils.1"/>
<plants name="Buxus sinica" height="0.45 m" leafAreaIndex="4.03" minimalStomatalResistance="165 s/m" growsOn="//@soils.2 //@soils.0 //@soils.3 //@soils.5 //@soils.1"/>
<plants name="Sedum acre" height="0.1 m" leafAreaIndex="3.5" leafReflectivity="0.36" leafEmissivity="0.9" growsOn="//@soils.2 //@soils.0 //@soils.1 //@soils.3"/>
<plants name="Frankenia thymifolia" height="0.15 m" leafAreaIndex="3.6" leafReflectivity="0.32" leafEmissivity="0.83" growsOn="//@soils.2 //@soils.1 //@soils.0 //@soils.3"/>
<plants name="Vinca major" leafAreaIndex="2.7" leafReflectivity="0.25" leafEmissivity="0.78" growsOn="//@soils.2 //@soils.0 //@soils.3 //@soils.1"/>
<plants name="Ivy (hedera helix)" height="0.1 m" leafAreaIndex="5" growsOn="//@soils.4 //@soils.1 //@soils.2 //@soils.0 //@soils.3"/>
</plantCategories>
<plantCategories name="Grass">
<plants name="Lawn" height="0.06 m" leafAreaIndex="1.4" leafReflectivity="0.1" minimalStomatalResistance="50 s/m" growsOn="//@soils.2"/>
</plantCategories>
<plantCategories name="Farming">
<plants name="Strawberry" growsOn="//@soils.2"/>
<plants name="Tomato" leafEmissivity="0.8" growsOn="//@soils.2 //@soils.3"/>
<plants name="Lettuce" growsOn="//@soils.2"/>
</plantCategories>
<vegetationCategories name="Urban Greening">
<vegetationTemplates name="Grass" soil="//@soils.1" management="Extensive">
<plants plant="//@plantCategories.1/@plants.0"/>
</vegetationTemplates>
</vegetationCategories>
<vegetationCategories name="Green Facade">
<vegetationTemplates name="Green Facade" soil="//@soils.2">
<plants percentage="100" plant="//@plantCategories.0/@plants.9"/>
</vegetationTemplates>
</vegetationCategories>
<vegetationCategories name="GreenRoof">
<vegetationTemplates name="Green Roof" thicknessOfSoil="20 cm" soil="//@soils.2">
<plants percentage="10" plant="//@plantCategories.0/@plants.5"/>
<plants percentage="10" plant="//@plantCategories.0/@plants.0"/>
<plants percentage="10" plant="//@plantCategories.0/@plants.8"/>
<plants percentage="10" plant="//@plantCategories.0/@plants.2"/>
<plants percentage="10" plant="//@plantCategories.0/@plants.4"/>
<plants percentage="10" plant="//@plantCategories.0/@plants.6"/>
<plants percentage="10" plant="//@plantCategories.0/@plants.1"/>
<plants percentage="10" plant="//@plantCategories.0/@plants.3"/>
<plants percentage="20" plant="//@plantCategories.0/@plants.7"/>
</vegetationTemplates>
</vegetationCategories>
<vegetationCategories name="Rooftop Farming">
<vegetationTemplates name="Rooftop Farming" thicknessOfSoil="30 cm" soil="//@soils.2">
<plants percentage="19" plant="//@plantCategories.2/@plants.0"/>
<plants percentage="60" plant="//@plantCategories.2/@plants.1"/>
<plants percentage="21" plant="//@plantCategories.2/@plants.2"/>
</vegetationTemplates>
</vegetationCategories>
<soils name="Sand" conductivityOfDrySoil="1.26 W/(m·K)" saturationVolumetricMoistureContent="0.43" residualVolumetricMoistureContent="0.045"/>
<soils name="Loamy sand" conductivityOfDrySoil="0.35 W/(m·K)" saturationVolumetricMoistureContent="0.41" residualVolumetricMoistureContent="0.057"/>
<soils name="Loam" conductivityOfDrySoil="0.67 W/(m·K)" specificHeatOfDrySoil="900 J/(kg·K)" thermalAbsorptance="0.9" saturationVolumetricMoistureContent="0.43" residualVolumetricMoistureContent="0.078"/>
<soils name="Sandy Loam" conductivityOfDrySoil="1.06 W/(m·K)" saturationVolumetricMoistureContent="0.41" residualVolumetricMoistureContent="0.065"/>
<soils name="Clay loam" conductivityOfDrySoil="0.7 W/(m·K)" saturationVolumetricMoistureContent="0.41" residualVolumetricMoistureContent="0.095"/>
<soils name="Silt" conductivityOfDrySoil="0.35 W/(m·K)" saturationVolumetricMoistureContent="0.46" residualVolumetricMoistureContent="0.034"/>
</greenery:GreeneryCatalog>

View File

@ -1,6 +1,395 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<library name="LCA"> <library name="LCA">
<Fuels> <building_materials>
<material type = "brick" id="1" name= "clay brick">
<density unit= "ton/m3"> 1.8 </density>
<embodied_carbon unit= "kgCO2/ton"> 560 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0.3 </onsite_recycling_ratio>
<company_recycling_ratio> 0.7 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "brick" id="2" name= "light clay brick">
<density unit= "ton/m3"> 1.2 </density>
<embodied_carbon unit= "kgCO2/ton"> 310 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0.3 </onsite_recycling_ratio>
<company_recycling_ratio> 0.7 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "brick" id="3" name= "refractory">
<density unit= "ton/m3"> 2 </density>
<embodied_carbon unit= "kgCO2/ton"> 3080 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0.3 </onsite_recycling_ratio>
<company_recycling_ratio> 0.7 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "brick" id="4" name= "sand-lime brick">
<density unit= "ton/m3"> 1.4 </density>
<embodied_carbon unit= "kgCO2/ton"> 300 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0.3 </onsite_recycling_ratio>
<company_recycling_ratio> 0.7 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "concrete" id="5" name= "light weight expanded clay">
<density unit= "ton/m3"> 1.6 </density>
<embodied_carbon unit= "kgCO2/ton"> 900 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "concrete" id="6" name= "lightweight Expanded perlite">
<density unit= "ton/m3"> 1.6 </density>
<embodied_carbon unit= "kgCO2/ton"> 2340 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "concrete" id="7" name= "lightweight expanded vermiculite">
<density unit= "ton/m3"> 1.6 </density>
<embodied_carbon unit= "kgCO2/ton"> 1570 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "concrete" id="8" name= "lightweight polystyrene">
<density unit= "ton/m3"> 1.4 </density>
<embodied_carbon unit= "kgCO2/ton"> 1840 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "concrete" id="9" name= "lightweight pumice">
<density unit= "ton/m3"> 1.3 </density>
<embodied_carbon unit= "kgCO2/ton"> 410 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "concrete" id="10" name= "concrete 20 MPa">
<density unit= "ton/m3"> 2.3 </density>
<embodied_carbon unit= "kgCO2/ton"> 160 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "concrete" id="11" name= "concrete 25 MPa">
<density unit= "ton/m3"> 2.3 </density>
<embodied_carbon unit= "kgCO2/ton"> 170 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "concrete" id="12" name= "concrete 30-32 MPa">
<density unit= "ton/m3"> 2.3 </density>
<embodied_carbon unit= "kgCO2/ton"> 230 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "concrete" id="13" name= "concrete 35 MPae">
<density unit= "ton/m3"> 2.4 </density>
<embodied_carbon unit= "kgCO2/ton"> 240 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "concrete" id="14" name= "concrete 50 MPa">
<density unit= "ton/m3"> 2.4 </density>
<embodied_carbon unit= "kgCO2/ton"> 280 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "concrete" id="15" name= "concrete block">
<density unit= "ton/m3"> 2.3 </density>
<embodied_carbon unit= "kgCO2/ton"> 170 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "concrete" id="16" name= "concrete roof tile">
<density unit= "ton/m3"> 1.2 </density>
<embodied_carbon unit= "kgCO2/ton"> 440 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "glass" id="17" name= "flat glass, coated">
<density unit= "ton/m3"> 2.58 </density>
<embodied_carbon unit= "kgCO2/ton"> 2660 </embodied_carbon>
<recycling_ratio> 0.95 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.05 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "glass" id="18" name= "glass fibre">
<density unit= "ton/m3"> 2.58 </density>
<embodied_carbon unit= "kgCO2/ton"> 5260 </embodied_carbon>
<recycling_ratio> 0.95 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.05 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "insulation" id="19" name= "cellulose fibre">
<density unit= "ton/m3"> 0.06 </density>
<embodied_carbon unit= "kgCO2/ton"> 1760 </embodied_carbon>
<recycling_ratio> 0.9 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.1 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "insulation" id="20" name= "cork slab">
<density unit= "ton/m3"> 0.122 </density>
<embodied_carbon unit= "kgCO2/ton"> 3080 </embodied_carbon>
<recycling_ratio> 0.9 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.1 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "insulation" id="21" name= "polystyren foam">
<density unit= "ton/m3"> 0.028 </density>
<embodied_carbon unit= "kgCO2/ton"> 3180 </embodied_carbon>
<recycling_ratio> 0.9 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.1 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "insulation" id="22" name= "polystyrene 10% recycled">
<density unit= "ton/m3"> 0.024 </density>
<embodied_carbon unit= "kgCO2/ton"> 5140 </embodied_carbon>
<recycling_ratio> 0.9 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.1 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "insulation" id="23" name= "stone wool">
<density unit= "ton/m3"> 0.1 </density>
<embodied_carbon unit= "kgCO2/ton"> 6040 </embodied_carbon>
<recycling_ratio> 0.9 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.1 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "insulation" id="24" name= "foam glass">
<density unit= "ton/m3"> 0.3 </density>
<embodied_carbon unit= "kgCO2/ton"> 5380 </embodied_carbon>
<recycling_ratio> 0.9 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.1 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "insulation" id="25" name= "glass wool mat">
<density unit= "ton/m3"> 0.032 </density>
<embodied_carbon unit= "kgCO2/ton"> 2150 </embodied_carbon>
<recycling_ratio> 0.9 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.1 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "wood" id="26" name= "fiberboard, hard">
<density unit= "ton/m3"> 0.9 </density>
<embodied_carbon unit= "kgCO2/ton"> 3420 </embodied_carbon>
<recycling_ratio> 0.6 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.4 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "wood" id="27" name= "three layerd laminated board">
<density unit= "ton/m3"> 0.7 </density>
<embodied_carbon unit= "kgCO2/ton"> 1430 </embodied_carbon>
<recycling_ratio> 0.6 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.4 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "wood" id="28" name= "fibreboard, soft">
<density unit= "ton/m3"> 0.65 </density>
<embodied_carbon unit= "kgCO2/ton"> 2780 </embodied_carbon>
<recycling_ratio> 0.6 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.4 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "wood" id="29" name= "plywood">
<density unit= "ton/m3"> 0.72 </density>
<embodied_carbon unit= "kgCO2/ton"> 2190 </embodied_carbon>
<recycling_ratio> 0.6 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.4 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "covering" id="30" name= "acrylic filler">
<density unit= "ton/m3"> 1.43 </density>
<embodied_carbon unit= "kgCO2/ton"> 1070 </embodied_carbon>
<recycling_ratio> 0 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 0 </company_recycling_ratio>
<landfilling_ratio> 1 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "covering" id="31" name= "anhydrite floor">
<density unit= "ton/m3"> 1.43 </density>
<embodied_carbon unit= "kgCO2/ton"> 240 </embodied_carbon>
<recycling_ratio> 0 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 0 </company_recycling_ratio>
<landfilling_ratio> 1 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "covering" id="32" name= "base plaster">
<density unit= "ton/m3"> 1.43 </density>
<embodied_carbon unit= "kgCO2/ton"> 430 </embodied_carbon>
<recycling_ratio> 0 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 0 </company_recycling_ratio>
<landfilling_ratio> 1 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "covering" id="33" name= "cement cast plaster floor">
<density unit= "ton/m3"> 1.43 </density>
<embodied_carbon unit= "kgCO2/ton"> 340 </embodied_carbon>
<recycling_ratio> 0 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 0 </company_recycling_ratio>
<landfilling_ratio> 1 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "covering" id="34" name= "cement tile">
<density unit= "ton/m3"> 1.2 </density>
<embodied_carbon unit= "kgCO2/ton"> 440 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "covering" id="35" name= "ceramic tile">
<density unit= "ton/m3"> 2.1 </density>
<embodied_carbon unit= "kgCO2/ton"> 1410 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "covering" id="36" name= "clay plaster">
<density unit= "ton/m3"> 1.43 </density>
<embodied_carbon unit= "kgCO2/ton"> 250 </embodied_carbon>
<recycling_ratio> 0 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 0 </company_recycling_ratio>
<landfilling_ratio> 1 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "covering" id="37" name= "fiber cement corrugated slab">
<density unit= "ton/m3"> 1.44 </density>
<embodied_carbon unit= "kgCO2/ton"> 1480 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "covering" id="38" name= "fiber cement facing tile">
<density unit= "ton/m3"> 1.44 </density>
<embodied_carbon unit= "kgCO2/ton"> 2220 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "wood" id="39" name= "gypsum fibreboard">
<density unit= "ton/m3"> 1.27 </density>
<embodied_carbon unit= "kgCO2/ton"> 3960 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "covering" id="40" name= "gypsum plaster board">
<density unit= "ton/m3"> 1.15 </density>
<embodied_carbon unit= "kgCO2/ton"> 760 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "metal" id="41" name= "steel">
<density unit= "ton/m3"> 8 </density>
<embodied_carbon unit= "kgCO2/ton"> 3160 </embodied_carbon>
<recycling_ratio> 0.98</recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.02 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "metal" id="42" name= "aluminium">
<density unit= "ton/m3"> 2.7 </density>
<embodied_carbon unit= "kgCO2/ton"> 5370 </embodied_carbon>
<recycling_ratio> 0.98</recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.02 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
<material type = "metal" id="43" name= "reinforcing steel">
<density unit= "ton/m3"> 7.85 </density>
<embodied_carbon unit= "kgCO2/ton"> 3910 </embodied_carbon>
<recycling_ratio> 0.98</recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.02 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</material>
</building_materials>
<fuels>
<fuel id="1" name= "Black_coal"> <fuel id="1" name= "Black_coal">
<carbon_emission_factor unit= "kgCO2/ kWh" > 0.32 </carbon_emission_factor> <carbon_emission_factor unit= "kgCO2/ kWh" > 0.32 </carbon_emission_factor>
</fuel> </fuel>
@ -76,498 +465,95 @@
<fuel id="25" name= "Steam"> <fuel id="25" name= "Steam">
<carbon_emission_factor unit= "kgCO2/ kg"> 0.61 </carbon_emission_factor> <carbon_emission_factor unit= "kgCO2/ kg"> 0.61 </carbon_emission_factor>
</fuel> </fuel>
</Fuels> </fuels>
<Machines> <machines>
<machine name= "Rock_drill"> <machine id="1" name= "Rock_drill">
<work_efficiency unit= "h/m3"> 0.347 </work_efficiency> <work_efficiency unit= "h/m3"> 0.347 </work_efficiency>
<energy_consumption_rate unit= "kWh/h"> 16.5 </energy_consumption_rate> <energy_consumption_rate unit= "kWh/h"> 16.5 </energy_consumption_rate>
<carbon_emission_factor unit= "kgCO2/kWh"> 0.918 </carbon_emission_factor> <carbon_emission_factor unit= "kgCO2/kWh"> 0.918 </carbon_emission_factor>
</machine> </machine>
<machine name= "Hydraulic_hammer"> <machine id="2" name= "Hydraulic_hammer">
<work_efficiency unit= "h/m3"> 0.033 </work_efficiency> <work_efficiency unit= "h/m3"> 0.033 </work_efficiency>
<energy_consumption_rate unit= "kg_fuel/h"> 25.2 </energy_consumption_rate> <energy_consumption_rate unit= "kg_fuel/h"> 25.2 </energy_consumption_rate>
<carbon_emission_factor unit= "kgCO2/kg_fuel"> 4.16 </carbon_emission_factor> <carbon_emission_factor unit= "kgCO2/kg_fuel"> 4.16 </carbon_emission_factor>
</machine> </machine>
<machine name= "Crawler_bulldozer"> <machine id="3" name= "Crawler_bulldozer">
<work_efficiency unit= "h/m3"> 0.027 </work_efficiency> <work_efficiency unit= "h/m3"> 0.027 </work_efficiency>
<energy_consumption_rate unit= "kg_fuel/h3"> 16.8 </energy_consumption_rate> <energy_consumption_rate unit= "kg_fuel/h3"> 16.8 </energy_consumption_rate>
<carbon_emission_factor unit= "kgCO2/kg_fuel"> 2.239 </carbon_emission_factor> <carbon_emission_factor unit= "kgCO2/kg_fuel"> 2.239 </carbon_emission_factor>
</machine> </machine>
<machine name= "Crawler_excavator"> <machine id="4" name= "Crawler_excavator">
<work_efficiency unit= "h/m3"> 0.023 </work_efficiency> <work_efficiency unit= "h/m3"> 0.023 </work_efficiency>
<energy_consumption_rate unit= "kg_fuel/h"> 16.8 </energy_consumption_rate> <energy_consumption_rate unit= "kg_fuel/h"> 16.8 </energy_consumption_rate>
<carbon_emission_factor unit= "kgCO2/kg_fuel"> 2.239 </carbon_emission_factor> <carbon_emission_factor unit= "kgCO2/kg_fuel"> 2.239 </carbon_emission_factor>
</machine> </machine>
<machine name= "Crawler_hydraulic_rock_crusher"> <machine id="5" name= "Crawler_hydraulic_rock_crusher">
<work_efficiency unit= "h/m3"> 0.109 </work_efficiency> <work_efficiency unit= "h/m3"> 0.109 </work_efficiency>
<energy_consumption_rate unit= "kg_fuel/h"> 25.2 </energy_consumption_rate> <energy_consumption_rate unit= "kg_fuel/h"> 25.2 </energy_consumption_rate>
<carbon_emission_factor unit= "kgCO2/kg_fuel"> 2.239 </carbon_emission_factor> <carbon_emission_factor unit= "kgCO2/kg_fuel"> 2.239 </carbon_emission_factor>
</machine> </machine>
<machine name= "Mobile_recycling_equipment"> <machine id="6" name= "Mobile_recycling_equipment">
<work_efficiency unit= "h/ton"> 0.003 </work_efficiency> <work_efficiency unit= "h/ton"> 0.003 </work_efficiency>
<energy_consumption_rate unit= "kg_fuel/h"> 16.4 </energy_consumption_rate> <energy_consumption_rate unit= "kg_fuel/h"> 16.4 </energy_consumption_rate>
<carbon_emission_factor unit= "kgCO2/kg_fuel"> 4.16 </carbon_emission_factor> <carbon_emission_factor unit= "kgCO2/kg_fuel"> 4.16 </carbon_emission_factor>
</machine> </machine>
<machine name= "Vibration_feeder"> <machine id="7" name= "Vibration_feeder">
<work_efficiency unit= "h/ton"> 0.002 </work_efficiency> <work_efficiency unit= "h/ton"> 0.002 </work_efficiency>
<energy_consumption_rate unit= "kWh/h"> 11 </energy_consumption_rate> <energy_consumption_rate unit= "kWh/h"> 11 </energy_consumption_rate>
<carbon_emission_factor unit= "kgCO2/kWh"> 0.918 </carbon_emission_factor> <carbon_emission_factor unit= "kgCO2/kWh"> 0.918 </carbon_emission_factor>
</machine> </machine>
<machine name= "Jaw_crusher"> <machine id="8" name= "Jaw_crusher">
<work_efficiency unit= "h/ton"> 0.002 </work_efficiency> <work_efficiency unit= "h/ton"> 0.002 </work_efficiency>
<energy_consumption_rate unit= "kWh/h"> 90 </energy_consumption_rate> <energy_consumption_rate unit= "kWh/h"> 90 </energy_consumption_rate>
<carbon_emission_factor unit= "kgCO2/kWh"> 0.918 </carbon_emission_factor> <carbon_emission_factor unit= "kgCO2/kWh"> 0.918 </carbon_emission_factor>
</machine> </machine>
<machine name= "Electromagnetic_separator"> <machine id="9" name= "Electromagnetic_separator">
<work_efficiency unit= "h/ton"> 0.002 </work_efficiency> <work_efficiency unit= "h/ton"> 0.002 </work_efficiency>
<energy_consumption_rate unit= "kWh/h"> 10 </energy_consumption_rate> <energy_consumption_rate unit= "kWh/h"> 10 </energy_consumption_rate>
<carbon_emission_factor unit= "kgCO2/kWh"> 0.918 </carbon_emission_factor> <carbon_emission_factor unit= "kgCO2/kWh"> 0.918 </carbon_emission_factor>
</machine> </machine>
<machine name= "Wind_sorting_machine"> <machine id="10" name= "Wind_sorting_machine">
<work_efficiency unit= "h/ton"> 0.002 </work_efficiency> <work_efficiency unit= "h/ton"> 0.002 </work_efficiency>
<energy_consumption_rate unit= "kWh/h"> 11 </energy_consumption_rate> <energy_consumption_rate unit= "kWh/h"> 11 </energy_consumption_rate>
<carbon_emission_factor unit= "kgCO2/kWh"> 0.918 </carbon_emission_factor> <carbon_emission_factor unit= "kgCO2/kWh"> 0.918 </carbon_emission_factor>
</machine> </machine>
<machine name= "Impact_crusher"> <machine id="11" name= "Impact_crusher">
<work_efficiency unit= "h/ton"> 0.002 </work_efficiency> <work_efficiency unit= "h/ton"> 0.002 </work_efficiency>
<energy_consumption_rate unit= "kWh/h"> 132 </energy_consumption_rate> <energy_consumption_rate unit= "kWh/h"> 132 </energy_consumption_rate>
<carbon_emission_factor unit= "kgCO2/kWh"> 0.918 </carbon_emission_factor> <carbon_emission_factor unit= "kgCO2/kWh"> 0.918 </carbon_emission_factor>
</machine> </machine>
<machine name= "Double_circular_vibrating_plug"> <machine id="12" name= "Double_circular_vibrating_plug">
<work_efficiency unit= " h/ton "> 0.002 </work_efficiency> <work_efficiency unit= " h/ton "> 0.002 </work_efficiency>
<energy_consumption_rate unit= "kWh/h"> 15 </energy_consumption_rate> <energy_consumption_rate unit= "kWh/h"> 15 </energy_consumption_rate>
<carbon_emission_factor unit= "kgCO2/kW"> 0.918 </carbon_emission_factor> <carbon_emission_factor unit= "kgCO2/kW"> 0.918 </carbon_emission_factor>
</machine> </machine>
<machine name= "Spiral_sand_washing_machine"> <machine id="13" name= "Spiral_sand_washing_machine">
<work_efficiency unit= "h/ton"> 0.002 </work_efficiency> <work_efficiency unit= "h/ton"> 0.002 </work_efficiency>
<energy_consumption_rate unit= "kWh/h"> 5.5 </energy_consumption_rate> <energy_consumption_rate unit= "kWh/h"> 5.5 </energy_consumption_rate>
<carbon_emission_factor unit= "kgCO2/kWh"> 0.918 </carbon_emission_factor> <carbon_emission_factor unit= "kgCO2/kWh"> 0.918 </carbon_emission_factor>
</machine> </machine>
<machine name= "Conveyor_belts"> <machine id="14" name= "Conveyor_belts">
<work_efficiency unit= "h/ton"> 0.002 </work_efficiency> <work_efficiency unit= "h/ton"> 0.002 </work_efficiency>
<energy_consumption_rate unit= "kWh/h"> 22.5 </energy_consumption_rate> <energy_consumption_rate unit= "kWh/h"> 22.5 </energy_consumption_rate>
<carbon_emission_factor unit= "kgCO2/kWh"> 0.918 </carbon_emission_factor> <carbon_emission_factor unit= "kgCO2/kWh"> 0.918 </carbon_emission_factor>
</machine> </machine>
</Machines> </machines>
<Vehicles> <vehicles>
<vehicle name= "Freight_lorry_18_ton"> <vehicle id="1" name= "Freight_lorry_18_ton">
<fuel_consumption_rate unit= "kg_fuel/ton.km"> 0.0123 </fuel_consumption_rate> <fuel_consumption_rate unit= "kg_fuel/ton.km"> 0.0123 </fuel_consumption_rate>
<carbon_emission_factor unit= "kgCO2/kg_fuel"> 2.239 </carbon_emission_factor> <carbon_emission_factor unit= "kgCO2/kg_fuel"> 2.239 </carbon_emission_factor>
</vehicle> </vehicle>
<vehicle name= "Freight_train"> <vehicle id="2" name= "Freight_train">
<fuel_consumption_rate unit= "kWh/ton.km"> 0.042 </fuel_consumption_rate> <fuel_consumption_rate unit= "kWh/ton.km"> 0.042 </fuel_consumption_rate>
<carbon_emission_factor unit= "kgCO2/kWh"> 0.918 </carbon_emission_factor> <carbon_emission_factor unit= "kgCO2/kWh"> 0.918 </carbon_emission_factor>
</vehicle> </vehicle>
<vehicle name= "Freight_ship"> <vehicle id="3" name= "Freight_ship">
<fuel_consumption_rate unit= "kWh/ton.km"> 0.01 </fuel_consumption_rate> <fuel_consumption_rate unit= "kWh/ton.km"> 0.01 </fuel_consumption_rate>
<carbon_emission_factor unit= "kgCO2/kWh"> 1.00000 </carbon_emission_factor> <carbon_emission_factor unit= "kgCO2/kWh"> 1.00000 </carbon_emission_factor>
</vehicle> </vehicle>
<vehicle name= "Freight_Air"> <vehicle id="4" name= "Freight_Air">
<fuel_consumption_rate unit= "kWh/ton.km"> 1.3 </fuel_consumption_rate> <fuel_consumption_rate unit= "kWh/ton.km"> 1.3 </fuel_consumption_rate>
<carbon_emission_factor unit= "kgCO2/kWh"> 1.00000 </carbon_emission_factor> <carbon_emission_factor unit= "kgCO2/kWh"> 1.00000 </carbon_emission_factor>
</vehicle> </vehicle>
</Vehicles> </vehicles>
<Building_materials>
<Bricks>
<brick id="1" type= "clay brick">
<density unit= "ton/m3"> 1.8 </density>
<embodied_carbon unit= "kgCO2/ton"> 560 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0.3 </onsite_recycling_ratio>
<company_recycling_ratio> 0.7 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</brick>
<brick id="2" type= "light clay brick">
<density unit= "ton/m3"> 1.2 </density>
<embodied_carbon unit= "kgCO2/ton"> 310 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0.3 </onsite_recycling_ratio>
<company_recycling_ratio> 0.7 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</brick>
<brick id="3" type= "refractory">
<density unit= "ton/m3"> 2 </density>
<embodied_carbon unit= "kgCO2/ton"> 3080 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0.3 </onsite_recycling_ratio>
<company_recycling_ratio> 0.7 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</brick>
<brick id="4" type= "sand-lime brick">
<density unit= "ton/m3"> 1.4 </density>
<embodied_carbon unit= "kgCO2/ton"> 300 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0.3 </onsite_recycling_ratio>
<company_recycling_ratio> 0.7 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</brick>
</Bricks>
<Concretes>
<concrete id="1" type= "light weight expanded clay">
<density unit= "ton/m3"> 1.6 </density>
<embodied_carbon unit= "kgCO2/ton"> 900 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</concrete>
<concrete id="2" type= "lightweight Expanded perlite">
<density unit= "ton/m3"> 1.6 </density>
<embodied_carbon unit= "kgCO2/ton"> 2340 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</concrete>
<concrete id="3" type= "lightweight expanded vermiculite">
<density unit= "ton/m3"> 1.6 </density>
<embodied_carbon unit= "kgCO2/ton"> 1570 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</concrete>
<concrete id="4" type= "lightweight polystyrene">
<density unit= "ton/m3"> 1.4 </density>
<embodied_carbon unit= "kgCO2/ton"> 1840 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</concrete>
<concrete id="5" type= "lightweight pumice">
<density unit= "ton/m3"> 1.3 </density>
<embodied_carbon unit= "kgCO2/ton"> 410 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</concrete>
<concrete id="6" type= "concrete 20 MPa">
<density unit= "ton/m3"> 2.3 </density>
<embodied_carbon unit= "kgCO2/ton"> 160 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</concrete>
<concrete id="7" type= "concrete 25 MPa">
<density unit= "ton/m3"> 2.3 </density>
<embodied_carbon unit= "kgCO2/ton"> 170 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</concrete>
<concrete id="8" type= "concrete 30-32 MPa">
<density unit= "ton/m3"> 2.3 </density>
<embodied_carbon unit= "kgCO2/ton"> 230 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</concrete>
<concrete id="9" type= "concrete 35 MPae">
<density unit= "ton/m3"> 2.4 </density>
<embodied_carbon unit= "kgCO2/ton"> 240 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</concrete>
<concrete id="10" type= "concrete 50 MPa">
<density unit= "ton/m3"> 2.4 </density>
<embodied_carbon unit= "kgCO2/ton"> 280 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</concrete>
<concrete id="11" type= "concrete block">
<density unit= "ton/m3"> 2.3 </density>
<embodied_carbon unit= "kgCO2/ton"> 170 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</concrete>
<concrete id="12" type= "concrete roof tile">
<density unit= "ton/m3"> 1.2 </density>
<embodied_carbon unit= "kgCO2/ton"> 440 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</concrete>
</Concretes>
<glasses>
<glass id="1" type= "flat glass, coated">
<density unit= "ton/m3"> 2.58 </density>
<embodied_carbon unit= "kgCO2/ton"> 2660 </embodied_carbon>
<recycling_ratio> 0.95 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.05 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</glass>
<glass id="2" type= "glass fibre">
<density unit= "ton/m3"> 2.58 </density>
<embodied_carbon unit= "kgCO2/ton"> 5260 </embodied_carbon>
<recycling_ratio> 0.95 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.05 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</glass>
</glasses>
<Insulations>
<Insulation id="1" type= "cellulose fibre">
<density unit= "ton/m3"> 0.06 </density>
<embodied_carbon unit= "kgCO2/ton"> 1760 </embodied_carbon>
<recycling_ratio> 0.9 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.1 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</Insulation>
<Insulation id="2" type= "cork slab">
<density unit= "ton/m3"> 0.122 </density>
<embodied_carbon unit= "kgCO2/ton"> 3080 </embodied_carbon>
<recycling_ratio> 0.9 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.1 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</Insulation>
<Insulation id="3" type= "polystyren foam">
<density unit= "ton/m3"> 0.028 </density>
<embodied_carbon unit= "kgCO2/ton"> 3180 </embodied_carbon>
<recycling_ratio> 0.9 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.1 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</Insulation>
<Insulation id="4" type= "polystyrene 10% recycled">
<density unit= "ton/m3"> 0.024 </density>
<embodied_carbon unit= "kgCO2/ton"> 5140 </embodied_carbon>
<recycling_ratio> 0.9 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.1 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</Insulation>
<Insulation id="5" type= "stone wool">
<density unit= "ton/m3"> 0.1 </density>
<embodied_carbon unit= "kgCO2/ton"> 6040 </embodied_carbon>
<recycling_ratio> 0.9 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.1 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</Insulation>
<Insulation id="6" type= "foam glass">
<density unit= "ton/m3"> 0.3 </density>
<embodied_carbon unit= "kgCO2/ton"> 5380 </embodied_carbon>
<recycling_ratio> 0.9 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.1 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</Insulation>
<Insulation id="7" type= "glass wool mat">
<density unit= "ton/m3"> 0.032 </density>
<embodied_carbon unit= "kgCO2/ton"> 2150 </embodied_carbon>
<recycling_ratio> 0.9 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.1 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</Insulation>
</Insulations>
<woods>
<wood id="1" type= "fiberboard, hard">
<density unit= "ton/m3"> 0.9 </density>
<embodied_carbon unit= "kgCO2/ton"> 3420 </embodied_carbon>
<recycling_ratio> 0.6 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.4 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</wood>
<wood id="2" type= "three layerd laminated board">
<density unit= "ton/m3"> 0.7 </density>
<embodied_carbon unit= "kgCO2/ton"> 1430 </embodied_carbon>
<recycling_ratio> 0.6 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.4 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</wood>
<wood id="3" type= "fibreboard, soft">
<density unit= "ton/m3"> 0.65 </density>
<embodied_carbon unit= "kgCO2/ton"> 2780 </embodied_carbon>
<recycling_ratio> 0.6 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.4 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</wood>
<wood id="4" type= "plywood">
<density unit= "ton/m3"> 0.72 </density>
<embodied_carbon unit= "kgCO2/ton"> 2190 </embodied_carbon>
<recycling_ratio> 0.6 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.4 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</wood>
</woods>
<coverings>
<covering id="1" type= "acrylic filler">
<density unit= "ton/m3"> 1.43 </density>
<embodied_carbon unit= "kgCO2/ton"> 1070 </embodied_carbon>
<recycling_ratio> 0 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 0 </company_recycling_ratio>
<landfilling_ratio> 1 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</covering>
<covering id="2" type= "anhydrite floor">
<density unit= "ton/m3"> 1.43 </density>
<embodied_carbon unit= "kgCO2/ton"> 240 </embodied_carbon>
<recycling_ratio> 0 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 0 </company_recycling_ratio>
<landfilling_ratio> 1 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</covering>
<covering id="3" type= "base plaster">
<density unit= "ton/m3"> 1.43 </density>
<embodied_carbon unit= "kgCO2/ton"> 430 </embodied_carbon>
<recycling_ratio> 0 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 0 </company_recycling_ratio>
<landfilling_ratio> 1 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</covering>
<covering id="4" type= "cement cast plaster floor">
<density unit= "ton/m3"> 1.43 </density>
<embodied_carbon unit= "kgCO2/ton"> 340 </embodied_carbon>
<recycling_ratio> 0 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 0 </company_recycling_ratio>
<landfilling_ratio> 1 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</covering>
<covering id="5" type= "cement tile">
<density unit= "ton/m3"> 1.2 </density>
<embodied_carbon unit= "kgCO2/ton"> 440 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</covering>
<covering id="6" type= "ceramic tile">
<density unit= "ton/m3"> 2.1 </density>
<embodied_carbon unit= "kgCO2/ton"> 1410 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</covering>
<covering id="7" type= "clay plaster">
<density unit= "ton/m3"> 1.43 </density>
<embodied_carbon unit= "kgCO2/ton"> 250 </embodied_carbon>
<recycling_ratio> 0 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 0 </company_recycling_ratio>
<landfilling_ratio> 1 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</covering>
<covering id="7" type= "fiber cement corrugated slab">
<density unit= "ton/m3"> 1.44 </density>
<embodied_carbon unit= "kgCO2/ton"> 1480 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</covering>
<covering id="7" type= "fiber cement facing tile">
<density unit= "ton/m3"> 1.44 </density>
<embodied_carbon unit= "kgCO2/ton"> 2220 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</covering>
<covering id="7" type= "gypsum fibreboard">
<density unit= "ton/m3"> 1.27 </density>
<embodied_carbon unit= "kgCO2/ton"> 3960 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</covering>
<covering id="7" type= "gypsum plaster board">
<density unit= "ton/m3"> 1.15 </density>
<embodied_carbon unit= "kgCO2/ton"> 760 </embodied_carbon>
<recycling_ratio> 0.8 </recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.2 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</covering>
</coverings>
<metals>
<metal id="1" type= "steel">
<density unit= "ton/m3"> 8 </density>
<embodied_carbon unit= "kgCO2/ton"> 3160 </embodied_carbon>
<recycling_ratio> 0.98</recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.02 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</metal>
<metal id="2" type= "aluminium">
<density unit= "ton/m3"> 2.7 </density>
<embodied_carbon unit= "kgCO2/ton"> 5370 </embodied_carbon>
<recycling_ratio> 0.98</recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.02 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</metal>
<metal id="3" type= "reinforcing steel">
<density unit= "ton/m3"> 7.85 </density>
<embodied_carbon unit= "kgCO2/ton"> 3910 </embodied_carbon>
<recycling_ratio> 0.98</recycling_ratio>
<onsite_recycling_ratio> 0 </onsite_recycling_ratio>
<company_recycling_ratio> 1 </company_recycling_ratio>
<landfilling_ratio> 0.02 </landfilling_ratio>
<cost unit= "...."> .... </cost>
</metal>
</metals>
</Building_materials>
</library> </library>

Binary file not shown.

View File

@ -28,7 +28,7 @@ class EnergySystemsExportFactory:
""" """
self._city = city self._city = city
if base_path is None: if base_path is None:
base_path = base_path = Path(Path(__file__).parent.parent / 'data/energy_systems') base_path = Path(Path(__file__).parent.parent / 'data/energy_systems')
self._base_path = base_path self._base_path = base_path
self._user_input = user_input self._user_input = user_input
self._hp_model = hp_model self._hp_model = hp_model

View File

@ -30,6 +30,10 @@ class ExportsFactory:
""" """
raise NotImplementedError raise NotImplementedError
@property
def _collada(self):
raise NotImplementedError
@property @property
def _energy_ade(self): def _energy_ade(self):
""" """

View File

@ -3,6 +3,7 @@ TestOccupancyFactory test and validate the city model structure schedules parame
SPDX - License - Identifier: LGPL - 3.0 - or -later SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Soroush Samareh Abolhassani - soroush.samarehabolhassani@mail.concordia.ca Copyright © 2020 Project Author Soroush Samareh Abolhassani - soroush.samarehabolhassani@mail.concordia.ca
""" """
from geomeppy import IDF from geomeppy import IDF
@ -18,6 +19,7 @@ class Idf:
_MATERIAL_NOMASS = 'MATERIAL:NOMASS' _MATERIAL_NOMASS = 'MATERIAL:NOMASS'
_ROUGHNESS = 'MediumRough' _ROUGHNESS = 'MediumRough'
_HOURLY_SCHEDULE = 'SCHEDULE:DAY:HOURLY' _HOURLY_SCHEDULE = 'SCHEDULE:DAY:HOURLY'
_COMPACT_SCHEDULE = 'SCHEDULE:COMPACT'
_ZONE = 'ZONE' _ZONE = 'ZONE'
_LIGHTS = 'LIGHTS' _LIGHTS = 'LIGHTS'
_PEOPLE = 'PEOPLE' _PEOPLE = 'PEOPLE'
@ -28,8 +30,8 @@ class Idf:
_ON_OFF = 'On/Off' _ON_OFF = 'On/Off'
_FRACTION = 'Fraction' _FRACTION = 'Fraction'
_ANY_NUMBER = 'Any Number' _ANY_NUMBER = 'Any Number'
_CONTINUOUS = 'CONTINUOUS' _CONTINUOUS = 'Continuous'
_DISCRETE = 'DISCRETE' _DISCRETE = 'Discrete'
idf_surfaces = { idf_surfaces = {
# todo: make an enum for all the surface types # todo: make an enum for all the surface types
@ -42,9 +44,18 @@ class Idf:
'residential': 'residential_building' 'residential': 'residential_building'
} }
idf_type_limits = {
'on_off': 'on/off',
'fraction': 'Fraction',
'any_number': 'Any Number',
'continuous': 'Continuous',
'discrete': 'Discrete'
}
def __init__(self, city, output_path, idf_file_path, idd_file_path, epw_file_path, export_type="Surfaces"): def __init__(self, city, output_path, idf_file_path, idd_file_path, epw_file_path, export_type="Surfaces"):
self._city = city self._city = city
self._output_path = str((output_path / f'{city.name}.idf').resolve()) self._output_path = str(output_path.resolve())
self._output_file = str((output_path / f'{city.name}.idf').resolve())
self._export_type = export_type self._export_type = export_type
self._idd_file_path = str(idd_file_path) self._idd_file_path = str(idd_file_path)
self._idf_file_path = str(idf_file_path) self._idf_file_path = str(idf_file_path)
@ -59,10 +70,13 @@ class Idf:
self._export() self._export()
@staticmethod @staticmethod
def _matrix_to_list(points): def _matrix_to_list(points, lower_corner):
lower_x = lower_corner[0]
lower_y = lower_corner[1]
lower_z = lower_corner[2]
points_list = [] points_list = []
for point in points: for point in points:
point_tuple = (point[0], point[1], point[2]) point_tuple = (point[0]-lower_x, point[1]-lower_y, point[2]-lower_z)
points_list.append(point_tuple) points_list.append(point_tuple)
return points_list return points_list
@ -103,40 +117,70 @@ class Idf:
Visible_Absorptance=layer.material.visible_absorptance Visible_Absorptance=layer.material.visible_absorptance
) )
def _add_schedule(self, usage_zone, schedule_type, limit_name='Any Number'): def _add_daily_schedule(self, usage_zone, schedule):
_schedule = self._idf.newidfobject(self._COMPACT_SCHEDULE, Name=f'{schedule.type} schedules {usage_zone.usage}')
_val = schedule.values
_schedule.Schedule_Type_Limits_Name = self.idf_type_limits[schedule.data_type.lower()]
_schedule.Field_1 = "Through: 12/31"
_schedule.Field_2 = "For: AllDays"
_schedule.Field_3 = "Until: 01:00"
_schedule.Field_4 = _val[0]
_schedule.Field_5 = "Until: 02:00"
_schedule.Field_6 = _val[1]
_schedule.Field_7 = "Until: 03:00"
_schedule.Field_8 = _val[2]
_schedule.Field_9 = "Until: 04:00"
_schedule.Field_10 = _val[3]
_schedule.Field_11 = "Until: 05:00"
_schedule.Field_12 = _val[4]
_schedule.Field_13 = "Until: 06:00"
_schedule.Field_14 = _val[5]
_schedule.Field_15 = "Until: 07:00"
_schedule.Field_16 = _val[6]
_schedule.Field_17 = "Until: 08:00"
_schedule.Field_18 = _val[7]
_schedule.Field_19 = "Until: 09:00"
_schedule.Field_20 = _val[8]
_schedule.Field_21 = "Until: 10:00"
_schedule.Field_22 = _val[9]
_schedule.Field_23 = "Until: 11:00"
_schedule.Field_24 = _val[10]
_schedule.Field_25 = "Until: 12:00"
_schedule.Field_26 = _val[11]
_schedule.Field_27 = "Until: 13:00"
_schedule.Field_28 = _val[12]
_schedule.Field_29 = "Until: 14:00"
_schedule.Field_30 = _val[13]
_schedule.Field_31 = "Until: 15:00"
_schedule.Field_32 = _val[14]
_schedule.Field_33 = "Until: 16:00"
_schedule.Field_34 = _val[15]
_schedule.Field_35 = "Until: 17:00"
_schedule.Field_36 = _val[16]
_schedule.Field_37 = "Until: 18:00"
_schedule.Field_38 = _val[17]
_schedule.Field_39 = "Until: 19:00"
_schedule.Field_40 = _val[18]
_schedule.Field_41 = "Until: 20:00"
_schedule.Field_42 = _val[19]
_schedule.Field_43 = "Until: 21:00"
_schedule.Field_44 = _val[20]
_schedule.Field_45 = "Until: 22:00"
_schedule.Field_46 = _val[21]
_schedule.Field_47 = "Until: 23:00"
_schedule.Field_48 = _val[22]
_schedule.Field_49 = "Until: 24:00"
_schedule.Field_50 = _val[23]
def _add_schedule(self, usage_zone, schedule_type):
for schedule in self._idf.idfobjects[self._HOURLY_SCHEDULE]: for schedule in self._idf.idfobjects[self._HOURLY_SCHEDULE]:
if schedule.Name == f'{schedule_type} schedules {usage_zone.usage}': if schedule.Name == f'{schedule_type} schedules {usage_zone.usage}':
return return
if usage_zone.schedules is None or schedule_type not in usage_zone.schedules: for schedule in usage_zone.schedules:
# there are no schedule for this type if schedule.type == schedule_type:
if schedule.time_range == "day":
return self._add_daily_schedule(usage_zone, schedule)
return return
schedule = self._idf.newidfobject(self._HOURLY_SCHEDULE, Name=f'{schedule_type} schedules {usage_zone.usage}')
schedule.Schedule_Type_Limits_Name = limit_name
schedule.Hour_1 = usage_zone.schedules[schedule_type]["WD"][0]
schedule.Hour_2 = usage_zone.schedules[schedule_type]["WD"][1]
schedule.Hour_3 = usage_zone.schedules[schedule_type]["WD"][2]
schedule.Hour_4 = usage_zone.schedules[schedule_type]["WD"][3]
schedule.Hour_5 = usage_zone.schedules[schedule_type]["WD"][4]
schedule.Hour_6 = usage_zone.schedules[schedule_type]["WD"][5]
schedule.Hour_7 = usage_zone.schedules[schedule_type]["WD"][6]
schedule.Hour_8 = usage_zone.schedules[schedule_type]["WD"][7]
schedule.Hour_9 = usage_zone.schedules[schedule_type]["WD"][8]
schedule.Hour_10 = usage_zone.schedules[schedule_type]["WD"][9]
schedule.Hour_11 = usage_zone.schedules[schedule_type]["WD"][10]
schedule.Hour_12 = usage_zone.schedules[schedule_type]["WD"][11]
schedule.Hour_13 = usage_zone.schedules[schedule_type]["WD"][12]
schedule.Hour_14 = usage_zone.schedules[schedule_type]["WD"][13]
schedule.Hour_15 = usage_zone.schedules[schedule_type]["WD"][14]
schedule.Hour_16 = usage_zone.schedules[schedule_type]["WD"][15]
schedule.Hour_17 = usage_zone.schedules[schedule_type]["WD"][16]
schedule.Hour_18 = usage_zone.schedules[schedule_type]["WD"][17]
schedule.Hour_19 = usage_zone.schedules[schedule_type]["WD"][18]
schedule.Hour_20 = usage_zone.schedules[schedule_type]["WD"][19]
schedule.Hour_21 = usage_zone.schedules[schedule_type]["WD"][20]
schedule.Hour_22 = usage_zone.schedules[schedule_type]["WD"][21]
schedule.Hour_23 = usage_zone.schedules[schedule_type]["WD"][22]
schedule.Hour_24 = usage_zone.schedules[schedule_type]["WD"][23]
def _add_construction(self, thermal_boundary): def _add_construction(self, thermal_boundary):
for construction in self._idf.idfobjects[self._CONSTRUCTION]: for construction in self._idf.idfobjects[self._CONSTRUCTION]:
@ -183,7 +227,9 @@ class Idf:
thermostat = self._add_thermostat(usage_zone) thermostat = self._add_thermostat(usage_zone)
self._idf.newidfobject(self._IDEAL_LOAD_AIR_SYSTEM, self._idf.newidfobject(self._IDEAL_LOAD_AIR_SYSTEM,
Zone_Name=usage_zone.id, Zone_Name=usage_zone.id,
Cooling_Availability_Schedule_Name=f'Refrigeration schedules {usage_zone.usage}', System_Availability_Schedule_Name=f'HVAC AVAIL SCHEDULES {usage_zone.usage}',
Heating_Availability_Schedule_Name=f'HVAC AVAIL SCHEDULES {usage_zone.usage}',
Cooling_Availability_Schedule_Name=f'HVAC AVAIL SCHEDULES {usage_zone.usage}',
Template_Thermostat_Name=thermostat.Name) Template_Thermostat_Name=thermostat.Name)
def _add_occupancy(self, usage_zone): def _add_occupancy(self, usage_zone):
@ -194,7 +240,7 @@ class Idf:
Number_of_People_Calculation_Method="People", Number_of_People_Calculation_Method="People",
Number_of_People=500, # todo: get people from where? Number_of_People=500, # todo: get people from where?
Fraction_Radiant=0.3, # todo: howto get this from InternalGains Fraction_Radiant=0.3, # todo: howto get this from InternalGains
Activity_Level_Schedule_Name='occupant schedules' Activity_Level_Schedule_Name=f'Occupancy schedules {usage_zone.usage}'
) )
def _add_equipment(self, usage_zone): def _add_equipment(self, usage_zone):
@ -227,17 +273,19 @@ class Idf:
Export the idf file into the given path Export the idf file into the given path
export type = "Surfaces|Block" export type = "Surfaces|Block"
""" """
for building in self._city.buildings: for building in self._city.buildings:
for usage_zone in building.usage_zones: for usage_zone in building.usage_zones:
self._add_schedule(usage_zone, "Infiltration") self._add_schedule(usage_zone, "Infiltration")
self._add_schedule(usage_zone, "Lights") self._add_schedule(usage_zone, "Lights")
self._add_schedule(usage_zone, "Occupancy") self._add_schedule(usage_zone, "Occupancy")
self._add_schedule(usage_zone, "Refrigeration", self._ON_OFF) self._add_schedule(usage_zone, "Refrigeration")
self._add_schedule(usage_zone, "HVAC Avail")
self._add_zone(usage_zone) self._add_zone(usage_zone)
self._add_heating_system(usage_zone) self._add_heating_system(usage_zone)
# self._add_infiltration(usage_zone) self._add_infiltration(usage_zone)
# self._add_occupancy(usage_zone) self._add_occupancy(usage_zone)
for thermal_zone in building.thermal_zones: for thermal_zone in building.thermal_zones:
for thermal_boundary in thermal_zone.thermal_boundaries: for thermal_boundary in thermal_zone.thermal_boundaries:
self._add_construction(thermal_boundary) self._add_construction(thermal_boundary)
@ -246,8 +294,27 @@ class Idf:
self._add_surfaces(building) self._add_surfaces(building)
else: else:
self._add_block(building) self._add_block(building)
self._idf.newidfobject(
"OUTPUT:VARIABLE",
Variable_Name="Zone Ideal Loads Supply Air Total Heating Energy",
Reporting_Frequency="Hourly",
)
self._idf.newidfobject(
"OUTPUT:VARIABLE",
Variable_Name="Zone Ideal Loads Supply Air Total Cooling Energy",
Reporting_Frequency="Hourly",
)
self._idf.match() self._idf.match()
self._idf.saveas(str(self._output_path)) self._idf.intersect_match()
self._idf.saveas(str(self._output_file))
return self._idf
def run(self):
"""
Start the energy plus simulation
"""
self._idf.run(expandobjects=True, readvars=True, output_directory=self._output_path,
output_prefix=f'{self._city.name}_')
def _add_block(self, building): def _add_block(self, building):
_points = self._matrix_to_2d_list(building.foot_print.coordinates) _points = self._matrix_to_2d_list(building.foot_print.coordinates)
@ -267,6 +334,7 @@ class Idf:
self._idf.intersect_match() self._idf.intersect_match()
def _add_surfaces(self, building): def _add_surfaces(self, building):
for thermal_zone in building.thermal_zones: for thermal_zone in building.thermal_zones:
for boundary in thermal_zone.thermal_boundaries: for boundary in thermal_zone.thermal_boundaries:
idf_surface_type = self.idf_surfaces[boundary.surface.type] idf_surface_type = self.idf_surfaces[boundary.surface.type]
@ -274,5 +342,5 @@ class Idf:
surface = self._idf.newidfobject(self._SURFACE, Name=f'{boundary.surface.name}', surface = self._idf.newidfobject(self._SURFACE, Name=f'{boundary.surface.name}',
Surface_Type=idf_surface_type, Zone_Name=usage_zone.id, Surface_Type=idf_surface_type, Zone_Name=usage_zone.id,
Construction_Name=boundary.construction_name) Construction_Name=boundary.construction_name)
coordinates = self._matrix_to_list(boundary.surface.solid_polygon.coordinates) coordinates = self._matrix_to_list(boundary.surface.solid_polygon.coordinates, self._city.lower_corner)
surface.setcoords(coordinates) surface.setcoords(coordinates)

View File

@ -122,8 +122,8 @@
No, !- Do Zone Sizing Calculation No, !- Do Zone Sizing Calculation
No, !- Do System Sizing Calculation No, !- Do System Sizing Calculation
No, !- Do Plant Sizing Calculation No, !- Do Plant Sizing Calculation
Yes, !- Run Simulation for Sizing Periods No, !- Run Simulation for Sizing Periods
No, !- Run Simulation for Weather File Run Periods Yes, !- Run Simulation for Weather File Run Periods
No, !- Do HVAC Sizing Simulation for Sizing Periods No, !- Do HVAC Sizing Simulation for Sizing Periods
1; !- Maximum Number of HVAC Sizing Simulation Passes 1; !- Maximum Number of HVAC Sizing Simulation Passes
@ -149,3 +149,4 @@
Output:Table:SummaryReports, Output:Table:SummaryReports,
AllSummary; !- Report 1 Name AllSummary; !- Report 1 Name
Output:Diagnostics,DisplayUnusedSchedules;

View File

@ -32,6 +32,9 @@ SUNDAY = 'sunday'
HOLIDAY = 'holiday' HOLIDAY = 'holiday'
WINTER_DESIGN_DAY = 'winter_design_day' WINTER_DESIGN_DAY = 'winter_design_day'
SUMMER_DESIGN_DAY = 'summer_design_day' SUMMER_DESIGN_DAY = 'summer_design_day'
WEEK_DAYS = 'Weekdays'
WEEK_ENDS = 'Weekends'
ALL_DAYS = 'Alldays'
# data types # data types
ANY_NUMBER = 'any_number' ANY_NUMBER = 'any_number'
@ -87,3 +90,6 @@ HVAC_AVAILABILITY = 'HVAC Avail'
INFILTRATION = 'Infiltration' INFILTRATION = 'Infiltration'
COOLING_SET_POINT = 'ClgSetPt' COOLING_SET_POINT = 'ClgSetPt'
HEATING_SET_POINT = 'HtgSetPt' HEATING_SET_POINT = 'HtgSetPt'
# todo: are any of these two the receptacle concept??
EQUIPMENT = 'Equipment'
ACTIVITY = 'Activity'

View File

@ -32,7 +32,8 @@ class YearlyFromDailySchedules:
values = [] values = []
for month in range(1, 13): for month in range(1, 13):
for day in range(1, cal.monthlen(self._year, month)+1): _, number_days = cal.monthrange(self._year, month)
for day in range(1, number_days+1):
week_day = cal.weekday(self._year, month, day) week_day = cal.weekday(self._year, month, day)
values.extend(weekly_schedules[week_day]) values.extend(weekly_schedules[week_day])
yearly_schedule.type = self._daily_schedules[0].type yearly_schedule.type = self._daily_schedules[0].type

View File

@ -10,7 +10,8 @@ class NrelLayerArchetype:
NrelLayerArchetype class NrelLayerArchetype class
""" """
def __init__(self, name, solar_absorptance, thermal_absorptance, visible_absorptance, thickness=None, def __init__(self, name, solar_absorptance, thermal_absorptance, visible_absorptance, thickness=None,
conductivity=None, specific_heat=None, density=None, no_mass=False, thermal_resistance=None): conductivity=None, specific_heat=None, density=None, no_mass=False, thermal_resistance=None,
lca_id=None):
self._thickness = thickness self._thickness = thickness
self._conductivity = conductivity self._conductivity = conductivity
self._specific_heat = specific_heat self._specific_heat = specific_heat
@ -21,6 +22,7 @@ class NrelLayerArchetype:
self._no_mass = no_mass self._no_mass = no_mass
self._name = name self._name = name
self._thermal_resistance = thermal_resistance self._thermal_resistance = thermal_resistance
self._lca_id = lca_id
@property @property
def thickness(self): def thickness(self):
@ -101,3 +103,11 @@ class NrelLayerArchetype:
:return: float :return: float
""" """
return self._thermal_resistance return self._thermal_resistance
@property
def lca_id(self):
"""
Get nrel lca_id equivalent for the material
:return: int
"""
return self._lca_id

View File

@ -71,6 +71,7 @@ class NrelPhysicsInterface:
for current_layer in c_lib['layers']['layer']: for current_layer in c_lib['layers']['layer']:
material_lib = self._search_construction_type('material', current_layer['material']) material_lib = self._search_construction_type('material', current_layer['material'])
name = material_lib['@name'] name = material_lib['@name']
lca_id = material_lib['@lca_id']
solar_absorptance = material_lib['solar_absorptance']['#text'] solar_absorptance = material_lib['solar_absorptance']['#text']
thermal_absorptance = material_lib['thermal_absorptance']['#text'] thermal_absorptance = material_lib['thermal_absorptance']['#text']
visible_absorptance = material_lib['visible_absorptance']['#text'] visible_absorptance = material_lib['visible_absorptance']['#text']
@ -81,7 +82,7 @@ class NrelPhysicsInterface:
if units != 'm2 K/W': if units != 'm2 K/W':
raise Exception(f'thermal resistance units = {units}, expected m2 K/W') raise Exception(f'thermal resistance units = {units}, expected m2 K/W')
layer = nla(name, solar_absorptance, thermal_absorptance, visible_absorptance, no_mass=no_mass, layer = nla(name, solar_absorptance, thermal_absorptance, visible_absorptance, no_mass=no_mass,
thermal_resistance=thermal_resistance) thermal_resistance=thermal_resistance, lca_id=lca_id)
else: else:
thickness = current_layer['thickness']['#text'] thickness = current_layer['thickness']['#text']
units = current_layer['thickness']['@units'] units = current_layer['thickness']['@units']
@ -100,7 +101,7 @@ class NrelPhysicsInterface:
if units != 'kg/m3': if units != 'kg/m3':
raise Exception(f'density units = {units}, expected kg/m3') raise Exception(f'density units = {units}, expected kg/m3')
layer = nla(name, solar_absorptance, thermal_absorptance, visible_absorptance, thickness=thickness, layer = nla(name, solar_absorptance, thermal_absorptance, visible_absorptance, thickness=thickness,
conductivity=conductivity, specific_heat=specific_heat, density=density) conductivity=conductivity, specific_heat=specific_heat, density=density, lca_id=lca_id)
layers.append(layer) layers.append(layer)
thermal_opening = None thermal_opening = None

View File

@ -83,6 +83,8 @@ class UsPhysicsParameters(NrelPhysicsInterface):
material.thermal_absorptance = layer_archetype.thermal_absorptance material.thermal_absorptance = layer_archetype.thermal_absorptance
material.visible_absorptance = layer_archetype.visible_absorptance material.visible_absorptance = layer_archetype.visible_absorptance
material.thermal_resistance = layer_archetype.thermal_resistance material.thermal_resistance = layer_archetype.thermal_resistance
if layer_archetype.lca_id is not None:
material.lca_id = layer_archetype.lca_id
layer.material = material layer.material = material
thermal_boundary.layers.append(layer) thermal_boundary.layers.append(layer)
for thermal_opening in thermal_boundary.thermal_openings: for thermal_opening in thermal_boundary.thermal_openings:

View File

@ -1,7 +1,8 @@
""" """
AirSourceHeatPumpParameters import the heat pump information AirSourceHeatPumpParameters import the heat pump information
SPDX - License - Identifier: LGPL - 3.0 - or -later SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2021 Project Author Peter Yefi peteryefi@gmail.com Copyright © 2020 Project Author Peter Yefi peteryefi@gmail.com
Contributor Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
""" """
import pandas as pd import pandas as pd
@ -21,7 +22,7 @@ class AirSourceHeatPumpParameters:
def __init__(self, city, base_path): def __init__(self, city, base_path):
self._city = city self._city = city
self._base_path = (base_path / 'heat_pumps/air_source.xlsx') self._base_path = (base_path / 'heat_pumps/Air source.xlsx')
def _read_file(self) -> Dict: def _read_file(self) -> Dict:
""" """

View File

@ -3,30 +3,29 @@ Rhino module parses rhino files and import the geometry into the city model stru
SPDX - License - Identifier: LGPL - 3.0 - or -later SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
""" """
import numpy as np
from numpy import inf
from rhino3dm import * from rhino3dm import *
from rhino3dm._rhino3dm import MeshType from rhino3dm._rhino3dm import MeshType
import numpy as np
import helpers.configuration_helper
from city_model_structure.attributes.polygon import Polygon from city_model_structure.attributes.polygon import Polygon
from city_model_structure.building import Building from city_model_structure.building import Building
from city_model_structure.city import City
from city_model_structure.building_demand.surface import Surface as LibsSurface from city_model_structure.building_demand.surface import Surface as LibsSurface
from imports.geometry.helpers.geometry_helper import GeometryHelper from city_model_structure.city import City
from helpers.configuration_helper import ConfigurationHelper from helpers.configuration_helper import ConfigurationHelper
from imports.geometry.helpers.geometry_helper import GeometryHelper
class Rhino: class Rhino:
def __init__(self, path): def __init__(self, path):
self._model = File3dm.Read(str(path)) self._model = File3dm.Read(str(path))
max_float = 1.7976931348623157e+308 max_float = float(ConfigurationHelper().max_coordinate)
min_float = -1.7976931348623157e+308 min_float = float(ConfigurationHelper().min_coordinate)
self._min_x = self._min_y = self._min_z = max_float self._min_x = self._min_y = self._min_z = max_float
self._max_x = self._max_y = self._max_z = min_float self._max_x = self._max_y = self._max_z = min_float
print('init')
@staticmethod @staticmethod
def _solid_points(coordinates) -> np.ndarray: def _solid_points(coordinates):
solid_points = np.fromstring(coordinates, dtype=float, sep=' ') solid_points = np.fromstring(coordinates, dtype=float, sep=' ')
solid_points = GeometryHelper.to_points_matrix(solid_points) solid_points = GeometryHelper.to_points_matrix(solid_points)
return solid_points return solid_points
@ -47,29 +46,58 @@ class Rhino:
@property @property
def city(self) -> City: def city(self) -> City:
rhino_objects = []
buildings = [] buildings = []
print('city') windows = []
holes = []
for obj in self._model.Objects: for obj in self._model.Objects:
name = obj.Attributes.Id name = obj.Attributes.Id
surfaces = [] surfaces = []
try:
for face in obj.Geometry.Faces: for face in obj.Geometry.Faces:
if face is None: if face is None:
break break
_mesh = face.GetMesh(MeshType.Default) _mesh = face.GetMesh(MeshType.Default)
polygon_points = None
for i in range(0, len(_mesh.Faces)): for i in range(0, len(_mesh.Faces)):
faces = _mesh.Faces[i] faces = _mesh.Faces[i]
_points = '' _points = ''
for index in faces: for index in faces:
self._lower_corner(_mesh.Vertices[index].X, _mesh.Vertices[index].Y, _mesh.Vertices[index].Z) self._lower_corner(_mesh.Vertices[index].X, _mesh.Vertices[index].Y, _mesh.Vertices[index].Z)
_points = _points + f'{_mesh.Vertices[index].X} {_mesh.Vertices[index].Y} {_mesh.Vertices[index].Z} ' _points = _points + f'{_mesh.Vertices[index].X} {_mesh.Vertices[index].Y} {_mesh.Vertices[index].Z} '
polygon_points = Rhino._solid_points(_points.strip()) polygon_points = Rhino._solid_points(_points.strip())
print(_points)
surfaces.append(LibsSurface(Polygon(polygon_points), Polygon(polygon_points))) surfaces.append(LibsSurface(Polygon(polygon_points), Polygon(polygon_points)))
buildings.append(Building(name, 3, surfaces, 'unknown', 'unknown', (self._min_x, self._min_y, self._min_z), [])) except AttributeError:
continue
rhino_objects.append(Building(name, 3, surfaces, 'unknown', 'unknown', (self._min_x, self._min_y, self._min_z), []))
lower_corner = (self._min_x, self._min_y, self._min_z) lower_corner = (self._min_x, self._min_y, self._min_z)
upper_corner = (self._max_x, self._max_y, self._max_z) upper_corner = (self._max_x, self._max_y, self._max_z)
city = City(lower_corner, upper_corner, 'Montreal') city = City(lower_corner, upper_corner, 'EPSG:26918')
for rhino_object in rhino_objects:
if rhino_object.volume is inf:
# is not a building but a window!
for surface in rhino_object.surfaces:
# add to windows the "hole" with the normal inverted
windows.append(Polygon(surface.perimeter_polygon.inverse))
else:
buildings.append(rhino_object)
# todo: this method will be pretty inefficient
for hole in windows:
corner = hole.coordinates[0]
for building in buildings:
for surface in building.surfaces:
plane = surface.perimeter_polygon.plane
# todo: this is a hack for dompark project it should not be done this way windows should be correctly modeled
# if the distance between the wall plane and the window is less than 2m
# and the window Z coordinate it's between the wall Z, it's a window of that wall
if plane.distance(corner) <= 2:
# check if the window is in the right high.
if surface.upper_corner[2] >= corner[2] >= surface.lower_corner[2]:
if surface.holes_polygons is None:
surface.holes_polygons = []
surface.holes_polygons.append(hole)
for building in buildings: for building in buildings:
city.add_city_object(building) city.add_city_object(building)
return city return city

View File

@ -8,7 +8,6 @@ from city_model_structure.city import City
from imports.geometry.citygml import CityGml from imports.geometry.citygml import CityGml
from imports.geometry.obj import Obj from imports.geometry.obj import Obj
from imports.geometry.osm_subway import OsmSubway from imports.geometry.osm_subway import OsmSubway
#from imports.geometry.rhino import Rhino
class GeometryFactory: class GeometryFactory:
@ -43,13 +42,13 @@ class GeometryFactory:
""" """
return OsmSubway(self._path).city return OsmSubway(self._path).city
# @property @property
# def _rhino(self) -> City: def _rhino(self) -> City:
# """ """
# Enrich the city by using OpenStreetMap information as data source Enrich the city by using OpenStreetMap information as data source
# :return: City :return: City
# """ """
# return Rhino(self._path).city return Rhino(self._path).city
@property @property
def city(self) -> City: def city(self) -> City:
@ -59,10 +58,10 @@ class GeometryFactory:
""" """
return getattr(self, self._file_type, lambda: None) return getattr(self, self._file_type, lambda: None)
# @property @property
# def city_debug(self) -> City: def city_debug(self) -> City:
# """ """
# Enrich the city given to the class using the class given handler Enrich the city given to the class using the class given handler
# :return: City :return: City
# """ """
# return Rhino(self._path).city return Rhino(self._path).city

View File

@ -1,7 +1,8 @@
""" """
CityGml module parses citygml_classes files and import the geometry into the city model structure CityGml module parses citygml_classes files and import the geometry into the city model structure
SPDX - License - Identifier: LGPL - 3.0 - or -later SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Atiya Copyright © 2020 Project Author Atiya atiya.atiya@mail.concordia.ca
Contributor Mohammad Reza mohammad.seyedabadi@mail.concordia.ca
""" """
import xmltodict import xmltodict
from pathlib import Path from pathlib import Path
@ -19,6 +20,6 @@ class LcaFuel:
with open(path) as xml: with open(path) as xml:
self._lca = xmltodict.parse(xml.read()) self._lca = xmltodict.parse(xml.read())
for fuel in self._lca["library"]["Fuels"]['fuel']: for fuel in self._lca["library"]["fuels"]['fuel']:
self._city.fuels.append(Fuel(fuel['@id'], fuel['@name'], fuel['carbon_emission_factor']['#text'], self._city.fuels.append(Fuel(fuel['@id'], fuel['@name'], fuel['carbon_emission_factor']['#text'],
fuel['carbon_emission_factor']['@unit'])) fuel['carbon_emission_factor']['@unit']))

View File

@ -1,12 +1,14 @@
""" """
CityGml module parses citygml_classes files and import the geometry into the city model structure CityGml module parses citygml_classes files and import the geometry into the city model structure
SPDX - License - Identifier: LGPL - 3.0 - or -later SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Atiya Copyright © 2020 Project Author Atiya atiya.atiya@mail.concordia.ca
Contributor Mohammad Reza mohammad.seyedabadi@mail.concordia.ca
""" """
import xmltodict import xmltodict
from pathlib import Path from pathlib import Path
from city_model_structure.machine import Machine from city_model_structure.machine import Machine
class LcaMachine: class LcaMachine:
def __init__(self, city, base_path): def __init__(self, city, base_path):
self._city = city self._city = city
@ -15,12 +17,15 @@ class LcaMachine:
def enrich(self): def enrich(self):
self._city.machines = [] self._city.machines = []
# print(self._base_path)
path = Path(self._base_path / 'lca_data.xml').resolve() path = Path(self._base_path / 'lca_data.xml').resolve()
with open(path) as xml: with open(path) as xml:
self._lca = xmltodict.parse(xml.read()) self._lca = xmltodict.parse(xml.read())
for machine in self._lca["library"]["Machines"]['machine']: for machine in self._lca["library"]["machines"]['machine']:
self._city.machines.append(Machine(machine['@id'], machine['@name'], machine['work_efficiency']['#text'], self._city.machines.append(Machine(machine['@id'], machine['@name'], machine['work_efficiency']['#text'],
machine['work_efficiency']['@unit'], machine['energy_consumption_rate']['#text'], machine['work_efficiency']['@unit'],
machine['energy_consumption_rate']['@unit'], machine['carbon_emission_factor']['#text'], machine['energy_consumption_rate']['#text'],
machine['energy_consumption_rate']['@unit'],
machine['carbon_emission_factor']['#text'],
machine['carbon_emission_factor']['@unit'])) machine['carbon_emission_factor']['@unit']))

View File

@ -0,0 +1,41 @@
"""
CityGml module parses citygml_classes files and import the geometry into the city model structure
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Atiya atiya.atiya@mail.concordia.ca
Contributor Mohammad Reza mohammad.seyedabadi@mail.concordia.ca
"""
import xmltodict
from pathlib import Path
from city_model_structure.building_demand.material import Material
from city_model_structure.lca_material import LcaMaterial as LcaMat
class LcaMaterial:
def __init__(self, city, base_path):
self._city = city
self._base_path = base_path
self._lca = None
def enrich(self):
self._city.lca_materials = []
path = Path(self._base_path / 'lca_data.xml').resolve()
with open(path) as xml:
self._lca = xmltodict.parse(xml.read())
for material in self._lca["library"]["building_materials"]['material']:
_lca_material = LcaMat()
_lca_material.type = material['@type']
_lca_material.id = material['@id']
_lca_material.name = material['@name']
_lca_material.density = material['density']['#text']
_lca_material.density_unit = material['density']['@unit']
_lca_material.embodied_carbon = material['embodied_carbon']['#text']
_lca_material.embodied_carbon_unit = material['embodied_carbon']['@unit']
_lca_material.recycling_ratio = material['recycling_ratio']
_lca_material.onsite_recycling_ratio = material['onsite_recycling_ratio']
_lca_material.company_recycling_ratio = material['company_recycling_ratio']
_lca_material.landfilling_ratio = material['landfilling_ratio']
_lca_material.cost = 10 # todo: change this into material['cost']['#text']
_lca_material._cost_unit = material['cost']['@unit']
self._city.lca_materials.append(_lca_material)

View File

@ -1,12 +1,14 @@
""" """
CityGml module parses citygml_classes files and import the geometry into the city model structure CityGml module parses citygml_classes files and import the geometry into the city model structure
SPDX - License - Identifier: LGPL - 3.0 - or -later SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Atiya Copyright © 2020 Project Author Atiya atiya.atiya@mail.concordia.ca
Contributor Mohammad Reza mohammad.seyedabadi@mail.concordia.ca
""" """
import xmltodict import xmltodict
from pathlib import Path from pathlib import Path
from city_model_structure.vehicle import Vehicle from city_model_structure.vehicle import Vehicle
class LcaVehicle: class LcaVehicle:
def __init__(self, city, base_path): def __init__(self, city, base_path):
self._city = city self._city = city
@ -19,7 +21,8 @@ class LcaVehicle:
with open(path) as xml: with open(path) as xml:
self._lca = xmltodict.parse(xml.read()) self._lca = xmltodict.parse(xml.read())
for vehicle in self._lca["library"]["Vehicles"]['vehicle']: for vehicle in self._lca["library"]["vehicles"]['vehicle']:
self._city.vehicles.append(Vehicle(vehicle['@id'], vehicle['@name'], vehicle['fuel_consumption_rate']['#text'], self._city.vehicles.append(Vehicle(vehicle['@id'], vehicle['@name'], vehicle['fuel_consumption_rate']['#text'],
vehicle['fuel_consumption_rate']['@unit'], vehicle['carbon_emission_factor']['#text'], vehicle['fuel_consumption_rate']['@unit'],
vehicle['carbon_emission_factor']['#text'],
vehicle['carbon_emission_factor']['@unit'])) vehicle['carbon_emission_factor']['@unit']))

View File

@ -1,14 +1,15 @@
""" """
ConstructionFactory (before PhysicsFactory) retrieve the specific construction module for the given region ConstructionFactory (before PhysicsFactory) retrieve the specific construction module for the given region
SPDX - License - Identifier: LGPL - 3.0 - or -later SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Atiya Copyright © 2020 Project Author Atiya atiya.atiya@mail.concordia.ca
Contributor Mohammad Reza mohammad.seyedabadi@mail.concordia.ca
""" """
from pathlib import Path from pathlib import Path
from imports.life_cycle_assessment.lca_fuel import LcaFuel from imports.life_cycle_assessment.lca_fuel import LcaFuel
from imports.life_cycle_assessment.lca_vehicle import LcaVehicle from imports.life_cycle_assessment.lca_vehicle import LcaVehicle
from imports.life_cycle_assessment.lca_machine import LcaMachine from imports.life_cycle_assessment.lca_machine import LcaMachine
# from imports.life_cycle_assessment.lca_material import LcaMaterial from imports.life_cycle_assessment.lca_material import LcaMaterial
class LifeCycleAssessment: class LifeCycleAssessment:

View File

@ -1,26 +1,43 @@
""" """
MyClass module Building test
SPDX - License - Identifier: LGPL - 3.0 - or -later SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Copyright © 2022 Project Author Guille Gutierrez Morote Guillermo.GutierrezMorote@concordia.ca
Contributor Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
""" """
import pandas as pd import pandas as pd
import parseidf import parseidf
import xmltodict import xmltodict
from imports.schedules.helpers.schedules_helper import SchedulesHelper from imports.schedules.helpers.schedules_helper import SchedulesHelper
from city_model_structure.attributes.schedule import Schedule
import helpers.constants as cte
class DoeIdf: class DoeIdf:
""" """
Idf factory to import schedules into the data model Idf factory to import schedules into the data model
""" """
idf_schedule_to_comnet_schedule = {'BLDG_LIGHT_SCH': 'Lights', # todo: shouldn't this be in the schedule helper class????
'BLDG_OCC_SCH_wo_SB': 'Occupancy', idf_schedule_to_standard_schedule = {'BLDG_LIGHT_SCH': cte.LIGHTING,
'BLDG_EQUIP_SCH': 'Equipment', 'BLDG_OCC_SCH_wo_SB': cte.OCCUPANCY,
'ACTIVITY_SCH': 'Activity', 'BLDG_EQUIP_SCH': cte.EQUIPMENT,
'INFIL_QUARTER_ON_SCH': 'Infiltration'} 'ACTIVITY_SCH': cte.ACTIVITY,
'INFIL_QUARTER_ON_SCH': cte.INFILTRATION}
# todo: @Guille -> in idf the types can be written in capital letters or low case, but both should be accepted.
# How is that solved?? Of course not like this
idf_data_type_to_standard_data_type = {'Fraction': cte.FRACTION,
'fraction': cte.FRACTION,
'Any Number': cte.ANY_NUMBER,
'ON/OFF': cte.ON_OFF,
'On/Off': cte.ON_OFF,
'Temperature': cte.TEMPERATURE,
'Humidity': cte.HUMIDITY,
'Control Type': cte.CONTROL_TYPE}
_SCHEDULE_COMPACT_TYPE = 'SCHEDULE:COMPACT' _SCHEDULE_COMPACT_TYPE = 'SCHEDULE:COMPACT'
_SCHEDULE_TYPE_NAME = 1 _SCHEDULE_TYPE_NAME = 1
_SCHEDULE_TYPE_DATA_TYPE = 2
def __init__(self, city, base_path, doe_idf_file): def __init__(self, city, base_path, doe_idf_file):
self._hours = [] self._hours = []
@ -47,11 +64,17 @@ class DoeIdf:
def _load_schedule(self, idf, usage_zone): def _load_schedule(self, idf, usage_zone):
schedules_day = {} schedules_day = {}
schedules = []
for compact_schedule in idf[self._SCHEDULE_COMPACT_TYPE]: for compact_schedule in idf[self._SCHEDULE_COMPACT_TYPE]:
if compact_schedule[self._SCHEDULE_TYPE_NAME] in self.idf_schedule_to_comnet_schedule: schedule = Schedule()
schedule_type = self.idf_schedule_to_comnet_schedule[compact_schedule[self._SCHEDULE_TYPE_NAME]] schedule.time_step = cte.HOUR
schedule.time_range = cte.DAY
if compact_schedule[self._SCHEDULE_TYPE_NAME] in self.idf_schedule_to_standard_schedule:
schedule.type = self.idf_schedule_to_standard_schedule[compact_schedule[self._SCHEDULE_TYPE_NAME]]
schedule.data_type = self.idf_data_type_to_standard_data_type[compact_schedule[self._SCHEDULE_TYPE_DATA_TYPE]]
else: else:
continue continue
days_index = [] days_index = []
days_schedules = [] days_schedules = []
for position, elements in enumerate(compact_schedule): for position, elements in enumerate(compact_schedule):
@ -61,13 +84,9 @@ class DoeIdf:
# store a cleaned version of the compact schedule # store a cleaned version of the compact schedule
days_schedules.append(element_title) days_schedules.append(element_title)
days_index.append(len(days_schedules)) days_index.append(len(days_schedules))
# create panda
data = {'WD': [], 'Sat': [], 'Sun': []} # save schedule
rows = [] values = []
for j in range(1, 13):
rows.append(f'{j}am')
for j in range(1, 13):
rows.append(f'{j}pm')
for i, day_index in enumerate(days_index): for i, day_index in enumerate(days_index):
if day_index == len(days_schedules): if day_index == len(days_schedules):
break break
@ -85,40 +104,31 @@ class DoeIdf:
entry = days_schedules[hours_values + 1] entry = days_schedules[hours_values + 1]
schedules_day[f'{days_schedules[day_index]}'].append(entry) schedules_day[f'{days_schedules[day_index]}'].append(entry)
if 'Weekdays' in days_schedules[day_index]:
data['WD'] = []
for entry in schedules_day[f'{days_schedules[day_index]}']: for entry in schedules_day[f'{days_schedules[day_index]}']:
data['WD'].append(entry) values.append(entry)
print(values)
schedule.values = values
if 'Weekdays' in days_schedules[day_index]:
schedule.day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY]
elif 'Alldays' in days_schedules[day_index]: elif 'Alldays' in days_schedules[day_index]:
data['WD'] = [] schedule.day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY, cte.SATURDAY,
data['Sat'] = [] cte.SUNDAY]
data['Sun'] = []
for entry in schedules_day[f'{days_schedules[day_index]}']:
data['WD'].append(entry)
data['Sat'].append(entry)
data['Sun'].append(entry)
elif 'Weekends' in days_schedules[day_index]: elif 'Weekends' in days_schedules[day_index]:
# Weekends schedule present so let's re set the values # Weekends schedule present so let's re set the values
data['Sat'] = [] schedule.day_types = [cte.SATURDAY, cte.SUNDAY]
data['Sun'] = []
for entry in schedules_day[f'{days_schedules[day_index]}']:
data['Sat'].append(entry)
data['Sun'].append(entry)
elif 'Saturday' in days_schedules[day_index]: elif 'Saturday' in days_schedules[day_index]:
data['Sat'] = [] schedule.day_types = [cte.SATURDAY]
for entry in schedules_day[f'{days_schedules[day_index]}']:
data['Sat'].append(entry)
elif 'Sunday' in days_schedules[day_index]: elif 'Sunday' in days_schedules[day_index]:
data['Sun'] = [] schedule.day_types = [cte.SUNDAY]
for entry in schedules_day[f'{days_schedules[day_index]}']:
data['Sun'].append(entry)
else: else:
continue continue
df = pd.DataFrame(data, index=rows) schedules.append(schedule)
if usage_zone.schedules is None:
usage_zone.schedules = {} usage_zone.schedules = schedules
usage_zone.schedules[schedule_type] = df

View File

@ -5,7 +5,6 @@ Copyright © 2021 Project Author Guille Gutierrez guillermo.gutierrezmorote@conc
""" """
import pandas as pd import pandas as pd
from imports.sensors.concordia_file_report import ConcordiaFileReport from imports.sensors.concordia_file_report import ConcordiaFileReport
from city_model_structure.iot.concordia_energy_sensor import ConcordiaEnergySensor
class ConcordiaEnergyConsumption(ConcordiaFileReport): class ConcordiaEnergyConsumption(ConcordiaFileReport):
@ -23,6 +22,9 @@ class ConcordiaEnergyConsumption(ConcordiaFileReport):
building_measures = [self._measures["Date time"], self._measures[self._sensor_point[self._sensors[i]]]] building_measures = [self._measures["Date time"], self._measures[self._sensor_point[self._sensors[i]]]]
building_headers = ["Date time", "Energy consumption"] building_headers = ["Date time", "Energy consumption"]
building_energy_consumption = pd.concat(building_measures, keys=building_headers, axis=1) building_energy_consumption = pd.concat(building_measures, keys=building_headers, axis=1)
print(building_energy_consumption)
"""
sensor = ConcordiaEnergySensor(self._sensors[i]) sensor = ConcordiaEnergySensor(self._sensors[i])
sensor_exist = False sensor_exist = False
for j in range(len(obj.sensors)): for j in range(len(obj.sensors)):
@ -33,3 +35,4 @@ class ConcordiaEnergyConsumption(ConcordiaFileReport):
if not sensor_exist: if not sensor_exist:
sensor.add_period(building_energy_consumption) sensor.add_period(building_energy_consumption)
obj.sensors.append(sensor) obj.sensors.append(sensor)
"""

View File

@ -5,7 +5,7 @@ Copyright © 2021 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.mons
""" """
import pandas as pd import pandas as pd
from imports.sensors.concordia_file_report import ConcordiaFileReport from imports.sensors.concordia_file_report import ConcordiaFileReport
from city_model_structure.iot.concordia_gas_flow_sensor import ConcordiaGasFlowSensor
class ConcordiaGasFlow(ConcordiaFileReport): class ConcordiaGasFlow(ConcordiaFileReport):
@ -24,6 +24,7 @@ class ConcordiaGasFlow(ConcordiaFileReport):
building_measures = [self._measures["Date time"], self._measures[self._sensor_point[self._sensors[i]]]] building_measures = [self._measures["Date time"], self._measures[self._sensor_point[self._sensors[i]]]]
building_headers = ["Date time", "Gas Flow Cumulative Monthly"] building_headers = ["Date time", "Gas Flow Cumulative Monthly"]
building_energy_consumption = pd.concat(building_measures, keys=building_headers, axis=1) building_energy_consumption = pd.concat(building_measures, keys=building_headers, axis=1)
"""
sensor = ConcordiaGasFlowSensor(self._sensors[i]) sensor = ConcordiaGasFlowSensor(self._sensors[i])
sensor_exist = False sensor_exist = False
for j in range(len(obj.sensors)): for j in range(len(obj.sensors)):
@ -34,3 +35,4 @@ class ConcordiaGasFlow(ConcordiaFileReport):
if not sensor_exist: if not sensor_exist:
sensor.add_period(building_energy_consumption) sensor.add_period(building_energy_consumption)
obj.sensors.append(sensor) obj.sensors.append(sensor)
"""

View File

@ -5,7 +5,6 @@ Copyright © 2021 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.mons
""" """
import pandas as pd import pandas as pd
from imports.sensors.concordia_file_report import ConcordiaFileReport from imports.sensors.concordia_file_report import ConcordiaFileReport
from city_model_structure.iot.concordia_temperature_sensor import ConcordiaTemperatureSensor
class ConcordiaTemperature(ConcordiaFileReport): class ConcordiaTemperature(ConcordiaFileReport):
@ -23,6 +22,7 @@ class ConcordiaTemperature(ConcordiaFileReport):
building_measures = [self._measures["Date time"], self._measures[self._sensor_point[self._sensors[i]]]] building_measures = [self._measures["Date time"], self._measures[self._sensor_point[self._sensors[i]]]]
building_headers = ["Date time", "Temperature"] building_headers = ["Date time", "Temperature"]
building_energy_consumption = pd.concat(building_measures, keys=building_headers, axis=1) building_energy_consumption = pd.concat(building_measures, keys=building_headers, axis=1)
"""
sensor = ConcordiaTemperatureSensor(self._sensors[i]) sensor = ConcordiaTemperatureSensor(self._sensors[i])
sensor_exist = False sensor_exist = False
for j in range(len(obj.sensors)): for j in range(len(obj.sensors)):
@ -33,3 +33,4 @@ class ConcordiaTemperature(ConcordiaFileReport):
if not sensor_exist: if not sensor_exist:
sensor.add_period(building_energy_consumption) sensor.add_period(building_energy_consumption)
obj.sensors.append(sensor) obj.sensors.append(sensor)
"""

View File

@ -9,9 +9,12 @@ geomeppy~=0.11.8
pathlib~=1.0.1 pathlib~=1.0.1
PyWavefront~=1.3.3 PyWavefront~=1.3.3
xlrd~=2.0.1 xlrd~=2.0.1
openpyxl~=3.0.7
networkx~=2.5.1 networkx~=2.5.1
parseidf~=1.0.0 parseidf~=1.0.0
ply~=3.11 ply~=3.11
rhino3dm~=7.11.1
scipy==1.7.1 scipy==1.7.1
PyYAML==6.0 PyYAML==6.0
rhino3dm~=7.7.0 yaml~=0.2.5
pyecore~=0.12.2

View File

@ -9,7 +9,7 @@ from unittest import TestCase
from imports.geometry_factory import GeometryFactory from imports.geometry_factory import GeometryFactory
from imports.construction_factory import ConstructionFactory from imports.construction_factory import ConstructionFactory
from imports.geometry.helpers.geometry_helper import GeometryHelper from imports.geometry.helpers.geometry_helper import GeometryHelper
from imports.life_cycle_assessment_factory import LifeCycleAssessment
class TestConstructionFactory(TestCase): class TestConstructionFactory(TestCase):
""" """
@ -28,6 +28,7 @@ class TestConstructionFactory(TestCase):
file = 'pluto_building.gml' file = 'pluto_building.gml'
file_path = (self._example_path / file).resolve() file_path = (self._example_path / file).resolve()
self._city = GeometryFactory('citygml', file_path).city self._city = GeometryFactory('citygml', file_path).city
LifeCycleAssessment('material', self._city).enrich()
self.assertIsNotNone(self._city, 'city is none') self.assertIsNotNone(self._city, 'city is none')
return self._city return self._city
@ -60,7 +61,8 @@ class TestConstructionFactory(TestCase):
if thermal_boundary.surface.type != 'Ground': if thermal_boundary.surface.type != 'Ground':
self.assertIsNotNone(thermal_boundary.outside_solar_absorptance, 'outside_solar_absorptance is none') self.assertIsNotNone(thermal_boundary.outside_solar_absorptance, 'outside_solar_absorptance is none')
self.assertIsNotNone(thermal_boundary.window_ratio, 'window_ratio is none') self.assertIsNotNone(thermal_boundary.window_ratio, 'window_ratio is none')
print(thermal_boundary.layers) for layer in thermal_boundary.layers:
self.assertTrue(city.lca_material(layer.material.lca_id) is not None)
def test_city_with_construction_reduced_library(self): def test_city_with_construction_reduced_library(self):
""" """

View File

@ -36,6 +36,13 @@ class TestBuildings(TestCase):
for building in city.buildings: for building in city.buildings:
self.assertTrue(len(building.usage_zones) > 0) self.assertTrue(len(building.usage_zones) > 0)
for usage_zone in building.usage_zones: for usage_zone in building.usage_zones:
self.assertTrue('Lights' in usage_zone.schedules) self.assertIsNot(len(usage_zone.schedules), 0, 'no usage_zones schedules defined')
for schedule in usage_zone.schedules:
self.assertIsNotNone(schedule.type)
self.assertIsNotNone(schedule.values)
self.assertIsNotNone(schedule.data_type)
self.assertIsNotNone(schedule.time_step)
self.assertIsNotNone(schedule.time_range)
self.assertIsNotNone(schedule.day_types)

View File

@ -0,0 +1,37 @@
"""
TestGeometryFactory test and validate the city model structure geometric parameters
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
"""
from unittest import TestCase
from catalogs.greenery_catalog_factory import GreeneryCatalogFactory
class TestGreeneryCatalog(TestCase):
def test_catalog(self):
catalog = GreeneryCatalogFactory('nrel').catalog_debug
catalog_categories = catalog.names()
vegetations = catalog.names('vegetations')
plants = catalog.names('plants')
soils = catalog.names('soils')
self.assertTrue(len(catalog_categories) == 3)
self.assertTrue(len(vegetations['vegetations']) == 4)
self.assertTrue(len(plants['plants']) == 14)
self.assertTrue(len(soils['soils']) == 6)
with self.assertRaises(ValueError):
catalog.names('unknown')
# retrieving all the entries should not raise any exceptions
for category in catalog_categories:
for value in catalog_categories[category]:
catalog.get_entry(value)
with self.assertRaises(IndexError):
catalog.get_entry('unknown')
self.assertTrue(len(catalog.entries().vegetations) == 4)
self.assertTrue(len(catalog.entries().plants) == 14)
self.assertTrue(len(catalog.entries().soils) == 6)

View File

@ -1,7 +1,8 @@
""" """
Building test Building test
SPDX - License - Identifier: LGPL - 3.0 - or -later SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Guille Gutierrez Morote Guillermo.GutierrezMorote@concordia.ca Copyright © 2020 Project Author Atiya atiya.atiya@mail.concordia.ca
Contributor Mohammad Reza mohammad.seyedabadi@mail.concordia.ca
""" """
from pathlib import Path from pathlib import Path
from unittest import TestCase from unittest import TestCase
@ -26,7 +27,6 @@ class TestLifeCycleAssessment(TestCase):
city = GeometryFactory('citygml', city_file).city city = GeometryFactory('citygml', city_file).city
LifeCycleAssessment('fuel', city).enrich() LifeCycleAssessment('fuel', city).enrich()
for fuel in city.fuels: for fuel in city.fuels:
# print(fuel.name)
self.assertTrue(len(city.fuels) > 0) self.assertTrue(len(city.fuels) > 0)
def test_vehicle(self): def test_vehicle(self):
@ -34,7 +34,6 @@ class TestLifeCycleAssessment(TestCase):
city = GeometryFactory('citygml', city_file).city city = GeometryFactory('citygml', city_file).city
LifeCycleAssessment('vehicle', city).enrich() LifeCycleAssessment('vehicle', city).enrich()
for vehicle in city.vehicles: for vehicle in city.vehicles:
# print(vehicle.name)
self.assertTrue(len(city.vehicles) > 0) self.assertTrue(len(city.vehicles) > 0)
def test_machine(self): def test_machine(self):
@ -42,16 +41,16 @@ class TestLifeCycleAssessment(TestCase):
city = GeometryFactory('citygml', city_file).city city = GeometryFactory('citygml', city_file).city
LifeCycleAssessment('machine', city).enrich() LifeCycleAssessment('machine', city).enrich()
for machine in city.machines: for machine in city.machines:
# print(machine.name)
self.assertTrue(len(city.machines) > 0) self.assertTrue(len(city.machines) > 0)
def test_material(self): def test_material(self):
city_file = "../unittests/tests_data/C40_Final.gml" city_file = "../unittests/tests_data/C40_Final.gml"
city = GeometryFactory('citygml', city_file).city city = GeometryFactory('citygml', city_file).city
LifeCycleAssessment('material', city).enrich() LifeCycleAssessment('material', city).enrich()
for material in city.materials: self.assertTrue(len(city.lca_materials) > 0)
print(material.material_name) for lca_material in city.lca_materials:
self.assertTrue(len(city.materials) > 0) lca_mat = city.lca_material(lca_material.id)
self.assertTrue(lca_mat is not None)

View File

@ -67,4 +67,3 @@ class TestSchedulesFactory(TestCase):
for usage_zone in building.usage_zones: for usage_zone in building.usage_zones:
for schedule in usage_zone.schedules: for schedule in usage_zone.schedules:
print(schedule) print(schedule)
print(usage_zone.schedules[schedule])

View File

@ -50,8 +50,8 @@ class TestSensorsFactory(TestCase):
Load concordia sensors and verify it Load concordia sensors and verify it
""" """
SensorsFactory('cec', self._city, self._end_point).enrich() SensorsFactory('cec', self._city, self._end_point).enrich()
SensorsFactory('cgf', self._city, self._end_point).enrich() # SensorsFactory('cgf', self._city, self._end_point).enrich()
SensorsFactory('ct', self._city, self._end_point).enrich() # SensorsFactory('ct', self._city, self._end_point).enrich()
for city_object in self._city.city_objects: for city_object in self._city.city_objects:
print(city_object.name, len(city_object.sensors)) print(city_object.name, len(city_object.sensors))
for sensor in city_object.sensors: for sensor in city_object.sensors:

View File

@ -7,7 +7,9 @@ from pathlib import Path
from unittest import TestCase from unittest import TestCase
from imports.geometry_factory import GeometryFactory from imports.geometry_factory import GeometryFactory
from imports.construction_factory import ConstructionFactory
from imports.usage_factory import UsageFactory from imports.usage_factory import UsageFactory
from imports.construction_factory import ConstructionFactory
from imports.geometry.helpers.geometry_helper import GeometryHelper from imports.geometry.helpers.geometry_helper import GeometryHelper
from imports.construction_factory import ConstructionFactory from imports.construction_factory import ConstructionFactory
@ -29,6 +31,15 @@ class TestUsageFactory(TestCase):
self.assertIsNotNone(_city, 'city is none') self.assertIsNotNone(_city, 'city is none')
return _city return _city
def test_comnet(self):
file = 'pluto_building.gml'
city = self._get_citygml(file)
for building in city.buildings:
building.function = GeometryHelper.pluto_to_function[building.function]
ConstructionFactory('nrel', city).enrich()
UsageFactory('comnet', city).enrich()
def test_city_with_usage(self): def test_city_with_usage(self):
""" """
Enrich the city with the usage information and verify it Enrich the city with the usage information and verify it

View File

@ -14,8 +14,8 @@
<gen:stringAttribute name="gross_floor_raea_unit"> <gen:stringAttribute name="gross_floor_raea_unit">
<gen:value>m2</gen:value> <gen:value>m2</gen:value>
</gen:stringAttribute> </gen:stringAttribute>
<bldg:function>1010</bldg:function>
<bldg:yearOfConstruction>1996</bldg:yearOfConstruction> <bldg:yearOfConstruction>1996</bldg:yearOfConstruction>
<bldg:function>residential</bldg:function>
<bldg:measuredHeight>5.3</bldg:measuredHeight> <bldg:measuredHeight>5.3</bldg:measuredHeight>
<bldg:storeysAboveGround>1</bldg:storeysAboveGround> <bldg:storeysAboveGround>1</bldg:storeysAboveGround>
<bldg:lod2Solid> <bldg:lod2Solid>