From c5d318d978da65e72914686b3facfd1d19a0af64 Mon Sep 17 00:00:00 2001 From: adfarth Date: Thu, 1 Oct 2026 15:32:25 -0600 Subject: [PATCH] add outage_production_fraction --- CHANGELOG.md | 5 ++++ ...uts_outage_production_fraction_and_more.py | 24 +++++++++++++++++++ reoptjl/models.py | 19 +++++++++++++++ reoptjl/test/posts/all_inputs_test.json | 6 +++-- 4 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 reoptjl/migrations/0126_pvinputs_outage_production_fraction_and_more.py diff --git a/CHANGELOG.md b/CHANGELOG.md index fb9f0135e..3c4610eae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,11 @@ Classify the change according to the following categories: ##### Removed ### Patches +## add-outage-prod-option +### Minor Updates +#### Added +- Inputs **PV.outage_production_fraction** and **Wind.outage_production_fraction** to optionally reduce production during modeled outages. Only applies with multiple outage modeling using inputs outage_start_time_steps and outage_durations. + ## v3.23.0 ### Minor Updates ##### Changed diff --git a/reoptjl/migrations/0126_pvinputs_outage_production_fraction_and_more.py b/reoptjl/migrations/0126_pvinputs_outage_production_fraction_and_more.py new file mode 100644 index 000000000..e2245c4e3 --- /dev/null +++ b/reoptjl/migrations/0126_pvinputs_outage_production_fraction_and_more.py @@ -0,0 +1,24 @@ +# Generated by Django 4.2.26 on 2026-10-01 21:31 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('reoptjl', '0125_chpoutputs_annual_thermal_curtailed_mmbtu_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='pvinputs', + name='outage_production_fraction', + field=models.FloatField(blank=True, default=1.0, help_text='Fraction of production available during outages. Only applies with multiple outage modeling using inputs outage_start_time_steps and outage_durations.', validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(1.0)]), + ), + migrations.AddField( + model_name='windinputs', + name='outage_production_fraction', + field=models.FloatField(blank=True, default=1.0, help_text='Fraction of production available during outages. Only applies with multiple outage modeling using inputs outage_start_time_steps and outage_durations.', validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(1.0)]), + ), + ] diff --git a/reoptjl/models.py b/reoptjl/models.py index 32f69e66d..de54216c7 100644 --- a/reoptjl/models.py +++ b/reoptjl/models.py @@ -3284,6 +3284,16 @@ class PV_LOCATION_CHOICES(models.TextChoices): "Required operating reserves applied to each timestep as a fraction of PV generation serving load in that timestep.") ) + outage_production_fraction = models.FloatField( + validators=[ + MinValueValidator(0), + MaxValueValidator(1.0) + ], + blank=True, + default=1.0, + help_text=("Fraction of production available during outages. Only applies with multiple outage modeling using inputs outage_start_time_steps and outage_durations.") + ) + class PVOutputs(BaseModel, models.Model): key = "PVOutputs" @@ -3624,6 +3634,15 @@ class WIND_SIZE_CLASS_CHOICES(models.TextChoices): blank=True, help_text="Land area required per kW of wind capacity in acres/kW; only constrained by this for systems greater than 1500 kW" ) + outage_production_fraction = models.FloatField( + validators=[ + MinValueValidator(0), + MaxValueValidator(1.0) + ], + blank=True, + default=1.0, + help_text=("Fraction of production available during outages. Only applies with multiple outage modeling using inputs outage_start_time_steps and outage_durations.") + ) def clean(self): if self.size_class != "" and self.installed_cost_per_kw is None: diff --git a/reoptjl/test/posts/all_inputs_test.json b/reoptjl/test/posts/all_inputs_test.json index e72fbdbc1..78447cda0 100644 --- a/reoptjl/test/posts/all_inputs_test.json +++ b/reoptjl/test/posts/all_inputs_test.json @@ -115,7 +115,8 @@ "can_wholesale": true, "can_export_beyond_nem_limit": true, "can_curtail": true, - "operating_reserve_required_fraction": 0.0 + "operating_reserve_required_fraction": 0.0, + "outage_production_fraction": 1.0 }, "Meta": { "description": "", @@ -269,7 +270,8 @@ "can_export_beyond_nem_limit": true, "can_curtail": true, "operating_reserve_required_fraction": 0.0, - "acres_per_kw": 0.03 + "acres_per_kw": 0.03, + "outage_production_fraction": 1.0 }, "ExistingBoiler": { "production_type": "hot_water",