예제 #1
0
def write_model_inputs(scenario_directory, scenario_id, subscenarios,
                       subproblem, stage, conn):
    """
    Get inputs from database and write out the model input .tab files
    :param scenario_directory: string, the scenario directory
    :param subscenarios: SubScenarios object with all subscenario info
    :param subproblem:
    :param stage:
    :param conn: database connection
    :return:
    """
    c = conn.cursor()
    # Load in the required capacity type modules

    required_capacity_type_modules = \
        get_required_capacity_types_from_database(conn, scenario_id)
    imported_capacity_type_modules = load_gen_storage_capacity_type_modules(
        required_capacity_type_modules)

    # Get module-specific inputs
    for op_m in required_capacity_type_modules:
        if hasattr(imported_capacity_type_modules[op_m],
                   "write_module_specific_model_inputs"):
            imported_capacity_type_modules[op_m].\
                write_module_specific_model_inputs(
                    scenario_directory, scenario_id, subscenarios, subproblem, stage, conn)
        else:
            pass
예제 #2
0
def validate_inputs(scenario_id, subscenarios, subproblem, stage, conn):
    """
    Get inputs from database and validate the inputs
    :param subscenarios: SubScenarios object with all subscenario info
    :param subproblem:
    :param stage:
    :param conn: database connection
    :return:
    """

    # Load in the required capacity type modules
    required_capacity_type_modules = \
        get_required_capacity_types_from_database(conn, scenario_id,)
    imported_capacity_type_modules = load_gen_storage_capacity_type_modules(
        required_capacity_type_modules)

    # Validate module-specific inputs
    for op_m in required_capacity_type_modules:
        if hasattr(imported_capacity_type_modules[op_m],
                   "validate_module_specific_inputs"):
            imported_capacity_type_modules[op_m]. \
                validate_module_specific_inputs(
                    scenario_id, subscenarios, subproblem, stage, conn)
        else:
            pass
예제 #3
0
파일: costs.py 프로젝트: yangqiu91/gridpath
def add_model_components(m, d, scenario_directory, subproblem, stage):
    """
    The following Pyomo model components are defined in this module:

    +-------------------------------------------------------------------------+
    | Expressions                                                             |
    +=========================================================================+
    | | :code:`Capacity_Cost_in_Period`                                       |
    | | *Defined Over*: :code:`PRJ_OPR_PRDS`                                  |
    |                                                                         |
    | This expression describe each project's capacity-related costs for each |
    | operational period, based on its capacity_type. For the purpose, call   |
    | the *capacity_cost_rule* method from the respective capacity-type       |
    | module. 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.                                                         |
    +-------------------------------------------------------------------------+

    """

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

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

    imported_capacity_modules = load_gen_storage_capacity_type_modules(
        required_capacity_modules
    )

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

    def capacity_cost_rule(mod, g, p):
        """
        Get capacity cost for each generator's respective capacity module.

        Note that capacity cost inputs and calculations in the modules are on
        an annual basis. Therefore, if the subproblem is less than a year we
        adjust the costs down.
        """
        return imported_capacity_modules[mod.capacity_type[g]].\
            capacity_cost_rule(mod, g, p) \
            * mod.hours_in_subproblem_period[p] \
            / mod.hours_in_full_period[p]

    # TODO: right now hours in spinup and lookahead tmps are not included in
    #  the "hours_in_subproblem". If that is not okay (not sure why), we could
    #  move the adjustment to a post-processing step (same for tx cap costs)

    m.Capacity_Cost_in_Period = Expression(
        m.PRJ_OPR_PRDS,
        rule=capacity_cost_rule
    )
예제 #4
0
def export_results(scenario_directory, subproblem, stage, m, d):
    """
    Export capacity results.
    :param scenario_directory:
    :param subproblem:
    :param stage:
    :param m:
    :param d:
    :return:
    """

    # Total capacity for all projects
    with open(os.path.join(scenario_directory, str(subproblem), str(stage), "results",
                           "capacity_all.csv"), "w", newline="") as f:
        writer = csv.writer(f)
        writer.writerow(["project", "period",
                         "capacity_type", "technology", "load_zone",
                         "capacity_mw", "capacity_mwh"])
        for (prj, p) in m.PRJ_OPR_PRDS:
            writer.writerow([
                prj,
                p,
                m.capacity_type[prj],
                m.technology[prj],
                m.load_zone[prj],
                value(m.Capacity_MW[prj, p]),
                value(m.Energy_Capacity_MWh[prj, p])
                if (prj, p) in m.STOR_OPR_PRDS else None
            ])

    # Module-specific capacity results
    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
    )
    for op_m in required_capacity_modules:
        if hasattr(imported_capacity_modules[op_m],
                   "export_module_specific_results"):
            imported_capacity_modules[
                op_m].export_module_specific_results(
                scenario_directory, subproblem, stage, m, d
            )
        else:
            pass
예제 #5
0
def summarize_results(scenario_directory, subproblem, stage):
    """
    :param scenario_directory:
    :param subproblem:
    :param stage:
    :return:

    Summarize capacity results
    """

    summary_results_file = os.path.join(
        scenario_directory, subproblem, stage, "results", "summary_results.txt"
    )
    # Check if the 'technology' exists in  projects.tab; if it doesn't, we
    # don't have a category to aggregate by, so we'll skip summarizing results

    # Open in 'append' mode, so that results already written by other
    # modules are not overridden
    with open(summary_results_file, "a") as outfile:
        outfile.write(
            "\n### CAPACITY RESULTS ###\n"
        )

    # Get the results CSV as dataframe
    capacity_results_df = pd.read_csv(
        os.path.join(scenario_directory, str(subproblem), str(stage), "results",
                     "capacity_all.csv")
    )

    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
    )
    for op_m in required_capacity_modules:
        if hasattr(imported_capacity_modules[op_m],
                   "summarize_module_specific_results"):
            imported_capacity_modules[
                op_m].summarize_module_specific_results(
                scenario_directory, subproblem, stage, summary_results_file
            )
        else:
            pass
예제 #6
0
def load_model_data(m, d, data_portal, scenario_directory, subproblem, stage):
    """
    """
    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
    )
    for op_m in required_capacity_modules:
        if hasattr(imported_capacity_modules[op_m],
                   "load_module_specific_data"):
            imported_capacity_modules[op_m].load_module_specific_data(
                m, data_portal, scenario_directory, subproblem, stage)
        else:
            pass
예제 #7
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
    )
예제 #8
0
def import_results_into_database(scenario_id, subproblem, stage, c, db,
                                 results_directory, quiet):
    """

    :param scenario_id:
    :param c:
    :param db:
    :param results_directory:
    :param quiet:
    :return:
    """
    # First import the capacity_all results; the capacity type modules will
    # then update the database tables rather than insert (all projects
    # should have been inserted here)
    # Delete prior results and create temporary import table for ordering
    # Capacity results
    if not quiet:
        print("project capacity")

    # Delete prior results and create temporary import table for ordering
    setup_results_import(conn=db,
                         cursor=c,
                         table="results_project_capacity",
                         scenario_id=scenario_id,
                         subproblem=subproblem,
                         stage=stage)

    # Load results into the temporary table
    results = []
    with open(os.path.join(results_directory, "capacity_all.csv"), "r") as \
            capacity_file:
        reader = csv.reader(capacity_file)

        next(reader)  # skip header
        for row in reader:
            project = row[0]
            period = row[1]
            capacity_type = row[2]
            technology = row[3]
            load_zone = row[4]
            capacity_mw = row[5]
            energy_capacity_mwh = None if row[6] == "" else row[6]

            results.append((scenario_id, project, period, subproblem, stage,
                            capacity_type, technology, load_zone, capacity_mw,
                            energy_capacity_mwh))

    insert_temp_sql = """
        INSERT INTO temp_results_project_capacity{}
        (scenario_id, project, period, subproblem_id, stage_id, capacity_type,
        technology, load_zone, capacity_mw, energy_capacity_mwh)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
        """.format(scenario_id)
    spin_on_database_lock(conn=db, cursor=c, sql=insert_temp_sql, data=results)

    # Insert sorted results into permanent results table
    insert_sql = """
        INSERT INTO results_project_capacity
        (scenario_id, project, period, subproblem_id, stage_id, capacity_type,
        technology, load_zone, capacity_mw, energy_capacity_mwh)
        SELECT
        scenario_id, project, period, subproblem_id, stage_id, capacity_type,
        technology, load_zone, capacity_mw, energy_capacity_mwh
        FROM temp_results_project_capacity{}
        ORDER BY scenario_id, project, period, subproblem_id, 
        stage_id;""".format(scenario_id)
    spin_on_database_lock(conn=db,
                          cursor=c,
                          sql=insert_sql,
                          data=(),
                          many=False)

    # Load in the required capacity type modules
    required_capacity_type_modules = \
        get_required_capacity_types_from_database(db, scenario_id)
    imported_capacity_type_modules = load_gen_storage_capacity_type_modules(
        required_capacity_type_modules)

    # Import module-specific results
    for op_m in required_capacity_type_modules:
        if hasattr(imported_capacity_type_modules[op_m],
                   "import_module_specific_results_into_database"):
            imported_capacity_type_modules[op_m]. \
                import_module_specific_results_into_database(
                scenario_id, subproblem, stage, c, db, results_directory, quiet
            )
        else:
            pass
예제 #9
0
def add_model_components(m, d, scenario_directory, subproblem, stage):
    """
    The following Pyomo model components are defined in this module:

    +-------------------------------------------------------------------------+
    | Sets                                                                    |
    +=========================================================================+
    | | :code:`CAPACITY_GROUP_PERIODS`                                        |
    |                                                                         |
    | A two-dimensional set of group-period combinations for which there may  |
    | be group capacity requirements.                                         |
    +-------------------------------------------------------------------------+
    | | :code:`CAPACITY_GROUPS`                                               |
    |                                                                         |
    | The groups of projects for which there may be group capacity            |
    | requirements.                                                           |
    +-------------------------------------------------------------------------+
    | | :code:`PROJECTS_IN_CAPACITY_GROUP`                                    |
    |                                                                         |
    | The list of projects by capacity group.                                 |
    +-------------------------------------------------------------------------+

    +-------------------------------------------------------------------------+
    | Optional Input Params                                                   |
    +=========================================================================+
    | | :code:`capacity_group_new_capacity_min`                               |
    | | *Defined over*: :code:`CAPACITY_GROUP_PERIODS`                        |
    | | *Within*: :code:`NonNegativeReals`                                    |
    | | *Default*: :code:`0`                                                  |
    |                                                                         |
    | The minimum amount of capacity (in MW) that must be built at projects   |
    | in this group in a given period.                                        |
    +-------------------------------------------------------------------------+
    | | :code:`capacity_group_new_capacity_max`                               |
    | | *Defined over*: :code:`CAPACITY_GROUP_PERIODS`                        |
    | | *Within*: :code:`NonNegativeReals`                                    |
    | | *Default*: :code:`inf`                                                |
    |                                                                         |
    | The maximum amount of capacity (in MW) that may be built at projects    |
    | in this group in a given period.                                        |
    +-------------------------------------------------------------------------+
    | | :code:`capacity_group_total_capacity_min`                             |
    | | *Defined over*: :code:`CAPACITY_GROUP_PERIODS`                        |
    | | *Within*: :code:`NonNegativeReals`                                    |
    | | *Default*: :code:`0`                                                  |
    |                                                                         |
    | The minimum amount of capacity (in MW) that must exist at projects      |
    | in this group in a given period.                                        |
    +-------------------------------------------------------------------------+
    | | :code:`capacity_group_total_capacity_max`                             |
    | | *Defined over*: :code:`CAPACITY_GROUP_PERIODS`                        |
    | | *Within*: :code:`NonNegativeReals`                                    |
    | | *Default*: :code:`inf`                                                |
    |                                                                         |
    | The maximum amount of capacity (in MW) that may exist at projects       |
    | in this group in a given period.                                        |
    +-------------------------------------------------------------------------+

    |

    +-------------------------------------------------------------------------+
    | Expressions                                                             |
    +=========================================================================+
    | | :code:`Group_New_Capacity_in_Period`                                  |
    | | *Defined over*: :code:`CAPACITY_GROUP_PERIODS`                        |
    |                                                                         |
    | The new capacity built at projects in this group in this period.        |
    +-------------------------------------------------------------------------+
    | | :code:`Group_Total_Capacity_in_Period`                                |
    | | *Defined over*: :code:`CAPACITY_GROUP_PERIODS`                        |
    |                                                                         |
    | The new capacity of at projects in this group in this period.           |
    +-------------------------------------------------------------------------+

    |

    +-------------------------------------------------------------------------+
    | Constraints                                                             |
    +=========================================================================+
    | | :code:`Max_Group_Build_in_Period_Constraint`                          |
    | | *Defined over*: :code:`CAPACITY_GROUP_PERIODS`                        |
    |                                                                         |
    | Limits the amount of new build in each group in each period.            |
    +-------------------------------------------------------------------------+
    | | :code:`Min_Group_Build_in_Period_Constraint`                          |
    | | *Defined over*: :code:`CAPACITY_GROUP_PERIODS`                        |
    |                                                                         |
    | Requires a certain amount of new build in each group in each period.    |
    +-------------------------------------------------------------------------+
    | | :code:`Max_Group_Total_Cap_in_Period_Constraint`                      |
    | | *Defined over*: :code:`CAPACITY_GROUP_PERIODS`                        |
    |                                                                         |
    | Limits the total amount of capacity in each group in each period        |
    +-------------------------------------------------------------------------+
    | | :code:`Min_Group_Build_in_Period_Constraint`                          |
    | | *Defined over*: :code:`CAPACITY_GROUP_PERIODS`                        |
    |                                                                         |
    | Requires a certain amount of capacity in each group in each period.     |
    +-------------------------------------------------------------------------+

    """

    # Sets
    m.CAPACITY_GROUP_PERIODS = Set(dimen=2)

    m.CAPACITY_GROUPS = Set(initialize=lambda mod: list(
        set([g for (g, p) in mod.CAPACITY_GROUP_PERIODS])))

    m.PROJECTS_IN_CAPACITY_GROUP = Set(m.CAPACITY_GROUPS, within=m.PROJECTS)

    # Params
    m.capacity_group_new_capacity_min = Param(m.CAPACITY_GROUP_PERIODS,
                                              within=NonNegativeReals,
                                              default=0)
    m.capacity_group_new_capacity_max = Param(m.CAPACITY_GROUP_PERIODS,
                                              within=NonNegativeReals,
                                              default=float('inf'))
    m.capacity_group_total_capacity_min = Param(m.CAPACITY_GROUP_PERIODS,
                                                within=NonNegativeReals,
                                                default=0)
    m.capacity_group_total_capacity_max = Param(m.CAPACITY_GROUP_PERIODS,
                                                within=NonNegativeReals,
                                                default=float('inf'))

    # Import needed capacity type modules
    required_capacity_modules = get_required_subtype_modules_from_projects_file(
        scenario_directory=scenario_directory,
        subproblem=subproblem,
        stage=stage,
        which_type="capacity_type")

    imported_capacity_modules = load_gen_storage_capacity_type_modules(
        required_capacity_modules)

    # Get the new and total capacity in the group for the respective
    # expressions
    def new_capacity_rule(mod, prj, prd):
        gen_cap_type = mod.capacity_type[prj]
        # The capacity type modules check if this period is a "vintage" for
        # this project and return 0 if not
        return imported_capacity_modules[gen_cap_type].new_capacity_rule(
            mod, prj, prd)

    def total_capacity_rule(mod, prj, prd):
        gen_cap_type = mod.capacity_type[prj]
        # Return the capacity type's capacity rule if the project is
        # operational in this timepoint; otherwise, return 0
        return imported_capacity_modules[gen_cap_type].capacity_rule(
            mod, prj, prd) \
            if prd in mod.OPR_PRDS_BY_PRJ[prj] \
            else 0

    # Expressions
    def group_new_capacity_rule(mod, grp, prd):
        return sum(
            new_capacity_rule(mod, prj, prd)
            for prj in mod.PROJECTS_IN_CAPACITY_GROUP[grp])

    m.Group_New_Capacity_in_Period = Expression(m.CAPACITY_GROUP_PERIODS,
                                                rule=group_new_capacity_rule)

    def group_total_capacity_rule(mod, grp, prd):
        return sum(
            total_capacity_rule(mod, prj, prd)
            for prj in mod.PROJECTS_IN_CAPACITY_GROUP[grp])

    m.Group_Total_Capacity_in_Period = Expression(
        m.CAPACITY_GROUP_PERIODS, rule=group_total_capacity_rule)

    # Constraints
    # Limit the min and max amount of new build in a group-period
    m.Max_Group_Build_in_Period_Constraint = Constraint(
        m.CAPACITY_GROUP_PERIODS, rule=new_capacity_max_rule)

    m.Min_Group_Build_in_Period_Constraint = Constraint(
        m.CAPACITY_GROUP_PERIODS, rule=new_capacity_min_rule)

    # Limit the min and max amount of total capacity in a group-period
    m.Max_Group_Total_Cap_in_Period_Constraint = Constraint(
        m.CAPACITY_GROUP_PERIODS, rule=total_capacity_max_rule)

    m.Min_Group_Total_Cap_in_Period_Constraint = Constraint(
        m.CAPACITY_GROUP_PERIODS, rule=total_capacity_min_rule)