Neko 1.99.9
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
intf.py
Go to the documentation of this file.
1from ctypes import (
2 CDLL,
3 util,
4 c_char_p,
5 c_int,
6 c_double,
7 c_float,
8 c_bool,
9 c_longlong,
10 POINTER,
11 byref,
12 cast,
13 addressof,
14 create_string_buffer,
15 CFUNCTYPE
16)
17from dataclasses import dataclass
18import json
19import numpy as np
20
21initial_condition = CFUNCTYPE(None, POINTER(c_char_p), c_int)
22
23preprocess = CFUNCTYPE(None, c_double, c_int)
24
25compute = CFUNCTYPE(None, c_double, c_int)
26
27dirichlet_condition = CFUNCTYPE(None, POINTER(c_int), c_int, c_double, c_int)
28
29material_properties = CFUNCTYPE(None, POINTER(c_char_p), c_int, c_double, c_int)
30
31source_term = CFUNCTYPE(None, POINTER(c_char_p), c_int, c_double, c_int)
32
33libneko = CDLL(util.find_library("neko"))
34
38
41
44
45
48
49libneko.neko_case_init.argtypes = [POINTER(c_char_p), c_int, POINTER(c_int)]
51
52libneko.neko_case_free.argtypes = [POINTER(c_int)]
54
55libneko.neko_case_time.argtypes = [POINTER(c_int)]
57
60
61libneko.neko_case_tstep.argtypes = [POINTER(c_int)]
63
66
67libneko.neko_solve.argtypes = [POINTER(c_int)]
69
70libneko.neko_step.argtypes = [POINTER(c_int)]
72
74libneko.neko_field.restype = POINTER(c_double)
75
78
81
84
86 POINTER(POINTER(c_longlong)),
87 POINTER(POINTER(c_double)),
88 POINTER(POINTER(c_double)),
89 POINTER(POINTER(c_double))]
91
93 POINTER(POINTER(c_longlong)),
94 POINTER(POINTER(c_double)),
95 POINTER(POINTER(c_double)),
96 POINTER(POINTER(c_double)),
97 POINTER(c_int)]
99
101 POINTER(c_int),
102 POINTER(POINTER(c_double)),
103 POINTER(POINTER(c_double)),
104 POINTER(POINTER(c_double)),
105 POINTER(POINTER(c_double)),
106 POINTER(POINTER(c_double)),
107 POINTER(POINTER(c_double)),
108 POINTER(POINTER(c_double)),
109 POINTER(POINTER(c_double)),
110 POINTER(POINTER(c_double)),
111 POINTER(POINTER(c_double))]
113
115 POINTER(c_int),
116 POINTER(POINTER(c_double)),
117 POINTER(POINTER(c_double)),
118 POINTER(POINTER(c_double)),
119 POINTER(POINTER(c_double)),
120 POINTER(POINTER(c_double)),
121 POINTER(POINTER(c_double)),
122 POINTER(POINTER(c_double)),
123 POINTER(POINTER(c_double)),
124 POINTER(POINTER(c_double)),
125 POINTER(POINTER(c_double))]
127
129 POINTER(POINTER(c_double)),
130 POINTER(POINTER(c_double)),
131 POINTER(POINTER(c_double)),
132 POINTER(POINTER(c_double)),
133 POINTER(POINTER(c_double)),
134 POINTER(POINTER(c_double)),
135 POINTER(POINTER(c_double)),
136 POINTER(POINTER(c_double)),
137 POINTER(POINTER(c_double)),
138 POINTER(POINTER(c_double)),
139 POINTER(POINTER(c_double)),
140 POINTER(POINTER(c_double)),
141 POINTER(POINTER(c_double)),
142 POINTER(POINTER(c_double)),
143 POINTER(POINTER(c_double)),
144 POINTER(POINTER(c_double)),
145 POINTER(POINTER(c_double)),
146 POINTER(POINTER(c_double)),
147 POINTER(POINTER(c_double)),
148 POINTER(POINTER(c_double)),
149 POINTER(POINTER(c_double)),
150 POINTER(POINTER(c_double)),
151 POINTER(POINTER(c_double)),
152 POINTER(POINTER(c_double)),
153 POINTER(POINTER(c_double)),
154 POINTER(POINTER(c_double)),
155 POINTER(POINTER(c_double)),
156 POINTER(POINTER(c_double)),
157 POINTER(POINTER(c_double)),
158 POINTER(POINTER(c_double)),
159 POINTER(POINTER(c_double))]
161
162libneko.neko_output_ctrl_execute.argtypes = [POINTER(c_int), c_bool]
163
164libneko.neko_user_setup.argtypes = [POINTER(c_int),
165 initial_condition,
166 preprocess,
167 compute,
168 dirichlet_condition,
169 material_properties,
170 source_term]
172
175
176libneko.neko_cb_field_name_at_index.argtypes = [POINTER(c_int), c_char_p]
178
179
180
181@dataclass
183 """ Defines a Neko mapping of the degrees of freedom """
188 ntot: int
189
190@dataclass
192 """ Defines a Neko space. """
193 lx: int
204
205@dataclass
207 """ Defines a Neko field. """
209 dm: neko_dofmap_t
210 Xh: neko_space_t
211
212@dataclass
247def init():
248 """ Initialise Neko. """
250
252 """ Finalize Neko. """
254
256 """ Initialise Neko device layer. """
258
260 """ Finalize Neko device lyaer. """
262
264 """ Display job information. """
266
268 """ Initialise a neko registry. """
270
272 """ Destroy a neko registry. """
274
275def case_init(case_json,
276 cb_initial_condition = initial_condition(0),
277 cb_preprocess = preprocess(0),
278 cb_compute = compute(0),
279 cb_dirichlet_condition = dirichlet_condition(0),
280 cb_material_properties = material_properties(0),
281 cb_source_term = source_term(0)):
282 """Initialise a Neko case
283
284 A case is created based on a JSON file and a couple of (optional)
285 callback functions.
286
287 """
288 cp = python_dict_to_fortran(case_json)
289 case_descr = c_int()
290
291 if (cb_initial_condition != initial_condition(0) or
292 cb_preprocess != preprocess(0) or
293 cb_compute != compute(0) or
294 cb_dirichlet_condition != dirichlet_condition(0) or
295 cb_material_properties != material_properties(0) or
296 cb_source_term != source_term(0)):
297
298 libneko.neko_case_allocate(byref(case_descr))
299 user_setup(case_descr, cb_initial_condition, cb_preprocess,
300 cb_compute, cb_dirichlet_condition, cb_material_properties,
301 cb_source_term)
302
303 libneko.neko_case_init(byref(cp), len(json.dumps(case_json)),
304 byref(case_descr))
305 return case_descr
306
307def case_free(case_descr):
308 """ Destroy a Neko case. """
309 libneko.neko_case_free(byref(case_descr))
310
311def time(case_descr):
312 """ Retrive the current time of a case. """
313 time = libneko.neko_case_time(byref(case_descr))
314 return time
315
316def end_time(case_descr):
317 """ Retrive the end time of a case. """
318 end_time = libneko.neko_case_end_time(byref(case_descr))
319 return end_time
320
321def tstep(case_descr):
322 """ Retrive the current time-step of a case. """
323 tstep = libneko.neko_case_tstep(byref(case_descr))
324 return tstep
325
326def is_done(case_descr):
327 """ Check if a case has reached its end time. """
328 is_done = libneko.neko_case_is_done(byref(case_descr))
329 return is_done > 0
330
331def solve(case_descr):
332 """ Solve a Neko case. """
333 libneko.neko_solve(byref(case_descr))
334
335def step(case_descr):
336 """ Compute a time-step for a Neko case. """
337 libneko.neko_step(byref(case_descr))
338
339def field(name):
340 """ Retrive a Neko field as a `neko_field_t`. """
341 a = neko_field_t(
342 np.frombuffer((c_double *
344 addressof(libneko.neko_field(name).contents)),
345 dtype=np.dtype(c_double)),
346 field_dofmap(name),
347 field_space(name)
348 )
349 return a
350
351def field_order(name):
352 """ Retrive the order of a Neko field. """
353 order = libneko.neko_field_order(name)
354 return order
355
356def field_nelements(name):
357 """ Retrive the number of elements in a Neko field. """
358 nelements = libneko.neko_field_nelements(name)
359 return nelements
360
361def field_size(name):
362 """ Retrive the total number of degrees of freedom of a Neko field. """
363 size = libneko.neko_field_size(name)
364 return size
365
366def field_dofmap(name):
367 """ Retrive a dofmap of a Neko field as a `neko_dofmap_t`. """
368 size = libneko.neko_field_size(name)
369 dof_ptr = POINTER(c_longlong)()
370 x_ptr = POINTER(c_double)()
371 y_ptr = POINTER(c_double)()
372 z_ptr = POINTER(c_double)()
373 libneko.neko_field_dofmap(name, byref(dof_ptr),
374 byref(x_ptr), byref(y_ptr), byref(z_ptr))
375
376 dofmap = wrap_dofmap(dof_ptr, x_ptr, y_ptr, z_ptr, size)
377
378 return dofmap
379
380def case_fluid_dofmap(case_descr):
381 """ Retrive a dofmap of a Neko case's fluid solver as a `neko_dofmap_t`. """
382 size = c_int()
383 dof_ptr = POINTER(c_longlong)()
384 x_ptr = POINTER(c_double)()
385 y_ptr = POINTER(c_double)()
386 z_ptr = POINTER(c_double)()
387 libneko.neko_case_fluid_dofmap(byref(case_descr), byref(dof_ptr),
388 byref(x_ptr), byref(y_ptr), byref(z_ptr),
389 byref(size))
390
391 dofmap = wrap_dofmap(dof_ptr, x_ptr, y_ptr, z_ptr, size.value)
392
393 return dofmap
394
395def wrap_dofmap(dof_ptr, x_ptr, y_ptr, z_ptr, size):
396 dofmap = neko_dofmap_t(
397 np.frombuffer((c_longlong * size).from_address(
398 addressof(dof_ptr.contents)), dtype=np.dtype(int)),
399 np.frombuffer((c_double * size).from_address(
400 addressof(x_ptr.contents)), dtype=np.dtype(c_double)),
401 np.frombuffer((c_double * size).from_address(
402 addressof(y_ptr.contents)), dtype=np.dtype(c_double)),
403 np.frombuffer((c_double * size).from_address(
404 addressof(z_ptr.contents)), dtype=np.dtype(c_double)),
405 size
406 )
407 return dofmap
408
409def field_space(name):
410 """ Retrive a space of a Neko field as a `neko_space_t`. """
411 lx = c_int()
412 zg = POINTER(c_double)()
413 dr_inv = POINTER(c_double)()
414 ds_inv = POINTER(c_double)()
415 dt_inv = POINTER(c_double)()
416 wx = POINTER(c_double)()
417 wy = POINTER(c_double)()
418 wz = POINTER(c_double)()
419 dx = POINTER(c_double)()
420 dy = POINTER(c_double)()
421 dz = POINTER(c_double)()
422 libneko.neko_field_space(name, byref(lx), byref(zg),
423 byref(dr_inv), byref(ds_inv), byref(dt_inv),
424 byref(wx), byref(wy), byref(wz),
425 byref(dx), byref(dy), byref(dz))
426
427 space = wrap_space(lx.value, zg,
428 dr_inv, ds_inv, dt_inv,
429 wx, wy, wz, dx, dy, dz)
430
431 return space
432
433def case_fluid_space(case_descr):
434 """ Retrive a space of a Neko case's fluid solver as a `neko_space_t`. """
435 lx = c_int()
436 zg = POINTER(c_double)()
437 dr_inv = POINTER(c_double)()
438 ds_inv = POINTER(c_double)()
439 dt_inv = POINTER(c_double)()
440 wx = POINTER(c_double)()
441 wy = POINTER(c_double)()
442 wz = POINTER(c_double)()
443 dx = POINTER(c_double)()
444 dy = POINTER(c_double)()
445 dz = POINTER(c_double)()
446 libneko.neko_case_fluid_space(byref(case_descr), byref(lx), byref(zg),
447 byref(dr_inv), byref(ds_inv), byref(dt_inv),
448 byref(wx), byref(wy), byref(wz),
449 byref(dx), byref(dy), byref(dz))
450
451 space = wrap_space(lx.value, zg,
452 dr_inv, ds_inv, dt_inv,
453 wx, wy, wz, dx, dy, dz)
454
455 return space
456
457def wrap_space(lx, zg, dr_inv, ds_inv, dt_inv, wx, wy, wz, dx, dy, dz):
458 space = neko_space_t(
459 lx,
460 np.frombuffer((c_double * lx * 3).from_address(
461 addressof(zg.contents))),
462 np.frombuffer((c_double * lx).from_address(
463 addressof(dr_inv.contents))),
464 np.frombuffer((c_double * lx).from_address(
465 addressof(ds_inv.contents))),
466 np.frombuffer((c_double * lx).from_address(
467 addressof(dt_inv.contents))),
468 np.frombuffer((c_double * lx).from_address(
469 addressof(wx.contents))),
470 np.frombuffer((c_double * lx).from_address(
471 addressof(wy.contents))),
472 np.frombuffer((c_double * lx).from_address(
473 addressof(wz.contents))),
474 np.frombuffer((c_double * lx * lx).from_address(
475 addressof(dx.contents))),
476 np.frombuffer((c_double * lx * lx).from_address(
477 addressof(dy.contents))),
478 np.frombuffer((c_double * lx * lx).from_address(
479 addressof(dz.contents)))
480 )
481
482 return space
483
484def case_fluid_coef(case_descr):
485 """ Retrive coefficients of a Neko case's fluid solver as a `neko_coef_t`. """
486 G11_ptr = POINTER(c_double)()
487 G22_ptr = POINTER(c_double)()
488 G33_ptr = POINTER(c_double)()
489 G12_ptr = POINTER(c_double)()
490 G13_ptr = POINTER(c_double)()
491 G23_ptr = POINTER(c_double)()
492 mult_ptr = POINTER(c_double)()
493 dxdr_ptr = POINTER(c_double)()
494 dydr_ptr = POINTER(c_double)()
495 dzdr_ptr = POINTER(c_double)()
496 dxds_ptr = POINTER(c_double)()
497 dyds_ptr = POINTER(c_double)()
498 dzds_ptr = POINTER(c_double)()
499 dxdt_ptr = POINTER(c_double)()
500 dydt_ptr = POINTER(c_double)()
501 dzdt_ptr = POINTER(c_double)()
502 drdx_ptr = POINTER(c_double)()
503 drdy_ptr = POINTER(c_double)()
504 drdz_ptr = POINTER(c_double)()
505 dsdx_ptr = POINTER(c_double)()
506 dsdy_ptr = POINTER(c_double)()
507 dsdz_ptr = POINTER(c_double)()
508 dtdx_ptr = POINTER(c_double)()
509 dtdy_ptr = POINTER(c_double)()
510 dtdz_ptr = POINTER(c_double)()
511 jac_ptr = POINTER(c_double)()
512 B_ptr = POINTER(c_double)()
513 area_ptr = POINTER(c_double)()
514 nx_ptr = POINTER(c_double)()
515 ny_ptr = POINTER(c_double)()
516 nz_ptr = POINTER(c_double)()
517
518 libneko.neko_case_fluid_coef(byref(case_descr),
519 byref(G11_ptr),
520 byref(G22_ptr),
521 byref(G33_ptr),
522 byref(G12_ptr),
523 byref(G13_ptr),
524 byref(G23_ptr),
525 byref(mult_ptr),
526 byref(dxdr_ptr),
527 byref(dydr_ptr),
528 byref(dzdr_ptr),
529 byref(dxds_ptr),
530 byref(dyds_ptr),
531 byref(dzds_ptr),
532 byref(dxdt_ptr),
533 byref(dydt_ptr),
534 byref(dzdt_ptr),
535 byref(drdx_ptr),
536 byref(drdy_ptr),
537 byref(drdz_ptr),
538 byref(dsdx_ptr),
539 byref(dsdy_ptr),
540 byref(dsdz_ptr),
541 byref(dtdx_ptr),
542 byref(dtdy_ptr),
543 byref(dtdz_ptr),
544 byref(jac_ptr),
545 byref(B_ptr),
546 byref(area_ptr),
547 byref(nx_ptr),
548 byref(ny_ptr),
549 byref(nz_ptr))
550
551 dm = case_fluid_dofmap(case_descr)
552
553 coef = neko_coef_t(
555 addressof(G11_ptr.contents))),
557 addressof(G22_ptr.contents))),
559 addressof(G33_ptr.contents))),
561 addressof(G12_ptr.contents))),
563 addressof(G13_ptr.contents))),
565 addressof(G23_ptr.contents))),
567 addressof(mult_ptr.contents))),
569 addressof(dxdr_ptr.contents))),
571 addressof(dydr_ptr.contents))),
573 addressof(dzdr_ptr.contents))),
575 addressof(dxds_ptr.contents))),
577 addressof(dyds_ptr.contents))),
579 addressof(dzds_ptr.contents))),
581 addressof(dxdt_ptr.contents))),
583 addressof(dydt_ptr.contents))),
585 addressof(dzdt_ptr.contents))),
587 addressof(drdx_ptr.contents))),
589 addressof(drdy_ptr.contents))),
591 addressof(drdz_ptr.contents))),
593 addressof(dsdx_ptr.contents))),
595 addressof(dsdy_ptr.contents))),
597 addressof(dsdz_ptr.contents))),
599 addressof(dtdx_ptr.contents))),
601 addressof(dtdy_ptr.contents))),
603 addressof(dtdz_ptr.contents))),
605 addressof(jac_ptr.contents))),
607 addressof(B_ptr.contents))),
609 addressof(area_ptr.contents))),
611 addressof(nx_ptr.contents))),
613 addressof(ny_ptr.contents))),
615 addressof(nz_ptr.contents)))
616 )
617
618 return coef
619
620def user_setup(case_descr, cb_initial_condition, cb_preprocess, cb_compute,
621 cb_dirichlet_condition, cb_material_properties, cb_source_term):
622 """ Setup user-provided callbacks. """
623 libneko.neko_user_setup(byref(case_descr),
624 cb_initial_condition,
625 cb_preprocess,
626 cb_compute,
627 cb_dirichlet_condition,
628 cb_material_properties,
629 cb_source_term)
630
631def output(case_descr, force = False):
632 libneko.neko_output_ctrl_execute(byref(case_descr), force)
633
634def callback_field(name):
635 """ Retrive a callback's Neko field as a `neko_field_t`. """
636 a = neko_field_t(
637 np.frombuffer((c_double *
639 addressof(libneko.neko_cb_field_by_name(name).contents)),
640 dtype=np.dtype(c_double)),
641 field_dofmap(name),
642 field_space(name)
643 )
644 return a
645
646def callback_field_name(index, name):
647 """ Check the name of a field at a certain index in the callback's field list. """
648 field_index = c_int(index)
649 same_field = libneko.neko_cb_field_name_at_index(byref(field_index), name)
650 return same_field > 0
651
652def bc_mask(msk, msk_size):
653 mask = np.frombuffer((c_int * msk_size).from_address(
654 addressof(msk.contents)), dtype=np.dtype(np.int32))
655 return mask
656
657#
658# https://degenerateconic.com/fortran-json-python.html
659#
660
662 return cast(create_string_buffer(s.encode()),c_char_p)
663
__global__ void ale_add_kinematics_kernel(const int n, T *__restrict__ wx, T *__restrict__ wy, T *__restrict__ wz, const T *__restrict__ x_ref, const T *__restrict__ y_ref, const T *__restrict__ z_ref, const T *__restrict__ phi, const T *__restrict__ x, const T *__restrict__ y, const T *__restrict__ z, const kinematics_params_t kin_params)
Defines a field.
Definition field.f90:34
Defines an output.
Definition output.f90:34
user_setup(case_descr, cb_initial_condition, cb_preprocess, cb_compute, cb_dirichlet_condition, cb_material_properties, cb_source_term)
Definition intf.py:621
registry_init()
Definition intf.py:267
python_str_to_fortran(s)
Definition intf.py:661
is_done(case_descr)
Definition intf.py:326
registry_free()
Definition intf.py:271
wrap_dofmap(dof_ptr, x_ptr, y_ptr, z_ptr, size)
Definition intf.py:395
job_info()
Definition intf.py:263
wrap_space(lx, zg, dr_inv, ds_inv, dt_inv, wx, wy, wz, dx, dy, dz)
Definition intf.py:457
python_dict_to_fortran(d)
Definition intf.py:664
device_init()
Definition intf.py:255
material_properties
Definition intf.py:29
initial_condition
Definition intf.py:21
device_finalize()
Definition intf.py:259
dirichlet_condition
Definition intf.py:27
finalize()
Definition intf.py:251
Implements the source_term_t type and a wrapper source_term_wrapper_t.