Merge branch 'internal_zones' into 'master'
complete modification of the structure of the classes that define the buildig... See merge request Guille/libs!7
This commit is contained in:
commit
91ddbb9341
|
@ -1,268 +0,0 @@
|
|||
<?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 "VeryRough", "Rough", "MediumRough", "MediumSmooth", "Smooth", and "VerySmooth" 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.
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).
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.
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.
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).
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).
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.
This parameter is used when calculating the long wavelength radiant exchange at the leaf surfaces.
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.
Plants with low values of stomatal resistance will result in higher evapotranspiration rates than plants with high resistance.
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>
|
|
@ -1,318 +0,0 @@
|
|||
"""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
|
|
@ -1,268 +0,0 @@
|
|||
<?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 "VeryRough", "Rough", "MediumRough", "MediumSmooth", "Smooth", and "VerySmooth" 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.
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).
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.
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.
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).
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).
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.
This parameter is used when calculating the long wavelength radiant exchange at the leaf surfaces.
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.
Plants with low values of stomatal resistance will result in higher evapotranspiration rates than plants with high resistance.
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>
|
|
@ -16,6 +16,7 @@ from city_model_structure.attributes.plane import Plane
|
|||
from city_model_structure.attributes.point import Point
|
||||
import helpers.constants as cte
|
||||
|
||||
|
||||
class Polygon:
|
||||
"""
|
||||
Polygon class
|
||||
|
@ -78,6 +79,48 @@ class Polygon:
|
|||
z = vector_0[2] * vector_1[2]
|
||||
return x+y+z
|
||||
|
||||
def contains_point(self, point):
|
||||
"""
|
||||
Determines if the given point is contained by the current polygon
|
||||
:return: boolean
|
||||
"""
|
||||
# fixme: This method doesn't seems to work.
|
||||
n = len(self.vertices)
|
||||
angle_sum = 0
|
||||
for i in range(0, n):
|
||||
vector_0 = self.vertices[i]
|
||||
vector_1 = self.vertices[(i+1) % n]
|
||||
# set to origin
|
||||
vector_0[0] = vector_0[0] - point.coordinates[0]
|
||||
vector_0[1] = vector_0[1] - point.coordinates[1]
|
||||
vector_0[2] = vector_0[2] - point.coordinates[2]
|
||||
vector_1[0] = vector_1[0] - point.coordinates[0]
|
||||
vector_1[1] = vector_1[1] - point.coordinates[1]
|
||||
vector_1[2] = vector_1[2] - point.coordinates[2]
|
||||
module = Polygon._module(vector_0) * Polygon._module(vector_1)
|
||||
|
||||
scalar_product = Polygon._scalar_product(vector_0, vector_1)
|
||||
angle = np.pi/2
|
||||
if module != 0:
|
||||
angle = abs(np.arcsin(scalar_product / module))
|
||||
angle_sum += angle
|
||||
print(angle_sum)
|
||||
return abs(angle_sum - math.pi*2) < cte.EPSILON
|
||||
|
||||
def contains_polygon(self, polygon):
|
||||
"""
|
||||
Determines if the given polygon is contained by the current polygon
|
||||
:return: boolean
|
||||
"""
|
||||
print('contains')
|
||||
for point in polygon.points:
|
||||
print(point.coordinates, self.contains_point(point))
|
||||
|
||||
if not self.contains_point(point):
|
||||
return False
|
||||
print('Belong!')
|
||||
return True
|
||||
|
||||
@property
|
||||
def points_list(self) -> np.ndarray:
|
||||
"""
|
||||
|
@ -249,7 +292,7 @@ class Polygon:
|
|||
points_list = self.points_list
|
||||
normal = self.normal
|
||||
if np.linalg.norm(normal) == 0:
|
||||
sys.stderr.write(f'Not able to triangulate polygon [normal length is 0]')
|
||||
sys.stderr.write('Not able to triangulate polygon\n')
|
||||
return [self]
|
||||
# are points concave or convex?
|
||||
total_points_list, concave_points, convex_points = self._starting_lists(points_list, normal)
|
||||
|
@ -297,10 +340,10 @@ class Polygon:
|
|||
continue
|
||||
break
|
||||
if len(total_points_list) <= 3 and len(convex_points) > 0:
|
||||
sys.stderr.write('Not able to triangulate polygon [convex surface]\n')
|
||||
sys.stderr.write('Not able to triangulate polygon\n')
|
||||
return [self]
|
||||
if j >= 100:
|
||||
sys.stderr.write('Not able to triangulate polygon [infinite loop]\n')
|
||||
sys.stderr.write('Not able to triangulate polygon\n')
|
||||
return [self]
|
||||
last_ear = self._triangle(points_list, total_points_list, concave_points[1])
|
||||
ears.append(last_ear)
|
||||
|
|
|
@ -114,7 +114,7 @@ class Polyhedron:
|
|||
if self._trimesh is None:
|
||||
for face in self.faces:
|
||||
if len(face) != 3:
|
||||
sys.stderr.write(f'Not able to generate trimesh the face has {len(face)} vertices\n')
|
||||
sys.stderr.write('Not able to generate trimesh\n')
|
||||
return None
|
||||
self._trimesh = Trimesh(vertices=self.vertices, faces=self.faces)
|
||||
return self._trimesh
|
||||
|
|
|
@ -9,131 +9,131 @@ from typing import Union, List
|
|||
|
||||
|
||||
class Schedule:
|
||||
"""
|
||||
"""
|
||||
Schedule class
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self._id = None
|
||||
self._type = None
|
||||
self._values = None
|
||||
self._data_type = None
|
||||
self._time_step = None
|
||||
self._time_range = None
|
||||
self._day_types = None
|
||||
def __init__(self):
|
||||
self._id = None
|
||||
self._type = None
|
||||
self._values = None
|
||||
self._data_type = None
|
||||
self._time_step = None
|
||||
self._time_range = None
|
||||
self._day_types = None
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
"""
|
||||
@property
|
||||
def id(self):
|
||||
"""
|
||||
Get schedule id, an universally unique identifier randomly generated
|
||||
:return: str
|
||||
"""
|
||||
if self._id is None:
|
||||
self._id = uuid.uuid4()
|
||||
return self._id
|
||||
if self._id is None:
|
||||
self._id = uuid.uuid4()
|
||||
return self._id
|
||||
|
||||
@property
|
||||
def type(self) -> Union[None, str]:
|
||||
"""
|
||||
@property
|
||||
def type(self) -> Union[None, str]:
|
||||
"""
|
||||
Get schedule type
|
||||
:return: None or str
|
||||
"""
|
||||
return self._type
|
||||
return self._type
|
||||
|
||||
@type.setter
|
||||
def type(self, value):
|
||||
"""
|
||||
@type.setter
|
||||
def type(self, value):
|
||||
"""
|
||||
Set schedule type
|
||||
:param: str
|
||||
"""
|
||||
if value is not None:
|
||||
self._type = str(value)
|
||||
if value is not None:
|
||||
self._type = str(value)
|
||||
|
||||
@property
|
||||
def values(self):
|
||||
"""
|
||||
@property
|
||||
def values(self):
|
||||
"""
|
||||
Get schedule values
|
||||
:return: [Any]
|
||||
"""
|
||||
return self._values
|
||||
return self._values
|
||||
|
||||
@values.setter
|
||||
def values(self, value):
|
||||
"""
|
||||
@values.setter
|
||||
def values(self, value):
|
||||
"""
|
||||
Set schedule values
|
||||
:param: [Any]
|
||||
"""
|
||||
self._values = value
|
||||
self._values = value
|
||||
|
||||
@property
|
||||
def data_type(self) -> Union[None, str]:
|
||||
"""
|
||||
@property
|
||||
def data_type(self) -> Union[None, str]:
|
||||
"""
|
||||
Get schedule data type from:
|
||||
['any_number', 'fraction', 'on_off', 'temperature', 'humidity', 'control_type']
|
||||
:return: None or str
|
||||
"""
|
||||
return self._data_type
|
||||
return self._data_type
|
||||
|
||||
@data_type.setter
|
||||
def data_type(self, value):
|
||||
"""
|
||||
@data_type.setter
|
||||
def data_type(self, value):
|
||||
"""
|
||||
Set schedule data type
|
||||
:param: str
|
||||
"""
|
||||
if value is not None:
|
||||
self._data_type = str(value)
|
||||
if value is not None:
|
||||
self._data_type = str(value)
|
||||
|
||||
@property
|
||||
def time_step(self) -> Union[None, str]:
|
||||
"""
|
||||
@property
|
||||
def time_step(self) -> Union[None, str]:
|
||||
"""
|
||||
Get schedule time step from:
|
||||
['second', 'minute', 'hour', 'day', 'week', 'month']
|
||||
:return: None or str
|
||||
"""
|
||||
return self._time_step
|
||||
return self._time_step
|
||||
|
||||
@time_step.setter
|
||||
def time_step(self, value):
|
||||
"""
|
||||
@time_step.setter
|
||||
def time_step(self, value):
|
||||
"""
|
||||
Set schedule time step
|
||||
:param: str
|
||||
"""
|
||||
if value is not None:
|
||||
self._time_step = str(value)
|
||||
if value is not None:
|
||||
self._time_step = str(value)
|
||||
|
||||
@property
|
||||
def time_range(self) -> Union[None, str]:
|
||||
"""
|
||||
@property
|
||||
def time_range(self) -> Union[None, str]:
|
||||
"""
|
||||
Get schedule time range from:
|
||||
['minute', 'hour', 'day', 'week', 'month', 'year']
|
||||
:return: None or str
|
||||
"""
|
||||
return self._time_range
|
||||
return self._time_range
|
||||
|
||||
@time_range.setter
|
||||
def time_range(self, value):
|
||||
"""
|
||||
@time_range.setter
|
||||
def time_range(self, value):
|
||||
"""
|
||||
Set schedule time range
|
||||
:param: str
|
||||
"""
|
||||
if value is not None:
|
||||
self._time_range = str(value)
|
||||
if value is not None:
|
||||
self._time_range = str(value)
|
||||
|
||||
@property
|
||||
def day_types(self) -> Union[None, List[str]]:
|
||||
"""
|
||||
@property
|
||||
def day_types(self) -> Union[None, List[str]]:
|
||||
"""
|
||||
Get schedule day types, as many as needed from:
|
||||
['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday', 'holiday', 'winter_design_day',
|
||||
'summer_design_day']
|
||||
:return: None or [str]
|
||||
"""
|
||||
return self._day_types
|
||||
return self._day_types
|
||||
|
||||
@day_types.setter
|
||||
def day_types(self, value):
|
||||
"""
|
||||
@day_types.setter
|
||||
def day_types(self, value):
|
||||
"""
|
||||
Set schedule day types
|
||||
:param: [str]
|
||||
"""
|
||||
if value is not None:
|
||||
self._day_types = [str(i) for i in value]
|
||||
if value is not None:
|
||||
self._day_types = [str(i) for i in value]
|
||||
|
|
|
@ -8,12 +8,9 @@ contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
|||
from typing import List, Union
|
||||
import numpy as np
|
||||
from city_model_structure.building_demand.surface import Surface
|
||||
from city_model_structure.building_demand.thermal_zone import ThermalZone
|
||||
from city_model_structure.building_demand.thermal_boundary import ThermalBoundary
|
||||
from city_model_structure.building_demand.usage_zone import UsageZone
|
||||
from city_model_structure.building_demand.storey import Storey
|
||||
from city_model_structure.city_object import CityObject
|
||||
from city_model_structure.building_demand.household import Household
|
||||
from city_model_structure.building_demand.internal_zone import InternalZone
|
||||
from city_model_structure.attributes.polyhedron import Polyhedron
|
||||
|
||||
|
||||
|
@ -34,10 +31,8 @@ class Building(CityObject):
|
|||
self._floor_area = None
|
||||
self._roof_type = None
|
||||
self._storeys = None
|
||||
self._geometrical_zones = None
|
||||
self._thermal_zones = []
|
||||
self._thermal_boundaries = None
|
||||
self._usage_zones = []
|
||||
self._internal_zones = None
|
||||
self._shell = None
|
||||
self._type = 'building'
|
||||
self._heating = dict()
|
||||
self._cooling = dict()
|
||||
|
@ -62,13 +57,26 @@ class Building(CityObject):
|
|||
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
|
||||
def shell(self) -> Polyhedron:
|
||||
"""
|
||||
Get building shell
|
||||
:return: [Polyhedron]
|
||||
"""
|
||||
if self._shell is None:
|
||||
self._shell = Polyhedron(self.surfaces)
|
||||
return self._shell
|
||||
|
||||
@property
|
||||
def internal_zones(self) -> List[InternalZone]:
|
||||
"""
|
||||
Get building internal zones
|
||||
For Lod up to 3, there is only one internal zone which corresponds to the building shell.
|
||||
In LoD 4 there can be more than one. In this case the definition of surfaces and floor area must be redefined.
|
||||
:return: [InternalZone]
|
||||
"""
|
||||
if self._internal_zones is None:
|
||||
self._internal_zones = [InternalZone(self.surfaces, self.floor_area)]
|
||||
return self._internal_zones
|
||||
|
||||
@property
|
||||
def grounds(self) -> List[Surface]:
|
||||
|
@ -78,28 +86,6 @@ class Building(CityObject):
|
|||
"""
|
||||
return self._grounds
|
||||
|
||||
@property
|
||||
def is_heated(self):
|
||||
"""
|
||||
Get building heated flag
|
||||
:return: Boolean
|
||||
"""
|
||||
for usage_zone in self.usage_zones:
|
||||
if usage_zone.is_heated:
|
||||
return usage_zone.is_heated
|
||||
return False
|
||||
|
||||
@property
|
||||
def is_cooled(self):
|
||||
"""
|
||||
Get building cooled flag
|
||||
:return: Boolean
|
||||
"""
|
||||
for usage_zone in self.usage_zones:
|
||||
if usage_zone.is_cooled:
|
||||
return usage_zone.is_cooled
|
||||
return False
|
||||
|
||||
@property
|
||||
def roofs(self) -> List[Surface]:
|
||||
"""
|
||||
|
@ -117,18 +103,7 @@ class Building(CityObject):
|
|||
return self._walls
|
||||
|
||||
@property
|
||||
def usage_zones(self) -> List[UsageZone]:
|
||||
"""
|
||||
Get city object usage zones
|
||||
:return: [UsageZone]
|
||||
"""
|
||||
if len(self._usage_zones) == 0:
|
||||
for thermal_zone in self.thermal_zones:
|
||||
self._usage_zones.extend(thermal_zone.usage_zones)
|
||||
return self._usage_zones
|
||||
|
||||
@property
|
||||
def terrains(self) -> List[Surface]:
|
||||
def terrains(self) -> Union[None, List[Surface]]:
|
||||
"""
|
||||
Get city object terrain surfaces
|
||||
:return: [Surface]
|
||||
|
@ -169,27 +144,6 @@ class Building(CityObject):
|
|||
if value is not None:
|
||||
self._basement_heated = int(value)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""
|
||||
Get building name
|
||||
:return: str
|
||||
"""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def thermal_zones(self) -> List[ThermalZone]:
|
||||
"""
|
||||
Get building thermal zones
|
||||
:return: [ThermalZone]
|
||||
"""
|
||||
if len(self._thermal_zones) == 0:
|
||||
if self.storeys is None:
|
||||
return []
|
||||
for storey in self.storeys:
|
||||
self._thermal_zones.append(storey.thermal_zone)
|
||||
return self._thermal_zones
|
||||
|
||||
@property
|
||||
def heated_volume(self):
|
||||
"""
|
||||
|
@ -213,7 +167,7 @@ class Building(CityObject):
|
|||
:param value: int
|
||||
"""
|
||||
if value is not None:
|
||||
self._year_of_construction = value
|
||||
self._year_of_construction = int(value)
|
||||
|
||||
@property
|
||||
def function(self) -> Union[None, str]:
|
||||
|
@ -310,22 +264,6 @@ class Building(CityObject):
|
|||
self._eave_height = max(self._eave_height, wall.upper_corner[2])
|
||||
return self._eave_height
|
||||
|
||||
@property
|
||||
def storeys(self) -> List[Storey]:
|
||||
"""
|
||||
Get building storeys
|
||||
:return: [Storey]
|
||||
"""
|
||||
return self._storeys
|
||||
|
||||
@storeys.setter
|
||||
def storeys(self, value):
|
||||
"""
|
||||
Set building storeys
|
||||
:param value: [Storey]
|
||||
"""
|
||||
self._storeys = value
|
||||
|
||||
@property
|
||||
def roof_type(self):
|
||||
"""
|
||||
|
@ -341,6 +279,14 @@ class Building(CityObject):
|
|||
break
|
||||
return self._roof_type
|
||||
|
||||
@roof_type.setter
|
||||
def roof_type(self, value):
|
||||
"""
|
||||
Set roof type for the building flat or pitch
|
||||
:return: str
|
||||
"""
|
||||
self._roof_type = value
|
||||
|
||||
@property
|
||||
def floor_area(self):
|
||||
"""
|
||||
|
@ -354,24 +300,6 @@ class Building(CityObject):
|
|||
self._floor_area += surface.perimeter_polygon.area
|
||||
return self._floor_area
|
||||
|
||||
@property
|
||||
def thermal_boundaries(self) -> List[ThermalBoundary]:
|
||||
"""
|
||||
Get all thermal boundaries associated to the building's thermal zones
|
||||
:return: [ThermalBoundary]
|
||||
"""
|
||||
if self._thermal_boundaries is None:
|
||||
self._thermal_boundaries = []
|
||||
for thermal_zone in self.thermal_zones:
|
||||
_thermal_boundary_duplicated = False
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
if len(thermal_boundary.thermal_zones) > 1:
|
||||
if thermal_zone != thermal_boundary.thermal_zones[1]:
|
||||
self._thermal_boundaries.append(thermal_boundary)
|
||||
else:
|
||||
self._thermal_boundaries.append(thermal_boundary)
|
||||
return self._thermal_boundaries
|
||||
|
||||
@property
|
||||
def households(self) -> List[Household]:
|
||||
"""
|
||||
|
@ -379,3 +307,18 @@ class Building(CityObject):
|
|||
:return: List[Household]
|
||||
"""
|
||||
return self._households
|
||||
|
||||
@property
|
||||
def is_conditioned(self):
|
||||
"""
|
||||
Get building heated flag
|
||||
:return: Boolean
|
||||
"""
|
||||
if self.internal_zones is None:
|
||||
return False
|
||||
for internal_zone in self.internal_zones:
|
||||
if internal_zone.usage_zones is not None:
|
||||
for usage_zone in internal_zone.usage_zones:
|
||||
if usage_zone.thermal_control is not None:
|
||||
return True
|
||||
return False
|
||||
|
|
103
city_model_structure/building_demand/appliances.py
Normal file
103
city_model_structure/building_demand/appliances.py
Normal file
|
@ -0,0 +1,103 @@
|
|||
"""
|
||||
Appliances module
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
from typing import Union, List
|
||||
from city_model_structure.attributes.schedule import Schedule
|
||||
|
||||
|
||||
class Appliances:
|
||||
"""
|
||||
Appliances class
|
||||
"""
|
||||
def __init__(self):
|
||||
self._appliances_density = None
|
||||
self._convective_fraction = None
|
||||
self._radiative_fraction = None
|
||||
self._latent_fraction = None
|
||||
self._schedules = None
|
||||
|
||||
@property
|
||||
def appliances_density(self) -> Union[None, float]:
|
||||
"""
|
||||
Get appliances density in Watts per m2
|
||||
:return: None or float
|
||||
"""
|
||||
return self._appliances_density
|
||||
|
||||
@appliances_density.setter
|
||||
def appliances_density(self, value):
|
||||
"""
|
||||
Set appliances density in Watts per m2
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._appliances_density = float(value)
|
||||
|
||||
@property
|
||||
def convective_fraction(self) -> Union[None, float]:
|
||||
"""
|
||||
Get convective fraction
|
||||
:return: None or float
|
||||
"""
|
||||
return self._convective_fraction
|
||||
|
||||
@convective_fraction.setter
|
||||
def convective_fraction(self, value):
|
||||
"""
|
||||
Set convective fraction
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._convective_fraction = float(value)
|
||||
|
||||
@property
|
||||
def radiative_fraction(self) -> Union[None, float]:
|
||||
"""
|
||||
Get radiant fraction
|
||||
:return: None or float
|
||||
"""
|
||||
return self._radiative_fraction
|
||||
|
||||
@radiative_fraction.setter
|
||||
def radiative_fraction(self, value):
|
||||
"""
|
||||
Set radiant fraction
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._radiative_fraction = float(value)
|
||||
|
||||
@property
|
||||
def latent_fraction(self) -> Union[None, float]:
|
||||
"""
|
||||
Get latent fraction
|
||||
:return: None or float
|
||||
"""
|
||||
return self._latent_fraction
|
||||
|
||||
@latent_fraction.setter
|
||||
def latent_fraction(self, value):
|
||||
"""
|
||||
Set latent fraction
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._latent_fraction = float(value)
|
||||
|
||||
@property
|
||||
def schedules(self) -> Union[None, List[Schedule]]:
|
||||
"""
|
||||
Get schedules
|
||||
:return: None or [Schedule]
|
||||
"""
|
||||
return self._schedules
|
||||
|
||||
@schedules.setter
|
||||
def schedules(self, value):
|
||||
"""
|
||||
Set schedules
|
||||
:param value: [Schedule]
|
||||
"""
|
||||
self._schedules = value
|
|
@ -4,7 +4,8 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
|
|||
Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
from typing import Union
|
||||
from typing import Union, List
|
||||
from city_model_structure.attributes.schedule import Schedule
|
||||
|
||||
|
||||
class InternalGains:
|
||||
|
@ -18,6 +19,7 @@ class InternalGains:
|
|||
self._convective_fraction = None
|
||||
self._radiative_fraction = None
|
||||
self._latent_fraction = None
|
||||
self._schedules = None
|
||||
|
||||
@property
|
||||
def type(self) -> Union[None, str]:
|
||||
|
@ -103,3 +105,19 @@ class InternalGains:
|
|||
"""
|
||||
if value is not None:
|
||||
self._latent_fraction = float(value)
|
||||
|
||||
@property
|
||||
def schedules(self) -> Union[None, List[Schedule]]:
|
||||
"""
|
||||
Get internal gain schedule
|
||||
:return: [Schedule]
|
||||
"""
|
||||
return self._schedules
|
||||
|
||||
@schedules.setter
|
||||
def schedules(self, value):
|
||||
"""
|
||||
Set internal gain schedule
|
||||
:param value: [Schedule]
|
||||
"""
|
||||
self._schedules = value
|
||||
|
|
123
city_model_structure/building_demand/internal_zone.py
Normal file
123
city_model_structure/building_demand/internal_zone.py
Normal file
|
@ -0,0 +1,123 @@
|
|||
"""
|
||||
InternalZone module. It saves the original geometrical information from interiors together with some attributes of those
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
|
||||
import uuid
|
||||
from typing import Union, List
|
||||
from city_model_structure.building_demand.usage_zone import UsageZone
|
||||
from city_model_structure.building_demand.thermal_zone import ThermalZone
|
||||
from city_model_structure.attributes.polyhedron import Polyhedron
|
||||
from city_model_structure.energy_systems.hvac_system import HvacSystem
|
||||
|
||||
|
||||
class InternalZone:
|
||||
"""
|
||||
InternalZone class
|
||||
"""
|
||||
def __init__(self, surfaces, area):
|
||||
self._surfaces = surfaces
|
||||
self._id = None
|
||||
self._geometry = None
|
||||
self._volume = None
|
||||
self._area = area
|
||||
self._thermal_zones = None
|
||||
self._usage_zones = None
|
||||
self._hvac_system = None
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
"""
|
||||
Get internal zone id, an universally unique identifier randomly generated
|
||||
:return: str
|
||||
"""
|
||||
if self._id is None:
|
||||
self._id = uuid.uuid4()
|
||||
return self._id
|
||||
|
||||
@property
|
||||
def geometry(self) -> Polyhedron:
|
||||
"""
|
||||
Get internal zone geometry
|
||||
:return: Polyhedron
|
||||
"""
|
||||
if self._geometry is None:
|
||||
polygons = []
|
||||
for surface in self.surfaces:
|
||||
polygons.append(surface.perimeter_polygon)
|
||||
self._geometry = Polyhedron(polygons)
|
||||
return self._geometry
|
||||
|
||||
@property
|
||||
def surfaces(self):
|
||||
"""
|
||||
Get internal zone surfaces
|
||||
:return: [Surface]
|
||||
"""
|
||||
return self._surfaces
|
||||
|
||||
@property
|
||||
def volume(self):
|
||||
"""
|
||||
Get internal zone volume in cubic meters
|
||||
:return: float
|
||||
"""
|
||||
return self.geometry.volume
|
||||
|
||||
@property
|
||||
def area(self):
|
||||
"""
|
||||
Get internal zone area in square meters
|
||||
:return: float
|
||||
"""
|
||||
return self._area
|
||||
|
||||
@property
|
||||
def usage_zones(self) -> [UsageZone]:
|
||||
"""
|
||||
Get internal zone usage zones
|
||||
:return: [UsageZone]
|
||||
"""
|
||||
return self._usage_zones
|
||||
|
||||
@usage_zones.setter
|
||||
def usage_zones(self, value):
|
||||
"""
|
||||
Set internal zone usage zones
|
||||
:param value: [UsageZone]
|
||||
"""
|
||||
self._usage_zones = value
|
||||
|
||||
@property
|
||||
def hvac_system(self) -> Union[None, HvacSystem]:
|
||||
"""
|
||||
Get HVAC system installed for this thermal zone
|
||||
:return: None or HvacSystem
|
||||
"""
|
||||
return self._hvac_system
|
||||
|
||||
@hvac_system.setter
|
||||
def hvac_system(self, value):
|
||||
"""
|
||||
Set HVAC system installed for this thermal zone
|
||||
:param value: HvacSystem
|
||||
"""
|
||||
self._hvac_system = value
|
||||
|
||||
@property
|
||||
def thermal_zones(self) -> Union[None, List[ThermalZone]]:
|
||||
"""
|
||||
Get building thermal zones
|
||||
:return: [ThermalZone]
|
||||
"""
|
||||
return self._thermal_zones
|
||||
|
||||
@thermal_zones.setter
|
||||
def thermal_zones(self, value):
|
||||
"""
|
||||
Set city object thermal zones
|
||||
:param value: [ThermalZone]
|
||||
"""
|
||||
self._thermal_zones = value
|
||||
|
103
city_model_structure/building_demand/lighting.py
Normal file
103
city_model_structure/building_demand/lighting.py
Normal file
|
@ -0,0 +1,103 @@
|
|||
"""
|
||||
Lighting module
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
from typing import Union, List
|
||||
from city_model_structure.attributes.schedule import Schedule
|
||||
|
||||
|
||||
class Lighting:
|
||||
"""
|
||||
Lighting class
|
||||
"""
|
||||
def __init__(self):
|
||||
self._lighting_density = None
|
||||
self._convective_fraction = None
|
||||
self._radiative_fraction = None
|
||||
self._latent_fraction = None
|
||||
self._schedules = None
|
||||
|
||||
@property
|
||||
def lighting_density(self) -> Union[None, float]:
|
||||
"""
|
||||
Get lighting density in Watts per m2
|
||||
:return: None or float
|
||||
"""
|
||||
return self._lighting_density
|
||||
|
||||
@lighting_density.setter
|
||||
def lighting_density(self, value):
|
||||
"""
|
||||
Set lighting density in Watts per m2
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._lighting_density = float(value)
|
||||
|
||||
@property
|
||||
def convective_fraction(self) -> Union[None, float]:
|
||||
"""
|
||||
Get convective fraction
|
||||
:return: None or float
|
||||
"""
|
||||
return self._convective_fraction
|
||||
|
||||
@convective_fraction.setter
|
||||
def convective_fraction(self, value):
|
||||
"""
|
||||
Set convective fraction
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._convective_fraction = float(value)
|
||||
|
||||
@property
|
||||
def radiative_fraction(self) -> Union[None, float]:
|
||||
"""
|
||||
Get radiant fraction
|
||||
:return: None or float
|
||||
"""
|
||||
return self._radiative_fraction
|
||||
|
||||
@radiative_fraction.setter
|
||||
def radiative_fraction(self, value):
|
||||
"""
|
||||
Set radiant fraction
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._radiative_fraction = float(value)
|
||||
|
||||
@property
|
||||
def latent_fraction(self) -> Union[None, float]:
|
||||
"""
|
||||
Get latent fraction
|
||||
:return: None or float
|
||||
"""
|
||||
return self._latent_fraction
|
||||
|
||||
@latent_fraction.setter
|
||||
def latent_fraction(self, value):
|
||||
"""
|
||||
Set latent fraction
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._latent_fraction = float(value)
|
||||
|
||||
@property
|
||||
def schedules(self) -> Union[None, List[Schedule]]:
|
||||
"""
|
||||
Get schedules
|
||||
:return: None or [Schedule]
|
||||
"""
|
||||
return self._schedules
|
||||
|
||||
@schedules.setter
|
||||
def schedules(self, value):
|
||||
"""
|
||||
Set schedules
|
||||
:param value: [Schedule]
|
||||
"""
|
||||
self._schedules = value
|
|
@ -6,6 +6,7 @@ Contributor Atiya atiya.atiya@mail.concordia.ca
|
|||
Contributor Mohammad Reza mohammad.seyedabadi@mail.concordia.ca
|
||||
"""
|
||||
|
||||
import ast
|
||||
from typing import Union
|
||||
|
||||
|
||||
|
@ -14,6 +15,7 @@ class Material:
|
|||
Material class
|
||||
"""
|
||||
def __init__(self):
|
||||
self._type = type
|
||||
self._id = None
|
||||
self._name = None
|
||||
self._conductivity = None
|
||||
|
@ -25,7 +27,30 @@ class Material:
|
|||
self._visible_absorptance = None
|
||||
self._no_mass = False
|
||||
self._thermal_resistance = None
|
||||
self._lca_id = None
|
||||
self._embodied_carbon = None
|
||||
self._embodied_carbon_unit = None
|
||||
self._recycling_ratio = None
|
||||
self._onsite_recycling_ratio = None
|
||||
self._company_recycling_ratio = None
|
||||
self._landfilling_ratio = None
|
||||
self._cost = None
|
||||
self._cost_unit = None
|
||||
|
||||
@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 id(self):
|
||||
|
@ -213,10 +238,137 @@ class Material:
|
|||
self._thermal_resistance = float(value)
|
||||
|
||||
@property
|
||||
def lca_id(self):
|
||||
return self._lca_id
|
||||
def embodied_carbon(self) -> Union[None, float]:
|
||||
"""
|
||||
Get material embodied carbon
|
||||
:return: None or float
|
||||
"""
|
||||
return self._embodied_carbon
|
||||
|
||||
@lca_id.setter
|
||||
def lca_id(self, value):
|
||||
self._lca_id = value
|
||||
@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)
|
||||
|
|
121
city_model_structure/building_demand/occupancy.py
Normal file
121
city_model_structure/building_demand/occupancy.py
Normal file
|
@ -0,0 +1,121 @@
|
|||
"""
|
||||
Occupancy module
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
from typing import Union, List
|
||||
from city_model_structure.attributes.schedule import Schedule
|
||||
from city_model_structure.building_demand.occupant import Occupant
|
||||
|
||||
|
||||
class Occupancy:
|
||||
"""
|
||||
Occupancy class
|
||||
"""
|
||||
def __init__(self):
|
||||
self._occupancy_density = None
|
||||
self._sensible_convective_internal_gain = None
|
||||
self._sensible_radiative_internal_gain = None
|
||||
self._latent_internal_gain = None
|
||||
self._occupancy_schedules = None
|
||||
self._occupants = None
|
||||
|
||||
@property
|
||||
def occupancy_density(self) -> Union[None, float]:
|
||||
"""
|
||||
Get density in m2 per person
|
||||
:return: None or float
|
||||
"""
|
||||
return self._occupancy_density
|
||||
|
||||
@occupancy_density.setter
|
||||
def occupancy_density(self, value):
|
||||
"""
|
||||
Set density in m2 per persons
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._occupancy_density = float(value)
|
||||
|
||||
@property
|
||||
def sensible_convective_internal_gain(self) -> Union[None, float]:
|
||||
"""
|
||||
Get sensible convective internal gain in Watts per m2
|
||||
:return: None or float
|
||||
"""
|
||||
return self._sensible_convective_internal_gain
|
||||
|
||||
@sensible_convective_internal_gain.setter
|
||||
def sensible_convective_internal_gain(self, value):
|
||||
"""
|
||||
Set sensible convective internal gain in Watts per m2
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._sensible_convective_internal_gain = float(value)
|
||||
|
||||
@property
|
||||
def sensible_radiative_internal_gain(self) -> Union[None, float]:
|
||||
"""
|
||||
Get sensible radiant internal gain in Watts per m2
|
||||
:return: None or float
|
||||
"""
|
||||
return self._sensible_radiative_internal_gain
|
||||
|
||||
@sensible_radiative_internal_gain.setter
|
||||
def sensible_radiative_internal_gain(self, value):
|
||||
"""
|
||||
Set sensible radiant internal gain in Watts per m2
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._sensible_radiative_internal_gain = float(value)
|
||||
|
||||
@property
|
||||
def latent_internal_gain(self) -> Union[None, float]:
|
||||
"""
|
||||
Get latent internal gain in Watts per m2
|
||||
:return: None or float
|
||||
"""
|
||||
return self._latent_internal_gain
|
||||
|
||||
@latent_internal_gain.setter
|
||||
def latent_internal_gain(self, value):
|
||||
"""
|
||||
Set latent internal gain in Watts per m2
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._latent_internal_gain = float(value)
|
||||
|
||||
@property
|
||||
def occupancy_schedules(self) -> Union[None, List[Schedule]]:
|
||||
"""
|
||||
Get occupancy schedules
|
||||
:return: None or [Schedule]
|
||||
"""
|
||||
return self._occupancy_schedules
|
||||
|
||||
@occupancy_schedules.setter
|
||||
def occupancy_schedules(self, value):
|
||||
"""
|
||||
Set occupancy schedules
|
||||
:param value: [Schedule]
|
||||
"""
|
||||
self._occupancy_schedules = value
|
||||
|
||||
@property
|
||||
def occupants(self) -> Union[None, List[Occupant]]:
|
||||
"""
|
||||
Get list of occupants
|
||||
:return: None or List of Occupant
|
||||
"""
|
||||
return self._occupants
|
||||
|
||||
@occupants.setter
|
||||
def occupants(self, value):
|
||||
"""
|
||||
Set list of occupants
|
||||
:param value: [Occupant]
|
||||
"""
|
||||
self._occupants = value
|
|
@ -1,19 +1,16 @@
|
|||
"""
|
||||
Occupants module
|
||||
Occupant module
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Sanam Dabirian sanam.dabirian@mail.concordia.ca
|
||||
Contributors Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
|
||||
from typing import TypeVar
|
||||
import calendar as cal
|
||||
|
||||
UsageZone = TypeVar('UsageZone')
|
||||
|
||||
|
||||
class Occupants:
|
||||
class Occupant:
|
||||
"""
|
||||
Occupants class
|
||||
Occupant class
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
|
@ -24,15 +21,11 @@ class Occupants:
|
|||
self._heat_dissipation = None
|
||||
self._occupancy_rate = None
|
||||
self._occupant_type = None
|
||||
self._usage_zone = None
|
||||
self._occupant_schedule = None
|
||||
self._number_of_occupants = None
|
||||
self._arrival_time = None
|
||||
self._departure_time = None
|
||||
self._break_time = None
|
||||
self._day_of_week = None
|
||||
self._pd_of_meetings_duration = None
|
||||
self._complete_year_schedule = None
|
||||
|
||||
@property
|
||||
def heat_dissipation(self):
|
||||
|
@ -82,46 +75,6 @@ class Occupants:
|
|||
"""
|
||||
self._occupant_type = float(value)
|
||||
|
||||
@property
|
||||
def usage_zone(self) -> UsageZone:
|
||||
"""
|
||||
Get the zone an occupant is in
|
||||
:return: UsageZone
|
||||
"""
|
||||
return self._usage_zone
|
||||
|
||||
@property
|
||||
def occupant_schedule(self):
|
||||
"""
|
||||
Get the schedules when an occupant is in a zone (24 values, 1 per hour of the day)
|
||||
:return: [float]
|
||||
"""
|
||||
return self._occupant_schedule
|
||||
|
||||
@occupant_schedule.setter
|
||||
def occupant_schedule(self, value):
|
||||
"""
|
||||
Set the schedules when an occupant is in a zone (24 values, 1 per hour of the day)
|
||||
:param value: [float]
|
||||
"""
|
||||
self._occupant_schedule = [float(i) for i in value]
|
||||
|
||||
@property
|
||||
def number_of_occupants(self):
|
||||
"""
|
||||
Get the number of occupants
|
||||
:return: int
|
||||
"""
|
||||
return self._number_of_occupants
|
||||
|
||||
@number_of_occupants.setter
|
||||
def number_of_occupants(self, value):
|
||||
"""
|
||||
Set the number of occupants
|
||||
:param value: int
|
||||
"""
|
||||
self._number_of_occupants = int(value)
|
||||
|
||||
@property
|
||||
def arrival_time(self):
|
||||
"""
|
||||
|
@ -191,27 +144,3 @@ class Occupants:
|
|||
"""
|
||||
# todo @Sanam: what format are you expecting here??
|
||||
self._pd_of_meetings_duration = value
|
||||
|
||||
def get_complete_year_schedule(self, schedules):
|
||||
"""
|
||||
Get the a non-leap year (8760 h), starting on Monday schedules out of archetypal days of week
|
||||
:return: [float]
|
||||
"""
|
||||
if self._complete_year_schedule is None:
|
||||
self._complete_year_schedule = []
|
||||
for i in range(1, 13):
|
||||
month_range = cal.monthrange(2015, i)[1]
|
||||
for day in range(1, month_range+1):
|
||||
if cal.weekday(2015, i, day) < 5:
|
||||
for j in range(0, 24):
|
||||
week_schedule = schedules['WD'][j]
|
||||
self._complete_year_schedule.append(week_schedule)
|
||||
elif cal.weekday(2015, i, day) == 5:
|
||||
for j in range(0, 24):
|
||||
week_schedule = schedules['Sat'][j]
|
||||
self._complete_year_schedule.append(week_schedule)
|
||||
else:
|
||||
for j in range(0, 24):
|
||||
week_schedule = schedules['Sun'][j]
|
||||
self._complete_year_schedule.append(week_schedule)
|
||||
return self._complete_year_schedule
|
|
@ -12,12 +12,10 @@ from city_model_structure.building_demand.thermal_zone import ThermalZone
|
|||
|
||||
|
||||
class Storey:
|
||||
# todo: rethink this class for buildings with windows
|
||||
"""
|
||||
Storey class
|
||||
"""
|
||||
def __init__(self, name, storey_surfaces, neighbours, volume):
|
||||
# todo: the information of the parent surface is lost -> need to recover it
|
||||
def __init__(self, name, storey_surfaces, neighbours, volume, floor_area):
|
||||
self._name = name
|
||||
self._storey_surfaces = storey_surfaces
|
||||
self._thermal_boundaries = None
|
||||
|
@ -25,6 +23,7 @@ class Storey:
|
|||
self._thermal_zone = None
|
||||
self._neighbours = neighbours
|
||||
self._volume = volume
|
||||
self._floor_area = floor_area
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
|
@ -59,7 +58,13 @@ class Storey:
|
|||
if self._thermal_boundaries is None:
|
||||
self._thermal_boundaries = []
|
||||
for surface in self.surfaces:
|
||||
self._thermal_boundaries.append(ThermalBoundary(surface))
|
||||
if surface.holes_polygons is None:
|
||||
windows_areas = None
|
||||
else:
|
||||
windows_areas = []
|
||||
for hole in surface.holes_polygons:
|
||||
windows_areas.append(hole.area)
|
||||
self._thermal_boundaries.append(ThermalBoundary(surface, surface.solid_polygon.area, windows_areas))
|
||||
return self._thermal_boundaries
|
||||
|
||||
@property
|
||||
|
@ -81,7 +86,7 @@ class Storey:
|
|||
:return: ThermalZone
|
||||
"""
|
||||
if self._thermal_zone is None:
|
||||
self._thermal_zone = ThermalZone(self.thermal_boundaries, self.volume)
|
||||
self._thermal_zone = ThermalZone(self.thermal_boundaries, self.volume, self.floor_area)
|
||||
return self._thermal_zone
|
||||
|
||||
@property
|
||||
|
@ -91,3 +96,11 @@ class Storey:
|
|||
:return: float
|
||||
"""
|
||||
return self._volume
|
||||
|
||||
@property
|
||||
def floor_area(self):
|
||||
"""
|
||||
Get storey's floor area in square meters
|
||||
:return: float
|
||||
"""
|
||||
return self._floor_area
|
||||
|
|
|
@ -71,6 +71,7 @@ class Surface:
|
|||
if value is not None:
|
||||
self._id = str(value)
|
||||
|
||||
# todo: implement share surfaces
|
||||
@property
|
||||
def share_surfaces(self):
|
||||
"""
|
||||
|
@ -191,6 +192,8 @@ class Surface:
|
|||
Get surface type Ground, Wall or Roof
|
||||
:return: str
|
||||
"""
|
||||
|
||||
# todo: there are more types: internal wall, internal floor... this method must be redefined
|
||||
if self._type is None:
|
||||
grad = np.rad2deg(self.inclination)
|
||||
if grad >= 170:
|
||||
|
|
|
@ -5,25 +5,24 @@ Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@conc
|
|||
Contributors Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
import uuid
|
||||
from typing import List, TypeVar, Union
|
||||
from typing import List, Union
|
||||
from helpers.configuration_helper import ConfigurationHelper as ch
|
||||
from city_model_structure.building_demand.layer import Layer
|
||||
from city_model_structure.building_demand.thermal_opening import ThermalOpening
|
||||
from city_model_structure.building_demand.thermal_zone import ThermalZone
|
||||
from city_model_structure.building_demand.surface import Surface
|
||||
|
||||
Polygon = TypeVar('Polygon')
|
||||
|
||||
|
||||
class ThermalBoundary:
|
||||
"""
|
||||
ThermalBoundary class
|
||||
"""
|
||||
def __init__(self, surface):
|
||||
self._surface = surface
|
||||
def __init__(self, parent_surface, opaque_area, windows_areas):
|
||||
self._parent_surface = parent_surface
|
||||
self._opaque_area = opaque_area
|
||||
self._windows_areas = windows_areas
|
||||
self._id = None
|
||||
self._thermal_zones = None
|
||||
# ToDo: up to at least LOD2 will be just one thermal opening per Thermal boundary only if window_ratio > 0,
|
||||
# review for LOD3 and LOD4
|
||||
self._thermal_openings = None
|
||||
self._layers = None
|
||||
self._outside_solar_absorptance = None
|
||||
|
@ -32,16 +31,16 @@ class ThermalBoundary:
|
|||
self._u_value = None
|
||||
self._shortwave_reflectance = None
|
||||
self._construction_name = None
|
||||
self._hi = 3.5
|
||||
self._he = 20
|
||||
self._window_ratio = None
|
||||
self._hi = ch().convective_heat_transfer_coefficient_interior
|
||||
self._he = ch().convective_heat_transfer_coefficient_exterior
|
||||
self._refurbishment_measure = None
|
||||
self._surface_geometry = None
|
||||
self._thickness = None
|
||||
self._virtual_internal_surface = None
|
||||
self._inside_emissivity = None
|
||||
self._alpha_coefficient = None
|
||||
self._radiative_coefficient = None
|
||||
self._window_ratio = None
|
||||
self._calculated = False
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
|
@ -54,13 +53,12 @@ class ThermalBoundary:
|
|||
return self._id
|
||||
|
||||
@property
|
||||
def surface(self) -> Surface:
|
||||
def parent_surface(self) -> Surface:
|
||||
"""
|
||||
Get the surface that belongs to the thermal boundary
|
||||
:return: Surface
|
||||
"""
|
||||
# todo: in LoD4 this property will be a list of surfaces, not only one
|
||||
return self._surface
|
||||
return self._parent_surface
|
||||
|
||||
@property
|
||||
def thermal_zones(self) -> List[ThermalZone]:
|
||||
|
@ -73,47 +71,35 @@ class ThermalBoundary:
|
|||
@thermal_zones.setter
|
||||
def thermal_zones(self, value):
|
||||
"""
|
||||
Set the thermal zones delimited by the thermal boundary
|
||||
Get the thermal zones delimited by the thermal boundary
|
||||
:param value: [ThermalZone]
|
||||
"""
|
||||
self._thermal_zones = value
|
||||
|
||||
# todo: do I need these two??
|
||||
@property
|
||||
def azimuth(self):
|
||||
"""
|
||||
Get the thermal boundary azimuth in radians
|
||||
:return: float
|
||||
"""
|
||||
return self._surface.azimuth
|
||||
return self.parent_surface.azimuth
|
||||
|
||||
@property
|
||||
def inclination(self):
|
||||
"""
|
||||
Set the thermal boundary inclination in radians
|
||||
Get the thermal boundary inclination in radians
|
||||
:return: float
|
||||
"""
|
||||
return self._surface.inclination
|
||||
return self.parent_surface.inclination
|
||||
|
||||
@property
|
||||
def area(self):
|
||||
def opaque_area(self):
|
||||
"""
|
||||
Set the thermal boundary area in square meters
|
||||
Get the thermal boundary area in square meters
|
||||
:return: float
|
||||
"""
|
||||
# to check the lod without depending on that parameter
|
||||
if float(self.surface.solid_polygon.area) - float(self.surface.perimeter_polygon.area) < 1e-3:
|
||||
area = float(self.surface.perimeter_polygon.area) * (1 - float(self.window_ratio))
|
||||
else:
|
||||
area = self.surface.solid_polygon.area
|
||||
return area
|
||||
|
||||
@property
|
||||
def _total_area_including_windows(self):
|
||||
"""
|
||||
Get the thermal boundary plus windows area in square meters
|
||||
:return: float
|
||||
"""
|
||||
return self.surface.perimeter_polygon.area
|
||||
return float(self._opaque_area)
|
||||
|
||||
@property
|
||||
def thickness(self):
|
||||
|
@ -125,7 +111,8 @@ class ThermalBoundary:
|
|||
self._thickness = 0.0
|
||||
if self.layers is not None:
|
||||
for layer in self.layers:
|
||||
self._thickness += layer.thickness
|
||||
if not layer.material.no_mass:
|
||||
self._thickness += layer.thickness
|
||||
return self._thickness
|
||||
|
||||
@property
|
||||
|
@ -181,30 +168,34 @@ class ThermalBoundary:
|
|||
self._outside_visible_absorptance = float(value)
|
||||
|
||||
@property
|
||||
def thermal_openings(self) -> List[ThermalOpening]:
|
||||
def thermal_openings(self) -> Union[None, List[ThermalOpening]]:
|
||||
"""
|
||||
Get thermal boundary thermal openings
|
||||
:return: [ThermalOpening]
|
||||
"""
|
||||
if self._thermal_openings is None:
|
||||
if float(self.window_ratio) > 0:
|
||||
thermal_opening = ThermalOpening()
|
||||
thermal_opening.area = float(self._total_area_including_windows) * float(self.window_ratio)
|
||||
thermal_opening.hi = self.hi
|
||||
thermal_opening.he = self.he
|
||||
self._thermal_openings = [thermal_opening]
|
||||
if self.window_ratio is not None:
|
||||
if self.window_ratio == 0:
|
||||
self._thermal_openings = []
|
||||
else:
|
||||
thermal_opening = ThermalOpening()
|
||||
if self.window_ratio == 1:
|
||||
_area = self.opaque_area
|
||||
else:
|
||||
_area = self.opaque_area * self.window_ratio / (1-self.window_ratio)
|
||||
thermal_opening.area = _area
|
||||
self._thermal_openings = [thermal_opening]
|
||||
else:
|
||||
self._thermal_openings = []
|
||||
if len(self.windows_areas) > 0:
|
||||
self._thermal_openings = []
|
||||
for window_area in self.windows_areas:
|
||||
thermal_opening = ThermalOpening()
|
||||
thermal_opening.area = window_area
|
||||
self._thermal_openings.append(thermal_opening)
|
||||
else:
|
||||
self._thermal_openings = []
|
||||
return self._thermal_openings
|
||||
|
||||
@thermal_openings.setter
|
||||
def thermal_openings(self, value):
|
||||
"""
|
||||
Set thermal boundary thermal openings
|
||||
:param value: [ThermalOpening]
|
||||
"""
|
||||
self._thermal_openings = value
|
||||
|
||||
@property
|
||||
def construction_name(self) -> Union[None, str]:
|
||||
"""
|
||||
|
@ -244,24 +235,47 @@ class ThermalBoundary:
|
|||
Get thermal boundary surface type
|
||||
:return: str
|
||||
"""
|
||||
return self._surface.type
|
||||
return self.parent_surface.type
|
||||
|
||||
@property
|
||||
def window_ratio(self) -> Union[None, float]:
|
||||
"""
|
||||
Get thermal boundary window ratio
|
||||
:return: None or float
|
||||
It returns the window ratio calculated as the total windows' areas in a wall divided by
|
||||
the total (opaque + transparent) area of that wall if windows are defined in the geometry imported.
|
||||
If not, it returns the window ratio imported from an external source (e.g. construction library, manually assigned).
|
||||
If none of those sources are available, it returns None.
|
||||
:return: float
|
||||
"""
|
||||
if self.windows_areas is not None:
|
||||
if not self._calculated:
|
||||
_calculated = True
|
||||
if len(self.windows_areas) == 0:
|
||||
self._window_ratio = 0
|
||||
else:
|
||||
total_window_area = 0
|
||||
for window_area in self.windows_areas:
|
||||
total_window_area += window_area
|
||||
self._window_ratio = total_window_area / (self.opaque_area + total_window_area)
|
||||
return self._window_ratio
|
||||
|
||||
@window_ratio.setter
|
||||
def window_ratio(self, value):
|
||||
"""
|
||||
Set thermal boundary window ratio
|
||||
:param value: float
|
||||
:param value: str
|
||||
"""
|
||||
if value is not None:
|
||||
self._window_ratio = float(value)
|
||||
if self._calculated:
|
||||
raise ValueError('Window ratio cannot be assigned when the windows are defined in the geometry.')
|
||||
self._window_ratio = float(value)
|
||||
|
||||
@property
|
||||
def windows_areas(self) -> [float]:
|
||||
"""
|
||||
Get windows areas
|
||||
:return: [float]
|
||||
"""
|
||||
return self._windows_areas
|
||||
|
||||
@property
|
||||
def u_value(self) -> Union[None, float]:
|
||||
|
@ -327,7 +341,7 @@ class ThermalBoundary:
|
|||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._hi = float(value)
|
||||
self._hi = value
|
||||
|
||||
@property
|
||||
def he(self) -> Union[None, float]:
|
||||
|
@ -344,14 +358,7 @@ class ThermalBoundary:
|
|||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._he = float(value)
|
||||
|
||||
@property
|
||||
def surface_geometry(self):
|
||||
"""
|
||||
Raises not implemented error
|
||||
"""
|
||||
raise NotImplementedError
|
||||
self._he = value
|
||||
|
||||
@property
|
||||
def virtual_internal_surface(self) -> Surface:
|
||||
|
@ -360,10 +367,9 @@ class ThermalBoundary:
|
|||
:return: Surface
|
||||
"""
|
||||
if self._virtual_internal_surface is None:
|
||||
self._virtual_internal_surface = self.surface.inverse
|
||||
self._virtual_internal_surface = self.parent_surface.inverse
|
||||
return self._virtual_internal_surface
|
||||
|
||||
# todo: need extract information from construction library or assume them at the beginning of workflows
|
||||
@property
|
||||
def inside_emissivity(self) -> Union[None, float]:
|
||||
"""
|
||||
|
|
144
city_model_structure/building_demand/thermal_control.py
Normal file
144
city_model_structure/building_demand/thermal_control.py
Normal file
|
@ -0,0 +1,144 @@
|
|||
"""
|
||||
ThermalControl module
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
from typing import Union, List
|
||||
from city_model_structure.attributes.schedule import Schedule
|
||||
|
||||
|
||||
class ThermalControl:
|
||||
"""
|
||||
ThermalControl class
|
||||
"""
|
||||
def __init__(self):
|
||||
self._mean_heating_set_point = None
|
||||
self._heating_set_back = None
|
||||
self._mean_cooling_set_point = None
|
||||
self._hvac_availability_schedules = None
|
||||
self._heating_set_point_schedules = None
|
||||
self._cooling_set_point_schedules = None
|
||||
|
||||
@staticmethod
|
||||
def _maximum_value(schedules):
|
||||
maximum = -1000
|
||||
for schedule in schedules:
|
||||
for value in schedule.values:
|
||||
if value > maximum:
|
||||
maximum = value
|
||||
return maximum
|
||||
|
||||
@staticmethod
|
||||
def _minimum_value(schedules):
|
||||
minimum = 1000
|
||||
for schedule in schedules:
|
||||
for value in schedule.values:
|
||||
if value < minimum:
|
||||
minimum = value
|
||||
return minimum
|
||||
|
||||
@property
|
||||
def mean_heating_set_point(self) -> Union[None, float]:
|
||||
"""
|
||||
Get heating set point defined for a thermal zone in Celsius
|
||||
:return: None or float
|
||||
"""
|
||||
if self._mean_heating_set_point is None:
|
||||
if self.heating_set_point_schedules is not None:
|
||||
self._mean_heating_set_point = self._maximum_value(self.heating_set_point_schedules)
|
||||
return self._mean_heating_set_point
|
||||
|
||||
@mean_heating_set_point.setter
|
||||
def mean_heating_set_point(self, value):
|
||||
"""
|
||||
Set heating set point defined for a thermal zone in Celsius
|
||||
:param value: float
|
||||
"""
|
||||
self._mean_heating_set_point = value
|
||||
|
||||
@property
|
||||
def heating_set_back(self) -> Union[None, float]:
|
||||
"""
|
||||
Get heating set back defined for a thermal zone in Celsius
|
||||
:return: None or float
|
||||
"""
|
||||
if self._heating_set_back is None:
|
||||
if self.heating_set_point_schedules is not None:
|
||||
self._heating_set_back = self._minimum_value(self.heating_set_point_schedules)
|
||||
return self._heating_set_back
|
||||
|
||||
@heating_set_back.setter
|
||||
def heating_set_back(self, value):
|
||||
"""
|
||||
Set heating set back defined for a thermal zone in Celsius
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._heating_set_back = float(value)
|
||||
|
||||
@property
|
||||
def mean_cooling_set_point(self) -> Union[None, float]:
|
||||
"""
|
||||
Get cooling set point defined for a thermal zone in Celsius
|
||||
:return: None or float
|
||||
"""
|
||||
if self._mean_cooling_set_point is None:
|
||||
if self.cooling_set_point_schedules is not None:
|
||||
self._mean_cooling_set_point = self._minimum_value(self.cooling_set_point_schedules)
|
||||
return self._mean_cooling_set_point
|
||||
|
||||
@mean_cooling_set_point.setter
|
||||
def mean_cooling_set_point(self, value):
|
||||
"""
|
||||
Set cooling set point defined for a thermal zone in Celsius
|
||||
:param value: float
|
||||
"""
|
||||
self._mean_cooling_set_point = value
|
||||
|
||||
@property
|
||||
def hvac_availability_schedules(self) -> Union[None, List[Schedule]]:
|
||||
"""
|
||||
Get the availability of the conditioning system defined for a thermal zone
|
||||
:return: None or [Schedule]
|
||||
"""
|
||||
return self._hvac_availability_schedules
|
||||
|
||||
@hvac_availability_schedules.setter
|
||||
def hvac_availability_schedules(self, value):
|
||||
"""
|
||||
Set the availability of the conditioning system defined for a thermal zone
|
||||
:param value: [Schedule]
|
||||
"""
|
||||
self._hvac_availability_schedules = value
|
||||
|
||||
@property
|
||||
def heating_set_point_schedules(self) -> Union[None, List[Schedule]]:
|
||||
"""
|
||||
Get heating set point schedule defined for a thermal zone in Celsius
|
||||
:return: None or [Schedule]
|
||||
"""
|
||||
return self._heating_set_point_schedules
|
||||
|
||||
@heating_set_point_schedules.setter
|
||||
def heating_set_point_schedules(self, value):
|
||||
"""
|
||||
Set heating set point schedule defined for a thermal zone in Celsius
|
||||
:param value: [Schedule]
|
||||
"""
|
||||
self._heating_set_point_schedules = value
|
||||
|
||||
@property
|
||||
def cooling_set_point_schedules(self) -> Union[None, List[Schedule]]:
|
||||
"""
|
||||
Get cooling set point schedule defined for a thermal zone in Celsius
|
||||
:return: None or [Schedule]
|
||||
"""
|
||||
return self._cooling_set_point_schedules
|
||||
|
||||
@cooling_set_point_schedules.setter
|
||||
def cooling_set_point_schedules(self, value):
|
||||
"""
|
||||
Set cooling set point schedule defined for a thermal zone in Celsius
|
||||
:param value: [Schedule]
|
||||
"""
|
||||
self._cooling_set_point_schedules = value
|
|
@ -6,6 +6,7 @@ Contributors Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
|||
"""
|
||||
import uuid
|
||||
from typing import TypeVar, Union
|
||||
from helpers.configuration_helper import ConfigurationHelper as ch
|
||||
|
||||
Polygon = TypeVar('Polygon')
|
||||
|
||||
|
@ -25,9 +26,8 @@ class ThermalOpening:
|
|||
self._front_side_solar_transmittance_at_normal_incidence = None
|
||||
self._back_side_solar_transmittance_at_normal_incidence = None
|
||||
self._overall_u_value = None
|
||||
self._hi = None
|
||||
self._he = None
|
||||
self._surface_geometry = None
|
||||
self._hi = ch().convective_heat_transfer_coefficient_interior
|
||||
self._he = ch().convective_heat_transfer_coefficient_exterior
|
||||
self._inside_emissivity = None
|
||||
self._alpha_coefficient = None
|
||||
self._radiative_coefficient = None
|
||||
|
@ -240,15 +240,6 @@ class ThermalOpening:
|
|||
if value is not None:
|
||||
self._he = float(value)
|
||||
|
||||
@property
|
||||
def surface_geometry(self) -> Polygon:
|
||||
"""
|
||||
Get the polygon that defines the thermal opening
|
||||
:return: Polygon
|
||||
"""
|
||||
return self._surface_geometry
|
||||
|
||||
# todo: need extract information from construction library or assume them at the beginning of workflows
|
||||
@property
|
||||
def inside_emissivity(self) -> Union[None, float]:
|
||||
"""
|
||||
|
|
|
@ -5,32 +5,34 @@ Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@conc
|
|||
Contributors Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
import uuid
|
||||
from typing import List, TypeVar, Union
|
||||
from typing import List, Union, TypeVar
|
||||
from city_model_structure.building_demand.usage_zone import UsageZone
|
||||
import ast
|
||||
from city_model_structure.attributes.schedule import Schedule
|
||||
from city_model_structure.building_demand.thermal_control import ThermalControl
|
||||
from city_model_structure.energy_systems.hvac_system import HvacSystem
|
||||
|
||||
ThermalBoundary = TypeVar('ThermalBoundary')
|
||||
Polyhedron = TypeVar('Polyhedron')
|
||||
|
||||
|
||||
class ThermalZone:
|
||||
"""
|
||||
ThermalZone class
|
||||
"""
|
||||
def __init__(self, thermal_boundaries, volume):
|
||||
self._floor_area = None
|
||||
def __init__(self, thermal_boundaries, volume, floor_area):
|
||||
self._id = None
|
||||
self._floor_area = floor_area
|
||||
self._thermal_boundaries = thermal_boundaries
|
||||
self._is_mechanically_ventilated = None
|
||||
self._additional_thermal_bridge_u_value = None
|
||||
self._effective_thermal_capacity = None
|
||||
self._indirectly_heated_area_ratio = None
|
||||
self._infiltration_rate_system_on = None
|
||||
self._infiltration_rate_system_off = None
|
||||
self._usage_zones = []
|
||||
self._volume = volume
|
||||
self._volume_geometry = None
|
||||
self._id = None
|
||||
self._ordinate_number = None
|
||||
self._usage_zones = None
|
||||
self._thermal_control = None
|
||||
self._hvac_system = None
|
||||
self._view_factors_matrix = None
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
|
@ -43,34 +45,11 @@ class ThermalZone:
|
|||
return self._id
|
||||
|
||||
@property
|
||||
def is_mechanically_ventilated(self) -> Union[None, bool]:
|
||||
"""
|
||||
Get thermal zone mechanical ventilation flag
|
||||
:return: None or Boolean
|
||||
"""
|
||||
return self._is_mechanically_ventilated
|
||||
|
||||
@is_mechanically_ventilated.setter
|
||||
def is_mechanically_ventilated(self, value):
|
||||
"""
|
||||
Set thermal zone mechanical ventilation flag
|
||||
:param value: Boolean
|
||||
"""
|
||||
if value is not None:
|
||||
self._is_mechanically_ventilated = ast.literal_eval(value)
|
||||
|
||||
@property
|
||||
def floor_area(self):
|
||||
def floor_area(self) -> float:
|
||||
"""
|
||||
Get thermal zone floor area in m2
|
||||
:return: float
|
||||
"""
|
||||
if self._floor_area is None:
|
||||
self._floor_area = 0
|
||||
for thermal_boundary in self.thermal_boundaries:
|
||||
s = thermal_boundary.surface
|
||||
if s.type == 'Ground':
|
||||
self._floor_area += s.perimeter_polygon.area
|
||||
return self._floor_area
|
||||
|
||||
@property
|
||||
|
@ -133,10 +112,10 @@ class ThermalZone:
|
|||
self._indirectly_heated_area_ratio = float(value)
|
||||
|
||||
@property
|
||||
def infiltration_rate_system_on(self) -> Union[None, float]:
|
||||
def infiltration_rate_system_on(self) -> Union[None, Schedule]:
|
||||
"""
|
||||
Get thermal zone infiltration rate system on in air changes per hour (ACH)
|
||||
:return: None or float
|
||||
:return: None or Schedule
|
||||
"""
|
||||
return self._infiltration_rate_system_on
|
||||
|
||||
|
@ -144,16 +123,15 @@ class ThermalZone:
|
|||
def infiltration_rate_system_on(self, value):
|
||||
"""
|
||||
Set thermal zone infiltration rate system on in air changes per hour (ACH)
|
||||
:param value: float
|
||||
:param value: Schedule
|
||||
"""
|
||||
if value is not None:
|
||||
self._infiltration_rate_system_on = float(value)
|
||||
self._infiltration_rate_system_on = value
|
||||
|
||||
@property
|
||||
def infiltration_rate_system_off(self) -> Union[None, float]:
|
||||
def infiltration_rate_system_off(self) -> Union[None, Schedule]:
|
||||
"""
|
||||
Get thermal zone infiltration rate system off in air changes per hour (ACH)
|
||||
:return: None or float
|
||||
:return: None or Schedule
|
||||
"""
|
||||
return self._infiltration_rate_system_off
|
||||
|
||||
|
@ -161,26 +139,9 @@ class ThermalZone:
|
|||
def infiltration_rate_system_off(self, value):
|
||||
"""
|
||||
Set thermal zone infiltration rate system on in air changes per hour (ACH)
|
||||
:param value: float
|
||||
:param value: Schedule
|
||||
"""
|
||||
if value is not None:
|
||||
self._infiltration_rate_system_off = float(value)
|
||||
|
||||
@property
|
||||
def usage_zones(self) -> List[UsageZone]:
|
||||
"""
|
||||
Get thermal zone usage zones
|
||||
:return: [UsageZone]
|
||||
"""
|
||||
return self._usage_zones
|
||||
|
||||
@usage_zones.setter
|
||||
def usage_zones(self, values):
|
||||
"""
|
||||
Set thermal zone usage zones
|
||||
:param values: [UsageZone]
|
||||
"""
|
||||
self._usage_zones = values
|
||||
self._infiltration_rate_system_off = value
|
||||
|
||||
@property
|
||||
def volume(self):
|
||||
|
@ -190,14 +151,6 @@ class ThermalZone:
|
|||
"""
|
||||
return self._volume
|
||||
|
||||
@property
|
||||
def volume_geometry(self) -> Polyhedron:
|
||||
"""
|
||||
Get the polyhedron defined by the thermal zone
|
||||
:return: Polyhedron
|
||||
"""
|
||||
return self._volume_geometry
|
||||
|
||||
@property
|
||||
def ordinate_number(self) -> Union[None, int]:
|
||||
"""
|
||||
|
@ -214,3 +167,73 @@ class ThermalZone:
|
|||
"""
|
||||
if value is not None:
|
||||
self._ordinate_number = int(value)
|
||||
|
||||
@property
|
||||
def usage_zones(self) -> [UsageZone]:
|
||||
"""
|
||||
Get list of usage zones and the percentage of thermal zone's volume affected by that usage
|
||||
From internal_zone
|
||||
:return: [UsageZone]
|
||||
"""
|
||||
return self._usage_zones
|
||||
|
||||
@usage_zones.setter
|
||||
def usage_zones(self, values):
|
||||
"""
|
||||
Set list of usage zones and the percentage of thermal zone's volume affected by that usage
|
||||
From internal_zone
|
||||
:param values: [UsageZone]
|
||||
"""
|
||||
self._usage_zones = values
|
||||
|
||||
@property
|
||||
def thermal_control(self) -> Union[None, ThermalControl]:
|
||||
"""
|
||||
Get thermal control of this thermal zone
|
||||
From internal_zone
|
||||
:return: None or ThermalControl
|
||||
"""
|
||||
return self._thermal_control
|
||||
|
||||
@thermal_control.setter
|
||||
def thermal_control(self, value):
|
||||
"""
|
||||
Set thermal control for this thermal zone
|
||||
From internal_zone
|
||||
:param value: ThermalControl
|
||||
"""
|
||||
self._thermal_control = value
|
||||
|
||||
@property
|
||||
def hvac_system(self) -> Union[None, HvacSystem]:
|
||||
"""
|
||||
Get HVAC system installed for this thermal zone
|
||||
From internal_zone
|
||||
:return: None or HvacSystem
|
||||
"""
|
||||
return self._hvac_system
|
||||
|
||||
@hvac_system.setter
|
||||
def hvac_system(self, value):
|
||||
"""
|
||||
Set HVAC system installed for this thermal zone
|
||||
From internal_zone
|
||||
:param value: HvacSystem
|
||||
"""
|
||||
self._hvac_system = value
|
||||
|
||||
@property
|
||||
def view_factors_matrix(self):
|
||||
"""
|
||||
Get thermal zone view factors matrix
|
||||
:return: [[float]]
|
||||
"""
|
||||
return self._view_factors_matrix
|
||||
|
||||
@view_factors_matrix.setter
|
||||
def view_factors_matrix(self, value):
|
||||
"""
|
||||
Set thermal zone view factors matrix
|
||||
:param value: [[float]]
|
||||
"""
|
||||
self._view_factors_matrix = value
|
||||
|
|
|
@ -5,13 +5,13 @@ Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.mons
|
|||
Contributors Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
import uuid
|
||||
from typing import List, TypeVar, Union
|
||||
import ast
|
||||
|
||||
InternalGains = TypeVar('InternalGains')
|
||||
Occupants = TypeVar('Occupants')
|
||||
Polyhedron = TypeVar('Polyhedron')
|
||||
Schedule = TypeVar('Schedule')
|
||||
from typing import List, Union
|
||||
import helpers.constants as cte
|
||||
from city_model_structure.building_demand.internal_gains import InternalGains
|
||||
from city_model_structure.building_demand.occupancy import Occupancy
|
||||
from city_model_structure.building_demand.lighting import Lighting
|
||||
from city_model_structure.building_demand.appliances import Appliances
|
||||
from city_model_structure.building_demand.thermal_control import ThermalControl
|
||||
|
||||
|
||||
class UsageZone:
|
||||
|
@ -21,23 +21,17 @@ class UsageZone:
|
|||
def __init__(self):
|
||||
self._id = None
|
||||
self._usage = None
|
||||
self._internal_gains = None
|
||||
self._heating_setpoint = None
|
||||
self._heating_setback = None
|
||||
self._cooling_setpoint = None
|
||||
self._occupancy_density = None
|
||||
self._percentage = None
|
||||
self._not_detailed_source_mean_annual_internal_gains = None
|
||||
self._hours_day = None
|
||||
self._days_year = None
|
||||
self._dhw_average_volume_pers_day = None
|
||||
self._dhw_preparation_temperature = None
|
||||
self._electrical_app_average_consumption_sqm_year = None
|
||||
# self._electrical_app_average_consumption_sqm_year = None
|
||||
self._mechanical_air_change = None
|
||||
self._occupants = None
|
||||
self._schedules = None
|
||||
self._volume = None
|
||||
self._volume_geometry = None
|
||||
self._is_heated = False
|
||||
self._is_cooled = False
|
||||
self._occupancy = None
|
||||
self._lighting = None
|
||||
self._appliances = None
|
||||
self._internal_gains = None
|
||||
self._thermal_control = None
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
|
@ -50,71 +44,54 @@ class UsageZone:
|
|||
return self._id
|
||||
|
||||
@property
|
||||
def internal_gains(self) -> List[InternalGains]:
|
||||
def usage(self) -> Union[None, str]:
|
||||
"""
|
||||
Get usage zone internal gains
|
||||
Get usage zone usage
|
||||
:return: None or str
|
||||
"""
|
||||
return self._usage
|
||||
|
||||
@usage.setter
|
||||
def usage(self, value):
|
||||
"""
|
||||
Set usage zone usage
|
||||
:param value: str
|
||||
"""
|
||||
if value is not None:
|
||||
self._usage = str(value)
|
||||
|
||||
@property
|
||||
def percentage(self):
|
||||
"""
|
||||
Get usage zone percentage in range[0,1]
|
||||
:return: float
|
||||
"""
|
||||
return self._percentage
|
||||
|
||||
@percentage.setter
|
||||
def percentage(self, value):
|
||||
"""
|
||||
Set usage zone percentage in range[0,1]
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._percentage = float(value)
|
||||
|
||||
@property
|
||||
def not_detailed_source_mean_annual_internal_gains(self) -> List[InternalGains]:
|
||||
"""
|
||||
Get usage zone internal gains with unknown energy source
|
||||
:return: [InternalGains]
|
||||
"""
|
||||
return self._internal_gains
|
||||
return self._not_detailed_source_mean_annual_internal_gains
|
||||
|
||||
@internal_gains.setter
|
||||
def internal_gains(self, value):
|
||||
@not_detailed_source_mean_annual_internal_gains.setter
|
||||
def not_detailed_source_mean_annual_internal_gains(self, value):
|
||||
"""
|
||||
Set usage zone internal gains
|
||||
Set usage zone internal gains with unknown energy source
|
||||
:param value: [InternalGains]
|
||||
"""
|
||||
self._internal_gains = value
|
||||
|
||||
@property
|
||||
def heating_setpoint(self) -> Union[None, float]:
|
||||
"""
|
||||
Get usage zone heating set point in Celsius
|
||||
:return: None or float
|
||||
"""
|
||||
return self._heating_setpoint
|
||||
|
||||
@heating_setpoint.setter
|
||||
def heating_setpoint(self, value):
|
||||
"""
|
||||
Set usage zone heating set point in Celsius
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._heating_setpoint = float(value)
|
||||
|
||||
@property
|
||||
def heating_setback(self) -> Union[None, float]:
|
||||
"""
|
||||
Get usage zone heating setback in Celsius
|
||||
:return: None or float
|
||||
"""
|
||||
return self._heating_setback
|
||||
|
||||
@heating_setback.setter
|
||||
def heating_setback(self, value):
|
||||
"""
|
||||
Set usage zone heating setback in Celsius
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._heating_setback = float(value)
|
||||
|
||||
@property
|
||||
def cooling_setpoint(self) -> Union[None, float]:
|
||||
"""
|
||||
Get usage zone cooling setpoint in Celsius
|
||||
:return: None or float
|
||||
"""
|
||||
return self._cooling_setpoint
|
||||
|
||||
@cooling_setpoint.setter
|
||||
def cooling_setpoint(self, value):
|
||||
"""
|
||||
Set usage zone cooling setpoint in Celsius
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._cooling_setpoint = float(value)
|
||||
self._not_detailed_source_mean_annual_internal_gains = value
|
||||
|
||||
@property
|
||||
def hours_day(self) -> Union[None, float]:
|
||||
|
@ -167,106 +144,6 @@ class UsageZone:
|
|||
if value is not None:
|
||||
self._mechanical_air_change = float(value)
|
||||
|
||||
@property
|
||||
def usage(self) -> Union[None, str]:
|
||||
"""
|
||||
Get usage zone usage
|
||||
:return: None or str
|
||||
"""
|
||||
return self._usage
|
||||
|
||||
@usage.setter
|
||||
def usage(self, value):
|
||||
"""
|
||||
Set usage zone usage
|
||||
:param value: str
|
||||
"""
|
||||
if value is not None:
|
||||
self._usage = str(value)
|
||||
|
||||
@property
|
||||
def occupants(self) -> List[Occupants]:
|
||||
"""
|
||||
Get occupants data
|
||||
:return: [Occupants]
|
||||
"""
|
||||
return self._occupants
|
||||
|
||||
@occupants.setter
|
||||
def occupants(self, values):
|
||||
"""
|
||||
Set occupants data
|
||||
:param values: [Occupants]
|
||||
"""
|
||||
self._occupants = values
|
||||
|
||||
@property
|
||||
def schedules(self) -> List[Schedule]:
|
||||
"""
|
||||
Get usage zone schedules
|
||||
:return: List[Schedule]
|
||||
"""
|
||||
return self._schedules
|
||||
|
||||
@schedules.setter
|
||||
def schedules(self, values):
|
||||
"""
|
||||
Set usage zone schedules
|
||||
:param values: List[Schedule]
|
||||
"""
|
||||
self._schedules = values
|
||||
|
||||
@property
|
||||
def occupancy_density(self) -> Union[None, float]:
|
||||
"""
|
||||
Get density in persons per m2
|
||||
:return: None or float
|
||||
"""
|
||||
return self._occupancy_density
|
||||
|
||||
@occupancy_density.setter
|
||||
def occupancy_density(self, value):
|
||||
"""
|
||||
Set density in persons per m2
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._occupancy_density = float(value)
|
||||
|
||||
@property
|
||||
def dhw_average_volume_pers_day(self) -> Union[None, float]:
|
||||
"""
|
||||
Get average DHW consumption in cubic meters per person per day
|
||||
:return: None or float
|
||||
"""
|
||||
return self._dhw_average_volume_pers_day
|
||||
|
||||
@dhw_average_volume_pers_day.setter
|
||||
def dhw_average_volume_pers_day(self, value):
|
||||
"""
|
||||
Set average DHW consumption in cubic meters per person per day
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._dhw_average_volume_pers_day = float(value)
|
||||
|
||||
@property
|
||||
def dhw_preparation_temperature(self) -> Union[None, float]:
|
||||
"""
|
||||
Get preparation temperature of the DHW in Celsius
|
||||
:return: None or float
|
||||
"""
|
||||
return self._dhw_preparation_temperature
|
||||
|
||||
@dhw_preparation_temperature.setter
|
||||
def dhw_preparation_temperature(self, value):
|
||||
"""
|
||||
Set preparation temperature of the DHW in Celsius
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._dhw_preparation_temperature = float(value)
|
||||
|
||||
@property
|
||||
def electrical_app_average_consumption_sqm_year(self) -> Union[None, float]:
|
||||
"""
|
||||
|
@ -285,60 +162,109 @@ class UsageZone:
|
|||
self._electrical_app_average_consumption_sqm_year = float(value)
|
||||
|
||||
@property
|
||||
def volume_geometry(self) -> Polyhedron:
|
||||
def occupancy(self) -> Union[None, Occupancy]:
|
||||
"""
|
||||
Get the polyhedron defined by the usage zone
|
||||
:return: Polyhedron
|
||||
Get occupancy in the usage zone
|
||||
:return: None or Occupancy
|
||||
"""
|
||||
return self._volume_geometry
|
||||
return self._occupancy
|
||||
|
||||
@occupancy.setter
|
||||
def occupancy(self, value):
|
||||
"""
|
||||
Set occupancy in the usage zone
|
||||
:param value: Occupancy
|
||||
"""
|
||||
self._occupancy = value
|
||||
|
||||
@property
|
||||
def volume(self) -> Union[None, float]:
|
||||
def lighting(self) -> Union[None, Lighting]:
|
||||
"""
|
||||
Get the volume in cubic meters
|
||||
:return: None or float
|
||||
Get lighting information
|
||||
:return: None or Lighting
|
||||
"""
|
||||
return self._volume
|
||||
return self._lighting
|
||||
|
||||
@volume.setter
|
||||
def volume(self, value):
|
||||
@lighting.setter
|
||||
def lighting(self, value):
|
||||
"""
|
||||
Set volume in cubic meters
|
||||
:param value: float
|
||||
Set lighting information
|
||||
:param value: Lighting
|
||||
"""
|
||||
if value is not None:
|
||||
self._volume = float(value)
|
||||
self._lighting = value
|
||||
|
||||
@property
|
||||
def is_heated(self) -> Union[None, bool]:
|
||||
def appliances(self) -> Union[None, Appliances]:
|
||||
"""
|
||||
Get thermal zone heated flag
|
||||
:return: None or Boolean
|
||||
Get appliances information
|
||||
:return: None or Appliances
|
||||
"""
|
||||
return self._is_heated
|
||||
return self._appliances
|
||||
|
||||
@is_heated.setter
|
||||
def is_heated(self, value):
|
||||
@appliances.setter
|
||||
def appliances(self, value):
|
||||
"""
|
||||
Set thermal zone heated flag
|
||||
:param value: Boolean
|
||||
Set appliances information
|
||||
:param value: Appliances
|
||||
"""
|
||||
if value is not None:
|
||||
self._is_heated = ast.literal_eval(value)
|
||||
self._appliances = value
|
||||
|
||||
def get_internal_gains(self) -> [InternalGains]:
|
||||
"""
|
||||
Calculates and returns the list of all internal gains defined
|
||||
:return: InternalGains
|
||||
"""
|
||||
if self.occupancy is not None:
|
||||
if self.occupancy.latent_internal_gain is not None:
|
||||
_internal_gain = InternalGains()
|
||||
_internal_gain.type = cte.OCCUPANCY
|
||||
_total_heat_gain = (self.occupancy.sensible_convective_internal_gain
|
||||
+ self.occupancy.sensible_radiative_internal_gain
|
||||
+ self.occupancy.latent_internal_gain)
|
||||
_internal_gain.average_internal_gain = _total_heat_gain
|
||||
_internal_gain.latent_fraction = self.occupancy.latent_internal_gain / _total_heat_gain
|
||||
_internal_gain.radiative_fraction = self.occupancy.sensible_radiative_internal_gain / _total_heat_gain
|
||||
_internal_gain.convective_fraction = self.occupancy.sensible_convective_internal_gain / _total_heat_gain
|
||||
_internal_gain.schedules = self.occupancy.occupancy_schedules
|
||||
self._internal_gains = [_internal_gain]
|
||||
if self.lighting is not None:
|
||||
_internal_gain = InternalGains()
|
||||
_internal_gain.type = cte.LIGHTING
|
||||
_internal_gain.average_internal_gain = self.lighting.lighting_density
|
||||
_internal_gain.latent_fraction = self.lighting.latent_fraction
|
||||
_internal_gain.radiative_fraction = self.lighting.radiative_fraction
|
||||
_internal_gain.convective_fraction = self.lighting.convective_fraction
|
||||
_internal_gain.schedules = self.lighting.schedules
|
||||
if self._internal_gains is not None:
|
||||
self._internal_gains.append(_internal_gain)
|
||||
else:
|
||||
self._internal_gains = [_internal_gain]
|
||||
if self.appliances is not None:
|
||||
_internal_gain = InternalGains()
|
||||
_internal_gain.type = cte.APPLIANCES
|
||||
_internal_gain.average_internal_gain = self.appliances.appliances_density
|
||||
_internal_gain.latent_fraction = self.appliances.latent_fraction
|
||||
_internal_gain.radiative_fraction = self.appliances.radiative_fraction
|
||||
_internal_gain.convective_fraction = self.appliances.convective_fraction
|
||||
_internal_gain.schedules = self.appliances.schedules
|
||||
if self._internal_gains is not None:
|
||||
self._internal_gains.append(_internal_gain)
|
||||
else:
|
||||
self._internal_gains = [_internal_gain]
|
||||
return self._internal_gains
|
||||
|
||||
@property
|
||||
def is_cooled(self) -> Union[None, bool]:
|
||||
def thermal_control(self) -> Union[None, ThermalControl]:
|
||||
"""
|
||||
Get thermal zone cooled flag
|
||||
:return: None or Boolean
|
||||
Get thermal control of this thermal zone
|
||||
:return: None or ThermalControl
|
||||
"""
|
||||
return self._is_cooled
|
||||
return self._thermal_control
|
||||
|
||||
@is_cooled.setter
|
||||
def is_cooled(self, value):
|
||||
@thermal_control.setter
|
||||
def thermal_control(self, value):
|
||||
"""
|
||||
Set thermal zone cooled flag
|
||||
:param value: Boolean
|
||||
Set thermal control for this thermal zone
|
||||
:param value: ThermalControl
|
||||
"""
|
||||
if value is not None:
|
||||
self._is_cooled = ast.literal_eval(value)
|
||||
self._thermal_control = value
|
||||
|
|
|
@ -36,13 +36,21 @@ class CityObject:
|
|||
self._beam = dict()
|
||||
self._sensors = []
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""
|
||||
Get building name
|
||||
:return: str
|
||||
"""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def lod(self) -> int:
|
||||
"""
|
||||
Get city object level of detail 1, 2, 3 or 4
|
||||
:return: int
|
||||
"""
|
||||
lod = math.log(self._lod, 2) + 1
|
||||
lod = int(math.log(self._lod, 2) + 1)
|
||||
return lod
|
||||
|
||||
@property
|
||||
|
|
32
city_model_structure/energy_systems/hvac_system.py
Normal file
32
city_model_structure/energy_systems/hvac_system.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
"""
|
||||
HvacSystem module
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
from typing import Union
|
||||
|
||||
|
||||
class HvacSystem:
|
||||
"""
|
||||
HvacSystem class
|
||||
"""
|
||||
def __init__(self):
|
||||
self._type = None
|
||||
|
||||
@property
|
||||
def type(self) -> Union[None, str]:
|
||||
"""
|
||||
Get hvac system type a thermal zone
|
||||
:return: None or str
|
||||
"""
|
||||
return self._type
|
||||
|
||||
@type.setter
|
||||
def type(self, value):
|
||||
"""
|
||||
Set heating set point defined for a thermal zone
|
||||
:param value: str
|
||||
"""
|
||||
if value is not None:
|
||||
self._type = str(value)
|
||||
|
45
city_model_structure/iot/concordia_energy_sensor.py
Normal file
45
city_model_structure/iot/concordia_energy_sensor.py
Normal file
|
@ -0,0 +1,45 @@
|
|||
"""
|
||||
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')
|
45
city_model_structure/iot/concordia_gas_flow_sensor.py
Normal file
45
city_model_structure/iot/concordia_gas_flow_sensor.py
Normal file
|
@ -0,0 +1,45 @@
|
|||
"""
|
||||
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')
|
45
city_model_structure/iot/concordia_temperature_sensor.py
Normal file
45
city_model_structure/iot/concordia_temperature_sensor.py
Normal file
|
@ -0,0 +1,45 @@
|
|||
"""
|
||||
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')
|
|
@ -1,73 +1,76 @@
|
|||
"""
|
||||
Sensor module
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
import uuid
|
||||
|
||||
from city_model_structure.iot.sensor_measure import SensorMeasure
|
||||
from city_model_structure.iot.sensor_type import SensorType
|
||||
from helpers.location import Location
|
||||
|
||||
|
||||
class Sensor:
|
||||
"""
|
||||
Sensor abstract class
|
||||
"""
|
||||
def __init__(self, sensor_id=None, model=None, sensor_type=None, indoor=False, board=None):
|
||||
self._id = sensor_id
|
||||
self._model = model
|
||||
self._type = sensor_type
|
||||
self._indoor = indoor
|
||||
self._board = board
|
||||
self._measures = []
|
||||
def __init__(self):
|
||||
self._name = None
|
||||
self._type = None
|
||||
self._units = None
|
||||
self._location = None
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
def name(self):
|
||||
"""
|
||||
Get the sensor id a random uuid will be assigned if no ID was provided to the constructor
|
||||
:return: Id
|
||||
Get sensor name
|
||||
:return: str
|
||||
"""
|
||||
if self._id is None:
|
||||
self._id = uuid.uuid4()
|
||||
return self._id
|
||||
if self._name is None:
|
||||
raise ValueError('Undefined sensor name')
|
||||
return self._name
|
||||
|
||||
@name.setter
|
||||
def name(self, value):
|
||||
"""
|
||||
Set sensor name
|
||||
:param value: str
|
||||
"""
|
||||
if value is not None:
|
||||
self._name = str(value)
|
||||
|
||||
@property
|
||||
def type(self) -> SensorType:
|
||||
def type(self):
|
||||
"""
|
||||
Get sensor type
|
||||
:return: SensorTypeEnum or Error
|
||||
:return: str
|
||||
"""
|
||||
if self._type is None:
|
||||
raise ValueError('Unknown sensor type')
|
||||
return self._type
|
||||
|
||||
@property
|
||||
def model(self):
|
||||
def units(self):
|
||||
"""
|
||||
Get sensor model is any
|
||||
:return: str or None
|
||||
Get sensor units
|
||||
:return: str
|
||||
"""
|
||||
return self._model
|
||||
return self._units
|
||||
|
||||
@property
|
||||
def board(self):
|
||||
def location(self) -> Location:
|
||||
"""
|
||||
Get sensor board if any
|
||||
:return: str or None
|
||||
Get sensor location
|
||||
:return: Location
|
||||
"""
|
||||
return self._model
|
||||
return self._location
|
||||
|
||||
@location.setter
|
||||
def location(self, value):
|
||||
"""
|
||||
Set sensor location
|
||||
:param value: Location
|
||||
"""
|
||||
self._location = value
|
||||
|
||||
@property
|
||||
def indoor(self):
|
||||
"""
|
||||
Get is the sensor it's located indoor or outdoor
|
||||
:return: boolean
|
||||
"""
|
||||
return self._indoor
|
||||
|
||||
@property
|
||||
def measures(self) -> [SensorMeasure]:
|
||||
def measures(self):
|
||||
"""
|
||||
Raises not implemented error
|
||||
"""
|
||||
return self._measures
|
||||
raise NotImplementedError
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
"""
|
||||
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
|
|
@ -1,20 +0,0 @@
|
|||
"""
|
||||
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
|
|
@ -1,41 +0,0 @@
|
|||
"""
|
||||
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
|
|
@ -1,242 +0,0 @@
|
|||
"""
|
||||
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)
|
|
@ -11,3 +11,5 @@ comnet_occupancy_sensible_radiant = 0.1
|
|||
comnet_plugs_latent = 0
|
||||
comnet_plugs_convective = 0.75
|
||||
comnet_plugs_radiant = 0.25
|
||||
convective_heat_transfer_coefficient_interior = 3.5
|
||||
convective_heat_transfer_coefficient_exterior = 20
|
||||
|
|
|
@ -105,84 +105,52 @@
|
|||
#wall below grade
|
||||
<construction type="basement_wall" id="17" name="wall below grade_post 2010">
|
||||
<overall_u_value units="W/m2 K">0.512</overall_u_value>
|
||||
<outside_solar_absorptance units="-">0</outside_solar_absorptance>
|
||||
<shortwave_reflectance units="-">0</shortwave_reflectance>
|
||||
</construction>
|
||||
<construction type="basement_wall" id="18" name="wall below grade_2001-2010">
|
||||
<overall_u_value units="W/m2 K">0.512</overall_u_value>
|
||||
<outside_solar_absorptance units="-">0</outside_solar_absorptance>
|
||||
<shortwave_reflectance units="-">0</shortwave_reflectance>
|
||||
</construction>
|
||||
<construction type="basement_wall" id="19" name="wall below grade_1996-2000">
|
||||
<overall_u_value units="W/m2 K">0.67</overall_u_value>
|
||||
<outside_solar_absorptance units="-">0</outside_solar_absorptance>
|
||||
<shortwave_reflectance units="-">0</shortwave_reflectance>
|
||||
</construction>
|
||||
<construction type="basement_wall" id="20" name="wall below grade_1984-1995">
|
||||
<overall_u_value units="W/m2 K">0.848</overall_u_value>
|
||||
<outside_solar_absorptance units="-">0</outside_solar_absorptance>
|
||||
<shortwave_reflectance units="-">0</shortwave_reflectance>
|
||||
</construction>
|
||||
<construction type="basement_wall" id="21" name="wall below grade_1978-1983">
|
||||
<overall_u_value units="W/m2 K">1.048</overall_u_value>
|
||||
<outside_solar_absorptance units="-">0</outside_solar_absorptance>
|
||||
<shortwave_reflectance units="-">0</shortwave_reflectance>
|
||||
</construction>
|
||||
<construction type="basement_wall" id="22" name="wall below grade_1961-1977">
|
||||
<overall_u_value units="W/m2 K">1.154</overall_u_value>
|
||||
<outside_solar_absorptance units="-">0</outside_solar_absorptance>
|
||||
<shortwave_reflectance units="-">0</shortwave_reflectance>
|
||||
</construction>
|
||||
<construction type="basement_wall" id="23" name="wall below grade_1946-1960">
|
||||
<overall_u_value units="W/m2 K">1.243</overall_u_value>
|
||||
<outside_solar_absorptance units="-">0</outside_solar_absorptance>
|
||||
<shortwave_reflectance units="-">0</shortwave_reflectance>
|
||||
</construction>
|
||||
<construction type="basement_wall" id="24" name="wall below grade_before 1946">
|
||||
<overall_u_value units="W/m2 K">1.425</overall_u_value>
|
||||
<outside_solar_absorptance units="-">0</outside_solar_absorptance>
|
||||
<shortwave_reflectance units="-">0</shortwave_reflectance>
|
||||
</construction>
|
||||
#slab on grade
|
||||
<construction type="floor" id="25" name="slab on grade_post 2010">
|
||||
<overall_u_value units="W/m2 K">0.512</overall_u_value>
|
||||
<outside_solar_absorptance units="-">0</outside_solar_absorptance>
|
||||
<shortwave_reflectance units="-">0</shortwave_reflectance>
|
||||
</construction>
|
||||
<construction type="floor" id="26" name="slab on grade_2001-2010">
|
||||
<overall_u_value units="W/m2 K">0.67</overall_u_value>
|
||||
<outside_solar_absorptance units="-">0</outside_solar_absorptance>
|
||||
<shortwave_reflectance units="-">0</shortwave_reflectance>
|
||||
</construction>
|
||||
<construction type="floor" id="27" name="slab on grade_1996-2000">
|
||||
<overall_u_value units="W/m2 K">0.67</overall_u_value>
|
||||
<outside_solar_absorptance units="-">0</outside_solar_absorptance>
|
||||
<shortwave_reflectance units="-">0</shortwave_reflectance>
|
||||
</construction>
|
||||
<construction type="floor" id="28" name="slab on grade_1984-1995">
|
||||
<overall_u_value units="W/m2 K">0.848</overall_u_value>
|
||||
<outside_solar_absorptance units="-">0</outside_solar_absorptance>
|
||||
<shortwave_reflectance units="-">0</shortwave_reflectance>
|
||||
</construction>
|
||||
<construction type="floor" id="29" name="slab on grade_1978-1983">
|
||||
<overall_u_value units="W/m2 K">0.848</overall_u_value>
|
||||
<outside_solar_absorptance units="-">0</outside_solar_absorptance>
|
||||
<shortwave_reflectance units="-">0</shortwave_reflectance>
|
||||
</construction>
|
||||
<construction type="floor" id="30" name="slab on grade_1961-1977">
|
||||
<overall_u_value units="W/m2 K">1.05</overall_u_value>
|
||||
<outside_solar_absorptance units="-">0</outside_solar_absorptance>
|
||||
<shortwave_reflectance units="-">0</shortwave_reflectance>
|
||||
</construction>
|
||||
<construction type="floor" id="31" name="slab on grade_1946-1960">
|
||||
<overall_u_value units="W/m2 K">1.154</overall_u_value>
|
||||
<outside_solar_absorptance units="-">0</outside_solar_absorptance>
|
||||
<shortwave_reflectance units="-">0</shortwave_reflectance>
|
||||
</construction>
|
||||
<construction type="floor" id="32" name="slab on grade_before 1946">
|
||||
<overall_u_value units="W/m2 K">1.154</overall_u_value>
|
||||
<outside_solar_absorptance units="-">0</outside_solar_absorptance>
|
||||
<shortwave_reflectance units="-">0</shortwave_reflectance>
|
||||
</construction>
|
||||
</constructions>
|
||||
</library>
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
</window>
|
||||
</windows>
|
||||
<materials>
|
||||
<material id="1" name="MAT-CC05 8 HW CONCRETE" lca_id="7">
|
||||
<material id="1" name="MAT-CC05 8 HW CONCRETE">
|
||||
<conductivity units="W/m K">1.311</conductivity>
|
||||
<density units="kg/m3">2240</density>
|
||||
<specific_heat units="J/kg K">836.8</specific_heat>
|
||||
|
@ -47,14 +47,14 @@
|
|||
<solar_absorptance units="-">0.7</solar_absorptance>
|
||||
<visible_absorptance units="-">0.7</visible_absorptance>
|
||||
</material>
|
||||
<material id="2" name="CP02 CARPET PAD" lca_id="7">
|
||||
<material id="2" name="CP02 CARPET PAD">
|
||||
<no_mass>true</no_mass>
|
||||
<thermal_resistance units="m2 K/W">0.21648</thermal_resistance>
|
||||
<thermal_absorptance units="-">0.9</thermal_absorptance>
|
||||
<solar_absorptance units="-">0.7</solar_absorptance>
|
||||
<visible_absorptance units="-">0.8</visible_absorptance>
|
||||
</material>
|
||||
<material id="3" name="Floor Insulation [4]" lca_id="7">
|
||||
<material id="3" name="Floor Insulation [4]">
|
||||
<conductivity units="W/m K">0.045</conductivity>
|
||||
<density units="kg/m3">265</density>
|
||||
<specific_heat units="J/kg K">836.8</specific_heat>
|
||||
|
@ -62,7 +62,7 @@
|
|||
<solar_absorptance units="-">0.7</solar_absorptance>
|
||||
<visible_absorptance units="-">0.7</visible_absorptance>
|
||||
</material>
|
||||
<material id="4" name="1IN Stucco" lca_id="7">
|
||||
<material id="4" name="1IN Stucco">
|
||||
<conductivity units="W/m K">0.6918</conductivity>
|
||||
<density units="kg/m3">1858</density>
|
||||
<specific_heat units="J/kg K">837</specific_heat>
|
||||
|
@ -70,7 +70,7 @@
|
|||
<solar_absorptance units="-">0.92</solar_absorptance>
|
||||
<visible_absorptance units="-">0.92</visible_absorptance>
|
||||
</material>
|
||||
<material id="5" name="8IN Concrete HW" lca_id="7">
|
||||
<material id="5" name="8IN Concrete HW">
|
||||
<conductivity units="W/m K">1.7296</conductivity>
|
||||
<density units="kg/m3">2243</density>
|
||||
<specific_heat units="J/kg K">837</specific_heat>
|
||||
|
@ -78,7 +78,7 @@
|
|||
<solar_absorptance units="-">0.65</solar_absorptance>
|
||||
<visible_absorptance units="-">0.65</visible_absorptance>
|
||||
</material>
|
||||
<material id="6" name="Wall Insulation [37]" lca_id="7">
|
||||
<material id="6" name="Wall Insulation [37]">
|
||||
<conductivity units="W/m K">0.0432</conductivity>
|
||||
<density units="kg/m3">91</density>
|
||||
<specific_heat units="J/kg K">837</specific_heat>
|
||||
|
@ -86,7 +86,7 @@
|
|||
<solar_absorptance units="-">0.5</solar_absorptance>
|
||||
<visible_absorptance units="-">0.5</visible_absorptance>
|
||||
</material>
|
||||
<material id="7" name="1/2IN Gypsum" lca_id="7">
|
||||
<material id="7" name="1/2IN Gypsum">
|
||||
<conductivity units="W/m K">0.16</conductivity>
|
||||
<density units="kg/m3">784.9</density>
|
||||
<specific_heat units="J/kg K">830</specific_heat>
|
||||
|
@ -94,7 +94,7 @@
|
|||
<solar_absorptance units="-">0.92</solar_absorptance>
|
||||
<visible_absorptance units="-">0.92</visible_absorptance>
|
||||
</material>
|
||||
<material id="8" name="Wood Siding" lca_id="7">
|
||||
<material id="8" name="Wood Siding">
|
||||
<conductivity units="W/m K">0.11</conductivity>
|
||||
<density units="kg/m3">544.62</density>
|
||||
<specific_heat units="J/kg K">1210</specific_heat>
|
||||
|
@ -102,7 +102,7 @@
|
|||
<solar_absorptance units="-">0.78</solar_absorptance>
|
||||
<visible_absorptance units="-">0.78</visible_absorptance>
|
||||
</material>
|
||||
<material id="9" name="Wood Shingles" lca_id="7">
|
||||
<material id="9" name="Wood Shingles">
|
||||
<conductivity units="W/m K">0.115</conductivity>
|
||||
<density units="kg/m3">513</density>
|
||||
<specific_heat units="J/kg K">1255</specific_heat>
|
||||
|
@ -110,7 +110,7 @@
|
|||
<solar_absorptance units="-">0.78</solar_absorptance>
|
||||
<visible_absorptance units="-">0.78</visible_absorptance>
|
||||
</material>
|
||||
<material id="10" name="1IN Wood Decking" lca_id="7">
|
||||
<material id="10" name="1IN Wood Decking">
|
||||
<conductivity units="W/m K">0.1211</conductivity>
|
||||
<density units="kg/m3">593</density>
|
||||
<specific_heat units="J/kg K">2510</specific_heat>
|
||||
|
@ -118,7 +118,7 @@
|
|||
<solar_absorptance units="-">0.78</solar_absorptance>
|
||||
<visible_absorptance units="-">0.78</visible_absorptance>
|
||||
</material>
|
||||
<material id="11" name="Roof Insulation [23]" lca_id="7">
|
||||
<material id="11" name="Roof Insulation [23]">
|
||||
<conductivity units="W/m K">0.049</conductivity>
|
||||
<density units="kg/m3">265</density>
|
||||
<specific_heat units="J/kg K">836.8</specific_heat>
|
||||
|
@ -126,14 +126,14 @@
|
|||
<solar_absorptance units="-">0.7</solar_absorptance>
|
||||
<visible_absorptance units="-">0.7</visible_absorptance>
|
||||
</material>
|
||||
<material id="12" name="MAT-SHEATH" lca_id="7">
|
||||
<material id="12" name="MAT-SHEATH">
|
||||
<no_mass>true</no_mass>
|
||||
<thermal_resistance units="m2 K/W">0.36256</thermal_resistance>
|
||||
<thermal_absorptance units="-">0.9</thermal_absorptance>
|
||||
<solar_absorptance units="-">0.7</solar_absorptance>
|
||||
<visible_absorptance units="-">0.7</visible_absorptance>
|
||||
</material>
|
||||
<material id="14" name="Metal Decking" lca_id="7">
|
||||
<material id="14" name="Metal Decking">
|
||||
<conductivity units="W/m K">45.006</conductivity>
|
||||
<density units="kg/m3">7680</density>
|
||||
<specific_heat units="J/kg K">418.4</specific_heat>
|
||||
|
@ -141,7 +141,7 @@
|
|||
<solar_absorptance units="-">0.7</solar_absorptance>
|
||||
<visible_absorptance units="-">0.3</visible_absorptance>
|
||||
</material>
|
||||
<material id="15" name="Roof Membrane" lca_id="7">
|
||||
<material id="15" name="Roof Membrane">
|
||||
<conductivity units="W/m K">0.16</conductivity>
|
||||
<density units="kg/m3">1121.29</density>
|
||||
<specific_heat units="J/kg K">1460</specific_heat>
|
||||
|
@ -149,28 +149,28 @@
|
|||
<solar_absorptance units="-">0.7</solar_absorptance>
|
||||
<visible_absorptance units="-">0.7</visible_absorptance>
|
||||
</material>
|
||||
<material id="16" name="CP02 CARPET PAD" lca_id="7">
|
||||
<material id="16" name="CP02 CARPET PAD">
|
||||
<no_mass>true</no_mass>
|
||||
<thermal_resistance units="m2 K/W">0.21648</thermal_resistance>
|
||||
<thermal_absorptance units="-">0.9</thermal_absorptance>
|
||||
<solar_absorptance units="-">0.7</solar_absorptance>
|
||||
<visible_absorptance units="-">0.8</visible_absorptance>
|
||||
</material>
|
||||
<material id="18" name="CP02 CARPET PAD" lca_id="7">
|
||||
<material id="18" name="CP02 CARPET PAD">
|
||||
<no_mass>true</no_mass>
|
||||
<thermal_resistance units="m2 K/W">0.21648</thermal_resistance>
|
||||
<thermal_absorptance units="-">0.9</thermal_absorptance>
|
||||
<solar_absorptance units="-">0.7</solar_absorptance>
|
||||
<visible_absorptance units="-">0.8</visible_absorptance>
|
||||
</material>
|
||||
<material id="20" name="CP02 CARPET PAD" lca_id="7">
|
||||
<material id="20" name="CP02 CARPET PAD">
|
||||
<no_mass>true</no_mass>
|
||||
<thermal_resistance units="m2 K/W">0.21648</thermal_resistance>
|
||||
<thermal_absorptance units="-">0.9</thermal_absorptance>
|
||||
<solar_absorptance units="-">0.7</solar_absorptance>
|
||||
<visible_absorptance units="-">0.8</visible_absorptance>
|
||||
</material>
|
||||
<material id="21" name="Wall Insulation [38]" lca_id="7">
|
||||
<material id="21" name="Wall Insulation [38]">
|
||||
<conductivity units="W/m K">0.045</conductivity>
|
||||
<density units="kg/m3">265</density>
|
||||
<specific_heat units="J/kg K">836.8</specific_heat>
|
||||
|
@ -178,7 +178,7 @@
|
|||
<solar_absorptance units="-">0.7</solar_absorptance>
|
||||
<visible_absorptance units="-">0.7</visible_absorptance>
|
||||
</material>
|
||||
<material id="22" name="metal siding" lca_id="7">
|
||||
<material id="22" name="metal siding">
|
||||
<conductivity units="W/m K">44.96</conductivity>
|
||||
<density units="kg/m3">7688.86</density>
|
||||
<specific_heat units="J/kg K">410</specific_heat>
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
<?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>
|
|
@ -1,394 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<library name="LCA">
|
||||
<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">
|
||||
<carbon_emission_factor unit= "kgCO2/ kWh" > 0.32 </carbon_emission_factor>
|
||||
|
@ -556,4 +167,393 @@
|
|||
<carbon_emission_factor unit= "kgCO2/kWh"> 1.00000 </carbon_emission_factor>
|
||||
</vehicle>
|
||||
</vehicles>
|
||||
<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="1" 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="2" 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="3" 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="4" 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="5" 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="6" 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="7" 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="8" 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="9" 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="10" 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="11" 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="12" 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="1" 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="2" 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="1" 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="2" 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="3" 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="4" 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="5" 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="6" 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="7" 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="1" 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="2" 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="3" 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="4" 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="1" 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="2" 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="3" 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="4" 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="5" 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="6" 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="7" 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="8" 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="9" 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="10" 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="11" 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="1" 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="2" 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="3" 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>
|
||||
</library>
|
BIN
data/usage/comnet_schedules_archetypes.xlsx
Normal file
BIN
data/usage/comnet_schedules_archetypes.xlsx
Normal file
Binary file not shown.
|
@ -84,7 +84,7 @@
|
|||
<weekDayProfile>
|
||||
<source>DIN 18599-10</source>
|
||||
<values>16.0 16.0 16.0 16.0 16.0 16.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0
|
||||
20.0 20.0 20.0 20.0 20.0 20.0 0.0
|
||||
20.0 20.0 20.0 20.0 20.0 20.0 20.0
|
||||
</values>
|
||||
</weekDayProfile>
|
||||
</schedule>
|
||||
|
@ -117,7 +117,7 @@
|
|||
<schedule>
|
||||
<weekDayProfile>
|
||||
<values>16.0 16.0 16.0 16.0 16.0 16.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0
|
||||
20.0 20.0 20.0 20.0 20.0 20.0 0.0
|
||||
20.0 20.0 20.0 20.0 20.0 20.0 20.0
|
||||
</values>
|
||||
</weekDayProfile>
|
||||
</schedule>
|
||||
|
|
|
@ -329,7 +329,7 @@ class EnergyAde:
|
|||
},
|
||||
'energy:area': {
|
||||
'@uom': 'm2',
|
||||
'#text': f'{thermal_boundary.area}'
|
||||
'#text': f'{thermal_boundary.opaque_area}'
|
||||
},
|
||||
'energy:surfaceGeometry': {
|
||||
'gml:MultiSurface': {
|
||||
|
|
|
@ -105,3 +105,19 @@ class ConfigurationHelper:
|
|||
:return: 0.1
|
||||
"""
|
||||
return self._config.getfloat('buildings', 'comnet_occupancy_sensible_radiant').real
|
||||
|
||||
@property
|
||||
def convective_heat_transfer_coefficient_interior(self) -> float:
|
||||
"""
|
||||
Get configured convective heat transfer coefficient for surfaces inside the building
|
||||
:return: 3.5
|
||||
"""
|
||||
return self._config.getfloat('buildings', 'convective_heat_transfer_coefficient_interior').real
|
||||
|
||||
@property
|
||||
def convective_heat_transfer_coefficient_exterior(self) -> float:
|
||||
"""
|
||||
Get configured convective heat transfer coefficient for surfaces outside the building
|
||||
:return: 20
|
||||
"""
|
||||
return self._config.getfloat('buildings', 'convective_heat_transfer_coefficient_exterior').real
|
||||
|
|
|
@ -11,6 +11,7 @@ KELVIN = 273.15
|
|||
HOUR_TO_MINUTES = 60
|
||||
METERS_TO_FEET = 3.28084
|
||||
BTU_H_TO_WATTS = 0.29307107
|
||||
KILO_WATTS_HOUR_TO_JULES = 3600000
|
||||
|
||||
# time
|
||||
SECOND = 'second'
|
||||
|
@ -57,39 +58,66 @@ WINDOW = 'Window'
|
|||
DOOR = 'Door'
|
||||
SKYLIGHT = 'Skylight'
|
||||
|
||||
# todo: homogenize function and usage!!
|
||||
# function
|
||||
RESIDENTIAL = 'residential'
|
||||
SFH = 'single family house'
|
||||
MFH = 'multifamily house'
|
||||
HOTEL = 'hotel'
|
||||
HOSPITAL = 'hospital'
|
||||
OUTPATIENT = 'outpatient'
|
||||
COMMERCIAL = 'commercial'
|
||||
STRIP_MALL = 'strip mall'
|
||||
WAREHOUSE = 'warehouse'
|
||||
# functions and usages
|
||||
SINGLE_FAMILY_HOUSE = 'single family house'
|
||||
MULTI_FAMILY_HOUSE = 'multifamily house'
|
||||
ROW_HOSE = 'row house'
|
||||
MID_RISE_APARTMENT = 'mid rise apartment'
|
||||
HIGH_RISE_APARTMENT = 'high rise apartment'
|
||||
SMALL_OFFICE = 'small office'
|
||||
MEDIUM_OFFICE = 'medium office'
|
||||
LARGE_OFFICE = 'large office'
|
||||
PRIMARY_SCHOOL = 'primary school'
|
||||
SECONDARY_SCHOOL = 'secondary school'
|
||||
OFFICE = 'office'
|
||||
LARGE_OFFICE = 'large office'
|
||||
OFFICE_WORKSHOP = 'office/workshop'
|
||||
|
||||
# usage
|
||||
INDUSTRY = 'industry'
|
||||
OFFICE_ADMINISTRATION = 'office and administration'
|
||||
HEALTH_CARE = 'health care'
|
||||
RETAIL = 'retail'
|
||||
HALL = 'hall'
|
||||
RESTAURANT = 'restaurant'
|
||||
STAND_ALONE_RETAIL = 'stand alone retail'
|
||||
HOSPITAL = 'hospital'
|
||||
OUT_PATIENT_HEALTH_CARE = 'out-patient health care'
|
||||
STRIP_MALL = 'strip mall'
|
||||
SUPERMARKET = 'supermarket'
|
||||
WAREHOUSE = 'warehouse'
|
||||
QUICK_SERVICE_RESTAURANT = 'quick service restaurant'
|
||||
FULL_SERVICE_RESTAURANT = 'full service restaurant'
|
||||
SMALL_HOTEL = 'small hotel'
|
||||
LARGE_HOTEL = 'large hotel'
|
||||
RESIDENTIAL = 'residential'
|
||||
EDUCATION = 'education'
|
||||
SCHOOL_WITHOUT_SHOWER = 'school without shower'
|
||||
SCHOOL_WITH_SHOWER = 'school with shower'
|
||||
RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD = 'retail shop without refrigerated food'
|
||||
RETAIL_SHOP_WITH_REFRIGERATED_FOOD = 'retail shop with refrigerated food'
|
||||
HOTEL = 'hotel'
|
||||
HOTEL_MEDIUM_CLASS = 'hotel medium class'
|
||||
DORMITORY = 'dormitory'
|
||||
INDUSTRY = 'industry'
|
||||
RESTAURANT = 'restaurant'
|
||||
HEALTH_CARE = 'health care'
|
||||
RETIREMENT_HOME_OR_ORPHANAGE = 'retirement home or orphanage'
|
||||
OFFICE_AND_ADMINISTRATION = 'office and administration'
|
||||
EVENT_LOCATION = 'event location'
|
||||
HALL = 'hall'
|
||||
SPORTS_LOCATION = 'sports location'
|
||||
LABOR = 'labor'
|
||||
GREEN_HOUSE = 'green house'
|
||||
NON_HEATED = 'non-heated'
|
||||
|
||||
LIGHTING = 'Lights'
|
||||
OCCUPANCY = 'Occupancy'
|
||||
RECEPTACLE = 'Receptacle'
|
||||
APPLIANCES = 'Appliances'
|
||||
HVAC_AVAILABILITY = 'HVAC Avail'
|
||||
INFILTRATION = 'Infiltration'
|
||||
COOLING_SET_POINT = 'ClgSetPt'
|
||||
HEATING_SET_POINT = 'HtgSetPt'
|
||||
# todo: are any of these two the receptacle concept??
|
||||
EQUIPMENT = 'Equipment'
|
||||
ACTIVITY = 'Activity'
|
||||
|
||||
# Geometry
|
||||
EPSILON = 0.0000001
|
||||
|
||||
# HVAC types
|
||||
ONLY_HEATING = 'Heating'
|
||||
ONLY_COOLING = 'Colling'
|
||||
ONLY_VENTILATION = 'Ventilation'
|
||||
HEATING_AND_VENTILATION = 'Heating and ventilation'
|
||||
COOLING_AND_VENTILATION = 'Cooling and ventilation'
|
||||
HEATING_AND_COLLING = 'Heating and cooling'
|
||||
FULL_HVAC = 'Heating and cooling and ventilation'
|
||||
|
|
|
@ -5,7 +5,7 @@ Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.mons
|
|||
"""
|
||||
import calendar as cal
|
||||
import pandas as pd
|
||||
from city_model_structure.building_demand.occupants import Occupants
|
||||
from city_model_structure.building_demand.occupant import Occupant
|
||||
import helpers.constants as cte
|
||||
|
||||
|
||||
|
@ -34,7 +34,7 @@ class MonthlyToHourlyDemand:
|
|||
# todo: if these are data frames, then they should be called as (Occupancy should be in low case):
|
||||
# usage_zone.schedules.Occupancy
|
||||
# self._conditioning_seasons.heating
|
||||
occupancy = Occupants().get_complete_year_schedule(usage_zone.schedules['Occupancy'])
|
||||
occupancy = Occupant().get_complete_year_schedule(usage_zone.schedules['Occupancy'])
|
||||
heating_schedule = self._conditioning_seasons['heating']
|
||||
|
||||
hourly_heating = []
|
||||
|
@ -92,7 +92,7 @@ class MonthlyToHourlyDemand:
|
|||
for usage_zone in self._building.usage_zones:
|
||||
temp_set = float(usage_zone.cooling_setpoint)
|
||||
temp_back = 100
|
||||
occupancy = Occupants().get_complete_year_schedule(usage_zone.schedules['Occupancy'])
|
||||
occupancy = Occupant().get_complete_year_schedule(usage_zone.schedules['Occupancy'])
|
||||
cooling_schedule = self._conditioning_seasons['cooling']
|
||||
|
||||
hourly_cooling = []
|
||||
|
|
|
@ -6,7 +6,6 @@ Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.mons
|
|||
import sys
|
||||
from imports.construction.helpers.construction_helper import ConstructionHelper
|
||||
from imports.construction.nrel_physics_interface import NrelPhysicsInterface
|
||||
from imports.construction.helpers.storeys_generation import StoreysGeneration
|
||||
|
||||
|
||||
class CaPhysicsParameters(NrelPhysicsInterface):
|
||||
|
@ -25,16 +24,24 @@ class CaPhysicsParameters(NrelPhysicsInterface):
|
|||
city = self._city
|
||||
# it is assumed that all buildings have the same archetypes' keys
|
||||
for building in city.buildings:
|
||||
archetype = self._search_archetype(ConstructionHelper.nrcan_from_function(building.function),
|
||||
building.year_of_construction)
|
||||
if archetype is None:
|
||||
try:
|
||||
archetype = self._search_archetype(ConstructionHelper.nrcan_from_libs_function(building.function),
|
||||
building.year_of_construction)
|
||||
except KeyError:
|
||||
sys.stderr.write(f'Building {building.name} has unknown archetype for building function: '
|
||||
f'{ConstructionHelper.nrcan_from_function(building.function)} '
|
||||
f'{ConstructionHelper.nrcan_from_libs_function(building.function)} '
|
||||
f'and building year of construction: {building.year_of_construction}\n')
|
||||
continue
|
||||
return
|
||||
|
||||
self._create_storeys(building, archetype)
|
||||
self._assign_values(building, archetype)
|
||||
# if building has no thermal zones defined from geometry, one thermal zone per storey is assigned
|
||||
if len(building.internal_zones) == 1:
|
||||
if building.internal_zones[0].thermal_zones is None:
|
||||
self._create_storeys(building, archetype)
|
||||
|
||||
self._assign_values(building.internal_zones, archetype)
|
||||
for internal_zone in building.internal_zones:
|
||||
for thermal_zone in internal_zone.thermal_zones:
|
||||
self._calculate_view_factors(thermal_zone)
|
||||
|
||||
def _search_archetype(self, function, year_of_construction):
|
||||
for building_archetype in self._building_archetypes:
|
||||
|
@ -47,33 +54,29 @@ class CaPhysicsParameters(NrelPhysicsInterface):
|
|||
return building_archetype
|
||||
return None
|
||||
|
||||
def _assign_values(self, building, archetype):
|
||||
for thermal_zone in building.thermal_zones:
|
||||
thermal_zone.additional_thermal_bridge_u_value = archetype.additional_thermal_bridge_u_value
|
||||
thermal_zone.effective_thermal_capacity = archetype.effective_thermal_capacity
|
||||
thermal_zone.indirectly_heated_area_ratio = archetype.indirectly_heated_area_ratio
|
||||
thermal_zone.infiltration_rate_system_on = archetype.infiltration_rate_system_on
|
||||
thermal_zone.infiltration_rate_system_off = archetype.infiltration_rate_system_off
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
construction_type = ConstructionHelper.nrcan_construction_types[thermal_boundary.type]
|
||||
thermal_boundary_archetype = self._search_construction_in_archetype(archetype, construction_type)
|
||||
thermal_boundary.u_value = thermal_boundary_archetype.overall_u_value
|
||||
thermal_boundary.outside_solar_absorptance = thermal_boundary_archetype.outside_solar_absorptance
|
||||
thermal_boundary.construction_name = thermal_boundary_archetype.construction_name
|
||||
thermal_boundary.window_ratio = thermal_boundary_archetype.window_ratio
|
||||
if thermal_boundary.thermal_openings is not None:
|
||||
for thermal_opening in thermal_boundary.thermal_openings:
|
||||
if thermal_boundary_archetype.thermal_opening is not None:
|
||||
thermal_opening_archetype = thermal_boundary_archetype.thermal_opening
|
||||
thermal_opening.frame_ratio = thermal_opening_archetype.frame_ratio
|
||||
thermal_opening.g_value = thermal_opening_archetype.g_value
|
||||
thermal_opening.overall_u_value = thermal_opening_archetype.overall_u_value
|
||||
|
||||
@staticmethod
|
||||
def _create_storeys(building, archetype):
|
||||
building.average_storey_height = archetype.average_storey_height
|
||||
building.storeys_above_ground = archetype.storeys_above_ground
|
||||
storeys_generation = StoreysGeneration(building)
|
||||
storeys = storeys_generation.storeys
|
||||
building.storeys = storeys
|
||||
storeys_generation.assign_thermal_zones_delimited_by_thermal_boundaries()
|
||||
def _assign_values(self, internal_zones, archetype):
|
||||
for internal_zone in internal_zones:
|
||||
for thermal_zone in internal_zone.thermal_zones:
|
||||
thermal_zone.additional_thermal_bridge_u_value = archetype.additional_thermal_bridge_u_value
|
||||
thermal_zone.effective_thermal_capacity = archetype.effective_thermal_capacity
|
||||
thermal_zone.indirectly_heated_area_ratio = archetype.indirectly_heated_area_ratio
|
||||
thermal_zone.infiltration_rate_system_on = archetype.infiltration_rate_system_on
|
||||
thermal_zone.infiltration_rate_system_off = archetype.infiltration_rate_system_off
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
construction_type = ConstructionHelper.nrcan_construction_types[thermal_boundary.type]
|
||||
thermal_boundary_archetype = self._search_construction_in_archetype(archetype, construction_type)
|
||||
thermal_boundary.u_value = thermal_boundary_archetype.overall_u_value
|
||||
thermal_boundary.outside_solar_absorptance = thermal_boundary_archetype.outside_solar_absorptance
|
||||
thermal_boundary.construction_name = thermal_boundary_archetype.construction_name
|
||||
try:
|
||||
thermal_boundary.window_ratio = thermal_boundary_archetype.window_ratio
|
||||
except ValueError:
|
||||
# This is the normal operation way when the windows are defined in the geometry
|
||||
continue
|
||||
if thermal_boundary.thermal_openings is not None:
|
||||
for thermal_opening in thermal_boundary.thermal_openings:
|
||||
if thermal_boundary_archetype.thermal_opening_archetype is not None:
|
||||
thermal_opening_archetype = thermal_boundary_archetype.thermal_opening_archetype
|
||||
thermal_opening.frame_ratio = thermal_opening_archetype.frame_ratio
|
||||
thermal_opening.g_value = thermal_opening_archetype.g_value
|
||||
thermal_opening.overall_u_value = thermal_opening_archetype.overall_u_value
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
"""
|
||||
NrelBuildingArchetype stores construction information by building archetypes
|
||||
BuildingArchetype stores construction information by building archetypes
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
from typing import List
|
||||
from imports.construction.data_classes.nrel_thermal_boundary_archetype import NrelThermalBoundaryArchetype
|
||||
from imports.construction.data_classes.thermal_boundary_archetype import ThermalBoundaryArchetype
|
||||
|
||||
|
||||
class NrelBuildingArchetype:
|
||||
class BuildingArchetype:
|
||||
"""
|
||||
NrelBuildingArchetype class
|
||||
BuildingArchetype class
|
||||
"""
|
||||
def __init__(self, archetype_keys, average_storey_height, storeys_above_ground, effective_thermal_capacity,
|
||||
additional_thermal_bridge_u_value, indirectly_heated_area_ratio, infiltration_rate_system_off,
|
||||
|
@ -89,7 +89,7 @@ class NrelBuildingArchetype:
|
|||
return self._infiltration_rate_system_on
|
||||
|
||||
@property
|
||||
def thermal_boundary_archetypes(self) -> List[NrelThermalBoundaryArchetype]:
|
||||
def thermal_boundary_archetypes(self) -> List[ThermalBoundaryArchetype]:
|
||||
"""
|
||||
Get thermal boundary archetypes associated to the building archetype
|
||||
:return: list of boundary archetypes
|
|
@ -1,17 +1,16 @@
|
|||
"""
|
||||
NrelLayerArchetype stores layer and materials information, complementing the NrelBuildingArchetype class
|
||||
LayerArchetype stores layer and materials information, complementing the BuildingArchetype class
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
|
||||
|
||||
class NrelLayerArchetype:
|
||||
class LayerArchetype:
|
||||
"""
|
||||
NrelLayerArchetype class
|
||||
LayerArchetype class
|
||||
"""
|
||||
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,
|
||||
lca_id=None):
|
||||
conductivity=None, specific_heat=None, density=None, no_mass=False, thermal_resistance=None):
|
||||
self._thickness = thickness
|
||||
self._conductivity = conductivity
|
||||
self._specific_heat = specific_heat
|
||||
|
@ -22,12 +21,11 @@ class NrelLayerArchetype:
|
|||
self._no_mass = no_mass
|
||||
self._name = name
|
||||
self._thermal_resistance = thermal_resistance
|
||||
self._lca_id = lca_id
|
||||
|
||||
@property
|
||||
def thickness(self):
|
||||
"""
|
||||
Get nrel layer archetype thickness in meters
|
||||
Get thickness in meters
|
||||
:return: float
|
||||
"""
|
||||
return self._thickness
|
||||
|
@ -35,7 +33,7 @@ class NrelLayerArchetype:
|
|||
@property
|
||||
def conductivity(self):
|
||||
"""
|
||||
Get nrel layer archetype conductivity in W/mK
|
||||
Get conductivity in W/mK
|
||||
:return: float
|
||||
"""
|
||||
return self._conductivity
|
||||
|
@ -43,7 +41,7 @@ class NrelLayerArchetype:
|
|||
@property
|
||||
def specific_heat(self):
|
||||
"""
|
||||
Get nrel layer archetype conductivity in J/kgK
|
||||
Get specific heat in J/kgK
|
||||
:return: float
|
||||
"""
|
||||
return self._specific_heat
|
||||
|
@ -51,7 +49,7 @@ class NrelLayerArchetype:
|
|||
@property
|
||||
def density(self):
|
||||
"""
|
||||
Get nrel layer archetype density in kg/m3
|
||||
Get density in kg/m3
|
||||
:return: float
|
||||
"""
|
||||
return self._density
|
||||
|
@ -59,7 +57,7 @@ class NrelLayerArchetype:
|
|||
@property
|
||||
def solar_absorptance(self):
|
||||
"""
|
||||
Get nrel layer archetype solar absorptance
|
||||
Get solar absorptance
|
||||
:return: float
|
||||
"""
|
||||
return self._solar_absorptance
|
||||
|
@ -67,7 +65,7 @@ class NrelLayerArchetype:
|
|||
@property
|
||||
def thermal_absorptance(self):
|
||||
"""
|
||||
Get nrel layer archetype thermal absorptance
|
||||
Get thermal absorptance
|
||||
:return: float
|
||||
"""
|
||||
return self._thermal_absorptance
|
||||
|
@ -75,7 +73,7 @@ class NrelLayerArchetype:
|
|||
@property
|
||||
def visible_absorptance(self):
|
||||
"""
|
||||
Get nrel layer archetype visible absorptance
|
||||
Get visible absorptance
|
||||
:return: float
|
||||
"""
|
||||
return self._visible_absorptance
|
||||
|
@ -83,7 +81,7 @@ class NrelLayerArchetype:
|
|||
@property
|
||||
def no_mass(self) -> bool:
|
||||
"""
|
||||
Get nrel layer archetype no mass flag
|
||||
Get no mass flag
|
||||
:return: Boolean
|
||||
"""
|
||||
return self._no_mass
|
||||
|
@ -91,7 +89,7 @@ class NrelLayerArchetype:
|
|||
@property
|
||||
def name(self):
|
||||
"""
|
||||
Get nrel layer archetype name
|
||||
Get name
|
||||
:return: str
|
||||
"""
|
||||
return self._name
|
||||
|
@ -99,15 +97,7 @@ class NrelLayerArchetype:
|
|||
@property
|
||||
def thermal_resistance(self):
|
||||
"""
|
||||
Get nrel layer archetype thermal resistance in m2K/W
|
||||
Get thermal resistance in m2K/W
|
||||
:return: float
|
||||
"""
|
||||
return self._thermal_resistance
|
||||
|
||||
@property
|
||||
def lca_id(self):
|
||||
"""
|
||||
Get nrel lca_id equivalent for the material
|
||||
:return: int
|
||||
"""
|
||||
return self._lca_id
|
|
@ -1,99 +0,0 @@
|
|||
"""
|
||||
NrelThermalBoundaryArchetype stores thermal boundaries information, complementing the NrelBuildingArchetype class
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
from typing import List
|
||||
|
||||
from imports.construction.data_classes.nrel_layer_archetype import NrelLayerArchetype
|
||||
from imports.construction.data_classes.nrel_thermal_opening_archetype import NrelThermalOpeningArchetype
|
||||
|
||||
|
||||
class NrelThermalBoundaryArchetype:
|
||||
"""
|
||||
NrelThermalBoundaryArchetype class
|
||||
"""
|
||||
def __init__(self, boundary_type, window_ratio, construction_name, layers, thermal_opening,
|
||||
outside_solar_absorptance=None, outside_thermal_absorptance=None, outside_visible_absorptance=None,
|
||||
overall_u_value=None):
|
||||
self._boundary_type = boundary_type
|
||||
self._outside_solar_absorptance = outside_solar_absorptance
|
||||
self._outside_thermal_absorptance = outside_thermal_absorptance
|
||||
self._outside_visible_absorptance = outside_visible_absorptance
|
||||
self._window_ratio = window_ratio
|
||||
self._construction_name = construction_name
|
||||
self._overall_u_value = overall_u_value
|
||||
self._layers = layers
|
||||
self._thermal_opening = thermal_opening
|
||||
|
||||
@property
|
||||
def boundary_type(self):
|
||||
"""
|
||||
Get nrel thermal boundary archetype type
|
||||
:return: str
|
||||
"""
|
||||
return self._boundary_type
|
||||
|
||||
@property
|
||||
def outside_solar_absorptance(self):
|
||||
"""
|
||||
Get nrel thermal boundary archetype outside solar absorptance
|
||||
:return: float
|
||||
"""
|
||||
return self._outside_solar_absorptance
|
||||
|
||||
@property
|
||||
def outside_thermal_absorptance(self):
|
||||
"""
|
||||
Get nrel thermal boundary archetype outside thermal absorptance
|
||||
:return: float
|
||||
"""
|
||||
return self._outside_thermal_absorptance
|
||||
|
||||
@property
|
||||
def outside_visible_absorptance(self):
|
||||
"""
|
||||
Get nrel thermal boundary archetype outside visible absorptance
|
||||
:return: float
|
||||
"""
|
||||
return self._outside_visible_absorptance
|
||||
|
||||
@property
|
||||
def window_ratio(self):
|
||||
"""
|
||||
Get nrel thermal boundary archetype window ratio
|
||||
:return: float
|
||||
"""
|
||||
return self._window_ratio
|
||||
|
||||
@property
|
||||
def construction_name(self):
|
||||
"""
|
||||
Get nrel thermal boundary archetype construction name
|
||||
:return: str
|
||||
"""
|
||||
return self._construction_name
|
||||
|
||||
@property
|
||||
def layers(self) -> List[NrelLayerArchetype]:
|
||||
"""
|
||||
Get nrel thermal boundary archetype layers
|
||||
:return: [NrelLayerArchetype]
|
||||
"""
|
||||
return self._layers
|
||||
|
||||
@property
|
||||
def thermal_opening(self) -> NrelThermalOpeningArchetype:
|
||||
"""
|
||||
Get nrel thermal boundary archetype
|
||||
:return: NrelThermalOpeningArchetype
|
||||
"""
|
||||
return self._thermal_opening
|
||||
|
||||
@property
|
||||
def overall_u_value(self):
|
||||
"""
|
||||
Get nrel thermal boundary archetype overall U-value in W/m2K
|
||||
:return: float
|
||||
"""
|
||||
return self._overall_u_value
|
136
imports/construction/data_classes/thermal_boundary_archetype.py
Normal file
136
imports/construction/data_classes/thermal_boundary_archetype.py
Normal file
|
@ -0,0 +1,136 @@
|
|||
"""
|
||||
ThermalBoundaryArchetype stores thermal boundaries information, complementing the BuildingArchetype class
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
from typing import List
|
||||
|
||||
from imports.construction.data_classes.layer_archetype import LayerArchetype
|
||||
from imports.construction.data_classes.thermal_opening_archetype import ThermalOpeningArchetype
|
||||
|
||||
|
||||
class ThermalBoundaryArchetype:
|
||||
"""
|
||||
ThermalBoundaryArchetype class
|
||||
"""
|
||||
def __init__(self, boundary_type, window_ratio, construction_name, layers, thermal_opening,
|
||||
outside_solar_absorptance=None, outside_thermal_absorptance=None, outside_visible_absorptance=None,
|
||||
overall_u_value=None, shortwave_reflectance=None, inside_emissivity=None, alpha_coefficient=None,
|
||||
radiative_coefficient=None):
|
||||
self._boundary_type = boundary_type
|
||||
self._outside_solar_absorptance = outside_solar_absorptance
|
||||
self._outside_thermal_absorptance = outside_thermal_absorptance
|
||||
self._outside_visible_absorptance = outside_visible_absorptance
|
||||
self._window_ratio = window_ratio
|
||||
self._construction_name = construction_name
|
||||
self._overall_u_value = overall_u_value
|
||||
self._layers = layers
|
||||
self._thermal_opening_archetype = thermal_opening
|
||||
self._shortwave_reflectance = shortwave_reflectance
|
||||
self._inside_emissivity = inside_emissivity
|
||||
self._alpha_coefficient = alpha_coefficient
|
||||
self._radiative_coefficient = radiative_coefficient
|
||||
|
||||
@property
|
||||
def boundary_type(self):
|
||||
"""
|
||||
Get type
|
||||
:return: str
|
||||
"""
|
||||
return self._boundary_type
|
||||
|
||||
@property
|
||||
def outside_solar_absorptance(self):
|
||||
"""
|
||||
Get outside solar absorptance
|
||||
:return: float
|
||||
"""
|
||||
return self._outside_solar_absorptance
|
||||
|
||||
@property
|
||||
def outside_thermal_absorptance(self):
|
||||
"""
|
||||
Get outside thermal absorptance
|
||||
:return: float
|
||||
"""
|
||||
return self._outside_thermal_absorptance
|
||||
|
||||
@property
|
||||
def outside_visible_absorptance(self):
|
||||
"""
|
||||
Get outside visible absorptance
|
||||
:return: float
|
||||
"""
|
||||
return self._outside_visible_absorptance
|
||||
|
||||
@property
|
||||
def window_ratio(self):
|
||||
"""
|
||||
Get window ratio
|
||||
:return: float
|
||||
"""
|
||||
return self._window_ratio
|
||||
|
||||
@property
|
||||
def construction_name(self):
|
||||
"""
|
||||
Get construction name
|
||||
:return: str
|
||||
"""
|
||||
return self._construction_name
|
||||
|
||||
@property
|
||||
def layers(self) -> List[LayerArchetype]:
|
||||
"""
|
||||
Get layers
|
||||
:return: [NrelLayerArchetype]
|
||||
"""
|
||||
return self._layers
|
||||
|
||||
@property
|
||||
def thermal_opening_archetype(self) -> ThermalOpeningArchetype:
|
||||
"""
|
||||
Get thermal opening archetype
|
||||
:return: ThermalOpeningArchetype
|
||||
"""
|
||||
return self._thermal_opening_archetype
|
||||
|
||||
@property
|
||||
def overall_u_value(self):
|
||||
"""
|
||||
Get overall U-value in W/m2K
|
||||
:return: float
|
||||
"""
|
||||
return self._overall_u_value
|
||||
|
||||
@property
|
||||
def shortwave_reflectance(self):
|
||||
"""
|
||||
Get shortwave reflectance
|
||||
:return: float
|
||||
"""
|
||||
return self._shortwave_reflectance
|
||||
|
||||
@property
|
||||
def inside_emissivity(self):
|
||||
"""
|
||||
Get emissivity inside
|
||||
:return: float
|
||||
"""
|
||||
return self._inside_emissivity
|
||||
|
||||
@property
|
||||
def alpha_coefficient(self):
|
||||
"""
|
||||
Get alpha coefficient
|
||||
:return: float
|
||||
"""
|
||||
return self._alpha_coefficient
|
||||
|
||||
@property
|
||||
def radiative_coefficient(self):
|
||||
"""
|
||||
Get radiative coefficient
|
||||
:return: float
|
||||
"""
|
||||
return self._radiative_coefficient
|
|
@ -1,30 +1,34 @@
|
|||
"""
|
||||
NrelThermalOpeningArchetype stores thermal openings information, complementing the NrelBuildingArchetype class
|
||||
ThermalOpeningArchetype stores thermal openings information, complementing the BuildingArchetype class
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
|
||||
|
||||
class NrelThermalOpeningArchetype:
|
||||
class ThermalOpeningArchetype:
|
||||
"""
|
||||
NrelThermalOpeningArchetype class
|
||||
ThermalOpeningArchetype class
|
||||
"""
|
||||
def __init__(self, conductivity=None, frame_ratio=None, g_value=None, thickness=None,
|
||||
back_side_solar_transmittance_at_normal_incidence=None,
|
||||
front_side_solar_transmittance_at_normal_incidence=None, shgc=None, overall_u_value=None):
|
||||
front_side_solar_transmittance_at_normal_incidence=None, overall_u_value=None,
|
||||
openable_ratio=None, inside_emissivity=None, alpha_coefficient=None, radiative_coefficient=None):
|
||||
self._conductivity = conductivity
|
||||
self._frame_ratio = frame_ratio
|
||||
self._g_value = g_value
|
||||
self._thickness = thickness
|
||||
self._back_side_solar_transmittance_at_normal_incidence = back_side_solar_transmittance_at_normal_incidence
|
||||
self._front_side_solar_transmittance_at_normal_incidence = front_side_solar_transmittance_at_normal_incidence
|
||||
self._shgc = shgc
|
||||
self._overall_u_value = overall_u_value
|
||||
self._openable_ratio = openable_ratio
|
||||
self._inside_emissivity = inside_emissivity
|
||||
self._alpha_coefficient = alpha_coefficient
|
||||
self._radiative_coefficient = radiative_coefficient
|
||||
|
||||
@property
|
||||
def conductivity(self):
|
||||
"""
|
||||
Get nrel thermal opening archetype conductivity in W/mK
|
||||
Get conductivity in W/mK
|
||||
:return: float
|
||||
"""
|
||||
return self._conductivity
|
||||
|
@ -32,7 +36,7 @@ class NrelThermalOpeningArchetype:
|
|||
@property
|
||||
def frame_ratio(self):
|
||||
"""
|
||||
Get nrel thermal opening archetype frame ratio
|
||||
Get frame ratio
|
||||
:return: float
|
||||
"""
|
||||
return self._frame_ratio
|
||||
|
@ -40,7 +44,7 @@ class NrelThermalOpeningArchetype:
|
|||
@property
|
||||
def g_value(self):
|
||||
"""
|
||||
Get nrel thermal opening archetype g-value
|
||||
Get g-value, also called shgc
|
||||
:return: float
|
||||
"""
|
||||
return self._g_value
|
||||
|
@ -48,7 +52,7 @@ class NrelThermalOpeningArchetype:
|
|||
@property
|
||||
def thickness(self):
|
||||
"""
|
||||
Get nrel thermal opening archetype thickness in meters
|
||||
Get thickness in meters
|
||||
:return: float
|
||||
"""
|
||||
return self._thickness
|
||||
|
@ -56,7 +60,7 @@ class NrelThermalOpeningArchetype:
|
|||
@property
|
||||
def back_side_solar_transmittance_at_normal_incidence(self):
|
||||
"""
|
||||
Get nrel thermal opening archetype back side solar transmittance at normal incidence
|
||||
Get back side solar transmittance at normal incidence
|
||||
:return: float
|
||||
"""
|
||||
return self._back_side_solar_transmittance_at_normal_incidence
|
||||
|
@ -64,23 +68,47 @@ class NrelThermalOpeningArchetype:
|
|||
@property
|
||||
def front_side_solar_transmittance_at_normal_incidence(self):
|
||||
"""
|
||||
Get nrel thermal opening archetype front side solar transmittance at normal incidence
|
||||
Get front side solar transmittance at normal incidence
|
||||
:return: float
|
||||
"""
|
||||
return self._front_side_solar_transmittance_at_normal_incidence
|
||||
|
||||
@property
|
||||
def shgc(self):
|
||||
"""
|
||||
Get nrel thermal opening archetype shcg
|
||||
:return: float
|
||||
"""
|
||||
return self._shgc
|
||||
|
||||
@property
|
||||
def overall_u_value(self):
|
||||
"""
|
||||
Get nrel thermal opening archetype overall U-value in W/m2K
|
||||
:param value: float
|
||||
Get overall U-value in W/m2K
|
||||
:return: float
|
||||
"""
|
||||
return self._overall_u_value
|
||||
|
||||
@property
|
||||
def openable_ratio(self):
|
||||
"""
|
||||
Get openable ratio
|
||||
:return: float
|
||||
"""
|
||||
return self._openable_ratio
|
||||
|
||||
@property
|
||||
def inside_emissivity(self):
|
||||
"""
|
||||
Get emissivity inside
|
||||
:return: float
|
||||
"""
|
||||
return self._inside_emissivity
|
||||
|
||||
@property
|
||||
def alpha_coefficient(self):
|
||||
"""
|
||||
Get alpha coefficient
|
||||
:return: float
|
||||
"""
|
||||
return self._alpha_coefficient
|
||||
|
||||
@property
|
||||
def radiative_coefficient(self):
|
||||
"""
|
||||
Get radiative coefficient
|
||||
:return: float
|
||||
"""
|
||||
return self._radiative_coefficient
|
|
@ -12,27 +12,35 @@ class ConstructionHelper:
|
|||
Construction helper
|
||||
"""
|
||||
# NREL
|
||||
function_to_nrel = {
|
||||
_function_to_nrel = {
|
||||
cte.RESIDENTIAL: 'residential',
|
||||
cte.SFH: 'single family house',
|
||||
cte.MFH: 'multifamily house',
|
||||
cte.HOTEL: 'hotel',
|
||||
cte.HOSPITAL: 'hospital',
|
||||
cte.OUTPATIENT: 'outpatient',
|
||||
cte.COMMERCIAL: 'commercial',
|
||||
cte.STRIP_MALL: 'strip mall',
|
||||
cte.WAREHOUSE: 'warehouse',
|
||||
cte.SINGLE_FAMILY_HOUSE: 'residential',
|
||||
cte.MULTI_FAMILY_HOUSE: 'residential',
|
||||
cte.ROW_HOSE: 'residential',
|
||||
cte.MID_RISE_APARTMENT: 'midrise apartment',
|
||||
cte.HIGH_RISE_APARTMENT: 'high-rise apartment',
|
||||
cte.SMALL_OFFICE: 'small office',
|
||||
cte.MEDIUM_OFFICE: 'medium office',
|
||||
cte.LARGE_OFFICE: 'large office',
|
||||
cte.PRIMARY_SCHOOL: 'primary school',
|
||||
cte.SECONDARY_SCHOOL: 'secondary school',
|
||||
cte.OFFICE: 'office',
|
||||
cte.LARGE_OFFICE: 'large office'
|
||||
cte.STAND_ALONE_RETAIL: 'stand-alone retail',
|
||||
cte.HOSPITAL: 'hospital',
|
||||
cte.OUT_PATIENT_HEALTH_CARE: 'outpatient healthcare',
|
||||
cte.STRIP_MALL: 'strip mall',
|
||||
cte.SUPERMARKET: 'supermarket',
|
||||
cte.WAREHOUSE: 'warehouse',
|
||||
cte.QUICK_SERVICE_RESTAURANT: 'quick service restaurant',
|
||||
cte.FULL_SERVICE_RESTAURANT: 'full service restaurant',
|
||||
cte.SMALL_HOTEL: 'small hotel',
|
||||
cte.LARGE_HOTEL: 'large hotel'
|
||||
}
|
||||
nrel_function_default_value = 'residential'
|
||||
nrel_standards = {
|
||||
|
||||
_nrel_standards = {
|
||||
'ASHRAE Std189': 1,
|
||||
'ASHRAE 90.1_2004': 2
|
||||
}
|
||||
reference_city_to_nrel_climate_zone = {
|
||||
_reference_city_to_nrel_climate_zone = {
|
||||
'Miami': 'ASHRAE_2004:1A',
|
||||
'Houston': 'ASHRAE_2004:2A',
|
||||
'Phoenix': 'ASHRAE_2004:2B',
|
||||
|
@ -51,6 +59,7 @@ class ConstructionHelper:
|
|||
'Fairbanks': 'ASHRAE_2004:8A'
|
||||
}
|
||||
nrel_window_types = [cte.WINDOW, cte.DOOR, cte.SKYLIGHT]
|
||||
|
||||
nrel_construction_types = {
|
||||
cte.WALL: 'exterior wall',
|
||||
cte.INTERIOR_WALL: 'interior wall',
|
||||
|
@ -62,24 +71,32 @@ class ConstructionHelper:
|
|||
}
|
||||
|
||||
# NRCAN
|
||||
function_to_nrcan = {
|
||||
_function_to_nrcan = {
|
||||
cte.RESIDENTIAL: 'residential',
|
||||
cte.SFH: 'single family house',
|
||||
cte.MFH: 'multifamily house',
|
||||
cte.HOTEL: 'hotel',
|
||||
cte.HOSPITAL: 'hospital',
|
||||
cte.OUTPATIENT: 'outpatient',
|
||||
cte.COMMERCIAL: 'commercial',
|
||||
cte.STRIP_MALL: 'strip mall',
|
||||
cte.WAREHOUSE: 'warehouse',
|
||||
cte.PRIMARY_SCHOOL: 'primary school',
|
||||
cte.SECONDARY_SCHOOL: 'secondary school',
|
||||
cte.OFFICE: 'office',
|
||||
cte.LARGE_OFFICE: 'large office',
|
||||
cte.OFFICE_WORKSHOP: 'residential'
|
||||
cte.SINGLE_FAMILY_HOUSE: 'residential',
|
||||
cte.MULTI_FAMILY_HOUSE: 'residential',
|
||||
cte.ROW_HOSE: 'residential',
|
||||
cte.MID_RISE_APARTMENT: 'residential',
|
||||
cte.HIGH_RISE_APARTMENT: 'residential',
|
||||
cte.SMALL_OFFICE: cte.SMALL_OFFICE,
|
||||
cte.MEDIUM_OFFICE: cte.MEDIUM_OFFICE,
|
||||
cte.LARGE_OFFICE: cte.LARGE_OFFICE,
|
||||
cte.PRIMARY_SCHOOL: cte.PRIMARY_SCHOOL,
|
||||
cte.SECONDARY_SCHOOL: cte.SECONDARY_SCHOOL,
|
||||
cte.STAND_ALONE_RETAIL: cte.STAND_ALONE_RETAIL,
|
||||
cte.HOSPITAL: cte.HOSPITAL,
|
||||
cte.OUT_PATIENT_HEALTH_CARE: cte.OUT_PATIENT_HEALTH_CARE,
|
||||
cte.STRIP_MALL: cte.STRIP_MALL,
|
||||
cte.SUPERMARKET: cte.SUPERMARKET,
|
||||
cte.WAREHOUSE: cte.WAREHOUSE,
|
||||
cte.QUICK_SERVICE_RESTAURANT: cte.QUICK_SERVICE_RESTAURANT,
|
||||
cte.FULL_SERVICE_RESTAURANT: cte.FULL_SERVICE_RESTAURANT,
|
||||
cte.SMALL_HOTEL: cte.SMALL_HOTEL,
|
||||
cte.LARGE_HOTEL: cte.LARGE_HOTEL
|
||||
}
|
||||
nrcan_function_default_value = 'residential'
|
||||
|
||||
nrcan_window_types = [cte.WINDOW]
|
||||
|
||||
nrcan_construction_types = {
|
||||
cte.WALL: 'wall',
|
||||
cte.GROUND_WALL: 'basement_wall',
|
||||
|
@ -90,17 +107,16 @@ class ConstructionHelper:
|
|||
}
|
||||
|
||||
@staticmethod
|
||||
def nrel_from_function(function):
|
||||
def nrel_from_libs_function(function):
|
||||
"""
|
||||
Get NREL function from the given internal function key
|
||||
:param function: str
|
||||
:return: str
|
||||
"""
|
||||
try:
|
||||
return ConstructionHelper.function_to_nrel[function]
|
||||
return ConstructionHelper._function_to_nrel[function]
|
||||
except KeyError:
|
||||
sys.stderr.write('Error: keyword not found. Returned default NREL function "residential"\n')
|
||||
return ConstructionHelper.nrel_function_default_value
|
||||
sys.stderr.write('Error: keyword not found.\n')
|
||||
|
||||
@staticmethod
|
||||
def yoc_to_nrel_standard(year_of_construction):
|
||||
|
@ -136,17 +152,16 @@ class ConstructionHelper:
|
|||
:return: str
|
||||
"""
|
||||
reference_city = ConstructionHelper.city_to_reference_city(city)
|
||||
return ConstructionHelper.reference_city_to_nrel_climate_zone[reference_city]
|
||||
return ConstructionHelper._reference_city_to_nrel_climate_zone[reference_city]
|
||||
|
||||
@staticmethod
|
||||
def nrcan_from_function(function):
|
||||
def nrcan_from_libs_function(function):
|
||||
"""
|
||||
Get NREL function from the given internal function key
|
||||
:param function: str
|
||||
:return: str
|
||||
"""
|
||||
try:
|
||||
return ConstructionHelper.function_to_nrcan[function]
|
||||
return ConstructionHelper._function_to_nrcan[function]
|
||||
except KeyError:
|
||||
sys.stderr.write('Error: keyword not found. Returned default NRCAN function "residential"\n')
|
||||
return ConstructionHelper.nrcan_function_default_value
|
||||
sys.stderr.write('Error: keyword not found.\n')
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
"""
|
||||
Storeys generation helper
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
Copyright © 2022 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
import sys
|
||||
import math
|
||||
import numpy as np
|
||||
from typing import List
|
||||
|
||||
from helpers import constants as cte
|
||||
from city_model_structure.attributes.polygon import Polygon
|
||||
from city_model_structure.attributes.point import Point
|
||||
from city_model_structure.building_demand.storey import Storey
|
||||
from city_model_structure.building_demand.surface import Surface
|
||||
from city_model_structure.building_demand.thermal_zone import ThermalZone
|
||||
|
||||
|
||||
class StoreysGeneration:
|
||||
|
@ -20,11 +22,14 @@ class StoreysGeneration:
|
|||
"""
|
||||
def __init__(self, building, divide_in_storeys=False):
|
||||
self._building = building
|
||||
self._thermal_zones = []
|
||||
self._divide_in_storeys = divide_in_storeys
|
||||
self._storeys = None
|
||||
self._floor_area = 0
|
||||
for ground in building.grounds:
|
||||
self._floor_area += ground.perimeter_polygon.area
|
||||
|
||||
@property
|
||||
def storeys(self) -> [Storey]:
|
||||
def thermal_zones(self) -> List[ThermalZone]:
|
||||
"""
|
||||
Get subsections of building trimesh by storey in case of no interiors defined
|
||||
:return: [Storey]
|
||||
|
@ -34,7 +39,21 @@ class StoreysGeneration:
|
|||
self._building.storeys_above_ground)
|
||||
number_of_storeys = 1
|
||||
if not self._divide_in_storeys or number_of_storeys == 1:
|
||||
return [Storey('storey_0', self._building.surfaces, [None, None], self._building.volume)]
|
||||
storey = Storey('storey_0', self._building.surfaces, [None, None], self._building.volume, self._floor_area)
|
||||
for thermal_boundary in storey.thermal_boundaries:
|
||||
if thermal_boundary.type != cte.INTERIOR_WALL or thermal_boundary.type != cte.INTERIOR_SLAB:
|
||||
# external thermal boundary -> only one thermal zone
|
||||
thermal_zones = [storey.thermal_zone]
|
||||
else:
|
||||
# internal thermal boundary -> two thermal zones
|
||||
grad = np.rad2deg(thermal_boundary.inclination)
|
||||
if grad >= 170:
|
||||
thermal_zones = [storey.thermal_zone, storey.neighbours[0]]
|
||||
else:
|
||||
thermal_zones = [storey.neighbours[1], storey.thermal_zone]
|
||||
thermal_boundary.thermal_zones = thermal_zones
|
||||
|
||||
return [storey.thermal_zone]
|
||||
|
||||
if number_of_storeys == 0:
|
||||
raise Exception('Number of storeys cannot be 0')
|
||||
|
@ -79,14 +98,32 @@ class StoreysGeneration:
|
|||
surfaces_child.append(ceiling)
|
||||
volume = ceiling.area_above_ground * height
|
||||
total_volume += volume
|
||||
storeys.append(Storey(name, surfaces_child, neighbours, volume))
|
||||
storeys.append(Storey(name, surfaces_child, neighbours, volume, self._floor_area))
|
||||
name = 'storey_' + str(number_of_storeys - 1)
|
||||
neighbours = ['storey_' + str(number_of_storeys - 2), None]
|
||||
volume = self._building.volume - total_volume
|
||||
if volume < 0:
|
||||
raise Exception('Error in storeys creation, volume of last storey cannot be lower that 0')
|
||||
storeys.append(Storey(name, surfaces_child_last_storey, neighbours, volume))
|
||||
return storeys
|
||||
storeys.append(Storey(name, surfaces_child_last_storey, neighbours, volume, self._floor_area))
|
||||
|
||||
for storey in storeys:
|
||||
for thermal_boundary in storey.thermal_boundaries:
|
||||
if thermal_boundary.type != cte.INTERIOR_WALL or thermal_boundary.type != cte.INTERIOR_SLAB:
|
||||
# external thermal boundary -> only one thermal zone
|
||||
thermal_zones = [storey.thermal_zone]
|
||||
else:
|
||||
# internal thermal boundary -> two thermal zones
|
||||
grad = np.rad2deg(thermal_boundary.inclination)
|
||||
if grad >= 170:
|
||||
thermal_zones = [storey.thermal_zone, storey.neighbours[0]]
|
||||
else:
|
||||
thermal_zones = [storey.neighbours[1], storey.thermal_zone]
|
||||
thermal_boundary.thermal_zones = thermal_zones
|
||||
|
||||
for storey in storeys:
|
||||
self._thermal_zones.append(storey.thermal_zone)
|
||||
|
||||
return self._thermal_zones
|
||||
|
||||
@staticmethod
|
||||
def _calculate_number_storeys_and_height(average_storey_height, eave_height, storeys_above_ground):
|
||||
|
@ -136,22 +173,3 @@ class StoreysGeneration:
|
|||
for point in points:
|
||||
array_points.append(point.coordinates)
|
||||
return np.array(array_points)
|
||||
|
||||
def assign_thermal_zones_delimited_by_thermal_boundaries(self):
|
||||
"""
|
||||
During storeys creation, the thermal boundaries and zones are also created.
|
||||
It is afterwards needed to define which zones are delimited by each thermal boundary
|
||||
"""
|
||||
for storey in self._building.storeys:
|
||||
for thermal_boundary in storey.thermal_boundaries:
|
||||
if thermal_boundary.surface.type != cte.INTERIOR_WALL or thermal_boundary.surface.type != cte.INTERIOR_SLAB:
|
||||
# external thermal boundary -> only one thermal zone
|
||||
thermal_zones = [storey.thermal_zone]
|
||||
else:
|
||||
# internal thermal boundary -> two thermal zones
|
||||
grad = np.rad2deg(thermal_boundary.surface.inclination)
|
||||
if grad >= 170:
|
||||
thermal_zones = [storey.thermal_zone, storey.neighbours[0]]
|
||||
else:
|
||||
thermal_zones = [storey.neighbours[1], storey.thermal_zone]
|
||||
thermal_boundary.thermal_zones = thermal_zones
|
||||
|
|
|
@ -6,10 +6,11 @@ Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.mons
|
|||
"""
|
||||
import xmltodict
|
||||
|
||||
from imports.construction.data_classes.nrel_building_achetype import NrelBuildingArchetype as nba
|
||||
from imports.construction.data_classes.nrel_thermal_boundary_archetype import NrelThermalBoundaryArchetype as ntba
|
||||
from imports.construction.data_classes.nrel_thermal_opening_archetype import NrelThermalOpeningArchetype as ntoa
|
||||
from imports.construction.data_classes.nrel_layer_archetype import NrelLayerArchetype as nla
|
||||
from imports.construction.data_classes.building_achetype import BuildingArchetype as nba
|
||||
from imports.construction.data_classes.thermal_boundary_archetype import ThermalBoundaryArchetype as ntba
|
||||
from imports.construction.data_classes.thermal_opening_archetype import ThermalOpeningArchetype as ntoa
|
||||
from imports.construction.data_classes.layer_archetype import LayerArchetype as nla
|
||||
from imports.construction.helpers.storeys_generation import StoreysGeneration
|
||||
|
||||
|
||||
class NrelPhysicsInterface:
|
||||
|
@ -71,7 +72,6 @@ class NrelPhysicsInterface:
|
|||
for current_layer in c_lib['layers']['layer']:
|
||||
material_lib = self._search_construction_type('material', current_layer['material'])
|
||||
name = material_lib['@name']
|
||||
lca_id = material_lib['@lca_id']
|
||||
solar_absorptance = material_lib['solar_absorptance']['#text']
|
||||
thermal_absorptance = material_lib['thermal_absorptance']['#text']
|
||||
visible_absorptance = material_lib['visible_absorptance']['#text']
|
||||
|
@ -82,7 +82,7 @@ class NrelPhysicsInterface:
|
|||
if units != '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,
|
||||
thermal_resistance=thermal_resistance, lca_id=lca_id)
|
||||
thermal_resistance=thermal_resistance)
|
||||
else:
|
||||
thickness = current_layer['thickness']['#text']
|
||||
units = current_layer['thickness']['@units']
|
||||
|
@ -101,7 +101,7 @@ class NrelPhysicsInterface:
|
|||
if units != 'kg/m3':
|
||||
raise Exception(f'density units = {units}, expected kg/m3')
|
||||
layer = nla(name, solar_absorptance, thermal_absorptance, visible_absorptance, thickness=thickness,
|
||||
conductivity=conductivity, specific_heat=specific_heat, density=density, lca_id=lca_id)
|
||||
conductivity=conductivity, specific_heat=specific_heat, density=density)
|
||||
layers.append(layer)
|
||||
|
||||
thermal_opening = None
|
||||
|
@ -150,10 +150,14 @@ class NrelPhysicsInterface:
|
|||
units = c_lib['overall_u_value']['@units']
|
||||
if units != 'W/m2 K':
|
||||
raise Exception(f'overall U-value units = {units}, expected W/m2 K')
|
||||
outside_solar_absorptance = c_lib['outside_solar_absorptance']['#text']
|
||||
thermal_boundary_archetype = ntba(construction_type, window_ratio, construction_name, layers,
|
||||
thermal_opening, outside_solar_absorptance=outside_solar_absorptance,
|
||||
overall_u_value=overall_u_value)
|
||||
if 'outside_solar_absorptance' in c_lib:
|
||||
outside_solar_absorptance = c_lib['outside_solar_absorptance']['#text']
|
||||
thermal_boundary_archetype = ntba(construction_type, window_ratio, construction_name, layers,
|
||||
thermal_opening, outside_solar_absorptance=outside_solar_absorptance,
|
||||
overall_u_value=overall_u_value)
|
||||
else:
|
||||
thermal_boundary_archetype = ntba(construction_type, window_ratio, construction_name, layers,
|
||||
thermal_opening, overall_u_value=overall_u_value)
|
||||
else:
|
||||
thermal_boundary_archetype = ntba(construction_type, window_ratio, construction_name, layers,
|
||||
thermal_opening)
|
||||
|
@ -178,8 +182,57 @@ class NrelPhysicsInterface:
|
|||
return thermal_boundary
|
||||
raise Exception('Construction type not found')
|
||||
|
||||
# todo: verify windows
|
||||
@staticmethod
|
||||
def _calculate_view_factors(thermal_zone):
|
||||
"""
|
||||
Get thermal zone view factors matrix
|
||||
:return: [[float]]
|
||||
"""
|
||||
total_area = 0
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
total_area += thermal_boundary.opaque_area
|
||||
for thermal_opening in thermal_boundary.thermal_openings:
|
||||
total_area += thermal_opening.area
|
||||
|
||||
view_factors_matrix = []
|
||||
for thermal_boundary_1 in thermal_zone.thermal_boundaries:
|
||||
values = []
|
||||
for thermal_boundary_2 in thermal_zone.thermal_boundaries:
|
||||
value = 0
|
||||
if thermal_boundary_1.id != thermal_boundary_2.id:
|
||||
value = thermal_boundary_2.opaque_area / (total_area - thermal_boundary_1.opaque_area)
|
||||
values.append(value)
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
for thermal_opening in thermal_boundary.thermal_openings:
|
||||
value = thermal_opening.area / (total_area - thermal_boundary_1.opaque_area)
|
||||
values.append(value)
|
||||
view_factors_matrix.append(values)
|
||||
|
||||
for thermal_boundary_1 in thermal_zone.thermal_boundaries:
|
||||
values = []
|
||||
for thermal_opening_1 in thermal_boundary_1.thermal_openings:
|
||||
for thermal_boundary_2 in thermal_zone.thermal_boundaries:
|
||||
value = thermal_boundary_2.opaque_area / (total_area - thermal_opening_1.area)
|
||||
values.append(value)
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
for thermal_opening_2 in thermal_boundary.thermal_openings:
|
||||
value = 0
|
||||
if thermal_opening_1.id != thermal_opening_2.id:
|
||||
value = thermal_opening_2.area / (total_area - thermal_opening_1.area)
|
||||
values.append(value)
|
||||
view_factors_matrix.append(values)
|
||||
thermal_zone.view_factors_matrix = view_factors_matrix
|
||||
|
||||
def enrich_buildings(self):
|
||||
"""
|
||||
Raise not implemented error
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@staticmethod
|
||||
def _create_storeys(building, archetype):
|
||||
building.average_storey_height = archetype.average_storey_height
|
||||
building.storeys_above_ground = archetype.storeys_above_ground
|
||||
thermal_zones = StoreysGeneration(building).thermal_zones
|
||||
building.internal_zones[0].thermal_zones = thermal_zones
|
||||
|
|
|
@ -10,7 +10,6 @@ from imports.construction.nrel_physics_interface import NrelPhysicsInterface
|
|||
from imports.construction.helpers.construction_helper import ConstructionHelper
|
||||
from city_model_structure.building_demand.layer import Layer
|
||||
from city_model_structure.building_demand.material import Material
|
||||
from imports.construction.helpers.storeys_generation import StoreysGeneration
|
||||
|
||||
|
||||
class UsPhysicsParameters(NrelPhysicsInterface):
|
||||
|
@ -30,19 +29,27 @@ class UsPhysicsParameters(NrelPhysicsInterface):
|
|||
city = self._city
|
||||
# it is assumed that all buildings have the same archetypes' keys
|
||||
for building in city.buildings:
|
||||
building_type = ConstructionHelper.nrel_from_function(building.function)
|
||||
building_type = ConstructionHelper.nrel_from_libs_function(building.function)
|
||||
if building_type is None:
|
||||
return
|
||||
archetype = self._search_archetype(building_type,
|
||||
ConstructionHelper.yoc_to_nrel_standard(building.year_of_construction),
|
||||
self._climate_zone)
|
||||
if archetype is None:
|
||||
try:
|
||||
archetype = self._search_archetype(building_type,
|
||||
ConstructionHelper.yoc_to_nrel_standard(building.year_of_construction),
|
||||
self._climate_zone)
|
||||
except KeyError:
|
||||
sys.stderr.write(f'Building {building.name} has unknown archetype for building function: {building.function} '
|
||||
f'and building year of construction: {building.year_of_construction}\n')
|
||||
continue
|
||||
return
|
||||
|
||||
self._create_storeys(building, archetype)
|
||||
self._assign_values(building, archetype)
|
||||
# if building has no thermal zones defined from geometry, one thermal zone per storey is assigned
|
||||
if len(building.internal_zones) == 1:
|
||||
if building.internal_zones[0].thermal_zones is None:
|
||||
self._create_storeys(building, archetype)
|
||||
|
||||
self._assign_values(building.internal_zones, archetype)
|
||||
for internal_zone in building.internal_zones:
|
||||
for thermal_zone in internal_zone.thermal_zones:
|
||||
self._calculate_view_factors(thermal_zone)
|
||||
|
||||
def _search_archetype(self, building_type, standard, climate_zone):
|
||||
for building_archetype in self._building_archetypes:
|
||||
|
@ -53,57 +60,50 @@ class UsPhysicsParameters(NrelPhysicsInterface):
|
|||
return building_archetype
|
||||
return None
|
||||
|
||||
def _assign_values(self, building, archetype):
|
||||
for thermal_zone in building.thermal_zones:
|
||||
thermal_zone.additional_thermal_bridge_u_value = archetype.additional_thermal_bridge_u_value
|
||||
thermal_zone.effective_thermal_capacity = archetype.effective_thermal_capacity
|
||||
thermal_zone.indirectly_heated_area_ratio = archetype.indirectly_heated_area_ratio
|
||||
thermal_zone.infiltration_rate_system_on = archetype.infiltration_rate_system_on
|
||||
thermal_zone.infiltration_rate_system_off = archetype.infiltration_rate_system_off
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
construction_type = ConstructionHelper.nrel_construction_types[thermal_boundary.type]
|
||||
thermal_boundary_archetype = self._search_construction_in_archetype(archetype, construction_type)
|
||||
if thermal_boundary_archetype.outside_solar_absorptance is not None:
|
||||
def _assign_values(self, internal_zones, archetype):
|
||||
for internal_zone in internal_zones:
|
||||
for thermal_zone in internal_zone.thermal_zones:
|
||||
thermal_zone.additional_thermal_bridge_u_value = archetype.additional_thermal_bridge_u_value
|
||||
thermal_zone.effective_thermal_capacity = archetype.effective_thermal_capacity
|
||||
thermal_zone.indirectly_heated_area_ratio = archetype.indirectly_heated_area_ratio
|
||||
thermal_zone.infiltration_rate_system_on = archetype.infiltration_rate_system_on
|
||||
thermal_zone.infiltration_rate_system_off = archetype.infiltration_rate_system_off
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
construction_type = ConstructionHelper.nrel_construction_types[thermal_boundary.type]
|
||||
thermal_boundary_archetype = self._search_construction_in_archetype(archetype, construction_type)
|
||||
thermal_boundary.outside_solar_absorptance = thermal_boundary_archetype.outside_solar_absorptance
|
||||
thermal_boundary.outside_thermal_absorptance = thermal_boundary_archetype.outside_thermal_absorptance
|
||||
thermal_boundary.outside_visible_absorptance = thermal_boundary_archetype.outside_visible_absorptance
|
||||
thermal_boundary.construction_name = thermal_boundary_archetype.construction_name
|
||||
thermal_boundary.window_ratio = thermal_boundary_archetype.window_ratio
|
||||
thermal_boundary.layers = []
|
||||
for layer_archetype in thermal_boundary_archetype.layers:
|
||||
layer = Layer()
|
||||
layer.thickness = layer_archetype.thickness
|
||||
material = Material()
|
||||
material.name = layer_archetype.name
|
||||
material.no_mass = layer_archetype.no_mass
|
||||
material.density = layer_archetype.density
|
||||
material.conductivity = layer_archetype.conductivity
|
||||
material.specific_heat = layer_archetype.specific_heat
|
||||
material.solar_absorptance = layer_archetype.solar_absorptance
|
||||
material.thermal_absorptance = layer_archetype.thermal_absorptance
|
||||
material.visible_absorptance = layer_archetype.visible_absorptance
|
||||
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
|
||||
thermal_boundary.layers.append(layer)
|
||||
for thermal_opening in thermal_boundary.thermal_openings:
|
||||
if thermal_boundary_archetype.thermal_opening is not None:
|
||||
thermal_opening_archetype = thermal_boundary_archetype.thermal_opening
|
||||
thermal_opening.frame_ratio = thermal_opening_archetype.frame_ratio
|
||||
thermal_opening.g_value = thermal_opening_archetype.g_value
|
||||
thermal_opening.conductivity = thermal_opening_archetype.conductivity
|
||||
thermal_opening.thickness = thermal_opening_archetype.thickness
|
||||
thermal_opening.back_side_solar_transmittance_at_normal_incidence = \
|
||||
thermal_opening_archetype.back_side_solar_transmittance_at_normal_incidence
|
||||
thermal_opening.front_side_solar_transmittance_at_normal_incidence = \
|
||||
thermal_opening_archetype.front_side_solar_transmittance_at_normal_incidence
|
||||
|
||||
@staticmethod
|
||||
def _create_storeys(building, archetype):
|
||||
building.average_storey_height = archetype.average_storey_height
|
||||
building.storeys_above_ground = archetype.storeys_above_ground
|
||||
storeys_generation = StoreysGeneration(building)
|
||||
storeys = storeys_generation.storeys
|
||||
building.storeys = storeys
|
||||
storeys_generation.assign_thermal_zones_delimited_by_thermal_boundaries()
|
||||
thermal_boundary.outside_thermal_absorptance = thermal_boundary_archetype.outside_thermal_absorptance
|
||||
thermal_boundary.outside_visible_absorptance = thermal_boundary_archetype.outside_visible_absorptance
|
||||
thermal_boundary.construction_name = thermal_boundary_archetype.construction_name
|
||||
try:
|
||||
thermal_boundary.window_ratio = thermal_boundary_archetype.window_ratio
|
||||
except ValueError:
|
||||
# This is the normal operation way when the windows are defined in the geometry
|
||||
continue
|
||||
thermal_boundary.layers = []
|
||||
for layer_archetype in thermal_boundary_archetype.layers:
|
||||
layer = Layer()
|
||||
layer.thickness = layer_archetype.thickness
|
||||
material = Material()
|
||||
material.name = layer_archetype.name
|
||||
material.no_mass = layer_archetype.no_mass
|
||||
material.density = layer_archetype.density
|
||||
material.conductivity = layer_archetype.conductivity
|
||||
material.specific_heat = layer_archetype.specific_heat
|
||||
material.solar_absorptance = layer_archetype.solar_absorptance
|
||||
material.thermal_absorptance = layer_archetype.thermal_absorptance
|
||||
material.visible_absorptance = layer_archetype.visible_absorptance
|
||||
material.thermal_resistance = layer_archetype.thermal_resistance
|
||||
layer.material = material
|
||||
thermal_boundary.layers.append(layer)
|
||||
for thermal_opening in thermal_boundary.thermal_openings:
|
||||
if thermal_boundary_archetype.thermal_opening_archetype is not None:
|
||||
thermal_opening_archetype = thermal_boundary_archetype.thermal_opening_archetype
|
||||
thermal_opening.frame_ratio = thermal_opening_archetype.frame_ratio
|
||||
thermal_opening.g_value = thermal_opening_archetype.g_value
|
||||
thermal_opening.conductivity = thermal_opening_archetype.conductivity
|
||||
thermal_opening.thickness = thermal_opening_archetype.thickness
|
||||
thermal_opening.back_side_solar_transmittance_at_normal_incidence = \
|
||||
thermal_opening_archetype.back_side_solar_transmittance_at_normal_incidence
|
||||
thermal_opening.front_side_solar_transmittance_at_normal_incidence = \
|
||||
thermal_opening_archetype.front_side_solar_transmittance_at_normal_incidence
|
||||
|
|
|
@ -14,7 +14,7 @@ class SanamCustomizedUsageHelper:
|
|||
usage_to_customized = {
|
||||
cte.RESIDENTIAL: 'residential',
|
||||
cte.INDUSTRY: 'manufacturing',
|
||||
cte.OFFICE_ADMINISTRATION: 'office',
|
||||
cte.OFFICE_AND_ADMINISTRATION: 'office',
|
||||
cte.HOTEL: 'hotel',
|
||||
cte.HEALTH_CARE: 'health',
|
||||
cte.RETAIL: 'retail',
|
||||
|
|
|
@ -6,9 +6,11 @@ Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.mons
|
|||
|
||||
import sys
|
||||
import xmltodict
|
||||
from imports.geometry.helpers.geometry_helper import GeometryHelper as gh
|
||||
from imports.usage.data_classes.hft_usage_zone_archetype import HftUsageZoneArchetype as huza
|
||||
import helpers.constants as cte
|
||||
from imports.usage.helpers.usage_helper import UsageHelper
|
||||
from city_model_structure.building_demand.occupancy import Occupancy
|
||||
from city_model_structure.building_demand.usage_zone import UsageZone
|
||||
from imports.geometry.helpers.geometry_helper import GeometryHelper
|
||||
|
||||
|
||||
class SanamCustomizedUsageParameters:
|
||||
|
@ -18,15 +20,10 @@ class SanamCustomizedUsageParameters:
|
|||
def __init__(self, city, base_path):
|
||||
file = 'ashrae_archetypes.xml'
|
||||
path = str(base_path / file)
|
||||
self._city = city
|
||||
self._usage_archetypes = []
|
||||
with open(path) as xml:
|
||||
self._archetypes = xmltodict.parse(xml.read(), force_list=('zoneUsageVariant', 'zoneUsageType'))
|
||||
for zone_usage_type in self._archetypes['buildingUsageLibrary']['zoneUsageType']:
|
||||
usage = zone_usage_type['id']
|
||||
usage_archetype = self._parse_zone_usage_type(usage, zone_usage_type)
|
||||
self._usage_archetypes.append(usage_archetype)
|
||||
|
||||
self._city = city
|
||||
|
||||
def enrich_buildings(self):
|
||||
"""
|
||||
|
@ -35,48 +32,59 @@ class SanamCustomizedUsageParameters:
|
|||
"""
|
||||
city = self._city
|
||||
for building in city.buildings:
|
||||
archetype = self._search_archetype(building.function) # todo: building.function or other translation???????
|
||||
height = building.average_storey_height
|
||||
if height is None:
|
||||
raise Exception('Average storey height not defined, ACH cannot be calculated')
|
||||
if height <= 0:
|
||||
raise Exception('Average storey height is zero, ACH cannot be calculated')
|
||||
libs_usage = GeometryHelper().libs_usage_from_libs_function(building.function)
|
||||
comnet_usage = UsageHelper().comnet_from_libs_usage(libs_usage)
|
||||
archetype = self._search_archetype(comnet_usage)
|
||||
if archetype is None:
|
||||
sys.stderr.write(f'Building {building.name} has unknown archetype for building function:'
|
||||
f' {building.function}, that assigns building usage as '
|
||||
f'{gh.usage_from_function(building.function)}\n')
|
||||
continue
|
||||
mix_usage = False
|
||||
if not mix_usage:
|
||||
# just one usage_zone
|
||||
for usage_zone in building.usage_zones:
|
||||
self._assign_values(usage_zone, archetype, height)
|
||||
f'{libs_usage}\n')
|
||||
return
|
||||
|
||||
def _search_archetype(self, building_usage):
|
||||
for building_archetype in self._usage_archetypes:
|
||||
if building_archetype.usage == building_usage:
|
||||
return building_archetype
|
||||
for internal_zone in building.internal_zones:
|
||||
if internal_zone.area is None:
|
||||
raise Exception('Internal zone area not defined, ACH cannot be calculated')
|
||||
if internal_zone.volume is None:
|
||||
raise Exception('Internal zone volume not defined, ACH cannot be calculated')
|
||||
if internal_zone.area <= 0:
|
||||
raise Exception('Internal zone area is zero, ACH cannot be calculated')
|
||||
if internal_zone.volume <= 0:
|
||||
raise Exception('Internal zone volume is zero, ACH cannot be calculated')
|
||||
volume_per_area = internal_zone.volume / internal_zone.area
|
||||
|
||||
usage_zone = UsageZone()
|
||||
usage_zone.usage = libs_usage
|
||||
self._assign_values(usage_zone, archetype, volume_per_area)
|
||||
|
||||
def _search_archetype(self, libs_usage):
|
||||
comnet_usage = UsageHelper.comnet_from_libs_usage(libs_usage)
|
||||
for building_archetype in self._archetypes['buildingUsageLibrary']['zoneUsageType']:
|
||||
if building_archetype['id'] == comnet_usage:
|
||||
usage_archetype = self._parse_usage_type(self._archetypes)
|
||||
return usage_archetype
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def _assign_values(usage_zone, archetype, height):
|
||||
def _assign_values(usage_zone, archetype, volume_per_area):
|
||||
usage_zone.usage = archetype.usage
|
||||
# Due to the fact that python is not a typed language, the wrong object type is assigned to
|
||||
# usage_zone.internal_gains when writing usage_zone.internal_gains = archetype.internal_gains.
|
||||
# Therefore, this walk around has been done.
|
||||
if archetype.occupancy_density is not None:
|
||||
usage_zone.occupancy_density = archetype.occupancy_density
|
||||
archetype_mechanical_air_change = float(archetype.mechanical_air_change) * float(usage_zone.occupancy_density) \
|
||||
* cte.HOUR_TO_MINUTES / cte.METERS_TO_FEET**3 / height
|
||||
usage_zone.mechanical_air_change = archetype_mechanical_air_change
|
||||
if archetype.occupancy.occupancy_density is not None:
|
||||
if usage_zone.occupancy is None:
|
||||
_occupancy = Occupancy()
|
||||
usage_zone.occupancy = _occupancy
|
||||
usage_zone.occupancy.occupancy_density = archetype.occupancy.occupancy_density
|
||||
archetype_mechanical_air_change = float(archetype.mechanical_air_change) * \
|
||||
float(usage_zone.occupancy.occupancy_density) * cte.METERS_TO_FEET ** 2 \
|
||||
* cte.HOUR_TO_MINUTES / cte.METERS_TO_FEET ** 3 / volume_per_area
|
||||
usage_zone.mechanical_air_change = archetype_mechanical_air_change
|
||||
|
||||
@staticmethod
|
||||
def _parse_zone_usage_type(usage, zone_usage_type):
|
||||
mechanical_air_change = zone_usage_type['endUses']['ventilation']['minimumVentilationRate']['#text']
|
||||
if 'occupancy' in zone_usage_type:
|
||||
occupancy_density = zone_usage_type['occupancy']['occupancyDensity']['#text']
|
||||
usage_zone_archetype = huza(usage=usage, occupancy_density=occupancy_density,
|
||||
mechanical_air_change=mechanical_air_change)
|
||||
else:
|
||||
usage_zone_archetype = huza(usage=usage, mechanical_air_change=mechanical_air_change)
|
||||
def _parse_usage_type(data):
|
||||
usage_zone_archetype = UsageZone()
|
||||
usage_zone_archetype.usage = data['id']
|
||||
usage_zone_archetype.mechanical_air_change = data['endUses']['ventilation']['minimumVentilationRate'][
|
||||
'#text']
|
||||
if 'occupancy' in data:
|
||||
_occupancy = Occupancy()
|
||||
_occupancy.occupancy_density = data['occupancy']['occupancyDensity']['#text']
|
||||
usage_zone_archetype.occupancy = _occupancy
|
||||
return usage_zone_archetype
|
||||
|
|
|
@ -17,10 +17,6 @@ class CustomizedImportsFactory:
|
|||
self._importer_class = importer_class
|
||||
self._city = city
|
||||
self._base_path = base_path
|
||||
for building in city.buildings:
|
||||
if len(building.thermal_zones) == 0:
|
||||
raise Exception('It seems that the customized imports factory is being called before the construction factory. '
|
||||
'Please ensure that the construction factory is called first.')
|
||||
|
||||
def enrich(self):
|
||||
"""
|
||||
|
|
|
@ -83,7 +83,7 @@ class CityGml:
|
|||
surfaces = CityGmlLod2(city_object).surfaces
|
||||
else:
|
||||
raise NotImplementedError("Not supported level of detail")
|
||||
return Building(name, lod, surfaces, year_of_construction, function, self._lower_corner, [])
|
||||
return Building(name, lod, surfaces, year_of_construction, function, self._lower_corner, terrains=None)
|
||||
|
||||
def _create_parts_consisting_building(self, city_object):
|
||||
name = city_object['@id']
|
||||
|
|
|
@ -12,292 +12,273 @@ class GeometryHelper:
|
|||
Geometry helper
|
||||
"""
|
||||
# function
|
||||
pluto_to_function = {
|
||||
'A0': 'single family house',
|
||||
'A1': 'single family house',
|
||||
'A2': 'single family house',
|
||||
'A3': 'single family house',
|
||||
'A4': 'single family house',
|
||||
'A5': 'single family house',
|
||||
'A6': 'single family house',
|
||||
'A7': 'single family house',
|
||||
'A8': 'single family house',
|
||||
'A9': 'single family house',
|
||||
'B1': 'multifamily house',
|
||||
'B2': 'multifamily house',
|
||||
'B3': 'multifamily house',
|
||||
'B9': 'multifamily house',
|
||||
'C0': 'residential',
|
||||
'C1': 'residential',
|
||||
'C2': 'residential',
|
||||
'C3': 'residential',
|
||||
'C4': 'residential',
|
||||
'C5': 'residential',
|
||||
'C6': 'residential',
|
||||
'C7': 'residential',
|
||||
'C8': 'residential',
|
||||
'C9': 'residential',
|
||||
'D0': 'residential',
|
||||
'D1': 'residential',
|
||||
'D2': 'residential',
|
||||
'D3': 'residential',
|
||||
'D4': 'residential',
|
||||
'D5': 'residential',
|
||||
'D6': 'residential',
|
||||
'D7': 'residential',
|
||||
'D8': 'residential',
|
||||
'D9': 'residential',
|
||||
'E1': 'warehouse',
|
||||
'E3': 'warehouse',
|
||||
'E4': 'warehouse',
|
||||
'E5': 'warehouse',
|
||||
'E7': 'warehouse',
|
||||
'E9': 'warehouse',
|
||||
'F1': 'warehouse',
|
||||
'F2': 'warehouse',
|
||||
'F4': 'warehouse',
|
||||
'F5': 'warehouse',
|
||||
'F8': 'warehouse',
|
||||
'F9': 'warehouse',
|
||||
'G0': 'office',
|
||||
'G1': 'office',
|
||||
'G2': 'office',
|
||||
'G3': 'office',
|
||||
'G4': 'office',
|
||||
'G5': 'office',
|
||||
'G6': 'office',
|
||||
'G7': 'office',
|
||||
'G8': 'office',
|
||||
'G9': 'office',
|
||||
'H1': 'hotel',
|
||||
'H2': 'hotel',
|
||||
'H3': 'hotel',
|
||||
'H4': 'hotel',
|
||||
'H5': 'hotel',
|
||||
'H6': 'hotel',
|
||||
'H7': 'hotel',
|
||||
'H8': 'hotel',
|
||||
'H9': 'hotel',
|
||||
'HB': 'hotel',
|
||||
'HH': 'hotel',
|
||||
'HR': 'hotel',
|
||||
'HS': 'hotel',
|
||||
'I1': 'hospital',
|
||||
'I2': 'outpatient',
|
||||
'I3': 'outpatient',
|
||||
'I4': 'residential',
|
||||
'I5': 'outpatient',
|
||||
'I6': 'outpatient',
|
||||
'I7': 'outpatient',
|
||||
'I9': 'outpatient',
|
||||
'J1': 'large office',
|
||||
'J2': 'large office',
|
||||
'J3': 'large office',
|
||||
'J4': 'large office',
|
||||
'J5': 'large office',
|
||||
'J6': 'large office',
|
||||
'J7': 'large office',
|
||||
'J8': 'large office',
|
||||
'J9': 'large office',
|
||||
'K1': 'strip mall',
|
||||
'K2': 'strip mall',
|
||||
'K3': 'strip mall',
|
||||
'K4': 'residential',
|
||||
'K5': 'restaurant',
|
||||
'K6': 'commercial',
|
||||
'K7': 'commercial',
|
||||
'K8': 'commercial',
|
||||
'K9': 'commercial',
|
||||
'L1': 'residential',
|
||||
'L2': 'residential',
|
||||
'L3': 'residential',
|
||||
'L8': 'residential',
|
||||
'L9': 'residential',
|
||||
'M1': 'large office',
|
||||
'M2': 'large office',
|
||||
'M3': 'large office',
|
||||
'M4': 'large office',
|
||||
'M9': 'large office',
|
||||
'N1': 'residential',
|
||||
'N2': 'residential',
|
||||
'N3': 'residential',
|
||||
'N4': 'residential',
|
||||
'N9': 'residential',
|
||||
'O1': 'office',
|
||||
'O2': 'office',
|
||||
'O3': 'office',
|
||||
'O4': 'office',
|
||||
'O5': 'office',
|
||||
'O6': 'office',
|
||||
'O7': 'office',
|
||||
'O8': 'office',
|
||||
'O9': 'office',
|
||||
'P1': 'large office',
|
||||
'P2': 'hotel',
|
||||
'P3': 'office',
|
||||
'P4': 'office',
|
||||
'P5': 'office',
|
||||
'P6': 'office',
|
||||
'P7': 'large office',
|
||||
'P8': 'large office',
|
||||
'P9': 'office',
|
||||
'Q0': 'office',
|
||||
'Q1': 'office',
|
||||
'Q2': 'office',
|
||||
'Q3': 'office',
|
||||
'Q4': 'office',
|
||||
'Q5': 'office',
|
||||
'Q6': 'office',
|
||||
'Q7': 'office',
|
||||
'Q8': 'office',
|
||||
'Q9': 'office',
|
||||
'R0': 'residential',
|
||||
'R1': 'residential',
|
||||
'R2': 'residential',
|
||||
'R3': 'residential',
|
||||
'R4': 'residential',
|
||||
'R5': 'residential',
|
||||
'R6': 'residential',
|
||||
'R7': 'residential',
|
||||
'R8': 'residential',
|
||||
'R9': 'residential',
|
||||
'RA': 'residential',
|
||||
'RB': 'residential',
|
||||
'RC': 'residential',
|
||||
'RD': 'residential',
|
||||
'RG': 'residential',
|
||||
'RH': 'residential',
|
||||
'RI': 'residential',
|
||||
'RK': 'residential',
|
||||
'RM': 'residential',
|
||||
'RR': 'residential',
|
||||
'RS': 'residential',
|
||||
'RW': 'residential',
|
||||
'RX': 'residential',
|
||||
'RZ': 'residential',
|
||||
'S0': 'residential',
|
||||
'S1': 'residential',
|
||||
'S2': 'residential',
|
||||
'S3': 'residential',
|
||||
'S4': 'residential',
|
||||
'S5': 'residential',
|
||||
'S9': 'residential',
|
||||
'T1': 'na',
|
||||
'T2': 'na',
|
||||
'T9': 'na',
|
||||
'U0': 'warehouse',
|
||||
'U1': 'warehouse',
|
||||
'U2': 'warehouse',
|
||||
'U3': 'warehouse',
|
||||
'U4': 'warehouse',
|
||||
'U5': 'warehouse',
|
||||
'U6': 'warehouse',
|
||||
'U7': 'warehouse',
|
||||
'U8': 'warehouse',
|
||||
'U9': 'warehouse',
|
||||
'V0': 'na',
|
||||
'V1': 'na',
|
||||
'V2': 'na',
|
||||
'V3': 'na',
|
||||
'V4': 'na',
|
||||
'V5': 'na',
|
||||
'V6': 'na',
|
||||
'V7': 'na',
|
||||
'V8': 'na',
|
||||
'V9': 'na',
|
||||
'W1': 'primary school',
|
||||
'W2': 'primary school',
|
||||
'W3': 'secondary school',
|
||||
'W4': 'secondary school',
|
||||
'W5': 'secondary school',
|
||||
'W6': 'secondary school',
|
||||
'W7': 'secondary school',
|
||||
'W8': 'primary school',
|
||||
'W9': 'secondary school',
|
||||
'Y1': 'large office',
|
||||
'Y2': 'large office',
|
||||
'Y3': 'large office',
|
||||
'Y4': 'large office',
|
||||
'Y5': 'large office',
|
||||
'Y6': 'large office',
|
||||
'Y7': 'large office',
|
||||
'Y8': 'large office',
|
||||
'Y9': 'large office',
|
||||
'Z0': 'na',
|
||||
'Z1': 'large office',
|
||||
'Z2': 'na',
|
||||
'Z3': 'na',
|
||||
'Z4': 'na',
|
||||
'Z5': 'na',
|
||||
'Z6': 'na',
|
||||
'Z7': 'na',
|
||||
'Z8': 'na',
|
||||
'Z9': 'na'
|
||||
_pluto_to_function = {
|
||||
'A0': cte.SINGLE_FAMILY_HOUSE,
|
||||
'A1': cte.SINGLE_FAMILY_HOUSE,
|
||||
'A2': cte.SINGLE_FAMILY_HOUSE,
|
||||
'A3': cte.SINGLE_FAMILY_HOUSE,
|
||||
'A4': cte.SINGLE_FAMILY_HOUSE,
|
||||
'A5': cte.SINGLE_FAMILY_HOUSE,
|
||||
'A6': cte.SINGLE_FAMILY_HOUSE,
|
||||
'A7': cte.SINGLE_FAMILY_HOUSE,
|
||||
'A8': cte.SINGLE_FAMILY_HOUSE,
|
||||
'A9': cte.SINGLE_FAMILY_HOUSE,
|
||||
'B1': cte.MULTI_FAMILY_HOUSE,
|
||||
'B2': cte.MULTI_FAMILY_HOUSE,
|
||||
'B3': cte.MULTI_FAMILY_HOUSE,
|
||||
'B9': cte.MULTI_FAMILY_HOUSE,
|
||||
'C0': cte.RESIDENTIAL,
|
||||
'C1': cte.RESIDENTIAL,
|
||||
'C2': cte.RESIDENTIAL,
|
||||
'C3': cte.RESIDENTIAL,
|
||||
'C4': cte.RESIDENTIAL,
|
||||
'C5': cte.RESIDENTIAL,
|
||||
'C6': cte.RESIDENTIAL,
|
||||
'C7': cte.RESIDENTIAL,
|
||||
'C8': cte.RESIDENTIAL,
|
||||
'C9': cte.RESIDENTIAL,
|
||||
'D0': cte.RESIDENTIAL,
|
||||
'D1': cte.RESIDENTIAL,
|
||||
'D2': cte.RESIDENTIAL,
|
||||
'D3': cte.RESIDENTIAL,
|
||||
'D4': cte.RESIDENTIAL,
|
||||
'D5': cte.RESIDENTIAL,
|
||||
'D6': cte.RESIDENTIAL,
|
||||
'D7': cte.RESIDENTIAL,
|
||||
'D8': cte.RESIDENTIAL,
|
||||
'D9': cte.RESIDENTIAL,
|
||||
'E1': cte.WAREHOUSE,
|
||||
'E3': cte.WAREHOUSE,
|
||||
'E4': cte.WAREHOUSE,
|
||||
'E5': cte.WAREHOUSE,
|
||||
'E7': cte.WAREHOUSE,
|
||||
'E9': cte.WAREHOUSE,
|
||||
'F1': cte.WAREHOUSE,
|
||||
'F2': cte.WAREHOUSE,
|
||||
'F4': cte.WAREHOUSE,
|
||||
'F5': cte.WAREHOUSE,
|
||||
'F8': cte.WAREHOUSE,
|
||||
'F9': cte.WAREHOUSE,
|
||||
'G0': cte.SMALL_OFFICE,
|
||||
'G1': cte.SMALL_OFFICE,
|
||||
'G2': cte.SMALL_OFFICE,
|
||||
'G3': cte.SMALL_OFFICE,
|
||||
'G4': cte.SMALL_OFFICE,
|
||||
'G5': cte.SMALL_OFFICE,
|
||||
'G6': cte.SMALL_OFFICE,
|
||||
'G7': cte.SMALL_OFFICE,
|
||||
'G8': cte.SMALL_OFFICE,
|
||||
'G9': cte.SMALL_OFFICE,
|
||||
'H1': cte.HOTEL,
|
||||
'H2': cte.HOTEL,
|
||||
'H3': cte.HOTEL,
|
||||
'H4': cte.HOTEL,
|
||||
'H5': cte.HOTEL,
|
||||
'H6': cte.HOTEL,
|
||||
'H7': cte.HOTEL,
|
||||
'H8': cte.HOTEL,
|
||||
'H9': cte.HOTEL,
|
||||
'HB': cte.HOTEL,
|
||||
'HH': cte.HOTEL,
|
||||
'HR': cte.HOTEL,
|
||||
'HS': cte.HOTEL,
|
||||
'I1': cte.HOSPITAL,
|
||||
'I2': cte.OUT_PATIENT_HEALTH_CARE,
|
||||
'I3': cte.OUT_PATIENT_HEALTH_CARE,
|
||||
'I4': cte.RESIDENTIAL,
|
||||
'I5': cte.OUT_PATIENT_HEALTH_CARE,
|
||||
'I6': cte.OUT_PATIENT_HEALTH_CARE,
|
||||
'I7': cte.OUT_PATIENT_HEALTH_CARE,
|
||||
'I9': cte.OUT_PATIENT_HEALTH_CARE,
|
||||
'J1': cte.LARGE_OFFICE,
|
||||
'J2': cte.LARGE_OFFICE,
|
||||
'J3': cte.LARGE_OFFICE,
|
||||
'J4': cte.LARGE_OFFICE,
|
||||
'J5': cte.LARGE_OFFICE,
|
||||
'J6': cte.LARGE_OFFICE,
|
||||
'J7': cte.LARGE_OFFICE,
|
||||
'J8': cte.LARGE_OFFICE,
|
||||
'J9': cte.LARGE_OFFICE,
|
||||
'K1': cte.STRIP_MALL,
|
||||
'K2': cte.STRIP_MALL,
|
||||
'K3': cte.STRIP_MALL,
|
||||
'K4': cte.RESIDENTIAL,
|
||||
'K5': cte.RESTAURANT,
|
||||
'K6': cte.SUPERMARKET,
|
||||
'K7': cte.SUPERMARKET,
|
||||
'K8': cte.SUPERMARKET,
|
||||
'K9': cte.SUPERMARKET,
|
||||
'L1': cte.RESIDENTIAL,
|
||||
'L2': cte.RESIDENTIAL,
|
||||
'L3': cte.RESIDENTIAL,
|
||||
'L8': cte.RESIDENTIAL,
|
||||
'L9': cte.RESIDENTIAL,
|
||||
'M1': cte.LARGE_OFFICE,
|
||||
'M2': cte.LARGE_OFFICE,
|
||||
'M3': cte.LARGE_OFFICE,
|
||||
'M4': cte.LARGE_OFFICE,
|
||||
'M9': cte.LARGE_OFFICE,
|
||||
'N1': cte.RESIDENTIAL,
|
||||
'N2': cte.RESIDENTIAL,
|
||||
'N3': cte.RESIDENTIAL,
|
||||
'N4': cte.RESIDENTIAL,
|
||||
'N9': cte.RESIDENTIAL,
|
||||
'O1': cte.SMALL_OFFICE,
|
||||
'O2': cte.SMALL_OFFICE,
|
||||
'O3': cte.SMALL_OFFICE,
|
||||
'O4': cte.SMALL_OFFICE,
|
||||
'O5': cte.SMALL_OFFICE,
|
||||
'O6': cte.SMALL_OFFICE,
|
||||
'O7': cte.SMALL_OFFICE,
|
||||
'O8': cte.SMALL_OFFICE,
|
||||
'O9': cte.SMALL_OFFICE,
|
||||
'P1': cte.LARGE_OFFICE,
|
||||
'P2': cte.HOTEL,
|
||||
'P3': cte.SMALL_OFFICE,
|
||||
'P4': cte.SMALL_OFFICE,
|
||||
'P5': cte.SMALL_OFFICE,
|
||||
'P6': cte.SMALL_OFFICE,
|
||||
'P7': cte.LARGE_OFFICE,
|
||||
'P8': cte.LARGE_OFFICE,
|
||||
'P9': cte.SMALL_OFFICE,
|
||||
'Q0': cte.SMALL_OFFICE,
|
||||
'Q1': cte.SMALL_OFFICE,
|
||||
'Q2': cte.SMALL_OFFICE,
|
||||
'Q3': cte.SMALL_OFFICE,
|
||||
'Q4': cte.SMALL_OFFICE,
|
||||
'Q5': cte.SMALL_OFFICE,
|
||||
'Q6': cte.SMALL_OFFICE,
|
||||
'Q7': cte.SMALL_OFFICE,
|
||||
'Q8': cte.SMALL_OFFICE,
|
||||
'Q9': cte.SMALL_OFFICE,
|
||||
'R0': cte.RESIDENTIAL,
|
||||
'R1': cte.RESIDENTIAL,
|
||||
'R2': cte.RESIDENTIAL,
|
||||
'R3': cte.RESIDENTIAL,
|
||||
'R4': cte.RESIDENTIAL,
|
||||
'R5': cte.RESIDENTIAL,
|
||||
'R6': cte.RESIDENTIAL,
|
||||
'R7': cte.RESIDENTIAL,
|
||||
'R8': cte.RESIDENTIAL,
|
||||
'R9': cte.RESIDENTIAL,
|
||||
'RA': cte.RESIDENTIAL,
|
||||
'RB': cte.RESIDENTIAL,
|
||||
'RC': cte.RESIDENTIAL,
|
||||
'RD': cte.RESIDENTIAL,
|
||||
'RG': cte.RESIDENTIAL,
|
||||
'RH': cte.RESIDENTIAL,
|
||||
'RI': cte.RESIDENTIAL,
|
||||
'RK': cte.RESIDENTIAL,
|
||||
'RM': cte.RESIDENTIAL,
|
||||
'RR': cte.RESIDENTIAL,
|
||||
'RS': cte.RESIDENTIAL,
|
||||
'RW': cte.RESIDENTIAL,
|
||||
'RX': cte.RESIDENTIAL,
|
||||
'RZ': cte.RESIDENTIAL,
|
||||
'S0': cte.RESIDENTIAL,
|
||||
'S1': cte.RESIDENTIAL,
|
||||
'S2': cte.RESIDENTIAL,
|
||||
'S3': cte.RESIDENTIAL,
|
||||
'S4': cte.RESIDENTIAL,
|
||||
'S5': cte.RESIDENTIAL,
|
||||
'S9': cte.RESIDENTIAL,
|
||||
'U0': cte.WAREHOUSE,
|
||||
'U1': cte.WAREHOUSE,
|
||||
'U2': cte.WAREHOUSE,
|
||||
'U3': cte.WAREHOUSE,
|
||||
'U4': cte.WAREHOUSE,
|
||||
'U5': cte.WAREHOUSE,
|
||||
'U6': cte.WAREHOUSE,
|
||||
'U7': cte.WAREHOUSE,
|
||||
'U8': cte.WAREHOUSE,
|
||||
'U9': cte.WAREHOUSE,
|
||||
'W1': cte.PRIMARY_SCHOOL,
|
||||
'W2': cte.PRIMARY_SCHOOL,
|
||||
'W3': cte.SECONDARY_SCHOOL,
|
||||
'W4': cte.SECONDARY_SCHOOL,
|
||||
'W5': cte.SECONDARY_SCHOOL,
|
||||
'W6': cte.SECONDARY_SCHOOL,
|
||||
'W7': cte.SECONDARY_SCHOOL,
|
||||
'W8': cte.PRIMARY_SCHOOL,
|
||||
'W9': cte.SECONDARY_SCHOOL,
|
||||
'Y1': cte.LARGE_OFFICE,
|
||||
'Y2': cte.LARGE_OFFICE,
|
||||
'Y3': cte.LARGE_OFFICE,
|
||||
'Y4': cte.LARGE_OFFICE,
|
||||
'Y5': cte.LARGE_OFFICE,
|
||||
'Y6': cte.LARGE_OFFICE,
|
||||
'Y7': cte.LARGE_OFFICE,
|
||||
'Y8': cte.LARGE_OFFICE,
|
||||
'Y9': cte.LARGE_OFFICE,
|
||||
'Z1': cte.LARGE_OFFICE
|
||||
}
|
||||
hft_to_function = {
|
||||
_hft_to_function = {
|
||||
'residential': cte.RESIDENTIAL,
|
||||
'single family house': cte.SFH,
|
||||
'multifamily house': cte.MFH,
|
||||
'single family house': cte.SINGLE_FAMILY_HOUSE,
|
||||
'multifamily house': cte.MULTI_FAMILY_HOUSE,
|
||||
'hotel': cte.HOTEL,
|
||||
'hospital': cte.HOSPITAL,
|
||||
'outpatient': cte.OUTPATIENT,
|
||||
'commercial': cte.COMMERCIAL,
|
||||
'outpatient': cte.OUT_PATIENT_HEALTH_CARE,
|
||||
'commercial': cte.SUPERMARKET,
|
||||
'strip mall': cte.STRIP_MALL,
|
||||
'warehouse': cte.WAREHOUSE,
|
||||
'primary school': cte.PRIMARY_SCHOOL,
|
||||
'secondary school': cte.SECONDARY_SCHOOL,
|
||||
'office': cte.OFFICE,
|
||||
'office': cte.MEDIUM_OFFICE,
|
||||
'large office': cte.LARGE_OFFICE
|
||||
}
|
||||
|
||||
# usage
|
||||
function_to_usage = {
|
||||
'full service restaurant': 'restaurant',
|
||||
'highrise apartment': cte.RESIDENTIAL,
|
||||
'hospital': 'health care',
|
||||
'large hotel': 'hotel',
|
||||
'large office': 'office and administration',
|
||||
'medium office': 'office and administration',
|
||||
'midrise apartment': cte.RESIDENTIAL,
|
||||
'outpatient healthcare': 'health care',
|
||||
'primary school': 'education',
|
||||
'quick service restaurant': 'restaurant',
|
||||
'secondary school': 'education',
|
||||
'small hotel': 'hotel',
|
||||
'small office': 'office and administration',
|
||||
'stand alone retail': 'retail',
|
||||
'strip mall': 'hall',
|
||||
'supermarket': 'retail',
|
||||
'warehouse': 'industry',
|
||||
'residential': cte.RESIDENTIAL
|
||||
_function_to_usage = {
|
||||
cte.RESIDENTIAL: cte.RESIDENTIAL,
|
||||
cte.SINGLE_FAMILY_HOUSE: cte.SINGLE_FAMILY_HOUSE,
|
||||
cte.MULTI_FAMILY_HOUSE: cte.MULTI_FAMILY_HOUSE,
|
||||
cte.ROW_HOSE: cte.RESIDENTIAL,
|
||||
cte.MID_RISE_APARTMENT: cte.RESIDENTIAL,
|
||||
cte.HIGH_RISE_APARTMENT: cte.RESIDENTIAL,
|
||||
cte.SMALL_OFFICE: cte.OFFICE_AND_ADMINISTRATION,
|
||||
cte.MEDIUM_OFFICE: cte.OFFICE_AND_ADMINISTRATION,
|
||||
cte.LARGE_OFFICE: cte.OFFICE_AND_ADMINISTRATION,
|
||||
cte.PRIMARY_SCHOOL: cte.EDUCATION,
|
||||
cte.SECONDARY_SCHOOL: cte.EDUCATION,
|
||||
cte.STAND_ALONE_RETAIL: cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
|
||||
cte.HOSPITAL: cte.HEALTH_CARE,
|
||||
cte.OUT_PATIENT_HEALTH_CARE: cte.HEALTH_CARE,
|
||||
cte.STRIP_MALL: cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
|
||||
cte.SUPERMARKET: cte.RETAIL_SHOP_WITH_REFRIGERATED_FOOD,
|
||||
cte.WAREHOUSE: cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
|
||||
cte.QUICK_SERVICE_RESTAURANT: cte.RESTAURANT,
|
||||
cte.FULL_SERVICE_RESTAURANT: cte.RESTAURANT,
|
||||
cte.SMALL_HOTEL: cte.HOTEL,
|
||||
cte.LARGE_HOTEL: cte.HOTEL
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def function_from_hft(building_hft_function):
|
||||
def libs_function_from_hft(building_hft_function):
|
||||
"""
|
||||
Get internal function from the given HfT function
|
||||
:param building_hft_function: str
|
||||
:return: str
|
||||
"""
|
||||
return GeometryHelper.hft_to_function[building_hft_function]
|
||||
return GeometryHelper._hft_to_function[building_hft_function]
|
||||
|
||||
@staticmethod
|
||||
def function_from_pluto(building_pluto_function):
|
||||
def libs_function_from_pluto(building_pluto_function):
|
||||
"""
|
||||
Get internal function from the given pluto function
|
||||
:param building_pluto_function: str
|
||||
:return: str
|
||||
"""
|
||||
return GeometryHelper.pluto_to_function[building_pluto_function]
|
||||
return GeometryHelper._pluto_to_function[building_pluto_function]
|
||||
|
||||
@staticmethod
|
||||
def usage_from_function(building_function):
|
||||
def libs_usage_from_libs_function(building_function):
|
||||
"""
|
||||
Get the internal usage for the given internal building function
|
||||
:param building_function: str
|
||||
:return: str
|
||||
"""
|
||||
return GeometryHelper.function_to_usage[building_function]
|
||||
return GeometryHelper._function_to_usage[building_function]
|
||||
|
||||
@staticmethod
|
||||
def to_points_matrix(points):
|
||||
|
|
|
@ -76,6 +76,6 @@ class Obj:
|
|||
perimeter_polygon = solid_polygon
|
||||
surface = Surface(solid_polygon, perimeter_polygon)
|
||||
surfaces.append(surface)
|
||||
building = Building(name, lod, surfaces, year_of_construction, function, self._lower_corner)
|
||||
building = Building(name, lod, surfaces, year_of_construction, function, self._lower_corner, terrains=None)
|
||||
self._city.add_city_object(building)
|
||||
return self._city
|
||||
|
|
|
@ -3,16 +3,18 @@ Rhino module parses rhino files and import the geometry into the city model stru
|
|||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
import numpy as np
|
||||
from numpy import inf
|
||||
from rhino3dm import *
|
||||
from rhino3dm._rhino3dm import MeshType
|
||||
#from rhino3dm import *
|
||||
#from rhino3dm._rhino3dm import MeshType
|
||||
from city_model_structure.attributes.point import Point
|
||||
import numpy as np
|
||||
|
||||
from helpers.configuration_helper import ConfigurationHelper
|
||||
from city_model_structure.attributes.polygon import Polygon
|
||||
from city_model_structure.building import Building
|
||||
from city_model_structure.building_demand.surface import Surface as LibsSurface
|
||||
from city_model_structure.city import City
|
||||
from helpers.configuration_helper import ConfigurationHelper
|
||||
from city_model_structure.building_demand.surface import Surface as LibsSurface
|
||||
from helpers.constants import EPSILON
|
||||
from imports.geometry.helpers.geometry_helper import GeometryHelper
|
||||
|
||||
|
||||
|
@ -25,7 +27,19 @@ class Rhino:
|
|||
self._max_x = self._max_y = self._max_z = min_float
|
||||
|
||||
@staticmethod
|
||||
def _solid_points(coordinates):
|
||||
def _in_perimeter(wall, corner):
|
||||
res = wall.contains_point(Point(corner))
|
||||
print(f'belong: {res} wall:({wall.coordinates}) corner: ({corner})')
|
||||
return res
|
||||
|
||||
@staticmethod
|
||||
def _add_hole(solid_polygon, hole):
|
||||
first = solid_polygon.points[0]
|
||||
points = first + hole.points + solid_polygon.points
|
||||
return Polygon(points)
|
||||
|
||||
@staticmethod
|
||||
def _solid_points(coordinates) -> np.ndarray:
|
||||
solid_points = np.fromstring(coordinates, dtype=float, sep=' ')
|
||||
solid_points = GeometryHelper.to_points_matrix(solid_points)
|
||||
return solid_points
|
||||
|
@ -82,6 +96,7 @@ class Rhino:
|
|||
windows.append(Polygon(surface.perimeter_polygon.inverse))
|
||||
else:
|
||||
buildings.append(rhino_object)
|
||||
print(f'windows: {len(windows)}')
|
||||
# todo: this method will be pretty inefficient
|
||||
for hole in windows:
|
||||
corner = hole.coordinates[0]
|
||||
|
|
|
@ -8,7 +8,6 @@ import xmltodict
|
|||
from pathlib import Path
|
||||
from city_model_structure.machine import Machine
|
||||
|
||||
|
||||
class LcaMachine:
|
||||
def __init__(self, city, base_path):
|
||||
self._city = city
|
||||
|
@ -17,15 +16,12 @@ class LcaMachine:
|
|||
|
||||
def enrich(self):
|
||||
self._city.machines = []
|
||||
# print(self._base_path)
|
||||
path = Path(self._base_path / 'lca_data.xml').resolve()
|
||||
|
||||
with open(path) as xml:
|
||||
self._lca = xmltodict.parse(xml.read())
|
||||
for machine in self._lca["library"]["machines"]['machine']:
|
||||
self._city.machines.append(Machine(machine['@id'], machine['@name'], machine['work_efficiency']['#text'],
|
||||
machine['work_efficiency']['@unit'],
|
||||
machine['energy_consumption_rate']['#text'],
|
||||
machine['energy_consumption_rate']['@unit'],
|
||||
machine['carbon_emission_factor']['#text'],
|
||||
machine['carbon_emission_factor']['@unit']))
|
||||
for machine in self._lca["library"]["machines"]['machine']:
|
||||
self._city.machines.append(Machine(machine['@id'], machine['@name'], machine['work_efficiency']['#text'],
|
||||
machine['work_efficiency']['@unit'], machine['energy_consumption_rate']['#text'],
|
||||
machine['energy_consumption_rate']['@unit'], machine['carbon_emission_factor']['#text'],
|
||||
machine['carbon_emission_factor']['@unit']))
|
||||
|
|
|
@ -7,8 +7,6 @@ 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):
|
||||
|
@ -17,25 +15,26 @@ class LcaMaterial:
|
|||
self._lca = None
|
||||
|
||||
def enrich(self):
|
||||
self._city.lca_materials = []
|
||||
self._city.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)
|
||||
_material = Material()
|
||||
_material.type = material['@type']
|
||||
_material.id = material['@id']
|
||||
_material.name = material['@name']
|
||||
_material.density=material['density']['#text']
|
||||
_material.density_unit=material['density']['@unit']
|
||||
_material.embodied_carbon=material['embodied_carbon']['#text']
|
||||
_material.embodied_carbon_unit=material['embodied_carbon']['@unit']
|
||||
_material.recycling_ratio=material['recycling_ratio']
|
||||
_material.onsite_recycling_ratio=material['onsite_recycling_ratio']
|
||||
_material.company_recycling_ratio=material['company_recycling_ratio']
|
||||
_material.landfilling_ratio=material['landfilling_ratio']
|
||||
_material.cost=material['cost']['#text']
|
||||
_material._cost_unit=material['cost']['@unit']
|
||||
|
||||
self._city.materials.append(_material)
|
||||
|
|
|
@ -10,6 +10,8 @@ import parseidf
|
|||
import xmltodict
|
||||
from imports.schedules.helpers.schedules_helper import SchedulesHelper
|
||||
from city_model_structure.attributes.schedule import Schedule
|
||||
from city_model_structure.building_demand.occupancy import Occupancy
|
||||
from city_model_structure.building_demand.lighting import Lighting
|
||||
import helpers.constants as cte
|
||||
|
||||
|
||||
|
@ -51,15 +53,16 @@ class DoeIdf:
|
|||
self._schedule_library = xmltodict.parse(xml.read())
|
||||
|
||||
for building in self._city.buildings:
|
||||
for usage_zone in building.usage_zones:
|
||||
for schedule_archetype in self._schedule_library['archetypes']['archetypes']:
|
||||
function = schedule_archetype['@building_type']
|
||||
if SchedulesHelper.usage_from_function(function) == usage_zone.usage:
|
||||
self._idf_schedules_path = (base_path / schedule_archetype['idf']['path']).resolve()
|
||||
with open(self._idf_schedules_path, 'r') as file:
|
||||
idf = parseidf.parse(file.read())
|
||||
self._load_schedule(idf, usage_zone)
|
||||
break
|
||||
for internal_zone in building.internal_zones:
|
||||
for usage_zone in internal_zone.usage_zones:
|
||||
for schedule_archetype in self._schedule_library['archetypes']['archetypes']:
|
||||
function = schedule_archetype['@building_type']
|
||||
if SchedulesHelper.usage_from_function(function) == usage_zone.usage:
|
||||
self._idf_schedules_path = (base_path / schedule_archetype['idf']['path']).resolve()
|
||||
with open(self._idf_schedules_path, 'r') as file:
|
||||
idf = parseidf.parse(file.read())
|
||||
self._load_schedule(idf, usage_zone)
|
||||
break
|
||||
|
||||
def _load_schedule(self, idf, usage_zone):
|
||||
schedules_day = {}
|
||||
|
@ -129,4 +132,12 @@ class DoeIdf:
|
|||
continue
|
||||
schedules.append(schedule)
|
||||
|
||||
usage_zone.schedules = schedules
|
||||
for schedule in schedules:
|
||||
if schedule.type == cte.OCCUPANCY:
|
||||
if usage_zone.occupancy is None:
|
||||
usage_zone.occupancy = Occupancy()
|
||||
usage_zone.occupancy.occupancy_schedules = [schedule]
|
||||
elif schedule.type == cte.LIGHTING:
|
||||
if usage_zone.lighting is None:
|
||||
usage_zone.lighting = Lighting()
|
||||
usage_zone.lighting.schedules = [schedule]
|
||||
|
|
|
@ -12,43 +12,42 @@ class SchedulesHelper:
|
|||
"""
|
||||
Schedules helper
|
||||
"""
|
||||
usage_to_comnet = {
|
||||
_usage_to_comnet = {
|
||||
cte.RESIDENTIAL: 'C-12 Residential',
|
||||
cte.INDUSTRY: 'C-10 Warehouse',
|
||||
cte.OFFICE_ADMINISTRATION: 'C-5 Office',
|
||||
cte.OFFICE_AND_ADMINISTRATION: 'C-5 Office',
|
||||
cte.HOTEL: 'C-3 Hotel',
|
||||
cte.HEALTH_CARE: 'C-2 Health',
|
||||
cte.RETAIL: 'C-8 Retail',
|
||||
cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD: 'C-8 Retail',
|
||||
cte.HALL: 'C-8 Retail',
|
||||
cte.RESTAURANT: 'C-7 Restaurant',
|
||||
cte.EDUCATION: 'C-9 School'
|
||||
}
|
||||
comnet_default_value = 'C-12 Residential'
|
||||
|
||||
comnet_to_data_type = {
|
||||
_comnet_to_data_type = {
|
||||
'Fraction': cte.FRACTION,
|
||||
'OnOff': cte.ON_OFF,
|
||||
'Temperature': cte.TEMPERATURE
|
||||
}
|
||||
|
||||
# usage
|
||||
function_to_usage = {
|
||||
_function_to_usage = {
|
||||
'full service restaurant': cte.RESTAURANT,
|
||||
'high-rise apartment': cte.RESIDENTIAL,
|
||||
'hospital': cte.HEALTH_CARE,
|
||||
'large hotel': cte.HOTEL,
|
||||
'large office': cte.OFFICE_ADMINISTRATION,
|
||||
'medium office': cte.OFFICE_ADMINISTRATION,
|
||||
'large office': cte.OFFICE_AND_ADMINISTRATION,
|
||||
'medium office': cte.OFFICE_AND_ADMINISTRATION,
|
||||
'midrise apartment': cte.RESIDENTIAL,
|
||||
'outpatient healthcare': cte.HEALTH_CARE,
|
||||
'primary school': cte.EDUCATION,
|
||||
'quick service restaurant': cte.RESTAURANT,
|
||||
'secondary school': cte.EDUCATION,
|
||||
'small hotel': cte.HOTEL,
|
||||
'small office': cte.OFFICE_ADMINISTRATION,
|
||||
'stand-alone-retail': cte.RETAIL,
|
||||
'small office': cte.OFFICE_AND_ADMINISTRATION,
|
||||
'stand-alone-retail': cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
|
||||
'strip mall': cte.HALL,
|
||||
'supermarket': cte.RETAIL,
|
||||
'supermarket': cte.RETAIL_SHOP_WITH_REFRIGERATED_FOOD,
|
||||
'warehouse': cte.INDUSTRY,
|
||||
'residential': cte.RESIDENTIAL
|
||||
}
|
||||
|
@ -61,10 +60,9 @@ class SchedulesHelper:
|
|||
:return: str
|
||||
"""
|
||||
try:
|
||||
return SchedulesHelper.usage_to_comnet[usage]
|
||||
return SchedulesHelper._usage_to_comnet[usage]
|
||||
except KeyError:
|
||||
sys.stderr.write('Error: keyword not found. Returned default Comnet schedules "residential"\n')
|
||||
return SchedulesHelper.comnet_default_value
|
||||
sys.stderr.write('Error: keyword not found.\n')
|
||||
|
||||
@staticmethod
|
||||
def data_type_from_comnet(comnet_data_type):
|
||||
|
@ -74,7 +72,7 @@ class SchedulesHelper:
|
|||
:return: str
|
||||
"""
|
||||
try:
|
||||
return SchedulesHelper.comnet_to_data_type[comnet_data_type]
|
||||
return SchedulesHelper._comnet_to_data_type[comnet_data_type]
|
||||
except KeyError:
|
||||
raise ValueError(f"Error: comnet data type keyword not found.")
|
||||
|
||||
|
@ -85,4 +83,4 @@ class SchedulesHelper:
|
|||
:param building_function: str
|
||||
:return: str
|
||||
"""
|
||||
return SchedulesHelper.function_to_usage[building_function]
|
||||
return SchedulesHelper._function_to_usage[building_function]
|
||||
|
|
|
@ -6,7 +6,6 @@ Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@conc
|
|||
"""
|
||||
|
||||
from pathlib import Path
|
||||
from imports.schedules.comnet_schedules_parameters import ComnetSchedules
|
||||
from imports.schedules.doe_idf import DoeIdf
|
||||
|
||||
|
||||
|
@ -19,15 +18,11 @@ class SchedulesFactory:
|
|||
self._city = city
|
||||
self._base_path = base_path
|
||||
for building in city.buildings:
|
||||
if len(building.usage_zones) == 0:
|
||||
raise Exception('It seems that the schedule factory is being called before the usage factory. '
|
||||
'Please ensure that the usage factory is called first.')
|
||||
|
||||
def _comnet(self):
|
||||
"""
|
||||
Enrich the city by using COMNET schedules as data source
|
||||
"""
|
||||
ComnetSchedules(self._city, self._base_path)
|
||||
for internal_zone in building.internal_zones:
|
||||
if len(internal_zone.usage_zones) == 0:
|
||||
raise Exception('It seems that the schedule factory is being called before the usage factory. '
|
||||
'Please ensure that the usage factory is called first as the usage zones must be '
|
||||
'firstly generated.')
|
||||
|
||||
def _doe_idf(self):
|
||||
"""
|
||||
|
|
|
@ -5,6 +5,7 @@ Copyright © 2021 Project Author Guille Gutierrez guillermo.gutierrezmorote@conc
|
|||
"""
|
||||
import pandas as pd
|
||||
from imports.sensors.concordia_file_report import ConcordiaFileReport
|
||||
from city_model_structure.iot.concordia_energy_sensor import ConcordiaEnergySensor
|
||||
|
||||
|
||||
class ConcordiaEnergyConsumption(ConcordiaFileReport):
|
||||
|
|
|
@ -5,7 +5,7 @@ Copyright © 2021 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.mons
|
|||
"""
|
||||
import pandas as pd
|
||||
from imports.sensors.concordia_file_report import ConcordiaFileReport
|
||||
|
||||
from city_model_structure.iot.concordia_gas_flow_sensor import ConcordiaGasFlowSensor
|
||||
|
||||
|
||||
class ConcordiaGasFlow(ConcordiaFileReport):
|
||||
|
@ -24,7 +24,6 @@ class ConcordiaGasFlow(ConcordiaFileReport):
|
|||
building_measures = [self._measures["Date time"], self._measures[self._sensor_point[self._sensors[i]]]]
|
||||
building_headers = ["Date time", "Gas Flow Cumulative Monthly"]
|
||||
building_energy_consumption = pd.concat(building_measures, keys=building_headers, axis=1)
|
||||
"""
|
||||
sensor = ConcordiaGasFlowSensor(self._sensors[i])
|
||||
sensor_exist = False
|
||||
for j in range(len(obj.sensors)):
|
||||
|
@ -35,4 +34,3 @@ class ConcordiaGasFlow(ConcordiaFileReport):
|
|||
if not sensor_exist:
|
||||
sensor.add_period(building_energy_consumption)
|
||||
obj.sensors.append(sensor)
|
||||
"""
|
|
@ -5,6 +5,7 @@ Copyright © 2021 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.mons
|
|||
"""
|
||||
import pandas as pd
|
||||
from imports.sensors.concordia_file_report import ConcordiaFileReport
|
||||
from city_model_structure.iot.concordia_temperature_sensor import ConcordiaTemperatureSensor
|
||||
|
||||
|
||||
class ConcordiaTemperature(ConcordiaFileReport):
|
||||
|
@ -22,7 +23,6 @@ class ConcordiaTemperature(ConcordiaFileReport):
|
|||
building_measures = [self._measures["Date time"], self._measures[self._sensor_point[self._sensors[i]]]]
|
||||
building_headers = ["Date time", "Temperature"]
|
||||
building_energy_consumption = pd.concat(building_measures, keys=building_headers, axis=1)
|
||||
"""
|
||||
sensor = ConcordiaTemperatureSensor(self._sensors[i])
|
||||
sensor_exist = False
|
||||
for j in range(len(obj.sensors)):
|
||||
|
@ -33,4 +33,3 @@ class ConcordiaTemperature(ConcordiaFileReport):
|
|||
if not sensor_exist:
|
||||
sensor.add_period(building_energy_consumption)
|
||||
obj.sensors.append(sensor)
|
||||
"""
|
|
@ -5,10 +5,14 @@ Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.mons
|
|||
"""
|
||||
import sys
|
||||
|
||||
from imports.geometry.helpers.geometry_helper import GeometryHelper as gh
|
||||
from imports.geometry.helpers.geometry_helper import GeometryHelper
|
||||
from imports.usage.hft_usage_interface import HftUsageInterface
|
||||
from imports.usage.helpers.usage_helper import UsageHelper
|
||||
from city_model_structure.building_demand.usage_zone import UsageZone
|
||||
from city_model_structure.building_demand.internal_gains import InternalGains
|
||||
from city_model_structure.building_demand.occupancy import Occupancy
|
||||
from city_model_structure.building_demand.appliances import Appliances
|
||||
from city_model_structure.building_demand.thermal_control import ThermalControl
|
||||
|
||||
|
||||
class CaUsageParameters(HftUsageInterface):
|
||||
|
@ -18,9 +22,6 @@ class CaUsageParameters(HftUsageInterface):
|
|||
def __init__(self, city, base_path):
|
||||
super().__init__(base_path, 'ca_archetypes_reduced.xml')
|
||||
self._city = city
|
||||
# todo: this is a wrong location for self._min_air_change -> re-think where to place this info
|
||||
# and where it comes from
|
||||
self._min_air_change = 0
|
||||
|
||||
def enrich_buildings(self):
|
||||
"""
|
||||
|
@ -29,50 +30,53 @@ class CaUsageParameters(HftUsageInterface):
|
|||
"""
|
||||
city = self._city
|
||||
for building in city.buildings:
|
||||
archetype = self._search_archetype(building.function)
|
||||
if archetype is None:
|
||||
usage = GeometryHelper().libs_usage_from_libs_function(building.function)
|
||||
try:
|
||||
archetype = self._search_archetype(usage)
|
||||
except KeyError:
|
||||
sys.stderr.write(f'Building {building.name} has unknown archetype for building function:'
|
||||
f' {building.function}, that assigns building usage as '
|
||||
f'{gh.usage_from_function(building.function)}\n')
|
||||
continue
|
||||
# todo: what to do with mix-usage usage from gml?
|
||||
mix_usage = False
|
||||
if not mix_usage:
|
||||
# just one usage_zone
|
||||
for thermal_zone in building.thermal_zones:
|
||||
usage_zone = UsageZone()
|
||||
self._assign_values(usage_zone, archetype)
|
||||
usage_zone.volume = thermal_zone.volume
|
||||
thermal_zone.usage_zones = [usage_zone]
|
||||
f' {building.function}\n')
|
||||
return
|
||||
|
||||
def _search_archetype(self, building_usage):
|
||||
for internal_zone in building.internal_zones:
|
||||
usage_zone = UsageZone()
|
||||
usage_zone.usage = building.function
|
||||
usage_zone.percentage = 1
|
||||
self._assign_values_usage_zone(usage_zone, archetype)
|
||||
internal_zone.usage_zones = [usage_zone]
|
||||
|
||||
def _search_archetype(self, libs_usage):
|
||||
building_usage = UsageHelper().hft_from_libs_usage(libs_usage)
|
||||
for building_archetype in self._usage_archetypes:
|
||||
if building_archetype.usage == building_usage:
|
||||
return building_archetype
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def _assign_values(usage_zone, archetype):
|
||||
usage_zone.usage = archetype.usage
|
||||
def _assign_values_usage_zone(usage_zone, archetype):
|
||||
# Due to the fact that python is not a typed language, the wrong object type is assigned to
|
||||
# usage_zone.internal_gains when writing usage_zone.internal_gains = archetype.internal_gains.
|
||||
# Therefore, this walk around has been done.
|
||||
internal_gains = []
|
||||
for archetype_internal_gain in archetype.internal_gains:
|
||||
internal_gain = InternalGains()
|
||||
internal_gain.average_internal_gain = archetype_internal_gain.average_internal_gain
|
||||
internal_gain.convective_fraction = archetype_internal_gain.convective_fraction
|
||||
internal_gain.radiative_fraction = archetype_internal_gain.radiative_fraction
|
||||
internal_gain.latent_fraction = archetype_internal_gain.latent_fraction
|
||||
internal_gains.append(internal_gain)
|
||||
usage_zone.internal_gains = internal_gains
|
||||
usage_zone.heating_setpoint = archetype.heating_setpoint
|
||||
usage_zone.heating_setback = archetype.heating_setback
|
||||
usage_zone.cooling_setpoint = archetype.cooling_setpoint
|
||||
usage_zone.occupancy_density = archetype.occupancy_density
|
||||
usage_zone.mechanical_air_change = archetype.mechanical_air_change
|
||||
_occupancy = Occupancy()
|
||||
_occupancy.occupancy_density = archetype.occupancy.occupancy_density
|
||||
usage_zone.occupancy = _occupancy
|
||||
usage_zone.hours_day = archetype.hours_day
|
||||
usage_zone.days_year = archetype.days_year
|
||||
usage_zone.dhw_average_volume_pers_day = archetype.dhw_average_volume_pers_day
|
||||
usage_zone.dhw_preparation_temperature = archetype.dhw_preparation_temperature
|
||||
usage_zone.electrical_app_average_consumption_sqm_year = archetype.electrical_app_average_consumption_sqm_year
|
||||
usage_zone.mechanical_air_change = archetype.mechanical_air_change
|
||||
_appliances = Appliances()
|
||||
_appliances.appliances_density = archetype.appliances.appliances_density
|
||||
usage_zone.appliances = _appliances
|
||||
_control = ThermalControl()
|
||||
_control.mean_heating_set_point = archetype.thermal_control.mean_heating_set_point
|
||||
_control.heating_set_back = archetype.thermal_control.heating_set_back
|
||||
_control.mean_cooling_set_point = archetype.thermal_control.mean_cooling_set_point
|
||||
usage_zone.thermal_control = _control
|
||||
_internal_gains = []
|
||||
for archetype_internal_gain in archetype.not_detailed_source_mean_annual_internal_gains:
|
||||
_internal_gain = InternalGains()
|
||||
_internal_gain.average_internal_gain = archetype_internal_gain.average_internal_gain
|
||||
_internal_gain.convective_fraction = archetype_internal_gain.convective_fraction
|
||||
_internal_gain.radiative_fraction = archetype_internal_gain.radiative_fraction
|
||||
_internal_gain.latent_fraction = archetype_internal_gain.latent_fraction
|
||||
_internal_gains.append(_internal_gain)
|
||||
usage_zone.not_detailed_source_mean_annual_internal_gains = _internal_gains
|
||||
|
|
|
@ -3,6 +3,7 @@ ComnetUsageParameters model the usage properties
|
|||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2021 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
|
||||
import sys
|
||||
from typing import Dict
|
||||
import pandas as pd
|
||||
|
@ -11,10 +12,13 @@ import helpers.constants as cte
|
|||
from helpers.configuration_helper import ConfigurationHelper as ch
|
||||
from imports.geometry.helpers.geometry_helper import GeometryHelper
|
||||
from imports.usage.helpers.usage_helper import UsageHelper
|
||||
from imports.schedules.helpers.schedules_helper import SchedulesHelper
|
||||
from city_model_structure.building_demand.usage_zone import UsageZone
|
||||
from city_model_structure.building_demand.internal_gains import InternalGains
|
||||
from imports.usage.data_classes.hft_usage_zone_archetype import HftUsageZoneArchetype as huza
|
||||
from imports.usage.data_classes.hft_internal_gains_archetype import HftInternalGainsArchetype as higa
|
||||
from city_model_structure.building_demand.lighting import Lighting
|
||||
from city_model_structure.building_demand.occupancy import Occupancy
|
||||
from city_model_structure.building_demand.appliances import Appliances
|
||||
from city_model_structure.building_demand.thermal_control import ThermalControl
|
||||
from city_model_structure.attributes.schedule import Schedule
|
||||
|
||||
|
||||
class ComnetUsageParameters:
|
||||
|
@ -24,24 +28,19 @@ class ComnetUsageParameters:
|
|||
def __init__(self, city, base_path):
|
||||
self._city = city
|
||||
self._base_path = str(base_path / 'comnet_archetypes.xlsx')
|
||||
self._usage_archetypes = []
|
||||
data = self._read_file()
|
||||
for item in data['lighting']:
|
||||
for usage in UsageHelper.usage_to_comnet:
|
||||
comnet_usage = UsageHelper.usage_to_comnet[usage]
|
||||
if comnet_usage == item:
|
||||
usage_archetype = self._parse_zone_usage_type(comnet_usage, data)
|
||||
self._usage_archetypes.append(usage_archetype)
|
||||
self._data = self._read_file()
|
||||
self._comnet_schedules_path = str(base_path / 'comnet_schedules_archetypes.xlsx')
|
||||
self._xls = pd.ExcelFile(self._comnet_schedules_path)
|
||||
|
||||
def _read_file(self) -> Dict:
|
||||
"""
|
||||
reads xlsx file containing usage information into a dictionary
|
||||
reads xlsx files containing usage information into a dictionary
|
||||
:return : Dict
|
||||
"""
|
||||
number_usage_types = 33
|
||||
xl_file = pd.ExcelFile(self._base_path)
|
||||
file_data = pd.read_excel(xl_file, sheet_name="Modeling Data", skiprows=[0, 1, 2],
|
||||
nrows=number_usage_types, usecols="A:Z")
|
||||
nrows=number_usage_types, usecols="A:AB")
|
||||
|
||||
lighting_data = {}
|
||||
plug_loads_data = {}
|
||||
|
@ -49,6 +48,7 @@ class ComnetUsageParameters:
|
|||
ventilation_rate = {}
|
||||
water_heating = {}
|
||||
process_data = {}
|
||||
schedules_key = {}
|
||||
|
||||
for j in range(0, number_usage_types):
|
||||
usage_parameters = file_data.iloc[j]
|
||||
|
@ -59,54 +59,129 @@ class ComnetUsageParameters:
|
|||
ventilation_rate[usage_type] = usage_parameters[20:21].values.tolist()
|
||||
water_heating[usage_type] = usage_parameters[23:24].values.tolist()
|
||||
process_data[usage_type] = usage_parameters[24:26].values.tolist()
|
||||
schedules_key[usage_type] = usage_parameters[27:28].values.tolist()
|
||||
|
||||
return {'lighting': lighting_data,
|
||||
'plug loads': plug_loads_data,
|
||||
'occupancy': occupancy_data,
|
||||
'ventilation rate': ventilation_rate,
|
||||
'water heating': water_heating,
|
||||
'process': process_data}
|
||||
'process': process_data,
|
||||
'schedules_key': schedules_key}
|
||||
|
||||
@staticmethod
|
||||
def _parse_zone_usage_type(usage, data):
|
||||
if data['occupancy'][usage][0] <= 0:
|
||||
occupancy_density = 0
|
||||
else:
|
||||
occupancy_density = 1 / data['occupancy'][usage][0]
|
||||
mechanical_air_change = data['ventilation rate'][usage][0]
|
||||
internal_gains = []
|
||||
# lighting
|
||||
latent_fraction = ch().comnet_lighting_latent
|
||||
convective_fraction = ch().comnet_lighting_convective
|
||||
radiative_fraction = ch().comnet_lighting_radiant
|
||||
average_internal_gain = data['lighting'][usage][4]
|
||||
internal_gains.append(higa(internal_gains_type=cte.LIGHTING, average_internal_gain=average_internal_gain,
|
||||
convective_fraction=convective_fraction, radiative_fraction=radiative_fraction,
|
||||
latent_fraction=latent_fraction))
|
||||
# occupancy
|
||||
latent_fraction = data['occupancy'][usage][2] / (data['occupancy'][usage][1] + data['occupancy'][usage][2])
|
||||
sensible_fraction = float(1 - latent_fraction)
|
||||
convective_fraction = sensible_fraction * ch().comnet_occupancy_sensible_convective
|
||||
radiative_fraction = sensible_fraction * ch().comnet_occupancy_sensible_radiant
|
||||
average_internal_gain = (data['occupancy'][usage][1] + data['occupancy'][usage][2]) \
|
||||
* occupancy_density * cte.BTU_H_TO_WATTS
|
||||
internal_gains.append(higa(internal_gains_type=cte.OCCUPANCY, average_internal_gain=average_internal_gain,
|
||||
convective_fraction=convective_fraction, radiative_fraction=radiative_fraction,
|
||||
latent_fraction=latent_fraction))
|
||||
# plug loads
|
||||
if data['plug loads'][usage][0] != 'n.a.':
|
||||
latent_fraction = ch().comnet_plugs_latent
|
||||
convective_fraction = ch().comnet_plugs_convective
|
||||
radiative_fraction = ch().comnet_plugs_radiant
|
||||
average_internal_gain = data['plug loads'][usage][0]
|
||||
internal_gains.append(higa(internal_gains_type=cte.RECEPTACLE, average_internal_gain=average_internal_gain,
|
||||
convective_fraction=convective_fraction, radiative_fraction=radiative_fraction,
|
||||
latent_fraction=latent_fraction))
|
||||
def _parse_usage_type(comnet_usage, data, schedules_data):
|
||||
_usage_zone = UsageZone()
|
||||
|
||||
usage_zone_archetype = huza(usage=usage, internal_gains=internal_gains,
|
||||
occupancy_density=occupancy_density,
|
||||
mechanical_air_change=mechanical_air_change)
|
||||
return usage_zone_archetype
|
||||
# lighting
|
||||
_lighting = Lighting()
|
||||
_lighting.latent_fraction = ch().comnet_lighting_latent
|
||||
_lighting.convective_fraction = ch().comnet_lighting_convective
|
||||
_lighting.radiative_fraction = ch().comnet_lighting_radiant
|
||||
_lighting.lighting_density = data['lighting'][comnet_usage][4]
|
||||
|
||||
# plug loads
|
||||
_appliances = None
|
||||
if data['plug loads'][comnet_usage][0] != 'n.a.':
|
||||
_appliances = Appliances()
|
||||
_appliances.latent_fraction = ch().comnet_plugs_latent
|
||||
_appliances.convective_fraction = ch().comnet_plugs_convective
|
||||
_appliances.radiative_fraction = ch().comnet_plugs_radiant
|
||||
_appliances.appliances_density = data['plug loads'][comnet_usage][0]
|
||||
|
||||
# occupancy
|
||||
_occupancy = Occupancy()
|
||||
_occupancy.occupancy_density = data['occupancy'][comnet_usage][0]
|
||||
_occupancy.sensible_convective_internal_gain = data['occupancy'][comnet_usage][1] \
|
||||
* ch().comnet_occupancy_sensible_convective
|
||||
_occupancy.sensible_radiative_internal_gain = data['occupancy'][comnet_usage][1] \
|
||||
* ch().comnet_occupancy_sensible_radiant
|
||||
_occupancy.latent_internal_gain = data['occupancy'][comnet_usage][2]
|
||||
|
||||
if _occupancy.occupancy_density <= 0:
|
||||
_usage_zone.mechanical_air_change = 0
|
||||
else:
|
||||
_usage_zone.mechanical_air_change = data['ventilation rate'][comnet_usage][0] / _occupancy.occupancy_density
|
||||
|
||||
schedules_usage = UsageHelper.schedules_key(data['schedules_key'][comnet_usage][0])
|
||||
|
||||
_extracted_data = pd.read_excel(schedules_data, sheet_name=schedules_usage,
|
||||
skiprows=[0, 1, 2, 3], nrows=39, usecols="A:AA")
|
||||
schedules = []
|
||||
number_of_schedule_types = 13
|
||||
schedules_per_schedule_type = 3
|
||||
day_types = dict({'week_day': 0, 'saturday': 1, 'sunday': 2})
|
||||
for schedule_types in range(0, number_of_schedule_types):
|
||||
name = ''
|
||||
data_type = ''
|
||||
for schedule_day in range(0, schedules_per_schedule_type):
|
||||
_schedule = Schedule()
|
||||
_schedule.time_step = cte.HOUR
|
||||
_schedule.time_range = cte.DAY
|
||||
row_cells = _extracted_data.iloc[schedules_per_schedule_type * schedule_types + schedule_day]
|
||||
if schedule_day == day_types['week_day']:
|
||||
name = row_cells[0]
|
||||
data_type = row_cells[1]
|
||||
_schedule.day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY]
|
||||
elif schedule_day == day_types['saturday']:
|
||||
_schedule.day_types = [cte.SATURDAY]
|
||||
else:
|
||||
_schedule.day_types = [cte.SUNDAY]
|
||||
_schedule.type = name
|
||||
_schedule.data_type = SchedulesHelper.data_type_from_comnet(data_type)
|
||||
if _schedule.data_type == cte.TEMPERATURE:
|
||||
values = []
|
||||
for cell in row_cells[schedules_per_schedule_type:].to_numpy():
|
||||
values.append((float(cell) - 32.) * 5 / 9)
|
||||
_schedule.values = values
|
||||
else:
|
||||
_schedule.values = row_cells[schedules_per_schedule_type:].to_numpy()
|
||||
schedules.append(_schedule)
|
||||
|
||||
schedules_types = dict({'Occupancy': 0, 'Lights': 3, 'Receptacle': 6, 'Infiltration': 9, 'HVAC Avail': 12,
|
||||
'ClgSetPt': 15, 'HtgSetPt': 18})
|
||||
|
||||
_schedules = []
|
||||
for pointer in range(0, 3):
|
||||
_schedules.append(schedules[schedules_types['Occupancy']+pointer])
|
||||
_occupancy.occupancy_schedules = _schedules
|
||||
_schedules = []
|
||||
for pointer in range(0, 3):
|
||||
_schedules.append(schedules[schedules_types['Lights']+pointer])
|
||||
_lighting.schedules = _schedules
|
||||
_schedules = []
|
||||
for pointer in range(0, 3):
|
||||
_schedules.append(schedules[schedules_types['Receptacle']+pointer])
|
||||
_appliances.schedules = _schedules
|
||||
|
||||
_usage_zone.occupancy = _occupancy
|
||||
_usage_zone.lighting = _lighting
|
||||
_usage_zone.appliances = _appliances
|
||||
|
||||
_control = ThermalControl()
|
||||
_schedules = []
|
||||
for pointer in range(0, 3):
|
||||
_schedules.append(schedules[schedules_types['HtgSetPt']+pointer])
|
||||
_control.heating_set_point_schedules = _schedules
|
||||
_schedules = []
|
||||
for pointer in range(0, 3):
|
||||
_schedules.append(schedules[schedules_types['ClgSetPt']+pointer])
|
||||
_control.cooling_set_point_schedules = _schedules
|
||||
_schedules = []
|
||||
for pointer in range(0, 3):
|
||||
_schedules.append(schedules[schedules_types['HVAC Avail']+pointer])
|
||||
_control.hvac_availability_schedules = _schedules
|
||||
_usage_zone.thermal_control = _control
|
||||
|
||||
return _usage_zone
|
||||
|
||||
def _search_archetypes(self, libs_usage):
|
||||
for item in self._data['lighting']:
|
||||
comnet_usage = UsageHelper.comnet_from_libs_usage(libs_usage)
|
||||
if comnet_usage == item:
|
||||
usage_archetype = self._parse_usage_type(comnet_usage, self._data, self._xls)
|
||||
return usage_archetype
|
||||
return None
|
||||
|
||||
def enrich_buildings(self):
|
||||
"""
|
||||
|
@ -115,48 +190,81 @@ class ComnetUsageParameters:
|
|||
"""
|
||||
city = self._city
|
||||
for building in city.buildings:
|
||||
usage = GeometryHelper.usage_from_function(building.function)
|
||||
height = building.average_storey_height
|
||||
if height is None:
|
||||
raise Exception('Average storey height not defined, ACH cannot be calculated')
|
||||
if height <= 0:
|
||||
raise Exception('Average storey height is zero, ACH cannot be calculated')
|
||||
archetype = self._search_archetype(UsageHelper.comnet_from_usage(usage))
|
||||
if archetype is None:
|
||||
usage = GeometryHelper.libs_usage_from_libs_function(building.function)
|
||||
try:
|
||||
archetype_usage = self._search_archetypes(usage)
|
||||
except KeyError:
|
||||
sys.stderr.write(f'Building {building.name} has unknown archetype for building function:'
|
||||
f' {building.function}, that assigns building usage as '
|
||||
f'{GeometryHelper.usage_from_function(building.function)}\n')
|
||||
continue
|
||||
f'{GeometryHelper.libs_usage_from_libs_function(building.function)}\n')
|
||||
return
|
||||
|
||||
# just one usage_zone
|
||||
for thermal_zone in building.thermal_zones:
|
||||
for internal_zone in building.internal_zones:
|
||||
if internal_zone.area is None:
|
||||
raise Exception('Internal zone area not defined, ACH cannot be calculated')
|
||||
if internal_zone.volume is None:
|
||||
raise Exception('Internal zone volume not defined, ACH cannot be calculated')
|
||||
if internal_zone.area <= 0:
|
||||
raise Exception('Internal zone area is zero, ACH cannot be calculated')
|
||||
if internal_zone.volume <= 0:
|
||||
raise Exception('Internal zone volume is zero, ACH cannot be calculated')
|
||||
volume_per_area = internal_zone.volume / internal_zone.area
|
||||
usage_zone = UsageZone()
|
||||
usage_zone.usage = usage
|
||||
self._assign_values(usage_zone, archetype, height)
|
||||
usage_zone.volume = thermal_zone.volume
|
||||
thermal_zone.usage_zones = [usage_zone]
|
||||
self._assign_values_usage_zone(usage_zone, archetype_usage, volume_per_area)
|
||||
usage_zone.percentage = 1
|
||||
self._calculate_reduced_values_from_extended_library(usage_zone, archetype_usage)
|
||||
|
||||
def _search_archetype(self, building_usage):
|
||||
for building_archetype in self._usage_archetypes:
|
||||
if building_archetype.usage == building_usage:
|
||||
return building_archetype
|
||||
return None
|
||||
internal_zone.usage_zones = [usage_zone]
|
||||
|
||||
@staticmethod
|
||||
def _assign_values(usage_zone, archetype, height):
|
||||
def _assign_values_usage_zone(usage_zone, archetype, volume_per_area):
|
||||
# Due to the fact that python is not a typed language, the wrong object type is assigned to
|
||||
# usage_zone.internal_gains when writing usage_zone.internal_gains = archetype.internal_gains.
|
||||
# Therefore, this walk around has been done.
|
||||
internal_gains = []
|
||||
for archetype_internal_gain in archetype.internal_gains:
|
||||
internal_gain = InternalGains()
|
||||
internal_gain.type = archetype_internal_gain.type
|
||||
internal_gain.average_internal_gain = archetype_internal_gain.average_internal_gain * cte.METERS_TO_FEET**2
|
||||
internal_gain.convective_fraction = archetype_internal_gain.convective_fraction
|
||||
internal_gain.radiative_fraction = archetype_internal_gain.radiative_fraction
|
||||
internal_gain.latent_fraction = archetype_internal_gain.latent_fraction
|
||||
internal_gains.append(internal_gain)
|
||||
usage_zone.internal_gains = internal_gains
|
||||
usage_zone.occupancy_density = archetype.occupancy_density * cte.METERS_TO_FEET**2
|
||||
usage_zone.mechanical_air_change = archetype.mechanical_air_change * usage_zone.occupancy_density \
|
||||
* cte.HOUR_TO_MINUTES / cte.METERS_TO_FEET**3 / height
|
||||
# usage_zone.occupancy when writing usage_zone.occupancy = archetype.occupancy.
|
||||
# Same happens for lighting and appliances. Therefore, this walk around has been done.
|
||||
usage_zone.mechanical_air_change = archetype.mechanical_air_change * cte.METERS_TO_FEET ** 2 \
|
||||
* cte.HOUR_TO_MINUTES / cte.METERS_TO_FEET ** 3 / volume_per_area
|
||||
_occupancy = Occupancy()
|
||||
_occupancy.occupancy_density = archetype.occupancy.occupancy_density * cte.METERS_TO_FEET**2
|
||||
_occupancy.sensible_radiative_internal_gain = archetype.occupancy.sensible_radiative_internal_gain
|
||||
_occupancy.latent_internal_gain = archetype.occupancy.latent_internal_gain
|
||||
_occupancy.sensible_convective_internal_gain = archetype.occupancy.sensible_convective_internal_gain
|
||||
_occupancy.occupancy_schedules = archetype.occupancy.occupancy_schedules
|
||||
usage_zone.occupancy = _occupancy
|
||||
_lighting = Lighting()
|
||||
_lighting.lighting_density = archetype.lighting.lighting_density / cte.METERS_TO_FEET**2
|
||||
_lighting.convective_fraction = archetype.lighting.convective_fraction
|
||||
_lighting.radiative_fraction = archetype.lighting.radiative_fraction
|
||||
_lighting.latent_fraction = archetype.lighting.latent_fraction
|
||||
_lighting.schedules = archetype.lighting.schedules
|
||||
usage_zone.lighting = _lighting
|
||||
_appliances = Appliances()
|
||||
_appliances.appliances_density = archetype.appliances.appliances_density / cte.METERS_TO_FEET**2
|
||||
_appliances.convective_fraction = archetype.appliances.convective_fraction
|
||||
_appliances.radiative_fraction = archetype.appliances.radiative_fraction
|
||||
_appliances.latent_fraction = archetype.appliances.latent_fraction
|
||||
_appliances.schedules = archetype.appliances.schedules
|
||||
usage_zone.appliances = _appliances
|
||||
_control = ThermalControl()
|
||||
_control.cooling_set_point_schedules = archetype.thermal_control.cooling_set_point_schedules
|
||||
_control.heating_set_point_schedules = archetype.thermal_control.heating_set_point_schedules
|
||||
_control.hvac_availability_schedules = archetype.thermal_control.hvac_availability_schedules
|
||||
usage_zone.thermal_control = _control
|
||||
|
||||
@staticmethod
|
||||
def _calculate_reduced_values_from_extended_library(usage_zone, archetype):
|
||||
number_of_days_per_type = {'WD': 251, 'Sat': 52, 'Sun': 62}
|
||||
total = 0
|
||||
for schedule in archetype.thermal_control.hvac_availability_schedules:
|
||||
if schedule.day_types[0] == cte.SATURDAY:
|
||||
for value in schedule.values:
|
||||
total += value * number_of_days_per_type['Sat']
|
||||
elif schedule.day_types[0] == cte.SUNDAY:
|
||||
for value in schedule.values:
|
||||
total += value * number_of_days_per_type['Sun']
|
||||
else:
|
||||
for value in schedule.values:
|
||||
total += value * number_of_days_per_type['WD']
|
||||
|
||||
usage_zone.hours_day = total / 365
|
||||
usage_zone.days_year = 365
|
||||
|
|
|
@ -1,144 +0,0 @@
|
|||
"""
|
||||
HftUsageZoneArchetype stores usage information by building archetypes
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
from typing import List
|
||||
from imports.usage.data_classes.hft_internal_gains_archetype import HftInternalGainsArchetype
|
||||
|
||||
|
||||
class HftUsageZoneArchetype:
|
||||
"""
|
||||
HftUsageZoneArchetype class
|
||||
"""
|
||||
def __init__(self, usage=None, internal_gains=None, heating_set_point=None, heating_set_back=None,
|
||||
cooling_set_point=None, occupancy_density=None, hours_day=None, days_year=None,
|
||||
dhw_average_volume_pers_day=None, dhw_preparation_temperature=None,
|
||||
electrical_app_average_consumption_sqm_year=None, mechanical_air_change=None,
|
||||
occupancy=None, schedules=None):
|
||||
self._usage = usage
|
||||
self._internal_gains = internal_gains
|
||||
self._heating_setpoint = heating_set_point
|
||||
self._heating_setback = heating_set_back
|
||||
self._cooling_setpoint = cooling_set_point
|
||||
self._occupancy_density = occupancy_density
|
||||
self._hours_day = hours_day
|
||||
self._days_year = days_year
|
||||
self._dhw_average_volume_pers_day = dhw_average_volume_pers_day
|
||||
self._dhw_preparation_temperature = dhw_preparation_temperature
|
||||
self._electrical_app_average_consumption_sqm_year = electrical_app_average_consumption_sqm_year
|
||||
self._mechanical_air_change = mechanical_air_change
|
||||
self._occupancy = occupancy
|
||||
self._schedules = schedules
|
||||
|
||||
@property
|
||||
def internal_gains(self) -> List[HftInternalGainsArchetype]:
|
||||
"""
|
||||
Get usage zone internal gains
|
||||
:return: [InternalGains]
|
||||
"""
|
||||
return self._internal_gains
|
||||
|
||||
@property
|
||||
def heating_setpoint(self):
|
||||
"""
|
||||
Get usage zone heating set point in celsius grads
|
||||
:return: float
|
||||
"""
|
||||
return self._heating_setpoint
|
||||
|
||||
@property
|
||||
def heating_setback(self):
|
||||
"""
|
||||
Get usage zone heating setback in celsius grads
|
||||
:return: float
|
||||
"""
|
||||
return self._heating_setback
|
||||
|
||||
@property
|
||||
def cooling_setpoint(self):
|
||||
"""
|
||||
Get usage zone cooling setpoint in celsius grads
|
||||
:return: float
|
||||
"""
|
||||
return self._cooling_setpoint
|
||||
|
||||
@property
|
||||
def hours_day(self):
|
||||
"""
|
||||
Get usage zone usage hours per day
|
||||
:return: float
|
||||
"""
|
||||
return self._hours_day
|
||||
|
||||
@property
|
||||
def days_year(self):
|
||||
"""
|
||||
Get usage zone usage days per year
|
||||
:return: float
|
||||
"""
|
||||
return self._days_year
|
||||
|
||||
@property
|
||||
def mechanical_air_change(self):
|
||||
"""
|
||||
Set usage zone mechanical air change in air change per hour (ACH)
|
||||
:return: float
|
||||
"""
|
||||
return self._mechanical_air_change
|
||||
|
||||
@property
|
||||
def usage(self):
|
||||
"""
|
||||
Get usage zone usage
|
||||
:return: str
|
||||
"""
|
||||
return self._usage
|
||||
|
||||
@property
|
||||
def occupancy(self):
|
||||
"""
|
||||
Get schedules data
|
||||
:return: [Occupancy]
|
||||
"""
|
||||
return self._occupancy
|
||||
|
||||
@property
|
||||
def schedules(self):
|
||||
"""
|
||||
Get schedules
|
||||
:return: [Schedule_Values]
|
||||
"""
|
||||
return self._schedules
|
||||
|
||||
@property
|
||||
def occupancy_density(self):
|
||||
"""
|
||||
Get schedules density in persons per m2
|
||||
:return: float
|
||||
"""
|
||||
return self._occupancy_density
|
||||
|
||||
@property
|
||||
def dhw_average_volume_pers_day(self):
|
||||
"""
|
||||
Get average DHW consumption in m3 per person per day
|
||||
:return: float
|
||||
"""
|
||||
return self._dhw_average_volume_pers_day
|
||||
|
||||
@property
|
||||
def dhw_preparation_temperature(self):
|
||||
"""
|
||||
Get preparation temperature of the DHW in degree Celsius
|
||||
:return: float
|
||||
"""
|
||||
return self._dhw_preparation_temperature
|
||||
|
||||
@property
|
||||
def electrical_app_average_consumption_sqm_year(self):
|
||||
"""
|
||||
Get average consumption of electrical appliances in Joules per m2 and year (J/m2yr)
|
||||
:return: float
|
||||
"""
|
||||
return self._electrical_app_average_consumption_sqm_year
|
98
imports/usage/data_classes/usage_zone_archetype.py
Normal file
98
imports/usage/data_classes/usage_zone_archetype.py
Normal file
|
@ -0,0 +1,98 @@
|
|||
"""
|
||||
UsageZoneArchetype stores usage information by usage type
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
|
||||
from typing import List
|
||||
from imports.usage.data_classes.hft_internal_gains_archetype import HftInternalGainsArchetype
|
||||
|
||||
|
||||
class UsageZoneArchetype:
|
||||
"""
|
||||
UsageZoneArchetype class
|
||||
"""
|
||||
def __init__(self, usage=None, not_detailed_source_mean_annual_internal_gains=None, hours_day=None, days_year=None,
|
||||
electrical_app_average_consumption_sqm_year=None, mechanical_air_change=None, occupancy=None,
|
||||
lighting=None, appliances=None):
|
||||
self._usage = usage
|
||||
self._not_detailed_source_mean_annual_internal_gains = not_detailed_source_mean_annual_internal_gains
|
||||
self._hours_day = hours_day
|
||||
self._days_year = days_year
|
||||
self._electrical_app_average_consumption_sqm_year = electrical_app_average_consumption_sqm_year
|
||||
self._mechanical_air_change = mechanical_air_change
|
||||
self._occupancy = occupancy
|
||||
self._lighting = lighting
|
||||
self._appliances = appliances
|
||||
|
||||
@property
|
||||
def not_detailed_source_mean_annual_internal_gains(self) -> List[HftInternalGainsArchetype]:
|
||||
"""
|
||||
Get usage zone internal gains from not detailed heating source in W/m2
|
||||
:return: [InternalGains]
|
||||
"""
|
||||
return self._not_detailed_source_mean_annual_internal_gains
|
||||
|
||||
@property
|
||||
def hours_day(self):
|
||||
"""
|
||||
Get usage zone usage hours per day
|
||||
:return: float
|
||||
"""
|
||||
return self._hours_day
|
||||
|
||||
@property
|
||||
def days_year(self):
|
||||
"""
|
||||
Get usage zone usage days per year
|
||||
:return: float
|
||||
"""
|
||||
return self._days_year
|
||||
|
||||
@property
|
||||
def mechanical_air_change(self):
|
||||
"""
|
||||
Set usage zone mechanical air change in air change per hour (ACH)
|
||||
:return: float
|
||||
"""
|
||||
return self._mechanical_air_change
|
||||
|
||||
@property
|
||||
def usage(self):
|
||||
"""
|
||||
Get usage zone usage
|
||||
:return: str
|
||||
"""
|
||||
return self._usage
|
||||
|
||||
@property
|
||||
def electrical_app_average_consumption_sqm_year(self):
|
||||
"""
|
||||
Get average consumption of electrical appliances in Joules per m2 and year (J/m2yr)
|
||||
:return: float
|
||||
"""
|
||||
return self._electrical_app_average_consumption_sqm_year
|
||||
|
||||
@property
|
||||
def occupancy(self):
|
||||
"""
|
||||
Get occupancy data
|
||||
:return: Occupancy
|
||||
"""
|
||||
return self._occupancy
|
||||
|
||||
@property
|
||||
def lighting(self):
|
||||
"""
|
||||
Get lighting data
|
||||
:return: Lighting
|
||||
"""
|
||||
return self._lighting
|
||||
|
||||
@property
|
||||
def appliances(self):
|
||||
"""
|
||||
Get appliances data
|
||||
:return: Appliances
|
||||
"""
|
||||
return self._appliances
|
|
@ -11,54 +11,104 @@ class UsageHelper:
|
|||
"""
|
||||
Usage helper class
|
||||
"""
|
||||
usage_to_hft = {
|
||||
_usage_to_hft = {
|
||||
cte.RESIDENTIAL: 'residential',
|
||||
cte.INDUSTRY: 'industry',
|
||||
cte.OFFICE_ADMINISTRATION: 'office and administration',
|
||||
cte.SINGLE_FAMILY_HOUSE: 'Single family house',
|
||||
cte.MULTI_FAMILY_HOUSE: 'Multi-family house',
|
||||
cte.EDUCATION: 'education',
|
||||
cte.SCHOOL_WITHOUT_SHOWER: 'school without shower',
|
||||
cte.SCHOOL_WITH_SHOWER: 'school with shower',
|
||||
cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD: 'retail',
|
||||
cte.RETAIL_SHOP_WITH_REFRIGERATED_FOOD: 'retail shop / refrigerated food',
|
||||
cte.HOTEL: 'hotel',
|
||||
cte.HEALTH_CARE: 'health care',
|
||||
cte.RETAIL: 'retail',
|
||||
cte.HALL: 'hall',
|
||||
cte.HOTEL_MEDIUM_CLASS: 'hotel (Medium-class)',
|
||||
cte.DORMITORY: 'dormitory',
|
||||
cte.INDUSTRY: 'industry',
|
||||
cte.RESTAURANT: 'restaurant',
|
||||
cte.EDUCATION: 'education'
|
||||
}
|
||||
hft_default_value = 'residential'
|
||||
cte.HEALTH_CARE: 'health care',
|
||||
cte.RETIREMENT_HOME_OR_ORPHANAGE: 'Home for the aged or orphanage',
|
||||
cte.OFFICE_AND_ADMINISTRATION: 'office and administration',
|
||||
cte.EVENT_LOCATION: 'event location',
|
||||
cte.HALL: 'hall',
|
||||
cte.SPORTS_LOCATION: 'sport location',
|
||||
cte.LABOR: 'Labor',
|
||||
cte.GREEN_HOUSE: 'green house',
|
||||
cte.NON_HEATED: 'non-heated'}
|
||||
|
||||
@staticmethod
|
||||
def hft_from_usage(usage):
|
||||
def hft_from_libs_usage(usage):
|
||||
"""
|
||||
Get HfT usage from the given internal usage key
|
||||
:param usage: str
|
||||
:return: str
|
||||
"""
|
||||
try:
|
||||
return UsageHelper.usage_to_hft[usage]
|
||||
return UsageHelper._usage_to_hft[usage]
|
||||
except KeyError:
|
||||
sys.stderr.write('Error: keyword not found. Returned default HfT usage "residential"\n')
|
||||
return UsageHelper.hft_default_value
|
||||
sys.stderr.write('Error: keyword not found to translate from libs_usage to hft usage.\n')
|
||||
|
||||
usage_to_comnet = {
|
||||
_usage_to_comnet = {
|
||||
cte.RESIDENTIAL: 'BA Multifamily',
|
||||
cte.INDUSTRY: 'BA Manufacturing Facility',
|
||||
cte.OFFICE_ADMINISTRATION: 'BA Office',
|
||||
cte.SINGLE_FAMILY_HOUSE: 'BA Multifamily',
|
||||
cte.MULTI_FAMILY_HOUSE: 'BA Multifamily',
|
||||
cte.EDUCATION: 'BA School/University',
|
||||
cte.SCHOOL_WITHOUT_SHOWER: 'BA School/University',
|
||||
cte.SCHOOL_WITH_SHOWER: 'BA School/University',
|
||||
cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD: 'BA Retail',
|
||||
cte.RETAIL_SHOP_WITH_REFRIGERATED_FOOD: 'BA Retail',
|
||||
cte.HOTEL: 'BA Hotel',
|
||||
cte.HOTEL_MEDIUM_CLASS: 'BA Hotel',
|
||||
cte.DORMITORY: 'BA Dormitory',
|
||||
cte.INDUSTRY: 'BA Manufacturing Facility',
|
||||
cte.RESTAURANT: 'BA Dining: Family',
|
||||
cte.HEALTH_CARE: 'BA Hospital',
|
||||
cte.RETAIL: 'BA Retail',
|
||||
cte.HALL: 'BA Town Hall',
|
||||
cte.RESTAURANT: 'BA Dining: Bar Lounge/Leisure',
|
||||
cte.EDUCATION: 'BA School/University'
|
||||
cte.RETIREMENT_HOME_OR_ORPHANAGE: 'BA Multifamily',
|
||||
cte.OFFICE_AND_ADMINISTRATION: 'BA Office',
|
||||
cte.EVENT_LOCATION: 'BA Convention Center',
|
||||
cte.HALL: 'BA Convention Center',
|
||||
cte.SPORTS_LOCATION: 'BA Sports Arena',
|
||||
cte.LABOR: 'BA Gymnasium',
|
||||
cte.GREEN_HOUSE: cte.GREEN_HOUSE,
|
||||
cte.NON_HEATED: cte.NON_HEATED
|
||||
}
|
||||
comnet_default_value = 'BA Multifamily'
|
||||
|
||||
_comnet_schedules_key_to_comnet_schedules = {
|
||||
'C-1 Assembly': 'C-1 Assembly',
|
||||
'C-2 Public': 'C-2 Health',
|
||||
'C-3 Hotel Motel': 'C-3 Hotel',
|
||||
'C-4 Manufacturing': 'C-4 Manufacturing',
|
||||
'C-5 Office': 'C-5 Office',
|
||||
'C-6 Parking Garage': 'C-6 Parking',
|
||||
'C-7 Restaurant': 'C-7 Restaurant',
|
||||
'C-8 Retail': 'C-8 Retail',
|
||||
'C-9 Schools': 'C-9 School',
|
||||
'C-10 Warehouse': 'C-10 Warehouse',
|
||||
'C-11 Laboratory': 'C-11 Lab',
|
||||
'C-12 Residential': 'C-12 Residential',
|
||||
'C-13 Data Center': 'C-13 Data',
|
||||
'C-14 Gymnasium': 'C-14 Gymnasium'}
|
||||
|
||||
@staticmethod
|
||||
def comnet_from_usage(usage):
|
||||
def comnet_from_libs_usage(usage):
|
||||
"""
|
||||
Get Comnet usage from the given internal usage key
|
||||
:param usage: str
|
||||
:return: str
|
||||
"""
|
||||
try:
|
||||
return UsageHelper.usage_to_comnet[usage]
|
||||
return UsageHelper._usage_to_comnet[usage]
|
||||
except KeyError:
|
||||
sys.stderr.write('Error: keyword not found. Returned default Comnet usage "BA Multifamily"\n')
|
||||
return UsageHelper.comnet_default_value
|
||||
sys.stderr.write('Error: keyword not found to translate from libs_usage to comnet usage.\n')
|
||||
|
||||
@staticmethod
|
||||
def schedules_key(usage):
|
||||
"""
|
||||
Get Comnet schedules key from the list found in the Comnet usage file
|
||||
:param usage: str
|
||||
:return: str
|
||||
"""
|
||||
try:
|
||||
return UsageHelper._comnet_schedules_key_to_comnet_schedules[usage]
|
||||
except KeyError:
|
||||
sys.stderr.write('Error: Comnet keyword not found. An update of the Comnet files might have been '
|
||||
'done changing the keywords.\n')
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
"""
|
||||
Hft-based interface, it reads format defined within the CERC team based on that one used in SimStadt and developed by
|
||||
the IAF team at hft-Stuttgart and enriches the city with usage parameters
|
||||
Hft-based interface, it reads format defined within the CERC team (based on that one used in SimStadt and developed by
|
||||
the IAF team at hft-Stuttgart)
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
Copyright © 2022 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
import xmltodict
|
||||
from imports.usage.data_classes.hft_usage_zone_archetype import HftUsageZoneArchetype as huza
|
||||
from imports.usage.data_classes.hft_internal_gains_archetype import HftInternalGainsArchetype as higa
|
||||
import copy
|
||||
from city_model_structure.building_demand.usage_zone import UsageZone
|
||||
from city_model_structure.building_demand.internal_gains import InternalGains
|
||||
from city_model_structure.building_demand.occupancy import Occupancy
|
||||
from city_model_structure.building_demand.appliances import Appliances
|
||||
from city_model_structure.building_demand.thermal_control import ThermalControl
|
||||
from city_model_structure.attributes.schedule import Schedule
|
||||
import helpers.constants as cte
|
||||
|
||||
|
||||
class HftUsageInterface:
|
||||
|
@ -31,113 +37,191 @@ class HftUsageInterface:
|
|||
|
||||
@staticmethod
|
||||
def _parse_zone_usage_type(usage, zone_usage_type):
|
||||
occupancy_density = zone_usage_type['occupancy']['occupancyDensity']
|
||||
hours_day = zone_usage_type['occupancy']['usageHoursPerDay']
|
||||
days_year = zone_usage_type['occupancy']['usageDaysPerYear']
|
||||
cooling_setpoint = zone_usage_type['endUses']['space_cooling']['coolingSetPointTemperature']
|
||||
heating_setpoint = zone_usage_type['endUses']['space_heating']['heatingSetPointTemperature']
|
||||
heating_setback = zone_usage_type['endUses']['space_heating']['heatingSetBackTemperature']
|
||||
mechanical_air_change = None
|
||||
if 'ventilation' in zone_usage_type['endUses'] and zone_usage_type['endUses']['ventilation'] is not None:
|
||||
mechanical_air_change = zone_usage_type['endUses']['ventilation']['mechanicalAirChangeRate']
|
||||
dhw_average_volume_pers_day = None
|
||||
dhw_preparation_temperature = None
|
||||
if 'domestic_hot_water' in zone_usage_type['endUses']:
|
||||
# liters to cubic meters
|
||||
dhw_average_volume_pers_day = float(
|
||||
zone_usage_type['endUses']['domestic_hot_water']['averageVolumePerPersAndDay']) / 1000
|
||||
dhw_preparation_temperature = zone_usage_type['endUses']['domestic_hot_water']['preparationTemperature']
|
||||
electrical_app_average_consumption_sqm_year = None
|
||||
if 'all_electrical_appliances' in zone_usage_type['endUses']:
|
||||
if 'averageConsumptionPerSqmAndYear' in zone_usage_type['endUses']['all_electrical_appliances']:
|
||||
# kWh to J
|
||||
electrical_app_average_consumption_sqm_year = \
|
||||
float(zone_usage_type['endUses']['all_electrical_appliances']['averageConsumptionPerSqmAndYear']) / 3.6
|
||||
usage_zone_archetype = UsageZone()
|
||||
usage_zone_archetype.usage = usage
|
||||
|
||||
# todo: for internal_gain in usage_zone_variant['schedules']['internGains']:????????????????
|
||||
# There are no more internal gains? How is it saved when more than one???
|
||||
internal_gains = []
|
||||
if 'internGains' in zone_usage_type['occupancy']:
|
||||
latent_fraction = zone_usage_type['occupancy']['internGains']['latentFraction']
|
||||
convective_fraction = zone_usage_type['occupancy']['internGains']['convectiveFraction']
|
||||
average_internal_gain = zone_usage_type['occupancy']['internGains']['averageInternGainPerSqm']
|
||||
radiative_fraction = zone_usage_type['occupancy']['internGains']['radiantFraction']
|
||||
else:
|
||||
latent_fraction = 0
|
||||
convective_fraction = 0
|
||||
average_internal_gain = 0
|
||||
radiative_fraction = 0
|
||||
if 'occupancy' in zone_usage_type:
|
||||
_occupancy = Occupancy()
|
||||
_occupancy.occupancy_density = zone_usage_type['occupancy']['occupancyDensity'] #todo: check units
|
||||
usage_zone_archetype.hours_day = zone_usage_type['occupancy']['usageHoursPerDay']
|
||||
usage_zone_archetype.days_year = zone_usage_type['occupancy']['usageDaysPerYear']
|
||||
usage_zone_archetype.occupancy = _occupancy
|
||||
|
||||
if 'internGains' in zone_usage_type['occupancy']:
|
||||
_internal_gain = InternalGains()
|
||||
_internal_gain.latent_fraction = zone_usage_type['occupancy']['internGains']['latentFraction']
|
||||
_internal_gain.convective_fraction = zone_usage_type['occupancy']['internGains']['convectiveFraction']
|
||||
_internal_gain.average_internal_gain = zone_usage_type['occupancy']['internGains']['averageInternGainPerSqm']
|
||||
_internal_gain.radiative_fraction = zone_usage_type['occupancy']['internGains']['radiantFraction']
|
||||
if 'load' in zone_usage_type['occupancy']['internGains']:
|
||||
_schedule = Schedule()
|
||||
_schedule.type = 'internal gains load'
|
||||
_schedule.time_range = cte.DAY
|
||||
_schedule.time_step = cte.HOUR
|
||||
_schedule.data_type = cte.ANY_NUMBER
|
||||
_schedule.day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY]
|
||||
_values = zone_usage_type['occupancy']['internGains']['load']['weekDayProfile']['values']
|
||||
while ' ' in _values:
|
||||
_values = _values.replace(' ', ' ')
|
||||
_schedule.values = _values.split()
|
||||
_internal_gain.schedules = [_schedule]
|
||||
|
||||
usage_zone_archetype.not_detailed_source_mean_annual_internal_gains = [_internal_gain]
|
||||
|
||||
if 'endUses' in zone_usage_type:
|
||||
_thermal_control = ThermalControl()
|
||||
if 'space_heating' in zone_usage_type['endUses']:
|
||||
_thermal_control.mean_heating_set_point = \
|
||||
zone_usage_type['endUses']['space_heating']['heatingSetPointTemperature']
|
||||
_thermal_control.heating_set_back = zone_usage_type['endUses']['space_heating']['heatingSetBackTemperature']
|
||||
if 'schedule' in zone_usage_type['endUses']['space_heating']:
|
||||
_schedule = Schedule()
|
||||
_schedule.type = 'heating temperature'
|
||||
_schedule.time_range = cte.DAY
|
||||
_schedule.time_step = cte.HOUR
|
||||
_schedule.data_type = cte.TEMPERATURE
|
||||
_schedule.day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY]
|
||||
_values = zone_usage_type['endUses']['space_heating']['schedule']['weekDayProfile']['values']
|
||||
while ' ' in _values:
|
||||
_values = _values.replace(' ', ' ')
|
||||
_schedule.values = _values.split()
|
||||
_thermal_control.heating_set_point_schedules = [_schedule]
|
||||
|
||||
if 'space_cooling' in zone_usage_type['endUses']:
|
||||
_thermal_control.mean_cooling_set_point = \
|
||||
zone_usage_type['endUses']['space_cooling']['coolingSetPointTemperature']
|
||||
if 'schedule' in zone_usage_type['endUses']['space_cooling']:
|
||||
_schedule = Schedule()
|
||||
_schedule.type = 'cooling temperature'
|
||||
_schedule.time_range = cte.DAY
|
||||
_schedule.time_step = cte.HOUR
|
||||
_schedule.data_type = cte.TEMPERATURE
|
||||
_schedule.day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY]
|
||||
_values = zone_usage_type['endUses']['space_cooling']['schedule']['weekDayProfile']['values']
|
||||
while ' ' in _values:
|
||||
_values = _values.replace(' ', ' ')
|
||||
_schedule.values = _values.split()
|
||||
_thermal_control.cooling_set_point_schedules = [_schedule]
|
||||
|
||||
usage_zone_archetype.thermal_control = _thermal_control
|
||||
|
||||
if 'ventilation' in zone_usage_type['endUses'] and zone_usage_type['endUses']['ventilation'] is not None:
|
||||
usage_zone_archetype.mechanical_air_change = \
|
||||
zone_usage_type['endUses']['ventilation']['mechanicalAirChangeRate']
|
||||
|
||||
# todo: not used or assigned anywhere
|
||||
if 'domestic_hot_water' in zone_usage_type['endUses']:
|
||||
# liters to cubic meters
|
||||
dhw_average_volume_pers_day = float(
|
||||
zone_usage_type['endUses']['domestic_hot_water']['averageVolumePerPersAndDay']) / 1000
|
||||
dhw_preparation_temperature = zone_usage_type['endUses']['domestic_hot_water']['preparationTemperature']
|
||||
|
||||
if 'all_electrical_appliances' in zone_usage_type['endUses']:
|
||||
if 'averageConsumptionPerSqmAndYear' in zone_usage_type['endUses']['all_electrical_appliances']:
|
||||
# kWh to J
|
||||
usage_zone_archetype.electrical_app_average_consumption_sqm_year = \
|
||||
float(zone_usage_type['endUses']['all_electrical_appliances']['averageConsumptionPerSqmAndYear']) \
|
||||
* cte.KILO_WATTS_HOUR_TO_JULES
|
||||
|
||||
if 'appliance' in zone_usage_type:
|
||||
_appliances = Appliances()
|
||||
_appliances.appliances_density = zone_usage_type['appliance']['#text'] #todo: check units
|
||||
|
||||
usage_zone_archetype.appliances = _appliances
|
||||
|
||||
internal_gains.append(higa(average_internal_gain=average_internal_gain, convective_fraction=convective_fraction,
|
||||
radiative_fraction=radiative_fraction, latent_fraction=latent_fraction))
|
||||
usage_zone_archetype = huza(usage=usage, internal_gains=internal_gains, heating_set_point=heating_setpoint,
|
||||
heating_set_back=heating_setback, cooling_set_point=cooling_setpoint,
|
||||
occupancy_density=occupancy_density, hours_day=hours_day, days_year=days_year,
|
||||
dhw_average_volume_pers_day=dhw_average_volume_pers_day,
|
||||
dhw_preparation_temperature=dhw_preparation_temperature,
|
||||
electrical_app_average_consumption_sqm_year=electrical_app_average_consumption_sqm_year,
|
||||
mechanical_air_change=mechanical_air_change)
|
||||
return usage_zone_archetype
|
||||
|
||||
@staticmethod
|
||||
def _parse_zone_usage_variant(usage, usage_zone, usage_zone_variant):
|
||||
# for the variants all is optional because it mimics the inheritance concept from OOP
|
||||
occupancy_density = usage_zone.occupancy_density
|
||||
hours_day = usage_zone.hours_day
|
||||
days_year = usage_zone.days_year
|
||||
cooling_setpoint = usage_zone.cooling_setpoint
|
||||
heating_setpoint = usage_zone.heating_setpoint
|
||||
heating_setback = usage_zone.heating_setback
|
||||
mechanical_air_change = usage_zone.mechanical_air_change
|
||||
dhw_average_volume_pers_day = usage_zone.dhw_average_volume_pers_day
|
||||
dhw_preparation_temperature = usage_zone.dhw_preparation_temperature
|
||||
electrical_app_average_consumption_sqm_year = usage_zone.electrical_app_average_consumption_sqm_year
|
||||
# the variants mimic the inheritance concept from OOP
|
||||
usage_zone_archetype = copy.deepcopy(usage_zone)
|
||||
usage_zone_archetype.usage = usage
|
||||
|
||||
# todo: for internal_gain in usage_zone_variant['schedules']['internGains']:????????????????
|
||||
# There are no more internal gains? How is it saved when more than one???
|
||||
# for internal_gain in usage_zone.internal_gains:
|
||||
internal_gains = usage_zone.internal_gains[0]
|
||||
latent_fraction = internal_gains.latent_fraction
|
||||
convective_fraction = internal_gains.convective_fraction
|
||||
average_internal_gain = internal_gains.average_internal_gain
|
||||
radiative_fraction = internal_gains.radiative_fraction
|
||||
if 'occupancy' in usage_zone_variant:
|
||||
_occupancy = Occupancy()
|
||||
if 'occupancyDensity' in usage_zone_variant['occupancy']:
|
||||
_occupancy.occupancy_density = usage_zone_variant['occupancy']['occupancyDensity'] # todo: check units
|
||||
if 'usageHoursPerDay' in usage_zone_variant['occupancy']:
|
||||
usage_zone_archetype.hours_day = usage_zone_variant['occupancy']['usageHoursPerDay']
|
||||
if 'usageDaysPerYear' in usage_zone_variant['occupancy']:
|
||||
usage_zone_archetype.days_year = usage_zone_variant['occupancy']['usageDaysPerYear']
|
||||
usage_zone_archetype.occupancy = _occupancy
|
||||
|
||||
if 'internGains' in usage_zone_variant['occupancy']:
|
||||
_internal_gain = InternalGains()
|
||||
if 'latentFraction' in usage_zone_variant['occupancy']['internGains']:
|
||||
_internal_gain.latent_fraction = usage_zone_variant['occupancy']['internGains']['latentFraction']
|
||||
if 'convectiveFraction' in usage_zone_variant['occupancy']['internGains']:
|
||||
_internal_gain.convective_fraction = usage_zone_variant['occupancy']['internGains']['convectiveFraction']
|
||||
if 'averageInternGainPerSqm' in usage_zone_variant['occupancy']['internGains']:
|
||||
_internal_gain.average_internal_gain = \
|
||||
usage_zone_variant['occupancy']['internGains']['averageInternGainPerSqm']
|
||||
if 'radiantFraction' in usage_zone_variant['occupancy']['internGains']:
|
||||
_internal_gain.radiative_fraction = usage_zone_variant['occupancy']['internGains']['radiantFraction']
|
||||
if 'load' in usage_zone_variant['occupancy']['internGains']:
|
||||
_schedule = Schedule()
|
||||
_schedule.type = 'internal gains load'
|
||||
_schedule.time_range = cte.DAY
|
||||
_schedule.time_step = cte.HOUR
|
||||
_schedule.data_type = cte.ANY_NUMBER
|
||||
_schedule.day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY]
|
||||
_values = usage_zone_variant['occupancy']['internGains']['load']['weekDayProfile']['values']
|
||||
while ' ' in _values:
|
||||
_values = _values.replace(' ', ' ')
|
||||
_schedule.values = _values.split()
|
||||
_internal_gain.schedules = [_schedule]
|
||||
|
||||
usage_zone_archetype.not_detailed_source_mean_annual_internal_gains = [_internal_gain]
|
||||
|
||||
if 'endUses' in usage_zone_variant:
|
||||
_thermal_control = ThermalControl()
|
||||
if 'space_heating' in usage_zone_variant['endUses']:
|
||||
if 'heatingSetPointTemperature' in usage_zone_variant['endUses']['space_heating']:
|
||||
_thermal_control.mean_heating_set_point = \
|
||||
usage_zone_variant['endUses']['space_heating']['heatingSetPointTemperature']
|
||||
if 'heatingSetBackTemperature' in usage_zone_variant['endUses']['space_heating']:
|
||||
_thermal_control.heating_set_back = usage_zone_variant['endUses']['space_heating']['heatingSetBackTemperature']
|
||||
if 'schedule' in usage_zone_variant['endUses']['space_heating']:
|
||||
_schedule = Schedule()
|
||||
_schedule.type = 'heating temperature'
|
||||
_schedule.time_range = cte.DAY
|
||||
_schedule.time_step = cte.HOUR
|
||||
_schedule.data_type = cte.TEMPERATURE
|
||||
_schedule.day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY]
|
||||
_values = usage_zone_variant['endUses']['space_heating']['schedule']['weekDayProfile']['values']
|
||||
while ' ' in _values:
|
||||
_values = _values.replace(' ', ' ')
|
||||
_schedule.values = _values.split()
|
||||
_thermal_control.heating_set_point_schedules = [_schedule]
|
||||
|
||||
if 'space_cooling' in usage_zone_variant['endUses'] and \
|
||||
usage_zone_variant['endUses']['space_cooling'] is not None:
|
||||
if 'coolingSetPointTemperature' in usage_zone_variant['endUses']['space_cooling']:
|
||||
_thermal_control.mean_cooling_set_point = \
|
||||
usage_zone_variant['endUses']['space_cooling']['coolingSetPointTemperature']
|
||||
if 'schedule' in usage_zone_variant['endUses']['space_cooling']:
|
||||
_schedule = Schedule()
|
||||
_schedule.type = 'cooling temperature'
|
||||
_schedule.time_range = cte.DAY
|
||||
_schedule.time_step = cte.HOUR
|
||||
_schedule.data_type = cte.TEMPERATURE
|
||||
_schedule.day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY]
|
||||
_values = usage_zone_variant['endUses']['space_cooling']['schedule']['weekDayProfile']['values']
|
||||
while ' ' in _values:
|
||||
_values = _values.replace(' ', ' ')
|
||||
_schedule.values = _values.split()
|
||||
_thermal_control.cooling_set_point_schedules = [_schedule]
|
||||
|
||||
usage_zone_archetype.thermal_control = _thermal_control
|
||||
|
||||
if 'ventilation' in usage_zone_variant['endUses'] and usage_zone_variant['endUses']['ventilation'] is not None:
|
||||
usage_zone_archetype.mechanical_air_change = \
|
||||
usage_zone_variant['endUses']['ventilation']['mechanicalAirChangeRate']
|
||||
|
||||
if 'appliance' in usage_zone_variant:
|
||||
_appliances = Appliances()
|
||||
_appliances.appliances_density = usage_zone_variant['appliance']['#text'] # todo: check units
|
||||
|
||||
usage_zone_archetype.appliances = _appliances
|
||||
|
||||
if 'space_cooling' in usage_zone_variant['endUses'] and usage_zone_variant['endUses']['space_cooling'] is not None:
|
||||
if 'coolingSetPointTemperature' in usage_zone_variant['endUses']['space_cooling']:
|
||||
cooling_setpoint = usage_zone_variant['endUses']['space_cooling']['coolingSetPointTemperature']
|
||||
if 'space_heating' in usage_zone_variant['endUses'] and usage_zone_variant['endUses']['space_heating'] is not None:
|
||||
if 'heatingSetPointTemperature' in usage_zone_variant['endUses']['space_heating']:
|
||||
heating_setpoint = usage_zone_variant['endUses']['space_heating']['heatingSetPointTemperature']
|
||||
if 'heatingSetBackTemperature' in usage_zone_variant['endUses']['space_heating']:
|
||||
heating_setback = usage_zone_variant['endUses']['space_heating']['heatingSetBackTemperature']
|
||||
if 'ventilation' in usage_zone_variant['endUses'] and usage_zone_variant['endUses']['ventilation'] is not None:
|
||||
if 'mechanicalAirChangeRate' in usage_zone_variant['endUses']['ventilation']:
|
||||
mechanical_air_change = usage_zone_variant['endUses']['ventilation']['mechanicalAirChangeRate']
|
||||
# todo: for internal_gain in usage_zone_variant['schedules']['internGains']:????????????????
|
||||
# There are no more internal gains? How is it saved when more than one???
|
||||
if 'schedules' in usage_zone_variant:
|
||||
if 'usageHoursPerDay' in usage_zone_variant['schedules']:
|
||||
hours_day = usage_zone_variant['schedules']['usageHoursPerDay']
|
||||
if 'usageDaysPerYear' in usage_zone_variant['schedules']:
|
||||
days_year = usage_zone_variant['schedules']['usageDaysPerYear']
|
||||
if 'internalGains' in usage_zone_variant['schedules'] and usage_zone_variant['schedules'][
|
||||
'internGains'] is not None:
|
||||
internal_gains = []
|
||||
if 'latentFraction' in usage_zone_variant['schedules']['internGains']:
|
||||
latent_fraction = usage_zone_variant['schedules']['internGains']['latentFraction']
|
||||
if 'convectiveFraction' in usage_zone_variant['schedules']['internGains']:
|
||||
convective_fraction = usage_zone_variant['schedules']['internGains']['convectiveFraction']
|
||||
if 'averageInternGainPerSqm' in usage_zone_variant['schedules']['internGains']:
|
||||
average_internal_gain = usage_zone_variant['schedules']['internGains']['averageInternGainPerSqm']
|
||||
if 'radiantFraction' in usage_zone_variant['schedules']['internGains']:
|
||||
radiative_fraction = usage_zone_variant['schedules']['internGains']['radiantFraction']
|
||||
internal_gains.append(higa(average_internal_gain=average_internal_gain, convective_fraction=convective_fraction,
|
||||
radiative_fraction=radiative_fraction, latent_fraction=latent_fraction))
|
||||
usage_zone_archetype = huza(usage=usage, internal_gains=internal_gains, heating_set_point=heating_setpoint,
|
||||
heating_set_back=heating_setback, cooling_set_point=cooling_setpoint,
|
||||
occupancy_density=occupancy_density, hours_day=hours_day, days_year=days_year,
|
||||
dhw_average_volume_pers_day=dhw_average_volume_pers_day,
|
||||
dhw_preparation_temperature=dhw_preparation_temperature,
|
||||
electrical_app_average_consumption_sqm_year=electrical_app_average_consumption_sqm_year,
|
||||
mechanical_air_change=mechanical_air_change)
|
||||
return usage_zone_archetype
|
||||
|
|
|
@ -4,11 +4,12 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
|
|||
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
import sys
|
||||
import copy
|
||||
|
||||
from imports.geometry.helpers.geometry_helper import GeometryHelper as gh
|
||||
from imports.geometry.helpers.geometry_helper import GeometryHelper
|
||||
from imports.usage.hft_usage_interface import HftUsageInterface
|
||||
from imports.usage.helpers.usage_helper import UsageHelper
|
||||
from city_model_structure.building_demand.usage_zone import UsageZone
|
||||
from city_model_structure.building_demand.internal_gains import InternalGains
|
||||
|
||||
|
||||
class HftUsageParameters(HftUsageInterface):
|
||||
|
@ -18,9 +19,6 @@ class HftUsageParameters(HftUsageInterface):
|
|||
def __init__(self, city, base_path):
|
||||
super().__init__(base_path, 'de_library.xml')
|
||||
self._city = city
|
||||
# todo: this is a wrong location for self._min_air_change -> re-think where to place this info
|
||||
# and where it comes from
|
||||
self._min_air_change = 0
|
||||
|
||||
def enrich_buildings(self):
|
||||
"""
|
||||
|
@ -29,23 +27,25 @@ class HftUsageParameters(HftUsageInterface):
|
|||
"""
|
||||
city = self._city
|
||||
for building in city.buildings:
|
||||
archetype = self._search_archetype(gh.usage_from_function(building.function))
|
||||
if archetype is None:
|
||||
usage = GeometryHelper().libs_usage_from_libs_function(building.function)
|
||||
try:
|
||||
archetype = self._search_archetype(usage)
|
||||
except KeyError:
|
||||
sys.stderr.write(f'Building {building.name} has unknown archetype for building function:'
|
||||
f' {building.function}, that assigns building usage as '
|
||||
f'{gh.usage_from_function(building.function)}\n')
|
||||
continue
|
||||
# todo: what to do with mix-usage usage from gml?
|
||||
mix_usage = False
|
||||
if not mix_usage:
|
||||
# just one usage_zone
|
||||
for thermal_zone in building.thermal_zones:
|
||||
usage_zone = UsageZone()
|
||||
self._assign_values(usage_zone, archetype)
|
||||
usage_zone.volume = thermal_zone.volume
|
||||
thermal_zone.usage_zones = [usage_zone]
|
||||
f'{GeometryHelper().libs_usage_from_libs_function(building.function)}\n')
|
||||
return
|
||||
|
||||
def _search_archetype(self, building_usage):
|
||||
for internal_zone in building.internal_zones:
|
||||
usage_zone = UsageZone()
|
||||
libs_usage = GeometryHelper().libs_usage_from_libs_function(building.function)
|
||||
usage_zone.usage = UsageHelper().hft_from_libs_usage(libs_usage)
|
||||
self._assign_values(usage_zone, archetype)
|
||||
usage_zone.percentage = 1
|
||||
internal_zone.usage_zones = [usage_zone]
|
||||
|
||||
def _search_archetype(self, libs_usage):
|
||||
building_usage = UsageHelper().hft_from_libs_usage(libs_usage)
|
||||
for building_archetype in self._usage_archetypes:
|
||||
if building_archetype.usage == building_usage:
|
||||
return building_archetype
|
||||
|
@ -53,26 +53,42 @@ class HftUsageParameters(HftUsageInterface):
|
|||
|
||||
@staticmethod
|
||||
def _assign_values(usage_zone, archetype):
|
||||
usage_zone.usage = archetype.usage
|
||||
# Due to the fact that python is not a typed language, the wrong object type is assigned to
|
||||
""" # Due to the fact that python is not a typed language, the wrong object type is assigned to
|
||||
# usage_zone.internal_gains when writing usage_zone.internal_gains = archetype.internal_gains.
|
||||
# Therefore, this walk around has been done.
|
||||
internal_gains = []
|
||||
for archetype_internal_gain in archetype.internal_gains:
|
||||
internal_gain = InternalGains()
|
||||
internal_gain.average_internal_gain = archetype_internal_gain.average_internal_gain
|
||||
internal_gain.convective_fraction = archetype_internal_gain.convective_fraction
|
||||
internal_gain.radiative_fraction = archetype_internal_gain.radiative_fraction
|
||||
internal_gain.latent_fraction = archetype_internal_gain.latent_fraction
|
||||
internal_gains.append(internal_gain)
|
||||
usage_zone.internal_gains = internal_gains
|
||||
usage_zone.heating_setpoint = archetype.heating_setpoint
|
||||
usage_zone.heating_setback = archetype.heating_setback
|
||||
usage_zone.cooling_setpoint = archetype.cooling_setpoint
|
||||
usage_zone.occupancy_density = archetype.occupancy_density
|
||||
usage_zone.hours_day = archetype.hours_day
|
||||
usage_zone.days_year = archetype.days_year
|
||||
usage_zone.dhw_average_volume_pers_day = archetype.dhw_average_volume_pers_day
|
||||
usage_zone.dhw_preparation_temperature = archetype.dhw_preparation_temperature
|
||||
usage_zone.electrical_app_average_consumption_sqm_year = archetype.electrical_app_average_consumption_sqm_year
|
||||
# Due to the fact that python is not a typed language, the wrong object type is assigned to
|
||||
# usage_zone.occupancy when writing usage_zone.occupancy = archetype.occupancy.
|
||||
# Same happens for lighting and appliances. Therefore, this walk around has been done.
|
||||
usage_zone.mechanical_air_change = archetype.mechanical_air_change
|
||||
_occupancy = Occupancy()
|
||||
_occupancy.occupancy_density = archetype.occupancy.occupancy_density
|
||||
usage_zone.occupancy = _occupancy
|
||||
_appliances = Appliances()
|
||||
_appliances.appliances_density = archetype.appliances.appliances_density
|
||||
usage_zone.appliances = _appliances
|
||||
_control = ThermalControl()
|
||||
_control.mean_heating_set_point = archetype.thermal_control.mean_heating_set_point
|
||||
_control.heating_set_back = archetype.thermal_control.heating_set_back
|
||||
_control.mean_cooling_set_point = archetype.thermal_control.mean_cooling_set_point
|
||||
_control.cooling_set_point_schedules = archetype.thermal_control.cooling_set_point_schedules
|
||||
_control.heating_set_point_schedules = archetype.thermal_control.heating_set_point_schedules
|
||||
usage_zone.thermal_control = _control
|
||||
_internal_gains = []
|
||||
for archetype_internal_gain in archetype.not_detailed_source_mean_annual_internal_gains:
|
||||
_internal_gain = InternalGains()
|
||||
_internal_gain.average_internal_gain = archetype_internal_gain.average_internal_gain
|
||||
_internal_gain.convective_fraction = archetype_internal_gain.convective_fraction
|
||||
_internal_gain.radiative_fraction = archetype_internal_gain.radiative_fraction
|
||||
_internal_gain.latent_fraction = archetype_internal_gain.latent_fraction
|
||||
_internal_gain.schedules = archetype_internal_gain.schedules
|
||||
_internal_gains.append(_internal_gain)
|
||||
usage_zone.not_detailed_source_mean_annual_internal_gains = _internal_gains
|
||||
"""
|
||||
usage_zone.mechanical_air_change = archetype.mechanical_air_change
|
||||
usage_zone.occupancy = copy.deepcopy(archetype.occupancy)
|
||||
usage_zone.appliances = copy.deepcopy(archetype.appliances)
|
||||
usage_zone.thermal_control = copy.deepcopy(archetype.thermal_control)
|
||||
usage_zone.not_detailed_source_mean_annual_internal_gains = \
|
||||
copy.deepcopy(archetype.not_detailed_source_mean_annual_internal_gains)
|
||||
usage_zone.days_year = archetype.days_year
|
||||
usage_zone.hours_day = archetype.hours_day
|
||||
|
|
|
@ -22,10 +22,6 @@ class UsageFactory:
|
|||
self._handler = '_' + handler.lower().replace(' ', '_')
|
||||
self._city = city
|
||||
self._base_path = base_path
|
||||
for building in city.buildings:
|
||||
if len(building.thermal_zones) == 0:
|
||||
raise Exception('It seems that the usage factory is being called before the construction factory. '
|
||||
'Please ensure that the construction factory is called first.')
|
||||
|
||||
def _hft(self):
|
||||
"""
|
||||
|
|
64
recognized_functions_and_usages.md
Normal file
64
recognized_functions_and_usages.md
Normal file
|
@ -0,0 +1,64 @@
|
|||
# Functions and usages internally recognized within the libs
|
||||
|
||||
The libs uses a list of building functions a building usages that are the only ones recognized. All new categories should be added to the dicctionaries that translate from the input formats to the libs functions. From the libs functions to the libs usages and from the libs usages and libs functions to the output formats.
|
||||
|
||||
Input formats accepted:
|
||||
* Function:
|
||||
* pluto
|
||||
* hft
|
||||
|
||||
Output formats accepted:
|
||||
* Function:
|
||||
* nrel
|
||||
* nrcan
|
||||
* Usage:
|
||||
* ca
|
||||
* hft
|
||||
* comnet
|
||||
|
||||
Libs_functions:
|
||||
* single family house
|
||||
* multi family house
|
||||
* row hose
|
||||
* mid rise apartment
|
||||
* high rise apartment
|
||||
* residential
|
||||
* small office
|
||||
* medium office
|
||||
* large office
|
||||
* primary school
|
||||
* secondary school
|
||||
* stand alone retail
|
||||
* hospital
|
||||
* out-patient health care
|
||||
* strip mall
|
||||
* supermarket
|
||||
* ware house
|
||||
* quick service restaurant
|
||||
* full service restaurant
|
||||
* small hotel
|
||||
* large hotel
|
||||
|
||||
Libs_usage:
|
||||
* residential
|
||||
* single family house
|
||||
* multi family house
|
||||
* education
|
||||
* school without shower
|
||||
* school with shower
|
||||
* retail shop without refrigerated food
|
||||
* retail shop with refrigerated food
|
||||
* hotel
|
||||
* hotel medium class
|
||||
* dormitory
|
||||
* industry
|
||||
* restaurant
|
||||
* health care
|
||||
* retirement home or orphanage
|
||||
* office and administration
|
||||
* event location
|
||||
* hall
|
||||
* sports location
|
||||
* labor
|
||||
* green-house
|
||||
* non-heated
|
|
@ -13,7 +13,7 @@ openpyxl~=3.0.7
|
|||
networkx~=2.5.1
|
||||
parseidf~=1.0.0
|
||||
ply~=3.11
|
||||
rhino3dm~=7.11.1
|
||||
rhino3dm~=7.7.0
|
||||
scipy==1.7.1
|
||||
PyYAML==6.0
|
||||
yaml~=0.2.5
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
"""
|
||||
TestConstructionFactory test and validate the city model structure construction parameters
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
Copyright © 2022 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
from pathlib import Path
|
||||
from unittest import TestCase
|
||||
|
||||
import helpers.constants as cte
|
||||
from imports.geometry_factory import GeometryFactory
|
||||
from imports.construction_factory import ConstructionFactory
|
||||
from imports.geometry.helpers.geometry_helper import GeometryHelper
|
||||
from imports.life_cycle_assessment_factory import LifeCycleAssessment
|
||||
|
||||
|
||||
class TestConstructionFactory(TestCase):
|
||||
"""
|
||||
|
@ -23,46 +24,139 @@ class TestConstructionFactory(TestCase):
|
|||
self._city = None
|
||||
self._example_path = (Path(__file__).parent / 'tests_data').resolve()
|
||||
|
||||
def _get_citygml(self, file=None):
|
||||
if file is None:
|
||||
file = 'pluto_building.gml'
|
||||
def _get_citygml(self, file):
|
||||
file_path = (self._example_path / file).resolve()
|
||||
self._city = GeometryFactory('citygml', file_path).city
|
||||
LifeCycleAssessment('material', self._city).enrich()
|
||||
self.assertIsNotNone(self._city, 'city is none')
|
||||
return self._city
|
||||
|
||||
def test_city_with_construction_extended_library(self):
|
||||
"""
|
||||
Enrich the city with the physic information and verify it
|
||||
:return: None
|
||||
"""
|
||||
|
||||
city = self._get_citygml()
|
||||
def _check_buildings(self, city):
|
||||
for building in city.buildings:
|
||||
building.function = GeometryHelper.pluto_to_function[building.function]
|
||||
self.assertIsNotNone(building.surfaces, 'Building has no surfaces')
|
||||
self.assertIsNotNone(building.name, 'building name is none')
|
||||
self.assertIsNotNone(building.lod, 'building lod is none')
|
||||
self.assertIsNotNone(building.type, 'building type is none')
|
||||
self.assertIsNotNone(building.volume, 'building volume is none')
|
||||
self.assertIsNotNone(building.detailed_polyhedron, 'building detailed polyhedron is none')
|
||||
self.assertIsNotNone(building.simplified_polyhedron, 'building simplified polyhedron is none')
|
||||
self.assertIsNotNone(building.surfaces, 'building surfaces is none')
|
||||
self.assertIsNotNone(building.centroid, 'building centroid is none')
|
||||
self.assertIsNotNone(building.max_height, 'building max_height is none')
|
||||
self.assertEqual(len(building.external_temperature), 0, 'building external temperature is calculated')
|
||||
self.assertEqual(len(building.global_horizontal), 0, 'building global horizontal is calculated')
|
||||
self.assertEqual(len(building.diffuse), 0, 'building diffuse is calculated')
|
||||
self.assertEqual(len(building.beam), 0, 'building beam is calculated')
|
||||
self.assertIsNotNone(building.lower_corner, 'building lower corner is none')
|
||||
self.assertEqual(len(building.sensors), 0, 'building sensors are assigned')
|
||||
self.assertIsNotNone(building.internal_zones, 'no internal zones created')
|
||||
self.assertIsNotNone(building.grounds, 'building grounds is none')
|
||||
self.assertIsNotNone(building.walls, 'building walls is none')
|
||||
self.assertIsNotNone(building.roofs, 'building roofs is none')
|
||||
for internal_zone in building.internal_zones:
|
||||
self.assertIsNone(internal_zone.usage_zones, 'usage zones are defined')
|
||||
self.assertTrue(len(internal_zone.thermal_zones) > 0, 'thermal zones are not defined')
|
||||
self.assertIsNone(building.basement_heated, 'building basement_heated is not none')
|
||||
self.assertIsNone(building.attic_heated, 'building attic_heated is not none')
|
||||
self.assertIsNone(building.terrains, 'building terrains is not none')
|
||||
self.assertIsNotNone(building.year_of_construction, 'building year_of_construction is none')
|
||||
self.assertIsNotNone(building.function, 'building function is none')
|
||||
self.assertIsNotNone(building.average_storey_height, 'building average_storey_height is none')
|
||||
self.assertIsNotNone(building.storeys_above_ground, 'building storeys_above_ground is none')
|
||||
self.assertEqual(len(building.heating), 0, 'building heating is not none')
|
||||
self.assertEqual(len(building.cooling), 0, 'building cooling is not none')
|
||||
self.assertIsNotNone(building.eave_height, 'building eave height is none')
|
||||
self.assertIsNotNone(building.roof_type, 'building roof type is none')
|
||||
self.assertIsNotNone(building.floor_area, 'building floor_area is none')
|
||||
self.assertIsNone(building.households, 'building households is not none')
|
||||
self.assertFalse(building.is_conditioned, 'building is conditioned')
|
||||
|
||||
# case 1: NREL
|
||||
ConstructionFactory('nrel', city).enrich()
|
||||
def _check_thermal_zones(self, internal_zone):
|
||||
for thermal_zone in internal_zone.thermal_zones:
|
||||
self.assertIsNotNone(thermal_zone.id, 'thermal_zone id is none')
|
||||
self.assertIsNotNone(thermal_zone.floor_area, 'thermal_zone floor area is none')
|
||||
self.assertTrue(len(thermal_zone.thermal_boundaries) > 0, 'thermal_zone thermal_boundaries not defined')
|
||||
self.assertIsNotNone(thermal_zone.additional_thermal_bridge_u_value, 'additional_thermal_bridge_u_value is none')
|
||||
self.assertIsNotNone(thermal_zone.effective_thermal_capacity, 'thermal_zone effective_thermal_capacity is none')
|
||||
self.assertIsNotNone(thermal_zone.indirectly_heated_area_ratio,
|
||||
'thermal_zone indirectly_heated_area_ratio is none')
|
||||
self.assertIsNotNone(thermal_zone.infiltration_rate_system_off,
|
||||
'thermal_zone infiltration_rate_system_off is none')
|
||||
self.assertIsNotNone(thermal_zone.infiltration_rate_system_on, 'thermal_zone infiltration_rate_system_on is none')
|
||||
self.assertIsNotNone(thermal_zone.volume, 'thermal_zone volume is none')
|
||||
self.assertIsNone(thermal_zone.ordinate_number, 'thermal_zone ordinate number is not none')
|
||||
self.assertIsNotNone(thermal_zone.view_factors_matrix, 'thermal_zone view factors matrix is none')
|
||||
self.assertIsNone(thermal_zone.usage_zones, 'thermal_zone usage_zones is not none')
|
||||
self.assertIsNone(thermal_zone.thermal_control, 'thermal_zone thermal_control is not none')
|
||||
self.assertIsNone(thermal_zone.hvac_system, 'thermal_zone hvac_system is not none')
|
||||
|
||||
def _check_thermal_boundaries(self, thermal_zone):
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
self.assertIsNotNone(thermal_boundary.id, 'thermal_boundary id is none')
|
||||
self.assertIsNotNone(thermal_boundary.parent_surface, 'thermal_boundary surface is none')
|
||||
self.assertIsNotNone(thermal_boundary.thermal_zones, 'thermal_boundary delimits no thermal zone')
|
||||
self.assertIsNotNone(thermal_boundary.opaque_area, 'thermal_boundary area is none')
|
||||
self.assertIsNotNone(thermal_boundary.azimuth, 'thermal_boundary azimuth is none')
|
||||
self.assertIsNotNone(thermal_boundary.inclination, 'thermal_boundary inclination is none')
|
||||
self.assertIsNotNone(thermal_boundary.thickness, 'thermal_boundary thickness is none')
|
||||
self.assertIsNotNone(thermal_boundary.type, 'thermal_boundary type is none')
|
||||
if thermal_boundary.type is not cte.GROUND:
|
||||
self.assertIsNotNone(thermal_boundary.outside_solar_absorptance, 'outside_solar_absorptance is none')
|
||||
self.assertIsNotNone(thermal_boundary.shortwave_reflectance, 'shortwave_reflectance is none')
|
||||
else:
|
||||
self.assertIsNone(thermal_boundary.outside_solar_absorptance, 'outside_solar_absorptance is not none')
|
||||
self.assertIsNone(thermal_boundary.shortwave_reflectance, 'shortwave_reflectance is not none')
|
||||
self.assertIsNotNone(thermal_boundary.thermal_openings, 'thermal_openings is none')
|
||||
self.assertIsNotNone(thermal_boundary.construction_name, 'construction_name is none')
|
||||
self.assertIsNotNone(thermal_boundary.window_ratio, 'window_ratio is none')
|
||||
self.assertIsNone(thermal_boundary.windows_areas, 'windows_areas is not none')
|
||||
self.assertIsNotNone(thermal_boundary.u_value, 'u_value is none')
|
||||
self.assertIsNotNone(thermal_boundary.hi, 'hi is none')
|
||||
self.assertIsNotNone(thermal_boundary.he, 'he is none')
|
||||
self.assertIsNotNone(thermal_boundary.virtual_internal_surface, 'virtual_internal_surface is none')
|
||||
self.assertIsNone(thermal_boundary.inside_emissivity, 'inside_emissivity is not none')
|
||||
self.assertIsNone(thermal_boundary.alpha_coefficient, 'alpha_coefficient is not none')
|
||||
self.assertIsNone(thermal_boundary.radiative_coefficient, 'radiative_coefficient is not none')
|
||||
|
||||
def _check_thermal_openings(self, thermal_boundary):
|
||||
for thermal_opening in thermal_boundary.thermal_openings:
|
||||
self.assertIsNotNone(thermal_opening.id, 'thermal opening id is not none')
|
||||
self.assertIsNotNone(thermal_opening.area, 'thermal opening area is not none')
|
||||
self.assertRaises(Exception, lambda: thermal_opening.openable_ratio,
|
||||
'thermal_opening openable_ratio is not raising an exception')
|
||||
self.assertIsNotNone(thermal_opening.frame_ratio, 'thermal opening frame_ratio is not none')
|
||||
self.assertIsNotNone(thermal_opening.g_value, 'thermal opening g_value is not none')
|
||||
self.assertIsNotNone(thermal_opening.overall_u_value, 'thermal opening overall_u_value is not none')
|
||||
self.assertIsNotNone(thermal_opening.hi, 'thermal opening hi is not none')
|
||||
self.assertIsNotNone(thermal_opening.he, 'thermal opening he is not none')
|
||||
self.assertIsNone(thermal_opening.inside_emissivity, 'thermal opening inside_emissivity is not none')
|
||||
self.assertIsNone(thermal_opening.alpha_coefficient, 'thermal opening alpha_coefficient is not none')
|
||||
self.assertIsNone(thermal_opening.radiative_coefficient, 'thermal opening radiative_coefficient is not none')
|
||||
|
||||
def test_citygml_function(self):
|
||||
"""
|
||||
Test city objects' functions in the city
|
||||
"""
|
||||
# case 1: hft
|
||||
file = 'one_building_in_kelowna.gml'
|
||||
function_format = 'hft'
|
||||
city = self._get_citygml(file)
|
||||
for building in city.buildings:
|
||||
self.assertIsNotNone(building.average_storey_height, 'average_storey_height is none')
|
||||
self.assertIsNotNone(building.storeys_above_ground, 'storeys_above_ground is none')
|
||||
self.assertIsNot(len(building.thermal_zones), 0, 'no building thermal_zones defined')
|
||||
for thermal_zone in building.thermal_zones:
|
||||
self.assertIsNotNone(thermal_zone.effective_thermal_capacity, 'effective_thermal_capacity is none')
|
||||
self.assertIsNotNone(thermal_zone.additional_thermal_bridge_u_value,
|
||||
'additional_thermal_bridge_u_value is none')
|
||||
self.assertIsNotNone(thermal_zone.indirectly_heated_area_ratio, 'indirectly_heated_area_ratio is none')
|
||||
self.assertIsNotNone(thermal_zone.infiltration_rate_system_on, 'infiltration_rate_system_on is none')
|
||||
self.assertIsNotNone(thermal_zone.infiltration_rate_system_off, 'infiltration_rate_system_off is none')
|
||||
self.assertIsNotNone(thermal_zone.thermal_boundaries, 'thermal_boundaries is none')
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
if thermal_boundary.surface.type != 'Ground':
|
||||
self.assertIsNotNone(thermal_boundary.outside_solar_absorptance, 'outside_solar_absorptance is none')
|
||||
self.assertIsNotNone(thermal_boundary.window_ratio, 'window_ratio is none')
|
||||
for layer in thermal_boundary.layers:
|
||||
self.assertTrue(city.lca_material(layer.material.lca_id) is not None)
|
||||
building.function = self._internal_function(function_format, building.function)
|
||||
self.assertEqual(building.function, 'residential', 'format hft')
|
||||
|
||||
# case 2: Pluto
|
||||
file = 'pluto_building.gml'
|
||||
function_format = 'pluto'
|
||||
city = self._get_citygml(file)
|
||||
for building in city.buildings:
|
||||
building.function = self._internal_function(function_format, building.function)
|
||||
self.assertEqual(building.function, 'secondary school', 'format pluto')
|
||||
|
||||
# case 3: Alkis
|
||||
file = 'one_building_in_kelowna_alkis.gml'
|
||||
function_format = 'alkis'
|
||||
city = self._get_citygml(file)
|
||||
for building in city.buildings:
|
||||
self.assertRaises(Exception, lambda: self._internal_function(function_format, building.function))
|
||||
|
||||
def test_city_with_construction_reduced_library(self):
|
||||
"""
|
||||
|
@ -71,22 +165,69 @@ class TestConstructionFactory(TestCase):
|
|||
file = 'one_building_in_kelowna.gml'
|
||||
city = self._get_citygml(file)
|
||||
for building in city.buildings:
|
||||
building.function = GeometryHelper.hft_to_function[building.function]
|
||||
# case 2: NRCAN
|
||||
building.function = GeometryHelper.libs_function_from_hft(building.function)
|
||||
ConstructionFactory('nrcan', city).enrich()
|
||||
|
||||
self._check_buildings(city)
|
||||
for building in city.buildings:
|
||||
self.assertIsNotNone(building.average_storey_height, 'average_storey_height is none')
|
||||
self.assertIsNotNone(building.storeys_above_ground, 'storeys_above_ground is none')
|
||||
self.assertIsNot(len(building.thermal_zones), 0, 'no building thermal_zones defined')
|
||||
for thermal_zone in building.thermal_zones:
|
||||
self.assertIsNotNone(thermal_zone.effective_thermal_capacity, 'effective_thermal_capacity is none')
|
||||
self.assertIsNotNone(thermal_zone.additional_thermal_bridge_u_value,
|
||||
'additional_thermal_bridge_u_value is none')
|
||||
self.assertIsNotNone(thermal_zone.indirectly_heated_area_ratio, 'indirectly_heated_area_ratio is none')
|
||||
self.assertIsNotNone(thermal_zone.infiltration_rate_system_on, 'infiltration_rate_system_on is none')
|
||||
self.assertIsNotNone(thermal_zone.infiltration_rate_system_off, 'infiltration_rate_system_off is none')
|
||||
self.assertIsNotNone(thermal_zone.thermal_boundaries, 'thermal_boundaries is none')
|
||||
self.assertIsNot(len(thermal_zone.thermal_boundaries), 0, 'no boundaries of thermal_zone defined')
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
self.assertIsNotNone(thermal_boundary.outside_solar_absorptance, 'outside_solar_absorptance is none')
|
||||
self.assertIsNotNone(thermal_boundary.window_ratio, 'window_ratio is none')
|
||||
for internal_zone in building.internal_zones:
|
||||
self._check_thermal_zones(internal_zone)
|
||||
for thermal_zone in internal_zone.thermal_zones:
|
||||
self._check_thermal_boundaries(thermal_zone)
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
self.assertIsNone(thermal_boundary.outside_thermal_absorptance, 'outside_thermal_absorptance is not none')
|
||||
self.assertIsNone(thermal_boundary.outside_visible_absorptance, 'outside_visible_absorptance is not none')
|
||||
self.assertIsNone(thermal_boundary.layers, 'layers is not none')
|
||||
|
||||
self._check_thermal_openings(thermal_boundary)
|
||||
for thermal_opening in thermal_boundary.thermal_openings:
|
||||
self.assertIsNone(thermal_opening.conductivity, 'thermal_opening conductivity is not none')
|
||||
self.assertIsNone(thermal_opening.thickness, 'thermal opening thickness is not none')
|
||||
self.assertIsNone(thermal_opening.front_side_solar_transmittance_at_normal_incidence,
|
||||
'thermal opening front_side_solar_transmittance_at_normal_incidence is not none')
|
||||
self.assertIsNone(thermal_opening.back_side_solar_transmittance_at_normal_incidence,
|
||||
'thermal opening back_side_solar_transmittance_at_normal_incidence is not none')
|
||||
|
||||
def test_city_with_construction_extended_library(self):
|
||||
"""
|
||||
Enrich the city with the construction information and verify it
|
||||
"""
|
||||
file = 'pluto_building.gml'
|
||||
city = self._get_citygml(file)
|
||||
for building in city.buildings:
|
||||
building.function = GeometryHelper.libs_function_from_pluto(building.function)
|
||||
ConstructionFactory('nrel', city).enrich()
|
||||
|
||||
self._check_buildings(city)
|
||||
for building in city.buildings:
|
||||
for internal_zone in building.internal_zones:
|
||||
self._check_thermal_zones(internal_zone)
|
||||
for thermal_zone in internal_zone.thermal_zones:
|
||||
self._check_thermal_boundaries(thermal_zone)
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
if thermal_boundary.type is not cte.GROUND:
|
||||
self.assertIsNotNone(thermal_boundary.outside_thermal_absorptance, 'outside_thermal_absorptance is none')
|
||||
self.assertIsNotNone(thermal_boundary.outside_visible_absorptance, 'outside_visible_absorptance is none')
|
||||
else:
|
||||
self.assertIsNone(thermal_boundary.outside_thermal_absorptance, 'outside_thermal_absorptance is not none')
|
||||
self.assertIsNone(thermal_boundary.outside_visible_absorptance, 'outside_visible_absorptance is not none')
|
||||
self.assertIsNotNone(thermal_boundary.layers, 'layers is none')
|
||||
|
||||
self._check_thermal_openings(thermal_boundary)
|
||||
for thermal_opening in thermal_boundary.thermal_openings:
|
||||
self.assertIsNotNone(thermal_opening.conductivity, 'thermal_opening conductivity is none')
|
||||
self.assertIsNotNone(thermal_opening.thickness, 'thermal opening thickness is none')
|
||||
self.assertIsNotNone(thermal_opening.front_side_solar_transmittance_at_normal_incidence,
|
||||
'thermal opening front_side_solar_transmittance_at_normal_incidence is none')
|
||||
self.assertIsNotNone(thermal_opening.back_side_solar_transmittance_at_normal_incidence,
|
||||
'thermal opening back_side_solar_transmittance_at_normal_incidence is none')
|
||||
|
||||
@staticmethod
|
||||
def _internal_function(function_format, original_function):
|
||||
if function_format == 'hft':
|
||||
new_function = GeometryHelper.libs_function_from_hft(original_function)
|
||||
elif function_format == 'pluto':
|
||||
new_function = GeometryHelper.libs_function_from_pluto(original_function)
|
||||
else:
|
||||
raise Exception('Function key not recognized. Implemented only "hft" and "pluto"')
|
||||
return new_function
|
||||
|
|
|
@ -6,8 +6,8 @@ Copyright © 2021 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.mons
|
|||
from pathlib import Path
|
||||
from unittest import TestCase
|
||||
|
||||
import helpers.constants as cte
|
||||
from imports.geometry_factory import GeometryFactory
|
||||
from imports.construction_factory import ConstructionFactory
|
||||
from imports.usage_factory import UsageFactory
|
||||
from imports.customized_imports_factory import CustomizedImportsFactory
|
||||
from imports.customized_imports.sanam_customized_usage_parameters import SanamCustomizedUsageParameters as scp
|
||||
|
@ -28,7 +28,6 @@ class TestCustomizedImportsFactory(TestCase):
|
|||
file_path = (self._example_path / file).resolve()
|
||||
_city = GeometryFactory('citygml', file_path).city
|
||||
self.assertIsNotNone(_city, 'city is none')
|
||||
ConstructionFactory('nrel', _city).enrich()
|
||||
UsageFactory('hft', _city).enrich()
|
||||
|
||||
return _city
|
||||
|
@ -44,6 +43,9 @@ class TestCustomizedImportsFactory(TestCase):
|
|||
|
||||
CustomizedImportsFactory(scp, city).enrich()
|
||||
for building in city.buildings:
|
||||
self.assertIsNot(len(building.usage_zones), 0, 'no building usage_zones defined')
|
||||
for usage_zone in building.usage_zones:
|
||||
self.assertIsNotNone(usage_zone.mechanical_air_change, 'usage is none')
|
||||
self.assertIsNot(len(building.internal_zones), 0, 'no building internal_zones defined')
|
||||
for internal_zone in building.internal_zones:
|
||||
for usage_zone in internal_zone.usage_zones:
|
||||
if usage_zone.usage != cte.RESIDENTIAL:
|
||||
self.assertIsNotNone(usage_zone.mechanical_air_change, 'mechanical air change rate is none')
|
||||
self.assertIsNotNone(usage_zone.occupancy.occupancy_density, 'occupancy density us none')
|
||||
|
|
|
@ -34,15 +34,22 @@ class TestBuildings(TestCase):
|
|||
ExportsFactory('idf', city, output_path).export()
|
||||
self.assertEqual(10, len(city.buildings))
|
||||
for building in city.buildings:
|
||||
self.assertTrue(len(building.usage_zones) > 0)
|
||||
for usage_zone in building.usage_zones:
|
||||
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)
|
||||
|
||||
|
||||
for internal_zone in building.internal_zones:
|
||||
self.assertTrue(len(internal_zone.usage_zones) > 0)
|
||||
for usage_zone in internal_zone.usage_zones:
|
||||
self.assertIsNot(len(usage_zone.occupancy.occupancy_schedules), 0, 'no occupancy schedules defined')
|
||||
for schedule in usage_zone.occupancy.occupancy_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)
|
||||
self.assertIsNot(len(usage_zone.lighting.schedules), 0, 'no lighting schedules defined')
|
||||
for schedule in usage_zone.lighting.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)
|
||||
|
|
163
unittests/test_enrichement.py
Normal file
163
unittests/test_enrichement.py
Normal file
|
@ -0,0 +1,163 @@
|
|||
"""
|
||||
TestGeometryFactory test and validate the city model structure geometric parameters
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
from pathlib import Path
|
||||
from unittest import TestCase
|
||||
from imports.geometry_factory import GeometryFactory
|
||||
from imports.geometry.helpers.geometry_helper import GeometryHelper
|
||||
from imports.usage_factory import UsageFactory
|
||||
from imports.construction_factory import ConstructionFactory
|
||||
|
||||
|
||||
class TestGeometryFactory(TestCase):
|
||||
"""
|
||||
Non-functional TestGeometryFactory
|
||||
Load testing
|
||||
"""
|
||||
def setUp(self) -> None:
|
||||
"""
|
||||
Test setup
|
||||
:return: None
|
||||
"""
|
||||
self._city = None
|
||||
self._example_path = (Path(__file__).parent / 'tests_data').resolve()
|
||||
|
||||
def _get_citygml(self, file):
|
||||
file_path = (self._example_path / file).resolve()
|
||||
self._city = GeometryFactory('citygml', file_path).city
|
||||
self.assertIsNotNone(self._city, 'city is none')
|
||||
return self._city
|
||||
|
||||
def _check_buildings(self, city):
|
||||
for building in city.buildings:
|
||||
self.assertIsNotNone(building.internal_zones, 'no internal zones created')
|
||||
for internal_zone in building.internal_zones:
|
||||
self.assertIsNotNone(internal_zone.usage_zones, 'usage zones are not defined')
|
||||
self.assertIsNotNone(internal_zone.thermal_zones, 'thermal zones are not defined')
|
||||
#self.assertIsNotNone(building.basement_heated, 'building basement_heated is none')
|
||||
#self.assertIsNotNone(building.attic_heated, 'building attic_heated is none')
|
||||
self.assertIsNotNone(building.average_storey_height, 'building average_storey_height is none')
|
||||
self.assertIsNotNone(building.storeys_above_ground, 'building storeys_above_ground is none')
|
||||
self.assertTrue(building.is_conditioned, 'building is_conditioned is not conditioned')
|
||||
|
||||
def _check_usage_zone(self, usage_zone):
|
||||
self.assertIsNotNone(usage_zone.id, 'usage id is none')
|
||||
|
||||
def _check_thermal_zones(self, thermal_zone):
|
||||
self.assertIsNotNone(thermal_zone.id, 'thermal_zone id is none')
|
||||
self.assertIsNone(thermal_zone.usage_zones, 'thermal_zone usage_zones is not none')
|
||||
self.assertIsNone(thermal_zone.thermal_control, 'thermal_zone thermal_control is not none')
|
||||
|
||||
@staticmethod
|
||||
def _prepare_case_usage_first(city, input_key, construction_key, usage_key):
|
||||
if input_key == 'pluto':
|
||||
for building in city.buildings:
|
||||
building.function = GeometryHelper.libs_function_from_pluto(building.function)
|
||||
elif input_key == 'hft':
|
||||
for building in city.buildings:
|
||||
building.function = GeometryHelper.libs_function_from_hft(building.function)
|
||||
UsageFactory(usage_key, city).enrich()
|
||||
ConstructionFactory(construction_key, city).enrich()
|
||||
|
||||
@staticmethod
|
||||
def _prepare_case_construction_first(city, input_key, construction_key, usage_key):
|
||||
if input_key == 'pluto':
|
||||
for building in city.buildings:
|
||||
building.function = GeometryHelper.libs_function_from_pluto(building.function)
|
||||
elif input_key == 'hft':
|
||||
for building in city.buildings:
|
||||
building.function = GeometryHelper.libs_function_from_hft(building.function)
|
||||
ConstructionFactory(construction_key, city).enrich()
|
||||
UsageFactory(usage_key, city).enrich()
|
||||
|
||||
def test_enrichment(self):
|
||||
"""
|
||||
Test enrichment of the city with different order and all possible combinations
|
||||
:return: None
|
||||
"""
|
||||
file_1 = 'one_building_in_kelowna.gml'
|
||||
file_2 = 'pluto_building.gml'
|
||||
file_3 = 'C40_Final.gml'
|
||||
_construction_keys = ['nrel', 'nrcan']
|
||||
_usage_keys = ['ca', 'comnet'] # todo: add 'hft'
|
||||
|
||||
for construction_key in _construction_keys:
|
||||
for usage_key in _usage_keys:
|
||||
city = self._get_citygml(file_1)
|
||||
self.assertTrue(len(city.buildings) == 1)
|
||||
self._prepare_case_construction_first(city, 'hft', construction_key, usage_key)
|
||||
self._check_buildings(city)
|
||||
for building in city.buildings:
|
||||
for internal_zone in building.internal_zones:
|
||||
self.assertIsNot(len(internal_zone.usage_zones), 0, 'no building usage_zones defined')
|
||||
for usage_zone in internal_zone.usage_zones:
|
||||
self._check_usage_zone(usage_zone)
|
||||
for thermal_zone in internal_zone.thermal_zones:
|
||||
self._check_thermal_zones(thermal_zone)
|
||||
|
||||
for construction_key in _construction_keys:
|
||||
for usage_key in _usage_keys:
|
||||
city = self._get_citygml(file_1)
|
||||
self.assertTrue(len(city.buildings) == 1)
|
||||
self._prepare_case_usage_first(city, 'hft', construction_key, usage_key)
|
||||
self._check_buildings(city)
|
||||
for building in city.buildings:
|
||||
for internal_zone in building.internal_zones:
|
||||
self.assertIsNot(len(internal_zone.usage_zones), 0, 'no building usage_zones defined')
|
||||
for usage_zone in internal_zone.usage_zones:
|
||||
self._check_usage_zone(usage_zone)
|
||||
for thermal_zone in internal_zone.thermal_zones:
|
||||
self._check_thermal_zones(thermal_zone)
|
||||
|
||||
for construction_key in _construction_keys:
|
||||
if construction_key != 'nrcan':
|
||||
for usage_key in _usage_keys:
|
||||
if usage_key != 'ca':
|
||||
city = self._get_citygml(file_2)
|
||||
self.assertTrue(len(city.buildings) == 1)
|
||||
self._prepare_case_construction_first(city, 'pluto', construction_key, usage_key)
|
||||
self._check_buildings(city)
|
||||
for building in city.buildings:
|
||||
for internal_zone in building.internal_zones:
|
||||
self.assertIsNot(len(internal_zone.usage_zones), 0, 'no building usage_zones defined')
|
||||
for usage_zone in internal_zone.usage_zones:
|
||||
self._check_usage_zone(usage_zone)
|
||||
for thermal_zone in internal_zone.thermal_zones:
|
||||
self._check_thermal_zones(thermal_zone)
|
||||
|
||||
for construction_key in _construction_keys:
|
||||
if construction_key != 'nrcan':
|
||||
for usage_key in _usage_keys:
|
||||
if usage_key != 'ca':
|
||||
city = self._get_citygml(file_2)
|
||||
self.assertTrue(len(city.buildings) == 1)
|
||||
self._prepare_case_usage_first(city, 'pluto', construction_key, usage_key)
|
||||
self._check_buildings(city)
|
||||
for building in city.buildings:
|
||||
for internal_zone in building.internal_zones:
|
||||
self.assertIsNot(len(internal_zone.usage_zones), 0, 'no building usage_zones defined')
|
||||
for usage_zone in internal_zone.usage_zones:
|
||||
self._check_usage_zone(usage_zone)
|
||||
for thermal_zone in internal_zone.thermal_zones:
|
||||
self._check_thermal_zones(thermal_zone)
|
||||
|
||||
city = self._get_citygml(file_3)
|
||||
self.assertTrue(len(city.buildings) == 10)
|
||||
|
||||
for construction_key in _construction_keys:
|
||||
if construction_key != 'nrcan':
|
||||
for usage_key in _usage_keys:
|
||||
if usage_key != 'ca':
|
||||
city = self._get_citygml(file_2)
|
||||
self.assertTrue(len(city.buildings) == 1)
|
||||
self._prepare_case_construction_first(city, 'pluto', construction_key, usage_key)
|
||||
self._check_buildings(city)
|
||||
for building in city.buildings:
|
||||
for internal_zone in building.internal_zones:
|
||||
self.assertIsNot(len(internal_zone.usage_zones), 0, 'no building usage_zones defined')
|
||||
for usage_zone in internal_zone.usage_zones:
|
||||
self._check_usage_zone(usage_zone)
|
||||
for thermal_zone in internal_zone.thermal_zones:
|
||||
self._check_thermal_zones(thermal_zone)
|
|
@ -9,8 +9,8 @@ from pathlib import Path
|
|||
from unittest import TestCase
|
||||
import pandas as pd
|
||||
from imports.geometry_factory import GeometryFactory
|
||||
from imports.geometry.helpers.geometry_helper import GeometryHelper
|
||||
from imports.construction_factory import ConstructionFactory
|
||||
from imports.schedules_factory import SchedulesFactory
|
||||
from imports.usage_factory import UsageFactory
|
||||
from exports.exports_factory import ExportsFactory
|
||||
import helpers.constants as cte
|
||||
|
@ -45,9 +45,10 @@ class TestExports(TestCase):
|
|||
else:
|
||||
file_path = (self._example_path / 'one_building_in_kelowna.gml').resolve()
|
||||
self._complete_city = self._get_citygml(file_path)
|
||||
for building in self._complete_city.buildings:
|
||||
building.function = GeometryHelper().libs_function_from_hft(building.function)
|
||||
ConstructionFactory('nrel', self._complete_city).enrich()
|
||||
UsageFactory('ca', self._complete_city).enrich()
|
||||
SchedulesFactory('comnet', self._complete_city).enrich()
|
||||
cli = 'C:\\Users\\Pilar\\PycharmProjects\\monthlyenergybalance\\tests_data\\weather\\inseldb_Summerland.cli'
|
||||
self._complete_city.climate_file = Path(cli)
|
||||
self._complete_city.climate_reference_city = 'Summerland'
|
||||
|
|
|
@ -6,8 +6,6 @@ Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.mons
|
|||
from pathlib import Path
|
||||
from unittest import TestCase
|
||||
from imports.geometry_factory import GeometryFactory
|
||||
from imports.geometry.helpers.geometry_helper import GeometryHelper
|
||||
from city_model_structure.building_demand.thermal_opening import ThermalOpening
|
||||
|
||||
|
||||
class TestGeometryFactory(TestCase):
|
||||
|
@ -36,20 +34,66 @@ class TestGeometryFactory(TestCase):
|
|||
self.assertIsNotNone(self._city, 'city is none')
|
||||
return self._city
|
||||
|
||||
@staticmethod
|
||||
def _internal_function(function_format, original_function):
|
||||
new_function = original_function
|
||||
if function_format == 'hft':
|
||||
new_function = GeometryHelper.hft_to_function[original_function]
|
||||
elif function_format == 'pluto':
|
||||
new_function = GeometryHelper.pluto_to_function[original_function]
|
||||
elif function_format == 'alkis':
|
||||
# todo: not implemented yet!!
|
||||
raise NotImplementedError
|
||||
return new_function
|
||||
def _check_buildings(self, city):
|
||||
for building in city.buildings:
|
||||
self.assertIsNotNone(building.name, 'building name is none')
|
||||
self.assertIsNotNone(building.lod, 'building lod is none')
|
||||
self.assertIsNotNone(building.type, 'building type is none')
|
||||
self.assertIsNotNone(building.volume, 'building volume is none')
|
||||
self.assertIsNotNone(building.detailed_polyhedron, 'building detailed polyhedron is none')
|
||||
self.assertIsNotNone(building.simplified_polyhedron, 'building simplified polyhedron is none')
|
||||
self.assertIsNotNone(building.surfaces, 'building surfaces is none')
|
||||
self.assertIsNotNone(building.centroid, 'building centroid is none')
|
||||
self.assertIsNotNone(building.max_height, 'building max_height is none')
|
||||
self.assertEqual(len(building.external_temperature), 0, 'building external temperature is calculated')
|
||||
self.assertEqual(len(building.global_horizontal), 0, 'building global horizontal is calculated')
|
||||
self.assertEqual(len(building.diffuse), 0, 'building diffuse is calculated')
|
||||
self.assertEqual(len(building.beam), 0, 'building beam is calculated')
|
||||
self.assertIsNotNone(building.lower_corner, 'building lower corner is none')
|
||||
self.assertEqual(len(building.sensors), 0, 'building sensors are assigned')
|
||||
self.assertIsNotNone(building.internal_zones, 'no internal zones created')
|
||||
self.assertIsNotNone(building.grounds, 'building grounds is none')
|
||||
self.assertIsNotNone(building.walls, 'building walls is none')
|
||||
self.assertIsNotNone(building.roofs, 'building roofs is none')
|
||||
self.assertIsNotNone(building.internal_zones, 'building internal zones is none')
|
||||
for internal_zone in building.internal_zones:
|
||||
self.assertIsNone(internal_zone.usage_zones, 'usage zones are defined')
|
||||
self.assertIsNone(internal_zone.thermal_zones, 'thermal zones are defined')
|
||||
self.assertIsNone(building.basement_heated, 'building basement_heated is not none')
|
||||
self.assertIsNone(building.attic_heated, 'building attic_heated is not none')
|
||||
self.assertIsNone(building.terrains, 'building terrains is not none')
|
||||
self.assertIsNotNone(building.year_of_construction, 'building year_of_construction is none')
|
||||
self.assertIsNotNone(building.function, 'building function is none')
|
||||
self.assertIsNone(building.average_storey_height, 'building average_storey_height is not none')
|
||||
self.assertIsNone(building.storeys_above_ground, 'building storeys_above_ground is not none')
|
||||
self.assertEqual(len(building.heating), 0, 'building heating is not none')
|
||||
self.assertEqual(len(building.cooling), 0, 'building cooling is not none')
|
||||
self.assertIsNotNone(building.eave_height, 'building eave height is none')
|
||||
self.assertIsNotNone(building.roof_type, 'building roof type is none')
|
||||
self.assertIsNotNone(building.floor_area, 'building floor_area is none')
|
||||
self.assertIsNone(building.households, 'building households is not none')
|
||||
self.assertFalse(building.is_conditioned, 'building is_conditioned is conditioned')
|
||||
|
||||
def _check_surfaces(self, building):
|
||||
for surface in building.surfaces:
|
||||
self.assertIsNotNone(surface.name, 'surface name is none')
|
||||
self.assertIsNotNone(surface.id, 'surface id is none')
|
||||
self.assertIsNone(surface.swr, 'surface swr is not none')
|
||||
self.assertIsNotNone(surface.lower_corner, 'surface envelope_lower_corner is none')
|
||||
self.assertIsNotNone(surface.upper_corner, 'surface envelope_upper_corner is none')
|
||||
self.assertIsNotNone(surface.area_below_ground, 'surface area_below_ground is none')
|
||||
self.assertIsNotNone(surface.area_above_ground, 'surface area_above_ground is none')
|
||||
self.assertIsNotNone(surface.azimuth, 'surface azimuth is none')
|
||||
self.assertIsNotNone(surface.type, 'surface type is none')
|
||||
self.assertIsNotNone(surface.inclination, 'surface inclination is none')
|
||||
self.assertEqual(len(surface.global_irradiance), 0, 'global irradiance is calculated')
|
||||
self.assertIsNotNone(surface.perimeter_polygon, 'surface perimeter_polygon is none')
|
||||
self.assertIsNone(surface.holes_polygons, 'surface hole_polygons is not none')
|
||||
self.assertIsNotNone(surface.solid_polygon, 'surface solid_polygon is none')
|
||||
self.assertIsNone(surface.pv_system_installed, 'surface PV system installed is not none')
|
||||
|
||||
# citygml_classes
|
||||
def test_citygml_buildings(self):
|
||||
def test_import_citygml(self):
|
||||
"""
|
||||
Test city objects in the city
|
||||
:return: None
|
||||
|
@ -57,175 +101,9 @@ class TestGeometryFactory(TestCase):
|
|||
file = 'one_building_in_kelowna.gml'
|
||||
city = self._get_citygml(file)
|
||||
self.assertTrue(len(city.buildings) == 1)
|
||||
self._check_buildings(city)
|
||||
for building in city.buildings:
|
||||
self.assertIsNotNone(building.name, 'building name is none')
|
||||
self.assertIsNotNone(building.lod, 'building lod is none')
|
||||
self.assertIsNotNone(building.centroid, 'building centroid is none')
|
||||
self.assertIsNotNone(building.year_of_construction, 'building year_of_construction is none')
|
||||
self.assertIsNotNone(building.function, 'building function is none')
|
||||
self.assertIsNotNone(building.volume, 'building volume is none')
|
||||
self.assertIsNotNone(building.surfaces, 'building surfaces is none')
|
||||
self.assertIsNotNone(building.surfaces[0].name, 'surface not found')
|
||||
self.assertIsNone(building.basement_heated, 'building basement_heated is not none')
|
||||
self.assertIsNone(building.attic_heated, 'building attic_heated is not none')
|
||||
self.assertIsNotNone(building.terrains, 'building terrains is none')
|
||||
self.assertIsNone(building.average_storey_height, 'building average_storey_height is not none')
|
||||
self.assertIsNotNone(building.type, 'building type is none')
|
||||
self.assertIsNotNone(building.max_height, 'building max_height is none')
|
||||
self.assertIsNotNone(building.floor_area, 'building floor_area is none')
|
||||
|
||||
def test_citygml_surfaces(self):
|
||||
"""
|
||||
Test surfaces in city objects
|
||||
:return: None
|
||||
"""
|
||||
file = 'one_building_in_kelowna.gml'
|
||||
city = self._get_citygml(file)
|
||||
for building in city.buildings:
|
||||
for surface in building.surfaces:
|
||||
self.assertIsNotNone(surface.name, 'surface name is none')
|
||||
self.assertIsNotNone(surface.type, 'surface type is none')
|
||||
self.assertIsNotNone(surface.azimuth, 'surface azimuth is none')
|
||||
self.assertIsNotNone(surface.inclination, 'surface inclination is none')
|
||||
self.assertIsNotNone(surface.area_below_ground, 'surface area_below_ground is none')
|
||||
self.assertIsNotNone(surface.area_above_ground, 'surface area_above_ground is none')
|
||||
self.assertIsNotNone(surface.global_irradiance, 'monthly irradiance is none')
|
||||
self.assertIsNone(surface.swr, 'surface swr is not none')
|
||||
self.assertIsNotNone(surface.lower_corner, 'surface envelope_lower_corner is none')
|
||||
self.assertIsNotNone(surface.upper_corner, 'surface envelope_upper_corner is none')
|
||||
self.assertIsNotNone(surface.area_above_ground, 'surface area_above_ground is none')
|
||||
self.assertIsNotNone(surface.perimeter_polygon, 'surface perimeter_polygon is none')
|
||||
self.assertIsNone(surface.holes_polygons, 'surface hole_polygons is not none')
|
||||
self.assertIsNotNone(surface.solid_polygon, 'surface solid_polygon is none')
|
||||
|
||||
def test_citygml_thermal_zone(self):
|
||||
"""
|
||||
Test thermal zones in city objects
|
||||
:return: None
|
||||
"""
|
||||
file = 'one_building_in_kelowna.gml'
|
||||
city = self._get_citygml(file)
|
||||
for building in city.buildings:
|
||||
self.assertIsNot(len(building.thermal_zones), 0, 'no building thermal_zones defined')
|
||||
for thermal_zone in building.thermal_zones:
|
||||
self.assertIsNotNone(thermal_zone.thermal_boundaries, 'thermal_zone thermal_boundaries is none')
|
||||
self.assertIsNotNone(thermal_zone.floor_area, 'thermal_zone floor_area is none')
|
||||
self.assertIsNone(thermal_zone.additional_thermal_bridge_u_value,
|
||||
'thermal_zone additional_thermal_bridge_u_value is not none')
|
||||
self.assertIsNone(thermal_zone.effective_thermal_capacity,
|
||||
'thermal_zone effective_thermal_capacity is not none')
|
||||
self.assertIsNone(thermal_zone.indirectly_heated_area_ratio,
|
||||
'thermal_zone indirectly_heated_area_ratio is not none')
|
||||
self.assertIsNone(thermal_zone.infiltration_rate_system_off,
|
||||
'thermal_zone infiltration_rate_system_off is not none')
|
||||
self.assertIsNone(thermal_zone.infiltration_rate_system_on,
|
||||
'thermal_zone infiltration_rate_system_on is not none')
|
||||
self.assertIsNone(thermal_zone.usage_zones,
|
||||
'thermal_zone usage_zones are not none')
|
||||
|
||||
def test_citygml_thermal_boundary(self):
|
||||
"""
|
||||
Test thermal boundaries in thermal zones
|
||||
:return: None
|
||||
"""
|
||||
file = 'one_building_in_kelowna.gml'
|
||||
city = self._get_citygml(file)
|
||||
for building in city.buildings:
|
||||
self.assertIsNot(len(building.thermal_zones), 0, 'no building thermal_zones defined')
|
||||
for thermal_zone in building.thermal_zones:
|
||||
self.assertIsNot(len(thermal_zone.thermal_boundaries), 0, 'no building thermal_boundaries defined')
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
print(thermal_boundary.surface.type)
|
||||
print(thermal_boundary.surface.area_above_ground)
|
||||
self.assertIsNotNone(thermal_boundary.surface, 'thermal_boundary surface is none')
|
||||
self.assertIsNotNone(thermal_boundary.type, 'thermal_boundary type is none')
|
||||
self.assertIsNotNone(thermal_boundary.area, 'thermal_boundary area is none')
|
||||
self.assertIsNotNone(thermal_boundary.azimuth, 'thermal_boundary azimuth is none')
|
||||
self.assertIsNotNone(thermal_boundary.thermal_zones, 'thermal_boundary delimits is none')
|
||||
self.assertIsNotNone(thermal_boundary.inclination, 'thermal_boundary inclination is none')
|
||||
|
||||
def test_citygml_thermal_opening(self):
|
||||
"""
|
||||
Test thermal openings in thermal zones
|
||||
:return: None
|
||||
"""
|
||||
file = 'one_building_in_kelowna.gml'
|
||||
city = self._get_citygml(file)
|
||||
for building in city.buildings:
|
||||
self.assertIsNot(len(building.thermal_zones), 0, 'no building thermal_zones defined')
|
||||
for thermal_zone in building.thermal_zones:
|
||||
self.assertIsNot(len(thermal_zone.thermal_boundaries), 0, 'no building thermal_boundaries defined')
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
thermal_opening: ThermalOpening
|
||||
for thermal_opening in thermal_boundary.thermal_openings:
|
||||
self.assertIsNone(thermal_opening.frame_ratio, 'thermal_opening frame_ratio was initialized')
|
||||
self.assertIsNone(thermal_opening.g_value, 'thermal_opening g_value was initialized')
|
||||
self.assertIsNone(thermal_opening.conductivity, 'thermal_opening conductivity_w_mk was initialized')
|
||||
self.assertIsNone(thermal_opening.back_side_solar_transmittance_at_normal_incidence,
|
||||
'thermal_opening back_side_solar_transmittance_at_normal_incidence was initialized')
|
||||
self.assertRaises(Exception, lambda: thermal_opening.openable_ratio,
|
||||
'thermal_opening openable_ratio is not raising an exception')
|
||||
self.assertIsNone(thermal_opening.front_side_solar_transmittance_at_normal_incidence,
|
||||
'thermal_opening front_side_solar_transmittance_at_normal_incidence was initialized')
|
||||
self.assertIsNone(thermal_opening.thickness, 'thermal_opening thickness_m was initialized')
|
||||
self.assertRaises(Exception, lambda: thermal_opening.overall_u_value,
|
||||
'thermal_opening u_value was initialized')
|
||||
self.assertIsNone(thermal_opening.overall_u_value, 'thermal_opening overall_u_value was initialized')
|
||||
self.assertIsNone(thermal_opening.hi, 'thermal_opening hi was initialized')
|
||||
self.assertIsNone(thermal_opening.he, 'thermal_opening he was initialized')
|
||||
|
||||
def test_citygml_function(self):
|
||||
"""
|
||||
Test city objects' functions in the city
|
||||
:return: None
|
||||
"""
|
||||
# case 1: hft
|
||||
file = 'one_building_in_kelowna.gml'
|
||||
function_format = 'hft'
|
||||
city = self._get_citygml(file)
|
||||
for building in city.buildings:
|
||||
building.function = self._internal_function(function_format, building.function)
|
||||
self.assertEqual(building.function, 'residential', 'format hft')
|
||||
|
||||
# case 2: Pluto
|
||||
file = 'pluto_building.gml'
|
||||
function_format = 'pluto'
|
||||
city = self._get_citygml(file)
|
||||
for building in city.buildings:
|
||||
building.function = self._internal_function(function_format, building.function)
|
||||
self.assertEqual(building.function, 'secondary school', 'format pluto')
|
||||
|
||||
# case 3: Alkis
|
||||
file = 'one_building_in_kelowna_alkis.gml'
|
||||
function_format = 'alkis'
|
||||
city = self._get_citygml(file)
|
||||
for building in city.buildings:
|
||||
self.assertRaises(Exception, lambda: self._internal_function(function_format, building.function))
|
||||
|
||||
def test_citygml_storeys(self):
|
||||
"""
|
||||
Test division by storeys of buildings
|
||||
:return: None
|
||||
"""
|
||||
|
||||
file = 'one_building_in_kelowna.gml'
|
||||
city = self._get_citygml(file)
|
||||
for building in city.buildings:
|
||||
print('building')
|
||||
for surface in building.surfaces:
|
||||
print(surface.name)
|
||||
print(surface.type)
|
||||
print(surface.perimeter_polygon.area)
|
||||
building.average_storey_height = 1.5
|
||||
building.storeys_above_ground = 2
|
||||
storeys = building.storeys
|
||||
for storey in storeys:
|
||||
print(storey.name)
|
||||
print(storey.neighbours)
|
||||
for surface in storey.surfaces:
|
||||
print(surface.name)
|
||||
print(surface.type)
|
||||
print(surface.perimeter_polygon.area)
|
||||
self._check_surfaces(building)
|
||||
|
||||
# obj
|
||||
def test_import_obj(self):
|
||||
|
@ -235,8 +113,10 @@ class TestGeometryFactory(TestCase):
|
|||
file = 'kelowna.obj'
|
||||
city = self._get_obj(file)
|
||||
self.assertIsNotNone(city, 'city is none')
|
||||
self.assertTrue(len(city.buildings) == 1)
|
||||
self._check_buildings(city)
|
||||
for building in city.buildings:
|
||||
self.assertIsNotNone(building, 'building is none')
|
||||
self._check_surfaces(building)
|
||||
|
||||
# osm
|
||||
def test_subway(self):
|
||||
|
|
|
@ -47,10 +47,8 @@ class TestLifeCycleAssessment(TestCase):
|
|||
city_file = "../unittests/tests_data/C40_Final.gml"
|
||||
city = GeometryFactory('citygml', city_file).city
|
||||
LifeCycleAssessment('material', city).enrich()
|
||||
self.assertTrue(len(city.lca_materials) > 0)
|
||||
for lca_material in city.lca_materials:
|
||||
lca_mat = city.lca_material(lca_material.id)
|
||||
self.assertTrue(lca_mat is not None)
|
||||
for material in city.materials:
|
||||
self.assertTrue(len(city.materials) > 0)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -31,30 +31,10 @@ class TestSchedulesFactory(TestCase):
|
|||
ConstructionFactory('nrel', _city).enrich()
|
||||
self.assertIsNotNone(_city, 'city is none')
|
||||
for building in _city.buildings:
|
||||
building.function = GeometryHelper.hft_to_function[building.function]
|
||||
building.function = GeometryHelper.libs_function_from_hft(building.function)
|
||||
UsageFactory('hft', _city).enrich()
|
||||
return _city
|
||||
|
||||
def test_comnet_archetypes(self):
|
||||
"""
|
||||
Enrich the city with commet schedule archetypes and verify it
|
||||
"""
|
||||
file = (self._example_path / 'one_building_in_kelowna.gml').resolve()
|
||||
city = self._get_citygml(file)
|
||||
occupancy_handler = 'comnet'
|
||||
SchedulesFactory(occupancy_handler, city).enrich()
|
||||
for building in city.buildings:
|
||||
self.assertIsNot(len(building.usage_zones), 0, 'no building usage_zones defined')
|
||||
for usage_zone in building.usage_zones:
|
||||
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)
|
||||
|
||||
def test_doe_idf_archetypes(self):
|
||||
"""
|
||||
Enrich the city with doe_idf schedule archetypes and verify it
|
||||
|
@ -64,6 +44,22 @@ class TestSchedulesFactory(TestCase):
|
|||
occupancy_handler = 'doe_idf'
|
||||
SchedulesFactory(occupancy_handler, city).enrich()
|
||||
for building in city.buildings:
|
||||
for usage_zone in building.usage_zones:
|
||||
for schedule in usage_zone.schedules:
|
||||
print(schedule)
|
||||
for internal_zone in building.internal_zones:
|
||||
self.assertTrue(len(internal_zone.usage_zones) > 0)
|
||||
for usage_zone in internal_zone.usage_zones:
|
||||
self.assertIsNot(len(usage_zone.occupancy.occupancy_schedules), 0, 'no occupancy schedules defined')
|
||||
for schedule in usage_zone.occupancy.occupancy_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)
|
||||
self.assertIsNot(len(usage_zone.lighting.schedules), 0, 'no lighting schedules defined')
|
||||
for schedule in usage_zone.lighting.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)
|
||||
|
|
|
@ -50,8 +50,8 @@ class TestSensorsFactory(TestCase):
|
|||
Load concordia sensors and verify it
|
||||
"""
|
||||
SensorsFactory('cec', self._city, self._end_point).enrich()
|
||||
# SensorsFactory('cgf', self._city, self._end_point).enrich()
|
||||
# SensorsFactory('ct', self._city, self._end_point).enrich()
|
||||
SensorsFactory('cgf', self._city, self._end_point).enrich()
|
||||
SensorsFactory('ct', self._city, self._end_point).enrich()
|
||||
for city_object in self._city.city_objects:
|
||||
print(city_object.name, len(city_object.sensors))
|
||||
for sensor in city_object.sensors:
|
||||
|
|
|
@ -7,9 +7,7 @@ from pathlib import Path
|
|||
from unittest import TestCase
|
||||
|
||||
from imports.geometry_factory import GeometryFactory
|
||||
from imports.construction_factory import ConstructionFactory
|
||||
from imports.usage_factory import UsageFactory
|
||||
from imports.construction_factory import ConstructionFactory
|
||||
from imports.geometry.helpers.geometry_helper import GeometryHelper
|
||||
from imports.construction_factory import ConstructionFactory
|
||||
|
||||
|
@ -23,66 +21,161 @@ class TestUsageFactory(TestCase):
|
|||
Configure test environment
|
||||
:return:
|
||||
"""
|
||||
self._city = None
|
||||
self._example_path = (Path(__file__).parent / 'tests_data').resolve()
|
||||
|
||||
def _get_citygml(self, file):
|
||||
file_path = (self._example_path / file).resolve()
|
||||
_city = GeometryFactory('citygml', file_path).city
|
||||
self.assertIsNotNone(_city, 'city is none')
|
||||
return _city
|
||||
self._city = GeometryFactory('citygml', file_path).city
|
||||
self.assertIsNotNone(self._city, 'city is none')
|
||||
return self._city
|
||||
|
||||
def test_comnet(self):
|
||||
def _check_buildings(self, city):
|
||||
for building in city.buildings:
|
||||
self.assertIsNotNone(building.name, 'building name is none')
|
||||
self.assertIsNotNone(building.lod, 'building lod is none')
|
||||
self.assertIsNotNone(building.type, 'building type is none')
|
||||
self.assertIsNotNone(building.volume, 'building volume is none')
|
||||
self.assertIsNotNone(building.detailed_polyhedron, 'building detailed polyhedron is none')
|
||||
self.assertIsNotNone(building.simplified_polyhedron, 'building simplified polyhedron is none')
|
||||
self.assertIsNotNone(building.surfaces, 'building surfaces is none')
|
||||
self.assertIsNotNone(building.centroid, 'building centroid is none')
|
||||
self.assertIsNotNone(building.max_height, 'building max_height is none')
|
||||
self.assertEqual(len(building.external_temperature), 0, 'building external temperature is calculated')
|
||||
self.assertEqual(len(building.global_horizontal), 0, 'building global horizontal is calculated')
|
||||
self.assertEqual(len(building.diffuse), 0, 'building diffuse is calculated')
|
||||
self.assertEqual(len(building.beam), 0, 'building beam is calculated')
|
||||
self.assertIsNotNone(building.lower_corner, 'building lower corner is none')
|
||||
self.assertEqual(len(building.sensors), 0, 'building sensors are assigned')
|
||||
self.assertIsNotNone(building.internal_zones, 'no internal zones created')
|
||||
self.assertIsNotNone(building.grounds, 'building grounds is none')
|
||||
self.assertIsNotNone(building.walls, 'building walls is none')
|
||||
self.assertIsNotNone(building.roofs, 'building roofs is none')
|
||||
for internal_zone in building.internal_zones:
|
||||
self.assertTrue(len(internal_zone.usage_zones) > 0, 'usage zones are not defined')
|
||||
self.assertIsNone(internal_zone.thermal_zones, 'thermal zones are defined')
|
||||
self.assertIsNone(building.basement_heated, 'building basement_heated is not none')
|
||||
self.assertIsNone(building.attic_heated, 'building attic_heated is not none')
|
||||
self.assertIsNone(building.terrains, 'building terrains is not none')
|
||||
self.assertIsNotNone(building.year_of_construction, 'building year_of_construction is none')
|
||||
self.assertIsNotNone(building.function, 'building function is none')
|
||||
self.assertIsNone(building.average_storey_height, 'building average_storey_height is not none')
|
||||
self.assertIsNone(building.storeys_above_ground, 'building storeys_above_ground is not none')
|
||||
self.assertEqual(len(building.heating), 0, 'building heating is not none')
|
||||
self.assertEqual(len(building.cooling), 0, 'building cooling is not none')
|
||||
self.assertIsNotNone(building.eave_height, 'building eave height is none')
|
||||
self.assertIsNotNone(building.roof_type, 'building roof type is none')
|
||||
self.assertIsNotNone(building.floor_area, 'building floor_area is none')
|
||||
self.assertIsNone(building.households, 'building households is not none')
|
||||
self.assertTrue(building.is_conditioned, 'building is not conditioned')
|
||||
|
||||
def _check_usage_zone(self, usage_zone):
|
||||
self.assertIsNotNone(usage_zone.usage, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.percentage, 'usage percentage is none')
|
||||
self.assertIsNotNone(usage_zone.get_internal_gains, 'internal gains is none')
|
||||
self.assertIsNotNone(usage_zone.hours_day, 'hours per day is none')
|
||||
self.assertIsNotNone(usage_zone.days_year, 'days per year is none')
|
||||
self.assertIsNotNone(usage_zone.thermal_control, 'thermal control is none')
|
||||
self.assertIsNotNone(usage_zone.thermal_control.mean_heating_set_point, 'control heating set point is none')
|
||||
self.assertIsNotNone(usage_zone.thermal_control.heating_set_back, 'control heating set back is none')
|
||||
self.assertIsNotNone(usage_zone.thermal_control.mean_cooling_set_point, 'control cooling set point is none')
|
||||
|
||||
def test_import_comnet(self):
|
||||
"""
|
||||
Enrich the city with the usage information from comnet and verify it
|
||||
"""
|
||||
file = 'pluto_building.gml'
|
||||
city = self._get_citygml(file)
|
||||
for building in city.buildings:
|
||||
building.function = GeometryHelper.pluto_to_function[building.function]
|
||||
building.function = GeometryHelper.libs_function_from_pluto(building.function)
|
||||
|
||||
ConstructionFactory('nrel', city).enrich()
|
||||
UsageFactory('comnet', city).enrich()
|
||||
|
||||
def test_city_with_usage(self):
|
||||
"""
|
||||
Enrich the city with the usage information and verify it
|
||||
:return: None
|
||||
"""
|
||||
# case 1: HFT
|
||||
file = 'pluto_building.gml'
|
||||
city = self._get_citygml(file)
|
||||
self._check_buildings(city)
|
||||
for building in city.buildings:
|
||||
building.function = GeometryHelper.pluto_to_function[building.function]
|
||||
ConstructionFactory('nrel', city).enrich()
|
||||
UsageFactory('hft', city).enrich()
|
||||
for building in city.buildings:
|
||||
self.assertIsNot(len(building.usage_zones), 0, 'no building usage_zones defined')
|
||||
for usage_zone in building.usage_zones:
|
||||
self.assertIsNotNone(usage_zone.usage, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.internal_gains, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.cooling_setpoint, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.heating_setback, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.heating_setpoint, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.occupancy_density, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.hours_day, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.days_year, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.dhw_average_volume_pers_day, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.dhw_preparation_temperature, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.electrical_app_average_consumption_sqm_year, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.is_heated, 'thermal_zone heated is none')
|
||||
self.assertIsNotNone(usage_zone.is_cooled, 'thermal_zone cooled is none')
|
||||
for internal_zone in building.internal_zones:
|
||||
self.assertIsNot(len(internal_zone.usage_zones), 0, 'no building usage_zones defined')
|
||||
for usage_zone in internal_zone.usage_zones:
|
||||
self._check_usage_zone(usage_zone)
|
||||
self.assertIsNotNone(usage_zone.mechanical_air_change, 'mechanical air change is none')
|
||||
self.assertIsNotNone(usage_zone.thermal_control.heating_set_point_schedules,
|
||||
'control heating set point schedule is none')
|
||||
self.assertIsNotNone(usage_zone.thermal_control.cooling_set_point_schedules,
|
||||
'control cooling set point schedule is none')
|
||||
self.assertIsNotNone(usage_zone.occupancy, 'occupancy is none')
|
||||
occupancy = usage_zone.occupancy
|
||||
self.assertIsNotNone(occupancy.occupancy_density, 'occupancy density is none')
|
||||
self.assertIsNotNone(occupancy.latent_internal_gain, 'occupancy latent internal gain is none')
|
||||
self.assertIsNotNone(occupancy.sensible_convective_internal_gain,
|
||||
'occupancy sensible convective internal gain is none')
|
||||
self.assertIsNotNone(occupancy.sensible_radiative_internal_gain,
|
||||
'occupancy sensible radiant internal gain is none')
|
||||
self.assertIsNotNone(occupancy.occupancy_schedules, 'occupancy schedule is none')
|
||||
self.assertIsNone(occupancy.occupants, 'occupancy density is not none')
|
||||
self.assertIsNotNone(usage_zone.lighting, 'lighting is none')
|
||||
lighting = usage_zone.lighting
|
||||
self.assertIsNotNone(lighting.lighting_density, 'lighting density is none')
|
||||
self.assertIsNotNone(lighting.latent_fraction, 'lighting latent fraction is none')
|
||||
self.assertIsNotNone(lighting.convective_fraction, 'lighting convective fraction is none')
|
||||
self.assertIsNotNone(lighting.radiative_fraction, 'lighting radiant fraction is none')
|
||||
self.assertIsNotNone(lighting.schedules, 'lighting schedule is none')
|
||||
self.assertIsNotNone(usage_zone.appliances, 'appliances is none')
|
||||
appliances = usage_zone.appliances
|
||||
self.assertIsNotNone(appliances.appliances_density, 'appliances density is none')
|
||||
self.assertIsNotNone(appliances.latent_fraction, 'appliances latent fraction is none')
|
||||
self.assertIsNotNone(appliances.convective_fraction, 'appliances convective fraction is none')
|
||||
self.assertIsNotNone(appliances.radiative_fraction, 'appliances radiant fraction is none')
|
||||
self.assertIsNotNone(appliances.schedules, 'appliances schedule is none')
|
||||
self.assertIsNotNone(usage_zone.thermal_control.hvac_availability_schedules,
|
||||
'control hvac availability is none')
|
||||
|
||||
|
||||
# case 2: CA
|
||||
def test_import_ca(self):
|
||||
"""
|
||||
Enrich the city with the usage information from canada and verify it
|
||||
"""
|
||||
file = 'one_building_in_kelowna.gml'
|
||||
city = self._get_citygml(file)
|
||||
ConstructionFactory('nrel', city).enrich()
|
||||
UsageFactory('ca', city).enrich()
|
||||
self._check_buildings(city)
|
||||
for building in city.buildings:
|
||||
self.assertIsNot(len(building.usage_zones), 0, 'no building usage_zones defined')
|
||||
for usage_zone in building.usage_zones:
|
||||
self.assertIsNotNone(usage_zone.usage, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.internal_gains, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.cooling_setpoint, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.heating_setback, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.heating_setpoint, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.occupancy_density, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.hours_day, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.days_year, 'usage is none')
|
||||
for internal_zone in building.internal_zones:
|
||||
self.assertIsNot(len(internal_zone.usage_zones), 0, 'no building usage_zones defined')
|
||||
for usage_zone in internal_zone.usage_zones:
|
||||
self._check_usage_zone(usage_zone)
|
||||
self.assertIsNotNone(usage_zone.mechanical_air_change, 'mechanical air change is none')
|
||||
self.assertIsNotNone(usage_zone.not_detailed_source_mean_annual_internal_gains,
|
||||
'not detailed internal gains is none')
|
||||
|
||||
def test_import_hft(self):
|
||||
"""
|
||||
Enrich the city with the usage information from hft and verify it
|
||||
"""
|
||||
file = 'pluto_building.gml'
|
||||
city = self._get_citygml(file)
|
||||
for building in city.buildings:
|
||||
building.function = GeometryHelper.libs_function_from_pluto(building.function)
|
||||
|
||||
UsageFactory('hft', city).enrich()
|
||||
self._check_buildings(city)
|
||||
for building in city.buildings:
|
||||
for internal_zone in building.internal_zones:
|
||||
self.assertIsNot(len(internal_zone.usage_zones), 0, 'no building usage_zones defined')
|
||||
for usage_zone in internal_zone.usage_zones:
|
||||
self._check_usage_zone(usage_zone)
|
||||
self.assertIsNone(usage_zone.mechanical_air_change, 'mechanical air change is not none')
|
||||
self.assertIsNotNone(usage_zone.thermal_control.heating_set_point_schedules,
|
||||
'control heating set point schedule is none')
|
||||
self.assertIsNotNone(usage_zone.thermal_control.cooling_set_point_schedules,
|
||||
'control cooling set point schedule is none')
|
||||
self.assertIsNotNone(usage_zone.occupancy, 'occupancy is none')
|
||||
occupancy = usage_zone.occupancy
|
||||
self.assertIsNotNone(occupancy.occupancy_density, 'occupancy density is none')
|
||||
self.assertIsNone(occupancy.latent_internal_gain, 'occupancy latent internal gain is none')
|
||||
self.assertIsNone(occupancy.sensible_convective_internal_gain,
|
||||
'occupancy sensible convective internal gain is not none')
|
||||
self.assertIsNone(occupancy.sensible_radiative_internal_gain,
|
||||
'occupancy sensible radiant internal gain is not none')
|
||||
self.assertIsNone(occupancy.occupancy_schedules, 'occupancy schedule is not none')
|
||||
self.assertIsNone(occupancy.occupants, 'occupancy density is not none')
|
||||
self.assertIsNone(usage_zone.lighting, 'lighting is not none')
|
||||
self.assertIsNone(usage_zone.appliances, 'appliances is not none')
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user