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