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