Skip to content

Commit

Permalink
Merge pull request #583 from NREL/disaggregated-heat-load-IO
Browse files Browse the repository at this point in the history
Disaggregated heat load inputs and outputs + Process heat load
  • Loading branch information
zolanaj authored May 10, 2024
2 parents 2b0ac75 + 581e796 commit a8d82ff
Show file tree
Hide file tree
Showing 8 changed files with 590 additions and 10 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,20 @@ Classify the change according to the following categories:
##### Removed
### Patches

## Develop 2024-05-09
### Minor Updates
#### Added
- In `reoptjl/models.py`, added the following fields:
- booleans **can_serve_dhw**, **can_serve_space_heating**, and **can_serve_process_heat** to models **CHPInputs**, **ExistingBoilerInputs**, **BoilerInputs**, **SteamTurbineInputs**, and **HotThermalStorageInputs**
- booleans **can_serve_space_heating** and **can_serve_process_heat** to model **GHPInputs**
- arrays **storage_to_dhw_load_series_mmbtu_per_hour**, **storage_to_space_heating_load_series_mmbtu_per_hour** and **storage_to_process_heat_load_series_mmbtu_per_hour** to model **HotThermalStorageOutputs**
- **heating_load_input** to model **AbsorptionChillerInputs**
- arrays **thermal_to_dhw_load_series_mmbtu_per_hour**, **thermal_to_space_heating_load_series_mmbtu_per_hour**, and **thermal_to_process_heat_load_series_mmbtu_per_hour** to models **CHPOutputs**, **ExistingBoilerOutputs**, **BoilerOutputs**, **SteamTurbineOutputs**, and **HotThermalStorageOutputs**
- boolean **retire_in_optimal** to **ExistingBoilerInputs**
- In `reopt.jl/models.py`, added new model **ProcessHeatLoadInputs** with references in `reoptjl/validators.py` and `reoptjl/views.py`
- Added process heat load to test scenario `reoptjl/test/posts/test_thermal_in_results.json`
- Added tests for the presence of process heat load and heat-load-specfic outputs to `test_thermal_in_results` within `reoptjl/test/test_job_endpoint.py`

## v3.8.0
### Minor Updates
#### Changed
Expand Down
4 changes: 2 additions & 2 deletions julia_src/Manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -917,9 +917,9 @@ uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"

[[deps.REopt]]
deps = ["ArchGDAL", "CSV", "CoolProp", "DataFrames", "Dates", "DelimitedFiles", "HTTP", "JLD", "JSON", "JuMP", "LinDistFlow", "LinearAlgebra", "Logging", "MathOptInterface", "Requires", "Roots", "Statistics", "TestEnv"]
git-tree-sha1 = "d2bbcbb8344f19ed87ee8cb6a196d4ed8415255b"
git-tree-sha1 = "3c40f3939f79c3f66df69e9acc503fef614cdd63"
uuid = "d36ad4e8-d74a-4f7a-ace1-eaea049febf6"
version = "0.45.0"
version = "0.46.1"

[[deps.Random]]
deps = ["SHA"]
Expand Down
241 changes: 241 additions & 0 deletions reoptjl/migrations/0059_processheatloadinputs_and_more.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
# Generated by Django 4.0.7 on 2024-05-09 20:02

import django.contrib.postgres.fields
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
import reoptjl.models


class Migration(migrations.Migration):

dependencies = [
('reoptjl', '0058_merge_20240425_1527'),
]

operations = [
migrations.CreateModel(
name='ProcessHeatLoadInputs',
fields=[
('meta', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, related_name='ProcessHeatLoadInputs', serialize=False, to='reoptjl.apimeta')),
('annual_mmbtu', models.FloatField(blank=True, help_text='Annual site process heat consumption, used to scale simulated load profile [MMBtu]', null=True, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(100000000.0)])),
('fuel_loads_mmbtu_per_hour', django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(blank=True), blank=True, default=list, help_text='Typical load over all hours in one year. Must be hourly (8,760 samples), 30 minute (17,520 samples), or 15 minute (35,040 samples). All non-net load values must be greater than or equal to zero. ', size=None)),
],
bases=(reoptjl.models.BaseModel, models.Model),
),
migrations.AddField(
model_name='absorptionchillerinputs',
name='heating_load_input',
field=models.TextField(blank=True, choices=[('DomesitHotWater', 'Domesithotwater'), ('SpaceHeating', 'Spaceheating'), ('ProcessHeat', 'Processheat')], help_text='Absorption chiller heat input - determines what heating load is added to by absorption chiller use', null=True),
),
migrations.AddField(
model_name='boilerinputs',
name='can_serve_dhw',
field=models.BooleanField(blank=True, default=True, help_text='Boolean indicator if boiler can serve domestic hot water load', null=True),
),
migrations.AddField(
model_name='boilerinputs',
name='can_serve_process_heat',
field=models.BooleanField(blank=True, default=True, help_text='Boolean indicator if boiler can serve process heat load', null=True),
),
migrations.AddField(
model_name='boilerinputs',
name='can_serve_space_heating',
field=models.BooleanField(blank=True, default=True, help_text='Boolean indicator if boiler can serve space heating load', null=True),
),
migrations.AddField(
model_name='boileroutputs',
name='thermal_to_dhw_load_series_mmbtu_per_hour',
field=django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(blank=True, null=True), default=list, size=None),
),
migrations.AddField(
model_name='boileroutputs',
name='thermal_to_process_heat_load_series_mmbtu_per_hour',
field=django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(blank=True, null=True), default=list, size=None),
),
migrations.AddField(
model_name='boileroutputs',
name='thermal_to_space_heating_load_series_mmbtu_per_hour',
field=django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(blank=True, null=True), default=list, size=None),
),
migrations.AddField(
model_name='chpinputs',
name='can_serve_dhw',
field=models.BooleanField(blank=True, default=True, help_text='Boolean indicator if CHP can serve hot water load', null=True),
),
migrations.AddField(
model_name='chpinputs',
name='can_serve_process_heat',
field=models.BooleanField(blank=True, default=True, help_text='Boolean indicator if CHP can serve process heat load', null=True),
),
migrations.AddField(
model_name='chpinputs',
name='can_serve_space_heating',
field=models.BooleanField(blank=True, default=True, help_text='Boolean indicator if CHP can serve space heating load', null=True),
),
migrations.AddField(
model_name='chpoutputs',
name='thermal_to_dhw_load_series_mmbtu_per_hour',
field=django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(blank=True, null=True), default=list, size=None),
),
migrations.AddField(
model_name='chpoutputs',
name='thermal_to_process_heat_load_series_mmbtu_per_hour',
field=django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(blank=True, null=True), default=list, size=None),
),
migrations.AddField(
model_name='chpoutputs',
name='thermal_to_space_heating_load_series_mmbtu_per_hour',
field=django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(blank=True, null=True), default=list, size=None),
),
migrations.AddField(
model_name='existingboilerinputs',
name='can_serve_dhw',
field=models.BooleanField(blank=True, default=True, help_text='Boolean indicator if the existing boiler can serve domestic hot water load', null=True),
),
migrations.AddField(
model_name='existingboilerinputs',
name='can_serve_process_heat',
field=models.BooleanField(blank=True, default=True, help_text='Boolean indicator if the existing boiler can serve process heat load', null=True),
),
migrations.AddField(
model_name='existingboilerinputs',
name='can_serve_space_heating',
field=models.BooleanField(blank=True, default=True, help_text='Boolean indicator if the existing boiler can serve space heating load', null=True),
),
migrations.AddField(
model_name='existingboilerinputs',
name='retire_in_optimal',
field=models.BooleanField(blank=True, default=False, help_text='Boolean indicator if the existing boiler is unavailable in the optimal case (still used in BAU)', null=True),
),
migrations.AddField(
model_name='existingboileroutputs',
name='thermal_to_dhw_load_series_mmbtu_per_hour',
field=django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(blank=True, null=True), default=list, size=None),
),
migrations.AddField(
model_name='existingboileroutputs',
name='thermal_to_process_heat_load_series_mmbtu_per_hour',
field=django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(blank=True, null=True), default=list, size=None),
),
migrations.AddField(
model_name='existingboileroutputs',
name='thermal_to_space_heating_load_series_mmbtu_per_hour',
field=django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(blank=True, null=True), default=list, size=None),
),
migrations.AddField(
model_name='ghpinputs',
name='can_serve_process_heat',
field=models.BooleanField(blank=True, default=False, help_text='Boolean indicator if GHP can serve process heat load', null=True),
),
migrations.AddField(
model_name='ghpinputs',
name='can_serve_space_heating',
field=models.BooleanField(blank=True, default=True, help_text='Boolean indicator if GHP can serve space heating load', null=True),
),
migrations.AddField(
model_name='heatingloadoutputs',
name='annual_calculated_process_heat_boiler_fuel_load_mmbtu',
field=models.FloatField(blank=True, default=0, help_text='Annual site process heat boiler fuel load [MMBTU]', null=True, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100000000.0)]),
),
migrations.AddField(
model_name='heatingloadoutputs',
name='annual_calculated_process_heat_thermal_load_mmbtu',
field=models.FloatField(blank=True, default=0, help_text='Annual site process heat load [MMBTU]', null=True, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100000000.0)]),
),
migrations.AddField(
model_name='heatingloadoutputs',
name='process_heat_boiler_fuel_load_series_mmbtu_per_hour',
field=django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(blank=True, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100000000.0)]), blank=True, default=list, help_text='Hourly process heat boiler fuel load [MMBTU/hr]', size=None),
),
migrations.AddField(
model_name='heatingloadoutputs',
name='process_heat_thermal_load_series_mmbtu_per_hour',
field=django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(blank=True, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100000000.0)]), blank=True, default=list, help_text='Hourly process heat load [MMBTU/hr]', size=None),
),
migrations.AddField(
model_name='hotthermalstorageinputs',
name='can_serve_dhw',
field=models.BooleanField(blank=True, default=True, help_text='Boolean indicator if hot thermal storage can serve space heating load', null=True),
),
migrations.AddField(
model_name='hotthermalstorageinputs',
name='can_serve_process_heat',
field=models.BooleanField(blank=True, default=False, help_text='Boolean indicator if hot thermal storage can serve process heat load', null=True),
),
migrations.AddField(
model_name='hotthermalstorageinputs',
name='can_serve_space_heating',
field=models.BooleanField(blank=True, default=True, help_text='Boolean indicator if hot thermal storage can serve space heating load', null=True),
),
migrations.AddField(
model_name='hotthermalstorageoutputs',
name='storage_to_dhw_load_series_mmbtu_per_hour',
field=django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(blank=True, null=True), default=list, size=None),
),
migrations.AddField(
model_name='hotthermalstorageoutputs',
name='storage_to_process_heat_load_series_mmbtu_per_hour',
field=django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(blank=True, null=True), default=list, size=None),
),
migrations.AddField(
model_name='hotthermalstorageoutputs',
name='storage_to_space_heating_load_series_mmbtu_per_hour',
field=django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(blank=True, null=True), default=list, size=None),
),
migrations.AddField(
model_name='steamturbineinputs',
name='can_serve_dhw',
field=models.BooleanField(blank=True, default=True, help_text='Boolean indicator if steam turbine can serve space heating load', null=True),
),
migrations.AddField(
model_name='steamturbineinputs',
name='can_serve_process_heat',
field=models.BooleanField(blank=True, default=True, help_text='Boolean indicator if steam turbine can serve process heat load', null=True),
),
migrations.AddField(
model_name='steamturbineinputs',
name='can_serve_space_heating',
field=models.BooleanField(blank=True, default=True, help_text='Boolean indicator if steam turbine can serve space heating load', null=True),
),
migrations.AddField(
model_name='steamturbineoutputs',
name='thermal_to_dhw_load_series_mmbtu_per_hour',
field=django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(blank=True, null=True), default=list, size=None),
),
migrations.AddField(
model_name='steamturbineoutputs',
name='thermal_to_process_heat_load_series_mmbtu_per_hour',
field=django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(blank=True, null=True), default=list, size=None),
),
migrations.AddField(
model_name='steamturbineoutputs',
name='thermal_to_space_heating_load_series_mmbtu_per_hour',
field=django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(blank=True, null=True), default=list, size=None),
),
migrations.AlterField(
model_name='heatingloadoutputs',
name='dhw_boiler_fuel_load_series_mmbtu_per_hour',
field=django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(blank=True, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100000000.0)]), blank=True, default=list, help_text='Hourly domestic hot water boiler fuel load [MMBTU/hr]', size=None),
),
migrations.AlterField(
model_name='heatingloadoutputs',
name='space_heating_boiler_fuel_load_series_mmbtu_per_hour',
field=django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(blank=True, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100000000.0)]), blank=True, default=list, help_text='Hourly space heating boiler fuel load [MMBTU/hr]', size=None),
),
migrations.AlterField(
model_name='heatingloadoutputs',
name='space_heating_thermal_load_series_mmbtu_per_hour',
field=django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(blank=True, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100000000.0)]), blank=True, default=list, help_text='Hourly space heating load [MMBTU/hr]', size=None),
),
migrations.AlterField(
model_name='heatingloadoutputs',
name='total_heating_boiler_fuel_load_series_mmbtu_per_hour',
field=django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(blank=True, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100000000.0)]), blank=True, default=list, help_text='Hourly total boiler fuel load [MMBTU/hr]', size=None),
),
migrations.AlterField(
model_name='pvinputs',
name='tilt',
field=models.FloatField(blank=True, help_text='PV system tilt angle. Default tilt is 20 degrees for fixed arrays (rooftop or ground-mounted) and 0 degrees for axis-tracking systems.', null=True, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(90)]),
),
]
Loading

0 comments on commit a8d82ff

Please sign in to comment.