• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

blue-marble / gridpath / 17133679901

11 Aug 2025 04:06PM UTC coverage: 88.961%. Remained the same
17133679901

push

github

web-flow
Fixes to inertia requirements (#1278)

Fix inertia requirement if they are based on the capacity of project. Also allow units to reduce operational reserve requirements based on their power output or capacity.

2 of 2 new or added lines in 2 files covered. (100.0%)

27 existing lines in 27 files now uncovered.

27344 of 30737 relevant lines covered (88.96%)

1.78 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.24
/tests/test_examples.py
1
# Copyright 2016-2023 Blue Marble Analytics LLC.
2
#
3
# Licensed under the Apache License, Version 2.0 (the "License");
4
# you may not use this file except in compliance with the License.
5
# You may obtain a copy of the License at
6
#
7
#     http://www.apache.org/licenses/LICENSE-2.0
8
#
9
# Unless required by applicable law or agreed to in writing, software
10
# distributed under the License is distributed on an "AS IS" BASIS,
11
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
# See the License for the specific language governing permissions and
13
# limitations under the License.
14

15
import ast
2✔
16
import csv
2✔
17
import logging
2✔
18
import multiprocessing
2✔
19
import os
2✔
20
import pandas as pd
2✔
21
import platform
2✔
22
import sqlite3
2✔
23
import unittest
2✔
24

25
from gridpath import run_end_to_end, run_scenario, validate_inputs
2✔
26
from db import create_database
2✔
27
from db.common_functions import connect_to_database
2✔
28
from db.utilities import port_csvs_to_db, scenario
2✔
29

30
# Change directory to 'gridpath' directory, as that's what run_scenario.py
31
# expects; the rest of the global variables are relative paths from there
32
os.chdir(os.path.join(os.path.dirname(__file__), "..", "gridpath"))
2✔
33
EXAMPLES_DIRECTORY = os.path.join("..", "examples")
2✔
34
DB_NAME = "unittest_examples"
2✔
35
DB_PATH = f"../db/{DB_NAME}.db"
2✔
36
DB_SCHEMA = f"../db/db_schema.sql"
2✔
37
DATA_DIRECTORY = "../db/data"
2✔
38
CSV_PATH = "../db//csvs_test_examples"
2✔
39
SCENARIOS_CSV = os.path.join(CSV_PATH, "scenarios.csv")
2✔
40
TEST_SCENARIOS_CSV = "../tests/test_data/test_scenario_objective_function_values.csv"
2✔
41

42
# Platform check
43
LINUX = True if platform.system() == "Linux" else False
2✔
44
MACOS = True if platform.system() == "Darwin" else False
2✔
45
WINDOWS = True if platform.system() == "Windows" else False
2✔
46

47

48
class TestExamples(unittest.TestCase):
2✔
49
    """ """
50

51
    df = pd.read_csv(TEST_SCENARIOS_CSV, delimiter=",")
2✔
52
    df.set_index("test_scenario", inplace=True)
2✔
53

54
    def assertDictAlmostEqual(self, d1, d2, msg=None, places=7):
2✔
55
        # check if both inputs are dicts
56
        self.assertIsInstance(d1, dict, "First argument is not a dictionary")
2✔
57
        self.assertIsInstance(d2, dict, "Second argument is not a dictionary")
2✔
58

59
        # check if both inputs have the same keys
60
        self.assertEqual(d1.keys(), d2.keys())
2✔
61

62
        # check each key
63
        for key, value in d1.items():
2✔
64
            if isinstance(value, dict):
2✔
65
                self.assertDictAlmostEqual(d1[key], d2[key], places=places, msg=msg)
2✔
66
            else:
67
                self.assertAlmostEqual(d1[key], d2[key], places=places, msg=msg)
2✔
68

69
    def check_validation(self, test):
2✔
70
        """
71
        Check that validate inputs runs without errors, and that there
72
        are no validation issues recorded in the status_validation table
73
        :return:
74
        """
75

76
        # Check that test validation runs without errors
77
        validate_inputs.main(["--database", DB_PATH, "--scenario", test, "--quiet"])
2✔
78

79
        # Check that no validation issues are recorded in the db for the test
80
        expected_validations = []
2✔
81

82
        conn = connect_to_database(
2✔
83
            db_path=DB_PATH, detect_types=sqlite3.PARSE_DECLTYPES
84
        )
85
        c = conn.cursor()
2✔
86
        validations = c.execute(
2✔
87
            """
88
            SELECT scenario_name FROM status_validation
89
            INNER JOIN
90
            (SELECT scenario_id, scenario_name FROM scenarios)
91
            USING (scenario_id)
92
            WHERE scenario_name = '{}'
93
            """.format(
94
                test
95
            )
96
        )
97
        actual_validations = validations.fetchall()
2✔
98

99
        self.assertListEqual(expected_validations, actual_validations)
2✔
100

101
    def run_and_check_objective(
2✔
102
        self, test, expected_objective, solver=None, parallel=1
103
    ):
104
        """
105

106
        :param test: str, name of the test example
107
        :param expected_objective: float or dict, expected objective
108
        :param parallel: int, set to a number > 1 to test
109
            parallelization functionality
110
        :return:
111
        """
112
        args_to_pass = [
2✔
113
            "--database",
114
            DB_PATH,
115
            "--scenario",
116
            test,
117
            "--scenario_location",
118
            EXAMPLES_DIRECTORY,
119
            # "--log",
120
            # "--write_solver_files_to_logs_dir",
121
            # "--keepfiles",
122
            # "--symbolic",
123
            "--n_parallel_get_inputs",
124
            str(parallel),
125
            "--n_parallel_solve",
126
            str(parallel),
127
            "--quiet",
128
            "--mute_solver_output",
129
            "--testing",
130
        ]
131
        if solver is not None:
2✔
132
            args_to_pass.append("--solver")
×
133
            args_to_pass.append(solver)
×
134

135
        actual_objective = run_end_to_end.main(args_to_pass)
2✔
136

137
        # Check if we have a multiprocessing manager
138
        # If so, convert the manager proxy dictionary to a simple dictionary
139
        # to avoid errors
140
        # Done via copies to avoid broken pipe error
141
        if hasattr(multiprocessing, "managers"):
2✔
142
            if isinstance(actual_objective, multiprocessing.managers.DictProxy):
2✔
143
                # Make a dictionary from a copy of the objective
144
                actual_objective_copy = dict(actual_objective.copy())
×
145
                for subproblem in actual_objective.keys():
×
146
                    # If we have stages, make a dictionary form a copy of the
147
                    # stage dictionary for each subproblem
148
                    if isinstance(
×
149
                        actual_objective[subproblem], multiprocessing.managers.DictProxy
150
                    ):
151
                        stage_dict_copy = dict(actual_objective_copy[subproblem].copy())
×
152
                        # Reset the stage dictionary to the new simple
153
                        # dictionary object
154
                        actual_objective_copy[subproblem] = stage_dict_copy
×
155
                # Reset the objective to the new dictionary object
156
                actual_objective = actual_objective_copy
×
157

158
        # Uncomment this to save new objective function values
159
        df = pd.read_csv(TEST_SCENARIOS_CSV, delimiter=",")
2✔
160
        df.set_index("test_scenario", inplace=True)
2✔
161
        # Set dtype to 'object' so that we can have floats and dictionaries
162
        # in the column
163
        df["actual_objective"] = df["actual_objective"].astype("object")
2✔
164
        df.at[test, "actual_objective"] = actual_objective
2✔
165
        df.to_csv(TEST_SCENARIOS_CSV, index=True)
2✔
166

167
        # Multi-subproblem and/or multi-stage scenarios return dict
168
        if isinstance(expected_objective, dict):
2✔
169
            self.assertDictAlmostEqual(expected_objective, actual_objective, places=1)
2✔
170
        # Otherwise, objective is a single value
171
        else:
172
            self.assertAlmostEqual(expected_objective, actual_objective, places=1)
×
173

174
    @classmethod
2✔
175
    def setUpClass(cls):
2✔
176
        """
177
        Set up the testing database
178
        :return:
179
        """
180

181
        if os.path.exists(DB_PATH):
2✔
182
            os.remove(DB_PATH)
×
183

184
        create_database.main(
2✔
185
            [
186
                "--database",
187
                DB_PATH,
188
                "--db_schema",
189
                DB_SCHEMA,
190
                "--data_directory",
191
                DATA_DIRECTORY,
192
            ]
193
        )
194

195
        try:
2✔
196
            port_csvs_to_db.main(
2✔
197
                ["--database", DB_PATH, "--csv_location", CSV_PATH, "--quiet"]
198
            )
199
        except Exception as e:
×
200
            print(
×
201
                "Error encountered during population of testing database "
202
                "{}.db. Deleting database ...".format(DB_NAME)
203
            )
204
            logging.exception(e)
×
205
            os.remove(DB_PATH)
×
206

207
        try:
2✔
208
            scenario.main(
2✔
209
                ["--database", DB_PATH, "--csv_path", SCENARIOS_CSV, "--quiet"]
210
            )
211
        except Exception as e:
×
212
            print(
×
213
                "Error encountered during population of testing database "
214
                "{}.db. Deleting database ...".format(DB_NAME)
215
            )
216
            logging.exception(e)
×
217
            os.remove(DB_PATH)
×
218

219
    def validate_and_test_example_generic(
2✔
220
        self, scenario_name, solver=None, skip_validation=False
221
    ):
222
        # Use the expected objective column by default
223
        column_to_use = "expected_objective"
2✔
224
        if MACOS and not pd.isnull(
2✔
225
            self.df.loc[scenario_name]["expected_objective_darwin"]
226
        ):
227
            column_to_use = "expected_objective_darwin"
×
228
        if WINDOWS and not pd.isnull(
2✔
229
            self.df.loc[scenario_name]["expected_objective_windows"]
230
        ):
231
            column_to_use = "expected_objective_windows"
×
232

233
        # Evaluate the objective function as a literal (as it is in
234
        # dictionary format stored as string in the CSV)
235
        # This is now done for all scenarios, even if they have no iterations
236
        # or multiple subproblem/stages
237
        objective = ast.literal_eval(self.df.loc[scenario_name][column_to_use])
2✔
238
        if not skip_validation:
2✔
239
            self.check_validation(scenario_name)
2✔
240
        self.run_and_check_objective(
2✔
241
            test=scenario_name, solver=solver, expected_objective=objective
242
        )
243

244
    def test_example_test(self):
2✔
245
        """
246
        Check validation and objective function value of "test" example
247
        :return:
248
        """
249
        scenario_name = "test"
2✔
250
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
251

252
    def test_example_test_no_overgen_allowed(self):
2✔
253
        """
254
        Check validation and objective function value of
255
        "test_no_overgen_allowed" example
256
        :return:
257
        """
258

259
        scenario_name = "test_no_overgen_allowed"
2✔
260
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
261

262
    def test_example_test_new_build_storage(self):
2✔
263
        """
264
        Check validation and objective function value of
265
        "test_new_build_storage" example
266
        :return:
267
        """
268

269
        scenario_name = "test_new_build_storage"
2✔
270
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
271

272
    def test_example_test_new_binary_build_storage(self):
2✔
273
        """
274
        Check validation and objective function value of
275
        "test_new_binary_build_storage" example
276
        :return:
277
        """
278
        scenario_name = "test_new_binary_build_storage"
2✔
279
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
280

281
    def test_example_test_new_build_storage_cumulative_min_max(self):
2✔
282
        """
283
        Check validation and objective function value of
284
        "test_new_build_storage_cumulative_min_max" example
285
        :return:
286
        """
287
        scenario_name = "test_new_build_storage_cumulative_min_max"
2✔
288
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
289

290
    def test_example_test_no_reserves(self):
2✔
291
        """
292
        Check validation and objective function value of
293
        "test_no_reserves" example
294
        :return:
295
        """
296
        scenario_name = "test_no_reserves"
2✔
297
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
298

299
    def test_example_test_w_hydro(self):
2✔
300
        """
301
        Check validation and objective function value of "test_w_hydro" example
302
        :return:
303
        """
304
        scenario_name = "test_w_hydro"
2✔
305
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
306

307
    def test_example_test_w_storage(self):
2✔
308
        """
309
        Check validation and objective function value of "test_w_storage" example
310
        :return:
311
        """
312
        scenario_name = "test_w_storage"
2✔
313
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
314

315
    def test_example_2horizons(self):
2✔
316
        """
317
        Check validation and objective function value of "2horizons" example
318
        :return:
319
        """
320
        scenario_name = "2horizons"
2✔
321
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
322

323
    def test_example_2horizons_w_hydro(self):
2✔
324
        """
325
        Check validation and objective function value of
326
        "2horizons_w_hydro" example
327
        :return:
328
        """
329
        scenario_name = "2horizons_w_hydro"
2✔
330
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
331

332
    def test_example_2horizons_w_hydro_and_nuclear_binary_availability(self):
2✔
333
        """
334
        Check validation and objective function value of
335
        "2horizons_w_hydro_and_nuclear_binary_availability" example
336

337
        NOTE: the objective function for this example is lower than that for
338
        the '2horizons_w_hydro' example because of the unrealistically high
339
        relative heat rate of the 'Nuclear' project relative to the gas
340
        projects; allowing binary availability for a must-run project
341
        actually allows lower-cost power when the nuclear plant is
342
        unavailable. We should probably re-think this example as part of a
343
        future more general revamp of the examples.
344

345
        :return:
346
        """
347
        scenario_name = "2horizons_w_hydro_and_nuclear_binary_availability"
2✔
348
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
349

350
    def test_example_2horizons_w_hydro_w_balancing_types(self):
2✔
351
        """
352
        Check validation and objective function value of
353
        "2horizons_w_hydro_w_balancing_types" example. The objective
354
        function of this example should be lower than that of the
355
        '2horizons_w_hydro' example, as the average hydro budget is the
356
        same across all timepoints, but the hydro balancing horizon is now
357
        longer.
358
        :return:
359
        """
360
        scenario_name = "2horizons_w_hydro_w_balancing_types"
2✔
361
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
362

363
    def test_example_2periods(self):
2✔
364
        """
365
        Check validation and objective function value of "2periods" example
366
        :return:
367
        """
368
        scenario_name = "2periods"
2✔
369
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
370

371
    def test_example_2periods_new_build(self):
2✔
372
        """
373
        Check validation and objective function value of "2periods_new_build" example
374
        """
375
        scenario_name = "2periods_new_build"
2✔
376
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
377

378
    def test_example_2periods_new_build_2zones(self):
2✔
379
        """
380
        Check validation and objective function value of
381
        "2periods_new_build_2zones" example
382
        :return:
383
        """
384
        scenario_name = "2periods_new_build_2zones"
2✔
385
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
386

387
    def test_example_2periods_new_build_2zones_new_build_transmission(self):
2✔
388
        """
389
        Check validation and objective function value of
390
        "2periods_new_build_2zones_new_build_transmission" example
391
        :return:
392
        """
393
        scenario_name = "2periods_new_build_2zones_new_build_transmission"
2✔
394
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
395

396
    def test_example_2periods_new_build_2zones_singleBA(self):
2✔
397
        """
398
        Check validation and objective function value of
399
        "2periods_new_build_2zones_singleBA"
400
        example
401
        :return:
402
        """
403
        scenario_name = "2periods_new_build_2zones_singleBA"
2✔
404
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
405

406
    def test_example_2periods_new_build_2zones_transmission(self):
2✔
407
        """
408
        Check validation and objective function value of
409
        "2periods_new_build_2zones_transmission" example
410
        :return:
411
        """
412
        scenario_name = "2periods_new_build_2zones_transmission"
2✔
413
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
414

415
    def test_example_2periods_new_build_2zones_transmission_w_losses(self):
2✔
416
        """
417
        Check validation and objective function value of
418
        "2periods_new_build_2zones_transmission_w_losses" example
419
        :return:
420
        """
421
        scenario_name = "2periods_new_build_2zones_transmission_w_losses"
2✔
422
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
423

424
    def test_example_2periods_new_build_2zones_transmission_w_losses_opp_dir(self):
2✔
425
        """
426
        Check validation and objective function value of
427
        "2periods_new_build_2zones_transmission_w_losses_opp_dir" example
428

429
        Note: this should be the same as the objective function for
430
        2periods_new_build_2zones_transmission_w_losses
431
        :return:
432
        """
433
        scenario_name = "2periods_new_build_2zones_transmission_w_losses_opp_dir"
2✔
434
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
435

436
    def test_example_2periods_new_build_rps(self):
2✔
437
        """
438
        Check validation and objective function value of
439
        "2periods_new_build_rps" example
440
        :return:
441
        """
442
        scenario_name = "2periods_new_build_rps"
2✔
443
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
444

445
    def test_example_2periods_new_build_rps_percent_target(self):
2✔
446
        """
447
        Check objective function value of
448
        "2periods_new_build_rps_percent_target" example
449
        This example should have the same objective function as
450
        test_example_2periods_new_build_rps, as its target is the same,
451
        but specified as percentage of load.
452
        :return:
453
        """
454
        scenario_name = "2periods_new_build_rps_percent_target"
2✔
455
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
456

457
    def test_example_2periods_new_build_cumulative_min_max(self):
2✔
458
        """
459
        Check validation and objective function value of
460
        "2periods_new_build_cumulative_min_max" example
461
        :return:
462
        """
463
        scenario_name = "2periods_new_build_cumulative_min_max"
2✔
464
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
465

466
    def test_example_single_stage_prod_cost(self):
2✔
467
        """
468
        Check validation and objective function values of
469
        "single_stage_prod_cost" example
470
        :return:
471
        """
472
        scenario_name = "single_stage_prod_cost"
2✔
473
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
474

475
    def test_example_single_stage_prod_cost_linked_subproblems(self):
2✔
476
        """
477
        Check objective function values of
478
        "single_stage_prod_cost_linked_subproblems" example
479
        :return:
480
        """
481
        scenario_name = "single_stage_prod_cost_linked_subproblems"
2✔
482
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
483

484
    def test_example_single_stage_prod_cost_linked_subproblems_w_hydro(self):
2✔
485
        """
486
        Check objective function values of
487
        "single_stage_prod_cost_linked_subproblems" example
488
        :return:
489
        """
490
        scenario_name = "single_stage_prod_cost_linked_subproblems_w_hydro"
2✔
491
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
492

493
    def test_example_multi_stage_prod_cost(self):
2✔
494
        """
495
        Check validation and objective function values of
496
        "multi_stage_prod_cost" example
497
        :return:
498
        """
499
        scenario_name = "multi_stage_prod_cost"
2✔
500
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
501

502
    def test_example_single_stage_prod_cost_cycle_select(self):
2✔
503
        """
504
        Check validation and objective function values of
505
        "single_stage_prod_cost_cycle_select" example. This example is the same as
506
        single_stage_prod_cost but the Coal and Gas_CCGT plants have mutually
507
        exclusive commitment in this example.
508
        """
509
        scenario_name = "single_stage_prod_cost_cycle_select"
2✔
510
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
511

512
    def test_example_multi_stage_prod_cost_parallel(self):
2✔
513
        """
514
        Check "multi_stage_prod_cost" example running subproblems in parallel
515
        (getting inputs and optimization)
516
        :return:
517
        """
518
        run_end_to_end.main(
2✔
519
            [
520
                "--database",
521
                DB_PATH,
522
                "--scenario",
523
                "multi_stage_prod_cost",
524
                "--scenario_location",
525
                EXAMPLES_DIRECTORY,
526
                # "--log",
527
                # "--write_solver_files_to_logs_dir",
528
                # "--keepfiles",
529
                # "--symbolic",
530
                "--n_parallel_get_inputs",
531
                "3",
532
                "--n_parallel_solve",
533
                "3",
534
                "--quiet",
535
                "--mute_solver_output",
536
                "--testing",
537
            ]
538
        )
539

540
    def test_example_multi_stage_prod_cost_w_hydro(self):
2✔
541
        """
542
        Check validation and objective function values of
543
        "multi_stage_prod_cost_w_hydro"
544
        example
545
        :return:
546
        """
547
        scenario_name = "multi_stage_prod_cost_w_hydro"
2✔
548
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
549

550
    def test_example_multi_stage_prod_cost_linked_subproblems(self):
2✔
551
        """
552
        Check validation and objective function values of
553
        "multi_stage_prod_cost_linked_subproblems" example
554
        :return:
555
        """
556
        scenario_name = "multi_stage_prod_cost_linked_subproblems"
2✔
557
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
558

559
    def test_example_2periods_gen_lin_econ_retirement(self):
2✔
560
        """
561
        Check validation and objective function value of
562
        "2periods_gen_lin_econ_retirement"
563
        example
564
        :return:
565
        """
566
        scenario_name = "2periods_gen_lin_econ_retirement"
2✔
567
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
568

569
    def test_example_2periods_gen_bin_econ_retirement(self):
2✔
570
        """
571
        Check validation and objective function value of
572
        "2periods_gen_bin_econ_retirement"
573
        example
574
        :return:
575
        """
576
        scenario_name = "2periods_gen_bin_econ_retirement"
2✔
577
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
578

579
    def test_example_variable_gen_reserves(self):
2✔
580
        """
581
        Check validation and objective function value of
582
        "variable_gen_reserves"
583
        example; this example requires a non-linear solver
584
        :return:
585
        """
586
        scenario_name = "test_variable_gen_reserves"
2✔
587
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
588

589
    def test_example_2periods_new_build_rps_variable_reserves(self):
2✔
590
        """
591
        Check validation and objective function value of
592
        "2periods_new_build_rps_variable_reserves" example
593
        :return:
594
        """
595
        scenario_name = "2periods_new_build_rps_variable_reserves"
2✔
596
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
597

598
    def test_example_2periods_new_build_rps_variable_reserves_subhourly_adj(self):
2✔
599
        """
600
        Check validation and objective function value of
601
        "2periods_new_build_rps_variable_reserves_subhourly_adj" example
602
        :return:
603
        """
604
        scenario_name = "2periods_new_build_rps_variable_reserves_subhourly_adj"
2✔
605
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
606

607
    def test_example_test_ramp_up_constraints(self):
2✔
608
        """
609
        Check validation and objective function value of
610
        "test_ramp_up_constraints" example
611
        :return:
612
        """
613
        scenario_name = "test_ramp_up_constraints"
2✔
614
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
615

616
    def test_example_test_ramp_up_and_down_constraints(self):
2✔
617
        """
618
        Check validation and objective function value of
619
        "test_ramp_up_and_down_constraints"
620
        example;
621
        :return:
622
        """
623
        scenario_name = "test_ramp_up_and_down_constraints"
2✔
624
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
625

626
    def test_example_2periods_new_build_rps_w_rps_ineligible_storage(self):
2✔
627
        """
628
        Check validation and objective function value of
629
        "2periods_new_build_rps_w_rps_ineligible_storage" example
630
        :return:
631
        """
632
        scenario_name = "2periods_new_build_rps_w_rps_ineligible_storage"
2✔
633
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
634

635
    def test_example_2periods_new_build_rps_w_rps_eligible_storage(self):
2✔
636
        """
637
        Check validation and objective function value of
638
        "2periods_new_build_rps_w_rps_eligible_storage" example
639
        :return:
640
        """
641
        scenario_name = "2periods_new_build_rps_w_rps_eligible_storage"
2✔
642
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
643

644
    def test_example_test_new_solar(self):
2✔
645
        """
646
        Check validation and objective function value of
647
        "test_new_solar" example
648
        :return:
649
        """
650
        scenario_name = "test_new_solar"
2✔
651
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
652

653
    def test_example_test_new_binary_solar(self):
2✔
654
        """
655
        Check validation and objective function value of
656
        "test_new_binary_solar" example
657
        :return:
658
        """
659
        scenario_name = "test_new_binary_solar"
2✔
660
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
661

662
    def test_example_test_new_solar_carbon_cap(self):
2✔
663
        """
664
        Check validation and objective function value of
665
        "test_new_solar_carbon_cap" example
666
        :return:
667
        """
668
        scenario_name = "test_new_solar_carbon_cap"
2✔
669
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
670

671
    def test_example_test_new_solar_carbon_cap_2zones_tx(self):
2✔
672
        """
673
        Check validation and objective function value of
674
        "test_new_solar_carbon_cap_2zones_tx" example
675
        :return:
676
        """
677
        scenario_name = "test_new_solar_carbon_cap_2zones_tx"
2✔
678
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
679

680
    def test_example_test_new_solar_carbon_cap_2zones_dont_count_tx(self):
2✔
681
        """
682
        Check validation and objective function value of
683
        "test_new_solar_carbon_cap_2zones_dont_count_tx" example
684
        :return:
685
        """
686
        scenario_name = "test_new_solar_carbon_cap_2zones_dont_count_tx"
2✔
687
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
688

689
    def test_example_test_new_solar_carbon_tax(self):
2✔
690
        """
691
        Check validation and objective function value of
692
        "test_new_solar_carbon_tax" example
693
        :return:
694
        """
695
        scenario_name = "test_new_solar_carbon_tax"
2✔
696
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
697

698
    def test_example_2periods_new_build_simple_prm(self):
2✔
699
        """
700
        Check validation and objective function value of
701
        "2periods_new_build_simple_prm"
702
        example
703
        :return:
704
        """
705
        scenario_name = "2periods_new_build_simple_prm"
2✔
706
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
707

708
    def test_example_2periods_new_build_simple_prm_w_energy_only(self):
2✔
709
        """
710
        Check validation and objective function value of
711
        "2periods_new_build_simple_prm"
712
        example
713
        :return:
714
        """
715
        scenario_name = "2periods_new_build_simple_prm_w_energy_only"
2✔
716
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
717

718
    def test_example_2periods_new_build_simple_prm_w_energy_only_deliv_cap_limit(self):
2✔
719
        """
720
        Check validation and objective function value of
721
        "2periods_new_build_simple_prm"
722
        example
723
        :return:
724
        """
725
        scenario_name = "2periods_new_build_simple_prm_w_energy_only_deliv_cap_limit"
2✔
726
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
727

728
    def test_example_2periods_new_build_local_capacity(self):
2✔
729
        """
730
        Check validation and objective function value of
731
        "2periods_new_build_local_capacity"
732
        example
733
        :return:
734
        """
735
        scenario_name = "2periods_new_build_local_capacity"
2✔
736
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
737

738
    def test_example_test_tx_dcopf(self):
2✔
739
        """
740
        Check validation and objective function value of
741
        "test_tx_dcopf" example
742
        :return:
743
        """
744
        scenario_name = "test_tx_dcopf"
2✔
745
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
746

747
    def test_example_test_tx_simple(self):
2✔
748
        """
749
        Check validation and objective function value of
750
        "test_tx_simple" example
751
        :return:
752
        """
753
        scenario_name = "test_tx_simple"
2✔
754
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
755

756
    def test_example_test_tx_simple_tmp_emissions(self):
2✔
757
        """
758
        Check validation and objective function value of
759
        "test_tx_simple_tmp_emissions" example
760
        :return:
761
        """
762
        scenario_name = "test_tx_simple_tmp_emissions"
2✔
763
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
764

765
    def test_example_test_tx_simple_additive(self):
2✔
766
        """
767
        Check validation and objective function value of
768
        "test_tx_simple_additive" example
769
        :return:
770
        """
771
        scenario_name = "test_tx_simple_additive"
2✔
772
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
773

774
    def test_example_test_startup_shutdown_rates(self):
2✔
775
        """
776
        Check validation and objective function value of
777
        "test_startup_shutdown_rates"
778
        example
779
        :return:
780
        """
781
        scenario_name = "test_startup_shutdown_rates"
2✔
782
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
783

784
    def test_no_fuels(self):
2✔
785
        """
786
        Check validation and objective function value of "test_no_fuels"
787
        example
788
        :return:
789
        """
790
        scenario_name = "test_no_fuels"
2✔
791
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
792

793
    def test_variable_om_curves(self):
2✔
794
        """
795
        Check validation and objective function value of
796
        "test_variable_om_curves"
797
        example
798
        :return:
799
        """
800
        scenario_name = "test_variable_om_curves"
2✔
801
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
802

803
    def test_aux_cons(self):
2✔
804
        """
805
        Check validation and objective function value of
806
        "test_aux_cons" example
807

808
        Note: the objective function value is lower than that for the "test"
809
        example because the auxiliary consumption results in less
810
        overgeneration and therefore lower overgeneration penalty.
811
        """
812
        scenario_name = "test_aux_cons"
2✔
813
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
814

815
    def test_example_test_w_lf_down_percent_req(self):
2✔
816
        """
817
        Check validation and objective function value of
818
        "test_w_lf_down_percent_req" example
819
        :return:
820
        """
821
        scenario_name = "test_w_lf_down_percent_req"
2✔
822
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
823

824
    def test_example_2periods_new_build_capgroups(self):
2✔
825
        """
826
        Check validation and objective function value of
827
        "test_example_2periods_new_build_capgroups" example
828
        """
829
        scenario_name = "2periods_new_build_capgroups"
2✔
830
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
831

832
    def test_example_test_markets(self):
2✔
833
        """
834
        Check validation and objective function value of "test" example
835
        :return:
836
        """
837
        scenario_name = "test_markets"
2✔
838
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
839

840
    def test_example_2periods_new_build_horizon_energy_target(self):
2✔
841
        """
842
        Check validation and objective function value of
843
        "test_example_2periods_new_build_horizon_energy_target" example
844
        :return:
845
        """
846
        scenario_name = "2periods_new_build_horizon_energy_target"
2✔
847
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
848

849
    def test_example_2periods_new_build_horizon_energy_target_halfyear(self):
2✔
850
        """
851
        Check validation and objective function value of
852
        "2periods_new_build_horizon_energy_target_halfyear" example
853
        :return:
854
        """
855
        scenario_name = "2periods_new_build_horizon_energy_target_halfyear"
2✔
856
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
857

858
    def test_example_test_new_build_gen_var_stor_hyb(self):
2✔
859
        """
860
        Check validation and objective function value of
861
        "test_new_build_gen_var_stor_hyb" example
862
        :return:
863
        """
864
        scenario_name = "test_new_build_gen_var_stor_hyb"
2✔
865
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
866

867
    def test_example_test_carbon_tax_allowance(self):
2✔
868
        """
869
        Check validation and objective function value of
870
        "test_carbon_tax_allowance" example
871
        :return:
872
        """
873
        scenario_name = "test_carbon_tax_allowance"
2✔
874
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
875

876
    def test_example_test_min_max_build_trans(self):
2✔
877
        """
878
        Check validation and objective function value of
879
        "test_min_max_build_trans" example
880
        :return:
881
        """
882
        scenario_name = "test_min_max_build_trans"
2✔
883
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
884

885
    def test_example_2periods_new_build_2zones_transmission_Tx1halfavail(self):
2✔
886
        """
887
        Check validation and objective function value of
888
        "2periods_new_build_2zones_transmission_Tx1halfavail" example
889
        :return:
890
        """
891
        scenario_name = "2periods_new_build_2zones_transmission_Tx1halfavail"
2✔
892
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
893

894
    def test_example_2periods_new_build_2zones_transmission_Tx1halfavailmonthly(self):
2✔
895
        """
896
        Check validation and objective function value of
897
        "2periods_new_build_2zones_transmission_Tx1halfavail" example
898
        :return:
899
        """
900
        scenario_name = "2periods_new_build_2zones_transmission_Tx1halfavailmonthly"
2✔
901
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
902

903
    def test_example_test_cheap_fuel_blend(self):
2✔
904
        """
905
        Check validation and objective function value of "test_cheap_fuel_blend" example
906
        :return:
907
        """
908
        scenario_name = "test_cheap_fuel_blend"
2✔
909
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
910

911
    def test_example_test_new_solar_carbon_cap_2zones_tx_low_carbon_fuel_blend(self):
2✔
912
        """
913
        Check validation and objective function value of
914
        "test_new_solar_carbon_cap_2zones_tx_low_carbon_fuel_blend" example
915
        :return:
916
        """
917
        scenario_name = "test_new_solar_carbon_cap_2zones_tx_low_carbon_fuel_blend"
2✔
918
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
919

920
    def test_example_test_cheap_fuel_blend_w_limit(self):
2✔
921
        """
922
        Check validation and objective function value of
923
        "test_cheap_fuel_blend_w_limit" example
924
        :return:
925
        """
926
        scenario_name = "test_cheap_fuel_blend_w_limit"
2✔
927
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
928

929
    def test_example_test_new_solar_fuel_burn_limit(self):
2✔
930
        """
931
        Check validation and objective function value of
932
        "test_new_solar_fuel_burn_limit" example. Inputs set up so that this should
933
        be the same as the "test_new_solar_carbon_cap" example.
934
        :return:
935
        """
936
        scenario_name = "test_new_solar_fuel_burn_limit"
2✔
937
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
938

939
    def test_example_test_new_solar_fuel_burn_limit_relative(self):
2✔
940
        """
941
        Check validation and objective function value of
942
        "test_new_solar_fuel_burn_limit_relative" example. Inputs set up so that this
943
        should be the same as the "test_new_solar_fuel_burn_limit" example.
944
        :return:
945
        """
946
        scenario_name = "test_new_solar_fuel_burn_limit_relative"
2✔
947
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
948

949
    def test_test_w_solver_options(self):
2✔
950
        """
951
        Check validation and objective function value of "test_w_solver_options" example
952
        :return:
953
        """
954
        scenario_name = "test_w_solver_options"
2✔
955
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
956

957
    def test_example_test_carbon_tax_allowance_with_different_fuel_groups(self):
2✔
958
        """
959
        Check validation and objective function value of
960
        "test_carbon_tax_allowance_with_different_fuel_groups" example
961
        :return:
962
        """
963
        scenario_name = "test_carbon_tax_allowance_with_different_fuel_groups"
2✔
964
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
965

966
    def test_performance_standard(self):
2✔
967
        """
968
        Check validation and objective function value of "test_performance_standard" example
969
        :return:
970
        """
971
        scenario_name = "test_performance_standard"
2✔
972
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
973

974
    def test_tx_flow(self):
2✔
975
        """
976
        Check validation and objective function value of
977
        "test_tx_flow" example
978
        :return:
979
        """
980
        scenario_name = "test_tx_flow"
2✔
981
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
982

983
    def test_example_test_new_solar_reserve_prj_contribution(self):
2✔
984
        """
985
        Check validation and objective function value of
986
        "test_reserve_prj_contribution" example.
987
        This example is based on "test_new_solar" with the only difference, the LF UP
988
        requirement ID
989
        :return:
990
        """
991
        scenario_name = "test_new_solar_reserve_prj_contribution"
2✔
992
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
993

994
    def test_test_new_solar_carbon_cap_2zones_tx_hydrogen_prod(self):
2✔
995
        """
996
        Check validation and objective function value of
997
        "test_reserve_prj_contribution" example.
998
        This example is based on "test_new_solar" with the only difference, the LF UP
999
        requirement ID
1000
        :return:
1001
        """
1002
        scenario_name = "test_new_solar_carbon_cap_2zones_tx_hydrogen_prod"
2✔
1003
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1004

1005
    def test_test_new_solar_carbon_cap_2zones_tx_hydrogen_prod_new(self):
2✔
1006
        """
1007
        Check validation and objective function value of
1008
        "test_reserve_prj_contribution" example.
1009
        This example is based on "test_new_solar" with the only difference, the LF UP
1010
        requirement ID
1011
        :return:
1012
        """
1013
        scenario_name = "test_new_solar_carbon_cap_2zones_tx_hydrogen_prod_new"
2✔
1014
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1015

1016
    def test_example_test_new_solar_carbon_cap_dac(self):
2✔
1017
        """
1018
        Check validation and objective function value of
1019
        "test_new_solar_carbon_cap_dac" example.
1020

1021
        Note that the same version of Cbc (v2.10.5) produces a slightly different
1022
        objective function for this problem on Windows than on Mac.
1023
        :return:
1024
        """
1025
        scenario_name = "test_new_solar_carbon_cap_dac"
2✔
1026
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1027

1028
    def test_example_test_cap_factor_limits(self):
2✔
1029
        """
1030
        Check validation and objective function value of "test" example
1031
        :return:
1032
        """
1033
        scenario_name = "test_cap_factor_limits"
2✔
1034
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1035

1036
    def test_example_multi_stage_prod_cost_w_markets(self):
2✔
1037
        """
1038
        Check validation and objective function values of
1039
        "multi_stage_prod_cost_w_markets" example
1040
        :return:
1041
        """
1042
        scenario_name = "multi_stage_prod_cost_w_markets"
2✔
1043
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1044

1045
    def test_example_test_supplemental_firing(self):
2✔
1046
        """
1047
        Check validation and objective function value of "test_supplemental_firing" example
1048
        :return:
1049
        """
1050
        scenario_name = "test_supplemental_firing"
2✔
1051
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1052

1053
    def test_example_test_tx_capacity_groups(self):
2✔
1054
        """
1055
        Check validation and objective function value of
1056
        "test_tx_capacity_groups" example
1057
        :return:
1058
        """
1059
        scenario_name = "test_tx_capacity_groups"
2✔
1060
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1061

1062
    def test_example_2periods_new_build_fin_lifetime(self):
2✔
1063
        """
1064
        Check validation and objective function value of
1065
        "2periods_new_build_fin_lifetime" example. Same as "2periods_new_build" but
1066
        with shorter financial lifetimes and some fixed costs. Cost is lower because
1067
        the same payment is made fewer times.
1068
        """
1069
        scenario_name = "2periods_new_build_fin_lifetime"
2✔
1070
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1071

1072
    def test_example_2periods_new_build_cumulative_and_vintage_min_max(self):
2✔
1073
        """
1074
        Check validation and objective function value of
1075
        "2periods_new_build_cumulative_and_vintage_min_max" example. It is the same
1076
        as 2periods_new_build_cumulative_and_min_max but with a max in 2020 for the
1077
        CCGT to force early build and a min on the CT in 2030 to force more build.
1078

1079
        :return:
1080
        """
1081
        scenario_name = "2periods_new_build_cumulative_and_vintage_min_max"
2✔
1082
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1083

1084
    def test_example_test_w_storage_w_soc_penalty(self):
2✔
1085
        """
1086
        Check validation and objective function value of "test_w_storage_w_soc_penalty"
1087
        example
1088
        :return:
1089
        """
1090
        scenario_name = "test_w_storage_w_soc_penalty"
2✔
1091
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1092

1093
    def test_example_test_w_storage_w_soc_last_tmp_penalty(self):
2✔
1094
        """
1095
        Check validation and objective function value of "test_w_storage_w_soc_penalty"
1096
        example
1097
        :return:
1098
        """
1099
        scenario_name = "test_w_storage_w_soc_last_tmp_penalty"
2✔
1100
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1101

1102
    def test_example_test_new_solar_itc(self):
2✔
1103
        """
1104
        Check validation and objective function value of
1105
        "test_new_solar_itc" example
1106
        :return:
1107
        """
1108
        scenario_name = "test_new_solar_itc"
2✔
1109
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1110

1111
    def test_example_test_new_build_storage_itc(self):
2✔
1112
        """
1113
        Check validation and objective function value of
1114
        "test_new_build_storage" example
1115
        :return:
1116
        """
1117
        scenario_name = "test_new_build_storage_itc"
2✔
1118
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1119

1120
    def test_example_2periods_new_build_simple_prm_2loadzones(self):
2✔
1121
        """
1122
        Check validation and objective function value of
1123
        "2periods_new_build_simple_prm_2loadzones"
1124
        example
1125
        :return:
1126
        """
1127
        scenario_name = "2periods_new_build_simple_prm_2loadzones"
2✔
1128
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1129

1130
    def test_example_2periods_new_build_simple_prm_2loadzones_newtx_w_transfers(self):
2✔
1131
        """
1132
        Check validation and objective function value of
1133
        "2periods_new_build_simple_prm_w_transfers"
1134
        example
1135
        :return:
1136
        """
1137
        scenario_name = "2periods_new_build_simple_prm_2loadzones_newtx_w_transfers"
2✔
1138
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1139

1140
    def test_example_2periods_new_build_simple_prm_2loadzones_newtx_w_transfers_w_costs(
2✔
1141
        self,
1142
    ):
1143
        """
1144
        Check validation and objective function value of
1145
        "2periods_new_build_simple_prm_2loadzones_newtx_w_transfers_w_costs"
1146
        example
1147
        :return:
1148
        """
1149
        scenario_name = (
2✔
1150
            "2periods_new_build_simple_prm_2loadzones_newtx_w_transfers_w_costs"
1151
        )
1152
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1153

1154
    def test_example_test_w_flex_load(self):
2✔
1155
        """
1156
        Check validation and objective function value of "test_w_storage" example
1157
        :return:
1158
        """
1159
        scenario_name = "test_w_flex_load"
2✔
1160
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1161

1162
    def test_example_test_new_solar_w_relative_capacity_instead_of_potential(self):
2✔
1163
        """
1164
        Check validation and objective function value of
1165
        "test_new_solar" example
1166
        :return:
1167
        """
1168
        scenario_name = "test_new_solar_w_relative_capacity_instead_of_potential"
2✔
1169
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1170

1171
    def test_example_2periods_new_build_2zones_transmission_w_hurdle_rates(self):
2✔
1172
        """
1173
        Check validation and objective function value of
1174
        "2periods_new_build_2zones_transmission_w_hurdle_rates" example
1175
        :return:
1176
        """
1177
        scenario_name = "2periods_new_build_2zones_transmission_w_hurdle_rates"
2✔
1178
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1179

1180
    def test_example_2periods_new_build_2zones_transmission_w_hurdle_rates_by_timepoint(
2✔
1181
        self,
1182
    ):
1183
        """
1184
        Check validation and objective function value of
1185
        "2periods_new_build_2zones_transmission_w_hurdle_rates_by_timepoint" example
1186
        :return:
1187
        """
1188
        scenario_name = (
2✔
1189
            "2periods_new_build_2zones_transmission_w_hurdle_rates_by_timepoint"
1190
        )
1191
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1192

1193
    def test_example_2periods_new_build_2zones_transmission_w_hurdle_rates_by_timepoint_and_period(
2✔
1194
        self,
1195
    ):
1196
        """
1197
        Check validation and objective function value of
1198
        "2periods_new_build_2zones_transmission_w_hurdle_rates_by_timepoint_and_period" example
1199
        :return:
1200
        """
1201
        scenario_name = "2periods_new_build_2zones_transmission_w_hurdle_rates_by_timepoint_and_period"
2✔
1202
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1203

1204
    def test_example_2periods_new_build_simple_prm_2loadzones_newtx_w_transfers_w_subsidies(
2✔
1205
        self,
1206
    ):
1207
        """
1208
        Check validation and objective function value of
1209
        "test_new_solar" example
1210
        :return:
1211
        """
1212
        scenario_name = (
2✔
1213
            "2periods_new_build_simple_prm_2loadzones_newtx_w_transfers_w_subsidies"
1214
        )
1215
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1216

1217
    def test_example_test_new_build_storage_itc_single_superperiod(self):
2✔
1218
        """
1219
        Check validation and objective function value of
1220
        "test_new_build_storage_itc_single_superperiodself" example
1221
        :return:
1222
        """
1223
        scenario_name = "test_new_build_storage_itc_single_superperiod"
2✔
1224
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1225

1226
    def test_incomplete_only(self):
2✔
1227
        """
1228
        Check that the "incomplete only" functionality works with no errors.
1229
        :return:
1230
        """
1231
        actual_objective = run_scenario.main(
2✔
1232
            [
1233
                "--scenario",
1234
                "test",
1235
                "--scenario_location",
1236
                EXAMPLES_DIRECTORY,
1237
                "--quiet",
1238
                "--mute_solver_output",
1239
                "--incomplete_only",
1240
            ]
1241
        )
1242

1243
    def test_example_test_w_storage_starting_soc(self):
2✔
1244
        """
1245
        Check validation and objective function value of
1246
        "test_w_storage_starting_soc" example
1247
        :return:
1248
        """
1249
        scenario_name = "test_w_storage_starting_soc"
2✔
1250
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1251

1252
    def test_example_test_w_nonfuel_emissions(self):
2✔
1253
        """
1254
        Check validation and objective function value of "test" example
1255
        :return:
1256
        """
1257
        scenario_name = "test_w_nonfuel_emissions"
2✔
1258
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1259

1260
    def test_example_test_new_solar_carbon_credits(self):
2✔
1261
        """
1262
        Check validation and objective function value of
1263
        "test_new_solar_carbon_credits" example
1264
        :return:
1265
        """
1266
        scenario_name = "test_new_solar_carbon_credits"
2✔
1267
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1268

1269
    def test_performance_standard_carbon_credits(self):
2✔
1270
        """
1271
        Check validation and objective function value of "test_performance_standard" example
1272
        :return:
1273
        """
1274
        scenario_name = "test_performance_standard_carbon_credits"
2✔
1275
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1276

1277
    def test_example_test_new_solar_carbon_tax_w_carbon_credits(self):
2✔
1278
        """
1279
        Check validation and objective function value of
1280
        "test_new_solar_carbon_tax_w_carbon_credits" example
1281
        :return:
1282
        """
1283
        scenario_name = "test_new_solar_carbon_tax_w_carbon_credits"
2✔
1284
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1285

1286
    def test_example_test_new_solar_carbon_credits_w_sell(self):
2✔
1287
        """
1288
        Check validation and objective function value of
1289
        "test_new_solar_carbon_credits_w_sell" example
1290
        The carbon credit price must be set higher than the cost of USE in this
1291
        example to incentivize the project to not run and generate credits.
1292
        :return:
1293
        """
1294
        scenario_name = "test_new_solar_carbon_credits_w_sell"
2✔
1295
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1296

1297
    def test_test_performance_standard_carbon_credits_w_cap_no_credits_mapping(self):
2✔
1298
        """
1299
        Check validation and objective function value of
1300
        "test_performance_standard_carbon_credits_w_cap_no_credits_mapping" example
1301
        :return:
1302
        """
1303
        scenario_name = (
2✔
1304
            "test_performance_standard_carbon_credits_w_cap_no_credits_mapping"
1305
        )
1306
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1307

1308
    def test_test_new_solar_carbon_credits_w_buy(self):
2✔
1309
        """
1310
        Check validation and objective function value of "test_new_solar_carbon_credits_w_buy" example
1311
        :return:
1312
        """
1313
        scenario_name = "test_new_solar_carbon_credits_w_buy"
2✔
1314
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1315

1316
    def test_test_new_solar_carbon_credits_w_buy_and_sell(self):
2✔
1317
        """
1318
        Check validation and objective function value of "test_new_solar_carbon_credits_w_buy_and_sell" example
1319
        :return:
1320
        """
1321
        scenario_name = "test_new_solar_carbon_credits_w_buy_and_sell"
2✔
1322
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1323

1324
    def test_example_single_stage_prod_cost_w_spinup_lookahead(self):
2✔
1325
        """
1326
        Check validation and objective function values of
1327
        "single_stage_prod_cost_w_spinup_lookahead" example
1328
        :return:
1329
        """
1330
        scenario_name = "single_stage_prod_cost_w_spinup_lookahead"
2✔
1331
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1332

1333
    def test_example_test_tx_targets_max(self):
2✔
1334
        """
1335
        Check validation and objective function value of
1336
        "test_example_test_tx_targets_max"
1337
        example
1338
        :return:
1339
        """
1340
        scenario_name = "test_tx_targets_max"
2✔
1341
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1342

1343
    def test_example_ra_toolkit_monte_carlo(self):
2✔
1344
        """
1345
        Check validation and objective function values of
1346
        "ra_toolkit_monte_carlo" example
1347
        :return:
1348
        """
1349
        scenario_name = "ra_toolkit_monte_carlo"
2✔
1350
        self.validate_and_test_example_generic(
2✔
1351
            scenario_name=scenario_name, skip_validation=True
1352
        )
1353

1354
    def test_example_ra_toolkit_sync(self):
2✔
1355
        """
1356
        Check validation and objective function values of
1357
        "ra_toolkit_sync" example
1358
        :return:
1359
        """
1360
        scenario_name = "ra_toolkit_sync"
2✔
1361
        self.validate_and_test_example_generic(
2✔
1362
            scenario_name=scenario_name, skip_validation=True
1363
        )
1364

1365
    def test_example_2periods_nuclear_var_cost_by_period_same(self):
2✔
1366
        """
1367
        Check validation and objective function value of "2periods_nuclear_var_cost_by_period_same" example
1368
        :return:
1369
        """
1370
        scenario_name = "2periods_nuclear_var_cost_by_period_same"
2✔
1371
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1372

1373
    def test_example_2periods_nuclear_var_cost_by_period_diff(self):
2✔
1374
        """
1375
        Check validation and objective function value of
1376
        "2periods_nuclear_var_cost_by_period_diff" example
1377
        :return:
1378
        """
1379
        scenario_name = "2periods_nuclear_var_cost_by_period_diff"
2✔
1380
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1381

1382
    def test_example_ra_toolkit_sync_single_year(self):
2✔
1383
        """
1384
        Check validation and objective function values of
1385
        "ra_toolkit_sync_single_year" example
1386
        :return:
1387
        """
1388
        scenario_name = "ra_toolkit_sync_single_year"
2✔
1389
        self.validate_and_test_example_generic(
2✔
1390
            scenario_name=scenario_name, skip_validation=True
1391
        )
1392

1393
    def test_test_performance_standard_power(self):
2✔
1394
        """
1395
        Check validation and objective function values of "test_performance_standard_power" example
1396
        :return:
1397
        """
1398
        scenario_name = "test_performance_standard_power"
2✔
1399
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1400

1401
    def test_test_performance_standard_both(self):
2✔
1402
        """
1403
        Check validation and objective function values of "test_performance_standard_both" example
1404
        :return:
1405
        """
1406
        scenario_name = "test_performance_standard_both"
2✔
1407
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1408

1409
    def test_test_new_instantaneous_penetration(self):
2✔
1410
        """
1411
        Check validation and objective function value of "test_new_instantaneous_penetration" example
1412
        :return:
1413
        """
1414

1415
        scenario_name = "test_new_instantaneous_penetration"
2✔
1416
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1417

1418
    def test_hydro_system_exog_elev(self):
2✔
1419
        """
1420
        Check validation and objective function value of "hydro_system" example
1421
        :return:
1422
        """
1423

1424
        scenario_name = "hydro_system_exog_elev"
2✔
1425
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1426

1427
    def test_hydro_system_exog_elev_w_travel_time(self):
2✔
1428
        """
1429
        Check validation and objective function value of "hydro_system" example
1430
        :return:
1431
        """
1432

1433
        scenario_name = "hydro_system_exog_elev_w_travel_time"
2✔
1434
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1435

1436
    def test_test_tx_flow_w_simflow(self):
2✔
1437
        """
1438
        Check validation and objective function value of "test_tx_flow_w_simflow" example
1439
        :return:
1440
        """
1441

1442
        scenario_name = "test_tx_flow_w_simflow"
2✔
1443
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1444

1445
    def test_example_ra_toolkit_sync_single_year_w_hydro_instead_of_weather_profile(
2✔
1446
        self,
1447
    ):
1448
        """
1449
        Check validation and objective function values of
1450
        "ra_toolkit_sync_single_year_w_hydro_instead_of_weather_profile" example
1451
        :return:
1452
        """
1453
        scenario_name = "ra_toolkit_sync_single_year_w_hydro_instead_of_weather_profile"
2✔
1454
        self.validate_and_test_example_generic(
2✔
1455
            scenario_name=scenario_name, skip_validation=True
1456
        )
1457

1458
    def test_example_2periods_new_build_2zones_loadcomponents(self):
2✔
1459
        """
1460
        Check validation and objective function value of
1461
        "2periods_new_build_2zones_loadcomponents" example
1462
        :return:
1463
        """
1464
        scenario_name = "2periods_new_build_2zones_loadcomponents"
2✔
1465
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1466

1467
    def test_example_2periods_nuclear_var_cost_by_timepoint_same(self):
2✔
1468
        """
1469
        Check validation and objective function value of
1470
        "2periods_nuclear_var_cost_by_timepoint_same" example
1471
        :return:
1472
        """
1473
        scenario_name = "2periods_nuclear_var_cost_by_timepoint_same"
2✔
1474
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1475

1476
    def test_example_2periods_nuclear_var_cost_by_timepoint_diff(self):
2✔
1477
        """
1478
        Check validation and objective function value of
1479
        "2periods_nuclear_var_cost_by_timepoint_diff" example
1480
        :return:
1481
        """
1482
        scenario_name = "2periods_nuclear_var_cost_by_timepoint_diff"
2✔
1483
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1484

1485
    def test_example_test_w_storage_wind_as_energy(self):
2✔
1486
        """
1487
        Check validation and objective function value of
1488
        "test_w_storage_wind_as_energy" example
1489
        :return:
1490
        """
1491
        scenario_name = "test_w_storage_wind_as_energy"
2✔
1492
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1493

1494
    def test_example_test_w_hydro_no_reserves(self):
2✔
1495
        """
1496
        Check validation and objective function value of
1497
        "test_w_hydro_no_reserves"
1498
        example
1499
        :return:
1500
        """
1501
        scenario_name = "test_w_hydro_no_reserves"
2✔
1502
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1503

1504
    def test_example_test_w_hydro_as_energy_no_reserves(self):
2✔
1505
        """
1506
        Check validation and objective function value of
1507
        "test_w_hydro_as_energy_no_reserves"
1508
        example
1509
        :return:
1510
        """
1511
        scenario_name = "test_w_hydro_as_energy_no_reserves"
2✔
1512
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1513

1514
    def test_example_test_w_lf(self):
2✔
1515
        """
1516
        Check validation and objective function value of
1517
        "test_w_lf" example
1518
        :return:
1519
        """
1520
        scenario_name = "test_w_lf"
2✔
1521
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1522

1523
    def test_example_test_w_lf_w_demand_charges(self):
2✔
1524
        """
1525
        Check validation and objective function value of
1526
        "test_w_lf_w_demand_charges" example
1527
        :return:
1528
        """
1529
        scenario_name = "test_w_lf_w_demand_charges"
2✔
1530
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1531

1532
    def test_example_test_w_lf_only(self):
2✔
1533
        """
1534
        Check validation and objective function value of
1535
        "test_w_lf_only" example
1536
        :return:
1537
        """
1538
        scenario_name = "test_w_lf_only"
2✔
1539
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1540

1541
    def test_example_test_w_lf_only_and_prices(self):
2✔
1542
        """
1543
        Check validation and objective function value of
1544
        "test_w_lf_only_and_prices" example
1545
        :return:
1546
        """
1547
        scenario_name = "test_w_lf_only_and_prices"
2✔
1548
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1549

1550
    def test_example_test_w_lf_only_energy_potential_limit(self):
2✔
1551
        """
1552
        Check validation and objective function value of
1553
        "test_w_lf_only_energy_potential_limit" example
1554
        :return:
1555
        """
1556
        scenario_name = "test_w_lf_only_energy_potential_limit"
2✔
1557
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1558

1559
    def test_example_test_w_hydro_as_slice_candidate(self):
2✔
1560
        """
1561
        Check validation and objective function value of
1562
        "test_w_hydro_as_slice_candidate"
1563
        example
1564
        :return:
1565
        """
1566
        scenario_name = "test_w_hydro_as_slice_candidate"
2✔
1567
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1568

1569
    def test_example_test_w_energy_products(self):
2✔
1570
        """
1571
        Check validation and objective function value of
1572
        "test_w_lf_only_and_prices" example
1573
        :return:
1574
        """
1575
        scenario_name = "test_w_energy_products"
2✔
1576
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1577

1578
    def test_example_test_w_energy_products_group_limits(self):
2✔
1579
        """
1580
        Check validation and objective function value of
1581
        "test_w_lf_only_and_prices" example
1582
        :return:
1583
        """
1584
        scenario_name = "test_w_energy_products_group_limits"
2✔
1585
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1586

1587
    def test_example_2periods_new_build_generic_policy(self):
2✔
1588
        """
1589
        Check validation and objective function value of
1590
        "2periods_new_build_generic_policy" example
1591
        :return:
1592
        """
1593
        scenario_name = "2periods_new_build_generic_policy"
2✔
1594
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1595

1596
    def test_open_data(self):
2✔
1597
        """
1598
        Check validation and objective function value of "open_data" example
1599
        :return:
1600
        """
1601

1602
        scenario_name = "open_data"
2✔
1603
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1604

1605
    def test_hydro_system_exog_elev_w_travel_time_and_max_halfday_flows(self):
2✔
1606
        """
1607
        :return:
1608
        """
1609

1610
        scenario_name = "hydro_system_exog_elev_w_travel_time_and_max_halfday_flows"
2✔
1611
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1612

1613
    def test_hydro_system_w_ramp_limits(self):
2✔
1614
        """
1615
        :return:
1616
        """
1617

1618
        scenario_name = "hydro_system_w_ramp_limits"
2✔
1619
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1620

1621
    def test_test_w_bt_hrz_avl(self):
2✔
1622
        """
1623
        :return:
1624
        """
1625

1626
        scenario_name = "test_w_bt_hrz_avl"
2✔
1627
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1628

1629
    def test_hydro_system_exog_elev_w_gen_ramp_limits(self):
2✔
1630
        """ """
1631
        scenario_name = "hydro_system_exog_elev_w_gen_ramp_limits"
2✔
1632
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1633

1634
    def test_dsm_examples(self):
2✔
1635
        scenario_name = "dsm_examples"
2✔
1636
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1637

1638
    def test_example_test_w_hydro_ramp_limits(self):
2✔
1639
        """
1640
        Check validation and objective function value of
1641
        "test_w_hydro_ramp_limits" example
1642
        :return:
1643
        """
1644
        scenario_name = "test_w_hydro_ramp_limits"
2✔
1645
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1646

1647
    def test_example_2periods_new_build_generic_policy_recs(self):
2✔
1648
        """
1649
        Check validation and objective function value of
1650
        "2periods_new_build_rps_recs" example
1651
        :return:
1652
        """
1653
        scenario_name = "2periods_new_build_generic_policy_recs"
2✔
1654
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1655

1656
    def test_example_test_markets_w_tmp_total_limits(self):
2✔
1657
        """
1658
        Check validation and objective function value of "test" example
1659
        :return:
1660
        """
1661
        scenario_name = "test_markets_w_tmp_total_limits"
2✔
1662
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1663

1664
    def test_example_test_markets_w_prd_total_limits(self):
2✔
1665
        """
1666
        Check validation and objective function value of "test" example
1667
        :return:
1668
        """
1669
        scenario_name = "test_markets_w_prd_total_limits"
2✔
1670
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1671

1672
    def test_example_test_new_build_storage_losses_limit(self):
2✔
1673
        """
1674
        Check validation and objective function value of
1675
        "test_new_build_storage_losses_limit" example
1676
        :return:
1677
        """
1678

1679
        scenario_name = "test_new_build_storage_losses_limit"
2✔
1680
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1681

1682
    def test_example_test_carbon_credits_purchase_limits(self):
2✔
1683
        """
1684
        Check validation and objective function value of
1685
        "test_carbon_credits_purchase_limits" example
1686
        :return:
1687
        """
1688

1689
        scenario_name = "test_carbon_credits_purchase_limits"
2✔
1690
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1691

1692
    def test_example_test_inertia_reserves(self):
2✔
1693
        """
1694
        Check validation and objective function value of
1695
        "test_new_build_storage_losses_limit" example
1696
        :return:
1697
        """
1698

1699
        scenario_name = "test_inertia_reserves"
2✔
1700
        self.validate_and_test_example_generic(scenario_name=scenario_name)
2✔
1701

1702
    @classmethod
2✔
1703
    def tearDownClass(cls):
2✔
1704
        os.remove(DB_PATH)
2✔
1705
        for temp_file_ext in ["-shm", "-wal"]:
2✔
1706
            temp_file = "{}{}".format(DB_PATH, temp_file_ext)
2✔
1707
            if os.path.exists(temp_file):
2✔
UNCOV
1708
                os.remove(temp_file)
1✔
1709

1710

1711
if __name__ == "__main__":
2✔
1712
    unittest.main()
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc