Ejemplo n.º 1
0
def rundcopp(net, verbose=False, check_connectivity=True, suppress_warnings=True, r_switch=0.0,
             delta=1e-10, trafo3w_losses="hv", **kwargs):
    """
    Runs the  pandapower Optimal Power Flow.
    Flexibilities, constraints and cost parameters are defined in the pandapower element tables.

    Flexibilities for generators can be defined in net.sgen / net.gen.
    net.sgen.controllable / net.gen.controllable signals if a generator is controllable. If False,
    the active and reactive power are assigned as in a normal power flow. If yes, the following
    flexibilities apply:
        - net.sgen.min_p_kw / net.sgen.max_p_kw
        - net.gen.min_p_kw / net.gen.max_p_kw
        - net.load.min_p_kw / net.load.max_p_kw

        Network constraints can be defined for buses, lines and transformers the elements in the following columns:
        - net.line.max_loading_percent
        - net.trafo.max_loading_percent
        - net.trafo3w.max_loading_percent

    INPUT:
        **net** - The pandapower format network

    OPTIONAL:
        **verbose** (bool, False) - If True, some basic information is printed

        **suppress_warnings** (bool, True) - suppress warnings in pypower

            If set to True, warnings are disabled during the loadflow. Because of the way data is
            processed in pypower, ComplexWarnings are raised during the loadflow.
            These warnings are suppressed by this option, however keep in mind all other pypower
            warnings are suppressed, too.
    """

    if (not net.sgen.empty) & (not "controllable" in net.sgen.columns):
        logger.warning('Warning: Please specify sgen["controllable"]\n')

    if (not net.load.empty) & (not "controllable" in net.load.columns):
        logger.warning('Warning: Please specify load["controllable"]\n')

    mode = "opf"
    ac = False
    init = "flat"
    copy_constraints_to_ppc = True
    trafo_model = "t"
    trafo_loading = 'current'
    calculate_voltage_angles = True
    enforce_q_lims = True
    recycle = dict(_is_elements=False, ppc=False, Ybus=False)

    # net.__internal_options = {}
    net._options = {}
    _add_ppc_options(net, calculate_voltage_angles=calculate_voltage_angles,
                     trafo_model=trafo_model, check_connectivity=check_connectivity,
                     mode=mode, copy_constraints_to_ppc=copy_constraints_to_ppc,
                     r_switch=r_switch, init=init, enforce_q_lims=enforce_q_lims, recycle=recycle,
                     voltage_depend_loads=False, delta=delta, trafo3w_losses=trafo3w_losses)
    _add_opf_options(net, trafo_loading=trafo_loading, ac=ac)
    _check_bus_index_and_print_warning_if_high(net)
    _check_gen_index_and_print_warning_if_high(net)
    _optimal_powerflow(net, verbose, suppress_warnings, **kwargs)
Ejemplo n.º 2
0
def runpm_vd(net,
             pp_to_pm_callback=None,
             calculate_voltage_angles=True,
             trafo_model="t",
             delta=1e-8,
             trafo3w_losses="hv",
             check_connectivity=True,
             pm_model="ACPPowerModel",
             pm_solver="ipopt",
             correct_pm_network_data=True,
             silence=True,
             pm_time_limits=None,
             pm_log_level=0,
             pm_file_path=None,
             delete_buffer_file=True,
             opf_flow_lim="S",
             pm_tol=1e-8,
             pdm_dev_mode=False,
             **kwargs):
    """
        Runs non-linear problem for voltage deviation minimization from PandaModels.jl.
    """
    net._options = {}
    _add_ppc_options(net,
                     calculate_voltage_angles=calculate_voltage_angles,
                     trafo_model=trafo_model,
                     check_connectivity=check_connectivity,
                     mode="opf",
                     switch_rx_ratio=2,
                     init_vm_pu="flat",
                     init_va_degree="flat",
                     enforce_q_lims=True,
                     recycle=dict(_is_elements=False, ppc=False, Ybus=False),
                     voltage_depend_loads=False,
                     delta=delta,
                     trafo3w_losses=trafo3w_losses)
    _add_opf_options(net,
                     trafo_loading='power',
                     ac=True,
                     init="flat",
                     numba=True,
                     pp_to_pm_callback=pp_to_pm_callback,
                     julia_file="run_pandamodels_vd",
                     pm_model=pm_model,
                     pm_solver=pm_solver,
                     correct_pm_network_data=correct_pm_network_data,
                     silence=silence,
                     pm_time_limits=pm_time_limits,
                     pm_log_level=pm_log_level,
                     opf_flow_lim=opf_flow_lim,
                     pm_tol=pm_tol)

    _runpm(net,
           delete_buffer_file=delete_buffer_file,
           pm_file_path=pm_file_path,
           pdm_dev_mode=pdm_dev_mode)
Ejemplo n.º 3
0
def convert_pp_to_pm(net, pm_file_path=None, correct_pm_network_data=True, calculate_voltage_angles=True, ac=True,
                     trafo_model="t", delta=1e-8, trafo3w_losses="hv", check_connectivity=True,
                     pp_to_pm_callback=None, pm_model="ACPPowerModel", pm_solver="ipopt",
                     pm_mip_solver="cbc", pm_nl_solver="ipopt"):
    """
    Converts a pandapower net to a PowerModels.jl datastructure and saves it to a json file

    INPUT:

    **net** - pandapower net

    OPTIONAL:
    **pm_file_path** (str, None) - file path to *.json file to store pm data to

    **correct_pm_network_data** (bool, True) - correct some input data (e.g. angles, p.u. conversion)

    **delta** (float, 1e-8) - (small) offset to set for "hard" OPF limits.

    **pp_to_pm_callback** (function, None) - callback function to add data to the PowerModels data structure

    **pm_model** (str, "ACPPowerModel") - model to use. Default is AC model

    **pm_solver** (str, "ipopt") - default solver to use.

    **pm_nl_solver** (str, "ipopt") - default nonlinear solver to use.

    **pm_mip_solver** (str, "cbc") - default mip solver to use.

    **correct_pm_network_data** (bool, True) - checks if network data is correct. If not tries to correct it

    Returns
    -------
    **pm** (json str) - PowerModels.jl data structure
    """

    net._options = {}

    _add_ppc_options(net, calculate_voltage_angles=calculate_voltage_angles,
                     trafo_model=trafo_model, check_connectivity=check_connectivity,
                     mode="opf", switch_rx_ratio=2, init_vm_pu="flat", init_va_degree="flat",
                     enforce_q_lims=True, recycle=dict(_is_elements=False, ppc=False, Ybus=False),
                     voltage_depend_loads=False, delta=delta, trafo3w_losses=trafo3w_losses)
    _add_opf_options(net, trafo_loading='power', ac=ac, init="flat", numba=True,
                     pp_to_pm_callback=pp_to_pm_callback, pm_solver=pm_solver, pm_model=pm_model,
                     correct_pm_network_data=correct_pm_network_data, pm_mip_solver=pm_mip_solver,
                     pm_nl_solver=pm_nl_solver)

    net, pm, ppc, ppci = convert_to_pm_structure(net)
    buffer_file = dump_pm_json(pm, pm_file_path)
    if pm_file_path is None and isfile(buffer_file):
        remove(buffer_file)
    return pm
Ejemplo n.º 4
0
def runopp(net,
           verbose=False,
           calculate_voltage_angles=False,
           check_connectivity=False,
           suppress_warnings=True,
           r_switch=0.0,
           delta=1e-10,
           init="flat",
           numba=True,
           trafo3w_losses="hv",
           **kwargs):
    """
    Runs the  pandapower Optimal Power Flow.
    Flexibilities, constraints and cost parameters are defined in the pandapower element tables.

    Flexibilities can be defined in net.sgen / net.gen /net.load
    net.sgen.controllable if a static generator is controllable. If False,
    the active and reactive power are assigned as in a normal power flow. If True, the following
    flexibilities apply:
        - net.sgen.min_p_kw / net.sgen.max_p_kw
        - net.sgen.min_q_kvar / net.sgen.max_q_kvar
        - net.load.min_p_kw / net.load.max_p_kw
        - net.load.min_q_kvar / net.load.max_q_kvar
        - net.gen.min_p_kw / net.gen.max_p_kw
        - net.gen.min_q_kvar / net.gen.max_q_kvar
        - net.ext_grid.min_p_kw / net.ext_grid.max_p_kw
        - net.ext_grid.min_q_kvar / net.ext_grid.max_q_kvar
        - net.dcline.min_q_to_kvar / net.dcline.max_q_to_kvar / net.dcline.min_q_from_kvar / net.dcline.max_q_from_kvar

    Controllable loads behave just like controllable static generators. It must be stated if they are controllable.
    Otherwise, they are not respected as flexibilities.
    Dc lines are controllable per default

    Network constraints can be defined for buses, lines and transformers the elements in the following columns:
        - net.bus.min_vm_pu / net.bus.max_vm_pu
        - net.line.max_loading_percent
        - net.trafo.max_loading_percent
        - net.trafo3w.max_loading_percent

    How these costs are combined into a cost function depends on the cost_function parameter.

    INPUT:
        **net** - The pandapower format network

    OPTIONAL:
        **verbose** (bool, False) - If True, some basic information is printed

        **suppress_warnings** (bool, True) - suppress warnings in pypower

            If set to True, warnings are disabled during the loadflow. Because of the way data is
            processed in pypower, ComplexWarnings are raised during the loadflow.
            These warnings are suppressed by this option, however keep in mind all other pypower
            warnings are suppressed, too.

        **init** (str, "flat") - init of starting opf vector. Options are "flat" or "pf"

            Starting solution vector (x0) for opf calculations is determined by this flag. Options are:
            "flat" (default): starting vector is (upper bound - lower bound) / 2
            "pf": a power flow is executed prior to the opf and the pf solution is the starting vector. This may improve
            convergence, but takes a longer runtime (which are probably neglectible for opf calculations)
    """
    logger.warning(
        "The OPF cost definition has changed! Please check out the tutorial 'opf_changes-may18.ipynb' or the documentation!"
    )
    _check_necessary_opf_parameters(net, logger)
    if numba:
        numba = _check_if_numba_is_installed(numba)
    mode = "opf"
    ac = True
    copy_constraints_to_ppc = True
    trafo_model = "t"
    trafo_loading = 'current'
    enforce_q_lims = True
    recycle = dict(_is_elements=False, ppc=False, Ybus=False)

    net._options = {}
    _add_ppc_options(net,
                     calculate_voltage_angles=calculate_voltage_angles,
                     trafo_model=trafo_model,
                     check_connectivity=check_connectivity,
                     mode=mode,
                     copy_constraints_to_ppc=copy_constraints_to_ppc,
                     r_switch=r_switch,
                     init_vm_pu=init,
                     init_va_degree=init,
                     enforce_q_lims=enforce_q_lims,
                     recycle=recycle,
                     voltage_depend_loads=False,
                     delta=delta,
                     trafo3w_losses=trafo3w_losses)
    _add_opf_options(net,
                     trafo_loading=trafo_loading,
                     ac=ac,
                     init=init,
                     numba=numba)
    _check_bus_index_and_print_warning_if_high(net)
    _check_gen_index_and_print_warning_if_high(net)
    _optimal_powerflow(net, verbose, suppress_warnings, **kwargs)
Ejemplo n.º 5
0
def runpm(net,
          julia_file=None,
          pp_to_pm_callback=None,
          calculate_voltage_angles=True,
          trafo_model="t",
          delta=0,
          trafo3w_losses="hv"):
    """
    Runs a power system optimization using PowerModels.jl.
    Flexibilities, constraints and cost parameters are defined in the pandapower element tables.

    Flexibilities can be defined in net.sgen / net.gen /net.load
    net.sgen.controllable if a static generator is controllable. If False,
    the active and reactive power are assigned as in a normal power flow. If True, the following
    flexibilities apply:
        - net.sgen.min_p_kw / net.sgen.max_p_kw
        - net.sgen.min_q_kvar / net.sgen.max_q_kvar
        - net.load.min_p_kw / net.load.max_p_kw
        - net.load.min_q_kvar / net.load.max_q_kvar
        - net.gen.min_p_kw / net.gen.max_p_kw
        - net.gen.min_q_kvar / net.gen.max_q_kvar
        - net.ext_grid.min_p_kw / net.ext_grid.max_p_kw
        - net.ext_grid.min_q_kvar / net.ext_grid.max_q_kvar
        - net.dcline.min_q_to_kvar / net.dcline.max_q_to_kvar / net.dcline.min_q_from_kvar / net.dcline.max_q_from_kvar

    Controllable loads behave just like controllable static generators. It must be stated if they are controllable.
    Otherwise, they are not respected as flexibilities.
    Dc lines are controllable per default

    Network constraints can be defined for buses, lines and transformers the elements in the following columns:
        - net.bus.min_vm_pu / net.bus.max_vm_pu
        - net.line.max_loading_percent
        - net.trafo.max_loading_percent
        - net.trafo3w.max_loading_percent

    How these costs are combined into a cost function depends on the cost_function parameter.

    INPUT:
        **net** - The pandapower format network

    OPTIONAL:
        **julia_file** (str, None) - path to a custom julia optimization file

        **pp_to_pm_callback** (function, None) - callback function to add data to the PowerModels data structure

     """

    net._options = {}
    _add_ppc_options(net,
                     calculate_voltage_angles=calculate_voltage_angles,
                     trafo_model=trafo_model,
                     check_connectivity=False,
                     mode="opf",
                     copy_constraints_to_ppc=True,
                     r_switch=0,
                     init_vm_pu="flat",
                     init_va_degree="flat",
                     enforce_q_lims=True,
                     recycle=dict(_is_elements=False, ppc=False, Ybus=False),
                     voltage_depend_loads=False,
                     delta=delta,
                     trafo3w_losses=trafo3w_losses)
    _add_opf_options(net,
                     trafo_loading='current',
                     ac=True,
                     init="flat",
                     numba=True)
    _runpm(net, julia_file, pp_to_pm_callback)
Ejemplo n.º 6
0
def runopp(net, verbose=False, calculate_voltage_angles=False, check_connectivity=False,
           suppress_warnings=True, r_switch=0.0, delta = 1e-10, **kwargs):
    """
    Runs the  pandapower Optimal Power Flow.
    Flexibilities, constraints and cost parameters are defined in the pandapower element tables.

    Flexibilities can be defined in net.sgen / net.gen /net.load
    net.sgen.controllable if a static generator is controllable. If False,
    the active and reactive power are assigned as in a normal power flow. If True, the following
    flexibilities apply:
        - net.sgen.min_p_kw / net.sgen.max_p_kw
        - net.sgen.min_q_kvar / net.sgen.max_q_kvar
        - net.load.min_p_kw / net.load.max_p_kw
        - net.load.min_q_kvar / net.load.max_q_kvar
        - net.gen.min_p_kw / net.gen.max_p_kw
        - net.gen.min_q_kvar / net.gen.max_q_kvar
        - net.ext_grid.min_p_kw / net.ext_grid.max_p_kw
        - net.ext_grid.min_q_kvar / net.ext_grid.max_q_kvar
        - net.dcline.min_q_to_kvar / net.dcline.max_q_to_kvar / net.dcline.min_q_from_kvar / net.dcline.max_q_from_kvar

    Controllable loads behave just like controllable static generators. It must be stated if they are controllable.
    Otherwise, they are not respected as flexibilities.
    Dc lines are controllable per default

    Network constraints can be defined for buses, lines and transformers the elements in the following columns:
        - net.bus.min_vm_pu / net.bus.max_vm_pu
        - net.line.max_loading_percent
        - net.trafo.max_loading_percent
        - net.trafo3w.max_loading_percent

    How these costs are combined into a cost function depends on the cost_function parameter.

    INPUT:
        **net** - The pandapower format network

    OPTIONAL:
        **verbose** (bool, False) - If True, some basic information is printed

        **suppress_warnings** (bool, True) - suppress warnings in pypower

            If set to True, warnings are disabled during the loadflow. Because of the way data is
            processed in pypower, ComplexWarnings are raised during the loadflow.
            These warnings are suppressed by this option, however keep in mind all other pypower
            warnings are suppressed, too.
    """

    # Check if all necessary parameters are given:

    if (not net.gen.empty) and (("min_p_kw" not in net.gen.columns) or ("max_p_kw" not in net.gen.columns) or (
        "max_q_kvar" not in net.gen.columns) or ("min_q_kvar" not in net.gen.columns)):
        raise UserWarning('Warning: Please specify operational constraints for controllable gens')

    if (not net.dcline.empty) and (("min_q_to_kvar" not in net.dcline.columns) or ("max_q_to_kvar" not in net.dcline.columns) or (
        "min_q_from_kvar" not in net.dcline.columns) or ("max_q_from_kvar" not in net.dcline.columns)):
        raise UserWarning('Warning: Please specify operational constraints for dclines')


    if "controllable" in net.sgen.columns:
        if net.sgen.controllable.any():
            if ("min_p_kw" not in net.sgen.columns) or ("max_p_kw" not in net.sgen.columns) or (
                "max_q_kvar" not in net.sgen.columns) or ("min_q_kvar" not in net.sgen.columns):
                raise UserWarning('Warning: Please specify operational constraints for controllable sgens')
        else:
            logger.debug('No controllable sgens found')


    if "controllable" in net.load.columns:
        if net.load.controllable.any():
            if ("min_p_kw" not in net.load.columns) or ("max_p_kw" not in net.load.columns) or (
                "max_q_kvar" not in net.load.columns) or ("min_q_kvar" not in net.load.columns):
                raise UserWarning('Warning: Please specify operational constraints for controllable loads')
        else:
            logger.debug('No controllable loads found')

    mode = "opf"
    ac = True
    copy_constraints_to_ppc = True
    trafo_model = "t"
    trafo_loading = 'current'
    init = "flat"
    enforce_q_lims = True
    recycle = dict(_is_elements=False, ppc=False, Ybus=False)

    net._options = {}
    _add_ppc_options(net, calculate_voltage_angles=calculate_voltage_angles,
                     trafo_model=trafo_model, check_connectivity=check_connectivity,
                     mode=mode, copy_constraints_to_ppc=copy_constraints_to_ppc,
                     r_switch=r_switch, init=init, enforce_q_lims=enforce_q_lims, recycle=recycle,
                     voltage_depend_loads=False, delta=delta)
    _add_opf_options(net, trafo_loading=trafo_loading, ac=ac)
    _optimal_powerflow(net, verbose, suppress_warnings, **kwargs)
Ejemplo n.º 7
0
def convert_pp_to_pm(net,
                     pm_file_path=None,
                     correct_pm_network_data=True,
                     calculate_voltage_angles=True,
                     ac=True,
                     silence=True,
                     trafo_model="t",
                     delta=1e-8,
                     trafo3w_losses="hv",
                     check_connectivity=True,
                     pp_to_pm_callback=None,
                     pm_model="ACPPowerModel",
                     pm_solver="ipopt",
                     pm_mip_solver="cbc",
                     pm_nl_solver="ipopt",
                     opf_flow_lim="S",
                     pm_tol=1e-8,
                     voltage_depend_loads=False):
    """
    Converts a pandapower net to a PowerModels.jl datastructure and saves it to a json file
    INPUT:
        **net**  - pandapower net
    OPTIONAL:
        **pm_file_path** (str, None) - Specifiy the filename, under which the .json file for
        powermodels is stored. If you want to keep the file after optimization, you should also
        set delete_buffer_file to False!

        **correct_pm_network_data** (bool, True) - checks if network data is correct.
        If not tries to correct it

        **silence** (bool, True) - Suppresses information and warning messages output by PowerModels

        **pm_model** (str, "ACPPowerModel") - The PowerModels.jl model to use

        **pm_solver** (str, "ipopt") - The "main" power models solver

        **pm_mip_solver** (str, "cbc") - The mixed integer solver (when "main" solver == juniper)

        **pm_nl_solver** (str, "ipopt") - The nonlinear solver (when "main" solver == juniper)

        **pm_time_limits** (Dict, None) - Time limits in seconds for power models interface.
        To be set as a dict like
        {"pm_time_limit": 300., "pm_nl_time_limit": 300., "pm_mip_time_limit": 300.}

        **pm_log_level** (int, 0) - solver log level in power models

        **delete_buffer_file** (Bool, True) - If True, the .json file used by powermodels will be
        deleted after optimization.

        **pp_to_pm_callback** (function, None) - callback function to add data to the PowerModels
        data structure

        **opf_flow_lim** (str, "I") - Quantity to limit for branch flow constraints, in line with
        matpower's "opf.flowlim" parameter:

            "S" - apparent power flow (limit in MVA),

            "I" - current magnitude (limit in MVA at 1 p.u. voltage)

        **pm_tol** (float, 1e-8) - default desired convergence tolerance for solver to use.

        **voltage_depend_loads** (bool, False) - consideration of voltage-dependent loads.
        If False, net.load.const_z_percent and net.load.const_i_percent are not considered,
        i.e. net.load.p_mw and net.load.q_mvar are considered as constant-power loads.

    Returns
    -------
    """

    net._options = {}

    _add_ppc_options(net,
                     calculate_voltage_angles=calculate_voltage_angles,
                     trafo_model=trafo_model,
                     check_connectivity=check_connectivity,
                     mode="opf",
                     switch_rx_ratio=2,
                     init_vm_pu="flat",
                     init_va_degree="flat",
                     enforce_q_lims=True,
                     recycle=dict(_is_elements=False, ppc=False, Ybus=False),
                     voltage_depend_loads=voltage_depend_loads,
                     delta=delta,
                     trafo3w_losses=trafo3w_losses)
    _add_opf_options(net,
                     trafo_loading='power',
                     ac=ac,
                     init="flat",
                     numba=True,
                     pp_to_pm_callback=pp_to_pm_callback,
                     pm_solver=pm_solver,
                     pm_model=pm_model,
                     correct_pm_network_data=correct_pm_network_data,
                     silence=silence,
                     pm_mip_solver=pm_mip_solver,
                     pm_nl_solver=pm_nl_solver,
                     opf_flow_lim=opf_flow_lim,
                     pm_tol=pm_tol)

    net, pm, ppc, ppci = convert_to_pm_structure(net)
    buffer_file = dump_pm_json(pm, pm_file_path)
    if pm_file_path is None and isfile(buffer_file):
        remove(buffer_file)
    return pm
Ejemplo n.º 8
0
def runpm_pf(net,
             julia_file=None,
             pp_to_pm_callback=None,
             calculate_voltage_angles=True,
             trafo_model="t",
             delta=1e-8,
             trafo3w_losses="hv",
             check_connectivity=True,
             correct_pm_network_data=True,
             silence=True,
             pm_model="ACPPowerModel",
             pm_solver="ipopt",
             pm_mip_solver="cbc",
             pm_nl_solver="ipopt",
             pm_time_limits=None,
             pm_log_level=0,
             delete_buffer_file=True,
             pm_file_path=None,
             opf_flow_lim="S",
             pm_tol=1e-8,
             pdm_dev_mode=False,
             **kwargs):  # pragma: no cover
    """
        Runs power flow from PowerModels.jl via PandaModels.jl
    """
    ac = True if "DC" not in pm_model else False
    net._options = {}
    _add_ppc_options(net,
                     calculate_voltage_angles=calculate_voltage_angles,
                     trafo_model=trafo_model,
                     check_connectivity=check_connectivity,
                     mode="opf",
                     switch_rx_ratio=2,
                     init_vm_pu="flat",
                     init_va_degree="flat",
                     enforce_q_lims=True,
                     recycle=dict(_is_elements=False, ppc=False, Ybus=False),
                     voltage_depend_loads=False,
                     delta=delta,
                     trafo3w_losses=trafo3w_losses)
    _add_opf_options(net,
                     trafo_loading='power',
                     ac=ac,
                     init="flat",
                     numba=True,
                     pp_to_pm_callback=pp_to_pm_callback,
                     julia_file="run_powermodels_pf",
                     pm_solver=pm_solver,
                     pm_model=pm_model,
                     correct_pm_network_data=correct_pm_network_data,
                     silence=silence,
                     pm_mip_solver=pm_mip_solver,
                     pm_nl_solver=pm_nl_solver,
                     pm_time_limits=pm_time_limits,
                     pm_log_level=pm_log_level,
                     opf_flow_lim=opf_flow_lim,
                     pm_tol=pm_tol)

    _runpm(net,
           delete_buffer_file=delete_buffer_file,
           pm_file_path=pm_file_path,
           pdm_dev_mode=pdm_dev_mode)
Ejemplo n.º 9
0
def runpm_storage_opf(net,
                      calculate_voltage_angles=True,
                      trafo_model="t",
                      delta=1e-8,
                      trafo3w_losses="hv",
                      check_connectivity=True,
                      n_timesteps=24,
                      time_elapsed=1.,
                      correct_pm_network_data=True,
                      silence=True,
                      pm_model="ACPPowerModel",
                      pm_time_limits=None,
                      pm_log_level=0,
                      opf_flow_lim="S",
                      charge_efficiency=1.,
                      discharge_efficiency=1.,
                      standby_loss=1e-8,
                      p_loss=1e-8,
                      q_loss=1e-8,
                      pm_tol=1e-8,
                      pdm_dev_mode=False,
                      **kwargs):
    """
    Runs a non-linear power system optimization with storages and time series using PowerModels.jl.
    """
    ac = True if "DC" not in pm_model else False
    net._options = {}
    _add_ppc_options(net,
                     calculate_voltage_angles=calculate_voltage_angles,
                     trafo_model=trafo_model,
                     check_connectivity=check_connectivity,
                     mode="opf",
                     switch_rx_ratio=2,
                     init_vm_pu="flat",
                     init_va_degree="flat",
                     enforce_q_lims=True,
                     recycle=dict(_is_elements=False, ppc=False, Ybus=False),
                     voltage_depend_loads=False,
                     delta=delta,
                     trafo3w_losses=trafo3w_losses)
    _add_opf_options(net,
                     trafo_loading='power',
                     ac=ac,
                     init="flat",
                     numba=True,
                     pp_to_pm_callback=add_storage_opf_settings,
                     julia_file="run_powermodels_mn_storage",
                     correct_pm_network_data=correct_pm_network_data,
                     silence=silence,
                     pm_model=pm_model,
                     pm_time_limits=pm_time_limits,
                     pm_log_level=pm_log_level,
                     opf_flow_lim=opf_flow_lim,
                     pm_tol=pm_tol,
                     pdm_dev_mode=pdm_dev_mode)

    net._options["n_time_steps"] = n_timesteps
    net._options["time_elapsed"] = time_elapsed

    net._options["charge_efficiency"] = charge_efficiency
    net._options["discharge_efficiency"] = discharge_efficiency

    net._options["standby_loss"] = standby_loss
    net._options["p_loss"] = p_loss
    net._options["q_loss"] = q_loss

    _runpm(net)
    storage_results = read_pm_storage_results(net)
    return storage_results
Ejemplo n.º 10
0
def runpm_tnep(net,
               julia_file=None,
               pp_to_pm_callback=None,
               calculate_voltage_angles=True,
               trafo_model="t",
               delta=1e-8,
               trafo3w_losses="hv",
               check_connectivity=True,
               pm_model="ACPPowerModel",
               pm_solver="juniper",
               correct_pm_network_data=True,
               silence=True,
               pm_nl_solver="ipopt",
               pm_mip_solver="cbc",
               pm_time_limits=None,
               pm_log_level=0,
               delete_buffer_file=True,
               pm_file_path=None,
               opf_flow_lim="S",
               pm_tol=1e-8,
               pdm_dev_mode=False,
               **kwargs):
    """
    Runs transmission network extension planning (tnep) optimization from PowerModels.jl via PandaModels.jl
    """
    ac = True if "DC" not in pm_model else False
    if pm_solver is None:
        if pm_model == "DCPPowerModel":
            pm_solver = "ipopt"
        else:
            pm_solver = "juniper"

    if "ne_line" not in net:
        raise ValueError(
            "ne_line DataFrame missing in net. Please define to run tnep")
    net._options = {}
    _add_ppc_options(net,
                     calculate_voltage_angles=calculate_voltage_angles,
                     trafo_model=trafo_model,
                     check_connectivity=check_connectivity,
                     mode="opf",
                     switch_rx_ratio=2,
                     init_vm_pu="flat",
                     init_va_degree="flat",
                     enforce_q_lims=True,
                     recycle=dict(_is_elements=False, ppc=False, Ybus=False),
                     voltage_depend_loads=False,
                     delta=delta,
                     trafo3w_losses=trafo3w_losses)
    _add_opf_options(net,
                     trafo_loading='power',
                     ac=ac,
                     init="flat",
                     numba=True,
                     pp_to_pm_callback=pp_to_pm_callback,
                     julia_file="run_powermodels_tnep",
                     pm_model=pm_model,
                     pm_solver=pm_solver,
                     correct_pm_network_data=correct_pm_network_data,
                     silence=silence,
                     pm_nl_solver=pm_nl_solver,
                     pm_mip_solver=pm_mip_solver,
                     pm_time_limits=pm_time_limits,
                     pm_log_level=pm_log_level,
                     opf_flow_lim=opf_flow_lim,
                     pm_tol=pm_tol)

    _runpm(net,
           delete_buffer_file=delete_buffer_file,
           pm_file_path=pm_file_path,
           pdm_dev_mode=pdm_dev_mode)
    read_tnep_results(net)
Ejemplo n.º 11
0
def runpm(net,
          julia_file=None,
          pp_to_pm_callback=None,
          calculate_voltage_angles=True,
          trafo_model="t",
          delta=1e-8,
          trafo3w_losses="hv",
          check_connectivity=True,
          correct_pm_network_data=True,
          silence=True,
          pm_model="ACPPowerModel",
          pm_solver="ipopt",
          pm_mip_solver="cbc",
          pm_nl_solver="ipopt",
          pm_time_limits=None,
          pm_log_level=0,
          delete_buffer_file=True,
          pm_file_path=None,
          opf_flow_lim="S",
          pm_tol=1e-8,
          pdm_dev_mode=False,
          **kwargs):  # pragma: no cover
    """
        Runs  optimal power flow from PowerModels.jl via PandaModels.jl

        Flexibilities, constraints and cost parameters are defined in the pandapower element tables.

        Flexibilities can be defined in net.sgen / net.gen /net.load
        net.sgen.controllable if a static generator is controllable. If False,
        the active and reactive power are assigned as in a normal power flow. If True, the following
        flexibilities apply:
            - net.sgen.min_p_mw / net.sgen.max_p_mw
            - net.sgen.min_q_mvar / net.sgen.max_q_mvar
            - net.load.min_p_mw / net.load.max_p_mw
            - net.load.min_q_mvar / net.load.max_q_mvar
            - net.gen.min_p_mw / net.gen.max_p_mw
            - net.gen.min_q_mvar / net.gen.max_q_mvar
            - net.ext_grid.min_p_mw / net.ext_grid.max_p_mw
            - net.ext_grid.min_q_mvar / net.ext_grid.max_q_mvar
            - net.dcline.min_q_to_mvar / net.dcline.max_q_to_mvar / net.dcline.min_q_from_mvar / net.dcline.max_q_from_mvar

        Controllable loads behave just like controllable static generators. It must be stated if they are controllable.
        Otherwise, they are not respected as flexibilities.
        Dc lines are controllable per default

        Network constraints can be defined for buses, lines and transformers the elements in the following columns:
            - net.bus.min_vm_pu / net.bus.max_vm_pu
            - net.line.max_loading_percent
            - net.trafo.max_loading_percent
            - net.trafo3w.max_loading_percent

        How these costs are combined into a cost function depends on the cost_function parameter.

        INPUT:
            **net** - The pandapower format network

        OPTIONAL:
            **julia_file** (str, None) - path to a custom julia optimization file
            **pp_to_pm_callback** (function, None) - callback function to add data to the PowerModels data structure
            **correct_pm_network_data** (bool, True) - checks if network data is correct. If not tries to correct it
            **silence** (bool, True) - Suppresses information and warning messages output by PowerModels
            **pm_model** (str, "ACPPowerModel") - The PowerModels.jl model to use
            **pm_solver** (str, "ipopt") - The "main" power models solver
            **pm_mip_solver** (str, "cbc") - The mixed integer solver (when "main" solver == juniper)
            **pm_nl_solver** (str, "ipopt") - The nonlinear solver (when "main" solver == juniper)
            **pm_time_limits** (Dict, None) - Time limits in seconds for power models interface. To be set as a dict like
                    {"pm_time_limit": 300., "pm_nl_time_limit": 300., "pm_mip_time_limit": 300.}
            **pm_log_level** (int, 0) - solver log level in power models
            **delete_buffer_file** (Bool, True) - If True, the .json file used by powermodels will be deleted after
                    optimization.
            **pm_file_path** (str, None) - Specifiy the filename, under which the .json file for powermodels is stored. If
                    you want to keep the file after optimization, you should also set
                    delete_buffer_file to False!
            **opf_flow_lim** (str, "I") - Quantity to limit for branch flow constraints, in line with matpower's
                    "opf.flowlim" parameter:
                        "S" - apparent power flow (limit in MVA),
                        "I" - current magnitude (limit in MVA at 1 p.u. voltage)
            **pm_tol** (float, 1e-8) - default desired convergence tolerance for solver to use.
            **pdm_dev_mode** (bool, False) - If True, the develope mode of PdM is called.
    """
    ac = True if "DC" not in pm_model else False
    net._options = {}
    _add_ppc_options(net,
                     calculate_voltage_angles=calculate_voltage_angles,
                     trafo_model=trafo_model,
                     check_connectivity=check_connectivity,
                     mode="opf",
                     switch_rx_ratio=2,
                     init_vm_pu="flat",
                     init_va_degree="flat",
                     enforce_q_lims=True,
                     recycle=dict(_is_elements=False, ppc=False, Ybus=False),
                     voltage_depend_loads=False,
                     delta=delta,
                     trafo3w_losses=trafo3w_losses)
    _add_opf_options(net,
                     trafo_loading='power',
                     ac=ac,
                     init="flat",
                     numba=True,
                     pp_to_pm_callback=pp_to_pm_callback,
                     julia_file="run_powermodels_opf",
                     pm_solver=pm_solver,
                     pm_model=pm_model,
                     correct_pm_network_data=correct_pm_network_data,
                     silence=silence,
                     pm_mip_solver=pm_mip_solver,
                     pm_nl_solver=pm_nl_solver,
                     pm_time_limits=pm_time_limits,
                     pm_log_level=pm_log_level,
                     opf_flow_lim=opf_flow_lim,
                     pm_tol=pm_tol)

    _runpm(net,
           delete_buffer_file=delete_buffer_file,
           pm_file_path=pm_file_path,
           pdm_dev_mode=pdm_dev_mode)
Ejemplo n.º 12
0
def runpm_storage_opf(net,
                      calculate_voltage_angles=True,
                      trafo_model="t",
                      delta=1e-8,
                      trafo3w_losses="hv",
                      check_connectivity=True,
                      n_timesteps=24,
                      time_elapsed=1.0,
                      correct_pm_network_data=True,
                      pm_model="ACPPowerModel",
                      pm_time_limits=None,
                      pm_log_level=0,
                      **kwargs):  # pragma: no cover
    """
    Runs a non-linear power system optimization with storages and time series using PowerModels.jl.


    INPUT:
        **net** - The pandapower format network

    OPTIONAL:
        **n_timesteps** (int, 24) - number of time steps to optimize

        **time_elapsed** (float, 1.0) - time elapsed between time steps (1.0 = 1 hour)

        **pm_time_limits** (Dict, None) - Time limits in seconds for power models interface. To be set as a dict like
                                          {"pm_time_limit": 300., "pm_nl_time_limit": 300., "pm_mip_time_limit": 300.}

        **pm_log_level** (int, 0) - solver log level in power models
     """
    julia_file = os.path.join(pp_dir, "opf", 'run_powermodels_mn_storage.jl')
    ac = True if "DC" not in pm_model else False
    net._options = {}
    _add_ppc_options(net,
                     calculate_voltage_angles=calculate_voltage_angles,
                     trafo_model=trafo_model,
                     check_connectivity=check_connectivity,
                     mode="opf",
                     switch_rx_ratio=2,
                     init_vm_pu="flat",
                     init_va_degree="flat",
                     enforce_q_lims=True,
                     recycle=dict(_is_elements=False, ppc=False, Ybus=False),
                     voltage_depend_loads=False,
                     delta=delta,
                     trafo3w_losses=trafo3w_losses)
    _add_opf_options(net,
                     trafo_loading='power',
                     ac=ac,
                     init="flat",
                     numba=True,
                     pp_to_pm_callback=add_storage_opf_settings,
                     julia_file=julia_file,
                     correct_pm_network_data=correct_pm_network_data,
                     pm_model=pm_model,
                     pm_time_limits=pm_time_limits,
                     pm_log_level=pm_log_level)

    net._options["n_time_steps"] = n_timesteps
    net._options["time_elapsed"] = time_elapsed

    _runpm(net)
    storage_results = read_pm_storage_results(net)
    return storage_results
Ejemplo n.º 13
0
def runpm_ots(net,
              pp_to_pm_callback=None,
              calculate_voltage_angles=True,
              trafo_model="t",
              delta=1e-8,
              trafo3w_losses="hv",
              check_connectivity=True,
              pm_model="DCPPowerModel",
              pm_solver="juniper",
              pm_nl_solver="ipopt",
              pm_mip_solver="cbc",
              correct_pm_network_data=True,
              pm_time_limits=None,
              pm_log_level=0,
              **kwargs):  # pragma: no cover
    """
    Runs a non-linear optimal transmission switching (OTS) optimization using PowerModels.jl.

    OPTIONAL:
        **julia_file** (str, None) - path to a custom julia optimization file

        **pp_to_pm_callback** (function, None) - callback function to add data to the PowerModels data structure

        **correct_pm_network_data** (bool, True) - checks if network data is correct. If not tries to correct it

        **pm_model** (str, "ACPPowerModel") - The PowerModels.jl model to use

        **pm_solver** (str, "juniper") - The "main" power models solver

        **pm_mip_solver** (str, "cbc") - The mixed integer solver (when "main" solver == juniper)

        **pm_nl_solver** (str, "ipopt") - The nonlinear solver (when "main" solver == juniper)

        **pm_time_limits** (Dict, None) - Time limits in seconds for power models interface. To be set as a dict like
                                          {"pm_time_limit": 300., "pm_nl_time_limit": 300., "pm_mip_time_limit": 300.}

        **pm_log_level** (int, 0) - solver log level in power models


     """
    julia_file = os.path.join(pp_dir, "opf", 'run_powermodels_ots.jl')
    ac = True if "DC" not in pm_model else False
    if pm_solver is None:
        pm_solver = "juniper"

    net._options = {}
    _add_ppc_options(net,
                     calculate_voltage_angles=calculate_voltage_angles,
                     trafo_model=trafo_model,
                     check_connectivity=check_connectivity,
                     mode="opf",
                     switch_rx_ratio=2,
                     init_vm_pu="flat",
                     init_va_degree="flat",
                     enforce_q_lims=True,
                     recycle=dict(_is_elements=False, ppc=False, Ybus=False),
                     voltage_depend_loads=False,
                     delta=delta,
                     trafo3w_losses=trafo3w_losses)
    _add_opf_options(net,
                     trafo_loading='power',
                     ac=ac,
                     init="flat",
                     numba=True,
                     pp_to_pm_callback=pp_to_pm_callback,
                     julia_file=julia_file,
                     pm_model=pm_model,
                     pm_solver=pm_solver,
                     correct_pm_network_data=correct_pm_network_data,
                     pm_mip_solver=pm_mip_solver,
                     pm_nl_solver=pm_nl_solver,
                     pm_time_limits=pm_time_limits,
                     pm_log_level=pm_log_level,
                     opf_flow_lim="S")
    _runpm(net)
    read_ots_results(net)
Ejemplo n.º 14
0
def runpm_dc_opf(net,
                 pp_to_pm_callback=None,
                 calculate_voltage_angles=True,
                 trafo_model="t",
                 delta=1e-8,
                 trafo3w_losses="hv",
                 check_connectivity=True,
                 correct_pm_network_data=True,
                 pm_model="DCPPowerModel",
                 pm_solver="ipopt",
                 pm_time_limits=None,
                 pm_log_level=0,
                 **kwargs):  # pragma: no cover
    """
    Runs a linearized power system optimization using PowerModels.jl.

    Flexibilities, constraints and cost parameters are defined in the pandapower element tables.

    Flexibilities can be defined in net.sgen / net.gen /net.load
    net.sgen.controllable if a static generator is controllable. If False,
    the active and reactive power are assigned as in a normal power flow. If True, the following
    flexibilities apply:
        - net.sgen.min_p_mw / net.sgen.max_p_mw
        - net.sgen.min_q_mvar / net.sgen.max_q_mvar
        - net.load.min_p_mw / net.load.max_p_mw
        - net.load.min_q_mvar / net.load.max_q_mvar
        - net.gen.min_p_mw / net.gen.max_p_mw
        - net.gen.min_q_mvar / net.gen.max_q_mvar
        - net.ext_grid.min_p_mw / net.ext_grid.max_p_mw
        - net.ext_grid.min_q_mvar / net.ext_grid.max_q_mvar
        - net.dcline.min_q_to_mvar / net.dcline.max_q_to_mvar / net.dcline.min_q_from_mvar / net.dcline.max_q_from_mvar

    Controllable loads behave just like controllable static generators. It must be stated if they are controllable.
    Otherwise, they are not respected as flexibilities.
    Dc lines are controllable per default

    Network constraints can be defined for buses, lines and transformers the elements in the following columns:
        - net.bus.min_vm_pu / net.bus.max_vm_pu
        - net.line.max_loading_percent
        - net.trafo.max_loading_percent
        - net.trafo3w.max_loading_percent

    How these costs are combined into a cost function depends on the cost_function parameter.

    INPUT:
        **net** - The pandapower format network

    OPTIONAL:
        **pp_to_pm_callback** (function, None) - callback function to add data to the PowerModels data structure

        **pm_model** (str, "DCPPowerModel") - model to use. Default is DC model

        **pm_solver** (str, "ipopt") - The "main" power models solver

        **correct_pm_network_data** (bool, True) - checks if network data is correct. If not tries to correct it

        **pm_time_limits** (Dict, None) - Time limits in seconds for power models interface. To be set as a dict like
                                          {"pm_time_limit": 300.}
        
        **pm_log_level** (int, 0) - solver log level in power models
     """
    julia_file = os.path.join(pp_dir, "opf", 'run_powermodels.jl')
    ac = True if "DC" not in pm_model else False

    net._options = {}
    _add_ppc_options(net,
                     calculate_voltage_angles=calculate_voltage_angles,
                     trafo_model=trafo_model,
                     check_connectivity=check_connectivity,
                     mode="opf",
                     switch_rx_ratio=2,
                     init_vm_pu="flat",
                     init_va_degree="flat",
                     enforce_q_lims=True,
                     recycle=dict(_is_elements=False, ppc=False, Ybus=False),
                     voltage_depend_loads=False,
                     delta=delta,
                     trafo3w_losses=trafo3w_losses)
    _add_opf_options(net,
                     trafo_loading='power',
                     ac=ac,
                     init="flat",
                     numba=True,
                     pp_to_pm_callback=pp_to_pm_callback,
                     julia_file=julia_file,
                     correct_pm_network_data=correct_pm_network_data,
                     pm_model=pm_model,
                     pm_solver=pm_solver,
                     pm_time_limits=pm_time_limits,
                     pm_log_level=pm_log_level,
                     opf_flow_lim="S")
    _runpm(net)
Ejemplo n.º 15
0
def runopp(net,
           verbose=False,
           calculate_voltage_angles=False,
           check_connectivity=True,
           suppress_warnings=True,
           r_switch=0.0,
           delta=1e-10,
           **kwargs):
    """
    Runs the  pandapower Optimal Power Flow.
    Flexibilities, constraints and cost parameters are defined in the pandapower element tables.

    Flexibilities for generators can be defined in net.sgen / net.gen.
    net.sgen.controllable / net.gen.controllable signals if a generator is controllable. If False,
    the active and reactive power are assigned as in a normal power flow. If yes, the following
    flexibilities apply:
        - net.sgen.min_p_kw / net.sgen.max_p_kw
        - net.sgen.min_q_kvar / net.sgen.max_q_kvar
        - net.gen.min_p_kw / net.gen.max_p_kw
        - net.gen.min_q_kvar / net.gen.max_q_kvar
        - net.ext_grid.min_p_kw / net.ext_grid.max_p_kw
        - net.ext_grid.min_q_kvar / net.ext_grid.max_q_kvar
        - net.dcline.min_q_to_kvar / net.dcline.max_q_to_kvar / net.dcline.min_q_from_kvar / net.dcline.max_q_from_kvar

    Network constraints can be defined for buses, lines and transformers the elements in the following columns:
        - net.bus.min_vm_pu / net.bus.max_vm_pu
        - net.line.max_loading_percent
        - net.trafo.max_loading_percent
        - net.trafo3w.max_loading_percent

    How these costs are combined into a cost function depends on the cost_function parameter.

    INPUT:
        **net** - The pandapower format network

    OPTIONAL:
        **verbose** (bool, False) - If True, some basic information is printed

        **suppress_warnings** (bool, True) - suppress warnings in pypower

            If set to True, warnings are disabled during the loadflow. Because of the way data is
            processed in pypower, ComplexWarnings are raised during the loadflow.
            These warnings are suppressed by this option, however keep in mind all other pypower
            warnings are suppressed, too.
    """
    mode = "opf"
    ac = True
    copy_constraints_to_ppc = True
    trafo_model = "t"
    trafo_loading = 'current'
    init = "flat"
    enforce_q_lims = True
    recycle = dict(_is_elements=False, ppc=False, Ybus=False)

    net._options = {}
    _add_ppc_options(net,
                     calculate_voltage_angles=calculate_voltage_angles,
                     trafo_model=trafo_model,
                     check_connectivity=check_connectivity,
                     mode=mode,
                     copy_constraints_to_ppc=copy_constraints_to_ppc,
                     r_switch=r_switch,
                     init=init,
                     enforce_q_lims=enforce_q_lims,
                     recycle=recycle,
                     voltage_depend_loads=False,
                     delta=delta)
    _add_opf_options(net, trafo_loading=trafo_loading, ac=ac)
    _optimal_powerflow(net, verbose, suppress_warnings, **kwargs)
Ejemplo n.º 16
0
def runpm(net,
          julia_file=None,
          pp_to_pm_callback=None,
          calculate_voltage_angles=True,
          trafo_model="t",
          delta=1e-8,
          trafo3w_losses="hv",
          check_connectivity=True,
          correct_pm_network_data=True,
          pm_model="ACPPowerModel",
          pm_solver="ipopt",
          pm_mip_solver="cbc",
          pm_nl_solver="ipopt",
          pm_time_limits=None,
          pm_log_level=0,
          report_duals=False,
          branch_limits="hard",
          objective="cost"):  # pragma: no cover
    """
    Runs a power system optimization using PowerModels.jl. with a custom julia file.
    
    Flexibilities, constraints and cost parameters are defined in the pandapower element tables.

    Flexibilities can be defined in net.sgen / net.gen /net.load
    net.sgen.controllable if a static generator is controllable. If False,
    the active and reactive power are assigned as in a normal power flow. If True, the following
    flexibilities apply:
        - net.sgen.min_p_mw / net.sgen.max_p_mw
        - net.sgen.min_q_mvar / net.sgen.max_q_mvar
        - net.load.min_p_mw / net.load.max_p_mw
        - net.load.min_q_mvar / net.load.max_q_mvar
        - net.gen.min_p_mw / net.gen.max_p_mw
        - net.gen.min_q_mvar / net.gen.max_q_mvar
        - net.ext_grid.min_p_mw / net.ext_grid.max_p_mw
        - net.ext_grid.min_q_mvar / net.ext_grid.max_q_mvar
        - net.dcline.min_q_to_mvar / net.dcline.max_q_to_mvar / net.dcline.min_q_from_mvar / net.dcline.max_q_from_mvar

    Controllable loads behave just like controllable static generators. It must be stated if they are controllable.
    Otherwise, they are not respected as flexibilities.
    Dc lines are controllable per default

    Network constraints can be defined for buses, lines and transformers the elements in the following columns:
        - net.bus.min_vm_pu / net.bus.max_vm_pu
        - net.line.max_loading_percent
        - net.trafo.max_loading_percent
        - net.trafo3w.max_loading_percent

    How these costs are combined into a cost function depends on the cost_function parameter.

    INPUT:
        **net** - The pandapower format network

    OPTIONAL:
        **julia_file** (str, None) - path to a custom julia optimization file

        **pp_to_pm_callback** (function, None) - callback function to add data to the PowerModels data structure

        **correct_pm_network_data** (bool, True) - checks if network data is correct. If not tries to correct it

        **pm_model** (str, "ACPPowerModel") - The PowerModels.jl model to use

        **pm_solver** (str, "ipopt") - The "main" power models solver

        **pm_mip_solver** (str, "cbc") - The mixed integer solver (when "main" solver == juniper)

        **pm_nl_solver** (str, "ipopt") - The nonlinear solver (when "main" solver == juniper)

        **pm_time_limits** (Dict, None) - Time limits in seconds for power models interface. To be set as a dict like
                                          {"pm_time_limit": 300., "pm_nl_time_limit": 300., "pm_mip_time_limit": 300.}
                                          
        **pm_log_level** (int, 0) - solver log level in power models

        ** report_duals ** (bool, False) - whether or not the dual variables should be reported 

        ** branch_limits ** (str, "hard") - how the power flow of the branches should be imposed
                - "hard": impose hard limits on the branch flows. any violation means divergence
                - "soft": violates the power flow restrictions in the branches as little as possible
                - "none": impose no restrictions on the branch power flows
        
        ** objective ** (str, "cost") - the objective function to be used in the DC optimal power flow
                - "cost": minimize the overall generation costs
                - "flow": minimize the sum of squares of branch flows
                - "cost-flow": minimize "cost" + "flow" (no weights are added)
                - "cost-fuel": minimize PowerModels.objective_min_fuel_and_cost_polynomial

     """
    net._options = {}
    ac = True if "DC" not in pm_model else False
    julia_file = os.path.join(
        pp_dir, "opf",
        'run_powermodels.jl') if julia_file is None else julia_file
    _add_ppc_options(net,
                     calculate_voltage_angles=calculate_voltage_angles,
                     trafo_model=trafo_model,
                     check_connectivity=check_connectivity,
                     mode="opf",
                     switch_rx_ratio=2,
                     init_vm_pu="flat",
                     init_va_degree="flat",
                     enforce_q_lims=True,
                     recycle=dict(_is_elements=False, ppc=False, Ybus=False),
                     voltage_depend_loads=False,
                     delta=delta,
                     trafo3w_losses=trafo3w_losses)
    _add_opf_options(net,
                     trafo_loading='power',
                     ac=ac,
                     init="flat",
                     numba=True,
                     pp_to_pm_callback=pp_to_pm_callback,
                     julia_file=julia_file,
                     pm_solver=pm_solver,
                     pm_model=pm_model,
                     correct_pm_network_data=correct_pm_network_data,
                     pm_mip_solver=pm_mip_solver,
                     pm_nl_solver=pm_nl_solver,
                     pm_time_limits=pm_time_limits,
                     pm_log_level=pm_log_level,
                     report_duals=report_duals,
                     branch_limits=branch_limits,
                     objective=objective)
    _runpm(net)