Esempio n. 1
0
    def test_join_sets(self):
        """

        :return:
        """
        mod = AbstractModel()

        # If set list empty
        set_list_empty_actual = auxiliary_module_to_test.join_sets(mod, [])
        self.assertListEqual(set_list_empty_actual, [])

        # If single set in list
        mod.set1 = [1, 2, 3]
        set_list_single_set = ["set1"]
        single_set_expected = [1, 2, 3]
        single_set_actual = auxiliary_module_to_test.join_sets(mod, set_list_single_set)
        self.assertListEqual(single_set_expected, single_set_actual)

        # If more than one set
        mod.set2 = [4, 5, 6]
        set_list_two_sets = ["set1", "set2"]
        two_sets_joined_expected = [1, 2, 3, 4, 5, 6]
        two_sets_joined_actual = auxiliary_module_to_test.join_sets(
            mod, set_list_two_sets
        )
        self.assertListEqual(two_sets_joined_expected, two_sets_joined_actual)
Esempio n. 2
0
def add_model_components(m, d, scenario_directory, subproblem, stage):
    """

    :param m:
    :param d:
    :return:
    """

    m.PRM_COST_GROUPS = Set(
        initialize=lambda mod: join_sets(mod, getattr(d, prm_cost_group_sets)))

    def group_prm_type_init(mod, group):
        """
        Figure out the PRM type of each group
        :param mod:
        :param group:
        :return:
        """
        for group_set in getattr(d, prm_cost_group_sets):
            for element in getattr(mod, group_set):
                if element == group:
                    return getattr(d, prm_cost_group_prm_type)[group_set]

    m.group_prm_type = Param(
        m.PRM_COST_GROUPS,
        within=["energy_only_allowed"],
        initialize=lambda mod, g: group_prm_type_init(mod, g),
    )

    # Import all possible PRM modules
    project_df = pd.read_csv(
        os.path.join(scenario_directory, str(subproblem), str(stage), "inputs",
                     "projects.tab"),
        sep="\t",
        usecols=["project", "prm_type"],
    )
    required_prm_modules = [
        prm_type for prm_type in project_df.prm_type.unique()
        if prm_type != "."
    ]

    imported_prm_modules = load_prm_type_modules(required_prm_modules)

    # For each PRM project type, get the group costs
    def group_cost_rule(mod, group, p):
        prm_type = mod.group_prm_type[group]
        return imported_prm_modules[prm_type].group_cost_rule(mod, group, p)

    m.PRM_Group_Costs = Expression(m.PRM_COST_GROUPS,
                                   m.PERIODS,
                                   rule=group_cost_rule)
Esempio n. 3
0
def add_model_components(m, d, scenario_directory, subproblem, stage):
    """
    First, we iterate over all required *capacity_types* modules (this is the
    set of distinct project capacity types in the list of projects specified
    by the user) and add the components specific to the respective
    *capacity_type* module. We do this by calling the
    *add_model_components* method of the capacity_type module if
    the method exists.

    Then, the following Pyomo model components are defined in this module:

    +-------------------------------------------------------------------------+
    | Sets                                                                    |
    +=========================================================================+
    | | :code:`PRJ_OPR_PRDS`                                                  |
    | | *Within*: :code:`PROJECTS x PERIODS`                                  |
    |                                                                         |
    | Two-dimensional set that defines all project-period combinations when   |
    | a project can be operational (i.e. either has specified capacity or     |
    | can be build). This set is created by joining sets added by the         |
    | capacity_type modules (which is done before loading this module),       |
    | as how operational periods are determined differs by capacity type.     |
    +-------------------------------------------------------------------------+
    | | :code:`STOR_OPR_PRDS`                                                 |
    | | *Within*: :code:`PRJ_OPR_PRDS`                                        |
    |                                                                         |
    | Two-dimensional set that defines all project-period combinations when a |
    | when a storage projects can be operational, i.e. either has specified   |
    | capacity or can be built).                                              |
    +-------------------------------------------------------------------------+
    | | :code:`OPR_PRDS_BY_PRJ`                                               |
    | | *Defined over*: :code:`PROJECTS`                                      |
    |                                                                         |
    | Indexed set that describes the possible operational periods for each    |
    | project.                                                                |
    +-------------------------------------------------------------------------+
    | | :code:`PRJ_OPR_TMPS`                                                  |
    |                                                                         |
    | Two-dimensional set that defines all project-timepoint combinations     |
    | when a project can be operational.                                      |
    +-------------------------------------------------------------------------+
    | | :code:`OPR_PRJS_IN_TMP`                                               |
    | | *Defined over*: :code:`TMPS`                                          |
    |                                                                         |
    | Indexed set that describes all projects that could be operational in    |
    | each timepoint.                                                         |
    +-------------------------------------------------------------------------+

    |

    +-------------------------------------------------------------------------+
    | Expressions                                                             |
    +=========================================================================+
    | | :code:`Capacity_MW`                                                   |
    | | *Defined over*: :code:`PRJ_OPR_PRDS`                                  |
    |                                                                         |
    | Defines the project capacity in each period (in which the project can   |
    | exist) in the model. The exact formulation of the expression depends on |
    | the project's capacity_type. For each project, we call its              |
    | capacity_type module's capacity_rule method in order to formulate the   |
    | expression. E.g. a project of the gen_spec capacity_type will have a    |
    | have a pre-specified capacity whereas a project of the gen_new_lin      |
    | capacity_type will have a model variable (or sum of variables) as its   |
    | Capacity_MW.                                                            |
    +-------------------------------------------------------------------------+
    | | :code:`Energy_Capacity_MWh`                                           |
    | | *Defined over*: :code:`STOR_OPR_PRDS`                                 |
    |                                                                         |
    | Defines the storage project's energy capacity in each period (in which  |
    | the project can exist). The exact formulation of the expression depends |
    | on the project's capacity_type. For each project, we call its           |
    | capacity_type module's energy_capacity_rule method in order to          |
    | formulate the expression.                                               |
    +-------------------------------------------------------------------------+

    """

    # Dynamic Inputs
    ###########################################################################

    required_capacity_modules = get_required_subtype_modules_from_projects_file(
        scenario_directory=scenario_directory, subproblem=subproblem,
        stage=stage, which_type="capacity_type"
    )

    # Import needed capacity type modules
    imported_capacity_modules = load_gen_storage_capacity_type_modules(
        required_capacity_modules
    )

    # Add any components specific to the capacity type modules
    for op_m in required_capacity_modules:
        imp_op_m = imported_capacity_modules[op_m]
        if hasattr(imp_op_m, "add_model_components"):
            imp_op_m.add_model_components(
                m, d, scenario_directory, subproblem, stage
            )

    # Sets
    ###########################################################################

    m.PRJ_OPR_PRDS = Set(
        dimen=2,
        within=m.PROJECTS * m.PERIODS,
        initialize=lambda mod:
        join_sets(mod, getattr(d, capacity_type_operational_period_sets),),
    )  # assumes capacity types model components are already added!

    m.STOR_OPR_PRDS = Set(
        dimen=2,
        within=m.PRJ_OPR_PRDS,
        initialize=lambda mod:
        join_sets(mod, getattr(
            d, storage_only_capacity_type_operational_period_sets)),
    )  # assumes storage capacity type model components are already added!

    m.OPR_PRDS_BY_PRJ = Set(
        m.PROJECTS,
        initialize=lambda mod, project:
        operational_periods_by_project(
            prj=project,
            project_operational_periods=mod.PRJ_OPR_PRDS
        )
    )

    m.PRJ_OPR_TMPS = Set(
        dimen=2,
        initialize=lambda mod: [
            (g, tmp) for g in mod.PROJECTS
            for p in mod.OPR_PRDS_BY_PRJ[g]
            for tmp in mod.TMPS_IN_PRD[p]
        ]
    )

    m.OPR_PRJS_IN_TMP = Set(
        m.TMPS,
        initialize=op_gens_by_tmp
    )

    # Expressions
    ###########################################################################

    def capacity_rule(mod, g, p):
        gen_cap_type = mod.capacity_type[g]
        return imported_capacity_modules[gen_cap_type].capacity_rule(mod, g, p)

    m.Capacity_MW = Expression(
        m.PRJ_OPR_PRDS,
        rule=capacity_rule
    )

    def energy_capacity_rule(mod, g, p):
        cap_type = mod.capacity_type[g]
        if hasattr(imported_capacity_modules[cap_type], "energy_capacity_rule"):
            return imported_capacity_modules[cap_type]. \
                energy_capacity_rule(mod, g, p)
        else:
            raise Exception("Project " + str(g)
                            + " is of capacity type " + str(cap_type)
                            + ". This capacity type module does not have "
                            + "a function 'energy_capacity_rule,' "
                            + "but " + str(g)
                            + " is defined as storage project.")

    m.Energy_Capacity_MWh = Expression(
        m.STOR_OPR_PRDS,
        rule=energy_capacity_rule
    )
Esempio n. 4
0
def add_model_components(m, d, scenario_directory, subproblem, stage):
    """
    Before adding any components, this module will go through each relevant
    capacity type and add the module components for that capacity type.

    Then the following Pyomo model components are defined in this module:

    +-------------------------------------------------------------------------+
    | Sets                                                                    |
    +=========================================================================+
    | | :code:`TX_OPR_PRDS`                                                   |
    |                                                                         |
    | Two-dimensional set of the transmission lines and their operational     |
    | periods (capacity exists and is available).                             |
    +-------------------------------------------------------------------------+
    | | :code:`TX_LINES_OPR_IN_PRD`                                           |
    | | *Defined over*: :code:`PERIODS`                                       |
    |                                                                         |
    | Indexed set of transmission lines operational in each period.           |
    +-------------------------------------------------------------------------+
    | | :code:`OPR_PRDS_BY_TX_LINE`                                           |
    | | *Defined over*: :code:`TX_LINES`                                      |
    |                                                                         |
    | Indexed set of operational period for each transmission line.           |
    +-------------------------------------------------------------------------+
    | | :code:`TX_OPR_TMPS`                                                   |
    |                                                                         |
    | Two-dimensional set of the transmission lines and their operational     |
    | timepoints, derived from :code:`TX_OPR_PRDS` and the timepoitns in each |
    | period.                                                                 |
    +-------------------------------------------------------------------------+
    | | :code:`TX_LINES_OPR_IN_TMP`                                           |
    | | *Defined over*: :code:`TIMEPOINTS`                                    |
    |                                                                         |
    | Indexed set of transmission lines operatoinal in each timepoint.        |
    +-------------------------------------------------------------------------+

    |

    +-------------------------------------------------------------------------+
    | Expressions                                                             |
    +=========================================================================+
    | | :code:`Tx_Min_Capacity_MW`                                            |
    | | *Defined over*: :code:`TX_OPR_PRDS`                                   |
    |                                                                         |
    | The transmission line's minimum flow in MW (negative number indicates   |
    | flow in the opposite direction of the line's defined flow direction).   |
    | Depending on the capacity type, this can be a pre-specified amount or   |
    | a decision variable (with an associated cost).                          |
    +-------------------------------------------------------------------------+
    | | :code:`Tx_Max_Capacity_MW`                                            |
    | | *Defined over*: :code:`TX_OPR_PRDS`                                   |
    |                                                                         |
    | The transmission line's maximum flow in MW (negative number indicates   |
    | flow in the opposite direction of the line's defined flow direction).   |
    | Depending on the capacity type, this can be a pre-specified amount or   |
    | a decision variable (with an associated cost).                          |
    +-------------------------------------------------------------------------+
    | | :code:`Tx_Capacity_Cost_in_Prd`                                       |
    | | *Defined over*: :code:`TX_OPR_PRDS`                                   |
    |                                                                         |
    | The cost to have the transmission capacity available in the period.     |
    | Depending on the capacity type, this could be zero.                     |
    | If the subproblem is less than a full year (e.g. in production-         |
    | cost mode with 365 daily subproblems), the costs are scaled down        |
    | proportionally.                                                         |
    +-------------------------------------------------------------------------+
    | | :code:`Total_Tx_Capacity_Costs`                                       |
    |                                                                         |
    | The total cost of the system's transmission capacity across all periods.|
    +-------------------------------------------------------------------------+

    """

    # Dynamic Inputs
    ###########################################################################

    df = pd.read_csv(os.path.join(scenario_directory, str(subproblem),
                                  str(stage), "inputs",
                                  "transmission_lines.tab"),
                     sep="\t",
                     usecols=[
                         "TRANSMISSION_LINES", "tx_capacity_type",
                         "tx_operational_type"
                     ])

    # Required capacity modules are the unique set of tx capacity types
    # This list will be used to know which capacity modules to load
    required_tx_capacity_modules = df.tx_capacity_type.unique()

    # Import needed transmission capacity type modules for expression rules
    imported_tx_capacity_modules = load_tx_capacity_type_modules(
        required_tx_capacity_modules)

    # Add model components for each of the transmission capacity modules
    for op_m in required_tx_capacity_modules:
        imp_op_m = imported_tx_capacity_modules[op_m]
        if hasattr(imp_op_m, "add_model_components"):
            imp_op_m.add_model_components(m, d, scenario_directory, subproblem,
                                          stage)

    # Sets
    ###########################################################################

    m.TX_OPR_PRDS = Set(
        dimen=2,
        within=m.TX_LINES * m.PERIODS,
        initialize=lambda mod: join_sets(
            mod,
            getattr(d, tx_capacity_type_operational_period_sets),
        ),
    )  # assumes capacity types model components are already added!

    m.TX_LINES_OPR_IN_PRD = Set(m.PERIODS,
                                initialize=lambda mod, period: list(
                                    set(tx for (tx, p) in mod.TX_OPR_PRDS
                                        if p == period)))

    m.OPR_PRDS_BY_TX_LINE = Set(m.TX_LINES,
                                initialize=lambda mod, tx: list(
                                    set(p for (l, p) in mod.TX_OPR_PRDS
                                        if l == tx)))

    m.TX_OPR_TMPS = Set(
        dimen=2,
        initialize=lambda mod: [(tx, tmp) for tx in mod.TX_LINES
                                for p in mod.OPR_PRDS_BY_TX_LINE[tx]
                                for tmp in mod.TMPS_IN_PRD[p]])

    m.TX_LINES_OPR_IN_TMP = Set(m.TMPS,
                                initialize=lambda mod, tmp: list(
                                    set(tx for (tx, t) in mod.TX_OPR_TMPS
                                        if t == tmp)))

    # Expressions
    ###########################################################################

    def tx_min_capacity_rule(mod, tx, p):
        tx_cap_type = mod.tx_capacity_type[tx]
        return imported_tx_capacity_modules[tx_cap_type]. \
            min_transmission_capacity_rule(mod, tx, p)

    def tx_max_capacity_rule(mod, tx, p):
        tx_cap_type = mod.tx_capacity_type[tx]
        return imported_tx_capacity_modules[tx_cap_type]. \
            max_transmission_capacity_rule(mod, tx, p)

    def tx_capacity_cost_rule(mod, tx, p):
        tx_cap_type = mod.tx_capacity_type[tx]
        return imported_tx_capacity_modules[tx_cap_type].\
            tx_capacity_cost_rule(mod, tx, p) \
            * mod.hours_in_subproblem_period[p] \
            / mod.hours_in_full_period[p]

    m.Tx_Min_Capacity_MW = Expression(m.TX_OPR_PRDS, rule=tx_min_capacity_rule)

    m.Tx_Max_Capacity_MW = Expression(m.TX_OPR_PRDS, rule=tx_max_capacity_rule)

    m.Tx_Capacity_Cost_in_Prd = Expression(m.TX_OPR_PRDS,
                                           rule=tx_capacity_cost_rule)