Skip to content

Commit

Permalink
Add new ProcessHeatInputs and fix thermal job test
Browse files Browse the repository at this point in the history
  • Loading branch information
Bill-Becker committed Jun 1, 2024
1 parent 05861e2 commit d6dc85c
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Generated by Django 4.0.7 on 2024-06-01 20:15

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


class Migration(migrations.Migration):

dependencies = [
('reoptjl', '0059_processheatloadinputs_and_more'),
]

operations = [
migrations.AddField(
model_name='processheatloadinputs',
name='addressable_load_fraction',
field=django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(blank=True, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(1.0)]), blank=True, default=list, help_text='Fraction of input fuel load which is addressable by heating technologies (default is 1.0).Can be a scalar or vector with length aligned with use of monthly_mmbtu (12) or fuel_loads_mmbtu_per_hour.', size=None),
),
migrations.AddField(
model_name='processheatloadinputs',
name='blended_industry_reference_names',
field=django.contrib.postgres.fields.ArrayField(base_field=models.TextField(blank=True, choices=[('Chemical', 'Chemical'), ('Warehouse', 'Warehouse'), ('FlatLoad', 'Flatload'), ('FlatLoad_24_5', 'Flatload 24 5'), ('FlatLoad_16_7', 'Flatload 16 7'), ('FlatLoad_16_5', 'Flatload 16 5'), ('FlatLoad_8_7', 'Flatload 8 7'), ('FlatLoad_8_5', 'Flatload 8 5')], null=True), blank=True, default=list, help_text='Used in concert with blended_industry_reference_percents to create a blended load profile from multiple Industrial reference facility/sector types.', size=None),
),
migrations.AddField(
model_name='processheatloadinputs',
name='blended_industry_reference_percents',
field=django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(1.0)]), blank=True, default=list, help_text='Used in concert with blended_industry_reference_names to create a blended load profile from multiple Industrial reference facility/sector types. Must sum to 1.0.', size=None),
),
migrations.AddField(
model_name='processheatloadinputs',
name='industry_reference_name',
field=models.TextField(blank=True, choices=[('Chemical', 'Chemical'), ('Warehouse', 'Warehouse'), ('FlatLoad', 'Flatload'), ('FlatLoad_24_5', 'Flatload 24 5'), ('FlatLoad_16_7', 'Flatload 16 7'), ('FlatLoad_16_5', 'Flatload 16 5'), ('FlatLoad_8_7', 'Flatload 8 7'), ('FlatLoad_8_5', 'Flatload 8 5')], help_text='Industrial process heat load reference facility/sector type', null=True),
),
migrations.AddField(
model_name='processheatloadinputs',
name='monthly_mmbtu',
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="Monthly site process heat fuel consumption in [MMbtu], used to scale simulated default building load profile for the site's climate zone", size=None),
),
migrations.AlterField(
model_name='absorptionchillerinputs',
name='heating_load_input',
field=models.TextField(blank=True, choices=[('DomesticHotWater', 'Domestichotwater'), ('SpaceHeating', 'Spaceheating'), ('ProcessHeat', 'Processheat')], help_text='Absorption chiller heat input - determines what heating load is added to by absorption chiller use', null=True),
),
migrations.AlterField(
model_name='processheatloadinputs',
name='annual_mmbtu',
field=models.FloatField(blank=True, help_text='Annual site process heat fuel consumption, used to scale simulated default industry load profile [MMBtu]', null=True, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(100000000.0)]),
),
migrations.AlterField(
model_name='processheatloadinputs',
name='fuel_loads_mmbtu_per_hour',
field=django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(blank=True), blank=True, default=list, help_text='Vector of process heat fuel loads [mmbtu/hr] over 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),
),
]
102 changes: 97 additions & 5 deletions reoptjl/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6384,19 +6384,53 @@ class ProcessHeatLoadInputs(BaseModel, models.Model):

possible_sets = [
["fuel_loads_mmbtu_per_hour"],
["annual_mmbtu"],
[],
["industry_reference_name", "monthly_mmbtu"],
["annual_mmbtu", "industry_reference_name"],
["industry_reference_name"],
["blended_industry_reference_names", "blended_industry_reference_percents"],
[]
]

INDUSTRY_REFERENCE_NAME = models.TextChoices('INDUSTRY_REFERENCE_NAME', (
'Chemical '
'Warehouse '
'FlatLoad '
'FlatLoad_24_5 '
'FlatLoad_16_7 '
'FlatLoad_16_5 '
'FlatLoad_8_7 '
'FlatLoad_8_5'
))

annual_mmbtu = models.FloatField(
validators=[
MinValueValidator(1),
MaxValueValidator(MAX_BIG_NUMBER)
],
null=True,
blank=True,
help_text=("Annual site process heat consumption, used "
"to scale simulated load profile [MMBtu]")
help_text=("Annual site process heat fuel consumption, used "
"to scale simulated default industry load profile [MMBtu]")
)

industry_reference_name = models.TextField(
null=True,
blank=True,
choices=INDUSTRY_REFERENCE_NAME.choices,
help_text=("Industrial process heat load reference facility/sector type")
)

monthly_mmbtu = ArrayField(
models.FloatField(
validators=[
MinValueValidator(0),
MaxValueValidator(MAX_BIG_NUMBER)
],
blank=True
),
default=list, blank=True,
help_text=("Monthly site process heat fuel consumption in [MMbtu], used "
"to scale simulated default building load profile for the site's climate zone")
)

fuel_loads_mmbtu_per_hour = ArrayField(
Expand All @@ -6405,11 +6439,50 @@ class ProcessHeatLoadInputs(BaseModel, models.Model):
),
default=list,
blank=True,
help_text=("Typical load over all hours in one year. Must be hourly (8,760 samples), 30 minute (17,"
help_text=("Vector of process heat fuel loads [mmbtu/hr] over 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. "
)
)

blended_industry_reference_names = ArrayField(
models.TextField(
choices=INDUSTRY_REFERENCE_NAME.choices,
blank=True,
null=True
),
default=list,
blank=True,
help_text=("Used in concert with blended_industry_reference_percents to create a blended load profile from multiple "
"Industrial reference facility/sector types.")
)

blended_industry_reference_percents = ArrayField(
models.FloatField(
null=True, blank=True,
validators=[
MinValueValidator(0),
MaxValueValidator(1.0)
],
),
default=list,
blank=True,
help_text=("Used in concert with blended_industry_reference_names to create a blended load profile from multiple "
"Industrial reference facility/sector types. Must sum to 1.0.")
)

addressable_load_fraction = ArrayField(
models.FloatField(
validators=[
MinValueValidator(0),
MaxValueValidator(1.0)
],
blank=True
),
default=list,
blank=True,
help_text=( "Fraction of input fuel load which is addressable by heating technologies (default is 1.0)."
"Can be a scalar or vector with length aligned with use of monthly_mmbtu (12) or fuel_loads_mmbtu_per_hour.")
)

def clean(self):
Expand All @@ -6420,6 +6493,25 @@ def clean(self):
error_messages["required inputs"] = \
"Must provide at least one set of valid inputs from {}.".format(self.possible_sets)

if len(self.blended_industry_reference_names) > 0 and self.industry_reference_name == "":
if len(self.blended_industry_reference_names) != len(self.blended_industry_reference_percents):
error_messages["blended_industry_reference_names"] = \
"The number of blended_industry_reference_names must equal the number of blended_industry_reference_percents."
if not math.isclose(sum(self.blended_industry_reference_percents), 1.0):
error_messages["blended_industry_reference_percents"] = "Sum must = 1.0."

if self.industry_reference_name != "" or \
len(self.blended_industry_reference_names) > 0:
self.year = 2017 # the validator provides an "info" message regarding this)

if self.addressable_load_fraction == None:
self.addressable_load_fraction = list([1.0]) # should not convert to timeseries, in case it is to be used with monthly_mmbtu or annual_mmbtu

# possible sets for defining load profile
if not at_least_one_set(self.dict, self.possible_sets):
error_messages["required inputs"] = \
"Must provide at least one set of valid inputs from {}.".format(self.possible_sets)

class HeatingLoadOutputs(BaseModel, models.Model):

key = "HeatingLoadOutputs"
Expand Down
1 change: 1 addition & 0 deletions reoptjl/test/posts/test_thermal_in_results.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"annual_mmbtu": 500.0
},
"ProcessHeatLoad": {
"industry_reference_name": "FlatLoad",
"annual_mmbtu": 100
},
"ExistingBoiler": {
Expand Down

0 comments on commit d6dc85c

Please sign in to comment.