def _create_base_relaxation(model_data): md = model_data.clone_in_service() tx_utils.scale_ModelData_to_pu(md, inplace=True) gens = dict(md.elements(element_type='generator')) buses = dict(md.elements(element_type='bus')) branches = dict(md.elements(element_type='branch')) loads = dict(md.elements(element_type='load')) shunts = dict(md.elements(element_type='shunt')) gen_attrs = md.attributes(element_type='generator') bus_attrs = md.attributes(element_type='bus') branch_attrs = md.attributes(element_type='branch') inlet_branches_by_bus, outlet_branches_by_bus = \ tx_utils.inlet_outlet_branches_by_bus(branches, buses) gens_by_bus = tx_utils.gens_by_bus(buses, gens) bus_pairs = zip_items(branch_attrs['from_bus'], branch_attrs['to_bus']) unique_bus_pairs = list( OrderedDict((val, None) for idx, val in bus_pairs.items())) model = pe.ConcreteModel() ### declare (and fix) the loads at the buses bus_p_loads, bus_q_loads = tx_utils.dict_of_bus_loads(buses, loads) libbus.declare_var_pl(model, bus_attrs['names'], initialize=bus_p_loads) libbus.declare_var_ql(model, bus_attrs['names'], initialize=bus_q_loads) model.pl.fix() model.ql.fix() ### declare the fixed shunts at the buses bus_bs_fixed_shunts, bus_gs_fixed_shunts = tx_utils.dict_of_bus_fixed_shunts( buses, shunts) libbus.declare_var_vmsq( model=model, index_set=bus_attrs['names'], initialize={k: v**2 for k, v in bus_attrs['vm'].items()}, bounds=zip_items({k: v**2 for k, v in bus_attrs['v_min'].items()}, {k: v**2 for k, v in bus_attrs['v_max'].items()})) libbranch.declare_var_c(model=model, index_set=unique_bus_pairs) libbranch.declare_var_s(model=model, index_set=unique_bus_pairs) ### declare the generator real and reactive power pg_init = { k: (gen_attrs['p_min'][k] + gen_attrs['p_max'][k]) / 2.0 for k in gen_attrs['pg'] } libgen.declare_var_pg(model, gen_attrs['names'], initialize=pg_init, bounds=zip_items(gen_attrs['p_min'], gen_attrs['p_max'])) qg_init = { k: (gen_attrs['q_min'][k] + gen_attrs['q_max'][k]) / 2.0 for k in gen_attrs['qg'] } libgen.declare_var_qg(model, gen_attrs['names'], initialize=qg_init, bounds=zip_items(gen_attrs['q_min'], gen_attrs['q_max'])) ### declare the current flows in the branches vr_init = { k: bus_attrs['vm'][k] * pe.cos(bus_attrs['va'][k]) for k in bus_attrs['vm'] } vj_init = { k: bus_attrs['vm'][k] * pe.sin(bus_attrs['va'][k]) for k in bus_attrs['vm'] } s_max = {k: branches[k]['rating_long_term'] for k in branches.keys()} s_lbub = dict() for k in branches.keys(): if s_max[k] is None: s_lbub[k] = (None, None) else: s_lbub[k] = (-s_max[k], s_max[k]) pf_bounds = s_lbub pt_bounds = s_lbub qf_bounds = s_lbub qt_bounds = s_lbub pf_init = dict() pt_init = dict() qf_init = dict() qt_init = dict() for branch_name, branch in branches.items(): from_bus = branch['from_bus'] to_bus = branch['to_bus'] y_matrix = tx_calc.calculate_y_matrix_from_branch(branch) ifr_init = tx_calc.calculate_ifr(vr_init[from_bus], vj_init[from_bus], vr_init[to_bus], vj_init[to_bus], y_matrix) ifj_init = tx_calc.calculate_ifj(vr_init[from_bus], vj_init[from_bus], vr_init[to_bus], vj_init[to_bus], y_matrix) itr_init = tx_calc.calculate_itr(vr_init[from_bus], vj_init[from_bus], vr_init[to_bus], vj_init[to_bus], y_matrix) itj_init = tx_calc.calculate_itj(vr_init[from_bus], vj_init[from_bus], vr_init[to_bus], vj_init[to_bus], y_matrix) pf_init[branch_name] = tx_calc.calculate_p(ifr_init, ifj_init, vr_init[from_bus], vj_init[from_bus]) pt_init[branch_name] = tx_calc.calculate_p(itr_init, itj_init, vr_init[to_bus], vj_init[to_bus]) qf_init[branch_name] = tx_calc.calculate_q(ifr_init, ifj_init, vr_init[from_bus], vj_init[from_bus]) qt_init[branch_name] = tx_calc.calculate_q(itr_init, itj_init, vr_init[to_bus], vj_init[to_bus]) libbranch.declare_var_pf(model=model, index_set=branch_attrs['names'], initialize=pf_init, bounds=pf_bounds) libbranch.declare_var_pt(model=model, index_set=branch_attrs['names'], initialize=pt_init, bounds=pt_bounds) libbranch.declare_var_qf(model=model, index_set=branch_attrs['names'], initialize=qf_init, bounds=qf_bounds) libbranch.declare_var_qt(model=model, index_set=branch_attrs['names'], initialize=qt_init, bounds=qt_bounds) ### declare the branch power flow constraints libbranch.declare_eq_branch_power(model=model, index_set=branch_attrs['names'], branches=branches) ### declare the pq balances libbus.declare_eq_p_balance(model=model, index_set=bus_attrs['names'], 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) libbus.declare_eq_q_balance(model=model, index_set=bus_attrs['names'], bus_q_loads=bus_q_loads, gens_by_bus=gens_by_bus, bus_bs_fixed_shunts=bus_bs_fixed_shunts, inlet_branches_by_bus=inlet_branches_by_bus, outlet_branches_by_bus=outlet_branches_by_bus) ### declare the thermal limits libbranch.declare_ineq_s_branch_thermal_limit( model=model, index_set=branch_attrs['names'], branches=branches, s_thermal_limits=s_max, flow_type=FlowType.POWER) ### declare the generator cost objective libgen.declare_expression_pgqg_operating_cost(model=model, index_set=gen_attrs['names'], p_costs=gen_attrs['p_cost'], q_costs=gen_attrs.get( 'q_cost', None)) obj_expr = sum(model.pg_operating_cost[gen_name] for gen_name in model.pg_operating_cost) if hasattr(model, 'qg_operating_cost'): obj_expr += sum(model.qg_operating_cost[gen_name] for gen_name in model.qg_operating_cost) model.obj = pe.Objective(expr=obj_expr) return model, md
def create_psv_acopf_model(model_data, include_feasibility_slack=False): md = model_data.clone_in_service() tx_utils.scale_ModelData_to_pu(md, inplace=True) gens = dict(md.elements(element_type='generator')) buses = dict(md.elements(element_type='bus')) branches = dict(md.elements(element_type='branch')) loads = dict(md.elements(element_type='load')) shunts = dict(md.elements(element_type='shunt')) gen_attrs = md.attributes(element_type='generator') bus_attrs = md.attributes(element_type='bus') branch_attrs = md.attributes(element_type='branch') load_attrs = md.attributes(element_type='load') shunt_attrs = md.attributes(element_type='shunt') inlet_branches_by_bus, outlet_branches_by_bus = \ tx_utils.inlet_outlet_branches_by_bus(branches, buses) gens_by_bus = tx_utils.gens_by_bus(buses, gens) model = pe.ConcreteModel() ### declare (and fix) the loads at the buses bus_p_loads, bus_q_loads = tx_utils.dict_of_bus_loads(buses, loads) libbus.declare_var_pl(model, bus_attrs['names'], initialize=bus_p_loads) libbus.declare_var_ql(model, bus_attrs['names'], initialize=bus_q_loads) model.pl.fix() model.ql.fix() ### declare the fixed shunts at the buses bus_bs_fixed_shunts, bus_gs_fixed_shunts = tx_utils.dict_of_bus_fixed_shunts( buses, shunts) ### declare the polar voltages libbus.declare_var_vm(model, bus_attrs['names'], initialize=bus_attrs['vm'], bounds=zip_items(bus_attrs['v_min'], bus_attrs['v_max'])) libbus.declare_expr_vmsq(model=model, index_set=bus_attrs['names'], coordinate_type=CoordinateType.POLAR) va_bounds = {k: (-pi, pi) for k in bus_attrs['va']} libbus.declare_var_va(model, bus_attrs['names'], initialize=bus_attrs['va'], bounds=va_bounds) ### include the feasibility slack for the bus balances p_rhs_kwargs = {} q_rhs_kwargs = {} if include_feasibility_slack: p_rhs_kwargs, q_rhs_kwargs, penalty_expr = _include_feasibility_slack( model, bus_attrs, gen_attrs, bus_p_loads, bus_q_loads) ### fix the reference bus ref_bus = md.data['system']['reference_bus'] ref_angle = md.data['system']['reference_bus_angle'] model.va[ref_bus].fix(radians(ref_angle)) ### declare the generator real and reactive power pg_init = { k: (gen_attrs['p_min'][k] + gen_attrs['p_max'][k]) / 2.0 for k in gen_attrs['pg'] } libgen.declare_var_pg(model, gen_attrs['names'], initialize=pg_init, bounds=zip_items(gen_attrs['p_min'], gen_attrs['p_max'])) qg_init = { k: (gen_attrs['q_min'][k] + gen_attrs['q_max'][k]) / 2.0 for k in gen_attrs['qg'] } libgen.declare_var_qg(model, gen_attrs['names'], initialize=qg_init, bounds=zip_items(gen_attrs['q_min'], gen_attrs['q_max'])) ### declare the current flows in the branches vr_init = { k: bus_attrs['vm'][k] * pe.cos(bus_attrs['va'][k]) for k in bus_attrs['vm'] } vj_init = { k: bus_attrs['vm'][k] * pe.sin(bus_attrs['va'][k]) for k in bus_attrs['vm'] } s_max = {k: branches[k]['rating_long_term'] for k in branches.keys()} s_lbub = dict() for k in branches.keys(): if s_max[k] is None: s_lbub[k] = (None, None) else: s_lbub[k] = (-s_max[k], s_max[k]) pf_bounds = s_lbub pt_bounds = s_lbub qf_bounds = s_lbub qt_bounds = s_lbub pf_init = dict() pt_init = dict() qf_init = dict() qt_init = dict() for branch_name, branch in branches.items(): from_bus = branch['from_bus'] to_bus = branch['to_bus'] y_matrix = tx_calc.calculate_y_matrix_from_branch(branch) ifr_init = tx_calc.calculate_ifr(vr_init[from_bus], vj_init[from_bus], vr_init[to_bus], vj_init[to_bus], y_matrix) ifj_init = tx_calc.calculate_ifj(vr_init[from_bus], vj_init[from_bus], vr_init[to_bus], vj_init[to_bus], y_matrix) itr_init = tx_calc.calculate_itr(vr_init[from_bus], vj_init[from_bus], vr_init[to_bus], vj_init[to_bus], y_matrix) itj_init = tx_calc.calculate_itj(vr_init[from_bus], vj_init[from_bus], vr_init[to_bus], vj_init[to_bus], y_matrix) pf_init[branch_name] = tx_calc.calculate_p(ifr_init, ifj_init, vr_init[from_bus], vj_init[from_bus]) pt_init[branch_name] = tx_calc.calculate_p(itr_init, itj_init, vr_init[to_bus], vj_init[to_bus]) qf_init[branch_name] = tx_calc.calculate_q(ifr_init, ifj_init, vr_init[from_bus], vj_init[from_bus]) qt_init[branch_name] = tx_calc.calculate_q(itr_init, itj_init, vr_init[to_bus], vj_init[to_bus]) libbranch.declare_var_pf(model=model, index_set=branch_attrs['names'], initialize=pf_init, bounds=pf_bounds) libbranch.declare_var_pt(model=model, index_set=branch_attrs['names'], initialize=pt_init, bounds=pt_bounds) libbranch.declare_var_qf(model=model, index_set=branch_attrs['names'], initialize=qf_init, bounds=qf_bounds) libbranch.declare_var_qt(model=model, index_set=branch_attrs['names'], initialize=qt_init, bounds=qt_bounds) ### declare the branch power flow constraints bus_pairs = zip_items(branch_attrs['from_bus'], branch_attrs['to_bus']) unique_bus_pairs = list( OrderedDict((val, None) for idx, val in bus_pairs.items()).keys()) libbranch.declare_expr_c(model=model, index_set=unique_bus_pairs, coordinate_type=CoordinateType.POLAR) libbranch.declare_expr_s(model=model, index_set=unique_bus_pairs, coordinate_type=CoordinateType.POLAR) libbranch.declare_eq_branch_power(model=model, index_set=branch_attrs['names'], branches=branches) ### declare the pq balances libbus.declare_eq_p_balance(model=model, index_set=bus_attrs['names'], 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, **p_rhs_kwargs) libbus.declare_eq_q_balance(model=model, index_set=bus_attrs['names'], bus_q_loads=bus_q_loads, gens_by_bus=gens_by_bus, bus_bs_fixed_shunts=bus_bs_fixed_shunts, inlet_branches_by_bus=inlet_branches_by_bus, outlet_branches_by_bus=outlet_branches_by_bus, **q_rhs_kwargs) ### declare the thermal limits libbranch.declare_ineq_s_branch_thermal_limit( model=model, index_set=branch_attrs['names'], branches=branches, s_thermal_limits=s_max, flow_type=FlowType.POWER) ### declare the voltage min and max inequalities libbus.declare_ineq_vm_bus_lbub(model=model, index_set=bus_attrs['names'], buses=buses, coordinate_type=CoordinateType.POLAR) ### declare angle difference limits on interconnected buses libbranch.declare_ineq_angle_diff_branch_lbub( model=model, index_set=branch_attrs['names'], branches=branches, coordinate_type=CoordinateType.POLAR) ### declare the generator cost objective libgen.declare_expression_pgqg_operating_cost(model=model, index_set=gen_attrs['names'], p_costs=gen_attrs['p_cost'], q_costs=gen_attrs.get( 'q_cost', None)) obj_expr = sum(model.pg_operating_cost[gen_name] for gen_name in model.pg_operating_cost) if include_feasibility_slack: obj_expr += penalty_expr if hasattr(model, 'qg_operating_cost'): obj_expr += sum(model.qg_operating_cost[gen_name] for gen_name in model.qg_operating_cost) model.obj = pe.Objective(expr=obj_expr) return model, md
def create_psv_acopf_model(model_data): md = tx_utils.scale_ModelData_to_pu(model_data) gens = dict(md.elements(element_type='generator')) buses = dict(md.elements(element_type='bus')) branches = dict(md.elements(element_type='branch')) loads = dict(md.elements(element_type='load')) shunts = dict(md.elements(element_type='shunt')) gen_attrs = md.attributes(element_type='generator') bus_attrs = md.attributes(element_type='bus') branch_attrs = md.attributes(element_type='branch') load_attrs = md.attributes(element_type='load') shunt_attrs = md.attributes(element_type='shunt') inlet_branches_by_bus, outlet_branches_by_bus = \ tx_utils.inlet_outlet_branches_by_bus(branches, buses) gens_by_bus = tx_utils.gens_in_service_by_bus(buses, gens) model = pe.ConcreteModel() ### declare (and fix) the loads at the buses bus_p_loads, bus_q_loads = tx_utils.dict_of_bus_loads(buses, loads) libbus.declare_var_pl(model, bus_attrs['names'], initialize=bus_p_loads) libbus.declare_var_ql(model, bus_attrs['names'], initialize=bus_q_loads) model.pl.fix() model.ql.fix() ### declare the fixed shunts at the buses bus_bs_fixed_shunts, bus_gs_fixed_shunts = tx_utils.dict_of_bus_fixed_shunts( buses, shunts) ### declare the polar voltages libbus.declare_var_vm(model, bus_attrs['names'], initialize=bus_attrs['vm'], bounds=zip_items(bus_attrs['v_min'], bus_attrs['v_max'])) va_bounds = {k: (-pi, pi) for k in bus_attrs['va']} libbus.declare_var_va(model, bus_attrs['names'], initialize=bus_attrs['va'], bounds=va_bounds) ### fix the reference bus ref_bus = md.data['system']['reference_bus'] model.va[ref_bus].fix(0.0) ref_angle = md.data['system']['reference_bus_angle'] if ref_angle != 0.0: raise ValueError('The RIV ACOPF formulation currently only supports' ' a reference bus angle of 0 degrees, but an angle' ' of {} degrees was found.'.format(ref_angle)) ### declare the generator real and reactive power pg_init = { k: (gen_attrs['p_min'][k] + gen_attrs['p_max'][k]) / 2.0 for k in gen_attrs['pg'] } libgen.declare_var_pg(model, gen_attrs['names'], initialize=pg_init, bounds=zip_items(gen_attrs['p_min'], gen_attrs['p_max'])) qg_init = { k: (gen_attrs['q_min'][k] + gen_attrs['q_max'][k]) / 2.0 for k in gen_attrs['qg'] } libgen.declare_var_qg(model, gen_attrs['names'], initialize=qg_init, bounds=zip_items(gen_attrs['q_min'], gen_attrs['q_max'])) ### declare the current flows in the branches vr_init = { k: bus_attrs['vm'][k] * pe.cos(bus_attrs['va'][k]) for k in bus_attrs['vm'] } vj_init = { k: bus_attrs['vm'][k] * pe.sin(bus_attrs['va'][k]) for k in bus_attrs['vm'] } s_max = {k: branches[k]['rating_long_term'] for k in branches.keys()} s_lbub = {k: (-s_max[k], s_max[k]) for k in branches.keys()} pf_bounds = s_lbub pt_bounds = s_lbub qf_bounds = s_lbub qt_bounds = s_lbub pf_init = dict() pt_init = dict() qf_init = dict() qt_init = dict() for branch_name, branch in branches.items(): from_bus = branch['from_bus'] to_bus = branch['to_bus'] y_matrix = tx_calc.calculate_y_matrix_from_branch(branch) ifr_init = tx_calc.calculate_ifr(vr_init[from_bus], vj_init[from_bus], vr_init[to_bus], vj_init[to_bus], y_matrix) ifj_init = tx_calc.calculate_ifj(vr_init[from_bus], vj_init[from_bus], vr_init[to_bus], vj_init[to_bus], y_matrix) itr_init = tx_calc.calculate_itr(vr_init[from_bus], vj_init[from_bus], vr_init[to_bus], vj_init[to_bus], y_matrix) itj_init = tx_calc.calculate_itj(vr_init[from_bus], vj_init[from_bus], vr_init[to_bus], vj_init[to_bus], y_matrix) pf_init[branch_name] = tx_calc.calculate_p(ifr_init, ifj_init, vr_init[from_bus], vj_init[from_bus]) pt_init[branch_name] = tx_calc.calculate_p(itr_init, itj_init, vr_init[to_bus], vj_init[to_bus]) qf_init[branch_name] = tx_calc.calculate_q(ifr_init, ifj_init, vr_init[from_bus], vj_init[from_bus]) qt_init[branch_name] = tx_calc.calculate_q(itr_init, itj_init, vr_init[to_bus], vj_init[to_bus]) libbranch.declare_var_pf(model=model, index_set=branch_attrs['names'], initialize=pf_init, bounds=pf_bounds) libbranch.declare_var_pt(model=model, index_set=branch_attrs['names'], initialize=pt_init, bounds=pt_bounds) libbranch.declare_var_qf(model=model, index_set=branch_attrs['names'], initialize=qf_init, bounds=qf_bounds) libbranch.declare_var_qt(model=model, index_set=branch_attrs['names'], initialize=qt_init, bounds=qt_bounds) ### declare the branch power flow constraints libbranch.declare_eq_branch_power(model=model, index_set=branch_attrs['names'], branches=branches, branch_attrs=branch_attrs, coordinate_type=CoordinateType.POLAR) ### declare the pq balances libbus.declare_eq_p_balance(model=model, index_set=bus_attrs['names'], 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, coordinate_type=CoordinateType.POLAR) libbus.declare_eq_q_balance(model=model, index_set=bus_attrs['names'], bus_q_loads=bus_q_loads, gens_by_bus=gens_by_bus, bus_bs_fixed_shunts=bus_bs_fixed_shunts, inlet_branches_by_bus=inlet_branches_by_bus, outlet_branches_by_bus=outlet_branches_by_bus, coordinate_type=CoordinateType.POLAR) ### declare the thermal limits libbranch.declare_ineq_s_branch_thermal_limit( model=model, index_set=branch_attrs['names'], branches=branches, s_thermal_limits=s_max, flow_type=FlowType.POWER) ### declare the voltage min and max inequalities libbus.declare_ineq_vm_bus_lbub(model=model, index_set=bus_attrs['names'], buses=buses, coordinate_type=CoordinateType.POLAR) ### declare angle difference limits on interconnected buses libbranch.declare_ineq_angle_diff_branch_lbub( model=model, index_set=branch_attrs['names'], branches=branches, coordinate_type=CoordinateType.POLAR) ### declare the generator cost objective libgen.declare_expression_pgqg_operating_cost(model=model, index_set=gen_attrs['names'], p_costs=gen_attrs['p_cost'], q_costs=gen_attrs.get( 'q_cost', None)) obj_expr = sum(model.pg_operating_cost[gen_name] for gen_name in model.pg_operating_cost) if hasattr(model, 'qg_operating_cost'): obj_expr += sum(model.qg_operating_cost[gen_name] for gen_name in model.qg_operating_cost) model.obj = pe.Objective(expr=obj_expr) return model
def _create_base_power_ac_model(model_data, include_feasibility_slack=False, pw_cost_model='delta'): md = model_data.clone_in_service() tx_utils.scale_ModelData_to_pu(md, inplace=True) gens = dict(md.elements(element_type='generator')) buses = dict(md.elements(element_type='bus')) branches = dict(md.elements(element_type='branch')) loads = dict(md.elements(element_type='load')) shunts = dict(md.elements(element_type='shunt')) gen_attrs = md.attributes(element_type='generator') bus_attrs = md.attributes(element_type='bus') branch_attrs = md.attributes(element_type='branch') inlet_branches_by_bus, outlet_branches_by_bus = \ tx_utils.inlet_outlet_branches_by_bus(branches, buses) gens_by_bus = tx_utils.gens_by_bus(buses, gens) bus_pairs = zip_items(branch_attrs['from_bus'], branch_attrs['to_bus']) unique_bus_pairs = list(OrderedDict((val, None) for idx, val in bus_pairs.items())) model = pe.ConcreteModel() ### declare (and fix) the loads at the buses bus_p_loads, bus_q_loads = tx_utils.dict_of_bus_loads(buses, loads) libbus.declare_var_pl(model, bus_attrs['names'], initialize=bus_p_loads) libbus.declare_var_ql(model, bus_attrs['names'], initialize=bus_q_loads) model.pl.fix() model.ql.fix() ### declare the fixed shunts at the buses bus_bs_fixed_shunts, bus_gs_fixed_shunts = tx_utils.dict_of_bus_fixed_shunts(buses, shunts) libbus.declare_var_vmsq(model=model, index_set=bus_attrs['names'], initialize={k: v**2 for k, v in bus_attrs['vm'].items()}, bounds=zip_items({k: v**2 for k, v in bus_attrs['v_min'].items()}, {k: v**2 for k, v in bus_attrs['v_max'].items()})) libbranch.declare_var_c(model=model, index_set=unique_bus_pairs, initialize=1) libbranch.declare_var_s(model=model, index_set=unique_bus_pairs, initialize=0) ### include the feasibility slack for the bus balances p_rhs_kwargs = {} q_rhs_kwargs = {} if include_feasibility_slack: p_marginal_slack_penalty, q_marginal_slack_penalty = _validate_and_extract_slack_penalties(md) p_rhs_kwargs, q_rhs_kwargs, penalty_expr = _include_feasibility_slack(model, bus_attrs['names'], bus_p_loads, bus_q_loads, gens_by_bus, gen_attrs, p_marginal_slack_penalty, q_marginal_slack_penalty) ### declare the generator real and reactive power pg_init = {k: (gen_attrs['p_min'][k] + gen_attrs['p_max'][k]) / 2.0 for k in gen_attrs['pg']} libgen.declare_var_pg(model, gen_attrs['names'], initialize=pg_init, bounds=zip_items(gen_attrs['p_min'], gen_attrs['p_max']) ) qg_init = {k: (gen_attrs['q_min'][k] + gen_attrs['q_max'][k]) / 2.0 for k in gen_attrs['qg']} libgen.declare_var_qg(model, gen_attrs['names'], initialize=qg_init, bounds=zip_items(gen_attrs['q_min'], gen_attrs['q_max']) ) ### declare the current flows in the branches vr_init = {k: bus_attrs['vm'][k] * pe.cos(radians(bus_attrs['va'][k])) for k in bus_attrs['vm']} vj_init = {k: bus_attrs['vm'][k] * pe.sin(radians(bus_attrs['va'][k])) for k in bus_attrs['vm']} s_max = {k: branches[k]['rating_long_term'] for k in branches.keys()} s_lbub = dict() for k in branches.keys(): if s_max[k] is None: s_lbub[k] = (None, None) else: s_lbub[k] = (-s_max[k],s_max[k]) pf_bounds = s_lbub pt_bounds = s_lbub qf_bounds = s_lbub qt_bounds = s_lbub pf_init = dict() pt_init = dict() qf_init = dict() qt_init = dict() for branch_name, branch in branches.items(): from_bus = branch['from_bus'] to_bus = branch['to_bus'] y_matrix = tx_calc.calculate_y_matrix_from_branch(branch) ifr_init = tx_calc.calculate_ifr(vr_init[from_bus], vj_init[from_bus], vr_init[to_bus], vj_init[to_bus], y_matrix) ifj_init = tx_calc.calculate_ifj(vr_init[from_bus], vj_init[from_bus], vr_init[to_bus], vj_init[to_bus], y_matrix) itr_init = tx_calc.calculate_itr(vr_init[from_bus], vj_init[from_bus], vr_init[to_bus], vj_init[to_bus], y_matrix) itj_init = tx_calc.calculate_itj(vr_init[from_bus], vj_init[from_bus], vr_init[to_bus], vj_init[to_bus], y_matrix) pf_init[branch_name] = tx_calc.calculate_p(ifr_init, ifj_init, vr_init[from_bus], vj_init[from_bus]) pt_init[branch_name] = tx_calc.calculate_p(itr_init, itj_init, vr_init[to_bus], vj_init[to_bus]) qf_init[branch_name] = tx_calc.calculate_q(ifr_init, ifj_init, vr_init[from_bus], vj_init[from_bus]) qt_init[branch_name] = tx_calc.calculate_q(itr_init, itj_init, vr_init[to_bus], vj_init[to_bus]) libbranch.declare_var_pf(model=model, index_set=branch_attrs['names'], initialize=pf_init, bounds=pf_bounds ) libbranch.declare_var_pt(model=model, index_set=branch_attrs['names'], initialize=pt_init, bounds=pt_bounds ) libbranch.declare_var_qf(model=model, index_set=branch_attrs['names'], initialize=qf_init, bounds=qf_bounds ) libbranch.declare_var_qt(model=model, index_set=branch_attrs['names'], initialize=qt_init, bounds=qt_bounds ) ### declare the branch power flow constraints libbranch.declare_eq_branch_power(model=model, index_set=branch_attrs['names'], branches=branches ) ### declare the pq balances libbus.declare_eq_p_balance(model=model, index_set=bus_attrs['names'], 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, **p_rhs_kwargs ) libbus.declare_eq_q_balance(model=model, index_set=bus_attrs['names'], bus_q_loads=bus_q_loads, gens_by_bus=gens_by_bus, bus_bs_fixed_shunts=bus_bs_fixed_shunts, inlet_branches_by_bus=inlet_branches_by_bus, outlet_branches_by_bus=outlet_branches_by_bus, **q_rhs_kwargs ) ### declare the thermal limits libbranch.declare_ineq_s_branch_thermal_limit(model=model, index_set=branch_attrs['names'], branches=branches, s_thermal_limits=s_max, flow_type=FlowType.POWER ) # declare angle difference limits on interconnected buses libbranch.declare_ineq_angle_diff_branch_lbub_c_s(model=model, index_set=branch_attrs['names'], branches=branches ) # declare the generator cost objective p_costs = gen_attrs['p_cost'] pw_pg_cost_gens = list(libgen.pw_gen_generator(gen_attrs['names'], costs=p_costs)) if len(pw_pg_cost_gens) > 0: if pw_cost_model == 'delta': libgen.declare_var_delta_pg(model=model, index_set=pw_pg_cost_gens, p_costs=p_costs) libgen.declare_pg_delta_pg_con(model=model, index_set=pw_pg_cost_gens, p_costs=p_costs) else: libgen.declare_var_pg_cost(model=model, index_set=pw_pg_cost_gens, p_costs=p_costs) libgen.declare_piecewise_pg_cost_cons(model=model, index_set=pw_pg_cost_gens, p_costs=p_costs) libgen.declare_expression_pg_operating_cost(model=model, index_set=gen_attrs['names'], p_costs=p_costs, pw_formulation=pw_cost_model) obj_expr = sum(model.pg_operating_cost[gen_name] for gen_name in model.pg_operating_cost) q_costs = gen_attrs.get('q_cost', None) if q_costs is not None: pw_qg_cost_gens = list(libgen.pw_gen_generator(gen_attrs['names'], costs=q_costs)) if len(pw_qg_cost_gens) > 0: if pw_cost_model == 'delta': libgen.declare_var_delta_qg(model=model, index_set=pw_qg_cost_gens, q_costs=q_costs) libgen.declare_qg_delta_qg_con(model=model, index_set=pw_qg_cost_gens, q_costs=q_costs) else: libgen.declare_var_qg_cost(model=model, index_set=pw_qg_cost_gens, q_costs=q_costs) libgen.declare_piecewise_qg_cost_cons(model=model, index_set=pw_qg_cost_gens, q_costs=q_costs) libgen.declare_expression_qg_operating_cost(model=model, index_set=gen_attrs['names'], q_costs=q_costs, pw_formulation=pw_cost_model) obj_expr += sum(model.qg_operating_cost[gen_name] for gen_name in model.qg_operating_cost) if include_feasibility_slack: obj_expr += penalty_expr model.obj = pe.Objective(expr=obj_expr) return model, md
def _create_base_acpf_model(model_data): md = model_data.clone_in_service() tx_utils.scale_ModelData_to_pu(md, inplace = True) gens = dict(md.elements(element_type='generator')) buses = dict(md.elements(element_type='bus')) branches = dict(md.elements(element_type='branch')) loads = dict(md.elements(element_type='load')) shunts = dict(md.elements(element_type='shunt')) gen_attrs = md.attributes(element_type='generator') bus_attrs = md.attributes(element_type='bus') branch_attrs = md.attributes(element_type='branch') inlet_branches_by_bus, outlet_branches_by_bus = \ tx_utils.inlet_outlet_branches_by_bus(branches, buses) gens_by_bus = tx_utils.gens_by_bus(buses, gens) bus_pairs = zip_items(branch_attrs['from_bus'], branch_attrs['to_bus']) unique_bus_pairs = list(OrderedDict((val, None) for idx, val in bus_pairs.items())) model = pe.ConcreteModel() ### declare (and fix) the loads at the buses bus_p_loads, bus_q_loads = tx_utils.dict_of_bus_loads(buses, loads) libbus.declare_var_pl(model, bus_attrs['names'], initialize=bus_p_loads) libbus.declare_var_ql(model, bus_attrs['names'], initialize=bus_q_loads) model.pl.fix() model.ql.fix() ### declare the fixed shunts at the buses bus_bs_fixed_shunts, bus_gs_fixed_shunts = tx_utils.dict_of_bus_fixed_shunts(buses, shunts) libbus.declare_var_vmsq(model=model, index_set=bus_attrs['names'], initialize={k: v**2 for k, v in bus_attrs['vm'].items()} ) libbranch.declare_var_c(model=model, index_set=unique_bus_pairs) libbranch.declare_var_s(model=model, index_set=unique_bus_pairs) ### declare the generator real and reactive power #pg_init = {k: (gen_attrs['p_min'][k] + gen_attrs['p_max'][k]) / 2.0 for k in gen_attrs['pg']} libgen.declare_var_pg(model, gen_attrs['names'], initialize=gen_attrs['pg']) #qg_init = {k: (gen_attrs['q_min'][k] + gen_attrs['q_max'][k]) / 2.0 for k in gen_attrs['qg']} libgen.declare_var_qg(model, gen_attrs['names'], initialize=gen_attrs['qg']) ### declare the current flows in the branches vr_init = {k: bus_attrs['vm'][k] * pe.cos(radians(bus_attrs['va'][k])) for k in bus_attrs['vm']} vj_init = {k: bus_attrs['vm'][k] * pe.sin(radians(bus_attrs['va'][k])) for k in bus_attrs['vm']} pf_init = dict() pt_init = dict() qf_init = dict() qt_init = dict() for branch_name, branch in branches.items(): from_bus = branch['from_bus'] to_bus = branch['to_bus'] y_matrix = tx_calc.calculate_y_matrix_from_branch(branch) ifr_init = tx_calc.calculate_ifr(vr_init[from_bus], vj_init[from_bus], vr_init[to_bus], vj_init[to_bus], y_matrix) ifj_init = tx_calc.calculate_ifj(vr_init[from_bus], vj_init[from_bus], vr_init[to_bus], vj_init[to_bus], y_matrix) itr_init = tx_calc.calculate_itr(vr_init[from_bus], vj_init[from_bus], vr_init[to_bus], vj_init[to_bus], y_matrix) itj_init = tx_calc.calculate_itj(vr_init[from_bus], vj_init[from_bus], vr_init[to_bus], vj_init[to_bus], y_matrix) pf_init[branch_name] = tx_calc.calculate_p(ifr_init, ifj_init, vr_init[from_bus], vj_init[from_bus]) pt_init[branch_name] = tx_calc.calculate_p(itr_init, itj_init, vr_init[to_bus], vj_init[to_bus]) qf_init[branch_name] = tx_calc.calculate_q(ifr_init, ifj_init, vr_init[from_bus], vj_init[from_bus]) qt_init[branch_name] = tx_calc.calculate_q(itr_init, itj_init, vr_init[to_bus], vj_init[to_bus]) libbranch.declare_var_pf(model=model, index_set=branch_attrs['names'], initialize=pf_init ) libbranch.declare_var_pt(model=model, index_set=branch_attrs['names'], initialize=pt_init ) libbranch.declare_var_qf(model=model, index_set=branch_attrs['names'], initialize=qf_init ) libbranch.declare_var_qt(model=model, index_set=branch_attrs['names'], initialize=qt_init ) ### declare the branch power flow constraints libbranch.declare_eq_branch_power(model=model, index_set=branch_attrs['names'], branches=branches ) ### declare the pq balances libbus.declare_eq_p_balance(model=model, index_set=bus_attrs['names'], 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 ) libbus.declare_eq_q_balance(model=model, index_set=bus_attrs['names'], bus_q_loads=bus_q_loads, gens_by_bus=gens_by_bus, bus_bs_fixed_shunts=bus_bs_fixed_shunts, inlet_branches_by_bus=inlet_branches_by_bus, outlet_branches_by_bus=outlet_branches_by_bus ) # if there are multiple generators at the same bus, we will # have unwanted degrees of freedom in qg # therefore, we add a constraint making them equal # if the reference bus has multiple generators, we will also # have unwanted degrees of freedom in pg #ref_bus = md.data['system']['reference_bus'] qg_equality_tuples = list() #pg_equality_tuples = list() for b, genlist in gens_by_bus.items(): if len(genlist) > 1: # we have more than one generator at this bus for i in range(1,len(genlist)): qg_equality_tuples.append((genlist[0], genlist[i])) # if b == ref_bus: # pg_equality_tuples.append((genlist[0], genlist[i])) def _qg_equalities(m,i,j): return m.qg[i] == m.qg[j] model.qg_equalities = pe.Constraint(qg_equality_tuples, rule=_qg_equalities) #def _pg_equalities(m,i,j): # return m.pg[i] == m.pg[j] #model.pg_equalities = pe.Constraint(pg_equality_tuples, rule=_pg_equalities) model.obj = pe.Objective(expr=0.0) return model, md