Merge branch 'master' of https://rs-loy-gitlab.concordia.ca/Guille/libs
This commit is contained in:
commit
fdbf1817c3
32
catalogs/catalog.py
Normal file
32
catalogs/catalog.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
"""
|
||||
Catalog base class
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
class Catalog:
|
||||
"""
|
||||
Catalog name
|
||||
"""
|
||||
|
||||
@property
|
||||
def names(self):
|
||||
"""
|
||||
Base property to return the catalog entries names
|
||||
:return: not implemented error
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def entries(self, category=None):
|
||||
"""
|
||||
Base property to return the catalog entries
|
||||
:return: not implemented error
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_entry(self, name):
|
||||
"""
|
||||
Base property to return the catalog entry matching the given name
|
||||
:return: not implemented error
|
||||
"""
|
||||
raise NotImplementedError
|
33
catalogs/data_model/greenery/greenery_content.py
Normal file
33
catalogs/data_model/greenery/greenery_content.py
Normal file
|
@ -0,0 +1,33 @@
|
|||
"""
|
||||
Greenery catalog content
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
class GreeneryContent:
|
||||
def __init__(self, vegetations, plants, soils):
|
||||
self._vegetations = vegetations
|
||||
self._plants = plants
|
||||
self._soils = soils
|
||||
|
||||
@property
|
||||
def vegetations(self):
|
||||
"""
|
||||
All vegetation in the catalog
|
||||
"""
|
||||
return self._vegetations
|
||||
|
||||
@property
|
||||
def plants(self):
|
||||
"""
|
||||
All plants in the catalog
|
||||
"""
|
||||
return self._plants
|
||||
|
||||
@property
|
||||
def soils(self):
|
||||
"""
|
||||
All soils in the catalog
|
||||
"""
|
||||
return self._soils
|
||||
|
85
catalogs/data_model/greenery/plant.py
Normal file
85
catalogs/data_model/greenery/plant.py
Normal file
|
@ -0,0 +1,85 @@
|
|||
"""
|
||||
Greenery catalog data model Plant class
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
from catalogs.data_model.greenery.soil import Soil as libs_soil
|
||||
|
||||
|
||||
class Plant:
|
||||
def __init__(self, category, plant):
|
||||
self._name = plant.name
|
||||
self._category = category
|
||||
self._height = plant.height
|
||||
self._leaf_area_index = plant.leafAreaIndex
|
||||
self._leaf_reflectivity = plant.leafReflectivity
|
||||
self._leaf_emissivity = plant.leafEmissivity
|
||||
self._minimal_stomatal_resistance = plant.minimalStomatalResistance
|
||||
self._co2_sequestration = plant.co2Sequestration
|
||||
self._grows_on = []
|
||||
for soil in plant.growsOn:
|
||||
self._grows_on.append(libs_soil(soil))
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""
|
||||
Get plant name
|
||||
"""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def category(self):
|
||||
"""
|
||||
Get plant category name
|
||||
"""
|
||||
return self._category
|
||||
|
||||
@property
|
||||
def height(self):
|
||||
"""
|
||||
Get plant height
|
||||
"""
|
||||
return self._height
|
||||
|
||||
@property
|
||||
def leaf_area_index(self):
|
||||
"""
|
||||
Get plant leaf area index
|
||||
"""
|
||||
return self._leaf_area_index
|
||||
|
||||
@property
|
||||
def leaf_reflectivity(self):
|
||||
"""
|
||||
Get plant leaf area index
|
||||
"""
|
||||
return self._leaf_reflectivity
|
||||
|
||||
@property
|
||||
def leaf_emissivity(self):
|
||||
"""
|
||||
Get plant leaf emissivity
|
||||
"""
|
||||
return self._leaf_emissivity
|
||||
|
||||
@property
|
||||
def minimal_stomatal_resistance(self):
|
||||
"""
|
||||
Get plant minimal stomatal resistance
|
||||
"""
|
||||
return self._minimal_stomatal_resistance
|
||||
|
||||
@property
|
||||
def co2_sequestration(self):
|
||||
"""
|
||||
Get plant co2 sequestration capacity
|
||||
"""
|
||||
return self._co2_sequestration
|
||||
|
||||
@property
|
||||
def grows_on(self) -> [libs_soil]:
|
||||
"""
|
||||
Get plant compatible soils
|
||||
"""
|
||||
return self._grows_on
|
17
catalogs/data_model/greenery/plant_percentage.py
Normal file
17
catalogs/data_model/greenery/plant_percentage.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
"""
|
||||
Greenery catalog data model Plant percentage class
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
from catalogs.data_model.greenery.plant import Plant as libs_plant
|
||||
|
||||
class PlantPercentage(libs_plant):
|
||||
|
||||
def __init__(self, percentage, plant_category, plant):
|
||||
super().__init__(plant_category, plant)
|
||||
self._percentage = percentage
|
||||
|
||||
@property
|
||||
def percentage(self):
|
||||
return self._percentage
|
96
catalogs/data_model/greenery/soil.py
Normal file
96
catalogs/data_model/greenery/soil.py
Normal file
|
@ -0,0 +1,96 @@
|
|||
"""
|
||||
Greenery catalog data model Soil class
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
class Soil:
|
||||
def __init__(self, soil):
|
||||
self._name = soil.name
|
||||
self._roughness = soil.roughness
|
||||
self._dry_conductivity = soil.conductivityOfDrySoil
|
||||
self._dry_density = soil.densityOfDrySoil
|
||||
self._dry_specific_heat = soil.specificHeatOfDrySoil
|
||||
self._thermal_absorptance = soil.thermalAbsorptance
|
||||
self._solar_absorptance = soil.solarAbsorptance
|
||||
self._visible_absorptance = soil.visibleAbsorptance
|
||||
self._saturation_volumetric_moisture_content = soil.saturationVolumetricMoistureContent
|
||||
self._residual_volumetric_moisture_content = soil.residualVolumetricMoistureContent
|
||||
self._initial_volumetric_moisture_content = soil.initialVolumetricMoistureContent
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""
|
||||
Get soil name
|
||||
"""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def roughness(self):
|
||||
"""
|
||||
Get soil roughness
|
||||
"""
|
||||
return self._roughness
|
||||
|
||||
@property
|
||||
def dry_conductivity(self):
|
||||
"""
|
||||
Get soil dry conductivity
|
||||
"""
|
||||
return self._dry_conductivity
|
||||
|
||||
@property
|
||||
def dry_density(self):
|
||||
"""
|
||||
Get soil dry density
|
||||
"""
|
||||
return self._dry_density
|
||||
|
||||
@property
|
||||
def dry_specific_heat(self):
|
||||
"""
|
||||
Get soil dry specific heat
|
||||
"""
|
||||
return self._dry_specific_heat
|
||||
|
||||
@property
|
||||
def thermal_absorptance(self):
|
||||
"""
|
||||
Get soil thermal absortance
|
||||
"""
|
||||
return self._thermal_absorptance
|
||||
|
||||
@property
|
||||
def solar_absorptance(self):
|
||||
"""
|
||||
Get soil solar absortance
|
||||
"""
|
||||
return self._solar_absorptance
|
||||
|
||||
@property
|
||||
def visible_absorptance(self):
|
||||
"""
|
||||
Get soil visible absortance
|
||||
"""
|
||||
return self._visible_absorptance
|
||||
|
||||
@property
|
||||
def saturation_volumetric_moisture_content(self):
|
||||
"""
|
||||
Get soil saturation volumetric moisture content
|
||||
"""
|
||||
return self._saturation_volumetric_moisture_content
|
||||
|
||||
@property
|
||||
def residual_volumetric_moisture_content(self):
|
||||
"""
|
||||
Get soil residual volumetric moisture content
|
||||
"""
|
||||
return self._residual_volumetric_moisture_content
|
||||
|
||||
@property
|
||||
def initial_volumetric_moisture_content(self):
|
||||
"""
|
||||
Get soil initial volumetric moisture content
|
||||
"""
|
||||
return self._initial_volumetric_moisture_content
|
151
catalogs/data_model/greenery/vegetation.py
Normal file
151
catalogs/data_model/greenery/vegetation.py
Normal file
|
@ -0,0 +1,151 @@
|
|||
"""
|
||||
Greenery catalog data model Vegetation class
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
from catalogs.data_model.greenery.plant_percentage import PlantPercentage
|
||||
|
||||
class Vegetation:
|
||||
def __init__(self, category, vegetation, plant_percentages):
|
||||
self._name = vegetation.name
|
||||
self._category = category
|
||||
self._soil_thickness = vegetation.thicknessOfSoil
|
||||
self._management = vegetation.management
|
||||
self._air_gap = vegetation.airGap
|
||||
self._soil_name = vegetation.soil.name
|
||||
self._soil_roughness = vegetation.soil.roughness
|
||||
self._dry_soil_conductivity = vegetation.soil.conductivityOfDrySoil
|
||||
self._dry_soil_density = vegetation.soil.densityOfDrySoil
|
||||
self._dry_soil_specific_heat = vegetation.soil.specificHeatOfDrySoil
|
||||
self._soil_thermal_absorptance = vegetation.soil.thermalAbsorptance
|
||||
self._soil_solar_absorptance = vegetation.soil.solarAbsorptance
|
||||
self._soil_visible_absorptance = vegetation.soil.visibleAbsorptance
|
||||
self._soil_saturation_volumetric_moisture_content = vegetation.soil.saturationVolumetricMoistureContent
|
||||
self._soil_residual_volumetric_moisture_content = vegetation.soil.residualVolumetricMoistureContent
|
||||
self._soil_initial_volumetric_moisture_content = vegetation.soil.initialVolumetricMoistureContent
|
||||
self._plant_percentages = plant_percentages
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""
|
||||
Get vegetation name
|
||||
"""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def category(self):
|
||||
"""
|
||||
Get vegetation category
|
||||
"""
|
||||
return self._category
|
||||
|
||||
@property
|
||||
def soil_thickness(self):
|
||||
"""
|
||||
Get soil thickness
|
||||
"""
|
||||
return self._soil_thickness
|
||||
|
||||
@property
|
||||
def management(self):
|
||||
"""
|
||||
Get management
|
||||
"""
|
||||
return self._management
|
||||
|
||||
@property
|
||||
def air_gap(self):
|
||||
"""
|
||||
Get air gap
|
||||
"""
|
||||
return self._air_gap
|
||||
|
||||
@property
|
||||
def plant_percentages(self) -> [PlantPercentage]:
|
||||
"""
|
||||
Get plant percentages
|
||||
"""
|
||||
percentage = 0.0
|
||||
for plant_percentage in self._plant_percentages:
|
||||
percentage += float(plant_percentage.percentage)
|
||||
if percentage > 100:
|
||||
raise ValueError('the plant percentage in this vegetation is over 100%')
|
||||
return self._plant_percentages
|
||||
|
||||
@property
|
||||
def soil_name(self):
|
||||
"""
|
||||
Get soil name
|
||||
"""
|
||||
return self._soil_name
|
||||
|
||||
@property
|
||||
def soil_roughness(self):
|
||||
"""
|
||||
Get soil roughness
|
||||
"""
|
||||
return self._soil_roughness
|
||||
|
||||
@property
|
||||
def dry_soil_conductivity(self):
|
||||
"""
|
||||
Get soil dry conductivity
|
||||
"""
|
||||
return self._dry_soil_conductivity
|
||||
|
||||
@property
|
||||
def dry_soil_density(self):
|
||||
"""
|
||||
Get soil dry density
|
||||
"""
|
||||
return self._dry_soil_density
|
||||
|
||||
@property
|
||||
def dry_soil_specific_heat(self):
|
||||
"""
|
||||
Get soil dry specific heat
|
||||
"""
|
||||
return self._dry_soil_specific_heat
|
||||
|
||||
@property
|
||||
def soil_thermal_absorptance(self):
|
||||
"""
|
||||
Get soil thermal absortance
|
||||
"""
|
||||
return self._soil_thermal_absorptance
|
||||
|
||||
@property
|
||||
def soil_solar_absorptance(self):
|
||||
"""
|
||||
Get soil solar absortance
|
||||
"""
|
||||
return self._soil_solar_absorptance
|
||||
|
||||
@property
|
||||
def soil_visible_absorptance(self):
|
||||
"""
|
||||
Get soil visible absortance
|
||||
"""
|
||||
return self._soil_visible_absorptance
|
||||
|
||||
@property
|
||||
def soil_saturation_volumetric_moisture_content(self):
|
||||
"""
|
||||
Get soil saturation volumetric moisture content
|
||||
"""
|
||||
return self._soil_saturation_volumetric_moisture_content
|
||||
|
||||
@property
|
||||
def soil_residual_volumetric_moisture_content(self):
|
||||
"""
|
||||
Get soil residual volumetric moisture content
|
||||
"""
|
||||
return self._soil_residual_volumetric_moisture_content
|
||||
|
||||
@property
|
||||
def soil_initial_volumetric_moisture_content(self):
|
||||
"""
|
||||
Get soil initial volumetric moisture content
|
||||
"""
|
||||
return self._soil_initial_volumetric_moisture_content
|
268
catalogs/greenery/ecore_greenery/greenerycatalog.ecore
Normal file
268
catalogs/greenery/ecore_greenery/greenerycatalog.ecore
Normal file
|
@ -0,0 +1,268 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="greenerycatalog" nsURI="http://ca.concordia/greenerycatalog"
|
||||
nsPrefix="greenery">
|
||||
<eClassifiers xsi:type="ecore:EClass" name="Soil">
|
||||
<eAnnotations source="http://www.eclipse.org/emf/2002/Ecore">
|
||||
<details key="constraints" value="nonNegative"/>
|
||||
</eAnnotations>
|
||||
<eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
|
||||
defaultValueLiteral=""/>
|
||||
<eStructuralFeatures xsi:type="ecore:EAttribute" name="roughness" eType="#//Roughness"
|
||||
defaultValueLiteral="MediumRough">
|
||||
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
|
||||
<details key="documentation" value="defines the relative roughness of a particular material layer. This parameter only influences the convection coefficients, more specifically the exterior convection coefficient. A nominal value is expected in with the options being "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>
|
318
catalogs/greenery/ecore_greenery/greenerycatalog.py
Normal file
318
catalogs/greenery/ecore_greenery/greenerycatalog.py
Normal file
|
@ -0,0 +1,318 @@
|
|||
"""Definition of meta model 'greenerycatalog'."""
|
||||
from functools import partial
|
||||
import pyecore.ecore as Ecore
|
||||
from pyecore.ecore import *
|
||||
|
||||
|
||||
name = 'greenerycatalog'
|
||||
nsURI = 'http://ca.concordia/greenerycatalog'
|
||||
nsPrefix = 'greenery'
|
||||
|
||||
eClass = EPackage(name=name, nsURI=nsURI, nsPrefix=nsPrefix)
|
||||
|
||||
eClassifiers = {}
|
||||
getEClassifier = partial(Ecore.getEClassifier, searchspace=eClassifiers)
|
||||
Management = EEnum('Management', literals=['Intensive', 'Extensive', 'SemiIntensive', 'NA'])
|
||||
|
||||
Roughness = EEnum('Roughness', literals=['VeryRough', 'Rough',
|
||||
'MediumRough', 'MediumSmooth', 'Smooth', 'VerySmooth'])
|
||||
|
||||
|
||||
class Soil(EObject, metaclass=MetaEClass):
|
||||
|
||||
name = EAttribute(eType=EString, unique=True, derived=False, changeable=True)
|
||||
roughness = EAttribute(eType=Roughness, unique=True, derived=False,
|
||||
changeable=True, default_value=Roughness.MediumRough)
|
||||
conductivityOfDrySoil = EAttribute(
|
||||
eType=EString, unique=True, derived=False, changeable=True, default_value='1.0 W/(m*K)')
|
||||
densityOfDrySoil = EAttribute(eType=EString, unique=True, derived=False,
|
||||
changeable=True, default_value='1100 kg/m³')
|
||||
specificHeatOfDrySoil = EAttribute(
|
||||
eType=EString, unique=True, derived=False, changeable=True, default_value='1200 J/(kg*K)')
|
||||
thermalAbsorptance = EAttribute(eType=EString, unique=True,
|
||||
derived=False, changeable=True, default_value='0.9')
|
||||
solarAbsorptance = EAttribute(eType=EString, unique=True,
|
||||
derived=False, changeable=True, default_value='0.7')
|
||||
visibleAbsorptance = EAttribute(eType=EString, unique=True,
|
||||
derived=False, changeable=True, default_value='0.75')
|
||||
saturationVolumetricMoistureContent = EAttribute(
|
||||
eType=EString, unique=True, derived=False, changeable=True, default_value='0.0')
|
||||
residualVolumetricMoistureContent = EAttribute(
|
||||
eType=EString, unique=True, derived=False, changeable=True, default_value='0.05')
|
||||
initialVolumetricMoistureContent = EAttribute(
|
||||
eType=EString, unique=True, derived=False, changeable=True, default_value='0.1')
|
||||
|
||||
def __init__(self, *, name=None, roughness=None, conductivityOfDrySoil=None, densityOfDrySoil=None, specificHeatOfDrySoil=None, thermalAbsorptance=None, solarAbsorptance=None, visibleAbsorptance=None, saturationVolumetricMoistureContent=None, residualVolumetricMoistureContent=None, initialVolumetricMoistureContent=None):
|
||||
# if kwargs:
|
||||
# raise AttributeError('unexpected arguments: {}'.format(kwargs))
|
||||
|
||||
super().__init__()
|
||||
|
||||
if name is not None:
|
||||
self.name = name
|
||||
|
||||
if roughness is not None:
|
||||
self.roughness = roughness
|
||||
|
||||
if conductivityOfDrySoil is not None:
|
||||
self.conductivityOfDrySoil = conductivityOfDrySoil
|
||||
|
||||
if densityOfDrySoil is not None:
|
||||
self.densityOfDrySoil = densityOfDrySoil
|
||||
|
||||
if specificHeatOfDrySoil is not None:
|
||||
self.specificHeatOfDrySoil = specificHeatOfDrySoil
|
||||
|
||||
if thermalAbsorptance is not None:
|
||||
self.thermalAbsorptance = thermalAbsorptance
|
||||
|
||||
if solarAbsorptance is not None:
|
||||
self.solarAbsorptance = solarAbsorptance
|
||||
|
||||
if visibleAbsorptance is not None:
|
||||
self.visibleAbsorptance = visibleAbsorptance
|
||||
|
||||
if saturationVolumetricMoistureContent is not None:
|
||||
self.saturationVolumetricMoistureContent = saturationVolumetricMoistureContent
|
||||
|
||||
if residualVolumetricMoistureContent is not None:
|
||||
self.residualVolumetricMoistureContent = residualVolumetricMoistureContent
|
||||
|
||||
if initialVolumetricMoistureContent is not None:
|
||||
self.initialVolumetricMoistureContent = initialVolumetricMoistureContent
|
||||
|
||||
|
||||
class Plant(EObject, metaclass=MetaEClass):
|
||||
|
||||
name = EAttribute(eType=EString, unique=True, derived=False, changeable=True)
|
||||
height = EAttribute(eType=EString, unique=True, derived=False,
|
||||
changeable=True, default_value='0.1 m')
|
||||
leafAreaIndex = EAttribute(eType=EString, unique=True, derived=False,
|
||||
changeable=True, default_value='2.5')
|
||||
leafReflectivity = EAttribute(eType=EString, unique=True,
|
||||
derived=False, changeable=True, default_value='0.1')
|
||||
leafEmissivity = EAttribute(eType=EString, unique=True, derived=False,
|
||||
changeable=True, default_value='0.9')
|
||||
minimalStomatalResistance = EAttribute(
|
||||
eType=EString, unique=True, derived=False, changeable=True, default_value='100.0 s/m')
|
||||
co2Sequestration = EAttribute(eType=EString, unique=True, derived=False,
|
||||
changeable=True, default_value='kgCO₂eq')
|
||||
growsOn = EReference(ordered=True, unique=True, containment=False, derived=False, upper=-1)
|
||||
|
||||
def __init__(self, *, name=None, height=None, leafAreaIndex=None, leafReflectivity=None, leafEmissivity=None, minimalStomatalResistance=None, growsOn=None, co2Sequestration=None):
|
||||
# if kwargs:
|
||||
# raise AttributeError('unexpected arguments: {}'.format(kwargs))
|
||||
|
||||
super().__init__()
|
||||
|
||||
if name is not None:
|
||||
self.name = name
|
||||
|
||||
if height is not None:
|
||||
self.height = height
|
||||
|
||||
if leafAreaIndex is not None:
|
||||
self.leafAreaIndex = leafAreaIndex
|
||||
|
||||
if leafReflectivity is not None:
|
||||
self.leafReflectivity = leafReflectivity
|
||||
|
||||
if leafEmissivity is not None:
|
||||
self.leafEmissivity = leafEmissivity
|
||||
|
||||
if minimalStomatalResistance is not None:
|
||||
self.minimalStomatalResistance = minimalStomatalResistance
|
||||
|
||||
if co2Sequestration is not None:
|
||||
self.co2Sequestration = co2Sequestration
|
||||
|
||||
if growsOn:
|
||||
self.growsOn.extend(growsOn)
|
||||
|
||||
|
||||
class SupportEnvelope(EObject, metaclass=MetaEClass):
|
||||
|
||||
roughness = EAttribute(eType=Roughness, unique=True, derived=False,
|
||||
changeable=True, default_value=Roughness.MediumRough)
|
||||
solarAbsorptance = EAttribute(eType=EDouble, unique=True,
|
||||
derived=False, changeable=True, default_value=0.0)
|
||||
conductivity = EAttribute(eType=EDouble, unique=True, derived=False,
|
||||
changeable=True, default_value=0.0)
|
||||
visibleAbsorptance = EAttribute(eType=EDouble, unique=True,
|
||||
derived=False, changeable=True, default_value=0.0)
|
||||
specificHeat = EAttribute(eType=EDouble, unique=True, derived=False,
|
||||
changeable=True, default_value=0.0)
|
||||
density = EAttribute(eType=EDouble, unique=True, derived=False,
|
||||
changeable=True, default_value=0.0)
|
||||
thermalAbsorptance = EAttribute(eType=EDouble, unique=True,
|
||||
derived=False, changeable=True, default_value=0.0)
|
||||
|
||||
def __init__(self, *, roughness=None, solarAbsorptance=None, conductivity=None, visibleAbsorptance=None, specificHeat=None, density=None, thermalAbsorptance=None):
|
||||
# if kwargs:
|
||||
# raise AttributeError('unexpected arguments: {}'.format(kwargs))
|
||||
|
||||
super().__init__()
|
||||
|
||||
if roughness is not None:
|
||||
self.roughness = roughness
|
||||
|
||||
if solarAbsorptance is not None:
|
||||
self.solarAbsorptance = solarAbsorptance
|
||||
|
||||
if conductivity is not None:
|
||||
self.conductivity = conductivity
|
||||
|
||||
if visibleAbsorptance is not None:
|
||||
self.visibleAbsorptance = visibleAbsorptance
|
||||
|
||||
if specificHeat is not None:
|
||||
self.specificHeat = specificHeat
|
||||
|
||||
if density is not None:
|
||||
self.density = density
|
||||
|
||||
if thermalAbsorptance is not None:
|
||||
self.thermalAbsorptance = thermalAbsorptance
|
||||
|
||||
|
||||
class GreeneryCatalog(EObject, metaclass=MetaEClass):
|
||||
|
||||
name = EAttribute(eType=EString, unique=True, derived=False, changeable=True)
|
||||
description = EAttribute(eType=EString, unique=True, derived=False, changeable=True)
|
||||
source = EAttribute(eType=EString, unique=True, derived=False, changeable=True)
|
||||
plantCategories = EReference(ordered=True, unique=True,
|
||||
containment=True, derived=False, upper=-1)
|
||||
vegetationCategories = EReference(ordered=True, unique=True,
|
||||
containment=True, derived=False, upper=-1)
|
||||
soils = EReference(ordered=True, unique=True, containment=True, derived=False, upper=-1)
|
||||
|
||||
def __init__(self, *, name=None, description=None, source=None, plantCategories=None, vegetationCategories=None, soils=None):
|
||||
# if kwargs:
|
||||
# raise AttributeError('unexpected arguments: {}'.format(kwargs))
|
||||
|
||||
super().__init__()
|
||||
|
||||
if name is not None:
|
||||
self.name = name
|
||||
|
||||
if description is not None:
|
||||
self.description = description
|
||||
|
||||
if source is not None:
|
||||
self.source = source
|
||||
|
||||
if plantCategories:
|
||||
self.plantCategories.extend(plantCategories)
|
||||
|
||||
if vegetationCategories:
|
||||
self.vegetationCategories.extend(vegetationCategories)
|
||||
|
||||
if soils:
|
||||
self.soils.extend(soils)
|
||||
|
||||
|
||||
class PlantCategory(EObject, metaclass=MetaEClass):
|
||||
"""Excluding (that is non-overlapping) categories like Trees, Hedeges, Grasses that help users finding a specific biol. plant species."""
|
||||
name = EAttribute(eType=EString, unique=True, derived=False, changeable=True)
|
||||
plants = EReference(ordered=True, unique=True, containment=True, derived=False, upper=-1)
|
||||
|
||||
def __init__(self, *, name=None, plants=None):
|
||||
# if kwargs:
|
||||
# raise AttributeError('unexpected arguments: {}'.format(kwargs))
|
||||
|
||||
super().__init__()
|
||||
|
||||
if name is not None:
|
||||
self.name = name
|
||||
|
||||
if plants:
|
||||
self.plants.extend(plants)
|
||||
|
||||
|
||||
class IrrigationSchedule(EObject, metaclass=MetaEClass):
|
||||
|
||||
name = EAttribute(eType=EString, unique=True, derived=False, changeable=True)
|
||||
|
||||
def __init__(self, *, name=None):
|
||||
# if kwargs:
|
||||
# raise AttributeError('unexpected arguments: {}'.format(kwargs))
|
||||
|
||||
super().__init__()
|
||||
|
||||
if name is not None:
|
||||
self.name = name
|
||||
|
||||
|
||||
class Vegetation(EObject, metaclass=MetaEClass):
|
||||
"""Plant life or total plant cover (as of an area)"""
|
||||
name = EAttribute(eType=EString, unique=True, derived=False, changeable=True)
|
||||
thicknessOfSoil = EAttribute(eType=EString, unique=True, derived=False,
|
||||
changeable=True, default_value='20 cm')
|
||||
management = EAttribute(eType=Management, unique=True, derived=False,
|
||||
changeable=True, default_value=Management.NA)
|
||||
airGap = EAttribute(eType=EString, unique=True, derived=False,
|
||||
changeable=True, default_value='0.0 cm')
|
||||
soil = EReference(ordered=True, unique=True, containment=False, derived=False)
|
||||
plants = EReference(ordered=True, unique=True, containment=True, derived=False, upper=-1)
|
||||
|
||||
def __init__(self, *, name=None, thicknessOfSoil=None, soil=None, plants=None, management=None, airGap=None):
|
||||
# if kwargs:
|
||||
# raise AttributeError('unexpected arguments: {}'.format(kwargs))
|
||||
|
||||
super().__init__()
|
||||
|
||||
if name is not None:
|
||||
self.name = name
|
||||
|
||||
if thicknessOfSoil is not None:
|
||||
self.thicknessOfSoil = thicknessOfSoil
|
||||
|
||||
if management is not None:
|
||||
self.management = management
|
||||
|
||||
if airGap is not None:
|
||||
self.airGap = airGap
|
||||
|
||||
if soil is not None:
|
||||
self.soil = soil
|
||||
|
||||
if plants:
|
||||
self.plants.extend(plants)
|
||||
|
||||
|
||||
class VegetationCategory(EObject, metaclass=MetaEClass):
|
||||
"""Excluding (that is non-overlapping) categories to help users finding a specific vegetation template."""
|
||||
name = EAttribute(eType=EString, unique=True, derived=False, changeable=True)
|
||||
vegetationTemplates = EReference(ordered=True, unique=True,
|
||||
containment=True, derived=False, upper=-1)
|
||||
|
||||
def __init__(self, *, vegetationTemplates=None, name=None):
|
||||
# if kwargs:
|
||||
# raise AttributeError('unexpected arguments: {}'.format(kwargs))
|
||||
|
||||
super().__init__()
|
||||
|
||||
if name is not None:
|
||||
self.name = name
|
||||
|
||||
if vegetationTemplates:
|
||||
self.vegetationTemplates.extend(vegetationTemplates)
|
||||
|
||||
|
||||
class PlantPercentage(EObject, metaclass=MetaEClass):
|
||||
|
||||
percentage = EAttribute(eType=EString, unique=True, derived=False,
|
||||
changeable=True, default_value='100')
|
||||
plant = EReference(ordered=True, unique=True, containment=False, derived=False)
|
||||
|
||||
def __init__(self, *, percentage=None, plant=None):
|
||||
# if kwargs:
|
||||
# raise AttributeError('unexpected arguments: {}'.format(kwargs))
|
||||
|
||||
super().__init__()
|
||||
|
||||
if percentage is not None:
|
||||
self.percentage = percentage
|
||||
|
||||
if plant is not None:
|
||||
self.plant = plant
|
|
@ -0,0 +1,268 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="greenerycatalog" nsURI="http://ca.concordia/greenerycatalog"
|
||||
nsPrefix="greenery">
|
||||
<eClassifiers xsi:type="ecore:EClass" name="Soil">
|
||||
<eAnnotations source="http://www.eclipse.org/emf/2002/Ecore">
|
||||
<details key="constraints" value="nonNegative"/>
|
||||
</eAnnotations>
|
||||
<eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
|
||||
defaultValueLiteral=""/>
|
||||
<eStructuralFeatures xsi:type="ecore:EAttribute" name="roughness" eType="#//Roughness"
|
||||
defaultValueLiteral="MediumRough">
|
||||
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
|
||||
<details key="documentation" value="defines the relative roughness of a particular material layer. This parameter only influences the convection coefficients, more specifically the exterior convection coefficient. A nominal value is expected in with the options being "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>
|
115
catalogs/greenery/greenery_catalog.py
Normal file
115
catalogs/greenery/greenery_catalog.py
Normal file
|
@ -0,0 +1,115 @@
|
|||
"""
|
||||
Greenery catalog
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
from pyecore.resources import ResourceSet, URI
|
||||
from catalogs.greenery.ecore_greenery.greenerycatalog import GreeneryCatalog as gc
|
||||
from catalogs.catalog import Catalog
|
||||
from pathlib import Path
|
||||
from catalogs.data_model.greenery.vegetation import Vegetation as libs_vegetation
|
||||
from catalogs.data_model.greenery.plant import Plant as libs_plant
|
||||
from catalogs.data_model.greenery.soil import Soil as libs_soil
|
||||
from catalogs.data_model.greenery.plant_percentage import PlantPercentage as libs_pp
|
||||
from catalogs.data_model.greenery.greenery_content import GreeneryContent
|
||||
|
||||
|
||||
class GreeneryCatalog(Catalog):
|
||||
|
||||
def __init__(self, path):
|
||||
base_path = Path(Path(__file__).parent / 'ecore_greenery' / 'greenerycatalog_no_quantities.ecore')
|
||||
resource_set = ResourceSet()
|
||||
data_model = resource_set.get_resource(URI(str(base_path)))
|
||||
data_model_root = data_model.contents[0]
|
||||
resource_set.metamodel_registry[data_model_root.nsURI] = data_model_root
|
||||
resource = resource_set.get_resource(URI(str(path)))
|
||||
catalog_data: gc = resource.contents[0]
|
||||
|
||||
plants = []
|
||||
for plant_category in catalog_data.plantCategories:
|
||||
name = plant_category.name
|
||||
for plant in plant_category.plants:
|
||||
plants.append(libs_plant(name, plant))
|
||||
|
||||
vegetations = []
|
||||
for vegetation_category in catalog_data.vegetationCategories:
|
||||
name = vegetation_category.name
|
||||
for vegetation in vegetation_category.vegetationTemplates:
|
||||
plant_percentages = []
|
||||
|
||||
for plant_percentage in vegetation.plants:
|
||||
plant_category = "Unknown"
|
||||
for plant in plants:
|
||||
if plant.name == plant_percentage.plant.name:
|
||||
plant_category = plant.category
|
||||
break
|
||||
plant_percentages.append(libs_pp(plant_percentage.percentage,plant_category, plant_percentage.plant))
|
||||
vegetations.append(libs_vegetation(name, vegetation, plant_percentages))
|
||||
plants = []
|
||||
for plant_category in catalog_data.plantCategories:
|
||||
name = plant_category.name
|
||||
for plant in plant_category.plants:
|
||||
plants.append(libs_plant(name, plant))
|
||||
|
||||
soils = []
|
||||
for soil in catalog_data.soils:
|
||||
soils.append(libs_soil(soil))
|
||||
|
||||
self._data = GreeneryContent(vegetations, plants, soils)
|
||||
|
||||
def names(self, category=None):
|
||||
"""
|
||||
Get the catalog elements names
|
||||
:parm: optional category filter
|
||||
"""
|
||||
if category is None:
|
||||
_names = {'vegetations': [], 'plants': [], 'soils': []}
|
||||
for vegetation in self._data.vegetations:
|
||||
_names['vegetations'].append(vegetation.name)
|
||||
for plant in self._data.plants:
|
||||
_names['plants'].append(plant.name)
|
||||
for soil in self._data.soils:
|
||||
_names['soils'].append(soil.name)
|
||||
else:
|
||||
_names = {category: []}
|
||||
if category.lower() == 'vegetations':
|
||||
for vegetation in self._data.vegetations:
|
||||
_names[category].append(vegetation.name)
|
||||
elif category.lower() == 'plants':
|
||||
for plant in self._data.plants:
|
||||
_names[category].append(plant.name)
|
||||
elif category.lower() == 'soils':
|
||||
for soil in self._data.soils:
|
||||
_names[category].append(soil.name)
|
||||
else:
|
||||
raise ValueError(f'Unknown category [{category}]')
|
||||
return _names
|
||||
|
||||
def get_entry(self, name):
|
||||
"""
|
||||
Get one complete entry from the greenery catalog
|
||||
"""
|
||||
for entry in self._data.vegetations:
|
||||
if entry.name.lower() == name.lower():
|
||||
return entry
|
||||
for entry in self._data.plants:
|
||||
if entry.name.lower() == name.lower():
|
||||
return entry
|
||||
for entry in self._data.soils:
|
||||
if entry.name.lower() == name.lower():
|
||||
return entry
|
||||
raise IndexError(f"{name} doesn't exists in the catalog")
|
||||
|
||||
def entries(self, category=None):
|
||||
if category is None:
|
||||
return self._data
|
||||
else:
|
||||
if category.lower() == 'vegetations':
|
||||
return self._data.vegetations
|
||||
elif category.lower() == 'plants':
|
||||
return self._data.plants
|
||||
elif category.lower() == 'soils':
|
||||
return self._data.soils
|
||||
else:
|
||||
raise ValueError(f'Unknown category [{category}]')
|
43
catalogs/greenery_catalog_factory.py
Normal file
43
catalogs/greenery_catalog_factory.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
"""
|
||||
Greenery catalog publish the greenery information
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
from catalogs.greenery.greenery_catalog import GreeneryCatalog
|
||||
|
||||
|
||||
class GreeneryCatalogFactory:
|
||||
"""
|
||||
GeometryFactory class
|
||||
"""
|
||||
def __init__(self, file_type, base_path=None):
|
||||
if base_path is None:
|
||||
base_path = Path(Path(__file__).parent.parent / 'data/greenery')
|
||||
self._file_type = '_' + file_type.lower()
|
||||
self._path = base_path
|
||||
|
||||
@property
|
||||
def _nrel(self) -> GreeneryCatalog:
|
||||
"""
|
||||
Return a greenery catalog using ecore as datasource
|
||||
:return: GreeneryCatalog
|
||||
"""
|
||||
return GreeneryCatalog((self._path / 'ecore_greenery_catalog.xml').resolve())
|
||||
|
||||
@property
|
||||
def catalog(self) -> GreeneryCatalog:
|
||||
"""
|
||||
Enrich the city given to the class using the class given handler
|
||||
:return: City
|
||||
"""
|
||||
return getattr(self, self._file_type, lambda: None)
|
||||
|
||||
@property
|
||||
def catalog_debug(self) -> GreeneryCatalog:
|
||||
"""
|
||||
Enrich the city given to the class using the class given handler
|
||||
:return: City
|
||||
"""
|
||||
return GreeneryCatalog((self._path / 'ecore_greenery_catalog.xml').resolve())
|
|
@ -17,10 +17,10 @@ from city_model_structure.building import Building
|
|||
from city_model_structure.city_object import CityObject
|
||||
from city_model_structure.city_objects_cluster import CityObjectsCluster
|
||||
from city_model_structure.buildings_cluster import BuildingsCluster
|
||||
from city_model_structure.parts_consisting_building import PartsConsistingBuilding
|
||||
from city_model_structure.subway_entrance import SubwayEntrance
|
||||
from city_model_structure.fuel import Fuel
|
||||
from city_model_structure.machine import Machine
|
||||
from city_model_structure.parts_consisting_building import PartsConsistingBuilding
|
||||
from city_model_structure.subway_entrance import SubwayEntrance
|
||||
from helpers.geometry_helper import GeometryHelper
|
||||
from helpers.location import Location
|
||||
from city_model_structure.energy_system import EnergySystem
|
||||
|
@ -154,6 +154,9 @@ class City:
|
|||
if self.subway_entrances is not None:
|
||||
for subway_entrance in self.subway_entrances:
|
||||
self._city_objects.append(subway_entrance)
|
||||
if self.energy_systems is not None:
|
||||
for energy_system in self.energy_systems:
|
||||
self._city_objects.append(energy_system)
|
||||
return self._city_objects
|
||||
|
||||
@property
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
"""
|
||||
EnergySystem module
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
Copyright © 2021 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
Contributor Peter Yefi peteryefi@gmail.com
|
||||
"""
|
||||
|
||||
from city_model_structure.city_object import CityObject
|
||||
from city_model_structure.energy_systems.heat_pump import HeatPump
|
||||
from city_model_structure.energy_systems.air_source_hp import AirSourceHP
|
||||
from city_model_structure.energy_systems.water_to_water_hp import WaterToWaterHP
|
||||
|
||||
|
||||
class EnergySystem(CityObject):
|
||||
|
@ -16,25 +17,43 @@ class EnergySystem(CityObject):
|
|||
|
||||
def __init__(self, name, lod, surfaces, city_lower_corner):
|
||||
super().__init__(name, lod, surfaces, city_lower_corner)
|
||||
self._heat_pump = None
|
||||
self._air_source_hp = None
|
||||
self._water_to_water_hp = None
|
||||
self._type = 'energy_system'
|
||||
|
||||
@property
|
||||
def heat_pump(self) -> HeatPump:
|
||||
def air_source_hp(self) -> AirSourceHP:
|
||||
"""
|
||||
Heat pump energy system
|
||||
:return:
|
||||
"""
|
||||
return self._heat_pump
|
||||
return self._air_source_hp
|
||||
|
||||
@heat_pump.setter
|
||||
def heat_pump(self, value):
|
||||
@air_source_hp.setter
|
||||
def air_source_hp(self, value):
|
||||
"""
|
||||
Set heat pumm for energy system
|
||||
:param value: HeatPump
|
||||
Set heat pump for energy system
|
||||
:param value: AirSourceHP
|
||||
"""
|
||||
if self._heat_pump is None:
|
||||
self._heat_pump = value
|
||||
if self._air_source_hp is None:
|
||||
self._air_source_hp = value
|
||||
|
||||
@property
|
||||
def water_to_water_hp(self) -> WaterToWaterHP:
|
||||
"""
|
||||
Water to water heat pump energy system
|
||||
:return:
|
||||
"""
|
||||
return self._water_to_water_hp
|
||||
|
||||
@water_to_water_hp.setter
|
||||
def water_to_water_hp(self, value):
|
||||
"""
|
||||
Set water to water heat pump for energy system
|
||||
:param value: WaterToWaterHP
|
||||
"""
|
||||
if self._water_to_water_hp is None:
|
||||
self._water_to_water_hp = value
|
||||
|
||||
@property
|
||||
def type(self) -> str:
|
||||
|
|
131
city_model_structure/energy_systems/air_source_hp.py
Normal file
131
city_model_structure/energy_systems/air_source_hp.py
Normal file
|
@ -0,0 +1,131 @@
|
|||
"""
|
||||
air_source_hp module defines an air source heat pump
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
Contributor Peter Yefi peteryefi@gmail.com
|
||||
"""
|
||||
|
||||
from typing import List
|
||||
from city_model_structure.energy_systems.heat_pump import HeatPump
|
||||
|
||||
|
||||
class AirSourceHP(HeatPump):
|
||||
"""
|
||||
AirSourceHP class
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._cooling_capacity = None
|
||||
self._cooling_comp_power = None
|
||||
self._cooling_capacity_coff = None # a coefficients for insel
|
||||
self._heating_capacity = None
|
||||
self._heating_comp_power = None
|
||||
self._heating_capacity_coff = None
|
||||
|
||||
@property
|
||||
def cooling_capacity(self) -> List[float]:
|
||||
"""
|
||||
Get cooling capacity in kW
|
||||
:return: [[float]]
|
||||
"""
|
||||
return self._cooling_capacity
|
||||
|
||||
@cooling_capacity.setter
|
||||
def cooling_capacity(self, value):
|
||||
"""
|
||||
Set cooling capacity in kW
|
||||
:param value: [[float]]
|
||||
"""
|
||||
if self._cooling_capacity is None:
|
||||
self._cooling_capacity = value
|
||||
|
||||
@property
|
||||
def cooling_comp_power(self) -> List[float]:
|
||||
"""
|
||||
Get cooling compressor power input in kW
|
||||
:return: [[float]]
|
||||
"""
|
||||
return self._cooling_comp_power
|
||||
|
||||
@cooling_comp_power.setter
|
||||
def cooling_comp_power(self, value):
|
||||
"""
|
||||
Set the cooling compressor in kW
|
||||
:param value: [[float]]
|
||||
:return:
|
||||
"""
|
||||
if self._cooling_comp_power is None:
|
||||
self._cooling_comp_power = value
|
||||
|
||||
@property
|
||||
def cooling_capacity_coff(self) -> List[float]:
|
||||
"""
|
||||
Get cooling capacity coefficients
|
||||
:return: [float]
|
||||
"""
|
||||
return self._cooling_capacity_coff
|
||||
|
||||
@cooling_capacity_coff.setter
|
||||
def cooling_capacity_coff(self, value):
|
||||
"""
|
||||
Set the value for cooling capacity coefficients
|
||||
:param value: [float]
|
||||
:return:
|
||||
"""
|
||||
if self._cooling_capacity_coff is None:
|
||||
self._cooling_capacity_coff = value
|
||||
|
||||
@property
|
||||
def heating_capacity(self) -> List[float]:
|
||||
"""
|
||||
Get heating capacity kW
|
||||
:return: [[float]]
|
||||
"""
|
||||
return self._heating_capacity
|
||||
|
||||
@heating_capacity.setter
|
||||
def heating_capacity(self, value):
|
||||
"""
|
||||
Set the heating capacity in kW
|
||||
:param value: [[float]]
|
||||
:return:
|
||||
"""
|
||||
if self._heating_capacity is None:
|
||||
self._heating_capacity = value
|
||||
|
||||
@property
|
||||
def heating_comp_power(self) -> List[float]:
|
||||
"""
|
||||
Get heating compressor power kW
|
||||
:return: [[float]]
|
||||
"""
|
||||
return self._heating_comp_power
|
||||
|
||||
@heating_comp_power.setter
|
||||
def heating_comp_power(self, value):
|
||||
"""
|
||||
Set the heating compressor power in kW
|
||||
:param value: [[float]]
|
||||
:return:
|
||||
"""
|
||||
if self._heating_comp_power is None:
|
||||
self._heating_comp_power = value
|
||||
|
||||
@property
|
||||
def heating_capacity_coff(self) -> List[float]:
|
||||
"""
|
||||
Get heating capacity coefficients
|
||||
:return: [float]
|
||||
"""
|
||||
return self._heating_capacity_coff
|
||||
|
||||
@heating_capacity_coff.setter
|
||||
def heating_capacity_coff(self, value):
|
||||
"""
|
||||
Set the value for heating capacity coefficients
|
||||
:param value: [float]
|
||||
:return:
|
||||
"""
|
||||
if self._heating_capacity_coff is None:
|
||||
self._heating_capacity_coff = value
|
|
@ -1,13 +1,9 @@
|
|||
"""
|
||||
heat_pump module defines a heat pump
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
Contributor Peter Yefi peteryefi@gmail.com
|
||||
Copyright © 2021 Project Author Peter Yefi peteryefi@gmail.com
|
||||
"""
|
||||
|
||||
from typing import List
|
||||
from typing import Dict
|
||||
|
||||
|
||||
class HeatPump:
|
||||
"""
|
||||
|
@ -16,14 +12,6 @@ class HeatPump:
|
|||
|
||||
def __init__(self):
|
||||
self._model = None
|
||||
self._cooling_capacity = None
|
||||
self._cooling_comp_power = None
|
||||
self._cooling_capacity_coff = None
|
||||
self._cooling_comp_power_coff = None
|
||||
self._heating_capacity = None
|
||||
self._heating_comp_power = None
|
||||
self._heating_capacity_coff = None
|
||||
self._heating_comp_power_coff = None
|
||||
|
||||
@property
|
||||
def model(self) -> str:
|
||||
|
@ -41,150 +29,3 @@ class HeatPump:
|
|||
"""
|
||||
if self._model is None:
|
||||
self._model = value
|
||||
|
||||
@property
|
||||
def cooling_capacity(self) -> List[float]:
|
||||
"""
|
||||
Get cooling capacity in kW
|
||||
:return: [[float]]
|
||||
"""
|
||||
return self._cooling_capacity
|
||||
|
||||
@cooling_capacity.setter
|
||||
def cooling_capacity(self, value):
|
||||
"""
|
||||
Set cooling capacity in kW
|
||||
:param value: [[float]]
|
||||
"""
|
||||
if self._cooling_capacity is None:
|
||||
self._cooling_capacity = value
|
||||
|
||||
@property
|
||||
def cooling_comp_power(self) -> List[float]:
|
||||
"""
|
||||
Get cooling compressor power input in kW
|
||||
:return: [[float]]
|
||||
"""
|
||||
return self._cooling_comp_power
|
||||
|
||||
@cooling_comp_power.setter
|
||||
def cooling_comp_power(self, value):
|
||||
"""
|
||||
Set the cooling compressor in kW
|
||||
:param value: [[float]]
|
||||
:return:
|
||||
"""
|
||||
if self._cooling_comp_power is None:
|
||||
self._cooling_comp_power = value
|
||||
|
||||
@property
|
||||
def cooling_capacity_coff(self) -> List[float]:
|
||||
"""
|
||||
Get cooling capacity coefficients
|
||||
:return: [float]
|
||||
"""
|
||||
return self._cooling_capacity_coff
|
||||
|
||||
@cooling_capacity_coff.setter
|
||||
def cooling_capacity_coff(self, value):
|
||||
"""
|
||||
Set the value for cooling capacity coefficients
|
||||
:param value: [float]
|
||||
:return:
|
||||
"""
|
||||
if self._cooling_capacity_coff is None:
|
||||
self._cooling_capacity_coff = value
|
||||
|
||||
@property
|
||||
def cooling_comp_power_coff(self) -> List[float]:
|
||||
"""
|
||||
Get cooling compressor power coefficients
|
||||
:return: [float]
|
||||
"""
|
||||
return self._cooling_comp_power_coff
|
||||
|
||||
@cooling_comp_power_coff.setter
|
||||
def cooling_comp_power_coff(self, value):
|
||||
"""
|
||||
Set the value for cooling compressor power coefficients
|
||||
:param value: [float]
|
||||
:return:
|
||||
"""
|
||||
if self._cooling_comp_power_coff is None:
|
||||
self._cooling_comp_power_coff = value
|
||||
|
||||
|
||||
|
||||
@property
|
||||
def heating_capacity(self) -> List[float]:
|
||||
"""
|
||||
Get heating capacity kW
|
||||
:return: [[float]]
|
||||
"""
|
||||
return self._heating_capacity
|
||||
|
||||
@heating_capacity.setter
|
||||
def heating_capacity(self, value):
|
||||
"""
|
||||
Set the heating capacity in kW
|
||||
:param value: [[float]]
|
||||
:return:
|
||||
"""
|
||||
if self._heating_capacity is None:
|
||||
self._heating_capacity = value
|
||||
|
||||
@property
|
||||
def heating_comp_power(self) -> List[float]:
|
||||
"""
|
||||
Get heating compressor power kW
|
||||
:return: [[float]]
|
||||
"""
|
||||
return self._heating_comp_power
|
||||
|
||||
@heating_comp_power.setter
|
||||
def heating_comp_power(self, value):
|
||||
"""
|
||||
Set the heating compressor power in kW
|
||||
:param value: [[float]]
|
||||
:return:
|
||||
"""
|
||||
if self._heating_comp_power is None:
|
||||
self._heating_comp_power = value
|
||||
|
||||
@property
|
||||
def heating_comp_power_coff(self) -> List[float]:
|
||||
"""
|
||||
Get heating compressor power coefficients
|
||||
:return: [float]
|
||||
"""
|
||||
return self._heating_comp_power_coff
|
||||
|
||||
@heating_comp_power_coff.setter
|
||||
def heating_comp_power_coff(self, value):
|
||||
"""
|
||||
Set the value for heating compressor power coefficients
|
||||
:param value: [float]
|
||||
:return:
|
||||
"""
|
||||
if self._heating_comp_power_coff is None:
|
||||
self._heating_comp_power_coff = value
|
||||
|
||||
@property
|
||||
def heating_capacity_coff(self) -> List[float]:
|
||||
"""
|
||||
Get heating capacity coefficients
|
||||
:return: [float]
|
||||
"""
|
||||
return self._heating_capacity_coff
|
||||
|
||||
@heating_capacity_coff.setter
|
||||
def heating_capacity_coff(self, value):
|
||||
"""
|
||||
Set the value for heating capacity coefficients
|
||||
:param value: [float]
|
||||
:return:
|
||||
"""
|
||||
if self._heating_capacity_coff is None:
|
||||
self._heating_capacity_coff = value
|
||||
|
||||
|
||||
|
|
130
city_model_structure/energy_systems/water_to_water_hp.py
Normal file
130
city_model_structure/energy_systems/water_to_water_hp.py
Normal file
|
@ -0,0 +1,130 @@
|
|||
"""
|
||||
water_to_water_hp module defines a water to water heat pump heat pump
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2021 Project Author Peter Yefi peteryefi@gmail.com
|
||||
"""
|
||||
|
||||
from typing import List
|
||||
from city_model_structure.energy_systems.heat_pump import HeatPump
|
||||
|
||||
|
||||
class WaterToWaterHP(HeatPump):
|
||||
"""
|
||||
WaterToWaterHP class
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._entering_water_temp = None
|
||||
self._leaving_water_temp = None
|
||||
self._total_cooling_capacity = None
|
||||
self._power_demand = None
|
||||
self._flow_rate = None
|
||||
self._power_demand_coff = None # a coefficients
|
||||
|
||||
@property
|
||||
def entering_water_temp(self) -> List[float]:
|
||||
"""
|
||||
Get entering water temperature in degree celsius
|
||||
:return: [[float]]
|
||||
"""
|
||||
return self._entering_water_temp
|
||||
|
||||
@entering_water_temp.setter
|
||||
def entering_water_temp(self, value):
|
||||
"""
|
||||
Set entering water temperature in degree celsius
|
||||
:param value: [[float]]
|
||||
"""
|
||||
if self._entering_water_temp is None:
|
||||
self._entering_water_temp = value
|
||||
|
||||
@property
|
||||
def leaving_water_temp(self) -> List[float]:
|
||||
"""
|
||||
Get leaving water temperature in degree celsius
|
||||
:return: [[float]]
|
||||
"""
|
||||
return self._leaving_water_temp
|
||||
|
||||
@leaving_water_temp.setter
|
||||
def leaving_water_temp(self, value):
|
||||
"""
|
||||
Set the leaving water temperature in degree celsius
|
||||
:param value: [[float]]
|
||||
:return:
|
||||
"""
|
||||
if self._leaving_water_temp is None:
|
||||
self._leaving_water_temp = value
|
||||
|
||||
@property
|
||||
def total_cooling_capacity(self) -> List[float]:
|
||||
"""
|
||||
Get total cooling capacity
|
||||
:return: [float]
|
||||
"""
|
||||
return self._total_cooling_capacity
|
||||
|
||||
@total_cooling_capacity.setter
|
||||
def total_cooling_capacity(self, value):
|
||||
"""
|
||||
Set the value for total cooling capacity
|
||||
:param value: [float]
|
||||
:return:
|
||||
"""
|
||||
if self._total_cooling_capacity is None:
|
||||
self._total_cooling_capacity = value
|
||||
|
||||
@property
|
||||
def power_demand(self) -> List[float]:
|
||||
"""
|
||||
Get power demand in kW
|
||||
:return: [float]
|
||||
"""
|
||||
return self._power_demand
|
||||
|
||||
@power_demand.setter
|
||||
def power_demand(self, value):
|
||||
"""
|
||||
Set the value for power demand in kW
|
||||
:param value: [float]
|
||||
:return:
|
||||
"""
|
||||
if self._power_demand is None:
|
||||
self._power_demand = value
|
||||
|
||||
@property
|
||||
def flow_rate(self) -> List[float]:
|
||||
"""
|
||||
Get flow rate in kg/s
|
||||
:return: [[float]]
|
||||
"""
|
||||
return self._flow_rate
|
||||
|
||||
@flow_rate.setter
|
||||
def flow_rate(self, value):
|
||||
"""
|
||||
Set flow rate in kW
|
||||
:param value: [[float]]
|
||||
:return:
|
||||
"""
|
||||
if self._flow_rate is None:
|
||||
self._flow_rate = value
|
||||
|
||||
@property
|
||||
def power_demand_coff(self) -> List[float]:
|
||||
"""
|
||||
Get power demand coefficients
|
||||
:return: [float]
|
||||
"""
|
||||
return self._power_demand_coff
|
||||
|
||||
@power_demand_coff.setter
|
||||
def power_demand_coff(self, value):
|
||||
"""
|
||||
Set the value for power demand coefficients
|
||||
:param value: [float]
|
||||
:return:
|
||||
"""
|
||||
if self._power_demand_coff is None:
|
||||
self._power_demand_coff = value
|
23
city_model_structure/lca_calculations.py
Normal file
23
city_model_structure/lca_calculations.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
LifeCycleAssessment retrieve the specific Life Cycle Assessment module for the given region
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Atiya
|
||||
"""
|
||||
from city_model_structure.machine import Machine
|
||||
|
||||
class LcaCalculations:
|
||||
"""
|
||||
LCA Calculations class
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
print("lca calculations class")
|
||||
|
||||
def emission_disposal_machines(self, ):
|
||||
return Machine.work_efficiency * Machine.energy_consumption_rate * Machine.carbon_emission_factor
|
||||
|
||||
def emission_transportation(self, weight, distance ):
|
||||
return weight * distance * Machine.energy_consumption_rate * Machine.carbon_emission_factor
|
||||
|
||||
|
||||
|
118
city_model_structure/material.py
Normal file
118
city_model_structure/material.py
Normal file
|
@ -0,0 +1,118 @@
|
|||
"""
|
||||
LifeCycleAssessment retrieve the specific Life Cycle Assessment module for the given region
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Atiya
|
||||
"""
|
||||
|
||||
class Material:
|
||||
"""
|
||||
LCA Material class
|
||||
"""
|
||||
|
||||
def __init__(self, material_name, material_id, type, density, density_unit, embodied_carbon, embodied_carbon_unit, recycling_ratio,
|
||||
onsite_recycling_ratio, company_recycling_ratio, landfilling_ratio, cost, cost_unit):
|
||||
self._material_name = material_name
|
||||
self._material_id = material_id
|
||||
self._type = type
|
||||
self._density = density
|
||||
self._density_unit = density_unit
|
||||
self._embodied_carbon = embodied_carbon
|
||||
self._embodied_carbon_unit = embodied_carbon_unit
|
||||
self._recycling_ratio = recycling_ratio
|
||||
self._onsite_recycling_ratio = onsite_recycling_ratio
|
||||
self._company_recycling_ratio = company_recycling_ratio
|
||||
self._landfilling_ratio = landfilling_ratio
|
||||
self._cost = cost
|
||||
self._cost_unit = cost_unit
|
||||
|
||||
@property
|
||||
def material_name(self):
|
||||
"""
|
||||
Get material name
|
||||
"""
|
||||
return self._material_name
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
"""
|
||||
Get material id
|
||||
"""
|
||||
return self._material_id
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
"""
|
||||
Get material type
|
||||
"""
|
||||
return self._type
|
||||
|
||||
@property
|
||||
def density(self):
|
||||
"""
|
||||
Get material density
|
||||
"""
|
||||
return self._density
|
||||
|
||||
@property
|
||||
def density_unit(self):
|
||||
"""
|
||||
Get material density unit
|
||||
"""
|
||||
return self._density_unit
|
||||
|
||||
@property
|
||||
def embodied_carbon(self):
|
||||
"""
|
||||
Get material embodied carbon
|
||||
"""
|
||||
return self._embodied_carbon
|
||||
|
||||
@property
|
||||
def embodied_carbon_unit(self):
|
||||
"""
|
||||
Get material embodied carbon unit
|
||||
"""
|
||||
return self._embodied_carbon_unit
|
||||
|
||||
@property
|
||||
def recycling_ratio(self):
|
||||
"""
|
||||
Get material recycling ratio
|
||||
"""
|
||||
return self._recycling_ratio
|
||||
|
||||
@property
|
||||
def onsite_recycling_ratio(self):
|
||||
"""
|
||||
Get material onsite recycling ratio
|
||||
"""
|
||||
return self._onsite_recycling_ratio
|
||||
|
||||
@property
|
||||
def company_recycling_ratio(self):
|
||||
"""
|
||||
Get material company recycling ratio
|
||||
"""
|
||||
return self._company_recycling_ratio
|
||||
|
||||
@property
|
||||
def landfilling_ratio(self):
|
||||
"""
|
||||
Get material landfilling ratio
|
||||
"""
|
||||
return self._landfilling_ratio
|
||||
|
||||
@property
|
||||
def cost(self):
|
||||
"""
|
||||
Get material cost
|
||||
"""
|
||||
return self._cost
|
||||
|
||||
@property
|
||||
def cost_unit(self):
|
||||
"""
|
||||
Get material cost unit
|
||||
"""
|
||||
return self._cost_unit
|
||||
|
786
data/energy_systems/heat_pumps/as_parallel.txt
Normal file
786
data/energy_systems/heat_pumps/as_parallel.txt
Normal file
|
@ -0,0 +1,786 @@
|
|||
|
||||
B 17 CONST
|
||||
P 17
|
||||
12 % Constant value
|
||||
|
||||
B 18 CONST
|
||||
P 18
|
||||
$a5 % Constant value
|
||||
|
||||
B 19 CONST
|
||||
P 19
|
||||
1 % Constant value
|
||||
|
||||
B 20 CONST
|
||||
P 20
|
||||
$HPSupTemp % Constant value
|
||||
|
||||
B 21 CONST
|
||||
P 21
|
||||
$AuxHeaterEfficiency % Constant value
|
||||
|
||||
B 22 CONST
|
||||
P 22
|
||||
$ElecGridEF % Constant value
|
||||
|
||||
B 23 CONST
|
||||
P 23
|
||||
2 % Constant value
|
||||
|
||||
B 24 CONST
|
||||
P 24
|
||||
$Cp % Constant value
|
||||
|
||||
B 25 CONST
|
||||
P 25
|
||||
9 % Constant value
|
||||
|
||||
B 26 CONST
|
||||
P 26
|
||||
2 % Constant value
|
||||
|
||||
B 27 CONST
|
||||
P 27
|
||||
$BuildingSuppTemp % Constant value
|
||||
|
||||
B 28 CONST
|
||||
P 28
|
||||
$a2 % Constant value
|
||||
|
||||
B 29 CONST
|
||||
P 29
|
||||
$a3 % Constant value
|
||||
|
||||
B 30 CONST
|
||||
P 30
|
||||
$MaximumHPEnergyInput % Constant value
|
||||
|
||||
B 31 CONST
|
||||
P 31
|
||||
12 % Constant value
|
||||
|
||||
B 32 CONST
|
||||
P 32
|
||||
12 % Constant value
|
||||
|
||||
B 33 CONST
|
||||
P 33
|
||||
$a6 % Constant value
|
||||
|
||||
B 34 CONST
|
||||
P 34
|
||||
10 % Constant value
|
||||
|
||||
B 35 CONST
|
||||
P 35
|
||||
1 % Constant value
|
||||
|
||||
B 36 CONST
|
||||
P 36
|
||||
$TemperatureDifference % Constant value
|
||||
|
||||
B 37 CONST
|
||||
P 37
|
||||
$ElectricityPrice % Constant value
|
||||
|
||||
B 38 CONST
|
||||
P 38
|
||||
$FuelPrice % Constant value
|
||||
|
||||
B 39 CONST
|
||||
P 39
|
||||
40 % Constant value
|
||||
|
||||
B 40 CONST
|
||||
P 40
|
||||
$Cp % Constant value
|
||||
|
||||
B 41 CONST
|
||||
P 41
|
||||
$HPDisactivationTemperature % Constant value
|
||||
|
||||
B 42 CONST
|
||||
P 42
|
||||
$FuelEF % Constant value
|
||||
|
||||
B 43 CONST
|
||||
P 43
|
||||
$HPReactivationTemperature % Constant value
|
||||
|
||||
B 44 CONST
|
||||
P 44
|
||||
$HPNominalCapacity % Constant value
|
||||
|
||||
B 45 CONST
|
||||
P 45
|
||||
0 % Constant value
|
||||
|
||||
B 46 CONST
|
||||
P 46
|
||||
$FuelLHV % Constant value
|
||||
|
||||
B 47 CONST
|
||||
P 47
|
||||
5 % Constant value
|
||||
|
||||
B 48 CONST
|
||||
P 48
|
||||
$TemperatureDifference % Constant value
|
||||
|
||||
B 49 CONST
|
||||
P 49
|
||||
$Cp % Constant value
|
||||
|
||||
B 50 CONST
|
||||
P 50
|
||||
$BuildingSuppTemp % Constant value
|
||||
|
||||
B 51 CONST
|
||||
P 51
|
||||
$a1 % Constant value
|
||||
|
||||
B 52 CONST
|
||||
P 52
|
||||
$a4 % Constant value
|
||||
|
||||
B 53 NOP
|
||||
120.1
|
||||
|
||||
B 54 NOP
|
||||
68.2
|
||||
|
||||
B 55 NOP
|
||||
217.1
|
||||
|
||||
B 56 NOP
|
||||
136.1
|
||||
|
||||
B 57 NOP
|
||||
20.1
|
||||
|
||||
B 58 NOP
|
||||
57.1
|
||||
|
||||
B 59 NOP
|
||||
165.1
|
||||
|
||||
B 60 NOP
|
||||
57.1
|
||||
|
||||
B 61 NOP
|
||||
177.1
|
||||
|
||||
B 62 NOP
|
||||
119.1
|
||||
|
||||
B 63 NOP
|
||||
136.1
|
||||
|
||||
B 64 NOP
|
||||
120.1
|
||||
|
||||
B 65 NOP
|
||||
58.1
|
||||
|
||||
B 66 NOP
|
||||
54.1
|
||||
|
||||
B 67 MIXER % Point 11
|
||||
217.4
|
||||
119.1
|
||||
56.1
|
||||
132.1
|
||||
|
||||
B 68 MIXER % Point 5
|
||||
60.1
|
||||
134.1
|
||||
55.1
|
||||
64.1
|
||||
|
||||
B 105 MUL
|
||||
40.1
|
||||
131.1
|
||||
|
||||
B 106 MUL
|
||||
171.1
|
||||
22.1
|
||||
|
||||
B 107 MUL
|
||||
221.1
|
||||
175.1
|
||||
129.1
|
||||
130.1
|
||||
|
||||
B 108 MUL
|
||||
18.1
|
||||
169.1
|
||||
|
||||
B 109 MUL
|
||||
68.1
|
||||
138.1
|
||||
|
||||
B 110 MUL
|
||||
20.1
|
||||
52.1
|
||||
|
||||
B 111 MUL
|
||||
205.1
|
||||
212.1
|
||||
140.1
|
||||
|
||||
B 112 MUL
|
||||
207.1
|
||||
48.1
|
||||
|
||||
B 113 MUL
|
||||
210.1
|
||||
19.1
|
||||
42.1
|
||||
|
||||
B 114 MUL
|
||||
51.1
|
||||
168.1
|
||||
|
||||
B 115 MUL
|
||||
208.1
|
||||
35.1
|
||||
38.1
|
||||
|
||||
B 116 MUL
|
||||
205.1
|
||||
111.1
|
||||
|
||||
B 117 MUL
|
||||
203.1
|
||||
50.1
|
||||
|
||||
B 118 MUL
|
||||
185.2
|
||||
20.1
|
||||
29.1
|
||||
|
||||
B 119 MUL
|
||||
139.1
|
||||
127.1
|
||||
|
||||
B 120 MUL
|
||||
214.1
|
||||
133.1
|
||||
|
||||
B 121 MUL
|
||||
172.1
|
||||
37.1
|
||||
|
||||
B 122 MUL
|
||||
215.1
|
||||
24.1
|
||||
68.2
|
||||
216.1
|
||||
126.1
|
||||
|
||||
B 123 MUL
|
||||
185.2
|
||||
28.1
|
||||
|
||||
B 124 MUL
|
||||
221.1
|
||||
44.1
|
||||
129.1
|
||||
130.1
|
||||
|
||||
B 125 SUM
|
||||
34.1
|
||||
185.2
|
||||
|
||||
B 126 SUM
|
||||
27.1
|
||||
197.1
|
||||
|
||||
B 127 SUM
|
||||
61.1
|
||||
200.1
|
||||
|
||||
B 128 SUM
|
||||
109.1
|
||||
117.1
|
||||
|
||||
B 129 SUM
|
||||
213.1
|
||||
141.1
|
||||
|
||||
B 130 SUM
|
||||
116.1
|
||||
204.1
|
||||
|
||||
B 131 SUM
|
||||
20.1
|
||||
196.1
|
||||
|
||||
B 132 SUM
|
||||
66.1
|
||||
198.1
|
||||
|
||||
B 133 SUM
|
||||
202.1
|
||||
179.1
|
||||
|
||||
B 134 SUM
|
||||
61.1
|
||||
201.1
|
||||
|
||||
B 135 SUM
|
||||
114.1
|
||||
123.1
|
||||
118.1
|
||||
110.1
|
||||
108.1
|
||||
33.1
|
||||
|
||||
B 136 SUM
|
||||
128.1
|
||||
199.1
|
||||
|
||||
B 137 MTM
|
||||
167.2
|
||||
P 137
|
||||
'Montreal' % Location
|
||||
|
||||
B 138 GT
|
||||
68.1
|
||||
50.1
|
||||
|
||||
B 139 GT
|
||||
61.1
|
||||
179.1
|
||||
|
||||
B 140 GT
|
||||
164.1
|
||||
45.1
|
||||
|
||||
B 141 GT
|
||||
167.2
|
||||
25.1
|
||||
|
||||
B 142 CUMC
|
||||
167.3
|
||||
107.1
|
||||
|
||||
B 143 CUMC
|
||||
167.2
|
||||
206.1
|
||||
|
||||
B 144 CUMC
|
||||
167.3
|
||||
106.1
|
||||
113.1
|
||||
|
||||
B 145 CUMC
|
||||
167.2
|
||||
106.1
|
||||
113.1
|
||||
|
||||
B 146 CUMC
|
||||
167.3
|
||||
206.1
|
||||
|
||||
B 147 CUMC
|
||||
167.2
|
||||
107.1
|
||||
|
||||
B 148 CUMC
|
||||
167.3
|
||||
121.1
|
||||
115.1
|
||||
|
||||
B 149 CUMC
|
||||
167.2
|
||||
121.1
|
||||
115.1
|
||||
|
||||
B 150 CUMC
|
||||
167.4
|
||||
107.1
|
||||
|
||||
B 158 CUM
|
||||
113.1
|
||||
|
||||
B 159 CUM
|
||||
106.1
|
||||
|
||||
B 160 CUM
|
||||
115.1
|
||||
|
||||
B 161 CUM
|
||||
206.1
|
||||
|
||||
B 162 CUM
|
||||
121.1
|
||||
|
||||
B 163 CUM
|
||||
124.1
|
||||
107.1
|
||||
|
||||
B 164 DELAY
|
||||
124.1
|
||||
P 164
|
||||
0 % Initial value
|
||||
|
||||
B 165 DELAY
|
||||
67.1
|
||||
P 165
|
||||
25 % Initial value
|
||||
|
||||
B 166 MAXX
|
||||
221.1
|
||||
|
||||
B 167 CLOCK
|
||||
P 167
|
||||
$StartYear % Start year
|
||||
$StartMonth % Start month
|
||||
$StartDay % Start day
|
||||
$StartHour % Start hour
|
||||
$StartMinute % Start minute
|
||||
$StartSecond % Start second
|
||||
$EndYear % End year
|
||||
$EndMonth % End month
|
||||
$EndDay % End day
|
||||
$EndHour % End hour
|
||||
$EndMinute % End minute
|
||||
$EndSecond % End second
|
||||
5 % Increment
|
||||
'm' % Unit
|
||||
|
||||
B 168 EXPG
|
||||
185.2
|
||||
23.1
|
||||
|
||||
B 169 EXPG
|
||||
20.1
|
||||
26.1
|
||||
|
||||
B 170 DIV
|
||||
209.1
|
||||
32.1
|
||||
|
||||
B 171 DIV
|
||||
107.1
|
||||
17.1
|
||||
|
||||
B 172 DIV
|
||||
107.1
|
||||
31.1
|
||||
|
||||
B 173 DIV
|
||||
180.1
|
||||
46.1
|
||||
|
||||
B 174 DIV
|
||||
124.1
|
||||
107.1
|
||||
|
||||
B 175 DIV
|
||||
44.1
|
||||
135.1
|
||||
|
||||
B 176 DIV
|
||||
30.1
|
||||
44.1
|
||||
|
||||
B 177 DIV
|
||||
218.1
|
||||
105.1
|
||||
|
||||
B 178 DIV
|
||||
163.1
|
||||
163.2
|
||||
|
||||
B 179 DIV
|
||||
220.1
|
||||
112.1
|
||||
|
||||
B 180 DIV
|
||||
170.1
|
||||
21.1
|
||||
|
||||
B 185 GENGT
|
||||
137.1
|
||||
137.3
|
||||
137.4
|
||||
137.5
|
||||
137.7
|
||||
137.8
|
||||
167.1
|
||||
167.2
|
||||
167.3
|
||||
167.4
|
||||
P 185
|
||||
45.5 % Latitude
|
||||
73.62 % Longitude
|
||||
5 % Time zone
|
||||
1 % Variance factor of the Gordon Reddy correlation
|
||||
0 % Year-to-year variability
|
||||
0.3 % Autocorrelation coefficient lag one
|
||||
0.171 % Autocorrelation coefficient lag two
|
||||
4711 % Initialisation of random number generator
|
||||
2 % Maximum allowed mean temperature deviation
|
||||
100 % Maximum number of iterations
|
||||
|
||||
B 186 WRITE
|
||||
147.1
|
||||
147.2
|
||||
P 186
|
||||
2 % Mode
|
||||
0 % Suppress FNQ inputs
|
||||
$fileOut8 % File name
|
||||
'*' % Fortran format
|
||||
|
||||
B 187 WRITE
|
||||
145.1
|
||||
145.2
|
||||
145.3
|
||||
P 187
|
||||
2 % Mode
|
||||
0 % Suppress FNQ inputs
|
||||
$fileOut5 % File name
|
||||
'*' % Fortran format
|
||||
|
||||
B 188 WRITE
|
||||
148.1
|
||||
148.2
|
||||
148.3
|
||||
P 188
|
||||
2 % Mode
|
||||
0 % Suppress FNQ inputs
|
||||
$fileOut7 % File name
|
||||
'*' % Fortran format
|
||||
|
||||
B 189 WRITE
|
||||
144.1
|
||||
144.2
|
||||
144.3
|
||||
P 189
|
||||
2 % Mode
|
||||
0 % Suppress FNQ inputs
|
||||
$fileOut2 % File name
|
||||
'*' % Fortran format
|
||||
|
||||
B 190 WRITE
|
||||
143.1
|
||||
143.2
|
||||
P 190
|
||||
2 % Mode
|
||||
0 % Suppress FNQ inputs
|
||||
$fileOut4 % File name
|
||||
'*' % Fortran format
|
||||
|
||||
B 191 WRITE
|
||||
149.1
|
||||
149.2
|
||||
149.3
|
||||
P 191
|
||||
2 % Mode
|
||||
0 % Suppress FNQ inputs
|
||||
$fileOut3 % File name
|
||||
'*' % Fortran format
|
||||
|
||||
B 192 WRITE
|
||||
142.1
|
||||
142.2
|
||||
P 192
|
||||
2 % Mode
|
||||
0 % Suppress FNQ inputs
|
||||
$fileOut6 % File name
|
||||
'*' % Fortran format
|
||||
|
||||
B 193 WRITE
|
||||
167.1
|
||||
167.2
|
||||
167.3
|
||||
167.4
|
||||
167.5
|
||||
124.1
|
||||
220.1
|
||||
177.1
|
||||
179.1
|
||||
119.1
|
||||
134.1
|
||||
60.1
|
||||
64.1
|
||||
55.1
|
||||
68.2
|
||||
68.1
|
||||
173.1
|
||||
209.1
|
||||
54.1
|
||||
128.1
|
||||
136.1
|
||||
53.1
|
||||
63.1
|
||||
132.1
|
||||
56.1
|
||||
62.1
|
||||
217.4
|
||||
67.2
|
||||
67.1
|
||||
217.1
|
||||
217.2
|
||||
217.3
|
||||
217.4
|
||||
217.5
|
||||
107.1
|
||||
174.1
|
||||
185.2
|
||||
121.1
|
||||
115.1
|
||||
106.1
|
||||
113.1
|
||||
P 193
|
||||
2 % Mode
|
||||
0 % Suppress FNQ inputs
|
||||
$fileOut1 % File name
|
||||
'*' % Fortran format
|
||||
|
||||
B 194 WRITE
|
||||
146.1
|
||||
146.2
|
||||
P 194
|
||||
2 % Mode
|
||||
0 % Suppress FNQ inputs
|
||||
$fileOut9 % File name
|
||||
'*' % Fortran format
|
||||
|
||||
B 195 WRITE
|
||||
167.1
|
||||
167.2
|
||||
167.3
|
||||
150.1
|
||||
150.2
|
||||
P 195
|
||||
2 % Mode
|
||||
0 % Suppress FNQ inputs
|
||||
$fileOut10 % File name
|
||||
'*' % Fortran format
|
||||
|
||||
B 196 CHS
|
||||
59.1
|
||||
|
||||
B 197 CHS
|
||||
68.1
|
||||
|
||||
B 198 CHS
|
||||
53.1
|
||||
|
||||
B 199 CHS
|
||||
36.1
|
||||
|
||||
B 200 CHS
|
||||
179.1
|
||||
|
||||
B 201 CHS
|
||||
62.1
|
||||
|
||||
B 202 CHS
|
||||
177.1
|
||||
|
||||
B 203 INV
|
||||
138.1
|
||||
|
||||
B 204 INV
|
||||
212.1
|
||||
|
||||
B 205 INV
|
||||
211.1
|
||||
|
||||
B 206 ATT
|
||||
173.1
|
||||
P 206
|
||||
$FuelDensity % Attenuation factor a
|
||||
|
||||
B 207 ATT
|
||||
49.1
|
||||
P 207
|
||||
1000 % Attenuation factor a
|
||||
|
||||
B 208 ATT
|
||||
173.1
|
||||
P 208
|
||||
$FuelDensity % Attenuation factor a
|
||||
|
||||
B 209 ATT
|
||||
122.1
|
||||
P 209
|
||||
1000 % Attenuation factor a
|
||||
|
||||
B 210 ATT
|
||||
173.1
|
||||
P 210
|
||||
$FuelDensity % Attenuation factor a
|
||||
|
||||
B 211 GE
|
||||
217.1
|
||||
41.1
|
||||
P 211
|
||||
0 % Error tolerance
|
||||
|
||||
B 212 GE
|
||||
217.1
|
||||
43.1
|
||||
P 212
|
||||
0 % Error tolerance
|
||||
|
||||
B 213 LT
|
||||
167.2
|
||||
47.1
|
||||
|
||||
B 214 LT
|
||||
177.1
|
||||
179.1
|
||||
|
||||
B 215 LT
|
||||
177.1
|
||||
179.1
|
||||
|
||||
B 216 LT
|
||||
68.1
|
||||
39.1
|
||||
|
||||
B 217 TANKST
|
||||
65.1
|
||||
62.1
|
||||
63.1
|
||||
53.1
|
||||
125.1
|
||||
219.1
|
||||
P 217
|
||||
$TESCapacity % Tank volume
|
||||
4 % Number of temperature nodes
|
||||
$TESDiameter % Tank diameter
|
||||
$Cp % Specfic heat of fluid
|
||||
$Rhow % Fluid density
|
||||
0 % Overall heat-loss coefficient
|
||||
1 % Effective heat conductivity
|
||||
30 % Initial tank temperature
|
||||
|
||||
B 218 GAIN
|
||||
124.1
|
||||
P 218
|
||||
1000 % Gain factor g
|
||||
|
||||
B 219 SOY
|
||||
167.1
|
||||
167.2
|
||||
167.3
|
||||
167.4
|
||||
167.5
|
||||
167.6
|
||||
|
||||
B 220 READ
|
||||
P 220
|
||||
1 % Number of values to be read per record
|
||||
0 % Number of records to be skipped on the first call
|
||||
$HeatingDemand % File name
|
||||
'*' % Fortran format
|
||||
|
||||
B 221 INT
|
||||
176.1
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -18,3 +18,11 @@ AuxHeaterEfficiency: 0.9
|
|||
ElecGridEF: 0.5
|
||||
ElectricityPrice: 0.073
|
||||
|
||||
# Water to Water HP constants
|
||||
HPNominalCapacity: 256
|
||||
LowestPossibleLoadFlow: 4.73
|
||||
HighestPossibleLoadFlow: 9.46
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
1135
data/energy_systems/heat_pumps/w2w_parallel.txt
Normal file
1135
data/energy_systems/heat_pumps/w2w_parallel.txt
Normal file
File diff suppressed because it is too large
Load Diff
1066
data/energy_systems/heat_pumps/w2w_series.txt
Normal file
1066
data/energy_systems/heat_pumps/w2w_series.txt
Normal file
File diff suppressed because it is too large
Load Diff
BIN
data/energy_systems/heat_pumps/water_to_water.xlsx
Normal file
BIN
data/energy_systems/heat_pumps/water_to_water.xlsx
Normal file
Binary file not shown.
105408
data/energy_systems/heat_pumps/wt_hourly3.txt
Normal file
105408
data/energy_systems/heat_pumps/wt_hourly3.txt
Normal file
File diff suppressed because it is too large
Load Diff
59
data/greenery/ecore_greenery_catalog.xml
Normal file
59
data/greenery/ecore_greenery_catalog.xml
Normal file
|
@ -0,0 +1,59 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<greenery:GreeneryCatalog xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:greenery="http://ca.concordia/greenerycatalog">
|
||||
<plantCategories name="Flowers">
|
||||
<plants name="Camellia Sasanqua" height="0.4 m" leafAreaIndex="2.18" leafReflectivity="0.2" leafEmissivity="0.9" minimalStomatalResistance="288 s/m" growsOn="//@soils.0 //@soils.2 //@soils.4 //@soils.3 //@soils.1"/>
|
||||
<plants name="Rhododendron" height="0.5 m" leafAreaIndex="1.85" minimalStomatalResistance="161 s/m" growsOn="//@soils.0 //@soils.3"/>
|
||||
<plants name="Ligustrum Japonicum 'Howardii' " height="0.48 m" leafAreaIndex="4.93" minimalStomatalResistance="172 s/m" growsOn="//@soils.0 //@soils.3"/>
|
||||
<plants name="Viburnum Dilatatum (Thunb)" height="0.7 m" leafAreaIndex="5" minimalStomatalResistance="212 s/m" growsOn="//@soils.0 //@soils.3 //@soils.2 //@soils.4 //@soils.1"/>
|
||||
<plants name="Lorpetalum Chinense var. Rubrum" height="0.7 m" leafAreaIndex="2" leafReflectivity="0.1" minimalStomatalResistance="228 s/m" growsOn="//@soils.0 //@soils.2 //@soils.3 //@soils.1"/>
|
||||
<plants name="Buxus sinica" height="0.45 m" leafAreaIndex="4.03" minimalStomatalResistance="165 s/m" growsOn="//@soils.2 //@soils.0 //@soils.3 //@soils.5 //@soils.1"/>
|
||||
<plants name="Sedum acre" height="0.1 m" leafAreaIndex="3.5" leafReflectivity="0.36" leafEmissivity="0.9" growsOn="//@soils.2 //@soils.0 //@soils.1 //@soils.3"/>
|
||||
<plants name="Frankenia thymifolia" height="0.15 m" leafAreaIndex="3.6" leafReflectivity="0.32" leafEmissivity="0.83" growsOn="//@soils.2 //@soils.1 //@soils.0 //@soils.3"/>
|
||||
<plants name="Vinca major" leafAreaIndex="2.7" leafReflectivity="0.25" leafEmissivity="0.78" growsOn="//@soils.2 //@soils.0 //@soils.3 //@soils.1"/>
|
||||
<plants name="Ivy (hedera helix)" height="0.1 m" leafAreaIndex="5" growsOn="//@soils.4 //@soils.1 //@soils.2 //@soils.0 //@soils.3"/>
|
||||
</plantCategories>
|
||||
<plantCategories name="Grass">
|
||||
<plants name="Lawn" height="0.06 m" leafAreaIndex="1.4" leafReflectivity="0.1" minimalStomatalResistance="50 s/m" growsOn="//@soils.2"/>
|
||||
</plantCategories>
|
||||
<plantCategories name="Farming">
|
||||
<plants name="Strawberry" growsOn="//@soils.2"/>
|
||||
<plants name="Tomato" leafEmissivity="0.8" growsOn="//@soils.2 //@soils.3"/>
|
||||
<plants name="Lettuce" growsOn="//@soils.2"/>
|
||||
</plantCategories>
|
||||
<vegetationCategories name="Urban Greening">
|
||||
<vegetationTemplates name="Grass" soil="//@soils.1" management="Extensive">
|
||||
<plants plant="//@plantCategories.1/@plants.0"/>
|
||||
</vegetationTemplates>
|
||||
</vegetationCategories>
|
||||
<vegetationCategories name="Green Facade">
|
||||
<vegetationTemplates name="Green Facade" soil="//@soils.2">
|
||||
<plants percentage="100" plant="//@plantCategories.0/@plants.9"/>
|
||||
</vegetationTemplates>
|
||||
</vegetationCategories>
|
||||
<vegetationCategories name="GreenRoof">
|
||||
<vegetationTemplates name="Green Roof" thicknessOfSoil="20 cm" soil="//@soils.2">
|
||||
<plants percentage="10" plant="//@plantCategories.0/@plants.5"/>
|
||||
<plants percentage="10" plant="//@plantCategories.0/@plants.0"/>
|
||||
<plants percentage="10" plant="//@plantCategories.0/@plants.8"/>
|
||||
<plants percentage="10" plant="//@plantCategories.0/@plants.2"/>
|
||||
<plants percentage="10" plant="//@plantCategories.0/@plants.4"/>
|
||||
<plants percentage="10" plant="//@plantCategories.0/@plants.6"/>
|
||||
<plants percentage="10" plant="//@plantCategories.0/@plants.1"/>
|
||||
<plants percentage="10" plant="//@plantCategories.0/@plants.3"/>
|
||||
<plants percentage="20" plant="//@plantCategories.0/@plants.7"/>
|
||||
</vegetationTemplates>
|
||||
</vegetationCategories>
|
||||
<vegetationCategories name="Rooftop Farming">
|
||||
<vegetationTemplates name="Rooftop Farming" thicknessOfSoil="30 cm" soil="//@soils.2">
|
||||
<plants percentage="19" plant="//@plantCategories.2/@plants.0"/>
|
||||
<plants percentage="60" plant="//@plantCategories.2/@plants.1"/>
|
||||
<plants percentage="21" plant="//@plantCategories.2/@plants.2"/>
|
||||
</vegetationTemplates>
|
||||
</vegetationCategories>
|
||||
<soils name="Sand" conductivityOfDrySoil="1.26 W/(m·K)" saturationVolumetricMoistureContent="0.43" residualVolumetricMoistureContent="0.045"/>
|
||||
<soils name="Loamy sand" conductivityOfDrySoil="0.35 W/(m·K)" saturationVolumetricMoistureContent="0.41" residualVolumetricMoistureContent="0.057"/>
|
||||
<soils name="Loam" conductivityOfDrySoil="0.67 W/(m·K)" specificHeatOfDrySoil="900 J/(kg·K)" thermalAbsorptance="0.9" saturationVolumetricMoistureContent="0.43" residualVolumetricMoistureContent="0.078"/>
|
||||
<soils name="Sandy Loam" conductivityOfDrySoil="1.06 W/(m·K)" saturationVolumetricMoistureContent="0.41" residualVolumetricMoistureContent="0.065"/>
|
||||
<soils name="Clay loam" conductivityOfDrySoil="0.7 W/(m·K)" saturationVolumetricMoistureContent="0.41" residualVolumetricMoistureContent="0.095"/>
|
||||
<soils name="Silt" conductivityOfDrySoil="0.35 W/(m·K)" saturationVolumetricMoistureContent="0.46" residualVolumetricMoistureContent="0.034"/>
|
||||
</greenery:GreeneryCatalog>
|
BIN
exports/energy_systems/__pycache__/__init__.cpython-38.pyc
Normal file
BIN
exports/energy_systems/__pycache__/__init__.cpython-38.pyc
Normal file
Binary file not shown.
Binary file not shown.
59
exports/energy_systems/air_source_hp_export.py
Normal file
59
exports/energy_systems/air_source_hp_export.py
Normal file
|
@ -0,0 +1,59 @@
|
|||
"""
|
||||
AirSourceHPExport exports air source values after executing insel.
|
||||
Multiple files are generated for the export
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2021 Project Author Peter Yefi peteryefi@gmail.com
|
||||
"""
|
||||
from exports.energy_systems.heat_pump_export import HeatPumpExport
|
||||
from typing import List, Tuple, Union
|
||||
|
||||
|
||||
class AirSourceHPExport(HeatPumpExport):
|
||||
"""
|
||||
Exports heat pump values as multiple files
|
||||
after executing insel
|
||||
"""
|
||||
|
||||
def __init__(self, base_path, city, output_path, sim_type):
|
||||
"""
|
||||
|
||||
:param base_path: path to energy system files
|
||||
:param city: the city object
|
||||
:param output_path: the file to hold insel simulation results
|
||||
:param sim_type: the simulation type to run: 1 for series, 0 for parallel
|
||||
"""
|
||||
tmp_file = 'heat_pumps/as_series.txt' if sim_type == 0 else 'heat_pumps/as_parallel.txt'
|
||||
template_path = (base_path / tmp_file)
|
||||
super().__init__(base_path, city, output_path, template_path)
|
||||
|
||||
def _extract_model_coff(self, hp_model: str, data_type='heat') -> Union[Tuple[List, List], None]:
|
||||
"""
|
||||
Extracts heat pump coefficient data for a specific
|
||||
model. e.g 012, 140
|
||||
:param hp_model: the model type
|
||||
:param data_type: indicates whether we're extracting cooling
|
||||
or heating perfarmcn coefficients
|
||||
:return:
|
||||
"""
|
||||
for energy_system in self._city.energy_systems:
|
||||
if energy_system.air_source_hp.model == hp_model:
|
||||
if data_type == 'heat':
|
||||
return energy_system.air_source_hp.heating_capacity_coff
|
||||
return energy_system.air_source_hp.cooling_capacity_coff
|
||||
return None
|
||||
|
||||
def execute_insel(self, user_input, hp_model, data_type):
|
||||
"""
|
||||
Runs insel and produces output files
|
||||
Runs insel and write the necessary files
|
||||
:param user_input: a dictionary containing the user
|
||||
values necessary to run insel
|
||||
:param hp_model: a string that indicates the heat
|
||||
pump model to be used e.g. 012, 015
|
||||
:param data_type: a string that indicates whether
|
||||
insel should run for heat or cooling performance
|
||||
:return:
|
||||
:return:
|
||||
"""
|
||||
capacity_coeff = self._extract_model_coff(hp_model, data_type)
|
||||
super(AirSourceHPExport, self)._run_insel(user_input, capacity_coeff, 'air_source.insel')
|
|
@ -1,5 +1,5 @@
|
|||
"""
|
||||
HeatPumpExport exports heatpump coefficient into several formats
|
||||
HeatPumpExport exports heatpump outputs into several files after insel execution
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2021 Project Author Peter Yefi peteryefi@gmail.com
|
||||
"""
|
||||
|
@ -16,8 +16,9 @@ class HeatPumpExport:
|
|||
of some defined function
|
||||
"""
|
||||
|
||||
def __init__(self, base_path, city, output_path):
|
||||
self._template_path = (base_path / 'heat_pumps/template.txt')
|
||||
def __init__(self, base_path, city, output_path, template, water_temp=None):
|
||||
self._template_path = template
|
||||
self._water_temp = water_temp
|
||||
self._constants_path = (base_path / 'heat_pumps/constants.yaml')
|
||||
# needed to compute max demand.
|
||||
self._demand_path = (base_path / 'heat_pumps/demand.txt')
|
||||
|
@ -26,21 +27,17 @@ class HeatPumpExport:
|
|||
self._base_path = base_path
|
||||
self._output_path = output_path
|
||||
|
||||
def run_insel(self, user_input: Dict, hp_model: str, data_type: str) -> None:
|
||||
def _run_insel(self, user_input: Dict, capacity_coeff: List, filename: str) -> None:
|
||||
"""
|
||||
Runs insel and write the necessary files
|
||||
:param user_input: a dictionary containing the user
|
||||
values necessary to run insel
|
||||
:param hp_model: a string that indicates the heat
|
||||
pump model to be used e.g. 012, 015
|
||||
:param data_type: a string that indicates whether
|
||||
insel should run for heat or cooling performance
|
||||
:param capacity_coeff: a list containing capacity coefficients
|
||||
:param filename: the name of the insel file to be created
|
||||
:return:
|
||||
"""
|
||||
self._input_data = user_input
|
||||
# update input data with other data necessary to run insel
|
||||
capacity_coff, comp_power_coff = self._extract_model_coff(hp_model, data_type)
|
||||
self._update_input_data_with_coff(capacity_coff, comp_power_coff)
|
||||
self._update_input_data_with_coff(capacity_coeff)
|
||||
# update input data with constants
|
||||
self._update_input_data_with_constants()
|
||||
# update input data with input and output files for insel
|
||||
|
@ -53,7 +50,7 @@ class HeatPumpExport:
|
|||
insel_template_content = insel_template_handler.read()
|
||||
insel_template = Template(insel_template_content).substitute(self._input_data)
|
||||
# create the insel file and write the template with substituted values into it
|
||||
insel_file = (self._base_path / 'heat_pumps/dompark_heat_pump.insel')
|
||||
insel_file = (self._base_path / 'heat_pumps' / filename)
|
||||
insel_file_handler = open(insel_file, "w")
|
||||
insel_file_handler.write(insel_template)
|
||||
# Now run insel
|
||||
|
@ -99,9 +96,15 @@ class HeatPumpExport:
|
|||
self._input_data['fileOut9']: ['Day', 'Daily Fuel Consumption of Auxiliary Heater (m3)'],
|
||||
self._input_data['fileOut10']: ['Year', 'Month', 'Day', 'Hour', 'HP Electricity Demand (kWh)']
|
||||
}
|
||||
|
||||
for file_path, header in header_data.items():
|
||||
file_path = file_path.strip("'")
|
||||
df = pd.read_csv(file_path, header=None, sep='\s+')
|
||||
# ignore ambient temperature for air source series run
|
||||
if df.shape[1] > 25:
|
||||
df.drop(columns=df.columns[-1],
|
||||
axis=1,
|
||||
inplace=True)
|
||||
df.to_csv(file_path, header=header)
|
||||
|
||||
def _update_input_data_with_files(self):
|
||||
|
@ -122,6 +125,9 @@ class HeatPumpExport:
|
|||
self._input_data["fileOut8"] = f"'{str((self._base_path / 'heat_pumps/monthly_hp_electricity_demand.csv'))}'"
|
||||
self._input_data["fileOut9"] = f"'{str((self._base_path / 'heat_pumps/daily_fossil_fuel_consumption.csv'))}'"
|
||||
self._input_data["fileOut10"] = f"'{str((self._base_path / 'heat_pumps/hp_hourly_electricity_demand.csv'))}'"
|
||||
# include water temperature for water to water heat pump
|
||||
if self._water_temp is not None:
|
||||
self._input_data['WaterTemperature'] = f"'{str(self._water_temp)}'"
|
||||
|
||||
def _delete_existing_output_files(self):
|
||||
"""
|
||||
|
@ -155,47 +161,49 @@ class HeatPumpExport:
|
|||
constants_dict = yaml.load(file, Loader=yaml.FullLoader)
|
||||
for key, value in constants_dict.items():
|
||||
self._input_data[key] = value
|
||||
# compute water to water HP specific values
|
||||
if 55 <= self._input_data['HPSupTemp'] <= 60:
|
||||
self._input_data["HPDisactivationTemperature"] = self._input_data["HPSupTemp"] - 5
|
||||
self._input_data["HPReactivationTemperature"] = self._input_data["HPSupTemp"] - 18
|
||||
elif 50 <= self._input_data["HPSupTemp"] < 55:
|
||||
self._input_data["HPDisactivationTemperature"] = self._input_data["HPSupTemp"] - 5
|
||||
self._input_data["HPReactivationTemperature"] = self._input_data["HPSupTemp"] - 13
|
||||
elif 45 <= self._input_data["HPSupTemp"] < 50:
|
||||
self._input_data["HPDisactivationTemperature"] = self._input_data["HPSupTemp"] - 3
|
||||
self._input_data["HPReactivationTemperature"] = self._input_data["HPSupTemp"] - 8
|
||||
elif 35 <= self._input_data["HPSupTemp"] < 40:
|
||||
self._input_data["HPDisactivationTemperature"] = self._input_data["HPSupTemp"] - 2
|
||||
self._input_data["HPReactivationTemperature"] = self._input_data["HPSupTemp"] - 4
|
||||
|
||||
# compute maximum demand. TODO: This should come from catalog in the future
|
||||
max_demand = self._compute_max_demand()
|
||||
# compute TESCapacity
|
||||
self._input_data["TESCapacity"] = self._input_data["HoursOfStorageAtMaxDemand"] * (max_demand * 3.6) / (
|
||||
(self._input_data["Cp"] / 1000) * self._input_data["TemperatureDifference"])
|
||||
|
||||
def _update_input_data_with_coff(self, capacity_coff: List, comp_power_coff: List):
|
||||
def _update_input_data_with_coff(self, a_coeff: List):
|
||||
"""
|
||||
Updates the user data with coefficients derived from imports
|
||||
:param capacity_coff: heat or cooling capacity coefficients
|
||||
:param comp_power_coff: heat or cooling comppressor power coefficients
|
||||
:param a_coeff: insel a coefficient values
|
||||
Meaning of a is in the models for air source heat pump
|
||||
and water to water source heat pump
|
||||
:return:
|
||||
"""
|
||||
self._input_data["a1"] = capacity_coff[0]
|
||||
self._input_data["a2"] = capacity_coff[1]
|
||||
self._input_data["a3"] = capacity_coff[2]
|
||||
self._input_data["a4"] = capacity_coff[3]
|
||||
self._input_data["a5"] = capacity_coff[4]
|
||||
self._input_data["a6"] = capacity_coff[5]
|
||||
self._input_data["b1"] = comp_power_coff[0]
|
||||
self._input_data["b2"] = comp_power_coff[1]
|
||||
self._input_data["b3"] = comp_power_coff[2]
|
||||
self._input_data["b4"] = comp_power_coff[3]
|
||||
self._input_data["b5"] = comp_power_coff[4]
|
||||
self._input_data["b6"] = comp_power_coff[5]
|
||||
|
||||
def _extract_model_coff(self, hp_model: str, data_type='heat') -> Union[Tuple[List, List], None]:
|
||||
"""
|
||||
Extracts heat pump coefficient data for a specific
|
||||
model. e.g 012, 140
|
||||
:param hp_model: the model type
|
||||
:param data_type: indicates whether we're extracting cooling
|
||||
or heating perfarmcn coefficients
|
||||
:return:
|
||||
"""
|
||||
for energy_system in self._city.energy_systems:
|
||||
if energy_system.heat_pump.model == hp_model:
|
||||
if data_type == 'heat':
|
||||
return energy_system.heat_pump.heating_capacity_coff, energy_system.heat_pump.heating_comp_power_coff
|
||||
return energy_system.heat_pump.cooling_capacity_coff, energy_system.heat_pump.cooling_comp_power_coff
|
||||
return None
|
||||
self._input_data["a1"] = a_coeff[0]
|
||||
self._input_data["a2"] = a_coeff[1]
|
||||
self._input_data["a3"] = a_coeff[2]
|
||||
self._input_data["a4"] = a_coeff[3]
|
||||
self._input_data["a5"] = a_coeff[4]
|
||||
self._input_data["a6"] = a_coeff[5]
|
||||
|
||||
# additional coefficients for water to water source
|
||||
if self._water_temp is not None:
|
||||
self._input_data["a7"] = a_coeff[6]
|
||||
self._input_data["a8"] = a_coeff[7]
|
||||
self._input_data["a9"] = a_coeff[8]
|
||||
self._input_data["a10"] = a_coeff[9]
|
||||
self._input_data["a11"] = a_coeff[10]
|
||||
|
||||
def _get_user_out_put(self):
|
||||
"""
|
||||
|
@ -209,8 +217,7 @@ class HeatPumpExport:
|
|||
|
||||
data = [electricity_df, fossil_df]
|
||||
df = pd.concat(data, axis=1)
|
||||
df = df.append(df.agg(['sum']))
|
||||
df = pd.concat([df, df.agg(['sum'])])
|
||||
s = pd.Series(["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "Total"])
|
||||
df = df.set_index([s])
|
||||
df.to_csv(self._output_path)
|
||||
|
||||
|
|
52
exports/energy_systems/water_to_water_hp_export.py
Normal file
52
exports/energy_systems/water_to_water_hp_export.py
Normal file
|
@ -0,0 +1,52 @@
|
|||
"""
|
||||
WaterToWaterHPExport exports water to water values after executing insel.
|
||||
Multiple files are generated for the export
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2021 Project Author Peter Yefi peteryefi@gmail.com
|
||||
"""
|
||||
from exports.energy_systems.heat_pump_export import HeatPumpExport
|
||||
from typing import List, Tuple, Union
|
||||
|
||||
|
||||
class WaterToWaterHPExport(HeatPumpExport):
|
||||
"""
|
||||
Exports heat pump values as multiple output files
|
||||
after executing insel
|
||||
"""
|
||||
|
||||
def __init__(self, base_path, city, output_path, sim_type):
|
||||
"""
|
||||
:param base_path: path to energy system files
|
||||
:param city: the city object
|
||||
:param output_path: the file to hold insel simulation results
|
||||
:param sim_type: the simulation type to run: 1 for series, 0 for parallel
|
||||
"""
|
||||
tmp_file = 'heat_pumps/w2w_series.txt' if sim_type == 0 else 'heat_pumps/w2w_parallel.txt'
|
||||
template_path = (base_path / tmp_file)
|
||||
water_temp = (base_path / 'heat_pumps/wt_hourly3.txt')
|
||||
super().__init__(base_path, city, output_path, template_path, water_temp)
|
||||
|
||||
def _extract_model_coff(self, hp_model: str) -> Union[List, None]:
|
||||
"""
|
||||
Extracts heat pump coefficient data for a specific
|
||||
model. e.g ClimateMaster 156 kW, etc
|
||||
:param hp_model: the model type
|
||||
:return:
|
||||
"""
|
||||
for energy_system in self._city.energy_systems:
|
||||
if energy_system.water_to_water_hp.model == hp_model:
|
||||
return energy_system.water_to_water_hp.power_demand_coff
|
||||
return None
|
||||
|
||||
def execute_insel(self, user_input, hp_model):
|
||||
"""
|
||||
Runs insel and produces output files
|
||||
Runs insel and write the necessary files
|
||||
:param user_input: a dictionary containing the user
|
||||
values necessary to run insel
|
||||
:param hp_model: a string that indicates the heat
|
||||
pump model to be used e.g. 012, 015
|
||||
:return:
|
||||
"""
|
||||
pow_demand_coeff = self._extract_model_coff(hp_model)
|
||||
super(WaterToWaterHPExport, self)._run_insel(user_input, pow_demand_coeff, 'w2w.insel')
|
|
@ -6,6 +6,8 @@ Copyright © 2020 Project Author Peter Yefi peteryefi@gmail.com
|
|||
|
||||
from pathlib import Path
|
||||
from exports.energy_systems.heat_pump_export import HeatPumpExport
|
||||
from exports.energy_systems.air_source_hp_export import AirSourceHPExport
|
||||
from exports.energy_systems.water_to_water_hp_export import WaterToWaterHPExport
|
||||
|
||||
|
||||
class EnergySystemsExportFactory:
|
||||
|
@ -13,28 +15,43 @@ class EnergySystemsExportFactory:
|
|||
Exports factory class for energy systems
|
||||
"""
|
||||
|
||||
def __init__(self, city, user_input, hp_model, output_path, data_type='heat', base_path=None):
|
||||
def __init__(self, city, user_input, hp_model, output_path, sim_type=0, data_type='heat', base_path=None):
|
||||
"""
|
||||
|
||||
:param city: the city object
|
||||
:param user_input: user provided input from UI
|
||||
:param hp_model: the heat pump model to run
|
||||
:param output_path: the file to hold simulation results
|
||||
:param sim_type: the simulation type, 0 for series 1 for parallel
|
||||
:param data_type: indicates whether cooling or heating data is used
|
||||
:param base_path: the data directory of energy systems
|
||||
"""
|
||||
self._city = city
|
||||
if base_path is None:
|
||||
base_path = base_path = Path(Path(__file__).parent.parent / 'data/energy_systems')
|
||||
base_path = Path(Path(__file__).parent.parent / 'data/energy_systems')
|
||||
self._base_path = base_path
|
||||
self._user_input = user_input
|
||||
self._hp_model = hp_model
|
||||
self._data_type = data_type
|
||||
self._output_path = output_path
|
||||
self._sim_type = sim_type
|
||||
|
||||
def _export_heat_pump(self):
|
||||
def _export_heat_pump(self, source):
|
||||
"""
|
||||
Exports heat pump performance data as coefficients
|
||||
of some objective function
|
||||
:return: None
|
||||
"""
|
||||
HeatPumpExport(self._base_path, self._city, self._output_path)\
|
||||
.run_insel(self._user_input, self._hp_model, self._data_type)
|
||||
if source == 'air':
|
||||
AirSourceHPExport(self._base_path, self._city, self._output_path, self._sim_type)\
|
||||
.execute_insel(self._user_input, self._hp_model, self._data_type)
|
||||
elif source == 'water':
|
||||
WaterToWaterHPExport(self._base_path, self._city, self._output_path, self._sim_type)\
|
||||
.execute_insel(self._user_input, self._hp_model)
|
||||
|
||||
def export(self):
|
||||
def export(self, source='air'):
|
||||
"""
|
||||
Export the city given to the class using the given export type handler
|
||||
:return: None
|
||||
"""
|
||||
return getattr(self, '_export_heat_pump', lambda: None)()
|
||||
return getattr(self, '_export_heat_pump', lambda: None)(source)
|
||||
|
|
|
@ -3,6 +3,7 @@ TestOccupancyFactory test and validate the city model structure schedules parame
|
|||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Soroush Samareh Abolhassani - soroush.samarehabolhassani@mail.concordia.ca
|
||||
"""
|
||||
|
||||
from geomeppy import IDF
|
||||
|
||||
|
||||
|
@ -18,6 +19,7 @@ class Idf:
|
|||
_MATERIAL_NOMASS = 'MATERIAL:NOMASS'
|
||||
_ROUGHNESS = 'MediumRough'
|
||||
_HOURLY_SCHEDULE = 'SCHEDULE:DAY:HOURLY'
|
||||
_COMPACT_SCHEDULE = 'SCHEDULE:COMPACT'
|
||||
_ZONE = 'ZONE'
|
||||
_LIGHTS = 'LIGHTS'
|
||||
_PEOPLE = 'PEOPLE'
|
||||
|
@ -28,8 +30,8 @@ class Idf:
|
|||
_ON_OFF = 'On/Off'
|
||||
_FRACTION = 'Fraction'
|
||||
_ANY_NUMBER = 'Any Number'
|
||||
_CONTINUOUS = 'CONTINUOUS'
|
||||
_DISCRETE = 'DISCRETE'
|
||||
_CONTINUOUS = 'Continuous'
|
||||
_DISCRETE = 'Discrete'
|
||||
|
||||
idf_surfaces = {
|
||||
# todo: make an enum for all the surface types
|
||||
|
@ -42,9 +44,18 @@ class Idf:
|
|||
'residential': 'residential_building'
|
||||
}
|
||||
|
||||
idf_type_limits = {
|
||||
'on_off': 'on/off',
|
||||
'fraction': 'Fraction',
|
||||
'any_number': 'Any Number',
|
||||
'continuous': 'Continuous',
|
||||
'discrete': 'Discrete'
|
||||
}
|
||||
|
||||
def __init__(self, city, output_path, idf_file_path, idd_file_path, epw_file_path, export_type="Surfaces"):
|
||||
self._city = city
|
||||
self._output_path = str((output_path / f'{city.name}.idf').resolve())
|
||||
self._output_path = str(output_path.resolve())
|
||||
self._output_file = str((output_path / f'{city.name}.idf').resolve())
|
||||
self._export_type = export_type
|
||||
self._idd_file_path = str(idd_file_path)
|
||||
self._idf_file_path = str(idf_file_path)
|
||||
|
@ -59,10 +70,13 @@ class Idf:
|
|||
self._export()
|
||||
|
||||
@staticmethod
|
||||
def _matrix_to_list(points):
|
||||
def _matrix_to_list(points, lower_corner):
|
||||
lower_x = lower_corner[0]
|
||||
lower_y = lower_corner[1]
|
||||
lower_z = lower_corner[2]
|
||||
points_list = []
|
||||
for point in points:
|
||||
point_tuple = (point[0], point[1], point[2])
|
||||
point_tuple = (point[0]-lower_x, point[1]-lower_y, point[2]-lower_z)
|
||||
points_list.append(point_tuple)
|
||||
return points_list
|
||||
|
||||
|
@ -103,41 +117,71 @@ class Idf:
|
|||
Visible_Absorptance=layer.material.visible_absorptance
|
||||
)
|
||||
|
||||
def _add_schedule(self, usage_zone, schedule_type, limit_name='Any Number'):
|
||||
def _add_daily_schedule(self, usage_zone, schedule):
|
||||
_schedule = self._idf.newidfobject(self._COMPACT_SCHEDULE, Name=f'{schedule.type} schedules {usage_zone.usage}')
|
||||
_val = schedule.values
|
||||
_schedule.Schedule_Type_Limits_Name = self.idf_type_limits[schedule.data_type.lower()]
|
||||
_schedule.Field_1 = "Through: 12/31"
|
||||
_schedule.Field_2 = "For: AllDays"
|
||||
_schedule.Field_3 = "Until: 01:00"
|
||||
_schedule.Field_4 = _val[0]
|
||||
_schedule.Field_5 = "Until: 02:00"
|
||||
_schedule.Field_6 = _val[1]
|
||||
_schedule.Field_7 = "Until: 03:00"
|
||||
_schedule.Field_8 = _val[2]
|
||||
_schedule.Field_9 = "Until: 04:00"
|
||||
_schedule.Field_10 = _val[3]
|
||||
_schedule.Field_11 = "Until: 05:00"
|
||||
_schedule.Field_12 = _val[4]
|
||||
_schedule.Field_13 = "Until: 06:00"
|
||||
_schedule.Field_14 = _val[5]
|
||||
_schedule.Field_15 = "Until: 07:00"
|
||||
_schedule.Field_16 = _val[6]
|
||||
_schedule.Field_17 = "Until: 08:00"
|
||||
_schedule.Field_18 = _val[7]
|
||||
_schedule.Field_19 = "Until: 09:00"
|
||||
_schedule.Field_20 = _val[8]
|
||||
_schedule.Field_21 = "Until: 10:00"
|
||||
_schedule.Field_22 = _val[9]
|
||||
_schedule.Field_23 = "Until: 11:00"
|
||||
_schedule.Field_24 = _val[10]
|
||||
_schedule.Field_25 = "Until: 12:00"
|
||||
_schedule.Field_26 = _val[11]
|
||||
_schedule.Field_27 = "Until: 13:00"
|
||||
_schedule.Field_28 = _val[12]
|
||||
_schedule.Field_29 = "Until: 14:00"
|
||||
_schedule.Field_30 = _val[13]
|
||||
_schedule.Field_31 = "Until: 15:00"
|
||||
_schedule.Field_32 = _val[14]
|
||||
_schedule.Field_33 = "Until: 16:00"
|
||||
_schedule.Field_34 = _val[15]
|
||||
_schedule.Field_35 = "Until: 17:00"
|
||||
_schedule.Field_36 = _val[16]
|
||||
_schedule.Field_37 = "Until: 18:00"
|
||||
_schedule.Field_38 = _val[17]
|
||||
_schedule.Field_39 = "Until: 19:00"
|
||||
_schedule.Field_40 = _val[18]
|
||||
_schedule.Field_41 = "Until: 20:00"
|
||||
_schedule.Field_42 = _val[19]
|
||||
_schedule.Field_43 = "Until: 21:00"
|
||||
_schedule.Field_44 = _val[20]
|
||||
_schedule.Field_45 = "Until: 22:00"
|
||||
_schedule.Field_46 = _val[21]
|
||||
_schedule.Field_47 = "Until: 23:00"
|
||||
_schedule.Field_48 = _val[22]
|
||||
_schedule.Field_49 = "Until: 24:00"
|
||||
_schedule.Field_50 = _val[23]
|
||||
|
||||
def _add_schedule(self, usage_zone, schedule_type):
|
||||
for schedule in self._idf.idfobjects[self._HOURLY_SCHEDULE]:
|
||||
if schedule.Name == f'{schedule_type} schedules {usage_zone.usage}':
|
||||
return
|
||||
if usage_zone.schedules is None or schedule_type not in usage_zone.schedules:
|
||||
# there are no schedule for this type
|
||||
return
|
||||
schedule = self._idf.newidfobject(self._HOURLY_SCHEDULE, Name=f'{schedule_type} schedules {usage_zone.usage}')
|
||||
schedule.Schedule_Type_Limits_Name = limit_name
|
||||
|
||||
schedule.Hour_1 = usage_zone.schedules[schedule_type]["WD"][0]
|
||||
schedule.Hour_2 = usage_zone.schedules[schedule_type]["WD"][1]
|
||||
schedule.Hour_3 = usage_zone.schedules[schedule_type]["WD"][2]
|
||||
schedule.Hour_4 = usage_zone.schedules[schedule_type]["WD"][3]
|
||||
schedule.Hour_5 = usage_zone.schedules[schedule_type]["WD"][4]
|
||||
schedule.Hour_6 = usage_zone.schedules[schedule_type]["WD"][5]
|
||||
schedule.Hour_7 = usage_zone.schedules[schedule_type]["WD"][6]
|
||||
schedule.Hour_8 = usage_zone.schedules[schedule_type]["WD"][7]
|
||||
schedule.Hour_9 = usage_zone.schedules[schedule_type]["WD"][8]
|
||||
schedule.Hour_10 = usage_zone.schedules[schedule_type]["WD"][9]
|
||||
schedule.Hour_11 = usage_zone.schedules[schedule_type]["WD"][10]
|
||||
schedule.Hour_12 = usage_zone.schedules[schedule_type]["WD"][11]
|
||||
schedule.Hour_13 = usage_zone.schedules[schedule_type]["WD"][12]
|
||||
schedule.Hour_14 = usage_zone.schedules[schedule_type]["WD"][13]
|
||||
schedule.Hour_15 = usage_zone.schedules[schedule_type]["WD"][14]
|
||||
schedule.Hour_16 = usage_zone.schedules[schedule_type]["WD"][15]
|
||||
schedule.Hour_17 = usage_zone.schedules[schedule_type]["WD"][16]
|
||||
schedule.Hour_18 = usage_zone.schedules[schedule_type]["WD"][17]
|
||||
schedule.Hour_19 = usage_zone.schedules[schedule_type]["WD"][18]
|
||||
schedule.Hour_20 = usage_zone.schedules[schedule_type]["WD"][19]
|
||||
schedule.Hour_21 = usage_zone.schedules[schedule_type]["WD"][20]
|
||||
schedule.Hour_22 = usage_zone.schedules[schedule_type]["WD"][21]
|
||||
schedule.Hour_23 = usage_zone.schedules[schedule_type]["WD"][22]
|
||||
schedule.Hour_24 = usage_zone.schedules[schedule_type]["WD"][23]
|
||||
|
||||
for schedule in usage_zone.schedules:
|
||||
if schedule.type == schedule_type:
|
||||
if schedule.time_range == "day":
|
||||
return self._add_daily_schedule(usage_zone, schedule)
|
||||
return
|
||||
|
||||
def _add_construction(self, thermal_boundary):
|
||||
for construction in self._idf.idfobjects[self._CONSTRUCTION]:
|
||||
if construction.Name == thermal_boundary.construction_name:
|
||||
|
@ -183,7 +227,9 @@ class Idf:
|
|||
thermostat = self._add_thermostat(usage_zone)
|
||||
self._idf.newidfobject(self._IDEAL_LOAD_AIR_SYSTEM,
|
||||
Zone_Name=usage_zone.id,
|
||||
Cooling_Availability_Schedule_Name=f'Refrigeration schedules {usage_zone.usage}',
|
||||
System_Availability_Schedule_Name=f'HVAC AVAIL SCHEDULES {usage_zone.usage}',
|
||||
Heating_Availability_Schedule_Name=f'HVAC AVAIL SCHEDULES {usage_zone.usage}',
|
||||
Cooling_Availability_Schedule_Name=f'HVAC AVAIL SCHEDULES {usage_zone.usage}',
|
||||
Template_Thermostat_Name=thermostat.Name)
|
||||
|
||||
def _add_occupancy(self, usage_zone):
|
||||
|
@ -194,7 +240,7 @@ class Idf:
|
|||
Number_of_People_Calculation_Method="People",
|
||||
Number_of_People=500, # todo: get people from where?
|
||||
Fraction_Radiant=0.3, # todo: howto get this from InternalGains
|
||||
Activity_Level_Schedule_Name='occupant schedules'
|
||||
Activity_Level_Schedule_Name=f'Occupancy schedules {usage_zone.usage}'
|
||||
)
|
||||
|
||||
def _add_equipment(self, usage_zone):
|
||||
|
@ -227,17 +273,19 @@ class Idf:
|
|||
Export the idf file into the given path
|
||||
export type = "Surfaces|Block"
|
||||
"""
|
||||
|
||||
for building in self._city.buildings:
|
||||
for usage_zone in building.usage_zones:
|
||||
self._add_schedule(usage_zone, "Infiltration")
|
||||
self._add_schedule(usage_zone, "Lights")
|
||||
self._add_schedule(usage_zone, "Occupancy")
|
||||
self._add_schedule(usage_zone, "Refrigeration", self._ON_OFF)
|
||||
self._add_schedule(usage_zone, "Refrigeration")
|
||||
self._add_schedule(usage_zone, "HVAC Avail")
|
||||
|
||||
self._add_zone(usage_zone)
|
||||
self._add_heating_system(usage_zone)
|
||||
# self._add_infiltration(usage_zone)
|
||||
# self._add_occupancy(usage_zone)
|
||||
self._add_infiltration(usage_zone)
|
||||
self._add_occupancy(usage_zone)
|
||||
for thermal_zone in building.thermal_zones:
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
self._add_construction(thermal_boundary)
|
||||
|
@ -246,8 +294,27 @@ class Idf:
|
|||
self._add_surfaces(building)
|
||||
else:
|
||||
self._add_block(building)
|
||||
self._idf.newidfobject(
|
||||
"OUTPUT:VARIABLE",
|
||||
Variable_Name="Zone Ideal Loads Supply Air Total Heating Energy",
|
||||
Reporting_Frequency="Hourly",
|
||||
)
|
||||
self._idf.newidfobject(
|
||||
"OUTPUT:VARIABLE",
|
||||
Variable_Name="Zone Ideal Loads Supply Air Total Cooling Energy",
|
||||
Reporting_Frequency="Hourly",
|
||||
)
|
||||
self._idf.match()
|
||||
self._idf.saveas(str(self._output_path))
|
||||
self._idf.intersect_match()
|
||||
self._idf.saveas(str(self._output_file))
|
||||
return self._idf
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
Start the energy plus simulation
|
||||
"""
|
||||
self._idf.run(expandobjects=True, readvars=True, output_directory=self._output_path,
|
||||
output_prefix=f'{self._city.name}_')
|
||||
|
||||
def _add_block(self, building):
|
||||
_points = self._matrix_to_2d_list(building.foot_print.coordinates)
|
||||
|
@ -267,6 +334,7 @@ class Idf:
|
|||
self._idf.intersect_match()
|
||||
|
||||
def _add_surfaces(self, building):
|
||||
|
||||
for thermal_zone in building.thermal_zones:
|
||||
for boundary in thermal_zone.thermal_boundaries:
|
||||
idf_surface_type = self.idf_surfaces[boundary.surface.type]
|
||||
|
@ -274,5 +342,5 @@ class Idf:
|
|||
surface = self._idf.newidfobject(self._SURFACE, Name=f'{boundary.surface.name}',
|
||||
Surface_Type=idf_surface_type, Zone_Name=usage_zone.id,
|
||||
Construction_Name=boundary.construction_name)
|
||||
coordinates = self._matrix_to_list(boundary.surface.solid_polygon.coordinates)
|
||||
coordinates = self._matrix_to_list(boundary.surface.solid_polygon.coordinates, self._city.lower_corner)
|
||||
surface.setcoords(coordinates)
|
||||
|
|
|
@ -122,8 +122,8 @@
|
|||
No, !- Do Zone Sizing Calculation
|
||||
No, !- Do System Sizing Calculation
|
||||
No, !- Do Plant Sizing Calculation
|
||||
Yes, !- Run Simulation for Sizing Periods
|
||||
No, !- Run Simulation for Weather File Run Periods
|
||||
No, !- Run Simulation for Sizing Periods
|
||||
Yes, !- Run Simulation for Weather File Run Periods
|
||||
No, !- Do HVAC Sizing Simulation for Sizing Periods
|
||||
1; !- Maximum Number of HVAC Sizing Simulation Passes
|
||||
|
||||
|
@ -149,3 +149,4 @@
|
|||
Output:Table:SummaryReports,
|
||||
AllSummary; !- Report 1 Name
|
||||
|
||||
Output:Diagnostics,DisplayUnusedSchedules;
|
|
@ -32,7 +32,8 @@ class YearlyFromDailySchedules:
|
|||
|
||||
values = []
|
||||
for month in range(1, 13):
|
||||
for day in range(1, cal.monthlen(self._year, month)+1):
|
||||
_, number_days = cal.monthrange(self._year, month)
|
||||
for day in range(1, number_days+1):
|
||||
week_day = cal.weekday(self._year, month, day)
|
||||
values.extend(weekly_schedules[week_day])
|
||||
yearly_schedule.type = self._daily_schedules[0].type
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
"""
|
||||
XlsxHeatPumpParameters import the heat pump information
|
||||
AirSourceHeatPumpParameters import the heat pump information
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Peter Yefi peteryefi@gmail.com
|
||||
Contributor Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
|
@ -7,7 +7,7 @@ Contributor Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
|||
|
||||
import pandas as pd
|
||||
from typing import Dict
|
||||
from city_model_structure.energy_systems.heat_pump import HeatPump
|
||||
from city_model_structure.energy_systems.air_source_hp import AirSourceHP
|
||||
from city_model_structure.energy_system import EnergySystem
|
||||
from scipy.optimize import curve_fit
|
||||
import numpy as np
|
||||
|
@ -15,14 +15,14 @@ from typing import List
|
|||
import itertools
|
||||
|
||||
|
||||
class XlsxHeatPumpParameters:
|
||||
class AirSourceHeatPumpParameters:
|
||||
"""
|
||||
XlsxHeatPumpParameters class
|
||||
AirSourceHeatPumpParameters class
|
||||
"""
|
||||
|
||||
def __init__(self, city, base_path):
|
||||
self._city = city
|
||||
self._base_path = (base_path / 'heat_pumps/Air Source.xlsx')
|
||||
self._base_path = (base_path / 'heat_pumps/Air source.xlsx')
|
||||
|
||||
def _read_file(self) -> Dict:
|
||||
"""
|
||||
|
@ -31,6 +31,7 @@ class XlsxHeatPumpParameters:
|
|||
:return : Dict
|
||||
"""
|
||||
xl_file = pd.ExcelFile(self._base_path)
|
||||
|
||||
heat_pump_dfs = {sheet_name: xl_file.parse(sheet_name)
|
||||
for sheet_name in xl_file.sheet_names}
|
||||
|
||||
|
@ -38,8 +39,10 @@ class XlsxHeatPumpParameters:
|
|||
heating_data = {}
|
||||
|
||||
for sheet, dataframe in heat_pump_dfs.items():
|
||||
if sheet == "Summary":
|
||||
continue
|
||||
|
||||
if 'Summary' in sheet:
|
||||
continue
|
||||
|
||||
# Remove nan rows and columns and extract cooling and heating data
|
||||
# for each sheet
|
||||
df = heat_pump_dfs[sheet].dropna(axis=1, how='all')
|
||||
|
@ -65,24 +68,22 @@ class XlsxHeatPumpParameters:
|
|||
"""
|
||||
Enriches the city with information from file
|
||||
"""
|
||||
heap_pump_data = self._read_file()
|
||||
heat_pump_data = self._read_file()
|
||||
for (k_cool, v_cool), (k_heat, v_heat) in \
|
||||
zip(heap_pump_data["cooling"].items(), heap_pump_data["heating"].items()):
|
||||
heat_pump = HeatPump()
|
||||
zip(heat_pump_data["cooling"].items(), heat_pump_data["heating"].items()):
|
||||
heat_pump = AirSourceHP()
|
||||
heat_pump.model = k_cool
|
||||
h_data = self._extract_heat_pump_data(v_heat)
|
||||
c_data = self._extract_heat_pump_data(v_cool)
|
||||
heat_pump.cooling_capacity = c_data[0]
|
||||
heat_pump.cooling_comp_power = c_data[1]
|
||||
heat_pump.cooling_capacity_coff = self._compute_coefficients(c_data[0], "cool")
|
||||
heat_pump.cooling_comp_power_coff = self._compute_coefficients(c_data[1], "cool")
|
||||
heat_pump.cooling_capacity_coff = self._compute_coefficients(c_data, "cool")
|
||||
heat_pump.heating_capacity = h_data[0]
|
||||
heat_pump.heating_comp_power = h_data[1]
|
||||
heat_pump.heating_capacity_coff = self._compute_coefficients(h_data[0])
|
||||
heat_pump.heating_comp_power_coff = self._compute_coefficients(h_data[1])
|
||||
heat_pump.heating_capacity_coff = self._compute_coefficients(h_data)
|
||||
|
||||
energy_system = EnergySystem('{} capacity heat pump'.format(heat_pump.model), 0, [], None)
|
||||
energy_system.heat_pump = heat_pump
|
||||
energy_system.air_source_hp = heat_pump
|
||||
self._city.add_city_object(energy_system)
|
||||
return self._city
|
||||
|
||||
|
@ -121,10 +122,13 @@ class XlsxHeatPumpParameters:
|
|||
x_values = heat_x_values if data_type == "heat" else cool_x_values
|
||||
x_values = x_values.tolist()
|
||||
# convert list of lists to one list
|
||||
heat_pump_data = list(itertools.chain.from_iterable(heat_pump_data))
|
||||
|
||||
hp_data = [i/j for i, j in
|
||||
zip(list(itertools.chain.from_iterable(heat_pump_data[0])),
|
||||
list(itertools.chain.from_iterable(heat_pump_data[1])))]
|
||||
|
||||
# Compute heat output coefficients
|
||||
popt, _ = curve_fit(self._objective_function, [x_values, out_temp], heat_pump_data)
|
||||
popt, _ = curve_fit(self._objective_function, [x_values, out_temp], hp_data)
|
||||
return popt.tolist()
|
||||
|
||||
def _objective_function(self, xdata: List, a1: float, a2: float, a3: float, a4: float, a5: float, a6: float) -> float:
|
169
imports/energy_systems/water_to_water_hp_parameters.py
Normal file
169
imports/energy_systems/water_to_water_hp_parameters.py
Normal file
|
@ -0,0 +1,169 @@
|
|||
"""
|
||||
WaterToWaterHPParameters import the heat pump information
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2021 Project Author Peter Yefi peteryefi@gmail.com
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
from typing import Dict
|
||||
from city_model_structure.energy_systems.water_to_water_hp import WaterToWaterHP
|
||||
from city_model_structure.energy_system import EnergySystem
|
||||
from scipy.optimize import curve_fit
|
||||
import numpy as np
|
||||
from typing import List
|
||||
|
||||
|
||||
class WaterToWaterHPParameters:
|
||||
"""
|
||||
WaterToWaterHPParameters class
|
||||
"""
|
||||
|
||||
def __init__(self, city, base_path):
|
||||
self._city = city
|
||||
self._base_path = (base_path / 'heat_pumps/water_to_water.xlsx')
|
||||
|
||||
def _read_file(self) -> Dict:
|
||||
"""
|
||||
reads xlsx file containing water to water heat pump information
|
||||
into a dictionary
|
||||
:return : Dict
|
||||
"""
|
||||
xl_file = pd.ExcelFile(self._base_path)
|
||||
heat_pump_dfs = {sheet_name: xl_file.parse(sheet_name)
|
||||
for sheet_name in xl_file.sheet_names}
|
||||
|
||||
hp_data = {}
|
||||
flow_rates = {
|
||||
'156': [2.84, 4.23, 5.68],
|
||||
'256': [4.73, 7.13, 9.446],
|
||||
'335': [6.62, 9.97, 12.93],
|
||||
}
|
||||
|
||||
for sheet, dataframe in heat_pump_dfs.items():
|
||||
|
||||
df = heat_pump_dfs[sheet].dropna(axis=1, how='all')
|
||||
df = df.iloc[3:, 6:35]
|
||||
|
||||
if '156' in sheet:
|
||||
hp_data[sheet] = self._extract_required_hp_data(df, [0, 10, 25, 40, 55, 67], flow_rates['156'])
|
||||
elif '256' in sheet:
|
||||
hp_data[sheet] = self._extract_required_hp_data(df, [0, 9, 24, 39, 54, 66], flow_rates['256'])
|
||||
elif '335' in sheet:
|
||||
hp_data[sheet] = self._extract_required_hp_data(df, [0, 11, 26, 41, 56, 69], flow_rates['335'])
|
||||
|
||||
return hp_data
|
||||
|
||||
def _extract_required_hp_data(self, dataframe, ranges, flow_rates):
|
||||
"""
|
||||
Extracts 156 Kw water to water heat pump data
|
||||
:param dataframe: dataframe containing all data
|
||||
:param ranges: the range of values to extract
|
||||
:param flow_rates: the flow rates of water through pump
|
||||
:return: Dict
|
||||
"""
|
||||
# extract data rows and columns
|
||||
data = {'tc': self._extract_hp_data(dataframe, [1, 11, 21], ranges),
|
||||
'pd': self._extract_hp_data(dataframe, [2, 12, 22], ranges),
|
||||
'lwt': self._extract_hp_data(dataframe, [5, 15, 25], ranges),
|
||||
'fr': (self._extract_flow_and_ewt(dataframe, ranges, [1, 11, 21], flow_rates))[0],
|
||||
'ewt': (self._extract_flow_and_ewt(dataframe, ranges, [1, 11, 21], flow_rates))[1]}
|
||||
# range values for extracting data
|
||||
return data
|
||||
|
||||
def _extract_hp_data(self, df, columns, ranges):
|
||||
"""
|
||||
Extract variable specific (LWT, PD or TC) data from water to water hp
|
||||
:param df: the dataframe
|
||||
:param columns: the columns to extract data from
|
||||
:param ranges: the range of values to extract
|
||||
:return: List
|
||||
"""
|
||||
data = df.iloc[ranges[0]:ranges[1], columns[0]].append(df.iloc[ranges[0]:ranges[1], columns[1]])\
|
||||
.append(df.iloc[ranges[0]:ranges[1], columns[2]])
|
||||
for i in range(1, 5):
|
||||
data = data.append(df.iloc[ranges[i]:ranges[i + 1], columns[0]]).append(
|
||||
df.iloc[ranges[i]:ranges[i + 1], columns[1]]).append(df.iloc[ranges[i]:ranges[i + 1], columns[2]])
|
||||
return data.dropna().values.tolist()
|
||||
|
||||
def _extract_flow_and_ewt(self, df, ranges, columns, flow_rates):
|
||||
"""
|
||||
Create the flow and ewt data based on the length of the various
|
||||
columns for the variables being extracted
|
||||
:param df: the dataframe
|
||||
:param ranges: the range of values to extract
|
||||
:param columns: the columns to extract data from
|
||||
:param flow_rates: flow rate values
|
||||
:return:
|
||||
"""
|
||||
ewt_values = [-1.111111111, 4.444444444, 10, 15.55555556, 21.11111111]
|
||||
length = [len(df.iloc[ranges[0]:ranges[1], columns[0]].dropna()),
|
||||
len(df.iloc[ranges[0]:ranges[1], columns[1]].dropna()),
|
||||
len(df.iloc[ranges[0]:ranges[1], columns[2]].dropna())]
|
||||
|
||||
ewt_data = np.repeat(ewt_values[0], sum(length))
|
||||
flow_rates_data = np.repeat(flow_rates, length)
|
||||
|
||||
for i in range(1, 5):
|
||||
length = [len(df.iloc[ranges[i]:ranges[i + 1], columns[0]].dropna()),
|
||||
len(df.iloc[ranges[i]:ranges[i + 1], columns[1]].dropna()),
|
||||
len(df.iloc[ranges[i]:ranges[i + 1], columns[2]].dropna())]
|
||||
flow_rates_data = np.append(flow_rates_data, np.repeat(flow_rates, length))
|
||||
ewt_data = np.append(ewt_data, np.repeat(ewt_values[i], sum(length)))
|
||||
|
||||
return flow_rates_data.tolist(), ewt_data.tolist()
|
||||
|
||||
def enrich_city(self):
|
||||
"""
|
||||
Enriches the city with information from file
|
||||
"""
|
||||
heap_pump_data = self._read_file()
|
||||
for model, data in heap_pump_data.items():
|
||||
heat_pump = WaterToWaterHP()
|
||||
heat_pump.model = model.strip()
|
||||
heat_pump.total_cooling_capacity = data['tc']
|
||||
heat_pump.power_demand = data['pd']
|
||||
heat_pump.flow_rate = data['fr']
|
||||
heat_pump.entering_water_temp = data['ewt']
|
||||
heat_pump.leaving_water_temp = data['lwt']
|
||||
heat_pump.power_demand_coff = self._compute_coefficients(data)
|
||||
energy_system = EnergySystem(heat_pump.model, 0, [], None)
|
||||
energy_system.water_to_water_hp = heat_pump
|
||||
self._city.add_city_object(energy_system)
|
||||
return self._city
|
||||
|
||||
def _compute_coefficients(self, heat_pump_data: Dict) -> List[float]:
|
||||
"""
|
||||
Compute heat output and electrical demand coefficients
|
||||
from heating performance data
|
||||
:param heat_pump_data: a dictionary of heat pump data.
|
||||
:return: Tuple[Dict, Dict]
|
||||
"""
|
||||
demand = [i / j for i, j in zip(heat_pump_data['tc'], heat_pump_data['pd'])]
|
||||
|
||||
# Compute heat output coefficients
|
||||
popt, _ = curve_fit(self._objective_function, [heat_pump_data['ewt'], heat_pump_data['lwt'], heat_pump_data['fr']],
|
||||
demand)
|
||||
return popt.tolist()
|
||||
|
||||
def _objective_function(self, xdata: List, a1: float, a2: float, a3: float, a4: float, a5: float, a6: float,
|
||||
a7: float, a8: float, a9: float, a10: float, a11: float) -> float:
|
||||
"""
|
||||
Objective function for computing coefficients
|
||||
:param xdata:
|
||||
:param a1: float
|
||||
:param a2: float
|
||||
:param a3: float
|
||||
:param a4: float
|
||||
:param a5: float
|
||||
:param a6: float
|
||||
:param a7: float
|
||||
:param a8: float
|
||||
:param a9: float
|
||||
:param a10: float
|
||||
:param a11: float
|
||||
:return:
|
||||
"""
|
||||
x, y, t = xdata
|
||||
return (a1 * x ** 2) + (a2 * x) + (a3 * y ** 2) + (a4 * y) + (a5 * t ** 2) + (a6 * t) + (a7 * x * y) + (
|
||||
a8 * x * t) + (a9 * y * t) + (a10 * x * y * t) + a11
|
||||
|
|
@ -2,9 +2,11 @@
|
|||
EnergySystemsFactory retrieve the energy system module for the given region
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Pilar Monsalvete pilar.monsalvete@concordi.ca
|
||||
Contributor Peter Yefi peteryefi@gmail.com
|
||||
"""
|
||||
from pathlib import Path
|
||||
from imports.energy_systems.xlsx_heat_pump_parameters import XlsxHeatPumpParameters
|
||||
from imports.energy_systems.air_source_hp_parameters import AirSourceHeatPumpParameters
|
||||
from imports.energy_systems.water_to_water_hp_parameters import WaterToWaterHPParameters
|
||||
|
||||
|
||||
class EnergySystemsFactory:
|
||||
|
@ -19,11 +21,17 @@ class EnergySystemsFactory:
|
|||
self._city = city
|
||||
self._base_path = base_path
|
||||
|
||||
def _xlsx_heat_pump(self):
|
||||
def _air_source_hp(self):
|
||||
"""
|
||||
Enrich the city by using xlsx heat pump information
|
||||
"""
|
||||
XlsxHeatPumpParameters(self._city, self._base_path).enrich_city()
|
||||
AirSourceHeatPumpParameters(self._city, self._base_path).enrich_city()
|
||||
|
||||
def _water_to_water_hp(self):
|
||||
"""
|
||||
Enrich the city by using water to water heat pump information
|
||||
"""
|
||||
WaterToWaterHPParameters(self._city, self._base_path).enrich_city()
|
||||
|
||||
def enrich(self):
|
||||
"""
|
||||
|
|
|
@ -3,6 +3,7 @@ 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
|
||||
|
|
|
@ -15,4 +15,6 @@ parseidf~=1.0.0
|
|||
ply~=3.11
|
||||
rhino3dm~=7.11.1
|
||||
scipy==1.7.1
|
||||
PyYAML==6.0
|
||||
PyYAML==6.0
|
||||
yaml~=0.2.5
|
||||
pyecore~=0.12.2
|
|
@ -7,7 +7,7 @@ import pandas as pd
|
|||
from unittest import TestCase
|
||||
from imports.geometry_factory import GeometryFactory
|
||||
from imports.energy_systems_factory import EnergySystemsFactory
|
||||
from city_model_structure.energy_systems.heat_pump import HeatPump
|
||||
from city_model_structure.energy_systems.air_source_hp import AirSourceHP
|
||||
from exports.energy_systems_factory import EnergySystemsExportFactory
|
||||
import os
|
||||
|
||||
|
@ -23,17 +23,17 @@ class TestEnergySystemsFactory(TestCase):
|
|||
:return: None
|
||||
"""
|
||||
city_file = "../unittests/tests_data/C40_Final.gml"
|
||||
self._output_path = "../unittests/tests_data/user_output.csv"
|
||||
self._output_path = "../unittests/tests_data/as_user_output.csv"
|
||||
self._city = GeometryFactory('citygml', city_file).city
|
||||
EnergySystemsFactory('xlsx heat pump', self._city).enrich()
|
||||
EnergySystemsFactory('air source hp', self._city).enrich()
|
||||
|
||||
def test_heat_pump_import(self):
|
||||
def test_air_source_heat_pump_import(self):
|
||||
self.assertIsNotNone(self._city.energy_systems, 'City has energy systems')
|
||||
self.assertIsInstance(self._city.energy_systems[0].heat_pump, HeatPump)
|
||||
self.assertEqual(self._city.energy_systems[0].heat_pump.model, '012')
|
||||
self.assertEqual(self._city.energy_systems[len(self._city.energy_systems) - 1].heat_pump.model, '140')
|
||||
self.assertIsInstance(self._city.energy_systems[0].air_source_hp, AirSourceHP)
|
||||
self.assertEqual(self._city.energy_systems[0].air_source_hp.model, '012')
|
||||
self.assertEqual(self._city.energy_systems[16].air_source_hp.model, '140')
|
||||
|
||||
def test_heat_pump_export(self):
|
||||
def test_air_source_heat_pump_export(self):
|
||||
# User defined paramenters
|
||||
user_input = {
|
||||
'StartYear': 2020,
|
||||
|
@ -52,7 +52,7 @@ class TestEnergySystemsFactory(TestCase):
|
|||
EnergySystemsExportFactory(self._city, user_input, '012', self._output_path).export()
|
||||
df = pd.read_csv(self._output_path)
|
||||
self.assertEqual(df.shape, (13, 3))
|
||||
self.assertEqual(df.iloc[0, 1], 3045398.0)
|
||||
self.assertEqual(df.iloc[0, 1], 1867715.88)
|
||||
|
||||
def tearDown(self) -> None:
|
||||
try:
|
63
unittests/test_energy_systems_water_to_water_hp.py
Normal file
63
unittests/test_energy_systems_water_to_water_hp.py
Normal file
|
@ -0,0 +1,63 @@
|
|||
"""
|
||||
Test EnergySystemsFactory and various heatpump models
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2021 Project Author Peter Yefi peteryefi@gmail.com
|
||||
"""
|
||||
from unittest import TestCase
|
||||
from imports.geometry_factory import GeometryFactory
|
||||
from imports.energy_systems_factory import EnergySystemsFactory
|
||||
from city_model_structure.energy_systems.water_to_water_hp import WaterToWaterHP
|
||||
from exports.energy_systems_factory import EnergySystemsExportFactory
|
||||
import pandas as pd
|
||||
|
||||
import os
|
||||
|
||||
|
||||
class TestEnergySystemsFactory(TestCase):
|
||||
"""
|
||||
TestEnergySystemsFactory for Water to Water HP
|
||||
"""
|
||||
|
||||
def setUp(self) -> None:
|
||||
"""
|
||||
Test setup
|
||||
:return: None
|
||||
"""
|
||||
city_file = "../unittests/tests_data/C40_Final.gml"
|
||||
self._output_path = "../unittests/tests_data/w2w_user_output.csv"
|
||||
self._city = GeometryFactory('citygml', city_file).city
|
||||
EnergySystemsFactory('water to water hp', self._city).enrich()
|
||||
|
||||
def test_water_to_water_heat_pump_import(self):
|
||||
self.assertIsNotNone(self._city.energy_systems, 'City has energy systems')
|
||||
self.assertIsInstance(self._city.energy_systems[0].water_to_water_hp, WaterToWaterHP)
|
||||
self.assertEqual(self._city.energy_systems[0].water_to_water_hp.model, 'ClimateMaster 156 kW')
|
||||
self.assertEqual(self._city.energy_systems[2].water_to_water_hp.model, 'ClimateMaster 335 kW')
|
||||
|
||||
def test_water_to_water_heat_pump_export(self):
|
||||
# User defined paramenters
|
||||
user_input = {
|
||||
'StartYear': 2020,
|
||||
'EndYear': 2021,
|
||||
'MaximumHPEnergyInput': 8000,
|
||||
'HoursOfStorageAtMaxDemand': 1,
|
||||
'BuildingSuppTemp': 40,
|
||||
'TemperatureDifference': 15,
|
||||
'FuelLHV': 47100,
|
||||
'FuelPrice': 0.12,
|
||||
'FuelEF': 1887,
|
||||
'FuelDensity': 0.717,
|
||||
'HPSupTemp': 60
|
||||
}
|
||||
|
||||
EnergySystemsExportFactory(self._city, user_input, 'ClimateMaster 156 kW', self._output_path).export('water')
|
||||
df = pd.read_csv(self._output_path)
|
||||
print(df.shape)
|
||||
#self.assertEqual(df.shape, (13, 3))
|
||||
#self.assertEqual(df.iloc[0, 1], 3045398.0)
|
||||
|
||||
def tearDown(self) -> None:
|
||||
try:
|
||||
os.remove(self._output_path)
|
||||
except OSError:
|
||||
pass
|
37
unittests/test_greenery_catalog.py
Normal file
37
unittests/test_greenery_catalog.py
Normal file
|
@ -0,0 +1,37 @@
|
|||
"""
|
||||
TestGeometryFactory test and validate the city model structure geometric parameters
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
from unittest import TestCase
|
||||
|
||||
from catalogs.greenery_catalog_factory import GreeneryCatalogFactory
|
||||
|
||||
|
||||
class TestGreeneryCatalog(TestCase):
|
||||
def test_catalog(self):
|
||||
catalog = GreeneryCatalogFactory('nrel').catalog_debug
|
||||
catalog_categories = catalog.names()
|
||||
vegetations = catalog.names('vegetations')
|
||||
plants = catalog.names('plants')
|
||||
soils = catalog.names('soils')
|
||||
self.assertTrue(len(catalog_categories) == 3)
|
||||
self.assertTrue(len(vegetations['vegetations']) == 4)
|
||||
self.assertTrue(len(plants['plants']) == 14)
|
||||
self.assertTrue(len(soils['soils']) == 6)
|
||||
with self.assertRaises(ValueError):
|
||||
catalog.names('unknown')
|
||||
|
||||
# retrieving all the entries should not raise any exceptions
|
||||
for category in catalog_categories:
|
||||
for value in catalog_categories[category]:
|
||||
catalog.get_entry(value)
|
||||
|
||||
with self.assertRaises(IndexError):
|
||||
catalog.get_entry('unknown')
|
||||
|
||||
self.assertTrue(len(catalog.entries().vegetations) == 4)
|
||||
self.assertTrue(len(catalog.entries().plants) == 14)
|
||||
self.assertTrue(len(catalog.entries().soils) == 6)
|
||||
|
|
@ -11,6 +11,7 @@ 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
|
||||
|
||||
|
||||
class TestUsageFactory(TestCase):
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
<gen:stringAttribute name="gross_floor_raea_unit">
|
||||
<gen:value>m2</gen:value>
|
||||
</gen:stringAttribute>
|
||||
<bldg:function>1010</bldg:function>
|
||||
<bldg:yearOfConstruction>1996</bldg:yearOfConstruction>
|
||||
<bldg:function>residential</bldg:function>
|
||||
<bldg:measuredHeight>5.3</bldg:measuredHeight>
|
||||
<bldg:storeysAboveGround>1</bldg:storeysAboveGround>
|
||||
<bldg:lod2Solid>
|
||||
|
|
Loading…
Reference in New Issue
Block a user