Source code for struphy.geometry.evaluation_kernels

"""
Module containing accelerated (pyccelized) functions for evaluating metric coefficients
corresponding to mappings (x, y, z) = F(eta_1, eta_2, eta_3).
"""

from numpy import empty, shape, zeros
from pyccel.decorators import stack_array

import struphy.geometry.domains.colella.colella_kernels as colella_kernels
import struphy.geometry.domains.cuboid.cuboid_kernels as cuboid_kernels
import struphy.geometry.domains.hollow_cylinder.hollow_cylinder_kernels as hollow_cylinder_kernels
import struphy.geometry.domains.hollow_torus.hollow_torus_kernels as hollow_torus_kernels
import struphy.geometry.domains.orthogonal.orthogonal_kernels as orthogonal_kernels
import struphy.geometry.domains.powered_elliptic_cylinder.powered_elliptic_cylinder_kernels as powered_elliptic_cylinder_kernels
import struphy.geometry.domains.shafranov_dshaped_cylinder.shafranov_dshaped_cylinder_kernels as shafranov_dshaped_cylinder_kernels
import struphy.geometry.domains.shafranov_shift_cylinder.shafranov_shift_cylinder_kernels as shafranov_shift_cylinder_kernels
import struphy.geometry.domains.shafranov_sqrt_cylinder.shafranov_sqrt_cylinder_kernels as shafranov_sqrt_cylinder_kernels
import struphy.geometry.spline_mappings_kernels as spline_mappings_kernels

# do not remove; needed to identify dependencies
import struphy.kernel_arguments.pusher_args_kernels as pusher_args_kernels
import struphy.linear_algebra.linalg_kernels as linalg_kernels
from struphy.kernel_arguments.pusher_args_kernels import DomainArguments


[docs] def f( eta1: float, eta2: float, eta3: float, args: "DomainArguments", f_out: "float[:]", ): """Point-wise evaluation of (x, y, z) = F(eta1, eta2, eta3). Parameters ---------- eta1, eta2, eta3 : float Position on the unit cube. args: DomainArguments Arguments for the mapping. f_out : xp.array Output array of shape (3,). """ if args.kind_map == 0: spline_mappings_kernels.spline_3d( eta1, eta2, eta3, args.degree, args.ind1, args.ind2, args.ind3, args, f_out, ) elif args.kind_map == 1: spline_mappings_kernels.spline_2d_straight( eta1, eta2, eta3, args.degree, args.ind1, args.ind2, args, args.params[0], f_out, ) elif args.kind_map == 2: spline_mappings_kernels.spline_2d_torus( eta1, eta2, eta3, args.degree, args.ind1, args.ind2, args, args.params[0], f_out, ) elif args.kind_map == 10: cuboid_kernels.cuboid( eta1, eta2, eta3, args.params[0], args.params[1], args.params[2], args.params[3], args.params[4], args.params[5], f_out, ) elif args.kind_map == 11: orthogonal_kernels.orthogonal( eta1, eta2, eta3, args.params[0], args.params[1], args.params[2], args.params[3], f_out, ) elif args.kind_map == 12: colella_kernels.colella( eta1, eta2, eta3, args.params[0], args.params[1], args.params[2], args.params[3], f_out, ) elif args.kind_map == 20: hollow_cylinder_kernels.hollow_cyl( eta1, eta2, eta3, args.params[0], args.params[1], args.params[2], args.params[3], f_out, ) elif args.kind_map == 21: powered_elliptic_cylinder_kernels.powered_ellipse( eta1, eta2, eta3, args.params[0], args.params[1], args.params[2], args.params[3], f_out, ) elif args.kind_map == 22: hollow_torus_kernels.hollow_torus( eta1, eta2, eta3, args.params[0], args.params[1], args.params[2], args.params[3], args.params[4], args.params[5], f_out, ) elif args.kind_map == 30: shafranov_shift_cylinder_kernels.shafranov_shift( eta1, eta2, eta3, args.params[0], args.params[1], args.params[2], args.params[3], f_out, ) elif args.kind_map == 31: shafranov_sqrt_cylinder_kernels.shafranov_sqrt( eta1, eta2, eta3, args.params[0], args.params[1], args.params[2], args.params[3], f_out, ) elif args.kind_map == 32: shafranov_dshaped_cylinder_kernels.shafranov_dshaped( eta1, eta2, eta3, args.params[0], args.params[1], args.params[2], args.params[3], args.params[4], args.params[5], args.params[6], f_out, )
[docs] def df( eta1: float, eta2: float, eta3: float, args: "DomainArguments", df_out: "float[:,:]", ): """Point-wise evaluation of the Jacobian matrix DF = (dF_i/deta_j)_(i,j=1,2,3). Parameters ---------- eta1, eta2, eta3 : float Position on the unit cube. args: DomainArguments Arguments for the mapping. df_out : xp.array Output array of shape (3, 3). """ if args.kind_map == 0: spline_mappings_kernels.spline_3d_df( eta1, eta2, eta3, args.degree, args.ind1, args.ind2, args.ind3, args, df_out, ) elif args.kind_map == 1: spline_mappings_kernels.spline_2d_straight_df( eta1, eta2, args.degree, args.ind1, args.ind2, args, args.params[0], df_out, ) elif args.kind_map == 2: spline_mappings_kernels.spline_2d_torus_df( eta1, eta2, eta3, args.degree, args.ind1, args.ind2, args, args.params[0], df_out, ) elif args.kind_map == 10: cuboid_kernels.cuboid_df( args.params[0], args.params[1], args.params[2], args.params[3], args.params[4], args.params[5], df_out, ) elif args.kind_map == 11: orthogonal_kernels.orthogonal_df( eta1, eta2, args.params[0], args.params[1], args.params[2], args.params[3], df_out, ) elif args.kind_map == 12: colella_kernels.colella_df( eta1, eta2, args.params[0], args.params[1], args.params[2], args.params[3], df_out, ) elif args.kind_map == 20: hollow_cylinder_kernels.hollow_cyl_df( eta1, eta2, args.params[0], args.params[1], args.params[2], args.params[3], df_out, ) elif args.kind_map == 21: powered_elliptic_cylinder_kernels.powered_ellipse_df( eta1, eta2, eta3, args.params[0], args.params[1], args.params[2], args.params[3], df_out, ) elif args.kind_map == 22: hollow_torus_kernels.hollow_torus_df( eta1, eta2, eta3, args.params[0], args.params[1], args.params[2], args.params[3], args.params[4], args.params[5], df_out, ) elif args.kind_map == 30: shafranov_shift_cylinder_kernels.shafranov_shift_df( eta1, eta2, eta3, args.params[0], args.params[1], args.params[2], args.params[3], df_out, ) elif args.kind_map == 31: shafranov_sqrt_cylinder_kernels.shafranov_sqrt_df( eta1, eta2, eta3, args.params[0], args.params[1], args.params[2], args.params[3], df_out, ) elif args.kind_map == 32: shafranov_dshaped_cylinder_kernels.shafranov_dshaped_df( eta1, eta2, eta3, args.params[0], args.params[1], args.params[2], args.params[3], args.params[4], args.params[5], args.params[6], df_out, )
[docs] def det_df( eta1: float, eta2: float, eta3: float, args: "DomainArguments", tmp1: "float[:,:]", ) -> float: """Point-wise evaluation of the Jacobian determinant det(dF) = dF/deta1.dot(dF/deta2 x dF/deta3). Parameters ---------- eta1, eta2, eta3 : float Position on the unit cube. args: DomainArguments Arguments for the mapping. tmp1 : xp.array Temporary array of shape (3, 3). """ df( eta1, eta2, eta3, args, tmp1, ) detdf = linalg_kernels.det(tmp1) return detdf
[docs] def df_inv( eta1: float, eta2: float, eta3: float, args: "DomainArguments", tmp1: "float[:,:]", avoid_round_off: bool, dfinv_out: "float[:,:]", ): """Point-wise evaluation of the inverse Jacobian matrix DF^(-1). Parameters ---------- eta1, eta2, eta3 : float Position on the unit cube. args: DomainArguments Arguments for the mapping. tmp1: xp.array Temporary array of shape (3, 3). avoid_round_off: bool Whether to manually set exact zeros in arrays. dfinv_out: xp.array Output array of shape (3, 3). """ df( eta1, eta2, eta3, args, tmp1, ) linalg_kernels.matrix_inv(tmp1, dfinv_out) # set known (analytical) zero components manually to zero to avoid round-off error remainders! if avoid_round_off: if args.kind_map == 1: dfinv_out[0, 2] = 0.0 dfinv_out[1, 2] = 0.0 dfinv_out[2, 0] = 0.0 dfinv_out[2, 1] = 0.0 elif args.kind_map == 2: dfinv_out[2, 2] = 0 elif args.kind_map == 10: dfinv_out[0, 1] = 0.0 dfinv_out[0, 2] = 0.0 dfinv_out[1, 0] = 0.0 dfinv_out[1, 2] = 0.0 dfinv_out[2, 0] = 0.0 dfinv_out[2, 1] = 0.0 elif args.kind_map == 11: dfinv_out[0, 1] = 0.0 dfinv_out[0, 2] = 0.0 dfinv_out[1, 0] = 0.0 dfinv_out[1, 2] = 0.0 dfinv_out[2, 0] = 0.0 dfinv_out[2, 1] = 0.0 elif args.kind_map == 12: dfinv_out[0, 2] = 0.0 dfinv_out[1, 2] = 0.0 dfinv_out[2, 0] = 0.0 dfinv_out[2, 1] = 0.0 elif args.kind_map == 20: dfinv_out[0, 2] = 0.0 dfinv_out[1, 2] = 0.0 dfinv_out[2, 0] = 0.0 dfinv_out[2, 1] = 0.0 elif args.kind_map == 21: dfinv_out[0, 2] = 0.0 dfinv_out[1, 2] = 0.0 dfinv_out[2, 0] = 0.0 dfinv_out[2, 1] = 0.0 elif args.kind_map == 22: dfinv_out[2, 2] = 0.0 elif args.kind_map == 30: dfinv_out[0, 2] = 0.0 dfinv_out[1, 2] = 0.0 dfinv_out[2, 0] = 0.0 dfinv_out[2, 1] = 0.0 elif args.kind_map == 31: dfinv_out[0, 2] = 0.0 dfinv_out[1, 2] = 0.0 dfinv_out[2, 0] = 0.0 dfinv_out[2, 1] = 0.0 elif args.kind_map == 32: dfinv_out[0, 2] = 0.0 dfinv_out[1, 2] = 0.0 dfinv_out[2, 0] = 0.0 dfinv_out[2, 1] = 0.0
[docs] def g( eta1: float, eta2: float, eta3: float, args: "DomainArguments", tmp1: "float[:,:]", tmp2: "float[:,:]", avoid_round_off: bool, g_out: "float[:,:]", ): """Point-wise evaluation of the metric tensor G = DF^T * DF. Parameters ---------- eta1, eta2, eta3: float Position on the unit cube. args: DomainArguments Arguments for the mapping. tmp1, tmp2: xp.array Temporary arrays of shape (3, 3). avoid_round_off: bool Whether to manually set exact zeros in arrays. g_out: xp.array Output array of shape (3, 3). """ df( eta1, eta2, eta3, args, tmp1, ) linalg_kernels.transpose(tmp1, tmp2) linalg_kernels.matrix_matrix(tmp2, tmp1, g_out) # set known (analytical) zero components manually to zero to avoid round-off error remainders! if avoid_round_off: if args.kind_map == 1: g_out[0, 2] = 0.0 g_out[1, 2] = 0.0 g_out[2, 0] = 0.0 g_out[2, 1] = 0.0 elif args.kind_map == 2: g_out[0, 2] = 0.0 g_out[1, 2] = 0.0 g_out[2, 0] = 0.0 g_out[2, 1] = 0.0 elif args.kind_map == 10: g_out[0, 1] = 0.0 g_out[0, 2] = 0.0 g_out[1, 0] = 0.0 g_out[1, 2] = 0.0 g_out[2, 0] = 0.0 g_out[2, 1] = 0.0 elif args.kind_map == 11: g_out[0, 1] = 0.0 g_out[0, 2] = 0.0 g_out[1, 0] = 0.0 g_out[1, 2] = 0.0 g_out[2, 0] = 0.0 g_out[2, 1] = 0.0 elif args.kind_map == 12: g_out[0, 2] = 0.0 g_out[1, 2] = 0.0 g_out[2, 0] = 0.0 g_out[2, 1] = 0.0 elif args.kind_map == 20: g_out[0, 1] = 0.0 g_out[0, 2] = 0.0 g_out[1, 0] = 0.0 g_out[1, 2] = 0.0 g_out[2, 0] = 0.0 g_out[2, 1] = 0.0 elif args.kind_map == 21: g_out[0, 2] = 0.0 g_out[1, 2] = 0.0 g_out[2, 0] = 0.0 g_out[2, 1] = 0.0 elif args.kind_map == 22: # straight field line coordinates if args.params[3] == 1.0: g_out[0, 2] = 0.0 g_out[1, 2] = 0.0 g_out[2, 0] = 0.0 g_out[2, 1] = 0.0 # equal angle coordinates else: g_out[0, 1] = 0.0 g_out[0, 2] = 0.0 g_out[1, 0] = 0.0 g_out[1, 2] = 0.0 g_out[2, 0] = 0.0 g_out[2, 1] = 0.0 elif args.kind_map == 30: g_out[0, 2] = 0.0 g_out[1, 2] = 0.0 g_out[2, 0] = 0.0 g_out[2, 1] = 0.0 elif args.kind_map == 31: g_out[0, 2] = 0.0 g_out[1, 2] = 0.0 g_out[2, 0] = 0.0 g_out[2, 1] = 0.0 elif args.kind_map == 32: g_out[0, 2] = 0.0 g_out[1, 2] = 0.0 g_out[2, 0] = 0.0 g_out[2, 1] = 0.0
[docs] def g_inv( eta1: float, eta2: float, eta3: float, args: "DomainArguments", tmp1: "float[:,:]", tmp2: "float[:,:]", tmp3: "float[:,:]", avoid_round_off: bool, ginv_out: "float[:,:]", ): """Point-wise evaluation of the inverse metric tensor G^(-1) = DF^(-1) * DF^(-T). Parameters ---------- eta1, eta2, eta3: float Position on the unit cube. args: DomainArguments Arguments for the mapping. tmp1, tmp2, tmp3: xp.array Temporary arrays of shape (3, 3). avoid_round_off: bool Whether to manually set exact zeros in arrays. ginv_out: xp.array Output array of shape (3, 3). """ g( eta1, eta2, eta3, args, tmp1, tmp2, avoid_round_off, tmp3, ) linalg_kernels.matrix_inv(tmp3, ginv_out) # set known (analytical) zero components manually to zero to avoid round-off error remainders! if avoid_round_off: if args.kind_map == 1: ginv_out[0, 2] = 0.0 ginv_out[1, 2] = 0.0 ginv_out[2, 0] = 0.0 ginv_out[2, 1] = 0.0 elif args.kind_map == 2: ginv_out[0, 2] = 0.0 ginv_out[1, 2] = 0.0 ginv_out[2, 0] = 0.0 ginv_out[2, 1] = 0.0 elif args.kind_map == 10: ginv_out[0, 1] = 0.0 ginv_out[0, 2] = 0.0 ginv_out[1, 0] = 0.0 ginv_out[1, 2] = 0.0 ginv_out[2, 0] = 0.0 ginv_out[2, 1] = 0.0 elif args.kind_map == 11: ginv_out[0, 1] = 0.0 ginv_out[0, 2] = 0.0 ginv_out[1, 0] = 0.0 ginv_out[1, 2] = 0.0 ginv_out[2, 0] = 0.0 ginv_out[2, 1] = 0.0 elif args.kind_map == 12: ginv_out[0, 2] = 0.0 ginv_out[1, 2] = 0.0 ginv_out[2, 0] = 0.0 ginv_out[2, 1] = 0.0 elif args.kind_map == 20: ginv_out[0, 1] = 0.0 ginv_out[0, 2] = 0.0 ginv_out[1, 0] = 0.0 ginv_out[1, 2] = 0.0 ginv_out[2, 0] = 0.0 ginv_out[2, 1] = 0.0 elif args.kind_map == 21: ginv_out[0, 2] = 0.0 ginv_out[1, 2] = 0.0 ginv_out[2, 0] = 0.0 ginv_out[2, 1] = 0.0 elif args.kind_map == 22: # straight field line coordinates if args.params[3] == 1.0: ginv_out[0, 2] = 0.0 ginv_out[1, 2] = 0.0 ginv_out[2, 0] = 0.0 ginv_out[2, 1] = 0.0 # equal angle coordinates else: ginv_out[0, 1] = 0.0 ginv_out[0, 2] = 0.0 ginv_out[1, 0] = 0.0 ginv_out[1, 2] = 0.0 ginv_out[2, 0] = 0.0 ginv_out[2, 1] = 0.0 elif args.kind_map == 30: ginv_out[0, 2] = 0.0 ginv_out[1, 2] = 0.0 ginv_out[2, 0] = 0.0 ginv_out[2, 1] = 0.0 elif args.kind_map == 31: ginv_out[0, 2] = 0.0 ginv_out[1, 2] = 0.0 ginv_out[2, 0] = 0.0 ginv_out[2, 1] = 0.0 elif args.kind_map == 32: ginv_out[0, 2] = 0.0 ginv_out[1, 2] = 0.0 ginv_out[2, 0] = 0.0 ginv_out[2, 1] = 0.0
[docs] def select_metric_coeff( eta1: float, eta2: float, eta3: float, kind_coeff: int, args: "DomainArguments", tmp0: "float[:]", tmp1: "float[:,:]", tmp2: "float[:,:]", tmp3: "float[:,:]", avoid_round_off: bool, out: "float[:,:]", ): """Point-wise evaluation of metric coefficients. Parameters ---------- eta1, eta2, eta3: float Position on the unit cube. kind_coeff : int Which metric coefficient to evaluate. * -1 : identity * 0 : mapping * 1 : Jacobian matrix * 2 : Jacobian determinant * 3 : inverse Jacobian matrix * 4 : metric tensor * 5 : inverse metric tensor args: DomainArguments Arguments for the mapping. tmp0: xp.array Temporary array of shape (3,). tmp1, tmp2, tmp3: xp.array Temporary arrays of shape (3, 3). avoid_round_off: bool Whether to manually set exact zeros in arrays. out: xp.array Output array of shape (3, 3). """ # identity map if kind_coeff == -1: out[0, 0] = eta1 out[1, 0] = eta2 out[2, 0] = eta3 # mapping F elif kind_coeff == 0: f( eta1, eta2, eta3, args, tmp0, ) out[:, 0] = tmp0 # Jacobian matrix DF elif kind_coeff == 1: df( eta1, eta2, eta3, args, out, ) # Jacobian determinant det(dF) elif kind_coeff == 2: out[0, 0] = det_df( eta1, eta2, eta3, args, tmp1, ) # inverse Jacobian matrix DF^(-1) elif kind_coeff == 3: df_inv( eta1, eta2, eta3, args, tmp1, avoid_round_off, out, ) # metric tensor G = DF^T * DF elif kind_coeff == 4: g( eta1, eta2, eta3, args, tmp1, tmp2, avoid_round_off, out, ) # inverse metric tensor G^(-1) = DF^(-1) * DF^(-T) elif kind_coeff == 5: g_inv( eta1, eta2, eta3, args, tmp1, tmp2, tmp3, avoid_round_off, out, )