forked from NREL/ReEDS-2.0
-
Notifications
You must be signed in to change notification settings - Fork 0
/
c_supplymodel.gms
3430 lines (2522 loc) · 138 KB
/
c_supplymodel.gms
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
*Setting the default slash
$setglobal ds \
*Change the default slash if in UNIX
$ifthen.unix %system.filesys% == UNIX
$setglobal ds /
$endif.unix
*========================================
* -- Supply Side Variable Declaration --
*========================================
positive variables
* load variable - set equal to load_exog to compute holistic marginal price
LOAD(r,allh,t) "--MW-- busbar load for each balancing region"
FLEX(flex_type,r,allh,t) "--MW-- flexible load shifted to each timeslice"
* PEAK_FLEX(r,ccseason,t) "--MW-- peak busbar load adjustment based on load flexibility"
DROPPED(r,allh,t) "--MW-- dropped load (only allowed before Sw_StartMarkets)"
* capacity and investment variables
CAP_SDBIN(i,v,r,ccseason,sdbin,t) "--MW-- generation capacity by storage duration bin for relevant technologies"
CAP(i,v,r,t) "--MW-- total generation capacity in MWac (MWdc for PV); PV capacity of hybrid PV+battery; max native, flexible EV load for EVMC"
CAP_RSC(i,v,r,rscbin,t) "--MW-- total generation capacity in MWac (MWdc for PV) for wind-ons and upv"
GROWTH_BIN(gbin,i,st,t) "--MW-- total new (from INV) generation capacity in each growth bin by state and technology group"
INV(i,v,r,t) "--MW-- generation capacity add in year t"
EXTRA_PRESCRIP(pcat,r,t) "--MW-- builds beyond those prescribed once allowed in firstyear(pcat) - exceptions for gas-ct, wind-ons, and wind-ofs"
INV_CAP_UP(i,v,r,rscbin,t) "--MW-- upsized generation capacity addition in year t"
INV_ENER_UP(i,v,r,rscbin,t) "--MW-- upsized energy addition in year t using capacity factor to convert to capacity units"
INV_REFURB(i,v,r,t) "--MW-- investment in refurbishments of technologies that use a resource supply curve"
INV_RSC(i,v,r,rscbin,t) "--MW-- investment in technologies that use a resource supply curve"
UPGRADES(i,v,r,t) "--MW-- investments in upgraded capacity from ii to i"
UPGRADES_RETIRE(i,v,r,t) "--MW-- upgrades that have been retired - used as a free slack variable in eq_cap_upgrade"
* The units for all of the operational variables are average MW or MWh/time-slice hours
* generation and storage variables
GEN(i,v,r,allh,t) "--MW-- electricity generation (post-curtailment) in hour h"
GEN_PLANT(i,v,r,allh,t) "--MW-- average plant generation from hybrid generation/storage technologies in hour h"
GEN_STORAGE(i,v,r,allh,t) "--MW-- average generation from hybrid storage technologies in hour h"
STORAGE_IN_PLANT(i,v,r,allh,t) "--MW-- hybrid plant storage charging in hour h that is charging from a coupled technology"
STORAGE_IN_GRID(i,v,r,allh,t) "--MW-- hybrid plant storage charging in hour h that is charging from the grid"
AVAIL_SITE(x,allh,t) "--MW-- available generation from all resources at reV site x"
CURT(r,allh,t) "--MW-- curtailment from vre generators in hour h"
MINGEN(r,allszn,t) "--MW-- minimum generation level in each season"
STORAGE_IN(i,v,r,allh,t) "--MW-- storage charging in hour h that is charging from a given source technology; not used for CSP-TES"
STORAGE_LEVEL(i,v,r,allh,t) "--MWh per day-- storage level in hour h"
DR_SHIFT(i,v,r,allh,allhh,t) "--MWh-- annual demand response load shifted to timeslice h from timeslice hh"
DR_SHED(i,v,r,allh,t) "--MWh-- annual demand response load shed from timeslice h"
RAMPUP(i,r,allh,allhh,t) "--MW-- upward change in generation from h to hh"
* flexible CCS variables
CCSFLEX_POW(i,v,r,allh,t) "--avg MW-- average power consumed for CCS system"
CCSFLEX_POWREQ(i,v,r,allh,t) "--avg MW-- average power requirement for CCS system"
CCSFLEX_STO_STORAGE_LEVEL(i,v,r,allh,t) "--varies-- level of process storage (e.g., chemical solvent) in the CCS system"
CCSFLEX_STO_STORAGE_CAP(i,v,r,t) "--varies-- capacity of process storage (e.g., chemical solvent) in the CCS system"
* trade variables
FLOW(r,rr,allh,t,trtype) "--MW-- electricity flow on transmission lines in hour h"
OPRES_FLOW(ortype,r,rr,allh,t) "--MW-- interregional trade of operating reserves by operating reserve type"
PRMTRADE(r,rr,trtype,ccseason,t) "--MW-- planning reserve margin capacity traded from r to rr"
* operating reserve variables
OPRES(ortype,i,v,r,allh,t) "--MW-- operating reserves by type"
* variable fuel amounts
GASUSED(cendiv,gb,allh,t) "--MMBtu/hour-- total gas used by gas bin",
VGASBINQ_NATIONAL(fuelbin,t) "--MMBtu-- National quantity of gas by bin"
VGASBINQ_REGIONAL(fuelbin,cendiv,t) "--MMBtu-- Regional (census divisions) quantity of gas by bin"
BIOUSED(bioclass,r,t) "--MMBtu-- total biomass used by biomass class"
* RECS variables
RECS(RPSCat,i,st,ast,t) "--MWh-- renewable energy credits from state st to state ast",
ACP_PURCHASES(RPSCat,st,t) "--MWh-- purchases of ACP credits to meet the RPS constraints",
* transmission variables
CAPTRAN_ENERGY(r,rr,trtype,t) "--MW-- capacity of transmission for energy trading"
CAPTRAN_PRM(r,rr,trtype,t) "--MW-- capacity of transmission for PRM trading"
CAPTRAN_GRP(transgrp,transgrpp,t) "--MW-- capacity of groups of transmission interfaces"
INVTRAN(r,rr,trtype,t) "--MW-- investment in transmission capacity"
CAP_CONVERTER(r,t) "--MW-- VSC AC/DC converter capacity"
INV_CONVERTER(r,t) "--MW-- investment in AC/DC converter capacity"
CONVERSION(r,allh,intype,outtype,t) "--MW-- conversion of AC->DC or DC->AC"
CONVERSION_PRM(r,ccseason,intype,outtype,t) "--MW-- planning reserve margin capacity sent through VSC AC/DC converters"
CAP_SPUR(x,t) "--MW-- capacity of spur lines"
INV_SPUR(x,t) "--MW-- investment in spur line capacity"
INV_POI(r,t) "--MW-- investment in new POI capacity (for network reinforcement costs)"
* production-, CO2-, and hydrogen-specific variables
PRODUCE(p,i,v,r,allh,t) "--tonnes/hour-- production of hydrogen or DAC capture"
CO2_CAPTURED(r,allh,t) "--tonnes/hour-- amount of CO2 captured from DAC and CCS technologies"
CO2_STORED(r,cs,allh,t) "--tonnes/hour-- amount of CO2 stored underground"
CO2_FLOW(r,rr,allh,t) "--tonnes/hour-- interregional flow of CO2"
CO2_TRANSPORT_INV(r,rr,t) "--tonnes/hour-- investment in interregional CO2 transport capacity"
CO2_SPURLINE_INV(r,cs,t) "--tonnes/hour-- spurline investment from r to carbon storage site (saline storage basin)"
H2_FLOW(r,rr,allh,t) "--tonnes/hour-- interregional flow of hydrogen"
H2_TRANSPORT_INV(r,rr,t) "--tonnes/hour-- investment in interregional hydrogen transmission capacity"
H2_STOR_INV(h2_stor,r,t) "--tonnes-- investment in hydrogen storage capacity"
H2_STOR_CAP(h2_stor,r,t) "--tonnes-- hydrogen storage capacity"
H2_STOR_IN(h2_stor,r,allh,t) "--tonnes/hour-- injection of H2 into storage in a given timeslice"
H2_STOR_OUT(h2_stor,r,allh,t) "--tonnes/hour-- widthdrawal of H2 from storage in a given timeslice"
H2_STOR_LEVEL(h2_stor,r,actualszn,allh,t) "--tonnes-- total storage level of H2 in a timeslice by storage type"
H2_STOR_LEVEL_SZN(h2_stor,r,actualszn,t) "--tonnes-- total storage level of H2 in a period by storage type"
* water climate variables
WATCAP(i,v,r,t) "--million gallons/year; Mgal/yr-- total water access capacity available in terms of withdraw/consumption per year"
WAT(i,v,w,r,allh,t) "--Mgal-- quantity of water withdrawn or consumed in hour h"
WATER_CAPACITY_LIMIT_SLACK(wst,r,t) "--Mgal/yr-- insufficient water supply in region r, of water type wst, in year t "
;
Variables
* with negative emissions technologies (e.g. BECCS, DAC) - emissions
* can become negative thus not restricted to the positive domain
EMIT(e,r,t) "----tons (thousand metric tons for CO2)-- total emissions in a region (note: units dependent on emit_scale)"
;
*========================================
* -- Supply Side Equation Declaration --
*========================================
EQUATION
* load constraint to compute proper marginal value
eq_loadcon(r,allh,t) "--MW-- load constraint used for computing the marginal energy price"
* load flexibility constraints
eq_load_flex_day(flex_type,r,allszn,t) "--MWh-- total flexible load in each season is equal to the exogenously-specified flexible load"
eq_load_flex1(flex_type,r,allh,t) "--MWh-- exogenously-specified flexible demand (load_exog_flex) must be served by flexible load (FLEX)"
eq_load_flex2(flex_type,r,allh,t) "--MWh-- flexible load (FLEX) can't exceed exogenously-specified flexible demand (load_exog_flex)"
* eq_load_flex_peak(r,allh,ccseason,t) "--MWh-- adjust peak demand as needed based on the load flexibility (FLEX)"
* capital stock constraints
eq_cap_init_noret(i,v,r,t) "--MW-- Existing capacity that cannot be retired is equal to exogenously-specified amount"
eq_cap_init_retmo(i,v,r,t) "--MW-- Existing capacity that can be retired must be monotonically decreasing"
eq_cap_init_retub(i,v,r,t) "--MW-- Existing capacity that can be retired is less than or equal to exogenously-specified amount"
eq_cap_new_noret(i,v,r,t) "--MW-- New capacity that cannot be retired is equal to sum of all previous years investment"
eq_cap_new_retmo(i,v,r,t) "--MW-- New capacity that can be retired must be monotonically decreasing unless increased by investment"
eq_cap_new_retub(i,v,r,t) "--MW-- New capacity that can be retired is less than or equal to all previous years investment"
eq_cap_rsc(i,v,r,rscbin,t) "--MW-- Capacity accounting for techs with exogenous capacity tracked by rscbin"
eq_cap_up(i,v,r,rscbin,t) "--MW-- limit on capacity upsizing"
eq_cap_upgrade(i,v,r,t) "--MW-- All purchased upgrades are greater than or equal to the sum of upgraded capacity"
eq_ener_up(i,v,r,rscbin,t) "--MW-- limit on energy upsizing"
eq_forceprescription(pcat,r,t) "--MW-- total investment in prescribed capacity must equal amount from exogenous prescriptions"
eq_refurblim(i,r,t) "--MW-- total refurbishments cannot exceed the amount of capacity that has reached the end of its life"
* renewable supply curves
eq_rsc_inv_account(i,v,r,t) "--MW-- INV for rsc techs is the sum over all bins of INV_RSC"
eq_rsc_INVlim(r,i,rscbin,t) "--MW-- total investment from each rsc bin cannot exceed the available investment"
* capacity growth limits
eq_growthlimit_relative(i,st,t) "--MW-- relative growth limit on technologies"
eq_growthbin_limit(gbin,st,tg,t) "--MW-- capacity limit for each growth bin"
eq_growthlimit_absolute(tg,t) "--MW-- absolute growth limit on technologies"
* storage capacity credit supply curves
eq_cap_sdbin_balance(i,v,r,ccseason,t) "--MW-- total binned storage capacity must be equal to total storage capacity"
eq_sdbin_limit(ccreg,ccseason,sdbin,t) "--MW-- binned storage capacity cannot exceed storage duration bin size"
* operation and reliability
eq_site_cf(x,allh,t) "--MW-- generation at site x <= CF * capacity of constituent resources"
eq_spurclip(x,allh,t) "--MW-- generation at site x <= spurline capacity to x"
eq_spur_noclip(x,t) "--MW-- spurline capacity to x must equal total generation capacity at x"
eq_capacity_limit(i,v,r,allh,t) "--MW-- generation limited to available capacity"
eq_capacity_limit_hybrid(r,allh,t) "--MW-- generation from hybrid resources limited to available capacity"
eq_capacity_limit_nd(i,v,r,allh,t) "--MW-- generation limited to available capacity for non-dispatchable resources"
eq_curt_gen_balance(r,allh,t) "--MW-- net generation and curtailment must equal gross generation"
eq_dhyd_dispatch(i,v,r,allszn,t) "--MWh-- dispatchable hydro seasonal energy constraint (when not allowing seasonal enregy shifting)"
eq_dhyd_dispatch_ann(i,v,r,t) "--MWh-- dispatchable hydro annual energy constraint (only when allowing seasonal energy shifting)"
eq_dhyd_dispatch_szn(i,v,r,allszn,t) "--MWh-- dispatchable hydro seasonal energy constraint"
eq_min_cf(i,r,t) "--MWh-- minimum capacity factor constraint for each generator fleet, applied to (i,r)"
eq_mingen_fixed(i,v,r,allh,t) "--MW-- Generation in each timeslice must be greater than mingen_fixed * capacity"
eq_mingen_lb(r,allh,allszn,t) "--MW-- lower bound on minimum generation level"
eq_mingen_ub(r,allh,allszn,t) "--MW-- upper bound on minimum generation level"
eq_minloading(i,v,r,allh,allhh,t) "--MW-- minimum loading across same-season hours"
eq_ramping(i,r,allh,allhh,t) "--MW-- definition of RAMPUP"
eq_reserve_margin(r,ccseason,t) "--MW-- planning reserve margin requirement"
eq_supply_demand_balance(r,allh,t) "--MW-- supply demand balance"
eq_vsc_flow(r,allh,t) "--MW-- DC power flow"
eq_transmission_limit(r,rr,allh,t,trtype) "--MW-- transmission flow limit"
* operating reserve constraints
eq_OpRes_requirement(ortype,r,allh,t) "--MW-- operating reserve constraint"
eq_ORCap_large_res_frac(ortype,i,v,r,allh,t) "--MW-- operating reserve capacity availability constraint for generators with reserve_frac > 0.5"
eq_ORCap_small_res_frac(ortype,i,v,r,allh,t) "--MW-- operating reserve capacity availability constraint for generators with reserve_frac <= 0.5"
* regional and national policies
eq_emit_accounting(e,r,t) "--tons (metric for CO2)-- accounting for total emissions in a region"
eq_emit_rate_limit(e,r,t) "--tons per MWh (metric for CO2)-- emission rate limit"
eq_annual_cap(e,t) "--tons (metric for CO2)-- annual (year-specific) emissions cap",
eq_bankborrowcap(e) "--weighted tons (metric for CO2)-- flexible banking and borrowing cap (to be used w/intertemporal solve only"
eq_RGGI_cap(t) "--metric tons CO2-- RGGI constraint -- Regions' emissions must be less than the RGGI cap"
eq_state_cap(st,t) "--metric tons CO2-- state-level CO2 cap constraint -- used to represent California cap and trade program"
eq_CSAPR_Budget(csapr_group,t) "--MT NOx-- CSAPR trading group emissions cannot exceed the budget cap"
eq_CSAPR_Assurance(st,t) "--MT NOx-- CSAPR state emissions cannot exceed the assurance cap"
eq_BatteryMandate(st,t) "--MW-- battery storage capacity must be greater than indicated level"
eq_cdr_cap(t) "--metric tons CO2-- CO2 removal (DAC and BECCS) can only offset emissions from fossil+CCS and methane leakage"
* RPS Policy equations
eq_REC_Generation(RPSCat,i,st,t) "--RECs-- Generation of RECs by state"
eq_REC_Requirement(RPSCat,st,t) "--RECs-- RECs generated plus trade must meet the state's requirement"
eq_REC_ooslim(RPSCat,st,t) "--RECs-- RECs imported cannot exceed a fraction of total requirement for certain states",
eq_REC_launder(RPSCat,st,t) "--RECs-- RECs laundering constraint"
eq_REC_BundleLimit(RPSCat,st,ast,t) "--RECS-- trade in bundle recs must be less than interstate electricity transmission"
eq_REC_unbundledLimit(RPScat,st,t) "--RECS-- unbundled RECS cannot exceed some percentage of total REC requirements"
eq_RPS_OFSWind(st,t) "--MW-- MW of offshore wind capacity must be greater than or equal to RPS amount"
eq_national_gen(t) "--MWh-- e.g. a national RPS or CES. require a certain amount of total generation to be from specified sources."
* fuel supply curve equations
eq_gasused(cendiv,allh,t) "--MMBtu-- gas used must be from the sum of gas bins"
eq_gasbinlimit(cendiv,gb,t) "--MMBtu-- limit on gas from each bin"
eq_gasbinlimit_nat(gb,t) "--MMBtu-- national limit on gas from each bin"
eq_bioused(r,t) "--MMBtu-- bio used must be from the sum of bio bins"
eq_biousedlimit(bioclass,usda_region,t) "--MMBtu-- limit on bio from each bin in each USDA region"
* regional natural gas supply curves
eq_gasaccounting_regional(cendiv,t) "--MMBtu-- regional gas consumption cannot exceed the amount used in bins"
eq_gasaccounting_national(t) "--MMBtu-- national gas consumption cannot exceed the amount used in bins"
eq_gasbinlimit_regional(fuelbin,cendiv,t) "--MMBtu-- regional binned gas usage cannot exceed bin capacity"
eq_gasbinlimit_national(fuelbin,t) "--MMBtu-- national binned gas usage cannot exceed bin capacity"
* hydrogen supply and demand
eq_prod_capacity_limit(i,v,r,allh,t) "--tonne-- production cannot exceeds its capacity"
eq_h2_demand(p,t) "--tonne-- production of hydrogen must meet exogenous demand plus H2-CT use"
eq_h2_demand_regional(r,allh,t) "--tonne/hour-- regional hydrogen supply must equal demand net trade and storage"
eq_h2_transport_caplimit(r,rr,allh,t) "--tonne/hour-- H2 flow cannot exceed cumulative pipeline investment"
eq_h2_storage_flowlimit(h2_stor,r,allh,t) "--tonne/hour-- H2 storage injection or withdrawal cannot exceed cumulative storage investment"
eq_h2_storage_capacity(h2_stor,r,t) "--tonnes-- H2 storage capacity is sum of H2 storage investments"
eq_h2_min_storage_cap(r,t) "--tonnes-- H2 storage capacity must be ≥ Sw_H2_MinStorHours * H2 usage capacity"
eq_h2_storage_caplimit(h2_stor,r,actualszn,allh,t) "--tonnes-- total H2 storage in a storage facility cannot exceed investment capacity"
eq_h2_storage_level(h2_stor,r,actualszn,allh,t) "--tonnes-- tracks H2 storage level by storage type and BA within and across periods"
eq_h2_storage_caplimit_szn(h2_stor,r,actualszn,t) "--tonnes-- total H2 storage in a storage facility cannot exceed investment capacity"
eq_h2_storage_level_szn(h2_stor,r,actualszn,t) "--tonnes-- tracks H2 storage level by storage type and BA within and across periods"
* CO2 capture and storage
eq_co2_capture(r,allh,t) "--tonne-- accounting of CO2 captured from DAC and CCS technologies"
eq_co2_injection_limit(cs,allh,t) "--tonnes/hour-- limit on CO2 injection for each carbon site as a rate"
eq_co2_sink(r,allh,t) "--tonnes/hour-- co2 stored or used must exceed co2 captured plus net trade"
eq_co2_transport_caplimit(r,rr,allh,t) "--tonnes-- limit on interregional co2 trade"
eq_co2_spurline_caplimit(r,cs,allh,t) "--tonnes-- limit on transport of CO2 from BA to carbon storage site"
eq_co2_cumul_limit(cs,t) "--cumulative tonnes-- total stored in a reservor cannot exceed capacity"
* transmission equations
eq_CAPTRAN_ENERGY(r,rr,trtype,t) "--MW-- capacity accounting for transmission capacity for energy trading"
eq_CAPTRAN_PRM(r,rr,trtype,t) "--MW-- capacity accounting for transmission capacity for PRM trading"
eq_prescribed_transmission(r,rr,trtype,t) "--MW-- investment in transmission up to first year allowed must be less than the exogenous possible transmission",
eq_PRMTRADELimit(r,rr,trtype,ccseason,t) "--MW-- trading of PRM capacity cannot exceed the line's capacity"
eq_transmission_investment_max(t) "--MWmile-- investment in transmission must be <= Sw_TransInvMax"
eq_CAPTRAN_max(r,rr,trtype,t) "--MW-- upper limit for transmission capacity of each trtype across individual interfaces"
eq_CAPTRAN_max_total(r,rr,t) "--MW-- upper limit for transmission capacity of all trtypes across individual interfaces"
eq_CAP_CONVERTER(r,t) "--MW-- capacity accounting for VSC AC/DC converters"
eq_CAP_SPUR(x,t) "--MW-- capacity accounting for spur lines"
eq_converter_max(r,t) "--MW-- upper limit for VSC AC/DC converter capacity in individual BAs"
eq_CONVERSION_limit_energy(r,allh,t) "--MW-- AC/DC energy conversion is limited to converter capacity"
eq_CONVERSION_limit_prm(r,ccseason,t) "--MW-- AC/DC PRM conversion is limited to converter capacity"
eq_PRMTRADE_VSC(r,ccseason,t) "--MW-- PRM capacity can flow through VSC lines but doesn't directly contribute to PRM"
eq_POI_cap(r,t) "--MW-- POI capacity accounting (for network reinforcement costs)"
eq_CAPTRAN_GRP(transgrp,transgrpp,t) "--MW-- combined flow capacity between transmission groups"
eq_transgrp_limit_energy(transgrp,transgrpp,allh,t) "--MW-- limit on combined interface energy flows"
eq_transgrp_limit_prm(transgrp,transgrpp,ccseason,t) "--MW-- limit on combined interface PRM flows"
eq_firm_transfer_limit(nercr,allh,t) "--MW-- limit net firm capacity imports into NERC regions when using stress periods"
eq_firm_transfer_limit_cc(nercr,ccseason,t) "--MW-- limit net firm capacity imports into NERC regions when using capacity credit"
* storage-specific equations
eq_storage_capacity(i,v,r,allh,t) "--MW-- Second storage capacity constraint in addition to eq_capacity_limit"
eq_storage_duration(i,v,r,allh,t) "--MWh-- limit STORAGE_LEVEL based on hours of storage available"
eq_storage_in_cap(i,v,r,allh,t) "--MW-- storage_in must be less than a given fraction of power output capacity"
eq_storage_in_minloading(i,v,r,allh,allhh,t) "--MW-- minimum level for storage_in across same-season hours"
eq_storage_level(i,v,r,allh,t) "--MWh per day-- Storage level inventory balance from one time-slice to the next"
eq_storage_opres(i,v,r,allh,t) "--MWh per day-- there must be sufficient energy in the storage to be able to provide operating reserves"
eq_storage_seas_szn(i,v,r,allszn,t) "--MWh-- GEN in a season must be greater than a certain percentage of STORAGE_IN in that season"
eq_storage_seas(i,v,r,t) "--MWh-- total STORAGE_IN must balance GEN across all time-slices"
eq_storage_thermalres(i,v,r,allh,t) "--MW-- thermal storage contribution to operating reserves is store_in only"
* demand-response specific equations
eq_dr_max_shed(i,v,r,allh,t) "--MW-- total shed allowed by demand response technologies from timeslice h"
eq_dr_max_shed_hrs(i,v,r,t) "--MW-- total hours shed is allowed to operate over the year"
eq_dr_max_shift(i,v,r,allh,allhh,t) "--MW-- total shifting allowed by demand response technologies to timeslice h from timeslice hh"
eq_dr_max_decrease(i,v,r,allh,t) "--MW-- maximum allowed decrease of load from demand response in timeslice h"
eq_dr_max_increase(i,v,r,allh,t) "--MW-- maximum allowed increase of load from demand response in timeslice h"
eq_dr_gen(i,v,r,allh,t) "--MW-- link demand response shifting to generation"
* hybrid plant equations
eq_plant_total_gen(i,v,r,allh,t) "--MW-- generation post curtailment = generation from pv (post curtailment) + generation from battery - charging from PV"
eq_hybrid_plant_energy_limit(i,v,r,allh,t) "--MW-- PV energy to storage (no curtailment recovery) + PV energy to inverter <= PV resource"
eq_plant_capacity_limit(i,v,r,allh,t) "--MW-- energy moving through the inverter cannot exceed the inverter capacity"
eq_pvb_itc_charge_reqt(i,v,r,t) "--MWh-- total energy charged from local PV >= ITC qualification fraction * total energy charged"
* Canadian imports balance
eq_Canadian_Imports(r,allszn,t) "--MWh-- Balance of Canadian imports by season"
* water usage accounting
eq_water_accounting(i,v,w,r,allh,t) "--Mgal-- water usage accounting"
eq_water_capacity_total(i,v,r,t) "--Mgal-- specify required water access based on generation capacity and water use rate"
eq_water_capacity_limit(wst,r,t) "--Mgal/yr-- total water access must not exceed supply by region and water type"
eq_water_use_limit(i,v,w,r,allszn,t) "--Mgal/yr-- water use must not exceed available access"
* flexible CCS constraints
eq_ccsflex_byp_ccsenergy_limit(i,v,r,allh,t) "--avg MW-- Limit the CCS power for a bypass system in each time-slice"
eq_ccsflex_sto_ccsenergy_limit_szn(i,v,r,allszn,t) "--MWh-- Limit the CCS power for a storage system across a characteristic day"
eq_ccsflex_sto_ccsenergy_balance(i,v,r,allszn,t) "--MWh-- Total CCS energy requirement can be distributed across a characteristic day"
eq_ccsflex_sto_storage_level(i,v,r,allh,t) "--varies-- Track the level of the CCS storage balance for each time-slice"
eq_ccsflex_sto_storage_level_max(i,v,r,allh,t) "--varies-- Limit the level of the CCS storage system"
;
*==========================
* --- LOAD CONSTRAINTS ---
*==========================
* ---------------------------------------------------------------------------
*the marginal off of this constraint allows you to
*determine the full price of electricity load
*i.e. the price of load with consideration to operating
*reserve and planning reserve margin considered
eq_loadcon(r,h,t)$tmodel(t)..
LOAD(r,h,t)
=e=
*[plus] the static, exogenous load
+ load_exog_static(r,h,t)
*[plus] exogenously defined exports to Canada
* note net canadian load (when Sw_Canada = 2) is included
* in eq_supply_demand since LOAD needs to stay positive
* while net_trade can be negative and cause infeasibilities
+ can_exports_h(r,h,t)$[Sw_Canada=1]
*[plus] load from EV charging (baseline/unmanaged)
+ evmc_baseline_load(r,h,t)$Sw_EVMC
*[plus] shifted load from adopted EVMC shape resources
+ sum{(i,v)$[evmc_shape(i)$valcap(i,v,r,t)], evmc_shape_load(i,r,h) * CAP(i,v,r,t)}
*[plus] load shifted from other timeslices
+ sum{flex_type, FLEX(flex_type,r,h,t) }$Sw_EFS_flex
*[plus] Load created by production activities - only tracked during representative hours
* [tonne/hour] / [tonne/MWh] = [MW]
+ sum{(p,i,v)$[consume(i)$valcap(i,v,r,t)$i_p(i,p)$(not sameas(i,"dac_gas"))],
PRODUCE(p,i,v,r,h,t) / prod_conversion_rate(i,v,r,t) }$[Sw_Prod$h_rep(h)]
*[plus] load for compressors associated with hydrogen storage injections or withdrawals
* tonnes/hour * MWh/tonnes = MW
+ sum{h2_stor$h2_stor_r(h2_stor,r),
h2_network_load(h2_stor,t)
* ( H2_STOR_IN(h2_stor,r,h,t) + H2_STOR_OUT(h2_stor,r,h,t) ) }$Sw_H2_CompressorLoad
* [plus] load for hydrogen pipeline compressors
* tonnes/hour * MWh/tonnes = MW
+ sum{rr$h2_routes(r,rr),
h2_network_load("h2_compressor",t)
* (( H2_FLOW(r,rr,h,t) + H2_FLOW(rr,r,h,t) ) / 2) }$Sw_H2_CompressorLoad
;
* ---------------------------------------------------------------------------
*======================================
* --- LOAD FLEXIBILITY CONSTRAINTS ---
*======================================
* ---------------------------------------------------------------------------
*The following 3 equations apply to the flexibility of load in ReEDS, originally developed
*as part of the EFS study in ReEDS heritage and adapted for ReEDS-2.0 here.
* Additional work has been done to represent flexible load as a generator + storage
* with boundaries on how many timeslices this generator may shift. See equations
* in the DR CONSTRAINTS section for that representation
* FLEX load in each season equals the total exogenously-specified flexible load in each season
eq_load_flex_day(flex_type,r,szn,t)$[tmodel(t)$Sw_EFS_flex]..
sum{h$h_szn(h,szn), FLEX(flex_type,r,h,t) * hours(h) } / numdays(szn)
=e=
sum{h$h_szn(h,szn), load_exog_flex(flex_type,r,h,t) * hours(h) } / numdays(szn)
;
* ---------------------------------------------------------------------------
* for the "previous" flex type: the amount of exogenously-specified load in timeslice "h"
* must be served by FLEX load either in the timeslice h or the timeslice PRECEEDING h
*
* for the "next" flex type: the amount of exogenously-specified load in timeslice "h"
* must be served by FLEX load either in the timeslice h or the timeslice FOLLOWING h
*
* for the "adjacent" flex type: the amount of exogenously-specified load in timeslice "h"
* must be served by FLEX load either in the timeslice h or a timeslice ADJACENT to h
eq_load_flex1(flex_type,r,h,t)$[tmodel(t)$Sw_EFS_flex]..
FLEX(flex_type,r,h,t) * hours(h)
+ sum{hh$flex_h_corr1(flex_type,h,hh), FLEX(flex_type,r,hh,t) * hours(hh) }
=g=
load_exog_flex(flex_type,r,h,t) * hours(h)
;
* ---------------------------------------------------------------------------
* for the "previous" flex type: FLEX load in timeslice "h" cannot exceed the sum of
* exogenously-specified load in timeslice h and the timeslice following h
*
* for the "next" flex type: FLEX load in timeslice "h" cannot exceed the sum of
* exogenously-specified load in timeslice h and the timeslice preceeding h
*
* for the "adjacent" flex type: FLEX load in timeslice "h" cannot exceed the sum of
* exogenously-specified load in timeslice h and the timeslices adjacent to h
eq_load_flex2(flex_type,r,h,t)$[tmodel(t)$Sw_EFS_flex]..
load_exog_flex(flex_type,r,h,t) * hours(h)
+ sum{hh$flex_h_corr2(flex_type,h,hh), load_exog_flex(flex_type,r,hh,t) * hours(hh) }
=g=
FLEX(flex_type,r,h,t) * hours(h)
;
* * ---------------------------------------------------------------------------
* This constraint and the associated PEAK_FLEX variable are not currently supported
* but are left in the model in case someone decides to revive them.
* eq_load_flex_peak(r,h,ccseason,t)$[tmodel(t)$Sw_EFS_flex]..
* * peak demand EFS flexibility adjustment is greater than
* PEAK_FLEX(r,ccseason,t)$h_ccseason(h,ccseason)
* =g=
* * the static peak in each timeslice
* peakdem_static_h(r,h,t)$h_ccseason(h,ccseason)
* * PLUS the flexibile load served in each timeslice
* + sum{flex_type, FLEX(flex_type,r,h,t) }$h_ccseason(h,ccseason)
* * MINUS the static peak demand in the season corresponding to each timeslice
* - peakdem_static_ccseason(r,ccseason,t)$h_ccseason(h,ccseason)
* ;
* ---------------------------------------------------------------------------
*=========================================================
* --- EQUATIONS RELATING CAPACITY ACROSS TIME PERIODS ---
*=========================================================
*====================================
* -- existing capacity equations --
*====================================
$ontext
The following six equations dictate how capacity is represented in the model.
The first three equations handle init-X vintages (those that existed pre-2010)
which are bounded by m_capacity_exog. With retirements (in the second and third
equations), the constraints imply that capacity must be less than or
equal to m_capacity_exog and monotonically decreasing over time -
implying that if endogenous capacity was reduced in the previous year,
it cannot be brought back online.
New capacity, handled in equations four through six, is the sum of previous
years' greenfield investments and refurbishments. The same logic is present
for retiring capacity, the only difference being that contemporaneous
investment can increase the present-period's capacity.
Upgraded capacity reduces the total amount of capacity available to the
upgraded-from technology. For example, the model starts with 100MW of
coaloldscr (m_capacity_exog = 100) capacity then upgrades 10MW of that to
coaloldscr_coal-ccs capacity. The remaining amount of available coaloldscr
is thus 90 and coaloldscr_coal-ccs capacity is 10 but both are still less
than the 100 available. As time progresses and exogenous capacity declines,
the model chooses which units to take offline.
$offtext
* ---------------------------------------------------------------------------
eq_cap_init_noret(i,v,r,t)$[valcap(i,v,r,t)$tmodel(t)$initv(v)$(not upgrade(i))
$(not retiretech(i,v,r,t))]..
m_capacity_exog(i,v,r,t)
* Account for capacity upsizing within init vintages
+ sum{(tt,rscbin)$[(tmodel(tt) or tfix(tt))$allow_cap_up(i,v,r,rscbin,tt)],
degrade(i,tt,t) * INV_CAP_UP(i,v,r,rscbin,tt) }
=e=
CAP(i,v,r,t)
+ sum{ii$[valcap(ii,v,r,t)$upgrade_from(ii,i)],
CAP(ii,v,r,t) / (1 - upgrade_derate(ii,v,r,t))}$[Sw_Upgrades = 1]
* include contemporaneous upgrades when they are intended to
* persist as new bintages with sw_upgrades = 2
+ sum{(ii)$[upgrade_from(ii,i)$valcap(ii,v,r,t)],
UPGRADES(ii,v,r,t) }$[Sw_Upgrades = 2]
;
* ---------------------------------------------------------------------------
eq_cap_init_retub(i,v,r,t)$[valcap(i,v,r,t)$tmodel(t)$initv(v)$(not upgrade(i))
$retiretech(i,v,r,t)]..
m_capacity_exog(i,v,r,t)
* Account for capacity upsizing within init vintages
+ sum{(tt,rscbin)$[(tmodel(tt) or tfix(tt))$allow_cap_up(i,v,r,rscbin,tt)],
degrade(i,tt,t) * INV_CAP_UP(i,v,r,rscbin,tt) }
=g=
CAP(i,v,r,t)
+ sum{ii$[valcap(ii,v,r,t)$upgrade_from(ii,i)],
CAP(ii,v,r,t) / (1 - upgrade_derate(ii,v,r,t))}$[Sw_Upgrades = 1]
* include contemporaneous upgrades when they are intended to
* persist as new bintages with sw_upgrades = 2
+ sum{(ii)$[upgrade_from(ii,i)$valcap(ii,v,r,t)],
UPGRADES(ii,v,r,t) }$[Sw_Upgrades = 2]
;
* ---------------------------------------------------------------------------
eq_cap_init_retmo(i,v,r,t)$[valcap(i,v,r,t)$tmodel(t)$initv(v)$(not upgrade(i))
$retiretech(i,v,r,t)]..
sum{tt$[tprev(t,tt)$valcap(i,v,r,tt)],
CAP(i,v,r,tt)
+ sum{ii$[valcap(ii,v,r,tt)$upgrade_from(ii,i)],
CAP(ii,v,r,tt) / (1 - upgrade_derate(ii,v,r,tt)) }$[Sw_Upgrades = 1]
}
* Account for capacity upsizing within init vintages
+ sum{rscbin$allow_cap_up(i,v,r,rscbin,t), INV_CAP_UP(i,v,r,rscbin,t) }
=g=
CAP(i,v,r,t)
+ sum{ii$[valcap(ii,v,r,t)$upgrade_from(ii,i)],
CAP(ii,v,r,t) / (1 - upgrade_derate(ii,v,r,t))}$[Sw_Upgrades = 1]
* include contemporaneous upgrades when they are intended to
* persist as new bintages with sw_upgrades = 2
+ sum{(ii)$[upgrade_from(ii,i)$valcap(ii,v,r,t)],
UPGRADES(ii,v,r,t) }$[Sw_Upgrades = 2]
;
* ---------------------------------------------------------------------------
*==============================
* -- new capacity equations --
*==============================
* ---------------------------------------------------------------------------
eq_cap_new_noret(i,v,r,t)$[valcap(i,v,r,t)$tmodel(t)$newv(v)$(not upgrade(i))
$(not retiretech(i,v,r,t))]..
sum{tt$[inv_cond(i,v,r,t,tt)$(tmodel(tt) or tfix(tt))$valcap(i,v,r,tt)],
degrade(i,tt,t) * (INV(i,v,r,tt) + INV_REFURB(i,v,r,tt)$[refurbtech(i)$Sw_Refurb])
}
* Account for capacity upsizing within new vintages
+ sum{(tt,rscbin)$[(tmodel(tt) or tfix(tt))$allow_cap_up(i,v,r,rscbin,tt)],
degrade(i,tt,t) * INV_CAP_UP(i,v,r,rscbin,tt) }
=e=
CAP(i,v,r,t)
+ sum{ii$[valcap(ii,v,r,t)$upgrade_from(ii,i)],
CAP(ii,v,r,t) / (1 - upgrade_derate(ii,v,r,t))}$[Sw_Upgrades = 1]
* include contemporaneous upgrades when they are intended to
* persist as new bintages with sw_upgrades = 2
+ sum{(ii)$[upgrade_from(ii,i)$valcap(ii,v,r,t)],
UPGRADES(ii,v,r,t) }$[Sw_Upgrades = 2]
;
* ---------------------------------------------------------------------------
eq_cap_new_retub(i,v,r,t)$[valcap(i,v,r,t)$tmodel(t)$newv(v)$(not upgrade(i))
$retiretech(i,v,r,t)]..
sum{tt$[inv_cond(i,v,r,t,tt)$(tmodel(tt) or tfix(tt))$valcap(i,v,r,tt)],
degrade(i,tt,t) * (INV(i,v,r,tt) + INV_REFURB(i,v,r,tt)$[refurbtech(i)$Sw_Refurb])
}
* Account for capacity upsizing within new vintages
+ sum{(tt,rscbin)$[(tmodel(tt) or tfix(tt))$allow_cap_up(i,v,r,rscbin,tt)],
degrade(i,tt,t) * INV_CAP_UP(i,v,r,rscbin,tt) }
=g=
CAP(i,v,r,t)
+ sum{ii$[valcap(ii,v,r,t)$upgrade_from(ii,i)],
CAP(ii,v,r,t) / (1 - upgrade_derate(ii,v,r,t))}$[Sw_Upgrades = 1]
* include contemporaneous upgrades when they are intended to
* persist as new bintages with sw_upgrades = 2
+ sum{(ii)$[upgrade_from(ii,i)$valcap(ii,v,r,t)],
UPGRADES(ii,v,r,t) }$[Sw_Upgrades = 2]
;
* ---------------------------------------------------------------------------
eq_cap_new_retmo(i,v,r,t)$[valcap(i,v,r,t)$tmodel(t)$newv(v)$(not upgrade(i))
$retiretech(i,v,r,t)]..
sum{tt$[tprev(t,tt)$valcap(i,v,r,tt)],
degrade(i,tt,t) * CAP(i,v,r,tt)
+ sum{ii$[valcap(ii,v,r,tt)$upgrade_from(ii,i)],
CAP(ii,v,r,tt) / (1 - upgrade_derate(ii,v,r,tt)) }$[Sw_Upgrades = 1]
}
+ INV(i,v,r,t)$valinv(i,v,r,t)
+ INV_REFURB(i,v,r,t)$[valinv(i,v,r,t)$refurbtech(i)$Sw_Refurb]
* Account for capacity upsizing within new vintages
+ sum{rscbin$allow_cap_up(i,v,r,rscbin,t), INV_CAP_UP(i,v,r,rscbin,t) }
=g=
CAP(i,v,r,t)
+ sum{ii$[valcap(ii,v,r,t)$upgrade_from(ii,i)],
CAP(ii,v,r,t) / (1 - upgrade_derate(ii,v,r,t))}$[Sw_Upgrades = 1]
* include contemporaneous upgrades when they are intended to
* persist as new bintages with sw_upgrades = 2
+ sum{(ii)$[upgrade_from(ii,i)$valcap(ii,v,r,t)],
UPGRADES(ii,v,r,t) }$[Sw_Upgrades = 2]
;
* ---------------------------------------------------------------------------
* Capacity accounting for rsc techs
eq_cap_rsc(i,v,r,rscbin,t)
$[tmodel(t)
$rsc_i(i)$(not sccapcosttech(i))
$valcap(i,v,r,t)]..
sum{tt$[tfirst(tt)$exog_rsc(i)],
capacity_exog_rsc(i,v,r,rscbin,tt) }
+ sum{tt$[(yeart(tt) <= yeart(t))$(tmodel(tt) or tfix(tt))
$m_rscfeas(r,i,rscbin)
$valinv(i,v,r,tt)],
INV_RSC(i,v,r,rscbin,tt)
}
=e=
CAP_RSC(i,v,r,rscbin,t)
;
* ---------------------------------------------------------------------------
eq_cap_upgrade(i,v,r,t)$[valcap(i,v,r,t)$upgrade(i)$Sw_Upgrades$tmodel(t)]..
(1 - upgrade_derate(i,v,r,t)) * (
* without peristent upgrades, all upgrades correspond to their original bintage
sum{(tt)$[(tfix(tt) or tmodel(tt))$(yeart(tt)<=yeart(t))$(yeart(tt)>=Sw_Upgradeyear)
$valcap(i,v,r,tt)$sum{ii$upgrade_from(i,ii),valcap(ii,v,r,tt)}],
UPGRADES(i,v,r,tt) }$[Sw_Upgrades=1]
* all previous years upgrades converted to new bintages of the present year
* NOTE: the 'v' in ivt(i,v,tt) here is an important distinction -
* although we're summing over 'vv' we still only want upgrades
* to be included for the upgrade tech's vintage combination
+ sum{(tt,vv)$[(tfix(tt) or tmodel(tt))$(initv(vv) or sameas(v,vv))
$(yeart(tt)<=yeart(t))$ivt(i,v,tt)
$(yeart(tt)>=Sw_Upgradeyear)
$valcap(i,v,r,tt)
$sum(ii$upgrade_from(i,ii),valcap(ii,vv,r,tt))],
UPGRADES(i,vv,r,tt) }$[Sw_Upgrades=2]
* end product on upgrade_derate
)
=e=
CAP(i,v,r,t)
* note this is equivalent to the previous version that had a =g=
* sign in the corrolary equation but either assumes a retired upgrade
* can be brought back to life again...
+ UPGRADES_RETIRE(i,v,r,t)$[not noret_upgrade_tech(i)]
;
* ---------------------------------------------------------------------------
* Capacity upsizing limit
* This uses rscbin to constrain hydropower upsizing using supply curve data.
eq_cap_up(i,v,r,rscbin,t)$[tmodel(t)$allow_cap_up(i,v,r,rscbin,t)]..
cap_cap_up(i,v,r,rscbin,t)
=g=
sum{tt$[(tmodel(tt) or tfix(tt))], INV_CAP_UP(i,v,r,rscbin,tt) }
;
* ---------------------------------------------------------------------------
*Energy upsizing limit
* This uses rscbin to constrain hydropower upsizing using supply curve data.
eq_ener_up(i,v,r,rscbin,t)$[tmodel(t)$allow_ener_up(i,v,r,rscbin,t)]..
cap_ener_up(i,v,r,rscbin,t)
=g=
sum{tt$[(tmodel(tt) or tfix(tt))], INV_ENER_UP(i,v,r,rscbin,tt) }
;
* ---------------------------------------------------------------------------
eq_forceprescription(pcat,r,t)$[tmodel(t)$force_pcat(pcat,t)$Sw_ForcePrescription
$sum{(i,newv)$[prescriptivelink(pcat,i)], valinv(i,newv,r,t) }]..
*capacity built in the current period or prior
sum{(i,newv,tt)$[valinv(i,newv,r,tt)$prescriptivelink(pcat,i)
$(yeart(tt)<=yeart(t))$(tmodel(tt) or tfix(tt))],
INV(i,newv,r,tt) + INV_REFURB(i,newv,r,tt)$[refurbtech(i)$Sw_Refurb]}
=e=
*must equal the cumulative prescribed amount
sum{tt$[(yeart(tt)<=yeart(t))
$(tmodel(tt) or tfix(tt))],
noncumulative_prescriptions(pcat,r,tt)}
* plus any extra buildouts (no penalty here - used as free slack)
* only on or after the first year the techs are available
+ EXTRA_PRESCRIP(pcat,r,t)$[yeart(t)>=firstyear_pcat(pcat)]
* or in regions where there is a offshore wind requirement
+ EXTRA_PRESCRIP(pcat,r,t)$[r_offshore(r,t)$sameas(pcat,'wind-ofs')]
;
* ---------------------------------------------------------------------------
*limit the amount of refurbishments available in specific year
*this is the sum of all previous year's investment that is now beyond the age
*limit (i.e. it has exited service) plus the amount of retired exogenous capacity
*that we begin with
eq_refurblim(i,r,t)$[tmodel(t)$refurbtech(i)$Sw_Refurb]..
*investments that meet the refurbishment requirement (i.e. they've expired)
sum{(vv,tt)$[m_refurb_cond(i,vv,r,t,tt)$(tmodel(tt) or tfix(tt))$valinv(i,vv,r,tt)],
INV(i,vv,r,tt) }
*[plus] exogenous decay in capacity
*note here that the tfix or tmodel set does not apply
*since we'd want capital that expires in off-years to
*be included in this calculation as well
+ sum{(v,tt)$[yeart(tt)<=yeart(t)],
avail_retire_exog_rsc(i,v,r,tt) }
=g=
*must exceed the total sum of investments in refurbishments
*that have yet to expire - implying an investment can be refurbished more than once
*if the first refurbishment has exceed its age limit
sum{(vv,tt)$[inv_cond(i,vv,r,t,tt)$(tmodel(tt) or tfix(tt))$valinv(i,vv,r,tt)],
INV_REFURB(i,vv,r,tt)
}
;
* ---------------------------------------------------------------------------
eq_rsc_inv_account(i,v,r,t)$[tmodel(t)$valinv(i,v,r,t)$rsc_i(i)]..
sum{rscbin$m_rscfeas(r,i,rscbin), INV_RSC(i,v,r,rscbin,t) }
=e=
INV(i,v,r,t)
;
* ---------------------------------------------------------------------------
*note that the following equation only restricts inv_rsc and not inv_refurb
*therefore, the capacity indicated by the supply curve may be limiting
*but the plant can still be refurbished
eq_rsc_INVlim(r,i,rscbin,t)$[tmodel(t)$rsc_i(i)$m_rscfeas(r,i,rscbin)$m_rsc_con(r,i)]..
*With water constraints, some RSC techs are expanded to include cooling technologies
*but the combination of m_rsc_con and rsc_agg allows for those investments
*to be limited by the numeraire techs' m_rsc_dat
*capacity indicated by the resource supply curve (with undiscovered geo available
*at the "discovered" amount and hydro upgrade availability adjusted over time)
m_rsc_dat(r,i,rscbin,"cap") * (
1$[not geo_hydro(i)] + geo_discovery(i,r,t)$geo_hydro(i))
+ hyd_add_upg_cap(r,i,rscbin,t)$(Sw_HydroCapEnerUpgradeType=1)
* available DR capacity
+ rsc_dr(i,r,"cap",rscbin,t)
* available EVMC capacity
+ rsc_evmc(i,r,"cap",rscbin,t)
=g=
*must exceed the cumulative invested capacity in that region/class/bin...
sum{(ii,v,tt)$[valinv(ii,v,r,tt)$(yeart(tt) <= yeart(t))$rsc_agg(i,ii)$(not dr(i))],
INV_RSC(ii,v,r,rscbin,tt) * resourcescaler(ii) }
*plus exogenous (pre-start-year) capacity, using its level in the first year (tfirst)
+ sum{(ii,v,tt)$[tfirst(tt)$rsc_agg(i,ii)$(not dr(i))$exog_rsc(i)],
capacity_exog_rsc(ii,v,r,rscbin,tt) }
* in that year for DR (since DR investment is annual)
+ sum{(ii,v)$[valinv(ii,v,r,t)$rsc_agg(i,ii)$dr(i)],
INV_RSC(ii,v,r,rscbin,t) * resourcescaler(ii) }
;
* ---------------------------------------------------------------------------
eq_growthlimit_relative(i,st,t)$[sum{r$[r_st(r,st)], valinv_irt(i,r,t) }
$tmodel(t)
$stfeas(st)
$Sw_GrowthPenalties
$(yeart(t)<=Sw_GrowthConLastYear)
$(yeart(t)>=model_builds_start_yr)]..
*the annual growth limit
(yeart(t) - sum{tt$[tprev(t,tt)], yeart(tt) })
* sum{gbin, GROWTH_BIN(gbin,i,st,t) }
=g=
* must exceed the current periods investment
sum{(v,r)$[valinv(i,v,r,t)$r_st(r,st)],
INV(i,v,r,t) }
;
eq_growthbin_limit(gbin,st,tg,t)$[valinv_tg(st,tg,t)
$tmodel(t)
$stfeas(st)
$Sw_GrowthPenalties
$(yeart(t)<=Sw_GrowthConLastYear)
$(yeart(t)>=model_builds_start_yr)]..
*the growth bin limit
growth_bin_limit(gbin,st,tg,t)
=g=
* must exceed the value in the growth bin
sum{i$tg_i(tg,i), GROWTH_BIN(gbin,i,st,t) }
;
* ---------------------------------------------------------------------------
eq_growthlimit_absolute(tg,t)$[growth_limit_absolute(tg)$tmodel(t)
$Sw_GrowthAbsCon$(yeart(t)<=Sw_GrowthConLastYear)
$(yeart(t)>=model_builds_start_yr)]..
* the absolute limit of growth (in MW)
(sum{tt$[tprev(tt,t)], yeart(tt) } - yeart(t))
* growth_limit_absolute(tg)
=g=
* must exceed the total investment - same RHS as previous equation
sum{(i,v,r,rscbin)$[valinv(i,v,r,t)$m_rscfeas(r,i,rscbin)$tg_i(tg,i)$rsc_i(i)],
INV_RSC(i,v,r,rscbin,t) }
;
* ---------------------------------------------------------------------------
* If using hybrid generators with endogenous spur lines, the available power from
* a reV site is limited by the CF and capacity of constituent resources at that site
eq_site_cf(x,h,t)
$[tmodel(t)
$Sw_SpurScen
$xfeas(x)]..
sum{(i,v,r)
$[spur_techs(i)
$x_r(x,r)
$valgen(i,v,r,t)],
* Capacity factor of techs with endogenously-modeled spur lines
m_cf(i,v,r,h,t)
* multiplied by total capacity of those techs
* sum{rscbin
$[valcap(i,v,r,t)
$m_rscfeas(r,i,rscbin)
$spurline_sitemap(i,r,rscbin,x)],
CAP_RSC(i,v,r,rscbin,t)
}
}
=g=
AVAIL_SITE(x,h,t)
;
* ---------------------------------------------------------------------------
* If using hybrid generators with endogenous spur lines, each wind and solar generator
* is associated with a specific reV site x. The available generation from all generators
* at site x is limited to the spur-line capacity built to site x.
eq_spurclip(x,h,t)
$[Sw_SpurScen
$xfeas(x)
$tmodel(t)]..
* Capacity of spur line to reV site limits the available generation at that site
CAP_SPUR(x,t)
=g=
AVAIL_SITE(x,h,t)
;
* ---------------------------------------------------------------------------
* If spur-line sharing is disabled, the capacity of the spur line for site x
* must be >= the capacity of the hybrid resources (wind and solar) installed at site x
eq_spur_noclip(x,t)
$[Sw_SpurScen
$(not Sw_SpurShare)
$xfeas(x)
$tmodel(t)]..
* Capacity of spur line to site x
CAP_SPUR(x,t)
=g=
* must be >= to the wind/solar capacity installed at x
* (Since PV capacity is in DC, we divide CAP_RSC [DC] by ILR [DC/AC] to get AC spur line capacity.
* ILR is 1 for all non-PV techs.)
sum{(i,v,r,rscbin)
$[spurline_sitemap(i,r,rscbin,x)
$valcap(i,v,r,t)],
CAP_RSC(i,v,r,rscbin,t) / ilr(i)
}
;
* ---------------------------------------------------------------------------
*capacity must be greater than supply
*dispatchable hydro is accounted for both in this constraint and in eq_dhyd_dispatch
*this constraint does not apply to storage nor hybrid plant
* limits for storage (including storage of hybrid plants) are tracked in eq_storage_capacity
* limits for plant of Hybrid Plant are tracked in eq_plant_energy_balance
* limits for hybrid techs with shared spur lines are treated in eq_capacity_limit_hybrid
eq_capacity_limit(i,v,r,h,t)
$[tmodel(t)$valgen(i,v,r,t)
$(not spur_techs(i))
$(not storage_standalone(i))$(not storage_hybrid(i)$(not csp(i)))$(not nondispatch(i))]..
*total amount of dispatchable, non-hydro capacity
avail(i,h)$[dispatchtech(i)$(not hydro_d(i))]
* derate_geo_vintage(i,v)
* (1 + sum{szn, h_szn(h,szn) * seas_cap_frac_delta(i,v,r,szn,t)})
* CAP(i,v,r,t)
*total amount of dispatchable hydro capacity
+ avail(i,h)$hydro_d(i)
* CAP(i,v,r,t)
* sum{szn$h_szn(h,szn), cap_hyd_szn_adj(i,szn,r) }
* (1 + hydro_capcredit_delta(i,t)$[h_stress(h)])
*sum of non-dispatchable capacity multiplied by its rated capacity factor,
*only vre technologies are curtailable.
* This term accounts for energy-only and capacity-only upsizing,
* which is initially implemented only for hydro.
+ (m_cf(i,v,r,h,t)
* (CAP(i,v,r,t)
*add energy embedded in energy-only upsizing
+ sum{(tt,rscbin)$[(tmodel(tt) or tfix(tt))],
INV_ENER_UP(i,v,r,rscbin,tt)$allow_ener_up(i,v,r,rscbin,tt)
*subtract energy that would be embedded in a capacity-only upsizing
- degrade(i,tt,t) * INV_CAP_UP(i,v,r,rscbin,tt)$allow_cap_up(i,v,r,rscbin,tt) })
)$[not dispatchtech(i)]
*add EVMC shape generation
+ (evmc_shape_gen(i,r,h) * CAP(i,v,r,t))
=g=
*must exceed generation
GEN(i,v,r,h,t)
*[plus] sum of operating reserves by type
+ sum{ortype$[Sw_OpRes$reserve_frac(i,ortype)$opres_h(h)$opres_model(ortype)],
OPRES(ortype,i,v,r,h,t) }