pydae 0.56.3__py3-none-any.whl → 0.56.5__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.
Files changed (35) hide show
  1. pydae/__init__.py +1 -1
  2. pydae/bmapu/bmapu_builder.py +49 -14
  3. pydae/bmapu/miscellaneous/banks.hjson +8 -0
  4. pydae/bmapu/miscellaneous/banks.py +79 -0
  5. pydae/bmapu/miscellaneous/pll.py +1 -0
  6. pydae/bmapu/miscellaneous/temp.py +27 -25
  7. pydae/bmapu/miscellaneous/temp_cffi.c +1115 -1662
  8. pydae/bmapu/miscellaneous/temp_xy_0.json +1 -7
  9. pydae/bmapu/miscellaneous/xy_0.json +1 -7
  10. pydae/bmapu/pvs/pv_string.py +647 -0
  11. pydae/bmapu/pvs/pvs.py +3 -0
  12. pydae/build_v2.py +29 -18
  13. pydae/etools/pv_designer.py +325 -0
  14. pydae/models/pendulum/api_test.http +106 -0
  15. pydae/models/pendulum/dae_api.py +107 -0
  16. pydae/models/pendulum/dashboard.py +211 -0
  17. pydae/models/pendulum/temp.py +1882 -0
  18. pydae/models/pendulum/temp_ini_cffi.c +1247 -0
  19. pydae/models/pendulum/temp_run_cffi.c +1247 -0
  20. pydae/models/pendulum/temp_trap_cffi.c +950 -0
  21. pydae/svg_tools/bmapu_tooltips.ipynb +119 -0
  22. pydae/svg_tools/svg_tools.py +11 -4
  23. pydae/temp.py +1 -1
  24. pydae/temp_ini_cffi.c +4 -0
  25. pydae/temp_run_cffi.c +4 -0
  26. pydae/temp_trap_cffi.c +4 -0
  27. pydae/templates/class_dae_template_api.py +1857 -0
  28. pydae/tools.py +22 -11
  29. pydae/urisi/fcs/sofc_dcdcac_gf.py +13 -9
  30. pydae/utils/svg2pdf.py +56 -0
  31. {pydae-0.56.3.dist-info → pydae-0.56.5.dist-info}/METADATA +4 -2
  32. {pydae-0.56.3.dist-info → pydae-0.56.5.dist-info}/RECORD +35 -21
  33. {pydae-0.56.3.dist-info → pydae-0.56.5.dist-info}/WHEEL +1 -1
  34. {pydae-0.56.3.dist-info → pydae-0.56.5.dist-info/licenses}/COPYING +0 -0
  35. {pydae-0.56.3.dist-info → pydae-0.56.5.dist-info/licenses}/LICENSE +0 -0
pydae/build_v2.py CHANGED
@@ -30,7 +30,7 @@ from cffi import FFI
30
30
 
31
31
  class builder():
32
32
 
33
- def __init__(self,sys,verbose=False):
33
+ def __init__(self,sys,verbose=False,API=False):
34
34
 
35
35
  logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO)
36
36
 
@@ -40,11 +40,12 @@ class builder():
40
40
  self.name = self.sys['name']
41
41
  self.save_sources = False
42
42
  self.string_u2z = ''
43
- self.u2z = '\#'
43
+ self.u2z = r'#'
44
44
  self.inirun = True
45
45
  self.sparse = False
46
46
  self.mkl = False
47
47
  self.platform = 'Windows'
48
+ self.API = API
48
49
 
49
50
 
50
51
  if not os.path.exists('build'):
@@ -118,7 +119,8 @@ class builder():
118
119
  x = sym.Matrix(sys['x_list']).T
119
120
  y_ini = sym.Matrix(sys['y_ini_list']).T
120
121
  y_run = sym.Matrix(sys['y_run_list']).T
121
- u_ini = sym.Matrix(list(sys['u_ini_dict'].keys()), real=True)
122
+ u_ini_list = [sym.Symbol(item,real=True) for item in list(sys['u_ini_dict'].keys())]
123
+ u_ini = sym.Matrix(u_ini_list).T
122
124
  u_run_list = [sym.Symbol(item,real=True) for item in list(sys['u_run_dict'].keys())]
123
125
  u_run = sym.Matrix(u_run_list).T
124
126
  h = sym.Matrix(list(sys['h_dict'].values())).T
@@ -802,7 +804,10 @@ class builder():
802
804
  if self.mkl:
803
805
  class_template = pkgutil.get_data(__name__, "templates/class_dae_template_v2_mkl.py").decode().replace('\r\n','\n')
804
806
  else:
805
- class_template = pkgutil.get_data(__name__, "templates/class_dae_template_v2.py").decode().replace('\r\n','\n')
807
+ if self.API:
808
+ class_template = pkgutil.get_data(__name__, "templates/class_dae_template_api.py").decode().replace('\r\n','\n')
809
+ else:
810
+ class_template = pkgutil.get_data(__name__, "templates/class_dae_template_v2.py").decode().replace('\r\n','\n')
806
811
  if self.uz_jacs:
807
812
  uz_jacs_template = pkgutil.get_data(__name__, "templates/uz_jacs_v2.py").decode().replace('\r\n','\n')
808
813
  class_template += uz_jacs_template
@@ -1341,9 +1346,11 @@ def sym2xyup_mp(sys,full_list,inirun):
1341
1346
  logging.debug('end full_list update with xyup and tipo')
1342
1347
 
1343
1348
 
1344
- def build_numba(sys_dict,verbose=False):
1349
+ def build_numba(sys_dict,verbose=False, API=False):
1350
+
1351
+ from pydae.build_v2 import builder
1345
1352
 
1346
- b = builder(sys_dict,verbose=verbose)
1353
+ b = builder(sys_dict,verbose=True,API=API)
1347
1354
  b.sparse = False
1348
1355
  b.mkl = False
1349
1356
  b.uz_jacs = False
@@ -1354,6 +1361,8 @@ def build_numba(sys_dict,verbose=False):
1354
1361
  b.template()
1355
1362
  b.compile()
1356
1363
 
1364
+
1365
+
1357
1366
  def build_mkl(sys_dict,verbose=False,platform='Windows'):
1358
1367
  '''
1359
1368
 
@@ -1376,20 +1385,22 @@ def build_mkl(sys_dict,verbose=False,platform='Windows'):
1376
1385
  def test_numba():
1377
1386
 
1378
1387
  from pydae.models.pendulum.dae import dae
1379
- from pydae.build_v2 import builder
1388
+ from pydae.build_v2 import builder,build_numba
1380
1389
 
1381
1390
  sys_dict = dae('temp')
1382
1391
 
1383
- b = builder(sys_dict,verbose=True)
1384
- b.sparse = False
1385
- b.mkl = False
1386
- b.uz_jacs = False
1387
- b.dict2system()
1388
- b.functions()
1389
- b.jacobians()
1390
- b.cwrite()
1391
- b.template()
1392
- b.compile()
1392
+ build_numba(sys_dict,verbose=True)
1393
+
1394
+ # b = builder(sys_dict,verbose=True)
1395
+ # b.sparse = False
1396
+ # b.mkl = False
1397
+ # b.uz_jacs = False
1398
+ # b.dict2system()
1399
+ # b.functions()
1400
+ # b.jacobians()
1401
+ # b.cwrite()
1402
+ # b.template()
1403
+ # b.compile()
1393
1404
 
1394
1405
  import temp
1395
1406
 
@@ -1471,4 +1482,4 @@ def test_mkl():
1471
1482
 
1472
1483
  if __name__ == "__main__":
1473
1484
 
1474
- test_mkl()
1485
+ test_numba()
@@ -0,0 +1,325 @@
1
+ import numpy as np
2
+ import json,hjson
3
+ from pydae.utils import read_data
4
+
5
+
6
+ class Desing:
7
+
8
+ def __init__(self, data):
9
+
10
+ self.data = read_data(data)
11
+ self.z_decimals = 5
12
+ self.lines_impedance_format = 'Z_km' # 'Z_km', 'pu-s', 'Z'
13
+
14
+
15
+ self.S_base = self.data['S_base']
16
+ self.P_inv_max = self.data['P_inv_max']
17
+ self.S_inv_max = self.data['S_inv_max']
18
+ self.U_lv = self.data['U_lv']
19
+ self.U_mv = self.data['U_mv']
20
+ self.U_hv = self.data['U_hv']
21
+ self.F = self.data['F']
22
+ self.M = self.data['M']
23
+ self.N = self.data['N']
24
+ self.S_bess_mva = self.data['S_bess_mva']
25
+ self.S_bess_storage_kWh = self.data['S_bess_storage_kWh']
26
+ self.Irrad_max = self.data['Irrad_max']
27
+ self.Area_form_factor = self.data['Area_form_factor']
28
+ self.PV_efficiency = self.data['PV_efficiency']
29
+ self.Z_trafo_poi_pu = self.data['Z_trafo_poi_pu']
30
+ self.I_mp = data["I_mp"]
31
+ self.V_mp = data["V_mp"]
32
+ self.V_dc_n = data["V_dc_n"]
33
+
34
+ self.cables = [
35
+ {'name': '1X95', 'R_dc_km': 0.320, 'R_ac_km': 0.403, 'X_km': 0.128, 'muC_km': 0.187, 'R_0_km': 1.050, 'X_0_km': 0.391, 'muC_0_km': 0.187, 'I_max_aire': 255, 'I_max_direct': 205, 'I_max_tube': 190, 'I_cc_max': 8930, 'I_cc_0_max': 3140},
36
+ {'name': '1X150', 'R_dc_km': 0.206, 'R_ac_km': 0.262, 'X_km': 0.119, 'muC_km': 0.216, 'R_0_km': 0.890, 'X_0_km': 0.341, 'muC_0_km': 0.216, 'I_max_aire': 335, 'I_max_direct': 260, 'I_max_tube': 245, 'I_cc_max': 14100, 'I_cc_0_max': 3470},
37
+ {'name': '1X240', 'R_dc_km': 0.125, 'R_ac_km': 0.161, 'X_km': 0.109, 'muC_km': 0.260, 'R_0_km': 0.768, 'X_0_km': 0.297, 'muC_0_km': 0.260, 'I_max_aire': 455, 'I_max_direct': 345, 'I_max_tube': 320, 'I_cc_max': 22600, 'I_cc_0_max': 3810},
38
+ {'name': '1X400', 'R_dc_km':0.0778, 'R_ac_km': 0.102, 'X_km': 0.103, 'muC_km': 0.313, 'R_0_km': 0.650, 'X_0_km': 0.237, 'muC_0_km': 0.313, 'I_max_aire': 610, 'I_max_direct': 445, 'I_max_tube': 415, 'I_cc_max': 37600, 'I_cc_0_max': 4300},
39
+ {'name': '1X500', 'R_dc_km':0.0605, 'R_ac_km': 0.084, 'X_km': 0.099, 'muC_km': 0.329, 'R_0_km': 0.618, 'X_0_km': 0.225, 'muC_0_km': 0.329, 'I_max_aire': 715, 'I_max_direct': 505, 'I_max_tube': 480, 'I_cc_max': 47000, 'I_cc_0_max': 4810},
40
+ {'name': '1X630', 'R_dc_km':0.0469, 'R_ac_km':0.0636, 'X_km': 0.095, 'muC_km': 0.396, 'R_0_km': 0.561, 'X_0_km': 0.195, 'muC_0_km': 0.396, 'I_max_aire': 830, 'I_max_direct': 575, 'I_max_tube': 545, 'I_cc_max': 59200, 'I_cc_0_max': 5140}
41
+ ]
42
+
43
+
44
+ def design(self):
45
+
46
+ M = self.M
47
+ N = self.N
48
+ self.S_plant = self.S_inv_max*N*M + 1.2*self.S_bess_mva*1e6
49
+ S_base = self.S_base
50
+
51
+ self.LV_MV_trafo_X_pu = 0.05
52
+ self.LV_MV_trafo_R_pu = 0.01
53
+
54
+ S_trafo_poi = M*N*self.S_inv_max*1.1
55
+
56
+ # Area_inv = Long_n * Long_m
57
+ # Long_n = Area_form_factor * Long_m
58
+ # Area_inv = Area_form_factor * Long_m**2
59
+
60
+ Area_inv = self.P_inv_max/(self.Irrad_max*self.PV_efficiency)
61
+ self.Long_m = np.sqrt( Area_inv/self.Area_form_factor )
62
+ self.Long_n = self.Area_form_factor * self.Long_m
63
+
64
+ S_grid_line = self.S_plant*2.0
65
+
66
+ self.base_data = {
67
+ "system":{"name":f"pv_{M}_{N}","S_base":S_base,"K_p_agc":0.0,"K_i_agc":0.0,"K_xif":0.01},
68
+ "buses":[
69
+ {"name": "POIMV","P_W":0.0,"Q_var":0.0,"U_kV":self.U_mv/1e3},
70
+ {"name": "POI","P_W":0.0,"Q_var":0.0,"U_kV":self.U_hv/1e3},
71
+ {"name": "GRID","P_W":0.0,"Q_var":0.0,"U_kV":self.U_hv/1e3},
72
+ {"name": "BESS","P_W":0.0,"Q_var":0.0,"U_kV":self.U_lv/1e3},
73
+ ],
74
+ "lines":[
75
+ {"bus_j":"POI","bus_k":"GRID","X_pu":0.001*S_base/S_grid_line,"R_pu":0.0,"Bs_pu":0.0,"S_mva":S_base/1e6, 'sym':True, 'monitor':True},
76
+ {"bus_j":"BESS","bus_k": "POIMV","X_pu":0.01,"R_pu":0.0,"Bs_pu":0.0,"S_mva":S_base/1e6, 'sym':True, 'monitor':True},
77
+ ],
78
+ "transformers":[{"bus_j":"POIMV","bus_k": "POI","X_pu":0.1,"R_pu":0.0,"Bs_pu":0.0,"S_mva":self.S_plant/1e6}],
79
+ "pvs":[],
80
+ "sources":[{"type":"genape","bus":"GRID",
81
+ "S_n":1000e6,"F_n":50.0,"X_v":0.001,"R_v":0.0,
82
+ "K_delta":0.001,"K_alpha":1e-6}],
83
+ "vscs":[{"type":"bess_pq","bus":"BESS","E_kWh":self.S_bess_storage_kWh,"S_n":self.S_bess_mva*1e6,
84
+ "soc_ref":0.5,
85
+ "socs":[0.0, 0.1, 0.2, 0.8,0.9,1.0],
86
+ "es":[1, 1.08, 1.13, 1.17, 1.18,1.25]}
87
+ ],
88
+ }
89
+
90
+
91
+ Z_base_trafo_poi = self.U_mv**2/S_trafo_poi
92
+ Z_trafo_poi = Z_base_trafo_poi*self.Z_trafo_poi_pu
93
+ I_cc_max = self.U_mv/(np.sqrt(3)*Z_trafo_poi)
94
+
95
+ for it, item in enumerate(self.cables):
96
+ if item['I_cc_max'] > I_cc_max:
97
+ print(f"Short circuit designed cable ({I_cc_max/1e3:0.2f} kA): {item['name']}")
98
+ idx_cc = it
99
+ break
100
+
101
+ I_max = 1.0*N*self.S_inv_max/(np.sqrt(3)*self.U_mv)
102
+
103
+ for it, item in enumerate(self.cables):
104
+ if item['I_max_tube'] > I_max:
105
+ print(f"Nominal current designed cable ({I_max:0.2f} A): {item['name']}")
106
+ idx_n = it
107
+ break
108
+
109
+ if idx_cc > idx_n:
110
+ idx_cable = idx_cc
111
+ else:
112
+ idx_cable = idx_n
113
+
114
+ print(f"Cable: {self.cables[idx_cable]['name']}")
115
+
116
+ self.section_cable = float(self.cables[idx_cable]['name'].split('X')[-1])
117
+ self.R_km_cable = self.cables[idx_cable]['R_ac_km']
118
+ self.X_km_cable = self.cables[idx_cable]['X_km']
119
+ self.B_km_cable = 2*np.pi*50*self.cables[idx_cable]['muC_km']*1e-6
120
+
121
+
122
+
123
+
124
+ P_mp = self.I_mp*self.V_mp
125
+ N_pv_s = int(self.V_dc_n/self.V_mp)
126
+ N_pv_p = int(self.P_inv_max/(P_mp*N_pv_s))
127
+
128
+ S_feeder = N*self.S_inv_max
129
+ I_feeder = S_feeder/(np.sqrt(3)*self.U_mv)
130
+
131
+ pos_mv_poi_m_pu = 0.0
132
+ pos_mv_poi_m = pos_mv_poi_m_pu * (M-1)*self.Long_m
133
+ pos_mv_poi_n = 0.0
134
+
135
+ for i_m in range(1,M+1):
136
+ name_j = "POIMV"
137
+ monitor = True
138
+ pos_m = (i_m-1) * self.Long_m
139
+
140
+
141
+ for i_n in range(1,N+1):
142
+ name = f"{i_m}".zfill(2) + f"{i_n}".zfill(2)
143
+ name_k = 'MV' + name
144
+
145
+ self.base_data['buses'].append({"name":f"LV{name}","P_W":0.0,"Q_var":0.0,"U_kV":self.U_lv/1e3})
146
+ self.base_data['buses'].append({"name":f"MV{name}","P_W":0.0,"Q_var":0.0,"U_kV":self.U_mv/1e3})
147
+
148
+
149
+ if i_n == 1:
150
+ Long = np.abs(pos_mv_poi_m - pos_m) + self.Long_n*0.5
151
+ else:
152
+ Long = self.Long_n
153
+
154
+ pos_n = (i_n-1) * self.Long_n + self.Long_n/2
155
+ #print(f'pos_m = {pos_m:5.1f}, pos_n = {pos_n:5.1f}')
156
+
157
+ # LV-MV Trafos
158
+ S_trafo_n = 1.2*self.S_inv_max
159
+ X_pu = self.LV_MV_trafo_X_pu*self.S_base/S_trafo_n
160
+ R_pu = self.LV_MV_trafo_R_pu*self.S_base/S_trafo_n
161
+
162
+
163
+
164
+ self.base_data['lines'].append({"bus_j":f"LV{name}","bus_k":f"MV{name}","X_pu":np.round(X_pu,self.z_decimals),"R_pu":np.round(R_pu,self.z_decimals),"Bs_pu":0.0,"S_mva":S_base/1e6,"monitor":False})
165
+
166
+
167
+ # MV Cables:
168
+ S_b = self.S_base
169
+ Z_b = self.U_mv**2/S_b
170
+ R_cable_pu = self.R_km_cable*Long/1e3/Z_b
171
+ X_cable_pu = self.X_km_cable*Long/1e3/Z_b
172
+ B_cable_pu = self.B_km_cable*Long/1e3*Z_b
173
+
174
+ print(f"{name_k} - {name_j}, Cable: {self.cables[idx_cable]['name']}, R_km = {self.R_km_cable:3.4f}, X_km = {self.X_km_cable:3.4f}, B_km = {self.B_km_cable:3.4f}, Long_km = {Long/1000:2.5f}")
175
+
176
+ # LV/MV Transformers
177
+
178
+ # MV Feeders lines
179
+ if self.lines_impedance_format == 'pu-s':
180
+ self.base_data['lines'].append({"bus_j":f"{name_k}","bus_k":f"{name_j}","X_pu":X_cable_pu,"R_pu":R_cable_pu,"Bs_pu":B_cable_pu,"S_mva":S_base/1e6,"monitor":monitor})
181
+
182
+ if self.lines_impedance_format == 'Z_km':
183
+ X_km_cable = np.round(self.X_km_cable,self.z_decimals)
184
+ R_km_cable = np.round(self.R_km_cable,self.z_decimals)
185
+ B_km_cable = np.round(self.B_km_cable,self.z_decimals)
186
+
187
+ self.base_data['lines'].append({"bus_j":f"{name_k}","bus_k":f"{name_j}","X_km": X_km_cable,"R_km": R_km_cable,"Bs_km": B_km_cable,"km":np.round(Long/1e3,4),"monitor":monitor})
188
+
189
+
190
+ name_j = name_k
191
+ self.base_data['pvs'].append({"bus":f"LV{name}","type":"pv_dq_d","S_n":self.S_inv_max,"U_n":self.U_lv,"F_n":50.0,"X_s":0.1,"R_s":0.0001,"monitor":False,
192
+ "I_sc":8,"V_oc":42.1,"I_mp":self.I_mp,"V_mp":self.V_mp,"K_vt":-0.160,"K_it":0.065,"N_pv_s":N_pv_s,"N_pv_p":N_pv_p})
193
+
194
+ monitor = False
195
+
196
+ with open(f'pv_{M}_{N}.json','w') as fobj:
197
+ fobj.write(json.dumps(self.base_data, indent=2))
198
+
199
+ def report(self):
200
+
201
+ M = self.M
202
+ N = self.N
203
+
204
+ latex = r'''
205
+ \begin{table}
206
+ \centering
207
+ \caption{Nominal characteristics of PV inverters and transformers of the benchmark 2$\times$3 PV park.}
208
+ \begin{tabular}{lr}
209
+ \toprule
210
+ \multicolumn{2}{c}{PV inverters} \\ \midrule
211
+ Rated voltage & inverter_rated_voltage V \\ \hline
212
+ Rated power & inverter_rated_mva MVA \\ \hline
213
+ Rated power factor & inverter_pf (ind/cap)\\ \midrule
214
+ \multicolumn{2}{c}{MV/LV PV transformers} \\ \midrule
215
+ Rated voltages & U_mv_kV/U_lv_kV kV \\ \hline
216
+ Rated power & MV_LV_rated_mva MVA \\ \hline
217
+ Short-circuit impedance & 0.06 p.u. \\ \hline
218
+ $X_{sc}/R_{sc}$ & 10 \\ \midrule
219
+ \multicolumn{2}{c}{HV/MV POI transformer} \\ \midrule
220
+ Rated voltages & U_hv_kV/U_mv_kV kV \\ \hline
221
+ Rated power & poi_trafo_rated_power MVA \\ \hline
222
+ Short-circuit impedance & 0.13 p.u. \\ \hline
223
+ $X_{sc}/R_{sc}$ & 10\\ \midrule
224
+ \multicolumn{2}{c}{MV branches} \\
225
+ \midrule
226
+ first_feeder_segment_string
227
+ Length MV\#\# - MV\#\# & length_segments m \\ \hline
228
+ Cross section & section_cable mm$^2$\\ \hline
229
+ Resistance & R_km_cable $\Omega$/km \\ \hline
230
+ Reactance & X_km_cable $\Omega$/km \\ %\hline
231
+ % Susceptance & B_km_cable S/km \\
232
+ \bottomrule
233
+ \end{tabular}
234
+ \label{tab:PV_MxN}
235
+ \end{table}
236
+ '''
237
+
238
+ latex = latex.replace('inverter_rated_voltage', f'{self.U_lv:0.0f}')
239
+ latex = latex.replace('inverter_rated_mva', f'{self.S_inv_max/1e6:0.1f}')
240
+ latex = latex.replace('inverter_pf', f'{self.P_inv_max/self.S_inv_max:0.2f}')
241
+ latex = latex.replace('U_mv_kV', f'{self.U_mv/1e3:0.0f}').replace('U_lv_kV', f'{self.U_lv/1e3}')
242
+ latex = latex.replace('inverter_pf', f'{self.P_inv_max/self.S_inv_max:0.2f}')
243
+ latex = latex.replace('U_mv_kV', f'{self.U_mv/1e3:0.0f}').replace('U_hv_kV', f'{self.U_hv/1e3:0.0f}')
244
+ latex = latex.replace('poi_trafo_rated_power', f'{self.S_plant/1e6:0.0f}')
245
+
246
+
247
+ pos_mv_poi_m_pu = 0.0
248
+ pos_mv_poi_m = pos_mv_poi_m_pu * (M-1)*self.Long_m
249
+ pos_mv_poi_n = 0.0
250
+
251
+ first_feeder_segment_string = ''
252
+ for i_m in range(1,M+1):
253
+ name_j = "POIMV"
254
+ monitor = True
255
+ pos_m = (i_m-1) * self.Long_m
256
+
257
+
258
+ for i_n in range(1,N+1):
259
+ name = f"{i_m}".zfill(2) + f"{i_n}".zfill(2)
260
+ name_k = 'MV' + name
261
+
262
+ self.base_data['buses'].append({"name":f"LV{name}","P_W":0.0,"Q_var":0.0,"U_kV":self.U_lv/1e3})
263
+ self.base_data['buses'].append({"name":f"MV{name}","P_W":0.0,"Q_var":0.0,"U_kV":self.U_mv/1e3})
264
+
265
+
266
+ if i_n == 1:
267
+ Long = np.abs(pos_mv_poi_m - pos_m) + self.Long_n*0.5
268
+ else:
269
+ Long = self.Long_n
270
+
271
+ if i_n == 1:
272
+ first_feeder_segment_string += f' Length {name_k}-{name_j} & {Long:0.0f} m' + r'\\ \hline'
273
+ if i_m < M:
274
+ first_feeder_segment_string += '\n'
275
+ else:
276
+ self.length_segments = Long
277
+
278
+ latex = latex.replace('first_feeder_segment_string', first_feeder_segment_string)
279
+ latex = latex.replace('length_segments', f'{self.length_segments:0.0f}')
280
+
281
+ latex = latex.replace('length_segments', f'{self.length_segments:0.0f}')
282
+ latex = latex.replace('R_km_cable', f'{self.R_km_cable:0.4f}')
283
+ latex = latex.replace('X_km_cable', f'{self.X_km_cable:0.4f}')
284
+
285
+ if self.B_km_cable > 0.001:
286
+ latex = latex.replace('B_km_cable', f'{self.B_km_cable:0.4f}')
287
+ else:
288
+ latex = latex.replace('B_km_cable', '0')
289
+
290
+ latex = latex.replace('section_cable', f'{self.section_cable:0.0f}')
291
+ latex = latex.replace('PV_MxN', f'PV_{M}x{N}')
292
+
293
+ return latex
294
+
295
+
296
+ if __name__ == "__main__":
297
+
298
+ data = {
299
+ "M": 2,
300
+ "N": 3,
301
+ "S_base": 10e6,
302
+ "P_inv_max": 3e6, # W
303
+ "S_inv_max": 3e6/0.85,
304
+ "U_lv": 800,
305
+ "U_mv": 20e3,
306
+ "U_hv": 132e3,
307
+ "F": 50, #Nominal Frequency (Hz)
308
+ "S_bess_mva": 1,
309
+ "S_bess_storage_kWh": 250,
310
+ "Irrad_max": 1000, # W/m_2
311
+ "Area_form_factor": 1.0,
312
+ "PV_efficiency": 0.1,
313
+ "Z_trafo_poi_pu": 0.1,
314
+ "I_mp" : 3.56, # PV module current at MP
315
+ "V_mp" : 33.7, # PV module voltage at MP
316
+ "V_dc_n" : 1200 # DC nominal voltage
317
+ }
318
+
319
+ d = Desing(data)
320
+ d.design()
321
+ print(d.report())
322
+
323
+ #print(d.base_data)
324
+
325
+
@@ -0,0 +1,106 @@
1
+ ### GET measures. Devuelve todas las medidas del POI y de los inversores
2
+ GET http://127.100.0.1:8000/measurements
3
+ Content-Type: application/json
4
+
5
+ ### GET measures. Devuelve todas las medidas del POI y de los inversores
6
+ GET http://10.20.0.2:5500/ppc_measurements
7
+ Content-Type: application/json
8
+
9
+ ### GET measures. Devuelve todas las medidas del POI y de los inversores
10
+ GET http://10.20.0.4:5500/ppc_measurements
11
+ Content-Type: application/json
12
+
13
+
14
+ ### POST setpoints. POST request to change PPC references.
15
+ POST http://127.0.0.1:5500/ppc_setpoints
16
+ Content-Type: application/json
17
+
18
+ {
19
+ "p_ol_ref":0.0,
20
+ "q_ol_ref":0.0,
21
+ "p_s_ref_BESS":0.0
22
+ }
23
+
24
+
25
+
26
+ ### POST false measurement liner transformations parameters .
27
+ POST http://127.100.0.1:8000/meas_pert
28
+ Content-Type: application/json
29
+
30
+ {
31
+ "U_SS1":{"m":0.5,"b":0}
32
+ }
33
+
34
+
35
+
36
+ ### POST setpoints. POST request to change active and reactive power references at POI.
37
+ POST http://10.20.0.2:8000/setpoints
38
+ Content-Type: application/json
39
+
40
+ {
41
+ "p_ol_ref":0.5,
42
+ "q_ol_ref":0.5,
43
+ "p_s_ref_BESS":0.0
44
+ }
45
+
46
+
47
+ ### POST setpoints. POST request to change active and reactive power references at POI.
48
+ POST http://10.20.0.2:8000/setpoints
49
+ Content-Type: application/json
50
+
51
+ {
52
+ "p_s_ppc_LV0101":1.5e6,
53
+ "p_s_ppc_LV0102":01.5e6,
54
+ "p_s_ref_BESS":0.0
55
+ }
56
+
57
+
58
+
59
+
60
+ ### POST setpoints. POST request to change PPC references.
61
+ POST http://127.0.0.1:5500/ppc_setpoints
62
+ Content-Type: application/json
63
+
64
+ {
65
+ "record":true
66
+ }
67
+
68
+
69
+
70
+ ### POST setpoints. POST request to change PPC references.
71
+ POST http://127.0.0.1:5500/ppc_setpoints
72
+ Content-Type: application/json
73
+
74
+ {
75
+ "P_POI_ref":0.5,
76
+ "Q_POI_ref":-0.9
77
+ }
78
+
79
+ ### POST setpoints. POST request to change PPC references.
80
+ POST http://127.0.0.1:5500/ppc_setpoints
81
+ Content-Type: application/json
82
+
83
+ {
84
+ "record":false
85
+ }
86
+
87
+
88
+ ### POST setpoints. POST request to change PPC references.
89
+ POST http://127.0.0.1:5500/ppc_setpoints
90
+ Content-Type: application/json
91
+
92
+ {
93
+ "stop_ppc":true
94
+ }
95
+
96
+
97
+ ### POST setpoints. POST request to change PPC references.
98
+ POST http://127.0.0.1:5500/ppc_params
99
+ Content-Type: application/json
100
+
101
+ {
102
+ "K_pp":0.5,
103
+ "K_pi":5.0,
104
+ "K_qp":0.5,
105
+ "K_qi":5.0
106
+ }
@@ -0,0 +1,107 @@
1
+ import numpy as np
2
+ import sympy as sym
3
+
4
+
5
+ def dae(model_name):
6
+ L,G,M,K_d = sym.symbols('L,G,M,K_d', real=True)
7
+ p_x,p_y,v_x,v_y = sym.symbols('p_x,p_y,v_x,v_y', real=True)
8
+ lam,f_x,theta,u_dummy = sym.symbols('lam,f_x,theta,u_dummy', real=True)
9
+
10
+ dp_x = v_x
11
+ dp_y = v_y
12
+ dv_x = (-2*p_x*lam + f_x - K_d*v_x)/M
13
+ dv_y = (-M*G - 2*p_y*lam - K_d*v_y)/M
14
+
15
+ g_1 = p_x**2 + p_y**2 - L**2 -lam*1e-6
16
+ g_2 = -theta + sym.atan2(p_x,-p_y) + u_dummy
17
+
18
+ params_dict = {'L':5.21,'G':9.81,'M':10.0,'K_d':1e-3} # parameters with default values
19
+
20
+ u_ini_dict = {'theta':np.deg2rad(5.0),'u_dummy':0.0} # input for the initialization problem
21
+ u_run_dict = {'f_x':0,'u_dummy':0.0} # input for the running problem, its value is updated
22
+
23
+ sys_dict = {'name':model_name,
24
+ 'params_dict':params_dict,
25
+ 'f_list':[dp_x,dp_y,dv_x,dv_y],
26
+ 'g_list':[g_1,g_2],
27
+ 'x_list':[ p_x, p_y, v_x, v_y],
28
+ 'y_ini_list':[lam,f_x],
29
+ 'y_run_list':[lam,theta],
30
+ 'u_ini_dict':u_ini_dict,
31
+ 'u_run_dict':u_run_dict,
32
+ 'h_dict':{'E_p':M*G*(p_y+L),'E_k':0.5*M*(v_x**2+v_y**2),
33
+ 'theta':theta,'f_x':f_x,'lam':lam},
34
+ 'xy_0':{'theta':sym.atan2(p_x,-p_y)}}
35
+
36
+ return sys_dict
37
+
38
+
39
+ def test_build():
40
+ import pydae.build_v2 as db
41
+ sys_dict = dae('temp')
42
+
43
+
44
+ b = db.builder(sys_dict,verbose=True,API=True)
45
+ b.sparse = False
46
+ b.mkl = False
47
+ b.platform = 'Windows'
48
+ b.dict2system()
49
+ b.functions()
50
+ b.jacobians()
51
+ b.cwrite()
52
+ b.template()
53
+ b.compile()
54
+
55
+
56
+ def test_ini():
57
+
58
+ import temp
59
+
60
+ model = temp.model()
61
+
62
+ M = 30.0 # mass of the bob (kg)
63
+ L = 5.21 # length of the pendulum (m)
64
+ model.ini({'M':M,'L':L, # parameters setting
65
+ 'theta':np.deg2rad(0) # initial desired angle = 0º
66
+ },-1) # here -1 means that -1 is considered as initial gess for
67
+ # dynamic and algebraic states
68
+
69
+ model.report_x() # obtained dynamic states
70
+ model.report_y() # obtained algebraic states
71
+ model.report_z() # obtained outputs
72
+ model.report_u() # obtained algebraic states (theta is both state and output; f_x is both input and output)
73
+ model.report_params() # considered parameters
74
+
75
+ def test_api():
76
+
77
+ import temp
78
+
79
+ model = temp.model()
80
+
81
+ M = 30.0 # mass of the bob (kg)
82
+ L = 5.21 # length of the pendulum (m)
83
+ model.ini({'M':M,'L':L, # parameters setting
84
+ 'theta':np.deg2rad(5) # initial desired angle = 0º
85
+ },-1) # here -1 means that -1 is considered as initial gess for
86
+ # dynamic and algebraic states
87
+
88
+ model.report_x() # obtained dynamic states
89
+ model.report_y() # obtained algebraic states
90
+ model.report_z() # obtained outputs
91
+ model.report_u() # obtained algebraic states (theta is both state and output; f_x is both input and output)
92
+ model.report_params() # considered parameters
93
+
94
+
95
+ # model.run(1.0,{})
96
+ model.run_api()
97
+ #model.step(0.000000001,{})
98
+
99
+ if __name__ == '__main__':
100
+
101
+ test_build()
102
+ test_ini()
103
+ test_api()
104
+
105
+
106
+
107
+