pydae 0.56.5__py3-none-any.whl → 0.57.1__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,1823 @@
1
+ import numpy as np
2
+ import numba
3
+ import scipy.optimize as sopt
4
+ import scipy.sparse as sspa
5
+ from scipy.sparse.linalg import spsolve,spilu,splu
6
+ from numba import cuda
7
+ import cffi
8
+ import numba.core.typing.cffi_utils as cffi_support
9
+ from io import BytesIO
10
+ import pkgutil
11
+
12
+ dae_file_mode = 'local'
13
+
14
+ ffi = cffi.FFI()
15
+
16
+ if dae_file_mode == 'local':
17
+ import temp_ini_cffi as jacs_ini
18
+ import temp_run_cffi as jacs_run
19
+ import temp_trap_cffi as jacs_trap
20
+
21
+ if dae_file_mode == 'enviroment':
22
+ import envus.no_enviroment.temp_cffi as jacs
23
+ if dae_file_mode == 'colab':
24
+ import temp_cffi as jacs
25
+
26
+ cffi_support.register_module(jacs_ini)
27
+ cffi_support.register_module(jacs_run)
28
+ cffi_support.register_module(jacs_trap)
29
+
30
+ f_ini_eval = jacs_ini.lib.f_ini_eval
31
+ g_ini_eval = jacs_ini.lib.g_ini_eval
32
+ f_run_eval = jacs_run.lib.f_run_eval
33
+ g_run_eval = jacs_run.lib.g_run_eval
34
+ h_eval = jacs_ini.lib.h_eval
35
+
36
+ sparse = False
37
+
38
+ de_jac_ini_xy_eval = jacs_ini.lib.de_jac_ini_xy_eval
39
+ de_jac_ini_up_eval = jacs_ini.lib.de_jac_ini_up_eval
40
+ de_jac_ini_num_eval = jacs_ini.lib.de_jac_ini_num_eval
41
+
42
+ if sparse:
43
+ sp_jac_ini_xy_eval = jacs.lib.sp_jac_ini_xy_eval
44
+ sp_jac_ini_up_eval = jacs.lib.sp_jac_ini_up_eval
45
+ sp_jac_ini_num_eval = jacs.lib.sp_jac_ini_num_eval
46
+
47
+ de_jac_run_xy_eval = jacs_run.lib.de_jac_run_xy_eval
48
+ de_jac_run_up_eval = jacs_run.lib.de_jac_run_up_eval
49
+ de_jac_run_num_eval = jacs_run.lib.de_jac_run_num_eval
50
+
51
+ if sparse:
52
+ sp_jac_run_xy_eval = jacs.lib.sp_jac_run_xy_eval
53
+ sp_jac_run_up_eval = jacs.lib.sp_jac_run_up_eval
54
+ sp_jac_run_num_eval = jacs.lib.sp_jac_run_num_eval
55
+
56
+ de_jac_trap_xy_eval= jacs_trap.lib.de_jac_trap_xy_eval
57
+ de_jac_trap_up_eval= jacs_trap.lib.de_jac_trap_up_eval
58
+ de_jac_trap_num_eval= jacs_trap.lib.de_jac_trap_num_eval
59
+
60
+ if sparse:
61
+ sp_jac_trap_xy_eval= jacs.lib.sp_jac_trap_xy_eval
62
+ sp_jac_trap_up_eval= jacs.lib.sp_jac_trap_up_eval
63
+ sp_jac_trap_num_eval= jacs.lib.sp_jac_trap_num_eval
64
+
65
+
66
+
67
+
68
+
69
+ import json
70
+
71
+ sin = np.sin
72
+ cos = np.cos
73
+ atan2 = np.arctan2
74
+ sqrt = np.sqrt
75
+ sign = np.sign
76
+ exp = np.exp
77
+
78
+
79
+ class model:
80
+
81
+ def __init__(self):
82
+
83
+ self.matrices_folder = 'build'
84
+ self.sparse = False
85
+ self.dae_file_mode = 'local'
86
+ self.t_end = 10.000000
87
+ self.Dt = 0.0010000
88
+ self.decimation = 10.000000
89
+ self.itol = 1e-6
90
+ self.Dt_max = 0.001000
91
+ self.Dt_min = 0.001000
92
+ self.solvern = 5
93
+ self.imax = 100
94
+ self.N_x = 2
95
+ self.N_y = 10
96
+ self.N_z = 9
97
+ self.N_store = 100000
98
+ self.params_list = ['S_base', 'g_1_2', 'b_1_2', 'bs_1_2', 'U_1_n', 'U_2_n', 'K_p_agc', 'K_i_agc', 'K_xif']
99
+ self.params_values_list = [100000000.0, 48.86242680554943, -504.3040020304095, 161.56799999999998, 400000.0, 400000.0, 0.01, 0.01, 0.01]
100
+ self.inputs_ini_list = ['P_1', 'Q_1', 'P_2', 'Q_2', 'v_ref_1', 'theta_ref_1']
101
+ self.inputs_ini_values_list = [0.0, 0.0, 5000000000.0, 0.0, 1.0, 0.0]
102
+ self.inputs_run_list = ['P_1', 'Q_1', 'P_2', 'Q_2', 'v_ref_1', 'theta_ref_1']
103
+ self.inputs_run_values_list = [0.0, 0.0, 5000000000.0, 0.0, 1.0, 0.0]
104
+ self.outputs_list = ['p_line_1_2', 'q_line_1_2', 'p_line_2_1', 'q_line_2_1', 'I_line_1_2', 'I_line_2_1', 'V_1', 'V_2', 'V_dummy_1']
105
+ self.x_list = ['V_dummy_1', 'xi_freq']
106
+ self.y_run_list = ['V_1', 'theta_1', 'V_2', 'theta_2', 'omega_coi', 'p_line_pu_1_2', 'q_line_pu_1_2', 'p_line_pu_2_1', 'q_line_pu_2_1', 'p_agc']
107
+ self.xy_list = self.x_list + self.y_run_list
108
+ self.y_ini_list = ['V_1', 'theta_1', 'V_2', 'theta_2', 'omega_coi', 'p_line_pu_1_2', 'q_line_pu_1_2', 'p_line_pu_2_1', 'q_line_pu_2_1', 'p_agc']
109
+ self.xy_ini_list = self.x_list + self.y_ini_list
110
+ self.t = 0.0
111
+ self.it = 0
112
+ self.it_store = 0
113
+ self.xy_prev = np.zeros((self.N_x+self.N_y,1))
114
+ self.initialization_tol = 1e-6
115
+ self.N_u = len(self.inputs_run_list)
116
+ self.sopt_root_method='hybr'
117
+ self.sopt_root_jac=True
118
+ self.u_ini_list = self.inputs_ini_list
119
+ self.u_ini_values_list = self.inputs_ini_values_list
120
+ self.u_run_list = self.inputs_run_list
121
+ self.u_run_values_list = self.inputs_run_values_list
122
+ self.N_u = len(self.u_run_list)
123
+ self.u_ini = np.array(self.inputs_ini_values_list, dtype=np.float64)
124
+ self.p = np.array(self.params_values_list, dtype=np.float64)
125
+ self.xy_0 = np.zeros((self.N_x+self.N_y,),dtype=np.float64)
126
+ self.xy = np.zeros((self.N_x+self.N_y,),dtype=np.float64)
127
+ self.z = np.zeros((self.N_z,),dtype=np.float64)
128
+
129
+ # numerical elements of jacobians computing:
130
+ x = self.xy[:self.N_x]
131
+ y = self.xy[self.N_x:]
132
+
133
+ self.yini2urun = list(set(self.u_run_list).intersection(set(self.y_ini_list)))
134
+ self.uini2yrun = list(set(self.y_run_list).intersection(set(self.u_ini_list)))
135
+ self.Time = np.zeros(self.N_store)
136
+ self.X = np.zeros((self.N_store,self.N_x))
137
+ self.Y = np.zeros((self.N_store,self.N_y))
138
+ self.Z = np.zeros((self.N_store,self.N_z))
139
+ self.iters = np.zeros(self.N_store)
140
+ self.u_run = np.array(self.u_run_values_list,dtype=np.float64)
141
+
142
+ ## jac_ini
143
+ self.jac_ini = np.zeros((self.N_x+self.N_y,self.N_x+self.N_y))
144
+ if self.sparse:
145
+ self.sp_jac_ini_ia, self.sp_jac_ini_ja, self.sp_jac_ini_nia, self.sp_jac_ini_nja = sp_jac_ini_vectors()
146
+ data = np.array(self.sp_jac_ini_ia,dtype=np.float64)
147
+ #self.sp_jac_ini = sspa.csr_matrix((data, self.sp_jac_ini_ia, self.sp_jac_ini_ja), shape=(self.sp_jac_ini_nia,self.sp_jac_ini_nja))
148
+
149
+ if self.dae_file_mode == 'enviroment':
150
+ fobj = BytesIO(pkgutil.get_data(__name__, f'./temp_sp_jac_ini_num.npz'))
151
+ self.sp_jac_ini = sspa.load_npz(fobj)
152
+ else:
153
+ self.sp_jac_ini = sspa.load_npz(f'./{self.matrices_folder}/temp_sp_jac_ini_num.npz')
154
+
155
+
156
+ self.jac_ini = self.sp_jac_ini.toarray()
157
+
158
+ #self.J_ini_d = np.array(self.sp_jac_ini_ia)*0.0
159
+ #self.J_ini_i = np.array(self.sp_jac_ini_ia)
160
+ #self.J_ini_p = np.array(self.sp_jac_ini_ja)
161
+ de_jac_ini_eval(self.jac_ini,x,y,self.u_ini,self.p,self.Dt)
162
+ if self.sparse:
163
+ sp_jac_ini_eval(self.sp_jac_ini.data,x,y,self.u_ini,self.p,self.Dt)
164
+ self.fill_factor_ini,self.drop_tol_ini,self.drop_rule_ini = 100,1e-10,'basic'
165
+
166
+
167
+ ## jac_run
168
+ self.jac_run = np.zeros((self.N_x+self.N_y,self.N_x+self.N_y))
169
+ if self.sparse:
170
+ self.sp_jac_run_ia, self.sp_jac_run_ja, self.sp_jac_run_nia, self.sp_jac_run_nja = sp_jac_run_vectors()
171
+ data = np.array(self.sp_jac_run_ia,dtype=np.float64)
172
+
173
+ if self.dae_file_mode == 'enviroment':
174
+ fobj = BytesIO(pkgutil.get_data(__name__, './temp_sp_jac_run_num.npz'))
175
+ self.sp_jac_run = sspa.load_npz(fobj)
176
+ else:
177
+ self.sp_jac_run = sspa.load_npz(f'./{self.matrices_folder}/temp_sp_jac_run_num.npz')
178
+ self.jac_run = self.sp_jac_run.toarray()
179
+
180
+ if self.sparse:
181
+ self.J_run_d = np.array(self.sp_jac_run_ia)*0.0
182
+ self.J_run_i = np.array(self.sp_jac_run_ia)
183
+ self.J_run_p = np.array(self.sp_jac_run_ja)
184
+ de_jac_run_eval(self.jac_run,x,y,self.u_run,self.p,self.Dt)
185
+
186
+ if self.sparse:
187
+ sp_jac_run_eval(self.J_run_d,x,y,self.u_run,self.p,self.Dt)
188
+
189
+ ## jac_trap
190
+ self.jac_trap = np.zeros((self.N_x+self.N_y,self.N_x+self.N_y))
191
+
192
+ if self.sparse:
193
+
194
+ self.sp_jac_trap_ia, self.sp_jac_trap_ja, self.sp_jac_trap_nia, self.sp_jac_trap_nja = sp_jac_trap_vectors()
195
+ data = np.array(self.sp_jac_trap_ia,dtype=np.float64)
196
+ #self.sp_jac_trap = sspa.csr_matrix((data, self.sp_jac_trap_ia, self.sp_jac_trap_ja), shape=(self.sp_jac_trap_nia,self.sp_jac_trap_nja))
197
+
198
+
199
+
200
+ if self.dae_file_mode == 'enviroment':
201
+ fobj = BytesIO(pkgutil.get_data(__name__, './temp_sp_jac_trap_num.npz'))
202
+ self.sp_jac_trap = sspa.load_npz(fobj)
203
+ else:
204
+ self.sp_jac_trap = sspa.load_npz(f'./{self.matrices_folder}/temp_sp_jac_trap_num.npz')
205
+
206
+
207
+ self.jac_trap = self.sp_jac_trap.toarray()
208
+
209
+ #self.J_trap_d = np.array(self.sp_jac_trap_ia)*0.0
210
+ #self.J_trap_i = np.array(self.sp_jac_trap_ia)
211
+ #self.J_trap_p = np.array(self.sp_jac_trap_ja)
212
+ de_jac_trap_eval(self.jac_trap,x,y,self.u_run,self.p,self.Dt)
213
+ if self.sparse:
214
+ sp_jac_trap_eval(self.sp_jac_trap.data,x,y,self.u_run,self.p,self.Dt)
215
+ self.fill_factor_trap,self.drop_tol_trap,self.drop_rule_trap = 100,1e-10,'basic'
216
+
217
+
218
+
219
+
220
+
221
+ self.max_it,self.itol,self.store = 50,1e-8,1
222
+ self.lmax_it,self.ltol,self.ldamp= 50,1e-8,1.0
223
+ self.mode = 0
224
+
225
+ self.lmax_it_ini,self.ltol_ini,self.ldamp_ini=50,1e-8,1.0
226
+
227
+ #self.sp_Fu_run = sspa.load_npz(f'./{self.matrices_folder}/temp_Fu_run_num.npz')
228
+ #self.sp_Gu_run = sspa.load_npz(f'./{self.matrices_folder}/temp_Gu_run_num.npz')
229
+ #self.sp_Hx_run = sspa.load_npz(f'./{self.matrices_folder}/temp_Hx_run_num.npz')
230
+ #self.sp_Hy_run = sspa.load_npz(f'./{self.matrices_folder}/temp_Hy_run_num.npz')
231
+ #self.sp_Hu_run = sspa.load_npz(f'./{self.matrices_folder}/temp_Hu_run_num.npz')
232
+
233
+ self.ss_solver = 2
234
+ self.lsolver = 2
235
+
236
+
237
+
238
+
239
+
240
+
241
+ def update(self):
242
+
243
+ self.Time = np.zeros(self.N_store)
244
+ self.X = np.zeros((self.N_store,self.N_x))
245
+ self.Y = np.zeros((self.N_store,self.N_y))
246
+ self.Z = np.zeros((self.N_store,self.N_z))
247
+ self.iters = np.zeros(self.N_store)
248
+
249
+ def ss_ini(self):
250
+
251
+ xy_ini,it = sstate(self.xy_0,self.u_ini,self.p,self.jac_ini,self.N_x,self.N_y)
252
+ self.xy_ini = xy_ini
253
+ self.N_iters = it
254
+
255
+ return xy_ini
256
+
257
+ # def ini(self,up_dict,xy_0={}):
258
+
259
+ # for item in up_dict:
260
+ # self.set_value(item,up_dict[item])
261
+
262
+ # self.xy_ini = self.ss_ini()
263
+ # self.ini2run()
264
+ # jac_run_ss_eval_xy(self.jac_run,self.x,self.y_run,self.u_run,self.p)
265
+ # jac_run_ss_eval_up(self.jac_run,self.x,self.y_run,self.u_run,self.p)
266
+
267
+ def jac_run_eval(self):
268
+ de_jac_run_eval(self.jac_run,self.x,self.y_run,self.u_run,self.p,self.Dt)
269
+
270
+
271
+ def run(self,t_end,up_dict):
272
+ for item in up_dict:
273
+ self.set_value(item,up_dict[item])
274
+
275
+ t = self.t
276
+ p = self.p
277
+ it = self.it
278
+ it_store = self.it_store
279
+ xy = self.xy
280
+ u = self.u_run
281
+ z = self.z
282
+
283
+ t,it,it_store,xy = daesolver(t,t_end,it,it_store,xy,u,p,z,
284
+ self.jac_trap,
285
+ self.Time,
286
+ self.X,
287
+ self.Y,
288
+ self.Z,
289
+ self.iters,
290
+ self.Dt,
291
+ self.N_x,
292
+ self.N_y,
293
+ self.N_z,
294
+ self.decimation,
295
+ max_it=self.max_it,itol=self.itol,store=self.store)
296
+
297
+ self.t = t
298
+ self.it = it
299
+ self.it_store = it_store
300
+ self.xy = xy
301
+ self.z = z
302
+
303
+ def runsp(self,t_end,up_dict):
304
+ for item in up_dict:
305
+ self.set_value(item,up_dict[item])
306
+
307
+ t = self.t
308
+ p = self.p
309
+ it = self.it
310
+ it_store = self.it_store
311
+ xy = self.xy
312
+ u = self.u_run
313
+
314
+ t,it,it_store,xy = daesolver_sp(t,t_end,it,it_store,xy,u,p,
315
+ self.sp_jac_trap,
316
+ self.Time,
317
+ self.X,
318
+ self.Y,
319
+ self.Z,
320
+ self.iters,
321
+ self.Dt,
322
+ self.N_x,
323
+ self.N_y,
324
+ self.N_z,
325
+ self.decimation,
326
+ max_it=50,itol=1e-8,store=1)
327
+
328
+ self.t = t
329
+ self.it = it
330
+ self.it_store = it_store
331
+ self.xy = xy
332
+
333
+ def post(self):
334
+
335
+ self.Time = self.Time[:self.it_store]
336
+ self.X = self.X[:self.it_store]
337
+ self.Y = self.Y[:self.it_store]
338
+ self.Z = self.Z[:self.it_store]
339
+
340
+ def ini2run(self):
341
+
342
+ ## y_ini to y_run
343
+ self.y_ini = self.xy_ini[self.N_x:]
344
+ self.y_run = np.copy(self.y_ini)
345
+
346
+ ## y_ini to u_run
347
+ for item in self.yini2urun:
348
+ self.u_run[self.u_run_list.index(item)] = self.y_ini[self.y_ini_list.index(item)]
349
+
350
+ ## u_ini to y_run
351
+ for item in self.uini2yrun:
352
+ self.y_run[self.y_run_list.index(item)] = self.u_ini[self.u_ini_list.index(item)]
353
+
354
+
355
+ self.x = self.xy_ini[:self.N_x]
356
+ self.xy[:self.N_x] = self.x
357
+ self.xy[self.N_x:] = self.y_run
358
+ c_h_eval(self.z,self.x,self.y_run,self.u_run,self.p,self.Dt)
359
+
360
+
361
+
362
+ def get_value(self,name):
363
+
364
+ if name in self.inputs_run_list:
365
+ value = self.u_run[self.inputs_run_list.index(name)]
366
+ return value
367
+
368
+ if name in self.x_list:
369
+ idx = self.x_list.index(name)
370
+ value = self.xy[idx]
371
+ return value
372
+
373
+ if name in self.y_run_list:
374
+ idy = self.y_run_list.index(name)
375
+ value = self.xy[self.N_x+idy]
376
+ return value
377
+
378
+ if name in self.params_list:
379
+ idp = self.params_list.index(name)
380
+ value = self.p[idp]
381
+ return value
382
+
383
+ if name in self.outputs_list:
384
+ idz = self.outputs_list.index(name)
385
+ value = self.z[idz]
386
+ return value
387
+
388
+ def get_values(self,name):
389
+ if name in self.x_list:
390
+ values = self.X[:,self.x_list.index(name)]
391
+ if name in self.y_run_list:
392
+ values = self.Y[:,self.y_run_list.index(name)]
393
+ if name in self.outputs_list:
394
+ values = self.Z[:,self.outputs_list.index(name)]
395
+
396
+ return values
397
+
398
+ def get_mvalue(self,names):
399
+ '''
400
+
401
+ Parameters
402
+ ----------
403
+ names : list
404
+ list of variables names to return each value.
405
+
406
+ Returns
407
+ -------
408
+ mvalue : TYPE
409
+ list of value of each variable.
410
+
411
+ '''
412
+ mvalue = []
413
+ for name in names:
414
+ mvalue += [self.get_value(name)]
415
+
416
+ return mvalue
417
+
418
+ def set_value(self,name_,value):
419
+ if name_ in self.inputs_ini_list or name_ in self.inputs_run_list:
420
+ if name_ in self.inputs_ini_list:
421
+ self.u_ini[self.inputs_ini_list.index(name_)] = value
422
+ if name_ in self.inputs_run_list:
423
+ self.u_run[self.inputs_run_list.index(name_)] = value
424
+ return
425
+ elif name_ in self.params_list:
426
+ self.p[self.params_list.index(name_)] = value
427
+ return
428
+ else:
429
+ print(f'Input or parameter {name_} not found.')
430
+
431
+ def report_x(self,value_format='5.2f'):
432
+ for item in self.x_list:
433
+ print(f'{item:5s} = {self.get_value(item):{value_format}}')
434
+
435
+ def report_y(self,value_format='5.2f'):
436
+ for item in self.y_run_list:
437
+ print(f'{item:5s} = {self.get_value(item):{value_format}}')
438
+
439
+ def report_u(self,value_format='5.2f'):
440
+ for item in self.inputs_run_list:
441
+ print(f'{item:5s} ={self.get_value(item):{value_format}}')
442
+
443
+ def report_z(self,value_format='5.2f'):
444
+ for item in self.outputs_list:
445
+ print(f'{item:5s} = {self.get_value(item):{value_format}}')
446
+
447
+ def report_params(self,value_format='5.2f'):
448
+ for item in self.params_list:
449
+ print(f'{item:5s} ={self.get_value(item):{value_format}}')
450
+
451
+ def ini(self,up_dict,xy_0={}):
452
+ '''
453
+ Find the steady state of the initialization problem:
454
+
455
+ 0 = f(x,y,u,p)
456
+ 0 = g(x,y,u,p)
457
+
458
+ Parameters
459
+ ----------
460
+ up_dict : dict
461
+ dictionary with all the parameters p and inputs u new values.
462
+ xy_0: if scalar, all the x and y values initial guess are set to the scalar.
463
+ if dict, the initial guesses are applied for the x and y that are in the dictionary
464
+ if string, the initial guess considers a json file with the x and y names and their initial values
465
+
466
+ Returns
467
+ -------
468
+ mvalue : TYPE
469
+ list of value of each variable.
470
+
471
+ '''
472
+
473
+ self.it = 0
474
+ self.it_store = 0
475
+ self.t = 0.0
476
+
477
+ for item in up_dict:
478
+ self.set_value(item,up_dict[item])
479
+
480
+ if type(xy_0) == dict:
481
+ xy_0_dict = xy_0
482
+ self.dict2xy0(xy_0_dict)
483
+
484
+ if type(xy_0) == str:
485
+ if xy_0 == 'eval':
486
+ N_x = self.N_x
487
+ self.xy_0_new = np.copy(self.xy_0)*0
488
+ xy0_eval(self.xy_0_new[:N_x],self.xy_0_new[N_x:],self.u_ini,self.p)
489
+ self.xy_0_evaluated = np.copy(self.xy_0_new)
490
+ self.xy_0 = np.copy(self.xy_0_new)
491
+ else:
492
+ self.load_xy_0(file_name = xy_0)
493
+
494
+ if type(xy_0) == float or type(xy_0) == int:
495
+ self.xy_0 = np.ones(self.N_x+self.N_y,dtype=np.float64)*xy_0
496
+
497
+ xy_ini,it = sstate(self.xy_0,self.u_ini,self.p,
498
+ self.jac_ini,
499
+ self.N_x,self.N_y,
500
+ max_it=self.max_it,tol=self.itol)
501
+
502
+ if it < self.max_it-1:
503
+
504
+ self.xy_ini = xy_ini
505
+ self.N_iters = it
506
+
507
+ self.ini2run()
508
+
509
+ self.ini_convergence = True
510
+
511
+ if it >= self.max_it-1:
512
+ print(f'Maximum number of iterations (max_it = {self.max_it}) reached without convergence.')
513
+ self.ini_convergence = False
514
+
515
+ return self.ini_convergence
516
+
517
+
518
+
519
+
520
+
521
+ def dict2xy0(self,xy_0_dict):
522
+
523
+ for item in xy_0_dict:
524
+ if item in self.x_list:
525
+ self.xy_0[self.x_list.index(item)] = xy_0_dict[item]
526
+ if item in self.y_ini_list:
527
+ self.xy_0[self.y_ini_list.index(item) + self.N_x] = xy_0_dict[item]
528
+
529
+
530
+ def save_xy_0(self,file_name = 'xy_0.json'):
531
+ xy_0_dict = {}
532
+ for item in self.x_list:
533
+ xy_0_dict.update({item:self.get_value(item)})
534
+ for item in self.y_ini_list:
535
+ xy_0_dict.update({item:self.get_value(item)})
536
+
537
+ xy_0_str = json.dumps(xy_0_dict, indent=4)
538
+ with open(file_name,'w') as fobj:
539
+ fobj.write(xy_0_str)
540
+
541
+ def load_xy_0(self,file_name = 'xy_0.json'):
542
+ with open(file_name) as fobj:
543
+ xy_0_str = fobj.read()
544
+ xy_0_dict = json.loads(xy_0_str)
545
+
546
+ for item in xy_0_dict:
547
+ if item in self.x_list:
548
+ self.xy_0[self.x_list.index(item)] = xy_0_dict[item]
549
+ if item in self.y_ini_list:
550
+ self.xy_0[self.y_ini_list.index(item)+self.N_x] = xy_0_dict[item]
551
+
552
+ def load_params(self,data_input):
553
+
554
+ if type(data_input) == str:
555
+ json_file = data_input
556
+ self.json_file = json_file
557
+ self.json_data = open(json_file).read().replace("'",'"')
558
+ data = json.loads(self.json_data)
559
+ elif type(data_input) == dict:
560
+ data = data_input
561
+
562
+ self.data = data
563
+ for item in self.data:
564
+ self.set_value(item, self.data[item])
565
+
566
+ def save_params(self,file_name = 'parameters.json'):
567
+ params_dict = {}
568
+ for item in self.params_list:
569
+ params_dict.update({item:self.get_value(item)})
570
+
571
+ params_dict_str = json.dumps(params_dict, indent=4)
572
+ with open(file_name,'w') as fobj:
573
+ fobj.write(params_dict_str)
574
+
575
+ def save_inputs_ini(self,file_name = 'inputs_ini.json'):
576
+ inputs_ini_dict = {}
577
+ for item in self.inputs_ini_list:
578
+ inputs_ini_dict.update({item:self.get_value(item)})
579
+
580
+ inputs_ini_dict_str = json.dumps(inputs_ini_dict, indent=4)
581
+ with open(file_name,'w') as fobj:
582
+ fobj.write(inputs_ini_dict_str)
583
+
584
+ def eval_preconditioner_ini(self):
585
+
586
+ sp_jac_ini_eval(self.sp_jac_ini.data,self.x,self.y_run,self.u_run,self.p,self.Dt)
587
+
588
+ csc_sp_jac_ini = sspa.csc_matrix(self.sp_jac_ini)
589
+ P_slu = spilu(csc_sp_jac_ini,
590
+ fill_factor=self.fill_factor_ini,
591
+ drop_tol=self.drop_tol_ini,
592
+ drop_rule = self.drop_rule_ini)
593
+
594
+ self.P_slu = P_slu
595
+ P_d,P_i,P_p,perm_r,perm_c = slu2pydae(P_slu)
596
+ self.P_d = P_d
597
+ self.P_i = P_i
598
+ self.P_p = P_p
599
+
600
+ self.perm_r = perm_r
601
+ self.perm_c = perm_c
602
+
603
+
604
+ def eval_preconditioner_trap(self):
605
+
606
+ sp_jac_trap_eval(self.sp_jac_trap.data,self.x,self.y_run,self.u_run,self.p,self.Dt)
607
+
608
+ #self.sp_jac_trap.data = self.J_trap_d
609
+
610
+ csc_sp_jac_trap = sspa.csc_matrix(self.sp_jac_trap)
611
+
612
+
613
+ P_slu_trap = spilu(csc_sp_jac_trap,
614
+ fill_factor=self.fill_factor_trap,
615
+ drop_tol=self.drop_tol_trap,
616
+ drop_rule = self.drop_rule_trap)
617
+
618
+ self.P_slu_trap = P_slu_trap
619
+ P_d,P_i,P_p,perm_r,perm_c = slu2pydae(P_slu_trap)
620
+ self.P_trap_d = P_d
621
+ self.P_trap_i = P_i
622
+ self.P_trap_p = P_p
623
+
624
+ self.perm_trap_r = perm_r
625
+ self.perm_trap_c = perm_c
626
+
627
+ def sprun(self,t_end,up_dict):
628
+
629
+ for item in up_dict:
630
+ self.set_value(item,up_dict[item])
631
+
632
+ t = self.t
633
+ p = self.p
634
+ it = self.it
635
+ it_store = self.it_store
636
+ xy = self.xy
637
+ u = self.u_run
638
+ z = self.z
639
+ self.iparams_run = np.zeros(10,dtype=np.float64)
640
+
641
+ t,it,it_store,xy = spdaesolver(t,t_end,it,it_store,xy,u,p,z,
642
+ self.sp_jac_trap.data,self.sp_jac_trap.indices,self.sp_jac_trap.indptr,
643
+ self.P_trap_d,self.P_trap_i,self.P_trap_p,self.perm_trap_r,self.perm_trap_c,
644
+ self.Time,
645
+ self.X,
646
+ self.Y,
647
+ self.Z,
648
+ self.iters,
649
+ self.Dt,
650
+ self.N_x,
651
+ self.N_y,
652
+ self.N_z,
653
+ self.decimation,
654
+ self.iparams_run,
655
+ max_it=self.max_it,itol=self.max_it,store=self.store,
656
+ lmax_it=self.lmax_it,ltol=self.ltol,ldamp=self.ldamp,mode=self.mode,
657
+ lsolver = self.lsolver)
658
+
659
+ self.t = t
660
+ self.it = it
661
+ self.it_store = it_store
662
+ self.xy = xy
663
+ self.z = z
664
+
665
+
666
+ def spini(self,up_dict,xy_0={}):
667
+
668
+ self.it = 0
669
+ self.it_store = 0
670
+ self.t = 0.0
671
+
672
+ for item in up_dict:
673
+ self.set_value(item,up_dict[item])
674
+
675
+ if type(xy_0) == dict:
676
+ xy_0_dict = xy_0
677
+ self.dict2xy0(xy_0_dict)
678
+
679
+ if type(xy_0) == str:
680
+ if xy_0 == 'eval':
681
+ N_x = self.N_x
682
+ self.xy_0_new = np.copy(self.xy_0)*0
683
+ xy0_eval(self.xy_0_new[:N_x],self.xy_0_new[N_x:],self.u_ini,self.p)
684
+ self.xy_0_evaluated = np.copy(self.xy_0_new)
685
+ self.xy_0 = np.copy(self.xy_0_new)
686
+ else:
687
+ self.load_xy_0(file_name = xy_0)
688
+
689
+ self.xy_ini = self.spss_ini()
690
+
691
+
692
+ if self.N_iters < self.max_it:
693
+
694
+ self.ini2run()
695
+ self.ini_convergence = True
696
+
697
+ if self.N_iters >= self.max_it:
698
+ print(f'Maximum number of iterations (max_it = {self.max_it}) reached without convergence.')
699
+ self.ini_convergence = False
700
+
701
+ #jac_run_eval_xy(self.jac_run,self.x,self.y_run,self.u_run,self.p)
702
+ #jac_run_eval_up(self.jac_run,self.x,self.y_run,self.u_run,self.p)
703
+
704
+ return self.ini_convergence
705
+
706
+
707
+ def spss_ini(self):
708
+ J_d,J_i,J_p = csr2pydae(self.sp_jac_ini)
709
+
710
+ xy_ini,it,iparams = spsstate(self.xy,self.u_ini,self.p,
711
+ self.sp_jac_ini.data,self.sp_jac_ini.indices,self.sp_jac_ini.indptr,
712
+ self.P_d,self.P_i,self.P_p,self.perm_r,self.perm_c,
713
+ self.N_x,self.N_y,
714
+ max_it=self.max_it,tol=self.itol,
715
+ lmax_it=self.lmax_it_ini,
716
+ ltol=self.ltol_ini,
717
+ ldamp=self.ldamp,solver=self.ss_solver)
718
+
719
+
720
+ self.xy_ini = xy_ini
721
+ self.N_iters = it
722
+ self.iparams = iparams
723
+
724
+ return xy_ini
725
+
726
+ #def import_cffi(self):
727
+
728
+
729
+ def eval_jac_u2z(self):
730
+
731
+ '''
732
+
733
+ 0 = J_run * xy + FG_u * u
734
+ z = Hxy_run * xy + H_u * u
735
+
736
+ xy = -1/J_run * FG_u * u
737
+ z = -Hxy_run/J_run * FG_u * u + H_u * u
738
+ z = (-Hxy_run/J_run * FG_u + H_u ) * u
739
+ '''
740
+
741
+ sp_Fu_run_eval(self.sp_Fu_run.data,self.x,self.y_run,self.u_run,self.p,self.Dt)
742
+ sp_Gu_run_eval(self.sp_Gu_run.data,self.x,self.y_run,self.u_run,self.p,self.Dt)
743
+ sp_H_jacs_run_eval(self.sp_Hx_run.data,
744
+ self.sp_Hy_run.data,
745
+ self.sp_Hu_run.data,
746
+ self.x,self.y_run,self.u_run,self.p,self.Dt)
747
+ sp_jac_run = self.sp_jac_run
748
+ sp_jac_run_eval(sp_jac_run.data,
749
+ self.x,self.y_run,
750
+ self.u_run,self.p,
751
+ self.Dt)
752
+
753
+
754
+
755
+ Hxy_run = sspa.bmat([[self.sp_Hx_run,self.sp_Hy_run]])
756
+ FGu_run = sspa.bmat([[self.sp_Fu_run],[self.sp_Gu_run]])
757
+
758
+
759
+ #((sspa.linalg.spsolve(s.sp_jac_ini,-Hxy_run)) @ FGu_run + sp_Hu_run )@s.u_ini
760
+
761
+ self.jac_u2z = Hxy_run @ sspa.linalg.spsolve(self.sp_jac_run,-FGu_run) + self.sp_Hu_run
762
+
763
+
764
+ def step(self,t_end,up_dict):
765
+ for item in up_dict:
766
+ self.set_value(item,up_dict[item])
767
+
768
+ t = self.t
769
+ p = self.p
770
+ it = self.it
771
+ it_store = self.it_store
772
+ xy = self.xy
773
+ u = self.u_run
774
+ z = self.z
775
+
776
+ t,it,xy = daestep(t,t_end,it,
777
+ xy,u,p,z,
778
+ self.jac_trap,
779
+ self.iters,
780
+ self.Dt,
781
+ self.N_x,
782
+ self.N_y,
783
+ self.N_z,
784
+ max_it=self.max_it,itol=self.itol,store=self.store)
785
+
786
+ self.t = t
787
+ self.it = it
788
+ self.it_store = it_store
789
+ self.xy = xy
790
+ self.z = z
791
+
792
+
793
+ def save_run(self,file_name):
794
+ np.savez(file_name,Time=self.Time,
795
+ X=self.X,Y=self.Y,Z=self.Z,
796
+ x_list = self.x_list,
797
+ y_ini_list = self.y_ini_list,
798
+ y_run_list = self.y_run_list,
799
+ u_ini_list=self.u_ini_list,
800
+ u_run_list=self.u_run_list,
801
+ z_list=self.outputs_list,
802
+ )
803
+
804
+ def load_run(self,file_name):
805
+ data = np.load(f'{file_name}.npz')
806
+ self.Time = data['Time']
807
+ self.X = data['X']
808
+ self.Y = data['Y']
809
+ self.Z = data['Z']
810
+ self.x_list = list(data['x_list'] )
811
+ self.y_run_list = list(data['y_run_list'] )
812
+ self.outputs_list = list(data['z_list'] )
813
+
814
+ def full_jacs_eval(self):
815
+ N_x = self.N_x
816
+ N_y = self.N_y
817
+ N_xy = N_x + N_y
818
+
819
+ sp_jac_run = self.sp_jac_run
820
+ sp_Fu = self.sp_Fu_run
821
+ sp_Gu = self.sp_Gu_run
822
+ sp_Hx = self.sp_Hx_run
823
+ sp_Hy = self.sp_Hy_run
824
+ sp_Hu = self.sp_Hu_run
825
+
826
+ x = self.xy[0:N_x]
827
+ y = self.xy[N_x:]
828
+ u = self.u_run
829
+ p = self.p
830
+ Dt = self.Dt
831
+
832
+ sp_jac_run_eval(sp_jac_run.data,x,y,u,p,Dt)
833
+
834
+ self.Fx = sp_jac_run[0:N_x,0:N_x]
835
+ self.Fy = sp_jac_run[ 0:N_x,N_x:]
836
+ self.Gx = sp_jac_run[ N_x:,0:N_x]
837
+ self.Gy = sp_jac_run[ N_x:, N_x:]
838
+
839
+ sp_Fu_run_eval(sp_Fu.data,x,y,u,p,Dt)
840
+ sp_Gu_run_eval(sp_Gu.data,x,y,u,p,Dt)
841
+ sp_H_jacs_run_eval(sp_Hx.data,sp_Hy.data,sp_Hu.data,x,y,u,p,Dt)
842
+
843
+ self.Fu = sp_Fu
844
+ self.Gu = sp_Gu
845
+ self.Hx = sp_Hx
846
+ self.Hy = sp_Hy
847
+ self.Hu = sp_Hu
848
+
849
+
850
+ @numba.njit()
851
+ def daestep(t,t_end,it,xy,u,p,z,jac_trap,iters,Dt,N_x,N_y,N_z,max_it=50,itol=1e-8,store=1):
852
+
853
+
854
+ fg = np.zeros((N_x+N_y,1),dtype=np.float64)
855
+ fg_i = np.zeros((N_x+N_y),dtype=np.float64)
856
+ x = xy[:N_x]
857
+ y = xy[N_x:]
858
+ fg = np.zeros((N_x+N_y,),dtype=np.float64)
859
+ f = fg[:N_x]
860
+ g = fg[N_x:]
861
+ #h = np.zeros((N_z),dtype=np.float64)
862
+
863
+ f_ptr=ffi.from_buffer(np.ascontiguousarray(f))
864
+ g_ptr=ffi.from_buffer(np.ascontiguousarray(g))
865
+ z_ptr=ffi.from_buffer(np.ascontiguousarray(z))
866
+ x_ptr=ffi.from_buffer(np.ascontiguousarray(x))
867
+ y_ptr=ffi.from_buffer(np.ascontiguousarray(y))
868
+ u_ptr=ffi.from_buffer(np.ascontiguousarray(u))
869
+ p_ptr=ffi.from_buffer(np.ascontiguousarray(p))
870
+
871
+ jac_trap_ptr=ffi.from_buffer(np.ascontiguousarray(jac_trap))
872
+
873
+ #de_jac_trap_num_eval(jac_trap_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
874
+ de_jac_trap_up_eval(jac_trap_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
875
+ de_jac_trap_xy_eval(jac_trap_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
876
+
877
+ if it == 0:
878
+ f_run_eval(f_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
879
+ g_run_eval(g_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
880
+ h_eval(z_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
881
+ it_store = 0
882
+
883
+ while t<t_end:
884
+ it += 1
885
+ t += Dt
886
+
887
+ f_run_eval(f_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
888
+ g_run_eval(g_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
889
+
890
+ x_0 = np.copy(x)
891
+ y_0 = np.copy(y)
892
+ f_0 = np.copy(f)
893
+ g_0 = np.copy(g)
894
+
895
+ for iti in range(max_it):
896
+ f_run_eval(f_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
897
+ g_run_eval(g_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
898
+ de_jac_trap_xy_eval(jac_trap_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
899
+
900
+ f_n_i = x - x_0 - 0.5*Dt*(f+f_0)
901
+
902
+ fg_i[:N_x] = f_n_i
903
+ fg_i[N_x:] = g
904
+
905
+ Dxy_i = np.linalg.solve(-jac_trap,fg_i)
906
+
907
+ x += Dxy_i[:N_x]
908
+ y += Dxy_i[N_x:]
909
+
910
+ #print(Dxy_i)
911
+
912
+ # iteration stop
913
+ max_relative = 0.0
914
+ for it_var in range(N_x+N_y):
915
+ abs_value = np.abs(xy[it_var])
916
+ if abs_value < 0.001:
917
+ abs_value = 0.001
918
+ relative_error = np.abs(Dxy_i[it_var])/abs_value
919
+
920
+ if relative_error > max_relative: max_relative = relative_error
921
+
922
+ if max_relative<itol:
923
+ break
924
+
925
+ h_eval(z_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
926
+ xy[:N_x] = x
927
+ xy[N_x:] = y
928
+
929
+ return t,it,xy
930
+
931
+
932
+ def daesolver_sp(t,t_end,it,it_store,xy,u,p,sp_jac_trap,T,X,Y,Z,iters,Dt,N_x,N_y,N_z,decimation,max_it=50,itol=1e-8,store=1):
933
+
934
+ fg = np.zeros((N_x+N_y,1),dtype=np.float64)
935
+ fg_i = np.zeros((N_x+N_y),dtype=np.float64)
936
+ x = xy[:N_x]
937
+ y = xy[N_x:]
938
+ fg = np.zeros((N_x+N_y,),dtype=np.float64)
939
+ f = fg[:N_x]
940
+ g = fg[N_x:]
941
+ h = np.zeros((N_z),dtype=np.float64)
942
+ sp_jac_trap_eval_up(sp_jac_trap.data,x,y,u,p,Dt,xyup=1)
943
+
944
+ if it == 0:
945
+ f_run_eval(f,x,y,u,p)
946
+ h_eval(h,x,y,u,p)
947
+ it_store = 0
948
+ T[0] = t
949
+ X[0,:] = x
950
+ Y[0,:] = y
951
+ Z[0,:] = h
952
+
953
+ while t<t_end:
954
+ it += 1
955
+ t += Dt
956
+
957
+ f_run_eval(f,x,y,u,p)
958
+ g_run_eval(g,x,y,u,p)
959
+
960
+ x_0 = np.copy(x)
961
+ y_0 = np.copy(y)
962
+ f_0 = np.copy(f)
963
+ g_0 = np.copy(g)
964
+
965
+ for iti in range(max_it):
966
+ f_run_eval(f,x,y,u,p)
967
+ g_run_eval(g,x,y,u,p)
968
+ sp_jac_trap_eval(sp_jac_trap.data,x,y,u,p,Dt,xyup=1)
969
+
970
+ f_n_i = x - x_0 - 0.5*Dt*(f+f_0)
971
+
972
+ fg_i[:N_x] = f_n_i
973
+ fg_i[N_x:] = g
974
+
975
+ Dxy_i = spsolve(sp_jac_trap,-fg_i)
976
+
977
+ x = x + Dxy_i[:N_x]
978
+ y = y + Dxy_i[N_x:]
979
+
980
+ # iteration stop
981
+ max_relative = 0.0
982
+ for it_var in range(N_x+N_y):
983
+ abs_value = np.abs(xy[it_var])
984
+ if abs_value < 0.001:
985
+ abs_value = 0.001
986
+ relative_error = np.abs(Dxy_i[it_var])/abs_value
987
+
988
+ if relative_error > max_relative: max_relative = relative_error
989
+
990
+ if max_relative<itol:
991
+ break
992
+
993
+ h_eval(h,x,y,u,p)
994
+ xy[:N_x] = x
995
+ xy[N_x:] = y
996
+
997
+ # store in channels
998
+ if store == 1:
999
+ if it >= it_store*decimation:
1000
+ T[it_store+1] = t
1001
+ X[it_store+1,:] = x
1002
+ Y[it_store+1,:] = y
1003
+ Z[it_store+1,:] = h
1004
+ iters[it_store+1] = iti
1005
+ it_store += 1
1006
+
1007
+ return t,it,it_store,xy
1008
+
1009
+
1010
+
1011
+
1012
+ @numba.njit()
1013
+ def sprichardson(A_d,A_i,A_p,b,P_d,P_i,P_p,perm_r,perm_c,x,iparams,damp=1.0,max_it=100,tol=1e-3):
1014
+ N_A = A_p.shape[0]-1
1015
+ f = np.zeros(N_A)
1016
+ for it in range(max_it):
1017
+ spMvmul(N_A,A_d,A_i,A_p,x,f)
1018
+ f -= b # A@x-b
1019
+ x = x - damp*splu_solve(P_d,P_i,P_p,perm_r,perm_c,f)
1020
+ if np.linalg.norm(f,2) < tol: break
1021
+ iparams[0] = it
1022
+ return x
1023
+
1024
+ @numba.njit()
1025
+ def spconjgradm(A_d,A_i,A_p,b,P_d,P_i,P_p,perm_r,perm_c,x,iparams,max_it=100,tol=1e-3, damp=None):
1026
+ """
1027
+ A function to solve [A]{x} = {b} linear equation system with the
1028
+ preconditioned conjugate gradient method.
1029
+ More at: http://en.wikipedia.org/wiki/Conjugate_gradient_method
1030
+ ========== Parameters ==========
1031
+ A_d,A_i,A_p : sparse matrix
1032
+ components in CRS form A_d = A_crs.data, A_i = A_crs.indices, A_p = A_crs.indptr.
1033
+ b : vector
1034
+ The right hand side (RHS) vector of the system.
1035
+ x : vector
1036
+ The starting guess for the solution.
1037
+ P_d,P_i,P_p,perm_r,perm_c: preconditioner LU matrix
1038
+ components in scipy.spilu form P_d,P_i,P_p,perm_r,perm_c = slu2pydae(M)
1039
+ with M = scipy.sparse.linalg.spilu(A_csc)
1040
+
1041
+ """
1042
+ N = len(b)
1043
+ Ax = np.zeros(N)
1044
+ Ap = np.zeros(N)
1045
+ App = np.zeros(N)
1046
+ pAp = np.zeros(N)
1047
+ z = np.zeros(N)
1048
+
1049
+ spMvmul(N,A_d,A_i,A_p,x,Ax)
1050
+ r = -(Ax - b)
1051
+ z = splu_solve(P_d,P_i,P_p,perm_r,perm_c,r) #z = M.solve(r)
1052
+ p = z
1053
+ zsold = 0.0
1054
+ for it in range(N): # zsold = np.dot(np.transpose(z), z)
1055
+ zsold += z[it]*z[it]
1056
+ for i in range(max_it):
1057
+ spMvmul(N,A_d,A_i,A_p,p,App) # #App = np.dot(A, p)
1058
+ Ap = splu_solve(P_d,P_i,P_p,perm_r,perm_c,App) #Ap = M.solve(App)
1059
+ pAp = 0.0
1060
+ for it in range(N):
1061
+ pAp += p[it]*Ap[it]
1062
+
1063
+ alpha = zsold / pAp
1064
+ x = x + alpha*p
1065
+ z = z - alpha*Ap
1066
+ zz = 0.0
1067
+ for it in range(N): # z.T@z
1068
+ zz += z[it]*z[it]
1069
+ zsnew = zz
1070
+ if np.sqrt(zsnew) < tol:
1071
+ break
1072
+
1073
+ p = z + (zsnew/zsold)*p
1074
+ zsold = zsnew
1075
+ iparams[0] = i
1076
+
1077
+ return x
1078
+
1079
+
1080
+ @numba.njit()
1081
+ def spsstate(xy,u,p,
1082
+ J_d,J_i,J_p,
1083
+ P_d,P_i,P_p,perm_r,perm_c,
1084
+ N_x,N_y,
1085
+ max_it=50,tol=1e-8,
1086
+ lmax_it=20,ltol=1e-8,ldamp=1.0, solver=2):
1087
+
1088
+
1089
+ x = xy[:N_x]
1090
+ y = xy[N_x:]
1091
+ fg = np.zeros((N_x+N_y,),dtype=np.float64)
1092
+ f = fg[:N_x]
1093
+ g = fg[N_x:]
1094
+ iparams = np.array([0],dtype=np.int64)
1095
+
1096
+ f_c_ptr=ffi.from_buffer(np.ascontiguousarray(f))
1097
+ g_c_ptr=ffi.from_buffer(np.ascontiguousarray(g))
1098
+ x_c_ptr=ffi.from_buffer(np.ascontiguousarray(x))
1099
+ y_c_ptr=ffi.from_buffer(np.ascontiguousarray(y))
1100
+ u_c_ptr=ffi.from_buffer(np.ascontiguousarray(u))
1101
+ p_c_ptr=ffi.from_buffer(np.ascontiguousarray(p))
1102
+ J_d_ptr=ffi.from_buffer(np.ascontiguousarray(J_d))
1103
+
1104
+ #sp_jac_ini_num_eval(J_d_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,1.0)
1105
+ sp_jac_ini_up_eval(J_d_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,1.0)
1106
+
1107
+ #sp_jac_ini_eval_up(J_d,x,y,u,p,0.0)
1108
+
1109
+ Dxy = np.zeros(N_x + N_y)
1110
+ for it in range(max_it):
1111
+
1112
+ x = xy[:N_x]
1113
+ y = xy[N_x:]
1114
+
1115
+ sp_jac_ini_xy_eval(J_d_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,1.0)
1116
+
1117
+
1118
+ f_ini_eval(f_c_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,1.0)
1119
+ g_ini_eval(g_c_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,1.0)
1120
+
1121
+ #f_ini_eval(f,x,y,u,p)
1122
+ #g_ini_eval(g,x,y,u,p)
1123
+
1124
+ fg[:N_x] = f
1125
+ fg[N_x:] = g
1126
+
1127
+ if solver==1:
1128
+
1129
+ Dxy = sprichardson(J_d,J_i,J_p,-fg,P_d,P_i,P_p,perm_r,perm_c,Dxy,iparams,damp=ldamp,max_it=lmax_it,tol=ltol)
1130
+
1131
+ if solver==2:
1132
+
1133
+ Dxy = spconjgradm(J_d,J_i,J_p,-fg,P_d,P_i,P_p,perm_r,perm_c,Dxy,iparams,damp=ldamp,max_it=lmax_it,tol=ltol)
1134
+
1135
+ xy += Dxy
1136
+ #if np.max(np.abs(fg))<tol: break
1137
+ if np.linalg.norm(fg,np.inf)<tol: break
1138
+
1139
+ return xy,it,iparams
1140
+
1141
+
1142
+
1143
+ @numba.njit()
1144
+ def daesolver(t,t_end,it,it_store,xy,u,p,z,jac_trap,T,X,Y,Z,iters,Dt,N_x,N_y,N_z,decimation,max_it=50,itol=1e-8,store=1):
1145
+
1146
+
1147
+ fg = np.zeros((N_x+N_y,1),dtype=np.float64)
1148
+ fg_i = np.zeros((N_x+N_y),dtype=np.float64)
1149
+ x = xy[:N_x]
1150
+ y = xy[N_x:]
1151
+ fg = np.zeros((N_x+N_y,),dtype=np.float64)
1152
+ f = fg[:N_x]
1153
+ g = fg[N_x:]
1154
+ #h = np.zeros((N_z),dtype=np.float64)
1155
+
1156
+ f_ptr=ffi.from_buffer(np.ascontiguousarray(f))
1157
+ g_ptr=ffi.from_buffer(np.ascontiguousarray(g))
1158
+ z_ptr=ffi.from_buffer(np.ascontiguousarray(z))
1159
+ x_ptr=ffi.from_buffer(np.ascontiguousarray(x))
1160
+ y_ptr=ffi.from_buffer(np.ascontiguousarray(y))
1161
+ u_ptr=ffi.from_buffer(np.ascontiguousarray(u))
1162
+ p_ptr=ffi.from_buffer(np.ascontiguousarray(p))
1163
+
1164
+ jac_trap_ptr=ffi.from_buffer(np.ascontiguousarray(jac_trap))
1165
+
1166
+ #de_jac_trap_num_eval(jac_trap_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
1167
+ de_jac_trap_up_eval(jac_trap_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
1168
+ de_jac_trap_xy_eval(jac_trap_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
1169
+
1170
+ if it == 0:
1171
+ f_run_eval(f_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
1172
+ g_run_eval(g_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
1173
+ h_eval(z_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
1174
+ it_store = 0
1175
+ T[0] = t
1176
+ X[0,:] = x
1177
+ Y[0,:] = y
1178
+ Z[0,:] = z
1179
+
1180
+ while t<t_end:
1181
+ it += 1
1182
+ t += Dt
1183
+
1184
+ f_run_eval(f_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
1185
+ g_run_eval(g_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
1186
+
1187
+ x_0 = np.copy(x)
1188
+ y_0 = np.copy(y)
1189
+ f_0 = np.copy(f)
1190
+ g_0 = np.copy(g)
1191
+
1192
+ for iti in range(max_it):
1193
+ f_run_eval(f_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
1194
+ g_run_eval(g_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
1195
+ de_jac_trap_xy_eval(jac_trap_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
1196
+
1197
+ f_n_i = x - x_0 - 0.5*Dt*(f+f_0)
1198
+
1199
+ fg_i[:N_x] = f_n_i
1200
+ fg_i[N_x:] = g
1201
+
1202
+ Dxy_i = np.linalg.solve(-jac_trap,fg_i)
1203
+
1204
+ x += Dxy_i[:N_x]
1205
+ y += Dxy_i[N_x:]
1206
+
1207
+ #print(Dxy_i)
1208
+
1209
+ # iteration stop
1210
+ max_relative = 0.0
1211
+ for it_var in range(N_x+N_y):
1212
+ abs_value = np.abs(xy[it_var])
1213
+ if abs_value < 0.001:
1214
+ abs_value = 0.001
1215
+ relative_error = np.abs(Dxy_i[it_var])/abs_value
1216
+
1217
+ if relative_error > max_relative: max_relative = relative_error
1218
+
1219
+ if max_relative<itol:
1220
+ break
1221
+
1222
+ h_eval(z_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
1223
+ xy[:N_x] = x
1224
+ xy[N_x:] = y
1225
+
1226
+ # store in channels
1227
+ if store == 1:
1228
+ if it >= it_store*decimation:
1229
+ T[it_store+1] = t
1230
+ X[it_store+1,:] = x
1231
+ Y[it_store+1,:] = y
1232
+ Z[it_store+1,:] = z
1233
+ iters[it_store+1] = iti
1234
+ it_store += 1
1235
+
1236
+ return t,it,it_store,xy
1237
+
1238
+ @numba.njit()
1239
+ def spdaesolver(t,t_end,it,it_store,xy,u,p,z,
1240
+ J_d,J_i,J_p,
1241
+ P_d,P_i,P_p,perm_r,perm_c,
1242
+ T,X,Y,Z,iters,Dt,N_x,N_y,N_z,decimation,
1243
+ iparams,
1244
+ max_it=50,itol=1e-8,store=1,
1245
+ lmax_it=20,ltol=1e-4,ldamp=1.0,mode=0,lsolver=2):
1246
+
1247
+ fg_i = np.zeros((N_x+N_y),dtype=np.float64)
1248
+ x = xy[:N_x]
1249
+ y = xy[N_x:]
1250
+ fg = np.zeros((N_x+N_y,),dtype=np.float64)
1251
+ f = fg[:N_x]
1252
+ g = fg[N_x:]
1253
+ z = np.zeros((N_z),dtype=np.float64)
1254
+ Dxy_i_0 = np.zeros(N_x+N_y,dtype=np.float64)
1255
+ f_ptr=ffi.from_buffer(np.ascontiguousarray(f))
1256
+ g_ptr=ffi.from_buffer(np.ascontiguousarray(g))
1257
+ z_ptr=ffi.from_buffer(np.ascontiguousarray(z))
1258
+ x_ptr=ffi.from_buffer(np.ascontiguousarray(x))
1259
+ y_ptr=ffi.from_buffer(np.ascontiguousarray(y))
1260
+ u_ptr=ffi.from_buffer(np.ascontiguousarray(u))
1261
+ p_ptr=ffi.from_buffer(np.ascontiguousarray(p))
1262
+
1263
+ J_d_ptr=ffi.from_buffer(np.ascontiguousarray(J_d))
1264
+
1265
+ #sp_jac_trap_num_eval(J_d_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
1266
+ sp_jac_trap_up_eval( J_d_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
1267
+ sp_jac_trap_xy_eval( J_d_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
1268
+
1269
+ if it == 0:
1270
+ f_run_eval(f_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
1271
+ g_run_eval(g_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
1272
+ h_eval(z_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
1273
+ it_store = 0
1274
+ T[0] = t
1275
+ X[0,:] = x
1276
+ Y[0,:] = y
1277
+ Z[0,:] = z
1278
+
1279
+ while t<t_end:
1280
+ it += 1
1281
+ t += Dt
1282
+
1283
+ f_run_eval(f_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
1284
+ g_run_eval(g_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
1285
+
1286
+ x_0 = np.copy(x)
1287
+ y_0 = np.copy(y)
1288
+ f_0 = np.copy(f)
1289
+ g_0 = np.copy(g)
1290
+
1291
+ for iti in range(max_it):
1292
+ f_run_eval(f_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
1293
+ g_run_eval(g_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
1294
+ sp_jac_trap_xy_eval(J_d_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
1295
+
1296
+ f_n_i = x - x_0 - 0.5*Dt*(f+f_0)
1297
+
1298
+ fg_i[:N_x] = f_n_i
1299
+ fg_i[N_x:] = g
1300
+
1301
+ #Dxy_i = np.linalg.solve(-jac_trap,fg_i)
1302
+ if lsolver == 1:
1303
+ Dxy_i = sprichardson(J_d,J_i,J_p,-fg_i,P_d,P_i,P_p,perm_r,perm_c,
1304
+ Dxy_i_0,iparams,damp=ldamp,max_it=lmax_it,tol=ltol)
1305
+ if lsolver == 2:
1306
+ Dxy_i = spconjgradm(J_d,J_i,J_p,-fg_i,P_d,P_i,P_p,perm_r,perm_c,
1307
+ Dxy_i_0,iparams,damp=ldamp,max_it=lmax_it,tol=ltol)
1308
+
1309
+ x += Dxy_i[:N_x]
1310
+ y += Dxy_i[N_x:]
1311
+
1312
+ #print(Dxy_i)
1313
+
1314
+ # iteration stop
1315
+ max_relative = 0.0
1316
+ for it_var in range(N_x+N_y):
1317
+ abs_value = np.abs(xy[it_var])
1318
+ if abs_value < 0.001:
1319
+ abs_value = 0.001
1320
+ relative_error = np.abs(Dxy_i[it_var])/abs_value
1321
+
1322
+ if relative_error > max_relative: max_relative = relative_error
1323
+
1324
+ if max_relative<itol:
1325
+ break
1326
+
1327
+ h_eval(z_ptr,x_ptr,y_ptr,u_ptr,p_ptr,Dt)
1328
+ xy[:N_x] = x
1329
+ xy[N_x:] = y
1330
+
1331
+ # store in channels
1332
+ if store == 1:
1333
+ if it >= it_store*decimation:
1334
+ T[it_store+1] = t
1335
+ X[it_store+1,:] = x
1336
+ Y[it_store+1,:] = y
1337
+ Z[it_store+1,:] = z
1338
+ iters[it_store+1] = iti
1339
+ it_store += 1
1340
+
1341
+ return t,it,it_store,xy
1342
+
1343
+
1344
+ @cuda.jit()
1345
+ def ode_solve(x,u,p,f_run,u_idxs,z_i,z,sim):
1346
+
1347
+ N_i,N_j,N_x,N_z,Dt = sim
1348
+
1349
+ # index of thread on GPU:
1350
+ i = cuda.grid(1)
1351
+
1352
+ if i < x.size:
1353
+ for j in range(N_j):
1354
+ f_run_eval(f_run[i,:],x[i,:],u[i,u_idxs[j],:],p[i,:])
1355
+ for k in range(N_x):
1356
+ x[i,k] += Dt*f_run[i,k]
1357
+
1358
+ # outputs in time range
1359
+ #z[i,j] = u[i,idxs[j],0]
1360
+ z[i,j] = x[i,1]
1361
+ h_eval(z_i[i,:],x[i,:],u[i,u_idxs[j],:],p[i,:])
1362
+
1363
+ def csr2pydae(A_csr):
1364
+ '''
1365
+ From scipy CSR to the three vectors:
1366
+
1367
+ - data
1368
+ - indices
1369
+ - indptr
1370
+
1371
+ '''
1372
+
1373
+ A_d = A_csr.data
1374
+ A_i = A_csr.indices
1375
+ A_p = A_csr.indptr
1376
+
1377
+ return A_d,A_i,A_p
1378
+
1379
+ def slu2pydae(P_slu):
1380
+ '''
1381
+ From SupderLU matrix to the three vectors:
1382
+
1383
+ - data
1384
+ - indices
1385
+ - indptr
1386
+
1387
+ and the premutation vectors:
1388
+
1389
+ - perm_r
1390
+ - perm_c
1391
+
1392
+ '''
1393
+ N = P_slu.shape[0]
1394
+ #P_slu_full = P_slu.L.A - sspa.eye(N,format='csr') + P_slu.U.A
1395
+ P_slu_full = P_slu.L - sspa.eye(N,format='csc') + P_slu.U
1396
+ perm_r = P_slu.perm_r
1397
+ perm_c = P_slu.perm_c
1398
+ P_csr = sspa.csr_matrix(P_slu_full)
1399
+
1400
+ P_d = P_csr.data
1401
+ P_i = P_csr.indices
1402
+ P_p = P_csr.indptr
1403
+
1404
+ return P_d,P_i,P_p,perm_r,perm_c
1405
+
1406
+ @numba.njit(cache=True)
1407
+ def spMvmul(N,A_data,A_indices,A_indptr,x,y):
1408
+ '''
1409
+ y = A @ x
1410
+
1411
+ with A in sparse CRS form
1412
+ '''
1413
+ #y = np.zeros(x.shape[0])
1414
+ for i in range(N):
1415
+ y[i] = 0.0
1416
+ for j in range(A_indptr[i],A_indptr[i + 1]):
1417
+ y[i] = y[i] + A_data[j]*x[A_indices[j]]
1418
+
1419
+
1420
+ @numba.njit(cache=True)
1421
+ def splu_solve(LU_d,LU_i,LU_p,perm_r,perm_c,b):
1422
+ N = len(b)
1423
+ y = np.zeros(N)
1424
+ x = np.zeros(N)
1425
+ z = np.zeros(N)
1426
+ bp = np.zeros(N)
1427
+
1428
+ for i in range(N):
1429
+ bp[perm_r[i]] = b[i]
1430
+
1431
+ for i in range(N):
1432
+ y[i] = bp[i]
1433
+ for j in range(LU_p[i],LU_p[i+1]):
1434
+ if LU_i[j]>i-1: break
1435
+ y[i] -= LU_d[j] * y[LU_i[j]]
1436
+
1437
+ for i in range(N-1,-1,-1): #(int i = N - 1; i >= 0; i--)
1438
+ z[i] = y[i]
1439
+ den = 0.0
1440
+ for j in range(LU_p[i],LU_p[i+1]): #(int k = i + 1; k < N; k++)
1441
+ if LU_i[j] > i:
1442
+ z[i] -= LU_d[j] * z[LU_i[j]]
1443
+ if LU_i[j] == i: den = LU_d[j]
1444
+ z[i] = z[i]/den
1445
+
1446
+ for i in range(N):
1447
+ x[i] = z[perm_c[i]]
1448
+
1449
+ return x
1450
+
1451
+
1452
+
1453
+ @numba.njit("float64[:,:](float64[:,:],float64[:],float64[:],float64[:],float64[:],float64)")
1454
+ def de_jac_ini_eval(de_jac_ini,x,y,u,p,Dt):
1455
+ '''
1456
+ Computes the dense full initialization jacobian:
1457
+
1458
+ jac_ini = [[Fx_ini, Fy_ini],
1459
+ [Gx_ini, Gy_ini]]
1460
+
1461
+ for the given x,y,u,p vectors and Dt time increment.
1462
+
1463
+ Parameters
1464
+ ----------
1465
+ de_jac_ini : (N, N) array_like
1466
+ Input data.
1467
+ x : (N_x,) array_like
1468
+ Vector with dynamical states.
1469
+ y : (N_y,) array_like
1470
+ Vector with algebraic states (ini problem).
1471
+ u : (N_u,) array_like
1472
+ Vector with inputs (ini problem).
1473
+ p : (N_p,) array_like
1474
+ Vector with parameters.
1475
+
1476
+ with N = N_x+N_y
1477
+
1478
+ Returns
1479
+ -------
1480
+
1481
+ de_jac_ini : (N, N) array_like
1482
+ Updated matrix.
1483
+
1484
+ '''
1485
+
1486
+ de_jac_ini_ptr=ffi.from_buffer(np.ascontiguousarray(de_jac_ini))
1487
+ x_c_ptr=ffi.from_buffer(np.ascontiguousarray(x))
1488
+ y_c_ptr=ffi.from_buffer(np.ascontiguousarray(y))
1489
+ u_c_ptr=ffi.from_buffer(np.ascontiguousarray(u))
1490
+ p_c_ptr=ffi.from_buffer(np.ascontiguousarray(p))
1491
+
1492
+ de_jac_ini_num_eval(de_jac_ini_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,Dt)
1493
+ de_jac_ini_up_eval( de_jac_ini_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,Dt)
1494
+ de_jac_ini_xy_eval( de_jac_ini_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,Dt)
1495
+
1496
+ return de_jac_ini
1497
+
1498
+ @numba.njit("float64[:,:](float64[:,:],float64[:],float64[:],float64[:],float64[:],float64)")
1499
+ def de_jac_run_eval(de_jac_run,x,y,u,p,Dt):
1500
+ '''
1501
+ Computes the dense full initialization jacobian:
1502
+
1503
+ jac_run = [[Fx_run, Fy_run],
1504
+ [Gx_run, Gy_run]]
1505
+
1506
+ for the given x,y,u,p vectors and Dt time increment.
1507
+
1508
+ Parameters
1509
+ ----------
1510
+ de_jac_run : (N, N) array_like
1511
+ Input data.
1512
+ x : (N_x,) array_like
1513
+ Vector with dynamical states.
1514
+ y : (N_y,) array_like
1515
+ Vector with algebraic states (ini problem).
1516
+ u : (N_u,) array_like
1517
+ Vector with inputs (ini problem).
1518
+ p : (N_p,) array_like
1519
+ Vector with parameters.
1520
+
1521
+ with N = N_x+N_y
1522
+
1523
+ Returns
1524
+ -------
1525
+
1526
+ de_jac_ini : (N, N) array_like
1527
+ Updated matrix.
1528
+
1529
+ '''
1530
+
1531
+ de_jac_run_ptr=ffi.from_buffer(np.ascontiguousarray(de_jac_run))
1532
+ x_c_ptr=ffi.from_buffer(np.ascontiguousarray(x))
1533
+ y_c_ptr=ffi.from_buffer(np.ascontiguousarray(y))
1534
+ u_c_ptr=ffi.from_buffer(np.ascontiguousarray(u))
1535
+ p_c_ptr=ffi.from_buffer(np.ascontiguousarray(p))
1536
+
1537
+ de_jac_run_num_eval(de_jac_run_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,Dt)
1538
+ de_jac_run_up_eval( de_jac_run_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,Dt)
1539
+ de_jac_run_xy_eval( de_jac_run_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,Dt)
1540
+
1541
+ return de_jac_run
1542
+
1543
+ @numba.njit("float64[:,:](float64[:,:],float64[:],float64[:],float64[:],float64[:],float64)")
1544
+ def de_jac_trap_eval(de_jac_trap,x,y,u,p,Dt):
1545
+ '''
1546
+ Computes the dense full trapezoidal jacobian:
1547
+
1548
+ jac_trap = [[eye - 0.5*Dt*Fx_run, -0.5*Dt*Fy_run],
1549
+ [ Gx_run, Gy_run]]
1550
+
1551
+ for the given x,y,u,p vectors and Dt time increment.
1552
+
1553
+ Parameters
1554
+ ----------
1555
+ de_jac_trap : (N, N) array_like
1556
+ Input data.
1557
+ x : (N_x,) array_like
1558
+ Vector with dynamical states.
1559
+ y : (N_y,) array_like
1560
+ Vector with algebraic states (run problem).
1561
+ u : (N_u,) array_like
1562
+ Vector with inputs (run problem).
1563
+ p : (N_p,) array_like
1564
+ Vector with parameters.
1565
+
1566
+ Returns
1567
+ -------
1568
+
1569
+ de_jac_trap : (N, N) array_like
1570
+ Updated matrix.
1571
+
1572
+ '''
1573
+
1574
+ de_jac_trap_ptr = ffi.from_buffer(np.ascontiguousarray(de_jac_trap))
1575
+ x_c_ptr = ffi.from_buffer(np.ascontiguousarray(x))
1576
+ y_c_ptr = ffi.from_buffer(np.ascontiguousarray(y))
1577
+ u_c_ptr = ffi.from_buffer(np.ascontiguousarray(u))
1578
+ p_c_ptr = ffi.from_buffer(np.ascontiguousarray(p))
1579
+
1580
+ de_jac_trap_num_eval(de_jac_trap_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,Dt)
1581
+ de_jac_trap_up_eval( de_jac_trap_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,Dt)
1582
+ de_jac_trap_xy_eval( de_jac_trap_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,Dt)
1583
+
1584
+ return de_jac_trap
1585
+
1586
+
1587
+ # @numba.njit("float64[:](float64[:],float64[:],float64[:],float64[:],float64[:],float64)")
1588
+ # def sp_jac_run_eval(sp_jac_run,x,y,u,p,Dt):
1589
+ # '''
1590
+ # Computes the sparse full trapezoidal jacobian:
1591
+
1592
+ # jac_trap = [[eye - 0.5*Dt*Fx_run, -0.5*Dt*Fy_run],
1593
+ # [ Gx_run, Gy_run]]
1594
+
1595
+ # for the given x,y,u,p vectors and Dt time increment.
1596
+
1597
+ # Parameters
1598
+ # ----------
1599
+ # sp_jac_trap : (Nnz,) array_like
1600
+ # Input data.
1601
+ # x : (N_x,) array_like
1602
+ # Vector with dynamical states.
1603
+ # y : (N_y,) array_like
1604
+ # Vector with algebraic states (run problem).
1605
+ # u : (N_u,) array_like
1606
+ # Vector with inputs (run problem).
1607
+ # p : (N_p,) array_like
1608
+ # Vector with parameters.
1609
+
1610
+ # with Nnz the number of non-zeros elements in the jacobian.
1611
+
1612
+ # Returns
1613
+ # -------
1614
+
1615
+ # sp_jac_trap : (Nnz,) array_like
1616
+ # Updated matrix.
1617
+
1618
+ # '''
1619
+ # sp_jac_run_ptr=ffi.from_buffer(np.ascontiguousarray(sp_jac_run))
1620
+ # x_c_ptr=ffi.from_buffer(np.ascontiguousarray(x))
1621
+ # y_c_ptr=ffi.from_buffer(np.ascontiguousarray(y))
1622
+ # u_c_ptr=ffi.from_buffer(np.ascontiguousarray(u))
1623
+ # p_c_ptr=ffi.from_buffer(np.ascontiguousarray(p))
1624
+
1625
+ # sp_jac_run_num_eval( sp_jac_run_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,Dt)
1626
+ # sp_jac_run_up_eval( sp_jac_run_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,Dt)
1627
+ # sp_jac_run_xy_eval( sp_jac_run_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,Dt)
1628
+
1629
+ # return sp_jac_run
1630
+
1631
+ # @numba.njit("float64[:](float64[:],float64[:],float64[:],float64[:],float64[:],float64)")
1632
+ # def sp_jac_trap_eval(sp_jac_trap,x,y,u,p,Dt):
1633
+ # '''
1634
+ # Computes the sparse full trapezoidal jacobian:
1635
+
1636
+ # jac_trap = [[eye - 0.5*Dt*Fx_run, -0.5*Dt*Fy_run],
1637
+ # [ Gx_run, Gy_run]]
1638
+
1639
+ # for the given x,y,u,p vectors and Dt time increment.
1640
+
1641
+ # Parameters
1642
+ # ----------
1643
+ # sp_jac_trap : (Nnz,) array_like
1644
+ # Input data.
1645
+ # x : (N_x,) array_like
1646
+ # Vector with dynamical states.
1647
+ # y : (N_y,) array_like
1648
+ # Vector with algebraic states (run problem).
1649
+ # u : (N_u,) array_like
1650
+ # Vector with inputs (run problem).
1651
+ # p : (N_p,) array_like
1652
+ # Vector with parameters.
1653
+
1654
+ # with Nnz the number of non-zeros elements in the jacobian.
1655
+
1656
+ # Returns
1657
+ # -------
1658
+
1659
+ # sp_jac_trap : (Nnz,) array_like
1660
+ # Updated matrix.
1661
+
1662
+ # '''
1663
+ # sp_jac_trap_ptr=ffi.from_buffer(np.ascontiguousarray(sp_jac_trap))
1664
+ # x_c_ptr=ffi.from_buffer(np.ascontiguousarray(x))
1665
+ # y_c_ptr=ffi.from_buffer(np.ascontiguousarray(y))
1666
+ # u_c_ptr=ffi.from_buffer(np.ascontiguousarray(u))
1667
+ # p_c_ptr=ffi.from_buffer(np.ascontiguousarray(p))
1668
+
1669
+ # sp_jac_trap_num_eval(sp_jac_trap_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,Dt)
1670
+ # sp_jac_trap_up_eval( sp_jac_trap_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,Dt)
1671
+ # sp_jac_trap_xy_eval( sp_jac_trap_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,Dt)
1672
+
1673
+ # return sp_jac_trap
1674
+
1675
+ # @numba.njit("float64[:](float64[:],float64[:],float64[:],float64[:],float64[:],float64)")
1676
+ # def sp_jac_ini_eval(sp_jac_ini,x,y,u,p,Dt):
1677
+ # '''
1678
+ # Computes the SPARSE full initialization jacobian:
1679
+
1680
+ # jac_ini = [[Fx_ini, Fy_ini],
1681
+ # [Gx_ini, Gy_ini]]
1682
+
1683
+ # for the given x,y,u,p vectors and Dt time increment.
1684
+
1685
+ # Parameters
1686
+ # ----------
1687
+ # de_jac_ini : (N, N) array_like
1688
+ # Input data.
1689
+ # x : (N_x,) array_like
1690
+ # Vector with dynamical states.
1691
+ # y : (N_y,) array_like
1692
+ # Vector with algebraic states (ini problem).
1693
+ # u : (N_u,) array_like
1694
+ # Vector with inputs (ini problem).
1695
+ # p : (N_p,) array_like
1696
+ # Vector with parameters.
1697
+
1698
+ # with N = N_x+N_y
1699
+
1700
+ # Returns
1701
+ # -------
1702
+
1703
+ # de_jac_ini : (N, N) array_like
1704
+ # Updated matrix.
1705
+
1706
+ # '''
1707
+
1708
+ # sp_jac_ini_ptr=ffi.from_buffer(np.ascontiguousarray(sp_jac_ini))
1709
+ # x_c_ptr=ffi.from_buffer(np.ascontiguousarray(x))
1710
+ # y_c_ptr=ffi.from_buffer(np.ascontiguousarray(y))
1711
+ # u_c_ptr=ffi.from_buffer(np.ascontiguousarray(u))
1712
+ # p_c_ptr=ffi.from_buffer(np.ascontiguousarray(p))
1713
+
1714
+ # sp_jac_ini_num_eval(sp_jac_ini_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,Dt)
1715
+ # sp_jac_ini_up_eval( sp_jac_ini_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,Dt)
1716
+ # sp_jac_ini_xy_eval( sp_jac_ini_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,Dt)
1717
+
1718
+ # return sp_jac_ini
1719
+
1720
+
1721
+ @numba.njit()
1722
+ def sstate(xy,u,p,jac_ini_ss,N_x,N_y,max_it=50,tol=1e-8):
1723
+
1724
+ x = xy[:N_x]
1725
+ y = xy[N_x:]
1726
+ fg = np.zeros((N_x+N_y,),dtype=np.float64)
1727
+ f = fg[:N_x]
1728
+ g = fg[N_x:]
1729
+
1730
+ f_c_ptr=ffi.from_buffer(np.ascontiguousarray(f))
1731
+ g_c_ptr=ffi.from_buffer(np.ascontiguousarray(g))
1732
+ x_c_ptr=ffi.from_buffer(np.ascontiguousarray(x))
1733
+ y_c_ptr=ffi.from_buffer(np.ascontiguousarray(y))
1734
+ u_c_ptr=ffi.from_buffer(np.ascontiguousarray(u))
1735
+ p_c_ptr=ffi.from_buffer(np.ascontiguousarray(p))
1736
+ jac_ini_ss_ptr=ffi.from_buffer(np.ascontiguousarray(jac_ini_ss))
1737
+
1738
+ #de_jac_ini_num_eval(jac_ini_ss_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,1.0)
1739
+ de_jac_ini_up_eval(jac_ini_ss_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,1.0)
1740
+
1741
+ for it in range(max_it):
1742
+ de_jac_ini_xy_eval(jac_ini_ss_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,1.0)
1743
+ f_ini_eval(f_c_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,1.0)
1744
+ g_ini_eval(g_c_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,1.0)
1745
+ fg[:N_x] = f
1746
+ fg[N_x:] = g
1747
+ xy += np.linalg.solve(jac_ini_ss,-fg)
1748
+ if np.max(np.abs(fg))<tol: break
1749
+
1750
+ return xy,it
1751
+
1752
+
1753
+ @numba.njit("float64[:](float64[:],float64[:],float64[:],float64[:],float64[:],float64)")
1754
+ def c_h_eval(z,x,y,u,p,Dt):
1755
+ '''
1756
+ Computes the SPARSE full initialization jacobian:
1757
+
1758
+ jac_ini = [[Fx_ini, Fy_ini],
1759
+ [Gx_ini, Gy_ini]]
1760
+
1761
+ for the given x,y,u,p vectors and Dt time increment.
1762
+
1763
+ Parameters
1764
+ ----------
1765
+ de_jac_ini : (N, N) array_like
1766
+ Input data.
1767
+ x : (N_x,) array_like
1768
+ Vector with dynamical states.
1769
+ y : (N_y,) array_like
1770
+ Vector with algebraic states (ini problem).
1771
+ u : (N_u,) array_like
1772
+ Vector with inputs (ini problem).
1773
+ p : (N_p,) array_like
1774
+ Vector with parameters.
1775
+
1776
+ with N = N_x+N_y
1777
+
1778
+ Returns
1779
+ -------
1780
+
1781
+ de_jac_ini : (N, N) array_like
1782
+ Updated matrix.
1783
+
1784
+ '''
1785
+
1786
+ z_c_ptr=ffi.from_buffer(np.ascontiguousarray(z))
1787
+ x_c_ptr=ffi.from_buffer(np.ascontiguousarray(x))
1788
+ y_c_ptr=ffi.from_buffer(np.ascontiguousarray(y))
1789
+ u_c_ptr=ffi.from_buffer(np.ascontiguousarray(u))
1790
+ p_c_ptr=ffi.from_buffer(np.ascontiguousarray(p))
1791
+
1792
+ h_eval(z_c_ptr,x_c_ptr,y_c_ptr,u_c_ptr,p_c_ptr,Dt)
1793
+
1794
+ return z
1795
+
1796
+
1797
+
1798
+
1799
+
1800
+
1801
+ def sp_jac_ini_vectors():
1802
+
1803
+ sp_jac_ini_ia = [0, 1, 6, 2, 3, 2, 3, 4, 5, 2, 3, 4, 5, 6, 2, 3, 4, 5, 7, 2, 3, 4, 5, 8, 2, 3, 4, 5, 9, 2, 3, 4, 5, 10, 1, 6, 11]
1804
+ sp_jac_ini_ja = [0, 1, 3, 4, 5, 9, 13, 14, 19, 24, 29, 34, 37]
1805
+ sp_jac_ini_nia = 12
1806
+ sp_jac_ini_nja = 12
1807
+ return sp_jac_ini_ia, sp_jac_ini_ja, sp_jac_ini_nia, sp_jac_ini_nja
1808
+
1809
+ def sp_jac_run_vectors():
1810
+
1811
+ sp_jac_run_ia = [0, 1, 6, 2, 3, 2, 3, 4, 5, 2, 3, 4, 5, 6, 2, 3, 4, 5, 7, 2, 3, 4, 5, 8, 2, 3, 4, 5, 9, 2, 3, 4, 5, 10, 1, 6, 11]
1812
+ sp_jac_run_ja = [0, 1, 3, 4, 5, 9, 13, 14, 19, 24, 29, 34, 37]
1813
+ sp_jac_run_nia = 12
1814
+ sp_jac_run_nja = 12
1815
+ return sp_jac_run_ia, sp_jac_run_ja, sp_jac_run_nia, sp_jac_run_nja
1816
+
1817
+ def sp_jac_trap_vectors():
1818
+
1819
+ sp_jac_trap_ia = [0, 1, 6, 2, 3, 2, 3, 4, 5, 2, 3, 4, 5, 6, 2, 3, 4, 5, 7, 2, 3, 4, 5, 8, 2, 3, 4, 5, 9, 2, 3, 4, 5, 10, 1, 6, 11]
1820
+ sp_jac_trap_ja = [0, 1, 3, 4, 5, 9, 13, 14, 19, 24, 29, 34, 37]
1821
+ sp_jac_trap_nia = 12
1822
+ sp_jac_trap_nja = 12
1823
+ return sp_jac_trap_ia, sp_jac_trap_ja, sp_jac_trap_nia, sp_jac_trap_nja