Package: mlpf
MLPFis a python library for (optimal) power flow calculations with machine learning.It offers a few main features such as::chart_with_downwards_trend: Efficient loss functions compatible with bothPyTorchandscikit-learn.ðŸ’± Conversion functions to go fromPPCstoNumPyarrays orTorchtensors.As well as some optional high level utilities:ðŸ—‚ï¸ Data classes that make it easy to go from PPCs to custom (orPyTorch Geometric) data objects with all the info needed for (O)PF extracted.ðŸ“Š Metrics specific to (O)PF for logging and evaluation.ðŸ”Ž Visualization and description tools to take a quick look at your data.Contributions welcome!Installationpip install mlpfThe previous command will install all the dependencies for working with numpy and scikit-learn. It willnot, however, install all the dependencies needed for
working with torch. To use the torch functionalities, please
installPyTorch,PyTorch Geometricwith its dependencies(torch-scatter etc.)
and optionallyTorchMetrics.Installation directly from the master branch:pip install git+https://github.com/viktor-ktorvi/mlpf.gitBasic usage:cd: :file_folder:    Load your data in thePYPOWER case format.:open_file_folder: :arrow_heading_up:    Extract powers, voltages, limits and cost coefficients from the PPCs into eitherNumPyarrays ortorchtensors.ðŸ‹ðŸ»â€â™€ï¸ :chart_with_downwards_trend:    Plug the data into your machine learning models.:chart_with_upwards_trend: :bar_chart:     Use the loss functions to evaluate your results or to train your models(thetorchversions of the loss functions are differentiable!).In depth examplesPower flowOptimal power flowData extraction and lossNumPy/scikit-learntorchNumPy/scikit-learntorchSupervised learningscikit-learn linear regressiontorch MLPtorch GCNscikit-learn linear regressiontorch MLPtorch GCNUnsupervised learningtorch MLPtorch GCNtorch MLPtorch GCNQuick startPower flowppcimportcopyimportpandapowerasppimportpandapower.networksaspnfrompypower.ppoptionimportppoptionfrompypower.runpfimportrunpfnet=pn.case118()ppc=pp.converter.to_ppc(net,init="flat")ppopt=ppoption(OUT_ALL=0,VERBOSE=0)ppc,converged=runpf(copy.deepcopy(ppc),ppopt=ppopt)NumPy/scikit-learnimportnumpyasnpfrommlpf.data.conversion.numpy.power_flowimport(extract_line_arrays,extract_power_arrays,extract_voltage_arrays)frommlpf.loss.numpy.power_flowimport(active_power_errors,reactive_power_errors)# extract quantitiesactive_powers,reactive_powers=extract_power_arrays(ppc)voltage_magnitudes,voltage_angles=extract_voltage_arrays(ppc)edge_index,conductances,susceptances=extract_line_arrays(ppc)active_errors=active_power_errors(edge_index,active_powers,voltage_magnitudes,voltage_angles,conductances,susceptances)reactive_errors=reactive_power_errors(edge_index,reactive_powers,voltage_magnitudes,voltage_angles,conductances,susceptances)print(f"Total P loss ={np.sum(active_errors):.3e}p.u.")print(f"Total Q loss ={np.sum(reactive_errors):.3e}p.u.")Torchimporttorchfrommlpf.data.conversion.torch.power_flowimport(extract_line_tensors,extract_power_tensors,extract_voltage_tensors)frommlpf.loss.torch.power_flowimport(active_power_errors,reactive_power_errors)# extract quantities# note: going from float64 to float32(the standard in torch) will increase the PF loss significantlyactive_powers,reactive_powers=extract_power_tensors(ppc,dtype=torch.float64)voltage_magnitudes,voltage_angles=extract_voltage_tensors(ppc,dtype=torch.float64)edge_index,conductances,susceptances=extract_line_tensors(ppc,dtype=torch.float64)active_errors=active_power_errors(edge_index,active_powers,voltage_magnitudes,voltage_angles,conductances,susceptances)reactive_errors=reactive_power_errors(edge_index,reactive_powers,voltage_magnitudes,voltage_angles,conductances,susceptances)print(f"Total P loss ={torch.sum(active_errors):.3e}p.u.")print(f"Total Q loss ={torch.sum(reactive_errors):.3e}p.u.")Optimal power flowppcimportcopyimportpandapowerasppimportpandapower.networksaspnfrompypower.ppoptionimportppoptionfrompypower.runopfimportrunopfnet=pn.case118()ppc=pp.converter.to_ppc(net,init="flat")ppopt=ppoption(OUT_ALL=0,VERBOSE=0)ppc=runopf(copy.deepcopy(ppc),ppopt=ppopt)NumPy/scikit-learnimportnumpyasnpfrommlpf.data.conversion.numpy.optimal_power_flowimport(extract_active_power_limits_arrays,extract_cost_coefficients_array,extract_demand_arrays,extract_reactive_power_limits_arrays,extract_voltage_limits_arrays,)frommlpf.data.conversion.numpy.power_flowimport(extract_power_arrays,extract_voltage_arrays)frommlpf.loss.numpy.bound_errorsimport(lower_bound_errors,upper_bound_errors)frommlpf.loss.numpy.costsimportpolynomial_costs# extract quantitiesactive_powers,reactive_powers=extract_power_arrays(ppc)voltage_magnitudes,voltage_angles=extract_voltage_arrays(ppc)voltages_min,voltages_max=extract_voltage_limits_arrays(ppc)active_powers_min,active_powers_max=extract_active_power_limits_arrays(ppc)reactive_powers_min,reactive_powers_max=extract_reactive_power_limits_arrays(ppc)active_power_demands,_=extract_demand_arrays(ppc)active_powers_generation=(active_powers+active_power_demands)*ppc["baseMVA"]cost_coefficients=extract_cost_coefficients_array(ppc)# calculate errorsvoltage_upper_errors=upper_bound_errors(voltage_magnitudes,voltages_max)voltage_lower_errors=lower_bound_errors(voltage_magnitudes,voltages_min)active_upper_errors=upper_bound_errors(active_powers,active_powers_max)active_lower_errors=lower_bound_errors(active_powers,active_powers_min)reactive_upper_errors=upper_bound_errors(reactive_powers,reactive_powers_max)reactive_lower_errors=lower_bound_errors(reactive_powers,reactive_powers_min)cost_errors=np.sum(polynomial_costs(active_powers_generation,cost_coefficients))-ppc["f"]print(f"Total V max violation ={np.sum(voltage_upper_errors):.3e}p.u.")print(f"Total V min violation ={np.sum(voltage_lower_errors):.3e}p.u.")print(f"Total P max violation ={np.sum(active_upper_errors):.3e}p.u.")print(f"Total P min violation ={np.sum(active_lower_errors):.3e}p.u.")print(f"Total Q max violation ={np.sum(reactive_upper_errors):.3e}p.u.")print(f"Total Q min violation ={np.sum(reactive_lower_errors):.3e}p.u.")print(f"Total costs ={cost_errors:.3e}$/h")Torchimporttorchfrommlpf.data.conversion.torch.optimal_power_flowimport(extract_active_power_limits_tensors,extract_cost_coefficients_tensor,extract_demand_tensors,extract_reactive_power_limits_tensors,extract_voltage_limits_tensors,)frommlpf.data.conversion.torch.power_flowimport(extract_power_tensors,extract_voltage_tensors)frommlpf.loss.torch.bound_errorsimport(lower_bound_errors,upper_bound_errors)frommlpf.loss.torch.costsimportpolynomial_costs# extract quantitiesactive_powers,reactive_powers=extract_power_tensors(ppc,dtype=torch.float64)voltage_magnitudes,voltage_angles=extract_voltage_tensors(ppc,dtype=torch.float64)voltages_min,voltages_max=extract_voltage_limits_tensors(ppc,dtype=torch.float64)active_powers_min,active_powers_max=extract_active_power_limits_tensors(ppc,dtype=torch.float64)reactive_powers_min,reactive_powers_max=extract_reactive_power_limits_tensors(ppc,dtype=torch.float64)active_power_demands,_=extract_demand_tensors(ppc,dtype=torch.float64)active_powers_generation=(active_powers+active_power_demands)*ppc["baseMVA"]cost_coefficients=extract_cost_coefficients_tensor(ppc,dtype=torch.float64)# calculate errorsvoltage_upper_errors=upper_bound_errors(voltage_magnitudes,voltages_max)voltage_lower_errors=lower_bound_errors(voltage_magnitudes,voltages_min)active_upper_errors=upper_bound_errors(active_powers,active_powers_max)active_lower_errors=lower_bound_errors(active_powers,active_powers_min)reactive_upper_errors=upper_bound_errors(reactive_powers,reactive_powers_max)reactive_lower_errors=lower_bound_errors(reactive_powers,reactive_powers_min)cost_errors=torch.sum(polynomial_costs(active_powers_generation,cost_coefficients))-ppc["f"]print(f"Total V max violation ={torch.sum(voltage_upper_errors):.3e}p.u.")print(f"Total V min violation ={torch.sum(voltage_lower_errors):.3e}p.u.")print(f"Total P max violation ={torch.sum(active_upper_errors):.3e}p.u.")print(f"Total P min violation ={torch.sum(active_lower_errors):.3e}p.u.")print(f"Total Q max violation ={torch.sum(reactive_upper_errors):.3e}p.u.")print(f"Total Q min violation ={torch.sum(reactive_lower_errors):.3e}p.u.")print(f"Total costs ={cost_errors:.3e}$/h")Developmentgit clone https://github.com/viktor-ktorvi/mlpf.git
cd mlpf

conda env create -f environment.yml
conda activate mlpfenv