Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gen defaults #473

Merged
merged 8 commits into from
Jul 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ Classify the change according to the following categories:
##### Removed
### Patches

## Develop v2.14.0
### Minor Updates
##### Fixed
- In job/ app (v3), updated `Generator` **installed_cost_per_kw** from 500 to 650 if **only_runs_during_grid_outage** is _true_ or 800 if _false_
- Added `test_other_conditional_inputs` method in `job/test/test_validator.py` to test inputs with defaults or overrides based on other input values within the same model

## v2.13.0
### Minor Updates
##### Fixed
Expand Down
19 changes: 19 additions & 0 deletions job/migrations/0037_alter_generatorinputs_installed_cost_per_kw.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 4.0.4 on 2023-07-03 20:25

import django.core.validators
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('job', '0036_merge_20230424_1645'),
]

operations = [
migrations.AlterField(
model_name='generatorinputs',
name='installed_cost_per_kw',
field=models.FloatField(blank=True, default=650, help_text='Installed diesel generator cost in $/kW', validators=[django.core.validators.MinValueValidator(0.0), django.core.validators.MaxValueValidator(100000.0)]),
),
]
19 changes: 19 additions & 0 deletions job/migrations/0038_alter_generatorinputs_installed_cost_per_kw.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 4.0.4 on 2023-07-05 18:52

import django.core.validators
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('job', '0037_alter_generatorinputs_installed_cost_per_kw'),
]

operations = [
migrations.AlterField(
model_name='generatorinputs',
name='installed_cost_per_kw',
field=models.FloatField(blank=True, help_text='Installed diesel generator cost in $/kW', null=True, validators=[django.core.validators.MinValueValidator(0.0), django.core.validators.MaxValueValidator(100000.0)]),
),
]
6 changes: 4 additions & 2 deletions job/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3271,15 +3271,15 @@ class GeneratorInputs(BaseModel, models.Model):
help_text="Maximum diesel generator size constraint for optimization. Set to zero to disable PV"
)
installed_cost_per_kw = models.FloatField(
default=500,
validators=[
MinValueValidator(0.0),
MaxValueValidator(1.0e5)
],
blank=True,
null=True,
help_text="Installed diesel generator cost in $/kW"
)
om_cost_per_kw = models.FloatField(
om_cost_per_kw = models.FloatField( #depends on Settings.off_grid_flag
validators=[
MinValueValidator(0.0),
MaxValueValidator(1.0e3)
Expand Down Expand Up @@ -3601,6 +3601,8 @@ class GeneratorInputs(BaseModel, models.Model):
)

def clean(self):
if not self.installed_cost_per_kw:
self.installed_cost_per_kw = 650.0 if self.only_runs_during_grid_outage else 800.0
if not self.electric_efficiency_half_load:
self.electric_efficiency_half_load = self.electric_efficiency_full_load

Expand Down
1 change: 1 addition & 0 deletions job/test/posts/all_inputs_test.json
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@
},
"SpaceHeatingLoad": {
"annual_mmbtu": null,
"year": 2017,
"doe_reference_name": "MidriseApartment",
"monthly_mmbtu": [],
"fuel_loads_mmbtu_per_hour": [],
Expand Down
1 change: 1 addition & 0 deletions job/test/posts/outage.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"outage_probabilities": [1]
},
"Generator": {
"installed_cost_per_kw": 500,
"min_kw": 1736.84,
"max_kw": 1736.84,
"min_turn_down_fraction": 0.0,
Expand Down
43 changes: 41 additions & 2 deletions job/test/test_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import uuid
from django.test import TestCase
from job.validators import InputValidator
from job.models import FUEL_DEFAULTS


class InputValidatorTests(TestCase):
Expand Down Expand Up @@ -178,8 +179,7 @@ def test_off_grid_defaults_overrides(self):
self.assertAlmostEqual(validator.models["Generator"].replacement_year, 7)
self.assertAlmostEqual(validator.models["Generator"].replace_cost_per_kw, 200.0)

def existing_boiler_validation(self):

def test_existing_boiler_validation(self):
"""
Validate clean, cross-clean methods are working as expected
"""
Expand Down Expand Up @@ -345,7 +345,46 @@ def test_pv_tilt_defaults(self):
validator.cross_clean()
self.assertAlmostEquals(validator.models["PV"].tilt, post["Site"]["latitude"], places=-3)

def test_other_conditional_defaults(self):
"""
Validate defaults that are based on other inputs in the same model are set properly in clean method
"""
# Remove/change inputs that we want to check defaulting of
post_file = os.path.join('job', 'test', 'posts', 'all_inputs_test.json')
post = json.load(open(post_file, 'r'))
post["APIMeta"] = {"run_uuid": uuid.uuid4()}

post["ElectricLoad"]["year"] = 2020
post["SpaceHeatingLoad"]["year"] = 2020
#TODO: uncomment when CoolingLoad added to all_inputs_test.json
# post["CoolingLoad"]["year"] = 2020
post["ElectricUtility"]["outage_durations"] = [10,20]
del(post["ElectricUtility"]["outage_probabilities"])
del(post["Financial"]["owner_tax_rate_fraction"])
del(post["Financial"]["owner_discount_rate_fraction"])
del(post["Generator"]["installed_cost_per_kw"])
#TODO: uncomment when CHP added to all_inputs_test.json
# del(post["CHP"]["electric_efficiency_half_load"])
# del(post["CHP"]["emissions_factor_lb_CO2_per_mmbtu"])
del(post["ExistingBoiler"]["emissions_factor_lb_CO2_per_mmbtu"])

# Create validator and call clean method
validator = InputValidator(post)
validator.clean_fields()
validator.clean()

# Check conditional defaults
self.assertEqual(validator.models["ElectricLoad"].year, 2017)
self.assertEqual(validator.models["ElectricLoad"].year, 2017)
#TODO: uncomment when CoolingLoad added to all_inputs_test.json
# self.assertEqual(validator.models["CoolingLoad"].year, 2017)
self.assertEqual(validator.models["ElectricUtility"].outage_probabilities, [0.5,0.5])
self.assertEqual(validator.models["Financial"].owner_tax_rate_fraction, post["Financial"]["offtaker_tax_rate_fraction"])
self.assertEqual(validator.models["Financial"].owner_discount_rate_fraction, post["Financial"]["offtaker_discount_rate_fraction"])
self.assertEqual(validator.models["Generator"].installed_cost_per_kw, 650)
#TODO: uncomment when CHP added to all_inputs_test.json
# self.assertEqual(validator.models["CHP"].electric_efficiency_half_load, post["CHP"]["electric_efficiency_full_load"])
# self.assertEqual(validator.models["CHP"].emissions_factor_lb_CO2_per_mmbtu, FUEL_DEFAULTS[post["CHP"]["fuel_type"]])
self.assertEqual(validator.models["ExistingBoiler"].emissions_factor_lb_CO2_per_mmbtu, FUEL_DEFAULTS["emissions_factor_lb_CO2_per_mmbtu"][post["ExistingBoiler"]["fuel_type"]])