-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add model for controlled distribution loop
- Loading branch information
Showing
6 changed files
with
297 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,8 @@ | |
"cvrmsd", | ||
"dassl", | ||
"dymola", | ||
"endfor", | ||
"endraw", | ||
"energyplus", | ||
"GDHC", | ||
"HVAC", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
115 changes: 115 additions & 0 deletions
115
geojson_modelica_translator/modelica/GMT_Lib/DHC/DHC_5G_waste_heat_GHX_variable.mot
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
within {{ data['project_name'] }}.Districts;{% raw %} | ||
model district | ||
"Series connection with variable district water mass flow rate" | ||
extends | ||
PartialSeries(redeclare | ||
Buildings.Experimental.DHC.Loads.Combined.BuildingTimeSeriesWithETS | ||
bui[nBui](final filNam=filNam), datDes( | ||
{% endraw %}nBui={{ data['building_load_files'] | count }}, | ||
mPumDis_flow_nominal={{ data['max_flow_rate'] }}, | ||
mPla_flow_nominal={{ data['max_flow_rate'] }}, | ||
mSto_flow_nominal={{ data['max_flow_rate'] / 10 }}, | ||
dp_length_nominal=250,{% raw %} | ||
epsPla=0.935)); | ||
parameter String filNam[nBui]={ | ||
{% endraw %}{% for building in data['building_load_files'] %} | ||
"{{ building }}"{% if not loop.last %},{% endif %} | ||
{% endfor %}{% raw %}} | ||
"Library paths of the files with thermal loads as time series"; | ||
Modelica.Blocks.Sources.Constant masFloDisPla( | ||
k=datDes.mPla_flow_nominal) | ||
"District water flow rate to plant" | ||
annotation (Placement(transformation(extent={{-250,10},{-230,30}}))); | ||
Buildings.Controls.OBC.CDL.Continuous.Sources.Constant THotWatSupSet[nBui]( | ||
k=fill(63 + 273.15, nBui)) | ||
"Hot water supply temperature set point" | ||
annotation (Placement(transformation(extent={{-190,170},{-170,190}}))); | ||
Buildings.Controls.OBC.CDL.Continuous.Sources.Constant TColWat[nBui]( | ||
k=fill(15 + 273.15, nBui)) | ||
"Cold water temperature" | ||
annotation (Placement(transformation(extent={{-160,150},{-140,170}}))); | ||
Buildings.Experimental.DHC.Networks.Controls.MainPump conPum( | ||
nMix=nBui, | ||
nSou=2, | ||
TMin=279.15, | ||
TMax=290.15, | ||
use_temperatureShift=false) "Main pump controller" | ||
annotation (Placement(transformation(extent={{-280,-70},{-260,-50}}))); | ||
Buildings.Controls.OBC.CDL.Continuous.MultiplyByParameter gai(k=datDes.mPumDis_flow_nominal) | ||
"Scale with nominal mass flow rate" | ||
annotation (Placement(transformation(extent={{-240,-70},{-220,-50}}))); | ||
equation | ||
connect(masFloDisPla.y, pla.mPum_flow) annotation (Line(points={{-229,20},{ | ||
-184,20},{-184,4.66667},{-161.333,4.66667}}, | ||
color={0,0,127})); | ||
connect(THotWatSupSet.y, bui.THotWatSupSet) annotation (Line(points={{-168, | ||
180},{-40,180},{-40,183},{-12,183}}, color={0,0,127})); | ||
connect(TColWat.y, bui.TColWat) annotation (Line(points={{-138,160},{-40,160}, | ||
{-40,164},{-8,164},{-8,168}}, | ||
color={0,0,127})); | ||
connect(pumDis.m_flow_in, gai.y) | ||
annotation (Line(points={{68,-60},{-218,-60}}, | ||
color={0,0,127})); | ||
connect(conPum.y, gai.u) | ||
annotation (Line(points={{-258,-60},{-242,-60}}, | ||
color={0,0,127})); | ||
connect(dis.TOut, conPum.TMix) annotation (Line(points={{22,134},{30,134},{30, | ||
120},{-300,120},{-300,-54},{-282,-54}}, | ||
color={0,0,127})); | ||
connect(TDisWatRet.T, conPum.TSouIn[1]) annotation (Line(points={{69,0},{60,0}, | ||
{60,80},{-304,80},{-304,-61},{-282,-61}}, | ||
color={0,0,127})); | ||
connect(TDisWatBorLvg.T, conPum.TSouIn[2]) annotation (Line(points={{-91,-40}, | ||
{-290,-40},{-290,-58},{-282,-58},{-282,-59}}, | ||
color={0,0,127})); | ||
connect(TDisWatBorLvg.T, conPum.TSouOut[1]) annotation (Line(points={{-91,-40}, | ||
{-290,-40},{-290,-67},{-282,-67}}, color={0,0,127})); | ||
connect(TDisWatSup.T, conPum.TSouOut[2]) annotation (Line(points={{-91,20},{-100, | ||
20},{-100,60},{-296,60},{-296,-65},{-282,-65}}, | ||
color={0,0,127})); | ||
connect(gai.y, pumSto.m_flow_in) annotation (Line(points={{-218,-60},{-180,-60}, | ||
{-180,-68}}, color={0,0,127})); | ||
annotation ( | ||
Diagram( | ||
coordinateSystem(preserveAspectRatio=false, extent={{-360,-260},{360,260}})), | ||
experiment( | ||
StopTime=31536000, | ||
Interval=300, | ||
Tolerance=1e-06, | ||
__Dymola_Algorithm="Dassl"), | ||
Documentation(info="<html> | ||
<p> | ||
This model is identical to | ||
<a href=\"Buildings.Experimental.DHC.Examples.Combined.SeriesConstantFlow\"> | ||
Buildings.Experimental.DHC.Examples.Combined.SeriesConstantFlow</a> | ||
except for the pipe diameter and the control of the main circulation pump. | ||
Rather than having a constant mass flow rate, the mass flow rate is varied | ||
based on the mixing temperatures after each agent. | ||
If these mixing temperatures are sufficiently far away from the minimum or maximum | ||
allowed loop temperature, then the mass flow rate is reduced to save pump energy. | ||
</p> | ||
</html>", revisions="<html> | ||
<ul> | ||
<li> | ||
November 1, 2023, by Nicholas Long:<br/> | ||
Templatized for direct use in GMT with n-building connectors.<br/> | ||
Changes include: removing dymola run command tied to MBL path, adding | ||
a constant for borehole field mass flow rate (no longer tied to main | ||
distribution loop). | ||
</li> | ||
<li> | ||
February 23, 2021, by Antoine Gautier:<br/> | ||
Refactored with base classes from the <code>DHC</code> package.<br/> | ||
This is for | ||
<a href=\"https://github.com/lbl-srg/modelica-buildings/issues/1769\"> | ||
issue 1769</a>. | ||
</li> | ||
<li> | ||
January 12, 2020, by Michael Wetter:<br/> | ||
Added documentation. | ||
</li> | ||
</ul> | ||
</html>"), | ||
__Dymola_experimentSetupOutput); | ||
end district; | ||
{% endraw %} |
101 changes: 101 additions & 0 deletions
101
geojson_modelica_translator/modelica/GMT_Lib/DHC/DHC_5G_waste_heat_GHX_variable.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import shutil | ||
from pathlib import Path | ||
|
||
from modelica_builder.modelica_mos_file import ModelicaMOS | ||
from modelica_builder.package_parser import PackageParser | ||
|
||
from geojson_modelica_translator.modelica.simple_gmt_base import SimpleGMTBase | ||
from geojson_modelica_translator.scaffold import Scaffold | ||
|
||
|
||
class DHC5GWasteHeatAndGHXVariable(SimpleGMTBase): | ||
"""Generates a full Modelica package with the DHC 5G waste heat and GHX model with a controlled variable speed distribution pump.""" | ||
|
||
def __init__(self, system_parameters): | ||
self.system_parameters = system_parameters | ||
self.template_dir = Path(__file__).parent | ||
super().__init__(self.system_parameters, self.template_dir) | ||
|
||
def build_from_template(self, output_dir: Path, project_name: str) -> None: | ||
"""This is a bit past being a simple template as it is exporting an entire scaffolded package | ||
that can be loaded and simulated in Modelica. The scaffold is very specific to DES. | ||
Args: | ||
output_dir (Path): directory to save the package to (without the project name) | ||
project_name (str, optional): The name of the project which is used in the Scaffold object. | ||
""" | ||
template_data = { | ||
'project_name': project_name, | ||
'save_file_name': 'district', | ||
'building_load_files': [] | ||
} | ||
|
||
# create the directory structure | ||
scaffold = Scaffold(output_dir, project_name=project_name) | ||
scaffold.create(ignore_paths=['Loads', 'Networks', 'Plants', 'Substations']) | ||
|
||
# create the root package | ||
package = PackageParser.new_from_template(scaffold.project_path, project_name, order=[]) | ||
package.add_model('Districts') | ||
|
||
# create the district package with the template_data from above | ||
files_to_copy = [] | ||
|
||
# 1: grab all of the time series files and place them in the proper location | ||
for building in self.system_parameters.get_param("$.buildings[?load_model=time_series]"): | ||
building_load_file = Path(building['load_model_parameters']['time_series']['filepath']) | ||
files_to_copy.append({ | ||
"orig_file": building_load_file, | ||
"geojson_id": building['geojson_id'], | ||
"save_path": f"{scaffold.districts_path.resources_dir}/{building['geojson_id']}", | ||
"save_filename": building_load_file.name | ||
}) | ||
|
||
# 2: Copy the files to the appropriate location and ensure uniqueness by putting into a unique directory | ||
# (since OpenStudio creates all files with modelica.mos) | ||
total_heating_load = 0 | ||
total_cooling_load = 0 | ||
total_swh_load = 0 | ||
for file_to_copy in files_to_copy: | ||
# create the path if it doesn't exist | ||
Path(file_to_copy['save_path']).mkdir(parents=True, exist_ok=True) | ||
save_filename = f"{file_to_copy['save_path']}/{file_to_copy['save_filename']}" | ||
shutil.copy(file_to_copy['orig_file'], save_filename) | ||
|
||
# 3: If the file is an MOS file, and it has the Peak water heating load set to zero, then set it to a minimum value | ||
# Also, store the total heating, cooling, and water loads which will be used for sizing. | ||
mos_file = ModelicaMOS(save_filename) | ||
total_heating_load += mos_file.retrieve_header_variable_value('Peak space heating load', cast_type=float) | ||
total_cooling_load += mos_file.retrieve_header_variable_value('Peak space cooling load', cast_type=float) | ||
peak_water = mos_file.retrieve_header_variable_value('Peak water heating load', cast_type=float) | ||
total_swh_load += peak_water | ||
if peak_water == 0: | ||
peak_heat = mos_file.retrieve_header_variable_value('Peak space heating load', cast_type=float) | ||
peak_swh = max(peak_heat / 10, 5000) | ||
|
||
mos_file.replace_header_variable_value('Peak water heating load', peak_swh) | ||
mos_file.save() | ||
|
||
# 4: Add the path to the param data with Modelica friendly path names | ||
rel_path_name = f"{project_name}/{scaffold.districts_path.resources_relative_dir}/{file_to_copy['geojson_id']}/{file_to_copy['save_filename']}" | ||
template_data['building_load_files'].append(f"modelica://{rel_path_name}") # type: ignore | ||
|
||
# 5: Calculate the mass flow rates (kg/s) for the heating and cooling networks peak load (in Watts) | ||
# (assuming 5C delta T [since 5G] and 4.18 Cp (kJ/kgK)). Add 1.5x the peak for oversizing | ||
delta_t = 5 | ||
heating_flow_rate = 1.5 * total_heating_load / (1000 * delta_t * 4.18) | ||
cooling_flow_rate = 1.5 * total_cooling_load / (1000 * delta_t * 4.18) | ||
swh_flow_rate = 1.5 * total_swh_load / (1000 * delta_t * 4.18) | ||
|
||
template_data['max_flow_rate'] = round(max(heating_flow_rate, cooling_flow_rate, swh_flow_rate), 3) # type: ignore | ||
|
||
# 6: generate the modelica files from the template | ||
self.to_modelica(output_dir=Path(scaffold.districts_path.files_dir), | ||
model_name='DHC_5G_waste_heat_GHX_variable', | ||
param_data=template_data, | ||
save_file_name='district.mo', | ||
generate_package=True, | ||
partial_files={'DHC_5G_partial': 'PartialSeries'}) | ||
|
||
# 7: save the root package.mo | ||
package.save() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters