grid_feedback_optimizer.engine package
Submodules
grid_feedback_optimizer.engine.grad_proj_optimizer module
- class grid_feedback_optimizer.engine.grad_proj_optimizer.GradientProjectionOptimizer(opt_model_data: OptimizationModelData, sensitivities: dict, alpha: float = 0.5, solver: str = 'CLARABEL', **solver_kwargs)
Bases:
objectGradient projection optimizer. Caches the CVXPY problem to allow fast updates of parameters.
- solve_problem(opt_input: OptimizationInputs)
Update CVXPY parameters using structured optimization inputs, solve the cached optimization problem, and return optimized setpoints.
- Parameters:
opt_input (OptimizationInputs) –
- Structured input model containing:
- u_pu_measnp.ndarray
Measured node voltages [p.u.]
- P_line_meas, Q_line_measnp.ndarray
Measured active/reactive line power flows
- p_gen_last, q_gen_lastnp.ndarray
Previous generator active/reactive power setpoints
- P_transformer_meas, Q_transformer_measnp.ndarray, optional
Measured transformer active/reactive power (if applicable)
- Returns:
Optimized generator setpoints of shape (n_generators, 2), where each row contains [p_opt, q_opt].
- Return type:
np.ndarray
grid_feedback_optimizer.engine.powerflow module
- class grid_feedback_optimizer.engine.powerflow.PowerFlowSolver(network: Network)
Bases:
objectRun a power flow simulation and return bus voltages and line currents.
- is_congested(output_data: Dict[ComponentType, ndarray] | None = None, tol_v: float = 0.0001, tol_l: float = 0.0001, tol_t: float = 0.0001)
Check if the network is congested. Returns True if any of the following occur: - Bus voltage exceeds limits (u_pu_max or u_pu_min) - Line or transformer loading exceeds 1.0 (100%)
- obtain_sensitivity(delta_p: float = 1.0, delta_q: float = 1.0, loading_meas_side: str = 'from', rel_tol: float = 0.0001, rel_tol_line: float = 0.01)
Compute sensitivities of bus voltages and line/transformer power flows to small perturbations in generator power injections (p and q) around the default operating point.
- Parameters:
delta_p (float) – Active power perturbation (W).
delta_q (float) – Reactive power perturbation (VAr).
loading_meas_side (str) – From which side branches are monitored: “from” or “to”.
- Returns:
sensitivities – { “du_dp”: array (n_bus, n_gen), “du_dq”: array (n_bus, n_gen), “dP_line_dp”: array (n_line, n_gen), “dQ_line_dp”: array (n_line, n_gen), “dP_line_dq”: array (n_line, n_gen), “dQ_line_dq”: array (n_line, n_gen), “dP_transformer_dp”: array (n_transformer, n_gen), “dQ_transformer_dp”: array (n_transformer, n_gen), “dP_transformer_dq”: array (n_transformer, n_gen), “dQ_transformer_dq”: array (n_transformer, n_gen) }
- Return type:
dict
- static prune_relative(A: ndarray, rel_tol: float = 0.0001)
Zero very small elements relative to the matrix scale.
- run(gen_update: ndarray = None, load_update: ndarray = None)
Re-run power flow in optimization iterations. The size of the arrays should match the total numbers of gens.
grid_feedback_optimizer.engine.primal_dual_optimizer module
- class grid_feedback_optimizer.engine.primal_dual_optimizer.PrimalDualOptimizer(opt_model_data: OptimizationModelData, sensitivities: dict, alpha: float = 0.5, alpha_v: float = 10.0, alpha_l: float = 10.0, alpha_t: float = 10.0, solver: str = 'CLARABEL', **solver_kwargs)
Bases:
objectA primal-dual gradient projection feedback optimizer.
- static calc_loading(p: ndarray | float, q: ndarray | float, s: ndarray | float) ndarray | float
- static calc_pf(p: ndarray | float, q: ndarray | float) ndarray | float
- static calc_rpf(p: ndarray | float, q: ndarray | float) ndarray | float
- solve_problem(opt_input: OptimizationInputs, grad_callback: Callable | None = None, **callback_kwargs)
Update parameters and implement primal-dual gradient projection.
- Parameters:
opt_input (OptimizationInputs) –
- Structured input model containing:
- u_pu_measnp.ndarray
Measured node voltages [p.u.]
- P_line_meas, Q_line_measnp.ndarray
Measured active/reactive line power flows
- p_gen_last, q_gen_lastnp.ndarray
Previous generator active/reactive power setpoints
- P_transformer_meas, Q_transformer_measnp.ndarray, optional
Measured transformer active/reactive power (if applicable)
grad_callback (callable | None = None) – A function which takes grad_p and grad_q and outputs grad_p and grad_q
- Returns:
Optimized generator setpoints of shape (n_generators, 2), where each row contains [p_opt, q_opt].
- Return type:
np.ndarray
grid_feedback_optimizer.engine.renew_gen_projection module
- class grid_feedback_optimizer.engine.renew_gen_projection.RenewGenProjection(solver: str = 'CLARABEL', **solver_kwargs)
Bases:
objectProject points onto the feasible inverter operating region. Supports analytical and CVXPY-based projections.
- static analytic_projection(p_max: float, s_inv: float, p: float, q: float)
Project a point (p, q) onto the feasible operating region of a PV inverter defined by active power limit p_max and apparent power limit s_inv.
Based on: Optimal Power Flow Pursuit (Appendix B) — setpoint update rule.
- Parameters:
p_max (float) – Active power limit (p_max >= 0)
s_inv (float) – Inverter apparent power capacity (s_inv >= 0)
p (float) – Active and reactive power values to project
q (float) – Active and reactive power values to project
- Returns:
The projected point [p_proj, q_proj] lying within the feasible PV region.
- Return type:
np.ndarray
- Raises:
ValueError – If projection fails or inputs are inconsistent.
- projection(p_max: float, p_min: float, p: float, q: float, s_inv: float | None = None, pf_min: float | None = None, q_min: float | None = None, q_max: float | None = None)
Hybrid projection: analytic if simple, CVXPY otherwise.
grid_feedback_optimizer.engine.solve module
- grid_feedback_optimizer.engine.solve.solve(network: Network, max_iter: int = 1000, tol: float = 0.001, delta_p: float = 1.0, delta_q: float = 1.0, algorithm: str = 'gp', alpha: float = 0.5, alpha_v: float = 10.0, alpha_l: float = 10.0, alpha_t: float = 10.0, record_iterates: bool = True, solver: str = 'CLARABEL', loading_meas_side: str = 'from', rel_tol: float = 0.0001, rel_tol_line: float = 0.01, **solver_kwargs)
Solve the grid optimization problem by iterating between power flow and optimization.