-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add validation notebooks for PF using matpower reader
Signed-off-by: martin.moraga <[email protected]>
- Loading branch information
1 parent
5b1025d
commit 9d4d269
Showing
3 changed files
with
1,373 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,286 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"attachments": {}, | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"# IEEE14 Powerflow" | ||
] | ||
}, | ||
{ | ||
"attachments": {}, | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Run simulation" | ||
] | ||
}, | ||
{ | ||
"attachments": {}, | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"### Import Libraries" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"import sys, os\n", | ||
"\n", | ||
"notebook_dir = os.path.abspath('')\n", | ||
"dpsim_root_dir = os.path.join(notebook_dir, \"../../..\")\n", | ||
"\n", | ||
"sys.path.insert(0, os.path.join(dpsim_root_dir, 'python/src/dpsim'))\n", | ||
"sys.path.insert(0, os.path.join(dpsim_root_dir, 'build'))\n", | ||
"\n", | ||
"import matpower\n", | ||
"import dpsimpy\n", | ||
"\n", | ||
"from villas.dataprocessing.readtools import *\n", | ||
"from villas.dataprocessing.timeseries import *\n", | ||
"import urllib.request\n", | ||
"import matplotlib.pyplot as plt" | ||
] | ||
}, | ||
{ | ||
"attachments": {}, | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"### Simulation parameters" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# simulation files\n", | ||
"path_static_file = './IEEE14/ieee14.mat'" | ||
] | ||
}, | ||
{ | ||
"attachments": {}, | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"### 1. Powerflow for initialization" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"sim_name_pf = 'IEEE14_PF'\n", | ||
"dpsimpy.Logger.set_log_dir('logs/' + sim_name_pf)\n", | ||
"\n", | ||
"# read and create dpsim topology\n", | ||
"mpc_reader = matpower.Reader(mpc_file_path=path_static_file, mpc_name='ieee14')\n", | ||
"mpc_reader.load_mpc(domain=matpower.Domain.PF)\n", | ||
"system_pf = mpc_reader.system\n", | ||
"\n", | ||
"# log results\n", | ||
"logger = dpsimpy.Logger(sim_name_pf)\n", | ||
"for node in system_pf.nodes:\n", | ||
" logger.log_attribute(node.name()+'.V', 'v', node)\n", | ||
" logger.log_attribute(node.name()+'.S', 's', node)\n", | ||
"\n", | ||
"# Parametrize and run simulation\n", | ||
"sim_pf = dpsimpy.Simulation(sim_name_pf, dpsimpy.LogLevel.info)\n", | ||
"sim_pf.set_system(system_pf)\n", | ||
"sim_pf.set_time_step(0.1)\n", | ||
"sim_pf.set_final_time(0.1)\n", | ||
"sim_pf.set_domain(dpsimpy.Domain.SP)\n", | ||
"sim_pf.set_solver(dpsimpy.Solver.NRP)\n", | ||
"sim_pf.do_init_from_nodes_and_terminals(False)\n", | ||
"sim_pf.set_solver_component_behaviour(dpsimpy.SolverBehaviour.Initialization)\n", | ||
"sim_pf.add_logger(logger)\n", | ||
"sim_pf.run()" | ||
] | ||
}, | ||
{ | ||
"attachments": {}, | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"### Read pf results" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"dpsim_result_file = 'logs/' + sim_name_pf + '/' + sim_name_pf + '.csv'\n", | ||
"ts_dpsim_pf = read_timeseries_csv(dpsim_result_file)" | ||
] | ||
}, | ||
{ | ||
"attachments": {}, | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"#### DPsim results" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"dpsim_results = pd.DataFrame(columns=['Bus', 'Vm [pu]', 'Va [°]', 'P [MW]', 'Q [MVAr]'])\n", | ||
"base_power = 100 #mw\n", | ||
"for i in range(len(system_pf.nodes)):\n", | ||
" node_name = system_pf.nodes[i].name() #ex. N5\n", | ||
" node_number = node_name.replace('N', '')\n", | ||
" node_baseV = mpc_reader.mpc_bus_data.loc[mpc_reader.mpc_bus_data['bus_i'] == int(node_number), 'baseKV'].iloc[0] * 1e3\n", | ||
" w_mw = 1e-6\n", | ||
" dpsim_results.loc[i] = ([node_name] + [round(np.absolute(ts_dpsim_pf[node_name + '.V'].values[-1]) / node_baseV, 5)]\n", | ||
" + [round(np.angle(ts_dpsim_pf[node_name + '.V'].values[-1])*180/np.pi, 5)] \n", | ||
" + [round(w_mw * np.real(ts_dpsim_pf[node_name + '.S'].values[-1]), 5)] \n", | ||
" + [round(w_mw * np.imag(ts_dpsim_pf[node_name + '.S'].values[-1]), 5)])\n", | ||
"\n", | ||
"dpsim_results" | ||
] | ||
}, | ||
{ | ||
"attachments": {}, | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"### Validate Results against PSAT" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"### PSAT Results\n", | ||
"voltage_mag = np.array([1.06, 1.045, 1.01, 1.0186, 1.0203, 1.07, 1.062, 1.09, 1.0564, 1.0513, 1.0571, 1.0552, 1.0504, 1.0358])\n", | ||
"voltage_angle = np.array([0, -0.08693, -0.22197, -0.18019, -0.15328, -0.24823, -0.23332, -0.23332, -0.26087, -0.26362, -0.25823, -0.26315, -0.26457, -0.27993])\n", | ||
"p_loads = np.array([0, 0.217, 0.942, 0.478, 0.076, 0.112, 0, 0, 0.295, 0.09, 0.035, 0.061, 0.135, 0.149])\n", | ||
"q_loads = np.array([0, 0.127, 0.19, -0.039, 0.016, 0.075, 0, 0, -0.04601, 0.058, 0.018, 0.016, 0.058, 0.05])\n", | ||
"p_gen = np.array([2.3239, 0.4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])\n", | ||
"q_gen = np.array([-0.16889, 0.42396, 0.23394, 0, 0, 0.1224, 0, 0.17357, 0, 0, 0, 0, 0, 0])\n", | ||
"busses = [\"N1\", \"N2\", \"N3\", \"N4\", \"N5\", \"N6\", \"N7\", \"N8\", \"N9\", \"N10\", \"N11\", \"N12\", \"N13\", \"N14\"]\n", | ||
"d = {\"Bus\": busses, \"V_mag(pu)\": voltage_mag, \"V_angle(deg)\": voltage_angle, \"P(pu)\": -p_loads+p_gen, \"Q(pu)\": -q_loads+q_gen}\n", | ||
"psat_results = pd.DataFrame(d)\n", | ||
"\n", | ||
"psat_results" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"### Matpower results" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"matpower_pf_results = mpc_reader.get_pf_results()\n", | ||
"matpower_pf_results" | ||
] | ||
}, | ||
{ | ||
"attachments": {}, | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"### Difference" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"difference_vmag = matpower_pf_results['Vm [pu]'] - dpsim_results['Vm [pu]']\n", | ||
"difference_vangle = matpower_pf_results['Va [°]'] - dpsim_results['Va [°]']\n", | ||
"\n", | ||
"#base power = 100MW\n", | ||
"difference_p = (matpower_pf_results['P [MW]'] - dpsim_results['P [MW]'])\n", | ||
"difference_q = (matpower_pf_results['Q [MVAr]'] - dpsim_results['Q [MVAr]'])\n", | ||
"difference = {\"Bus\": matpower_pf_results['Bus'], \"V_mag [pu]\": difference_vmag, \"Va [°]\": difference_vangle, \"P [MW]\": difference_p, \"Q [MVAr]\": difference_q}\n", | ||
"difference = pd.DataFrame(difference)\n", | ||
"\n", | ||
"difference" | ||
] | ||
}, | ||
{ | ||
"attachments": {}, | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"### Assertion" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"tolerance = 5e-5\n", | ||
"\n", | ||
"print(np.max(np.absolute(difference_p)))\n", | ||
"assert(np.all(np.absolute(difference_p)<tolerance))\n", | ||
"\n", | ||
"print(np.max(np.absolute(difference_q)))\n", | ||
"assert(np.all(np.absolute(difference_q)<tolerance))\n", | ||
"\n", | ||
"print(np.max(np.absolute(difference_vmag)))\n", | ||
"assert(np.all(np.absolute(difference_vmag)<tolerance))\n", | ||
"\n", | ||
"print(np.max(np.absolute(difference_vangle)))\n", | ||
"assert(np.all(np.absolute(difference_vangle)<tolerance))" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Python 3", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.9.13" | ||
}, | ||
"tests": { | ||
"skip": false | ||
}, | ||
"vscode": { | ||
"interpreter": { | ||
"hash": "767d51c1340bd893661ea55ea3124f6de3c7a262a8b4abca0554b478b1e2ff90" | ||
} | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 4 | ||
} |
Oops, something went wrong.