def _ptdf_dcopf_network_model(block, tm): m, gens_by_bus, bus_p_loads, bus_gs_fixed_shunts = \ _setup_egret_network_model(block, tm) buses, branches, \ branches_in_service, branches_out_service, \ interfaces, contingencies = _setup_egret_network_topology(m, tm) ptdf_options = m._ptdf_options libbus.declare_var_p_nw(block, m.Buses) ### declare net withdraw expression for use in PTDF power flows libbus.declare_eq_p_net_withdraw_at_bus( model=block, index_set=m.Buses, bus_p_loads=bus_p_loads, gens_by_bus=gens_by_bus, bus_gs_fixed_shunts=bus_gs_fixed_shunts, ) ### declare the p balance libbus.declare_eq_p_balance_ed( model=block, index_set=m.Buses, bus_p_loads=bus_p_loads, gens_by_bus=gens_by_bus, bus_gs_fixed_shunts=bus_gs_fixed_shunts, ) ### add "blank" power flow expressions libbranch.declare_expr_pf( model=block, index_set=branches_in_service, ) _setup_branch_slacks(m, block, tm) ### interface setup libbranch.declare_expr_pfi(model=block, index_set=interfaces.keys()) _setup_interface_slacks(m, block, tm) ### contingency setup ### NOTE: important that this not be dense, we'll add elements ### as we find violations block._contingency_set = Set(within=m.Contingencies * m.TransmissionLines) block.pfc = Expression(block._contingency_set) _setup_contingency_slacks(m, block, tm) ### Get the PTDF matrix from cache, from file, or create a new one ### m._PTDFs set in uc_model_generator if branches_out_service not in m._PTDFs: buses_idx = tuple(buses.keys()) reference_bus = value(m.ReferenceBus) ## NOTE: For now, just use a flat-start for unit commitment PTDF = ptdf_utils.VirtualPTDFMatrix(branches, buses, reference_bus, BasePointType.FLATSTART, ptdf_options, contingencies=contingencies, branches_keys=branches_in_service, buses_keys=buses_idx, interfaces=interfaces) m._PTDFs[branches_out_service] = PTDF else: PTDF = m._PTDFs[branches_out_service] ### attach the current PTDF object to this block block._PTDF = PTDF rel_ptdf_tol = m._ptdf_options['rel_ptdf_tol'] abs_ptdf_tol = m._ptdf_options['abs_ptdf_tol'] if ptdf_options['lazy']: ### add "blank" real power flow limits libbranch.declare_ineq_p_branch_thermal_bounds( model=block, index_set=branches_in_service, branches=branches, p_thermal_limits=None, approximation_type=None, slacks=True, slack_cost_expr=m.BranchViolationCost[tm]) ### declare the "blank" interface flow limits libbranch.declare_ineq_p_interface_bounds( model=block, index_set=interfaces.keys(), interfaces=interfaces, approximation_type=None, slacks=True, slack_cost_expr=m.InterfaceViolationCost[tm]) ### declare the "blank" interface flow limits libbranch.declare_ineq_p_contingency_branch_thermal_bounds( model=block, index_set=block._contingency_set, pc_thermal_limits=None, approximation_type=None, slacks=True, slack_cost_expr=m.ContingencyViolationCost[tm]) ### add helpers for tracking monitored branches lpu.add_monitored_flow_tracker(block) ### add initial branches to monitored set lpu.add_initial_monitored_branches(block, branches, branches_in_service, ptdf_options, PTDF) ### add initial interfaces to monitored set lpu.add_initial_monitored_interfaces(block, interfaces, ptdf_options, PTDF) else: ### add all the dense constraints if contingencies: raise RuntimeError( "Contingency constraints only supported in lazy mode") p_max = { k: branches[k]['rating_long_term'] for k in branches_in_service } ### declare the branch power flow approximation constraints libbranch.declare_eq_branch_power_ptdf_approx( model=block, index_set=branches_in_service, PTDF=PTDF, abs_ptdf_tol=abs_ptdf_tol, rel_ptdf_tol=rel_ptdf_tol) ### declare the real power flow limits libbranch.declare_ineq_p_branch_thermal_bounds( model=block, index_set=branches_in_service, branches=branches, p_thermal_limits=p_max, approximation_type=ApproximationType.PTDF, slacks=True, slack_cost_expr=m.BranchViolationCost[tm]) ### declare the branch power flow approximation constraints libbranch.declare_eq_interface_power_ptdf_approx( model=block, index_set=interfaces.keys(), PTDF=PTDF, abs_ptdf_tol=abs_ptdf_tol, rel_ptdf_tol=rel_ptdf_tol) ### declare the interface flow limits libbranch.declare_ineq_p_interface_bounds( model=block, index_set=interfaces.keys(), interfaces=interfaces, approximation_type=ApproximationType.PTDF, slacks=True, slack_cost_expr=m.InterfaceViolationCost[tm])
def _btheta_dcopf_network_model(block, tm): m, gens_by_bus, bus_p_loads, bus_gs_fixed_shunts = \ _setup_egret_network_model(block, tm) buses, branches, \ branches_in_service, branches_out_service, \ interfaces, contingencies = _setup_egret_network_topology(m, tm) if contingencies: raise RuntimeError( "Contingency constraints only supported in lazy-PTDF mode") ## need the inlet/outlet relationship given some lines may be out inlet_branches_by_bus = dict() outlet_branches_by_bus = dict() for b in m.Buses: inlet_branches_by_bus[b] = list() for l in m.LinesTo[b]: if l not in branches_out_service: inlet_branches_by_bus[b].append(l) outlet_branches_by_bus[b] = list() for l in m.LinesFrom[b]: if l not in branches_out_service: outlet_branches_by_bus[b].append(l) va_bounds = {k: (-pi, pi) for k in buses.keys()} libbus.declare_var_va(block, buses.keys(), initialize=None, bounds=va_bounds) ### fix the reference bus ref_bus = value(m.ReferenceBus) ref_angle = value(m.ReferenceBusAngle) block.va[ref_bus].fix(math.radians(ref_angle)) p_max = {k: branches[k]['rating_long_term'] for k in branches_in_service} p_lbub = {k: (-p_max[k], p_max[k]) for k in branches_in_service} pf_bounds = p_lbub libbranch.declare_var_pf( model=block, index_set=branches_in_service, initialize=None, ) _setup_branch_slacks(m, block, tm) ### declare the branch power flow approximation constraints libbranch.declare_eq_branch_power_btheta_approx( model=block, index_set=branches_in_service, branches=branches) ### declare the p balance libbus.declare_eq_p_balance_dc_approx( model=block, index_set=buses.keys(), bus_p_loads=bus_p_loads, gens_by_bus=gens_by_bus, bus_gs_fixed_shunts=bus_gs_fixed_shunts, inlet_branches_by_bus=inlet_branches_by_bus, outlet_branches_by_bus=outlet_branches_by_bus, approximation_type=ApproximationType.BTHETA) ### declare the real power flow limits libbranch.declare_ineq_p_branch_thermal_lbub( model=block, index_set=branches_in_service, branches=branches, p_thermal_limits=p_max, approximation_type=ApproximationType.BTHETA, slacks=True, slack_cost_expr=m.BranchViolationCost[tm]) ### declare angle difference limits on interconnected buses libbranch.declare_ineq_angle_diff_branch_lbub( model=block, index_set=branches_in_service, branches=branches, coordinate_type=CoordinateType.POLAR) ### interface model ### declare the interface variables libbranch.declare_var_pfi( model=block, index_set=interfaces.keys(), ) _setup_interface_slacks(m, block, tm) ### declare the interface flow equality constraint libbranch.declare_eq_interface_power_btheta_approx( model=block, index_set=interfaces.keys(), interfaces=interfaces, ) ### declare the interface flow limits libbranch.declare_ineq_p_interface_bounds( model=block, index_set=interfaces.keys(), interfaces=interfaces, slacks=True, slack_cost_expr=m.InterfaceViolationCost[tm]) return block
def _ptdf_dcopf_network_model(block, tm): m, gens_by_bus, bus_p_loads, bus_gs_fixed_shunts = \ _setup_egret_network_model(block, tm) buses, branches, branches_in_service, branches_out_service, interfaces = \ _setup_egret_network_topology(m, tm) ptdf_options = m._ptdf_options libbus.declare_var_p_nw(block, m.Buses) ### declare net withdraw expression for use in PTDF power flows libbus.declare_eq_p_net_withdraw_at_bus( model=block, index_set=m.Buses, bus_p_loads=bus_p_loads, gens_by_bus=gens_by_bus, bus_gs_fixed_shunts=bus_gs_fixed_shunts, ) ### declare the p balance libbus.declare_eq_p_balance_ed( model=block, index_set=m.Buses, bus_p_loads=bus_p_loads, gens_by_bus=gens_by_bus, bus_gs_fixed_shunts=bus_gs_fixed_shunts, ) ### add "blank" power flow expressions libbranch.declare_expr_pf( model=block, index_set=branches_in_service, ) ### interface setup libbranch.declare_expr_pfi(model=block, index_set=interfaces.keys()) _setup_interface_slacks(m, block, tm) ### Get the PTDF matrix from cache, from file, or create a new one if branches_out_service not in m._PTDFs: buses_idx = tuple(buses.keys()) reference_bus = value(m.ReferenceBus) PTDF = ptdf_utils.get_ptdf_potentially_from_file(ptdf_options, branches_in_service, buses_idx, interfaces=interfaces) ## NOTE: For now, just use a flat-start for unit commitment if PTDF is None: PTDF = ptdf_utils.PTDFMatrix(branches, buses, reference_bus, BasePointType.FLATSTART, ptdf_options, branches_keys=branches_in_service, buses_keys=buses_idx, interfaces=interfaces) m._PTDFs[branches_out_service] = PTDF else: PTDF = m._PTDFs[branches_out_service] ### attach the current PTDF object to this block block._PTDF = PTDF rel_ptdf_tol = m._ptdf_options['rel_ptdf_tol'] abs_ptdf_tol = m._ptdf_options['abs_ptdf_tol'] if ptdf_options['lazy']: ### add "blank" real power flow limits libbranch.declare_ineq_p_branch_thermal_bounds( model=block, index_set=branches_in_service, branches=branches, p_thermal_limits=None, approximation_type=None, ) ### declare the "blank" interface flow limits libbranch.declare_ineq_p_interface_bounds( model=block, index_set=interfaces.keys(), interfaces=interfaces, approximation_type=None, ) ### add helpers for tracking monitored branches lpu.add_monitored_flow_tracker(block) ### add initial branches to monitored set lpu.add_initial_monitored_branches(block, branches, branches_in_service, ptdf_options, PTDF) ### add initial interfaces to monitored set lpu.add_initial_monitored_interfaces(block, interfaces, ptdf_options, PTDF) else: ### add all the dense constraints p_max = { k: branches[k]['rating_long_term'] for k in branches_in_service } ### declare the branch power flow approximation constraints libbranch.declare_eq_branch_power_ptdf_approx( model=block, index_set=branches_in_service, PTDF=PTDF, abs_ptdf_tol=abs_ptdf_tol, rel_ptdf_tol=rel_ptdf_tol) ### declare the real power flow limits libbranch.declare_ineq_p_branch_thermal_bounds( model=block, index_set=branches_in_service, branches=branches, p_thermal_limits=p_max, approximation_type=ApproximationType.PTDF) ### declare the branch power flow approximation constraints libbranch.declare_eq_interface_power_ptdf_approx( model=block, index_set=interfaces.keys(), PTDF=PTDF, abs_ptdf_tol=abs_ptdf_tol, rel_ptdf_tol=rel_ptdf_tol) ### declare the interface flow limits libbranch.declare_ineq_p_interface_bounds( model=block, index_set=interfaces.keys(), interfaces=interfaces, approximation_type=ApproximationType.PTDF)