pydae 0.56.4__py3-none-any.whl → 0.57__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,564 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Created on Thu Feb 25 23:52:55 2021
4
+
5
+ @author: jmmau
6
+ """
7
+
8
+ import numpy as np
9
+ import sympy as sym
10
+ import json
11
+ import os
12
+ import hjson
13
+ from pydae.bmapu.lines.lines import add_lines
14
+ from pydae.bmapu.syns.syns import add_syns
15
+ from pydae.bmapu.vscs.vscs import add_vscs
16
+ from pydae.bmapu.vsgs.vsgs import add_vsgs
17
+ from pydae.bmapu.wecs.wecs import add_wecs
18
+ from pydae.bmapu.pvs.pvs import add_pvs
19
+ from pydae.bmapu.loads.loads import add_loads
20
+ from pydae.bmapu.sources.sources import add_sources
21
+ from pydae.bmapu.miscellaneous.miscellaneous import add_miscellaneous
22
+ from pydae.bmapu.pods.pods import add_pods
23
+ from pydae.bmapu.miscellaneous.banks import add_banks
24
+
25
+ import pydae.build_cffi as db
26
+ from pydae.build_v2 import builder
27
+
28
+ import requests
29
+
30
+ # todo:
31
+ # S_base can't be modified becuase impedances in element base are computed
32
+ # in S_base only in the build
33
+ class bmapu:
34
+ '''
35
+
36
+
37
+ Parameters
38
+ ----------
39
+ data_input : string or dict
40
+ File path to the system data information or dictionary with the information.
41
+
42
+ Returns
43
+ -------
44
+ dict
45
+ Dictionary with the equations for pydae.
46
+
47
+ {
48
+ 'sys':{'name':'pf_1','S_base':100e6},
49
+ 'buses':[{'name':'GRI','P_W':0.0,'Q_var':0.0,'U_kV':66.0, 'type':'slack'},
50
+ {'name':'POI','P_W':0.0,'Q_var':0.0,'U_kV':66.0},
51
+ {'name':'PMV','P_W':0.0,'Q_var':0.0,'U_kV':20.0}],
52
+ 'lines':[{'bus_j':'GRI','bus_k':'POI','X_km':0.4,'R_km':0.12,'km':20},
53
+ {'bus_j':'POI','bus_k':'PMV','X_pu':0.04,'R_pu':0.01, 'S_mva':50.0}]
54
+ }
55
+
56
+
57
+ '''
58
+
59
+ def __init__(self,data_input='',testing=False):
60
+
61
+ if type(data_input) == str:
62
+ if 'http' in data_input:
63
+ url = data_input
64
+ resp = requests.get(url)
65
+ data = hjson.loads(resp.text)
66
+ else:
67
+ if os.path.splitext(data_input)[1] == '.json':
68
+ with open(data_input,'r') as fobj:
69
+ data = json.loads(fobj.read().replace("'",'"'))
70
+ if os.path.splitext(data_input)[1] == '.hjson':
71
+ with open(data_input,'r') as fobj:
72
+ data = hjson.loads(fobj.read().replace("'",'"'))
73
+ elif type(data_input) == dict:
74
+ data = data_input
75
+
76
+ self.data = data
77
+
78
+ if not 'lines' in self.data:
79
+ self.data['lines'] = []
80
+ if not 'shunts' in self.data:
81
+ self.data['shunts'] = []
82
+ if not 'transformers' in self.data:
83
+ self.data['transformers'] = []
84
+ if not 'loads' in self.data:
85
+ self.data['loads'] = []
86
+
87
+ self.system = data['system']
88
+ self.buses = data['buses']
89
+ self.lines = data['lines']
90
+ self.shunts = data['shunts']
91
+ self.transformers = data['transformers']
92
+ self.loads = data['loads']
93
+
94
+ self.y_grid = []
95
+ self.g_grid = []
96
+ self.x_grid = []
97
+ self.f_grid = []
98
+
99
+ self.params_grid = {'S_base':self.system['S_base']}
100
+ self.S_base = sym.Symbol("S_base", real=True)
101
+ self.N_bus = len(self.buses)
102
+ self.N_branch = 3*len(self.lines) + len(self.shunts) + 2*len(self.transformers)
103
+
104
+ self.dae = {'f':[],'g':[],'x':[],'y_ini':[],'y_run':[],
105
+ 'u_ini_dict':{},'u_run_dict':{},'params_dict':{},
106
+ 'h_dict':{},'xy_0_dict':{}}
107
+
108
+ self.uz_jacs = True
109
+ self.verbose = False
110
+ self.testing = testing
111
+
112
+ def contruct_grid(self):
113
+
114
+ N_branch = self.N_branch
115
+ N_bus = self.N_bus
116
+ self.sys = self.system
117
+
118
+ S_base = sym.Symbol('S_base', real=True)
119
+ self.S_base = S_base
120
+
121
+ self.xy_0_dict_grid = {}
122
+ self.u_grid = {}
123
+ self.h_grid = {}
124
+
125
+ self.A = sym.zeros(N_branch,N_bus)
126
+ self.G_primitive = sym.zeros(N_branch,N_branch)
127
+ self.B_primitive = sym.zeros(N_branch,N_branch)
128
+ self.buses_list = [bus['name'] for bus in self.buses]
129
+ self.it = 0
130
+
131
+ add_lines(self)
132
+
133
+ for trafo in self.transformers:
134
+
135
+ bus_j = trafo['bus_j']
136
+ bus_k = trafo['bus_k']
137
+
138
+ idx_j = self.buses_list.index(bus_j)
139
+ idx_k = self.buses_list.index(bus_k)
140
+
141
+ self.A[it,idx_j] = 1
142
+ self.A[it+1,idx_k] = 1
143
+
144
+ trafo_name = f"{bus_j}_{bus_k}"
145
+ g_jk = sym.Symbol(f"g_cc_{trafo_name}", real=True)
146
+ b_jk = sym.Symbol(f"b_cc_{trafo_name}", real=True)
147
+ tap = sym.Symbol(f"tap_{trafo_name}", real=True)
148
+ ang = sym.Symbol(f"ang_{trafo_name}", real=True)
149
+ a_s = tap*sym.cos(ang)
150
+ b_s = tap*sym.sin(ang)
151
+
152
+ Y_cc = g_jk + sym.I*b_jk
153
+
154
+
155
+ Y_primitive =sym.Matrix([[ Y_cc/(a_s**2+b_s**2),-Y_cc/(a_s-sym.I*b_s)],
156
+ [-Y_cc/(a_s+sym.I*b_s), Y_cc]])
157
+
158
+
159
+ self.G_primitive[self.it:self.it+2,self.it:self.it+2] = sym.re(Y_primitive)
160
+ self.B_primitive[self.it:self.it+2,self.it:self.it+2] = sym.im(Y_primitive)
161
+
162
+
163
+ if 'X_pu' in trafo:
164
+ if 'S_mva' in trafo: S_trafo = 1e6*trafo['S_mva']
165
+ R = trafo['R_pu']*sys['S_base']/S_trafo # in pu of the system base
166
+ X = trafo['X_pu']*sys['S_base']/S_trafo # in pu of the system base
167
+ G = R/(R**2+X**2)
168
+ B = -X/(R**2+X**2)
169
+ self.params_grid.update({f"g_cc_{trafo_name}":G})
170
+ self.params_grid.update({f'b_cc_{trafo_name}':B})
171
+ tap_m = 1.0
172
+ if 'tap_m' in trafo:
173
+ tap_m = trafo['tap_m']
174
+ self.params_grid.update({f'tap_{trafo_name}':tap_m})
175
+ self.params_grid.update({f'ang_{trafo_name}':0.0})
176
+
177
+
178
+ if 'X' in trafo:
179
+ bus_idx = self.buses_list.index(trafo['bus_j'])
180
+ U_base = self.buses[bus_idx]['U_kV']*1000
181
+ Z_base = U_base**2/sys['S_base']
182
+ R = trafo['R']/Z_base # in pu of the system base
183
+ X = trafo['X']/Z_base # in pu of the system base
184
+ G = R/(R**2+X**2)
185
+ B = -X/(R**2+X**2)
186
+ self.params_grid.update({f"g_cc_{trafo_name}":G})
187
+ self.params_grid.update({f'b_cc_{trafo_name}':B})
188
+ self.params_grid.update({f'tap_{trafo_name}':1.0})
189
+ self.params_grid.update({f'ang_{trafo_name}':0.0})
190
+
191
+ self.it += 2
192
+
193
+
194
+ for shunt in self.shunts:
195
+
196
+ bus_j = shunt['bus']
197
+ idx_j = self.buses_list.index(bus_j)
198
+
199
+ self.A[self.it,idx_j] = 1
200
+
201
+ shunt_name = f"{bus_j}"
202
+ g_j = sym.Symbol(f"g_shunt_{shunt_name}", real=True)
203
+ b_j = sym.Symbol(f"b_shunt_{shunt_name}", real=True)
204
+ self.G_primitive[self.it,self.it] = g_j
205
+ self.B_primitive[self.it,self.it] = b_j
206
+
207
+
208
+ if 'X_pu' in shunt:
209
+ if 'S_mva' in shunt: S_line = 1e6*shunt['S_mva']
210
+ R = shunt['R_pu']*self.sys['S_base']/S_line # in pu of the system base
211
+ X = shunt['X_pu']*self.sys['S_base']/S_line # in pu of the system base
212
+ G = R/(R**2+X**2)
213
+ B = -X/(R**2+X**2)
214
+ self.params_grid.update({f"g_shunt_{shunt_name}":G})
215
+ self.params_grid.update({f'b_shunt_{shunt_name}':B})
216
+
217
+ if 'X' in shunt:
218
+ U_base = self.buses[idx_j]['U_kV']*1000
219
+ Z_base = U_base**2/self.sys['S_base']
220
+ R = shunt['R']/Z_base # in pu of the system base
221
+ X = shunt['X']/Z_base # in pu of the system base
222
+ G = R/(R**2+X**2)
223
+ B = -X/(R**2+X**2)
224
+ self.params_grid.update({f"g_shunt_{shunt_name}":G})
225
+ self.params_grid.update({f'b_shunt_{shunt_name}':B})
226
+
227
+ self.it += 1
228
+
229
+ G = self.A.T * self.G_primitive * self.A
230
+ B = self.A.T * self.B_primitive * self.A
231
+
232
+ sin = sym.sin
233
+ cos = sym.cos
234
+ g = sym.zeros(2*N_bus,1)
235
+
236
+ for j in range(N_bus):
237
+ bus_j_name = self.buses_list[j]
238
+ P_j = sym.Symbol(f"P_{bus_j_name}", real=True)
239
+ Q_j = sym.Symbol(f"Q_{bus_j_name}", real=True)
240
+ g[2*j] = -P_j/S_base
241
+ g[2*j+1] = -Q_j/S_base
242
+ for k in range(N_bus):
243
+
244
+ bus_k_name = self.buses_list[k]
245
+ V_j = sym.Symbol(f"V_{bus_j_name}", real=True)
246
+ V_k = sym.Symbol(f"V_{bus_k_name}", real=True)
247
+ theta_j = sym.Symbol(f"theta_{bus_j_name}", real=True)
248
+ theta_k = sym.Symbol(f"theta_{bus_k_name}", real=True)
249
+ g[2*j] += V_j*V_k*(G[j,k]*cos(theta_j - theta_k) + B[j,k]*sin(theta_j - theta_k))
250
+ g[2*j+1] += V_j*V_k*(G[j,k]*sin(theta_j - theta_k) - B[j,k]*cos(theta_j - theta_k))
251
+ self.h_grid.update({f"V_{bus_j_name}":V_j})
252
+ bus = self.buses[j]
253
+ bus_name = bus['name']
254
+ if 'type' in bus:
255
+ if bus['type'] == 'slack':
256
+ self.y_grid += [P_j]
257
+ self.y_grid += [Q_j]
258
+ self.u_grid.update({f"V_{bus_name}":1.0})
259
+ self.u_grid.update({f"theta_{bus_name}":0.0})
260
+ else:
261
+ self.y_grid += [V_j]
262
+ self.y_grid += [theta_j]
263
+ self.u_grid.update({f"P_{bus_name}":bus['P_W']})
264
+ self.u_grid.update({f"Q_{bus_name}":bus['Q_var']})
265
+ self.xy_0_dict_grid.update({str(V_j):1.0,str(theta_j):0.0})
266
+
267
+ self.params_grid.update({f'U_{bus_name}_n':bus['U_kV']*1000})
268
+ self.g_grid = list(g)
269
+
270
+ if False:
271
+ v_sym_list = []
272
+ for bus in buses_list:
273
+ V_m = sym.Symbol(f'V_{bus}',real=True)
274
+ V_a = sym.Symbol(f'theta_{bus}',real=True)
275
+ v_sym_list += [V_m*sym.exp(sym.I*V_a)]
276
+
277
+ sym.Matrix(v_sym_list)
278
+
279
+ I_lines = (G_primitive+1j*B_primitive) * A * sym.Matrix(v_sym_list)
280
+
281
+ it = 0
282
+ for line in self.lines:
283
+ I_jk_r = sym.Symbol(f"I_{line['bus_j']}_{line['bus_k']}_r", real=True)
284
+ I_jk_i = sym.Symbol(f"I_{line['bus_j']}_{line['bus_k']}_i", real=True)
285
+ g_grid += [-I_jk_r + sym.re(I_lines[it])]
286
+ g_grid += [-I_jk_i + sym.im(I_lines[it])]
287
+ y_grid += [I_jk_r]
288
+ y_grid += [I_jk_i]
289
+ it += 1
290
+
291
+
292
+
293
+ for bus in self.buses:
294
+ if 'monitor' in bus:
295
+ if bus['monitor']:
296
+ U_base = bus['U_kV']*1000
297
+ V = sym.Symbol(f"V_{bus['name']}", real=True)
298
+ self.h_grid.update({f"U_{bus['name']}":V*U_base})
299
+
300
+
301
+
302
+ self.dae['f'] += []
303
+ self.dae['g'] += self.g_grid
304
+ self.dae['x'] += []
305
+ self.dae['y_ini'] += self.y_grid
306
+ self.dae['y_run'] += self.y_grid
307
+ self.dae['u_ini_dict'].update(self.u_grid)
308
+ self.dae['u_run_dict'].update(self.u_grid)
309
+ self.dae['h_dict'].update(self.h_grid)
310
+ self.dae['params_dict'].update(self.params_grid)
311
+ self.dae['xy_0_dict'].update(self.xy_0_dict_grid)
312
+
313
+ self.A_incidence = self.A
314
+ self.G_primitive = self.G_primitive
315
+ self.B_primitive = self.B_primitive
316
+
317
+
318
+ self.N_syn = 0
319
+ self.N_gformers = 0
320
+
321
+ self.generators_list = []
322
+ self.generators_id_list = []
323
+
324
+ # COI
325
+ omega_coi = sym.Symbol("omega_coi", real=True)
326
+
327
+ self.H_total = 0
328
+ self.omega_coi_numerator = 0.0
329
+ self.omega_coi_denominator = 0.0
330
+
331
+ self.dae['xy_0_dict'].update({str(omega_coi):1.0})
332
+
333
+ self.buses = self.data['buses']
334
+ self.buses_list = [bus['name'] for bus in self.buses]
335
+
336
+
337
+ def construct(self, name):
338
+
339
+ self.contruct_grid()
340
+
341
+ # omega_coi = sym.Symbol("omega_coi", real=True)
342
+ #
343
+ # self.dae['g'] += [ -omega_coi + self.omega_coi_numerator/self.omega_coi_denominator]
344
+ # self.dae['y_ini'] += [ omega_coi]
345
+ # self.dae['y_run'] += [ omega_coi]
346
+
347
+
348
+
349
+ #grid = bmapu_builder.bmapu(data)
350
+ if 'syns' in self.data:
351
+ add_syns(self)
352
+ if 'vscs' in self.data:
353
+ add_vscs(self)
354
+ if 'vsgs' in self.data:
355
+ add_vsgs(self)
356
+ if 'sources' in self.data:
357
+ add_sources(self)
358
+ if 'wecs' in self.data:
359
+ add_wecs(self)
360
+ if 'pvs' in self.data:
361
+ add_pvs(self)
362
+ if 'loads' in self.data:
363
+ add_loads(self)
364
+ if 'pods' in self.data:
365
+ add_pods(self)
366
+ if 'banks' in self.data:
367
+ add_banks(self)
368
+
369
+ add_miscellaneous(self)
370
+
371
+ #add_vsgs(grid)
372
+ omega_coi = sym.Symbol("omega_coi", real=True)
373
+
374
+ self.dae['g'] += [ -omega_coi + self.omega_coi_numerator/self.omega_coi_denominator]
375
+ self.dae['y_ini'] += [ omega_coi]
376
+ self.dae['y_run'] += [ omega_coi]
377
+
378
+
379
+ self.dae['g'] += self.g_line_monitors
380
+ self.dae['y_ini'] += self.y_line_monitors
381
+ self.dae['y_run'] += self.y_line_monitors
382
+
383
+ # secondary frequency control
384
+ xi_freq = sym.Symbol("xi_freq", real=True)
385
+ p_agc = sym.Symbol("p_agc", real=True)
386
+ K_p_agc = sym.Symbol("K_p_agc", real=True)
387
+ K_i_agc = sym.Symbol("K_i_agc", real=True)
388
+ K_xif = sym.Symbol("K_xif", real=True)
389
+
390
+ epsilon_freq = 1-omega_coi
391
+ g_agc = [ -p_agc + K_p_agc*epsilon_freq + K_i_agc*xi_freq ]
392
+ y_agc = [ p_agc]
393
+ x_agc = [ xi_freq]
394
+ f_agc = [epsilon_freq - K_xif*xi_freq]
395
+
396
+ self.dae['g'] += g_agc
397
+ self.dae['y_ini'] += y_agc
398
+ self.dae['y_run'] += y_agc
399
+ self.dae['f'] += f_agc
400
+ self.dae['x'] += x_agc
401
+ self.dae['params_dict'].update({'K_p_agc':self.system['K_p_agc'],'K_i_agc':self.system['K_i_agc']})
402
+
403
+ if 'K_xif' in self.system:
404
+ self.dae['params_dict'].update({'K_xif':self.system['K_xif']})
405
+ else:
406
+ self.dae['params_dict'].update({'K_xif':0.0})
407
+
408
+
409
+ with open('xy_0.json','w') as fobj:
410
+ fobj.write(json.dumps(self.dae['xy_0_dict'],indent=4))
411
+
412
+ with open(f'{name}_xy_0.json','w') as fobj:
413
+ fobj.write(json.dumps(self.dae['xy_0_dict'],indent=4))
414
+
415
+ self.sys_dict = {'name':name,'uz_jacs':self.uz_jacs,
416
+ 'params_dict':self.dae['params_dict'],
417
+ 'f_list':self.dae['f'],
418
+ 'g_list':self.dae['g'] ,
419
+ 'x_list':self.dae['x'],
420
+ 'y_ini_list':self.dae['y_ini'],
421
+ 'y_run_list':self.dae['y_run'],
422
+ 'u_run_dict':self.dae['u_run_dict'],
423
+ 'u_ini_dict':self.dae['u_ini_dict'],
424
+ 'h_dict':self.dae['h_dict']}
425
+ if self.testing:
426
+ self.sys_dict.update({'testing':True})
427
+
428
+
429
+ def compile(self, API=False):
430
+
431
+ bldr = db.builder(self.sys_dict,verbose=self.verbose);
432
+ bldr.build(API=API)
433
+
434
+ def compile_mkl(self, name):
435
+
436
+ b = builder(self.sys_dict,verbose=self.verbose)
437
+ b.sparse = True
438
+ b.mkl = True
439
+ b.uz_jacs = False
440
+ b.dict2system()
441
+ b.functions()
442
+ b.jacobians()
443
+ b.cwrite()
444
+ b.template()
445
+ b.compile_mkl()
446
+
447
+ def build(self, name ='', API=False):
448
+ if name == '':
449
+ print('Error: name is not provided.')
450
+ self.construct(name)
451
+ self.compile(API=False)
452
+
453
+ def build_mkl_win(self, name =''):
454
+ if name == '':
455
+ print('Error: name is not provided.')
456
+ self.construct(name)
457
+ self.compile_mkl(name)
458
+
459
+ def checker(self):
460
+
461
+ if not 'syns' in self.data: self.data.update({'syns':[]})
462
+ if not 'vscs' in self.data: self.data.update({'vscs':[]})
463
+ if not 'vsgs' in self.data: self.data.update({'vsgs':[]})
464
+ if not 'genapes' in self.data: self.data.update({'genapes':[]})
465
+ if not 'sources' in self.data: self.data.update({'sources':[]})
466
+
467
+
468
+ K_deltas_n = 0
469
+ for item in self.data['syns']:
470
+ if item['K_delta'] > 0.0:
471
+ K_deltas_n += 1
472
+ for item in self.data['vscs']:
473
+ if item['K_delta'] > 0.0:
474
+ K_deltas_n += 1
475
+ for item in self.data['vsgs']:
476
+ if item['K_delta'] > 0.0:
477
+ K_deltas_n += 1
478
+ for item in self.data['genapes']:
479
+ if item['K_delta'] > 0.0:
480
+ K_deltas_n += 1
481
+ for item in self.data['sources']:
482
+ if item['type'] > 'vsource':
483
+ K_deltas_n += 1
484
+
485
+ if K_deltas_n == 0:
486
+ print('One generator must have K_delta > 0.0')
487
+ if K_deltas_n > 1:
488
+ print('Only one generator must have K_delta > 0.0')
489
+
490
+ if len(self.data['genapes']) > 0:
491
+ if self.data['system']['K_p_agc'] != 0.0:
492
+ print('With a genape in the system K_p_agc must be set to 0.0')
493
+ if self.data['system']['K_i_agc'] != 0.0:
494
+ print('With a genape in the system K_i_agc must be set to 0.0')
495
+ if not self.data['system']['K_xif'] > 0.0:
496
+ print('With a genape in the system K_xif must be set larger than 0.0')
497
+
498
+
499
+ for item in self.data['syns']:
500
+ if 'gov' in item:
501
+ if 'K_imw' in item['gov']:
502
+ if item['gov']['p_c'] > 0.0 and item['gov']['K_imw'] == 0.0:
503
+ print(f"Synchornous machine at bus {item['bus']} has p_c > 0, therefore K_imw should be larger than 0")
504
+
505
+
506
+ for item in self.data['syns']:
507
+ if 'avr' in item:
508
+ if 'sexs' in item['avr']:
509
+ if item['avr']['K_ai'] <= 0.0:
510
+ print(f"AVR of a synchornous machine at bus {item['bus']} must have constant K_ai larger than 0")
511
+
512
+
513
+
514
+
515
+ if __name__ == "__main__":
516
+
517
+ from pydae.bmapu import bmapu_builder
518
+ from pydae.build_v2 import build_mkl,build_numba
519
+
520
+
521
+ data = {
522
+ "system":{"name":"temp","S_base":100e6, "K_p_agc":0.01,"K_i_agc":0.01},
523
+ "buses":[{"name":"1", "P_W":0.0,"Q_var":0.0,"U_kV":20.0},
524
+ {"name":"2", "P_W":0.0,"Q_var":0.0,"U_kV":20.0}],
525
+ "lines":[{"bus_j":"1", "bus_k":"2", "X_pu":0.15,"R_pu":0.0, "S_mva":900.0}],
526
+ "sources":[{"bus":"1","type":"vsource","V_mag_pu":1.0,"V_ang_rad":0.0,"K_delta":0.1}]
527
+ }
528
+
529
+ grid = bmapu_builder.bmapu(data)
530
+ grid.uz_jacs = False
531
+ grid.verbose = True
532
+ grid.construct(f'temp')
533
+ build_numba(grid.sys_dict)
534
+
535
+ # data = {
536
+ # "sys":{"name":"k12p6","S_base":100e6, "K_p_agc":0.01,"K_i_agc":0.01},
537
+ # "buses":[{"name":"1", "P_W":0.0,"Q_var":0.0,"U_kV":20.0},
538
+ # {"name":"2", "P_W":0.0,"Q_var":0.0,"U_kV":20.0},
539
+ # {"name":"3", "P_W":0.0,"Q_var":0.0,"U_kV":20.0},
540
+ # {"name":"4", "P_W":0.0,"Q_var":0.0,"U_kV":20.0},
541
+ # {"name":"5", "P_W":0.0,"Q_var":0.0,"U_kV":230.0},
542
+ # {"name":"6", "P_W":0.0,"Q_var":0.0,"U_kV":230.0},
543
+ # {"name":"7", "P_W":-967e6,"Q_var":100e6,"U_kV":230.0},
544
+ # {"name":"8", "P_W":0.0,"Q_var":0.0,"U_kV":230.0},
545
+ # {"name":"9", "P_W":-1767e6,"Q_var":250e6,"U_kV":230.0},
546
+ # {"name":"10","P_W":0.0,"Q_var":0.0,"U_kV":230.0},
547
+ # {"name":"11","P_W":0.0,"Q_var":0.0,"U_kV":230.0}
548
+ # ],
549
+ # "lines":[{"bus_j":"1", "bus_k":"5", "X_pu":0.15,"R_pu":0.0, "S_mva":900.0},
550
+ # {"bus_j":"2", "bus_k":"6", "X_pu":0.15,"R_pu":0.0, "S_mva":900.0},
551
+ # {"bus_j":"3", "bus_k":"11","X_pu":0.15,"R_pu":0.0, "S_mva":900.0},
552
+ # {"bus_j":"4", "bus_k":"10","X_pu":0.15,"R_pu":0.0, "S_mva":900.0},
553
+ # {"bus_j":"5", "bus_k":"6", "X_km":0.529,"R_km":0.0529,"Bs_km":2.1e-6,"km":25},
554
+ # {"bus_j":"6", "bus_k":"7", "X_km":0.529,"R_km":0.0529,"Bs_km":2.1e-6,"km":10},
555
+ # {"bus_j":"7", "bus_k":"8", "X_km":0.529,"R_km":0.0529,"Bs_km":2.1e-6,"km":110},
556
+ # {"bus_j":"7", "bus_k":"8", "X_km":0.529,"R_km":0.0529,"Bs_km":2.1e-6,"km":110},
557
+ # {"bus_j":"8", "bus_k":"9", "X_km":0.529,"R_km":0.0529,"Bs_km":2.1e-6,"km":110},
558
+ # {"bus_j":"8", "bus_k":"9", "X_km":0.529,"R_km":0.0529,"Bs_km":2.1e-6,"km":110},
559
+ # {"bus_j":"9", "bus_k":"10","X_km":0.529,"R_km":0.0529,"Bs_km":2.1e-6,"km":10},
560
+ # {"bus_j":"10","bus_k":"11","X_km":0.529,"R_km":0.0529,"Bs_km":2.1e-6,"km":25}]
561
+ # }
562
+
563
+ # bpu_obj = bpu(data_input=data)
564
+