Skip to content

Latest commit

 

History

History
95 lines (70 loc) · 3.62 KB

Developing Modules.md

File metadata and controls

95 lines (70 loc) · 3.62 KB

Developing modules

Modules are the core elements of SWITCH. Each module defines a specific functionality for the model. For example, the switch_model.generators.core.build defines how generators are allowed to be built while switch_model.timescales defines how time is handled in SWITCH.

There are 3 important parts to any module.

  1. define_components(model): This function specifies the Pyomo Sets, Parameters, Variables and Expressions for the module as well as the input files that should be used. It's the first thing that gets called when you run switch solve as it creates the Pyomo model.

  2. post_solve(): This function gets run after the solver has found the optimal solution. This is where you can output results to e.g. a csv file.

  3. Functions with the @graph(...) decorator. These functions get called last and are responsible for creating graphs for analysis using the data from the csv files you created in post_solve().

There are also a few other components that you may encounter:

  • load_inputs(): This function is the old way of loading inputs from .csv files into the model. It gets called right after define_components(). Now the prefered way of loading inputs is by using input_file= (see next section for details).

  • define_dynamic_lists(model) and define_dynamic_components(model): Some modules need to define objects to be shared across multiple modules. The best example of this is switch_model.balancing.load_zones which allows different modules to add elements to a dynamic list that is defined in define_dynamic_lists. Then in define_dynamic_components it defines the energy balance constraint using the dynamic list. See the module for details.

Writing define_components()

define_components(mod) takes in the model as an argument and is responsible for adding constraints, expressions, variables, sets or parameters to the model.

Sometimes Sets or Parameters should be initialized from an input csv file. If this is the case, add input_file= (and optionally input_column) to the set or parameter definition.

For example the following code snippet defines a Set and a parameter indexed over that set. Both the set and parameter are initialized from the input.csv file.

from pyomo.environ import *


def define_components(mod):
    mod.SetA = Set(
        dimen=2,
        input_file="input.csv",
    )

    mod.some_indexed_param = Param(
        mod.SetA,
        input_file="input.csv",
        input_column="param1"  # only specify when the name of the column in the csv is not the same as the component name
    )

Writing post_solve()

Once the model is solved, the post_solve() function in each module is called. Within the post_solve() function you may

  • Call write_table() to create a .csv file with data from the solution (see existing modules for examples).

  • Call add_info() (from utilities/result_info.py) to add a line of information to the outputs/info.txt file. add_info() can also be added to graph().

Example

from switch_model.utilities.results_info import add_info
from switch_model.reporting import write_table
import os

...


def post_solve(instance, outdir):
    ...
    # This will add the a line to info.txt in the outputs folder
    add_info("Some important value", instance.important_value)
    ...
    # This will create my_table.csv
    write_table(
        instance,
        instance.TIMEPOINTS,  # Set that the values function will iterate over
        output_file=os.path.join(outdir, "my_table.csv"),
        headings=("timepoint", "some value"),
        values=lambda m, t: (t, m.some_value[t])
    )