Pusher kernels#

Pusher kernels for full orbit (6D) particles.

struphy.pic.pushing.pusher_kernels.push_v_with_efield(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, e1_1: float[:, :, :], e1_2: float[:, :, :], e1_3: float[:, :, :], const: float)[source]#

Updates particle velocities as

\[\frac{\mathbf v^{n+1} - \mathbf v^n}{\Delta t} = c \, \bar{DF}^{-\top} (\mathbb L^1)^\top \mathbf e\]

where \(\mathbf e \in \mathbb R^{N_1}\) are given FE coefficients of the 1-form spline field and \(c \in \mathbb R\) is some constant.

Parameters:
  • e1_1 (ndarray[float]) – 3d array of FE coeffs of E-field as 1-form.

  • e1_2 (ndarray[float]) – 3d array of FE coeffs of E-field as 1-form.

  • e1_3 (ndarray[float]) – 3d array of FE coeffs of E-field as 1-form.

  • const (float) – A constant (usuallly related to the charge-to-mass ratio).

struphy.pic.pushing.pusher_kernels.push_vxb_analytic(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, b2_1: float[:, :, :], b2_2: float[:, :, :], b2_3: float[:, :, :])[source]#

Solves exactly the rotation

\[\frac{\textnormal d \mathbf v_p(t)}{\textnormal d t} = \mathbf v_p(t) \times \frac{DF\, \hat{\mathbf B}^2}{\sqrt g}\]

for each marker \(p\) in markers array, with fixed rotation vector.

Parameters:
  • b2_1 (array[float]) – 3d array of FE coeffs of B-field as 2-form.

  • b2_2 (array[float]) – 3d array of FE coeffs of B-field as 2-form.

  • b2_3 (array[float]) – 3d array of FE coeffs of B-field as 2-form.

struphy.pic.pushing.pusher_kernels.push_vxb_implicit(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, b2_1: float[:, :, :], b2_2: float[:, :, :], b2_3: float[:, :, :])[source]#

Solves the rotation

\[\frac{\textnormal d \mathbf v_p(t)}{\textnormal d t} = \mathbf v_p(t) \times \frac{DF\, \hat{\mathbf B}^2}{\sqrt g}\]

with the Crank-Nicolson method for each marker \(p\) in markers array, with fixed rotation vector.

Parameters:
  • b2_1 (array[float]) – 3d array of FE coeffs of B-field as 2-form.

  • b2_2 (array[float]) – 3d array of FE coeffs of B-field as 2-form.

  • b2_3 (array[float]) – 3d array of FE coeffs of B-field as 2-form.

struphy.pic.pushing.pusher_kernels.push_pxb_analytic(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, b2_1: float[:, :, :], b2_2: float[:, :, :], b2_3: float[:, :, :], a1_1: float[:, :, :], a1_2: float[:, :, :], a1_3: float[:, :, :])[source]#

Solves exactly the rotation

\[\frac{\textnormal d \mathbf v_p(t)}{\textnormal d t} = \mathbf v_p(t) \times \frac{DF\, \hat{\mathbf B}^2}{\sqrt g}\]

for each marker \(p\) in markers array, with fixed rotation vector.

Parameters:
  • b2_1 (array[float]) – 3d array of FE coeffs of B-field as 2-form.

  • b2_2 (array[float]) – 3d array of FE coeffs of B-field as 2-form.

  • b2_3 (array[float]) – 3d array of FE coeffs of B-field as 2-form.

struphy.pic.pushing.pusher_kernels.push_hybrid_xp_lnn(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, p_shape: int[:], p_size: float[:], Nel: int[:], pts1: float[:], pts2: float[:], pts3: float[:], wts1: float[:], wts2: float[:], wts3: float[:], weight: float[:, :, :, :, :, :], thermal: float, n_quad: int[:])[source]#

Solves exactly the rotation

\[\frac{\textnormal d \mathbf v_p(t)}{\textnormal d t} = \mathbf v_p(t) \times \frac{DF\, \hat{\mathbf B}^2}{\sqrt g}\]

for each marker \(p\) in markers array, with fixed rotation vector.

struphy.pic.pushing.pusher_kernels.push_hybrid_xp_ap(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, pn1: int, pn2: int, pn3: int, a1_1: float[:, :, :], a1_2: float[:, :, :], a1_3: float[:, :, :])[source]#

Solves exactly the rotation

\[\frac{\textnormal d \mathbf v_p(t)}{\textnormal d t} = \mathbf v_p(t) \times \frac{DF\, \hat{\mathbf B}^2}{\sqrt g}\]

for each marker \(p\) in markers array, with fixed rotation vector.

struphy.pic.pushing.pusher_kernels.push_bxu_Hdiv(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, b2_1: float[:, :, :], b2_2: float[:, :, :], b2_3: float[:, :, :], u2_1: float[:, :, :], u2_2: float[:, :, :], u2_3: float[:, :, :], boundary_cut: float)[source]#

Updates

\[\frac{\mathbf v^{n+1}_p - \mathbf v^n_p}{\Delta t} = DF^{-\top} \left( \hat{\mathbf B}^2 \times \frac{\hat{\mathbf U}^2}{\sqrt g} \right)^n_p\]

for each marker \(p\) in markers array, where \(\hat{\mathbf U}^2 \in H(\textnormal{div})\).

Parameters:
  • b2_1 (array[float]) – 3d array of FE coeffs of B-field as 2-form.

  • b2_2 (array[float]) – 3d array of FE coeffs of B-field as 2-form.

  • b2_3 (array[float]) – 3d array of FE coeffs of B-field as 2-form.

  • u2_1 (array[float]) – 3d array of FE coeffs of U-field as 2-form.

  • u2_2 (array[float]) – 3d array of FE coeffs of U-field as 2-form.

  • u2_3 (array[float]) – 3d array of FE coeffs of U-field as 2-form.

struphy.pic.pushing.pusher_kernels.push_bxu_Hcurl(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, b2_1: float[:, :, :], b2_2: float[:, :, :], b2_3: float[:, :, :], u1_1: float[:, :, :], u1_2: float[:, :, :], u1_3: float[:, :, :], boundary_cut: float)[source]#

Updates

\[\frac{\mathbf v^{n+1}_p - \mathbf v^n_p}{\Delta t} = DF^{-\top} \left( \hat{\mathbf B}^2 \times G^{-1}\hat{\mathbf U}^1 \right)^n_p\]

for each marker \(p\) in markers array, where \(\hat{\mathbf U}^1 \in H(\textnormal{curl})\).

Parameters:
  • b2_1 (array[float]) – 3d array of FE coeffs of B-field as 2-form.

  • b2_2 (array[float]) – 3d array of FE coeffs of B-field as 2-form.

  • b2_3 (array[float]) – 3d array of FE coeffs of B-field as 2-form.

  • u1_1 (array[float]) – 3d array of FE coeffs of U-field as 1-form.

  • u1_2 (array[float]) – 3d array of FE coeffs of U-field as 1-form.

  • u1_3 (array[float]) – 3d array of FE coeffs of U-field as 1-form.

struphy.pic.pushing.pusher_kernels.push_bxu_H1vec(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, b2_1: float[:, :, :], b2_2: float[:, :, :], b2_3: float[:, :, :], uv_1: float[:, :, :], uv_2: float[:, :, :], uv_3: float[:, :, :], boundary_cut: float)[source]#

Updates

\[\frac{\mathbf v^{n+1}_p - \mathbf v^n_p}{\Delta t} = DF^{-\top} \left( \hat{\mathbf B}^2 \times \hat{\mathbf U} \right)^n_p\]

for each marker \(p\) in markers array, where \(\hat{\mathbf U}\) is a vector-field (dual to 1-form) in \((H^1)^3\).

Parameters:
  • b2_1 (array[float]) – 3d array of FE coeffs of B-field as 2-form.

  • b2_2 (array[float]) – 3d array of FE coeffs of B-field as 2-form.

  • b2_3 (array[float]) – 3d array of FE coeffs of B-field as 2-form.

  • uv_1 (array[float]) – 3d array of FE coeffs of U-field as vector field in (H^1)^3.

  • uv_2 (array[float]) – 3d array of FE coeffs of U-field as vector field in (H^1)^3.

  • uv_3 (array[float]) – 3d array of FE coeffs of U-field as vector field in (H^1)^3.

struphy.pic.pushing.pusher_kernels.push_bxu_Hdiv_pauli(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, pn1: int, pn2: int, pn3: int, b2_1: float[:, :, :], b2_2: float[:, :, :], b2_3: float[:, :, :], u2_1: float[:, :, :], u2_2: float[:, :, :], u2_3: float[:, :, :], b0: float[:, :, :], mu: float[:])[source]#

Updates

\[\frac{\mathbf v^{n+1}_p - \mathbf v^n_p}{\Delta t} = DF^{-\top} \left( \hat{\mathbf B}^2 \times \frac{\hat{\mathbf U}^2}{\sqrt g} - \mu\,\nabla \hat{|\mathbf B|}^0 \right)^n_p\]

for each marker \(p\) in markers array, where \(\hat{\mathbf U}^2 \in H(\textnormal{div})\) and \(\hat{|\mathbf B|}^0 \in H^1\).

Parameters:
  • b2_1 (array[float]) – 3d array of FE coeffs of B-field as 2-form.

  • b2_2 (array[float]) – 3d array of FE coeffs of B-field as 2-form.

  • b2_3 (array[float]) – 3d array of FE coeffs of B-field as 2-form.

  • u2_1 (array[float]) – 3d array of FE coeffs of U-field as 2-form.

  • u2_2 (array[float]) – 3d array of FE coeffs of U-field as 2-form.

  • u2_3 (array[float]) – 3d array of FE coeffs of U-field as 2-form.

  • b0 (array[float]) – 3d array of FE coeffs of abs(B) as 0-form.

  • mu (array[float]) – 1d array of size n_markers holding particle magnetic moments.

struphy.pic.pushing.pusher_kernels.push_pc_GXu_full(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, GXu_11: float[:, :, :], GXu_12: float[:, :, :], GXu_13: float[:, :, :], GXu_21: float[:, :, :], GXu_22: float[:, :, :], GXu_23: float[:, :, :], GXu_31: float[:, :, :], GXu_32: float[:, :, :], GXu_33: float[:, :, :])[source]#

Updates

\[\frac{\mathbf v^{n+1}_p - \mathbf v^n_p}{\Delta t} = - DF^{-\top} \left( \boldsymbol \Lambda^1 \mathbb G \mathcal X(\mathbf u, \mathbf v) \right)^n_p\]

for each marker \(p\) in markers array, where \(\mathbf u\) are the coefficients of the mhd velocity field (either 1-form or 2-form) and \(\mathcal X\) is either the MHD operator struphy.feec.basis_projection_ops.MHDOperators.assemble_X1() (if u is 1-form) or struphy.feec.basis_projection_ops.MHDOperators.assemble_X2() (if u is 2-form).

Parameters:

grad_Xu_ij (array[float]) – 3d array of FE coeffs of \(\nabla_j(\mathcal X \cdot \mathbf u)_i\). i,j=1,2,3.

struphy.pic.pushing.pusher_kernels.push_pc_GXu(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, GXu_11: float[:, :, :], GXu_12: float[:, :, :], GXu_13: float[:, :, :], GXu_21: float[:, :, :], GXu_22: float[:, :, :], GXu_23: float[:, :, :], GXu_31: float[:, :, :], GXu_32: float[:, :, :], GXu_33: float[:, :, :])[source]#

Updates

\[\frac{\mathbf v^{n+1}_p - \mathbf v^n_p}{\Delta t} = - DF^{-\top} \left( \boldsymbol \Lambda^1 \mathbb G \mathcal X(\mathbf u, \mathbf v) \right)^n_p\]

for each marker \(p\) in markers array, where \(\mathbf u\) are the coefficients of the mhd velocity field (either 1-form or 2-form) and \(\mathcal X\) is either the MHD operator struphy.feec.basis_projection_ops.MHDOperators.assemble_X1() (if u is 1-form) or struphy.feec.basis_projection_ops.MHDOperators.assemble_X2() (if u is 2-form).

Parameters:

grad_Xu_ij (array[float]) – 3d array of FE coeffs of \(\nabla_j(\mathcal X \cdot \mathbf u)_i\). i,j=1,2,3.

struphy.pic.pushing.pusher_kernels.push_eta_stage(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, a: float[:], b: float[:], c: float[:])[source]#

Single stage of a s-stage Runge-Kutta solve of

\[\frac{\textnormal d \boldsymbol \eta_p(t)}{\textnormal d t} = DF^{-1}(\boldsymbol \eta_p(t)) \mathbf v\]

for each marker \(p\) in markers array, where \(\mathbf v\) is constant.

struphy.pic.pushing.pusher_kernels.push_pc_eta_stage_Hcurl(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, u_1: float[:, :, :], u_2: float[:, :, :], u_3: float[:, :, :], use_perp_model: bool, a: float[:], b: float[:], c: float[:])[source]#

Fourth order Runge-Kutta solve of

\[\frac{\textnormal d \boldsymbol \eta_p(t)}{\textnormal d t} = DF^{-1}(\boldsymbol \eta_p(t)) \mathbf v + \textnormal{vec}( \hat{\mathbf U}^{1(2)})\]

for each marker \(p\) in markers array, where \(\mathbf v\) is constant and

\[\textnormal{vec}( \hat{\mathbf U}^{1}) = G^{-1}\hat{\mathbf U}^{1}\,,\qquad \textnormal{vec}( \hat{\mathbf U}^{2}) = \frac{\hat{\mathbf U}^{2}}{\sqrt g}\,.\]
struphy.pic.pushing.pusher_kernels.push_pc_eta_stage_Hdiv(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, u_1: float[:, :, :], u_2: float[:, :, :], u_3: float[:, :, :], use_perp_model: bool, a: float[:], b: float[:], c: float[:])[source]#

Fourth order Runge-Kutta solve of

\[\frac{\textnormal d \boldsymbol \eta_p(t)}{\textnormal d t} = DF^{-1}(\boldsymbol \eta_p(t)) \mathbf v + \textnormal{vec}( \hat{\mathbf U}^{1(2)})\]

for each marker \(p\) in markers array, where \(\mathbf v\) is constant and

\[\textnormal{vec}( \hat{\mathbf U}^{1}) = G^{-1}\hat{\mathbf U}^{1}\,,\qquad \textnormal{vec}( \hat{\mathbf U}^{2}) = \frac{\hat{\mathbf U}^{2}}{\sqrt g}\,.\]
struphy.pic.pushing.pusher_kernels.push_pc_eta_stage_H1vec(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, u_1: float[:, :, :], u_2: float[:, :, :], u_3: float[:, :, :], use_perp_model: bool, a: float[:], b: float[:], c: float[:])[source]#

Fourth order Runge-Kutta solve of

\[\frac{\textnormal d \boldsymbol \eta_p(t)}{\textnormal d t} = DF^{-1}(\boldsymbol \eta_p(t)) \mathbf v + \textnormal{vec}( \hat{\mathbf U}^{1(2)})\]

for each marker \(p\) in markers array, where \(\mathbf v\) is constant and

\[\textnormal{vec}( \hat{\mathbf U}^{1}) = G^{-1}\hat{\mathbf U}^{1}\,,\qquad \textnormal{vec}( \hat{\mathbf U}^{2}) = \frac{\hat{\mathbf U}^{2}}{\sqrt g}\,.\]
Parameters:
  • u_1 (array[float]) – 3d array of FE coeffs of U-field, either as 1-form or as 2-form.

  • u_2 (array[float]) – 3d array of FE coeffs of U-field, either as 1-form or as 2-form.

  • u_3 (array[float]) – 3d array of FE coeffs of U-field, either as 1-form or as 2-form.

  • u_basis (int) – U is 1-form (u_basis=1) or a 2-form (u_basis=2).

struphy.pic.pushing.pusher_kernels.push_weights_with_efield_lin_va(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, e1_1: float[:, :, :], e1_2: float[:, :, :], e1_3: float[:, :, :], f0_values: float[:], kappa: float, vth: float)[source]#

updates the single weights in the e_W substep of the linear Vlasov Ampère system with delta-f; c.f. EfieldWeights.

Parameters:
  • e1_1 (array[float]) – 3d array of FE coeffs of E-field as 1-form.

  • e1_2 (array[float]) – 3d array of FE coeffs of E-field as 1-form.

  • e1_3 (array[float]) – 3d array of FE coeffs of E-field as 1-form.

  • f0_values (array[float]) – Value of f0 for each particle.

  • kappa (float) – = 2 * pi * Omega_c / omega ; Parameter determining the coupling strength between particles and fields

struphy.pic.pushing.pusher_kernels.push_deterministic_diffusion_stage(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, pi_u: float[:, :, :], pi_grad_u1: float[:, :, :], pi_grad_u2: float[:, :, :], pi_grad_u3: float[:, :, :], diffusion_coeff: float, a: float[:], b: float[:], c: float[:])[source]#

Single stage of a s-stage Runge-Kutta solve of

\[\frac{\textnormal d \boldsymbol \eta_p(t)}{\textnormal d t} = - D \,G^{-1}(\boldsymbol \eta_p(t)) \frac{\nabla \hat u^0}{\hat u^0}(\boldsymbol \eta_p(t))\]

for each marker \(p\) in markers array, where \(\frac{\nabla \hat u^0}{\hat u^0}\) is constant in time. \(D>0\) is a positive, constant diffusion coefficient.

struphy.pic.pushing.pusher_kernels.push_random_diffusion_stage(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, noise: float[:, :], diffusion_coeff: float, a: float[:], b: float[:], c: float[:])[source]#

Single stage of a s-stage Runge-Kutta solve of

\[{\textnormal d \boldsymbol \eta_p(t)} = \sqrt{2 \, D}\, \textnormal d \boldsymbol B_t\,,\]

for each marker \(p\) in markers array, where \(\textnormal d \boldsymbol B_t\) is a Brownian Motion and $D$ is a positive diffusion coefficient.

struphy.pic.pushing.pusher_kernels.push_v_sph_pressure(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, boxes: int[:, :], neighbours: int[:, :], holes: bool[:], periodic1: bool, periodic2: bool, periodic3: bool, kernel_type: int, h1: float, h2: float, h3: float, gravity: float[:])[source]#

Updates particle velocities as

\[\frac{\mathbf v^{n+1} - \mathbf v^n}{\Delta t} = \kappa_p \sum_{q} w_p\,w_q \left( \frac{1}{\rho^{N,h}(\boldsymbol \eta_p)} + \frac{1}{\rho^{N,h}(\boldsymbol \eta_q)} \right) G^{-1}\nabla W_h(\boldsymbol \eta_p - \boldsymbol \eta_q) \,,\]

where \(G^{-1}\) denotes the inverse metric tensor, and with the smoothed density

\[\rho^{N,h}(\boldsymbol \eta_p) = \frac 1N \sum_q w_q \, W_h(\boldsymbol \eta_p - \boldsymbol \eta_q)\,,\]

where \(W_h(\boldsymbol \eta)\) is a smoothing kernel from sph_smoothing_kernels.

Parameters:
  • boxes (2d array) – Box array of the sorting boxes structure.

  • neighbours (2d array) – Array containing the 27 neighbouring boxes of each box.

  • holes (bool) – 1D array of length markers.shape[0]. True if markers[i] is a hole.

  • periodic1 (bool) – True if periodic in that dimension.

  • periodic2 (bool) – True if periodic in that dimension.

  • periodic3 (bool) – True if periodic in that dimension.

  • kernel_type (int) – Number of the smoothing kernel.

  • h1 (float) – Kernel width in respective dimension.

  • h2 (float) – Kernel width in respective dimension.

  • h3 (float) – Kernel width in respective dimension.

  • gravity (xp.ndarray) – Constant gravitational force as 3-vector.

struphy.pic.pushing.pusher_kernels.push_v_sph_pressure_ideal_gas(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, boxes: int[:, :], neighbours: int[:, :], holes: bool[:], periodic1: bool, periodic2: bool, periodic3: bool, kernel_type: int, h1: float, h2: float, h3: float, gravity: float[:])[source]#

Updates particle velocities as

\[\frac{\mathbf v^{n+1} - \mathbf v^n}{\Delta t} = \kappa_p \sum_{q} w_p\,w_q \left( \frac{1}{\rho^{N,h}(\boldsymbol \eta_p)} + \frac{1}{\rho^{N,h}(\boldsymbol \eta_q)} \right) G^{-1}\nabla W_h(\boldsymbol \eta_p - \boldsymbol \eta_q) \,,\]

where \(G^{-1}\) denotes the inverse metric tensor, and with the smoothed density

\[\rho^{N,h}(\boldsymbol \eta_p) = \frac 1N \sum_q w_q \, W_h(\boldsymbol \eta_p - \boldsymbol \eta_q)\,,\]

where \(W_h(\boldsymbol \eta)\) is a smoothing kernel from sph_smoothing_kernels.

Parameters:
  • boxes (2d array) – Box array of the sorting boxes structure.

  • neighbours (2d array) – Array containing the 27 neighbouring boxes of each box.

  • holes (bool) – 1D array of length markers.shape[0]. True if markers[i] is a hole.

  • periodic1 (bool) – True if periodic in that dimension.

  • periodic2 (bool) – True if periodic in that dimension.

  • periodic3 (bool) – True if periodic in that dimension.

  • kernel_type (int) – Number of the smoothing kernel.

  • h1 (float) – Kernel width in respective dimension.

  • h2 (float) – Kernel width in respective dimension.

  • h3 (float) – Kernel width in respective dimension.

  • gravity (xp.ndarray) – Constant gravitational force as 3-vector.

struphy.pic.pushing.pusher_kernels.push_v_viscosity(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, boxes: int[:, :], neighbours: int[:, :], holes: bool[:], periodic1: bool, periodic2: bool, periodic3: bool, kernel_type: int, h1: float, h2: float, h3: float)[source]#

Updates particle velocities as

\[\frac{\mathbf v^{n+1} - \mathbf v^n}{\Delta t} = \kappa_p \sum_{q} w_p\,w_q \left( \frac{1}{\rho^{N,h}(\boldsymbol \eta_p)} + \frac{1}{\rho^{N,h}(\boldsymbol \eta_q)} \right) G^{-1}\nabla W_h(\boldsymbol \eta_p - \boldsymbol \eta_q) \,,\]

where \(G^{-1}\) denotes the inverse metric tensor, and with the smoothed density

\[\rho^{N,h}(\boldsymbol \eta_p) = \frac 1N \sum_q w_q \, W_h(\boldsymbol \eta_p - \boldsymbol \eta_q)\,,\]

where \(W_h(\boldsymbol \eta)\) is a smoothing kernel from sph_smoothing_kernels.

Parameters:
  • boxes (2d array) – Box array of the sorting boxes structure.

  • neighbours (2d array) – Array containing the 27 neighbouring boxes of each box.

  • holes (bool) – 1D array of length markers.shape[0]. True if markers[i] is a hole.

  • periodic1 (bool) – True if periodic in that dimension.

  • periodic2 (bool) – True if periodic in that dimension.

  • periodic3 (bool) – True if periodic in that dimension.

  • kernel_type (int) – Number of the smoothing kernel.

  • h1 (float) – Kernel width in respective dimension.

  • h2 (float) – Kernel width in respective dimension.

  • h3 (float) – Kernel width in respective dimension.

  • gravity (xp.ndarray) – Constant gravitational force as 3-vector.

Pusher kernels guiding-center#

Pusher kernels for gyro-center (5D) dynamics.

struphy.pic.pushing.pusher_kernels_gc.push_gc_bxEstar_explicit_multistage(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, epsilon: float, unit_b1_1: float[:, :, :], unit_b1_2: float[:, :, :], unit_b1_3: float[:, :, :], grad_b_full_1: float[:, :, :], grad_b_full_2: float[:, :, :], grad_b_full_3: float[:, :, :], B_dot_b_coeffs: float[:, :, :], curl_unit_b_dot_b0: float[:, :, :], e_field_1: float[:, :, :], e_field_2: float[:, :, :], e_field_3: float[:, :, :], evaluate_e_field: bool, a: float[:], b: float[:], c: float[:])[source]#

Single stage of an s-stage explicit Runge-Kutta scheme for solving

\[\frac{\textnormal d \boldsymbol \eta_p(t)}{\textnormal d t} = \frac{\hat{\mathbf E}^{*1} \times \hat{\mathbf b}^1_0}{\sqrt g\,\hat B_\parallel^{*}} (\boldsymbol \eta_p(t)) \,,\]

where

\[\hat{\mathbf E}^{*1} = - \hat \nabla \hat \phi -\varepsilon \mu_p \hat \nabla \hat B\,,\qquad \hat B^*_\parallel = \hat B + \varepsilon v_{\parallel,p} \widehat{\left[(\nabla \times \mathbf b_0) \cdot \mathbf b_0\right]}\,,\]

for each marker \(p\) in markers array.

struphy.pic.pushing.pusher_kernels_gc.push_gc_bxEstar_discrete_gradient_1st_order(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, epsilon: float, grad_b_full_1: float[:, :, :], grad_b_full_2: float[:, :, :], grad_b_full_3: float[:, :, :], e_field_1: float[:, :, :], e_field_2: float[:, :, :], e_field_3: float[:, :, :], evaluate_e_field: bool)[source]#

For each marker \(p\) in markers array, make one step of Picard iteration (index \(k\)) for

\[\frac{\boldsymbol \eta_p^{n+1, k+1} - \boldsymbol \eta_p^{n}}{\Delta t} = \frac{\hat{\mathbf b}^1_0}{\sqrt g\,\hat B_\parallel^{*}} (\mathbf Z_p^{n}) \times \frac{\partial \overline H}{\partial \boldsymbol \eta} (\mathbf Z_p^{n+1, k}, \mathbf Z_p^{n} ) \,,\]

where the Hamiltonian reads

\[H(\mathbf Z) = H(\boldsymbol \eta, v_{\parallel}) = \varepsilon\frac{v_{\parallel}^2}{2} + \varepsilon\mu_p |\hat{\mathbf B}| (\boldsymbol \eta) + \hat \phi(\boldsymbol \eta)\,,\]

and where

\[\frac{\partial \overline H}{\partial \boldsymbol \eta} (\mathbf Z_p^{n+1, k}, \mathbf Z_p^{n}) = \frac{\partial H}{\partial \boldsymbol \eta} \left( \frac{\mathbf Z_p^{n+1, k} + \mathbf Z_p^{n}}{2} \right) + (\boldsymbol \eta_p^{n+1, k} - \boldsymbol \eta_p^{n}) \, \frac{H(\mathbf Z_p^{n+1, k}) - H(\mathbf Z_p^{n}) - (\boldsymbol \eta_p^{n+1, k} - \boldsymbol \eta_p^{n}) \cdot \frac{\partial H}{\partial \boldsymbol \eta} \left( \frac{\mathbf Z_p^{n+1, k} + \mathbf Z_p^{n}}{2} \right)}{||\mathbf Z_p^{n+1, k} - \mathbf Z_p^{n}||}\,,\]

is the Gonzalez discrete gradient.

struphy.pic.pushing.pusher_kernels_gc.push_gc_bxEstar_discrete_gradient_2nd_order(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, epsilon: float, unit_b1_1: float[:, :, :], unit_b1_2: float[:, :, :], unit_b1_3: float[:, :, :], grad_b_full_1: float[:, :, :], grad_b_full_2: float[:, :, :], grad_b_full_3: float[:, :, :], B_dot_b_coeffs: float[:, :, :], curl_unit_b_dot_b0: float[:, :, :], e_field_1: float[:, :, :], e_field_2: float[:, :, :], e_field_3: float[:, :, :], evaluate_e_field: bool)[source]#

For each marker \(p\) in markers array, make one step of Picard iteration (index \(k\)) for

\[\frac{\boldsymbol \eta_p^{n+1, k+1} - \boldsymbol \eta_p^{n}}{\Delta t} = \frac{\hat{\mathbf b}^1_0}{\sqrt g\,\hat B_\parallel^{*}} \left( \frac{\mathbf Z_p^{n+1, k} + \mathbf Z_p^{n}}{2} \right) \times \frac{\partial \overline H}{\partial \boldsymbol \eta} (\mathbf Z_p^{n+1, k}, \mathbf Z_p^{n} ) \,,\]

where the Hamiltonian reads

\[H(\mathbf Z) = H(\boldsymbol \eta, v_{\parallel}) = \varepsilon\frac{v_{\parallel}^2}{2} + \varepsilon\mu_p |\hat{\mathbf B}| (\boldsymbol \eta) + \hat \phi(\boldsymbol \eta)\,,\]

and where

\[\frac{\partial \overline H}{\partial \boldsymbol \eta} (\mathbf Z_p^{n+1, k}, \mathbf Z_p^{n}) = \frac{\partial H}{\partial \boldsymbol \eta} \left( \frac{\mathbf Z_p^{n+1, k} + \mathbf Z_p^{n}}{2} \right) + (\boldsymbol \eta_p^{n+1, k} - \boldsymbol \eta_p^{n}) \, \frac{H(\mathbf Z_p^{n+1, k}) - H(\mathbf Z_p^{n}) - (\boldsymbol \eta_p^{n+1, k} - \boldsymbol \eta_p^{n}) \cdot \frac{\partial H}{\partial \boldsymbol \eta} \left( \frac{\mathbf Z_p^{n+1, k} + \mathbf Z_p^{n}}{2} \right)}{||\mathbf Z_p^{n+1, k} - \mathbf Z_p^{n}||}\,,\]

is the Gonzalez discrete gradient.

Notes

This kernel performs evaluations at mid-points. Other evaluations are performed in init_kernels and eval_kernels, respectively.

struphy.pic.pushing.pusher_kernels_gc.push_gc_bxEstar_discrete_gradient_1st_order_newton(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, epsilon: float, grad_b_full_1: float[:, :, :], grad_b_full_2: float[:, :, :], grad_b_full_3: float[:, :, :], B_dot_b_coeffs: float[:, :, :], e_field_1: float[:, :, :], e_field_2: float[:, :, :], e_field_3: float[:, :, :], phi_coeffs: float[:, :, :], evaluate_e_field: bool)[source]#

For each marker \(p\) in markers array, make one step of Newton iteration for

\[\frac{\boldsymbol \eta_p^{n+1} - \boldsymbol \eta_p^{n}}{\Delta t} = \frac{\hat{\mathbf b}^1_0}{\sqrt g\,\hat B_\parallel^{*}} (\mathbf Z_p^{n}) \times \frac{\partial \overline H}{\partial \boldsymbol \eta} (\boldsymbol \eta_p^{n+1}, \boldsymbol \eta_p^{n} ) \,,\]

where the Hamiltonian reads

\[H(\mathbf Z) = H(\boldsymbol \eta, v_{\parallel}) = \varepsilon\frac{v_{\parallel}^2}{2} + \varepsilon\mu_p |\hat{\mathbf B}| (\boldsymbol \eta) + \hat \phi(\boldsymbol \eta)\,,\]

and where

\[\begin{split}\frac{\partial \overline H}{\partial \boldsymbol \eta} (\boldsymbol \eta_p^{n+1}, \boldsymbol \eta_p^{n}) = \begin{pmatrix} \frac{H(\eta_{p,1}^{n+1}) - H}{\eta_{p,1}^{n+1} - \eta_{p,1}^n} \\[1mm] \frac{H(\eta_{p,1}^{n+1}, \eta_{p,2}^{n+1}) - H(\eta_{p,1}^{n+1})}{\eta_{p,2}^{n+1} - \eta_{p,2}^n} \\[1mm] \frac{H(\eta_{p,1}^{n+1}, \eta_{p,2}^{n+1}, \eta_{p,3}^{n+1}) - H(\eta_{p,1}^{n+1}, \eta_{p,2}^{n+1})}{\eta_{p,3}^{n+1} - \eta_{p,3}^n} \end{pmatrix}\,,\end{split}\]

is the Itoh-Abe discrete gradient. The Newton algorithm searches the roots of

\[\mathbf F(\boldsymbol \eta_p^{n+1}) = \boldsymbol \eta_p^{n+1} - \boldsymbol \eta_p^{n} - \Delta t \frac{\hat{\mathbf b}^1_0}{\sqrt g\,\hat B_\parallel^{*}} (\mathbf Z_p^{n}) \times \frac{\partial \overline H}{\partial \boldsymbol \eta} (\boldsymbol \eta_p^{n+1}, \boldsymbol \eta_p^{n}) = 0\,,\]

via (iteration index \(k\))

\[\boldsymbol \eta_p^{n+1, k+1} = \boldsymbol \eta_p^{n+1, k} - D\mathbf F^{-1}(\boldsymbol \eta_p^{n+1, k}) \mathbf F( \boldsymbol \eta_p^{n+1, k})\,,\]

where the Jacobian is given by

\[D\mathbf F(\boldsymbol \eta_p^{n+1, k}) = \mathbb I_{3\times 3} - \Delta t \frac{\hat{\mathbf b}^1_0}{\sqrt g\,\hat B_\parallel^{*}} (\mathbf Z_p^{n}) \times D\frac{\partial \overline H}{\partial \boldsymbol \eta} (\boldsymbol \eta_p^{n+1}, \boldsymbol \eta_p^{n})\,.\]

Notes

This kernel performs evaluations at \(\boldsymbol \eta_p^{n+1, k}\). Other evaluations are performed in init_kernels and eval_kernels, respectively.

struphy.pic.pushing.pusher_kernels_gc.push_gc_Bstar_explicit_multistage(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, epsilon: float, grad_b_full_1: float[:, :, :], grad_b_full_2: float[:, :, :], grad_b_full_3: float[:, :, :], b2_1: float[:, :, :], b2_2: float[:, :, :], b2_3: float[:, :, :], curl_unit_b2_1: float[:, :, :], curl_unit_b2_2: float[:, :, :], curl_unit_b2_3: float[:, :, :], B_dot_b_coeffs: float[:, :, :], curl_unit_b_dot_b0: float[:, :, :], e_field_1: float[:, :, :], e_field_2: float[:, :, :], e_field_3: float[:, :, :], evaluate_e_field: bool, a: float[:], b: float[:], c: float[:])[source]#

Single stage of an s-stage explicit Runge-Kutta scheme for solving

\[\begin{split}\left\{ \begin{aligned} \frac{\textnormal d \boldsymbol \eta_p(t)}{\textnormal d t} &= v_{\parallel,p}(t) \frac{\hat{\mathbf B}^{*2}}{\sqrt g \,\hat B^{*}_\parallel}(\boldsymbol \eta_p(t)) \,, \\ \frac{\textnormal d v_{\parallel,p}(t)}{\textnormal d t} &= \frac{1}{\varepsilon} \frac{\hat{\mathbf B}^{*2}}{\sqrt g\, \hat B^{*}_\parallel} \cdot \hat{\mathbf E}^{*1} (\boldsymbol \eta_p(t)) \,, \end{aligned} \right.\end{split}\]

where

\[\hat{\mathbf E}^{*1} = - \hat \nabla \hat \phi - \varepsilon \mu_p \hat \nabla \hat B\,,\qquad \hat{\mathbf B}^{*2} = \hat{\mathbf B}^2 + \varepsilon v_\parallel \hat \nabla \times \hat{\mathbf b}^1_0\,,\qquad \hat B^*_\parallel = \hat B + \varepsilon v_{\parallel,p} \widehat{\left[(\nabla \times \mathbf b_0) \cdot \mathbf b_0\right]}\,,\]

for each marker \(p\) in markers array.

struphy.pic.pushing.pusher_kernels_gc.push_gc_Bstar_discrete_gradient_1st_order(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, epsilon: float, grad_b_full_1: float[:, :, :], grad_b_full_2: float[:, :, :], grad_b_full_3: float[:, :, :], e_field_1: float[:, :, :], e_field_2: float[:, :, :], e_field_3: float[:, :, :], evaluate_e_field: bool)[source]#

For each marker \(p\) in markers array, make one step of Picard iteration (index \(k\)) for

\[\begin{split}\left\{ \begin{aligned} \frac{\boldsymbol \eta_p^{n+1, k+1} - \boldsymbol \eta_p^{n}}{\Delta t} &= \frac 1 \varepsilon\frac{\hat{\mathbf B}^{*2}}{\sqrt g \,\hat B^{*}_\parallel} (\mathbf Z_p^{n}) \frac{\partial \overline H}{\partial v_{\parallel}} (\mathbf Z_p^{n+1, k}, \mathbf Z_p^{n})\,, \\ \frac{v_{\parallel,p}^{n+1,k+1} - v_{\parallel,p}^{n}}{\Delta t} &= - \frac 1 \varepsilon\frac{\hat{\mathbf B}^{*2}}{\sqrt g\, \hat B^{*}_\parallel} (\mathbf Z_p^{n}) \cdot \frac{\partial \overline H}{\partial \boldsymbol \eta} (\mathbf Z_p^{n+1, k}, \mathbf Z_p^{n})\,, \end{aligned} \right.\end{split}\]

where the Hamiltonian reads

\[H(\mathbf Z) = H(\boldsymbol \eta, v_{\parallel}) = \varepsilon\frac{v_{\parallel}^2}{2} + \varepsilon\mu_p |\hat{\mathbf B}| (\boldsymbol \eta) + \hat \phi(\boldsymbol \eta)\,,\]

and where

\[\frac{\partial \overline H}{\partial \mathbf Z} (\mathbf Z_p^{n+1, k}, \mathbf Z_p^{n}) = \frac{\partial H}{\partial \mathbf Z} \left( \frac{\mathbf Z_p^{n+1, k} + \mathbf Z_p^{n}}{2} \right) + (\mathbf Z_p^{n+1, k} - \mathbf Z_p^{n}) \, \frac{H(\mathbf Z_p^{n+1, k}) - H(\mathbf Z_p^{n}) - (\mathbf Z_p^{n+1, k} - \mathbf Z_p^{n}) \cdot \frac{\partial H}{\partial \mathbf Z} \left( \frac{\mathbf Z_p^{n+1, k} + \mathbf Z_p^{n}}{2} \right)}{||\mathbf Z_p^{n+1, k} - \mathbf Z_p^{n}||}\,,\]

is the Gonzalez discrete gradient.

struphy.pic.pushing.pusher_kernels_gc.push_gc_Bstar_discrete_gradient_2nd_order(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, epsilon: float, grad_b_full_1: float[:, :, :], grad_b_full_2: float[:, :, :], grad_b_full_3: float[:, :, :], b2_1: float[:, :, :], b2_2: float[:, :, :], b2_3: float[:, :, :], curl_unit_b2_1: float[:, :, :], curl_unit_b2_2: float[:, :, :], curl_unit_b2_3: float[:, :, :], B_dot_b_coeffs: float[:, :, :], curl_unit_b_dot_b0: float[:, :, :], e_field_1: float[:, :, :], e_field_2: float[:, :, :], e_field_3: float[:, :, :], evaluate_e_field: bool)[source]#

For each marker \(p\) in markers array, make one step of Picard iteration (index \(k\)) for

\[\begin{split}\left\{ \begin{aligned} \frac{\boldsymbol \eta_p^{n+1, k+1} - \boldsymbol \eta_p^{n}}{\Delta t} &= \frac 1 \varepsilon\frac{\hat{\mathbf B}^{*2}}{\sqrt g \,\hat B^{*}_\parallel} \left( \frac{\mathbf Z_p^{n+1, k} + \mathbf Z_p^{n}}{2} \right) \frac{\partial \overline H}{\partial v_{\parallel}} (\mathbf Z_p^{n+1, k}, \mathbf Z_p^{n})\,, \\ \frac{v_{\parallel,p}^{n+1,k+1} - v_{\parallel,p}^{n}}{\Delta t} &= - \frac 1 \varepsilon\frac{\hat{\mathbf B}^{*2}}{\sqrt g\, \hat B^{*}_\parallel} \left( \frac{\mathbf Z_p^{n+1, k} + \mathbf Z_p^{n}}{2} \right) \cdot \frac{\partial \overline H}{\partial \boldsymbol \eta} (\mathbf Z_p^{n+1, k}, \mathbf Z_p^{n})\,, \end{aligned} \right.\end{split}\]

where the Hamiltonian reads

\[H(\mathbf Z) = H(\boldsymbol \eta, v_{\parallel}) =\varepsilon\frac{v_{\parallel}^2}{2} + \varepsilon\mu_p |\hat{\mathbf B}| (\boldsymbol \eta) + \hat \phi(\boldsymbol \eta)\,,\]

and where

\[\frac{\partial \overline H}{\partial \mathbf Z} (\mathbf Z_p^{n+1, k}, \mathbf Z_p^{n}) = \frac{\partial H}{\partial \mathbf Z} \left( \frac{\mathbf Z_p^{n+1, k} + \mathbf Z_p^{n}}{2} \right) + (\mathbf Z_p^{n+1, k} - \mathbf Z_p^{n}) \, \frac{H(\mathbf Z_p^{n+1, k}) - H(\mathbf Z_p^{n}) - (\mathbf Z_p^{n+1, k} - \mathbf Z_p^{n}) \cdot \frac{\partial H}{\partial \mathbf Z} \left( \frac{\mathbf Z_p^{n+1, k} + \mathbf Z_p^{n}}{2} \right)}{||\mathbf Z_p^{n+1, k} - \mathbf Z_p^{n}||}\,,\]

is the Gonzalez discrete gradient.

Notes

This kernel performs evaluations at mid-points. Other evaluations are performed in init_kernels and eval_kernels, respectively.

struphy.pic.pushing.pusher_kernels_gc.push_gc_Bstar_discrete_gradient_1st_order_newton(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, epsilon: float, grad_b_full_1: float[:, :, :], grad_b_full_2: float[:, :, :], grad_b_full_3: float[:, :, :], B_dot_b_coeffs: float[:, :, :], e_field_1: float[:, :, :], e_field_2: float[:, :, :], e_field_3: float[:, :, :], phi_coeffs: float[:, :, :], evaluate_e_field: bool)[source]#

For each marker \(p\) in markers array, make one step of Newton iteration for

\[\begin{split}\left\{ \begin{aligned} \frac{\boldsymbol \eta_p^{n+1, k+1} - \boldsymbol \eta_p^{n}}{\Delta t} &= \frac 1 \varepsilon\frac{\hat{\mathbf B}^{*2}}{\sqrt g \,\hat B^{*}_\parallel} (\mathbf Z_p^{n}) \frac{\partial \overline H}{\partial v_{\parallel}} (\mathbf Z_p^{n+1, k}, \mathbf Z_p^{n})\,, \\ \frac{v_{\parallel,p}^{n+1,k+1} - v_{\parallel,p}^{n}}{\Delta t} &= - \frac 1 \varepsilon\frac{\hat{\mathbf B}^{*2}}{\sqrt g\, \hat B^{*}_\parallel} (\mathbf Z_p^{n}) \cdot \frac{\partial \overline H}{\partial \boldsymbol \eta} (\mathbf Z_p^{n+1, k}, \mathbf Z_p^{n})\,, \end{aligned} \right.\end{split}\]

where the Hamiltonian reads

\[H(\mathbf Z) = H(\boldsymbol \eta, v_{\parallel}) = \varepsilon\frac{v_{\parallel}^2}{2} + \varepsilon\mu_p |\hat{\mathbf B}| (\boldsymbol \eta) + \hat \phi(\boldsymbol \eta)\,,\]

and where

\[\begin{split}\frac{\partial \overline H}{\partial \mathbf Z} (\mathbf Z_p^{n+1}, \mathbf Z_p^{n}) = \begin{pmatrix} \frac{H(\eta_{p,1}^{n+1}) - H}{\eta_{p,1}^{n+1} - \eta_{p,1}^n} \\[1mm] \frac{H(\eta_{p,1}^{n+1}, \eta_{p,2}^{n+1}) - H(\eta_{p,1}^{n+1})}{\eta_{p,2}^{n+1} - \eta_{p,2}^n} \\[1mm] \frac{H(\eta_{p,1}^{n+1}, \eta_{p,2}^{n+1}, \eta_{p,3}^{n+1}) - H(\eta_{p,1}^{n+1}, \eta_{p,2}^{n+1})}{\eta_{p,3}^{n+1} - \eta_{p,3}^n} \\[1mm] \frac{H(\eta_{p,1}^{n+1}, \eta_{p,2}^{n+1}, \eta_{p,3}^{n+1}, v_{\parallel, p}^{n+1}) - H(\eta_{p,1}^{n+1}, \eta_{p,2}^{n+1}, \eta_{p,3}^{n+1})}{v_{\parallel, p}^{n+1} - v_{\parallel,p}^n} \end{pmatrix}\,,\end{split}\]

is the Itoh-Abe discrete gradient. The Newton algorithm searches the roots of

\[\mathbf F(\mathbf Z_p^{n+1}) = \mathbf Z_p^{n+1} - \mathbf Z_p^{n} - \Delta t \mathbb J (\mathbf Z_p^{n}) \frac{\partial \overline H}{\partial \mathbf Z} (\mathbf Z_p^{n+1}, \mathbf Z_p^{n}) = 0\,,\]

via (iteration index \(k\))

\[\mathbf Z^{n+1, k+1} = \mathbf Z_p^{n+1, k} - D\mathbf F^{-1}(\mathbf Z_p^{n+1, k}) \mathbf F( \mathbf Z_p^{n+1, k})\,,\]

where the Jacobian is given by

\[D\mathbf F(\boldsymbol \eta_p^{n+1, k}) = \mathbb I_{3\times 3} - \Delta t \mathbb J (\mathbf Z_p^{n}) D\frac{\partial \overline H}{\partial \mathbf Z} (\mathbf Z_p^{n+1}, \mathbf Z_p^{n})\,.\]

Notes

This kernel performs evaluations at \(\mathbf Z_p^{n+1, k}\). Other evaluations are performed in init_kernels and eval_kernels, respectively.

struphy.pic.pushing.pusher_kernels_gc.push_gc_cc_J1_H1vec(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, epsilon: float, b1: float[:, :, :], b2: float[:, :, :], b3: float[:, :, :], norm_b11: float[:, :, :], norm_b12: float[:, :, :], norm_b13: float[:, :, :], curl_norm_b1: float[:, :, :], curl_norm_b2: float[:, :, :], curl_norm_b3: float[:, :, :], u1: float[:, :, :], u2: float[:, :, :], u3: float[:, :, :])[source]#

Velocity update step for the CurrentCoupling5DCurlb

Marker update :

\[v_{\parallel,p}^{n+1} = v_{\parallel,p}^n - \frac{\Delta t}{2} \hat B^{*,-1}_\parallel(\mathbf X_p, v^n_{\parallel,p}) \frac{1}{\sqrt{g(\mathbf X_p)}} v_{\parallel,p}^n \hat{\mathbf B}^2(\mathbf X_p) \times(\hat \nabla \times \hat{\mathbf b}_0)(\mathbf X_p) \Lambda^v (\mathbf u^{n+1} + \mathbf u^n ) (\mathbf X_p) \,,\]

for each marker \(p\) in markers array.

struphy.pic.pushing.pusher_kernels_gc.push_gc_cc_J1_Hcurl(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, epsilon: float, b1: float[:, :, :], b2: float[:, :, :], b3: float[:, :, :], norm_b11: float[:, :, :], norm_b12: float[:, :, :], norm_b13: float[:, :, :], curl_norm_b1: float[:, :, :], curl_norm_b2: float[:, :, :], curl_norm_b3: float[:, :, :], u1: float[:, :, :], u2: float[:, :, :], u3: float[:, :, :])[source]#

Velocity update step for the CurrentCoupling5DCurlb

Marker update:

\[v_{\parallel,p}^{n+1} = v_{\parallel,p}^n - \frac{\Delta t}{2} \hat B^{*,-1}_\parallel(\mathbf X_p, v^n_{\parallel,p}) \frac{1}{\sqrt{g(\mathbf X_p)}} v_{\parallel,p}^n G^{-1}(\mathbf X_p) \hat{\mathbf B}^2(\mathbf X_p) \times(\hat \nabla \times \hat{\mathbf b}_0)(\mathbf X_p) \Lambda^1 (\mathbf u^{n+1} + \mathbf u^n ) (\mathbf X_p) \,,\]

for each marker \(p\) in markers array.

struphy.pic.pushing.pusher_kernels_gc.push_gc_cc_J1_Hdiv(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, epsilon: float, b1: float[:, :, :], b2: float[:, :, :], b3: float[:, :, :], norm_b11: float[:, :, :], norm_b12: float[:, :, :], norm_b13: float[:, :, :], curl_norm_b1: float[:, :, :], curl_norm_b2: float[:, :, :], curl_norm_b3: float[:, :, :], u1: float[:, :, :], u2: float[:, :, :], u3: float[:, :, :])[source]#

Velocity update step for the CurrentCoupling5DCurlb

Marker update:

\[v_{\parallel,p}^{n+1} = v_{\parallel,p}^n - \frac{\Delta t}{2} \hat B^{*,-1}_\parallel(\mathbf X_p, v^n_{\parallel,p}) \frac{1}{\sqrt{g(\mathbf X_p)}} \frac{1}{\sqrt{g(\mathbf X_p)}} v_{\parallel,p}^n \hat{\mathbf B}^2(\mathbf X_p) \times(\hat \nabla \times \hat{\mathbf b}_0)(\mathbf X_p) \Lambda^2 (\mathbf u^{n+1} + \mathbf u^n ) (\mathbf X_p) \,,\]

for each marker \(p\) in markers array.

struphy.pic.pushing.pusher_kernels_gc.push_gc_cc_J2_stage_H1vec(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, epsilon: float, b1: float[:, :, :], b2: float[:, :, :], b3: float[:, :, :], norm_b11: float[:, :, :], norm_b12: float[:, :, :], norm_b13: float[:, :, :], curl_norm_b1: float[:, :, :], curl_norm_b2: float[:, :, :], curl_norm_b3: float[:, :, :], u1: float[:, :, :], u2: float[:, :, :], u3: float[:, :, :], a: float[:], b: float[:], c: float[:])[source]#

Single stage of a s-stage explicit pushing step for the CurrentCoupling5DGradB

Marker update:

\[\mathbf X^{n+1} = \mathbf X^n - \frac{\Delta t}{2} \hat B^{*,-1}_\parallel(\mathbf X_p, v^n_{\parallel,p}) G^{-1}(\mathbf X_p) \hat{\mathbf b}_0^2(\mathbf X_p) \times G^{-1}(\mathbf X_p) \hat{\mathbf B}^2(\mathbf X_p) \times \Lambda^v (\mathbf u^{n+1} + \mathbf u^n ) (\mathbf X_p) \,,\]

for each marker \(p\) in markers array.

struphy.pic.pushing.pusher_kernels_gc.push_gc_cc_J2_stage_Hdiv(dt: float, stage: int, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, epsilon: float, b1: float[:, :, :], b2: float[:, :, :], b3: float[:, :, :], norm_b11: float[:, :, :], norm_b12: float[:, :, :], norm_b13: float[:, :, :], curl_norm_b1: float[:, :, :], curl_norm_b2: float[:, :, :], curl_norm_b3: float[:, :, :], u1: float[:, :, :], u2: float[:, :, :], u3: float[:, :, :], a: float[:], b: float[:], c: float[:])[source]#

Single stage of a s-stage explicit pushing step for the CurrentCoupling5DGradB

Marker update:

\[\mathbf X^{n+1} = \mathbf X^n - \frac{\Delta t}{2} \hat B^{*,-1}_\parallel(\mathbf X_p, v^n_{\parallel,p}) \frac{1}{\sqrt{g(\mathbf X_p)}} G^{-1}(\mathbf X_p) \hat{\mathbf b}_0^2(\mathbf X_p) \times G^{-1}(\mathbf X_p) \hat{\mathbf B}^2(\mathbf X_p) \times \Lambda^2 (\mathbf u^{n+1} + \mathbf u^n ) (\mathbf X_p) \,,\]

for each marker \(p\) in markers array.

struphy.pic.pushing.pusher_kernels_gc.push_gc_cc_J2_dg_init_Hdiv(dt: float, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, epsilon: float, b1: float[:, :, :], b2: float[:, :, :], b3: float[:, :, :], norm_b11: float[:, :, :], norm_b12: float[:, :, :], norm_b13: float[:, :, :], curl_norm_b1: float[:, :, :], curl_norm_b2: float[:, :, :], curl_norm_b3: float[:, :, :], u1: float[:, :, :], u2: float[:, :, :], u3: float[:, :, :])[source]#

TODO

struphy.pic.pushing.pusher_kernels_gc.push_gc_cc_J2_dg_Hdiv(dt: float, args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, epsilon: float, b1: float[:, :, :], b2: float[:, :, :], b3: float[:, :, :], norm_b11: float[:, :, :], norm_b12: float[:, :, :], norm_b13: float[:, :, :], curl_norm_b1: float[:, :, :], curl_norm_b2: float[:, :, :], curl_norm_b3: float[:, :, :], u1: float[:, :, :], u2: float[:, :, :], u3: float[:, :, :], ud1: float[:, :, :], ud2: float[:, :, :], ud3: float[:, :, :], const: float, alpha: float)[source]#

TODO

Evaluation kernels guiding-center#

Initialization routines (initial guess, evaluations) for 5D gyro-center pusher kernels.

struphy.pic.pushing.eval_kernels_gc.driftkinetic_hamiltonian(alpha: float[:], column_nr: int, comps: int[:], args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, epsilon: float, B_dot_b_coeffs: float[:, :, :], phi_coeffs: float[:, :, :], evaluate_e_field: bool)[source]#

Evaluate the Hamiltonian

\[H(\mathbf Z_p) = H(\boldsymbol \eta_p, v_{\parallel,p}) = \varepsilon \frac{v_{\parallel,p}^2}{2} + \varepsilon\mu |\hat \mathbf B| (\boldsymbol \eta_p) + \hat \phi(\boldsymbol \eta_p)\,,\]

where the evaluation point is the weighted average \(Z_{p,i} = \alpha_i Z_{p,i}^{n+1,k} + (1 - \alpha_i) Z_{p,i}^n\), for \(i=1,2,3,4\). Markers must be sorted according to the evaluation point \(\boldsymbol \eta_p\) beforehand.

The result is saved at column_nr in markers array for each particle.

struphy.pic.pushing.eval_kernels_gc.grad_driftkinetic_hamiltonian(alpha: float[:], column_nr: int, comps: int[:], args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, epsilon: float, grad_b_full_1: float[:, :, :], grad_b_full_2: float[:, :, :], grad_b_full_3: float[:, :, :], e_field_1: float[:, :, :], e_field_2: float[:, :, :], e_field_3: float[:, :, :], evaluate_e_field: bool)[source]#

Evaluate the \(\boldsymbol \eta\)-gradient of the Hamiltonian

\[H(\mathbf Z_p) = H(\boldsymbol \eta_p, v_{\parallel,p}) = \varepsilon \frac{v_{\parallel,p}^2}{2} + \varepsilon \mu |\hat \mathbf B| (\boldsymbol \eta_p) + \hat \phi(\boldsymbol \eta_p)\,,\]

that is

\[\hat \nabla H(\mathbf Z_p) = \varepsilon \mu \hat \nabla |\hat \mathbf B| (\boldsymbol \eta_p) + \hat \nabla \hat \phi(\boldsymbol \eta_p)\,,\]

where the evaluation point is the weighted average \(Z_{p,i} = \alpha_i Z_{p,i}^{n+1,k} + (1 - \alpha_i) Z_{p,i}^n\), for \(i=1,2,3,4\). Markers must be sorted according to the evaluation point \(\boldsymbol \eta_p\) beforehand.

The components specified in comps are save at column_nr:column_nr + len(comps) in markers array for each particle.

struphy.pic.pushing.eval_kernels_gc.bstar_parallel_3form(alpha: float[:], column_nr: int, comps: int[:], args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, epsilon: float, B_dot_b_coeffs: float[:, :, :], curl_unit_b_dot_b0: float[:, :, :])[source]#

Evaluate

\[\hat B^{*3}_\parallel(\mathbf Z_p) = \sqrt g \left(\hat B + \varepsilon v_{\parallel,p} \widehat{\left[(\nabla \times \mathbf b_0) \cdot \mathbf b_0\right]}(\boldsymbol \eta_p) \right)\,,\]

where the evaluation point is the weighted average \(Z_{p,i} = \alpha_i Z_{p,i}^{n+1,k} + (1 - \alpha_i) Z_{p,i}^n\), for \(i=1,2,3,4\). Markers must be sorted according to the evaluation point \(\boldsymbol \eta_p\) beforehand.

The result is saved at column_nr in markers array for each particle.

struphy.pic.pushing.eval_kernels_gc.bstar_2form(alpha: float[:], column_nr: int, comps: int[:], args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, epsilon: float, b2_1: float[:, :, :], b2_2: float[:, :, :], b2_3: float[:, :, :], curl_unit_b2_1: float[:, :, :], curl_unit_b2_2: float[:, :, :], curl_unit_b2_3: float[:, :, :])[source]#

Evaluate

\[\hat{\mathbf B}^{*2}(\mathbf Z_p) = \hat{\mathbf B}^2(\boldsymbol \eta_p) + \varepsilon v_{\parallel,p} \hat \nabla \times \hat{\mathbf b}^1_0 (\boldsymbol \eta_p)\,,\]

where the evaluation point is the weighted average \(Z_{p,i} = \alpha_i Z_{p,i}^{n+1,k} + (1 - \alpha_i) Z_{p,i}^n\), for \(i=1,2,3,4\). Markers must be sorted according to the evaluation point \(\boldsymbol \eta_p\) beforehand.

The components specified in comps are save at column_nr:column_nr + len(comps) in markers array for each particle.

struphy.pic.pushing.eval_kernels_gc.unit_b_1form(alpha: float[:], column_nr: int, comps: int[:], args_markers: MarkerArguments, args_domain: DomainArguments, args_derham: DerhamArguments, unit_b1_1: float[:, :, :], unit_b1_2: float[:, :, :], unit_b1_3: float[:, :, :])[source]#

Evaluate \(\hat{\mathbf b}^1_0(\boldsymbol \eta_p)\), where the evaluation point is the weighted average \(\eta_{p,i} = \alpha_i \eta_{p,i}^{n+1,k} + (1 - \alpha_i) \eta_{p,i}^n\), for \(i=1,2,3\). Markers must be sorted according to the evaluation point \(\boldsymbol \eta_p\) beforehand.

The components specified in comps are save at column_nr:column_nr + len(comps) in markers array for each particle.

struphy.pic.pushing.eval_kernels_gc.sph_pressure_coeffs(alpha: float[:], column_nr: int, comps: int[:], args_markers: MarkerArguments, args_domain: DomainArguments, boxes: int[:, :], neighbours: int[:, :], holes: bool[:], periodic1: bool, periodic2: bool, periodic3: bool, kernel_type: int, h1: float, h2: float, h3: float)[source]#

Evaluate the \(\boldsymbol \eta\)-gradient of the Hamiltonian

\[H(\mathbf Z_p) = H(\boldsymbol \eta_p, v_{\parallel,p}) = \varepsilon \frac{v_{\parallel,p}^2}{2} + \varepsilon \mu |\hat \mathbf B| (\boldsymbol \eta_p) + \hat \phi(\boldsymbol \eta_p)\,,\]

that is

\[\hat \nabla H(\mathbf Z_p) = \varepsilon \mu \hat \nabla |\hat \mathbf B| (\boldsymbol \eta_p) + \hat \nabla \hat \phi(\boldsymbol \eta_p)\,,\]

where the evaluation point is the weighted average \(Z_{p,i} = \alpha_i Z_{p,i}^{n+1,k} + (1 - \alpha_i) Z_{p,i}^n\), for \(i=1,2,3,4\). Markers must be sorted according to the evaluation point \(\boldsymbol \eta_p\) beforehand.

The components specified in comps are save at column_nr:column_nr + len(comps) in markers array for each particle.

struphy.pic.pushing.eval_kernels_gc.sph_isotherm_kappa(alpha: float[:], column_nr: int, comps: int[:], args_markers: MarkerArguments)[source]#

Evaluate the \(\boldsymbol \eta\)-gradient of the Hamiltonian

\[H(\mathbf Z_p) = H(\boldsymbol \eta_p, v_{\parallel,p}) = \varepsilon \frac{v_{\parallel,p}^2}{2} + \varepsilon \mu |\hat \mathbf B| (\boldsymbol \eta_p) + \hat \phi(\boldsymbol \eta_p)\,,\]

that is

\[\hat \nabla H(\mathbf Z_p) = \varepsilon \mu \hat \nabla |\hat \mathbf B| (\boldsymbol \eta_p) + \hat \nabla \hat \phi(\boldsymbol \eta_p)\,,\]

where the evaluation point is the weighted average \(Z_{p,i} = \alpha_i Z_{p,i}^{n+1,k} + (1 - \alpha_i) Z_{p,i}^n\), for \(i=1,2,3,4\). Markers must be sorted according to the evaluation point \(\boldsymbol \eta_p\) beforehand.

The components specified in comps are save at column_nr:column_nr + len(comps) in markers array for each particle.

struphy.pic.pushing.eval_kernels_gc.sph_mean_velocity_coeffs(alpha: float[:], column_nr: int, comps: int[:], args_markers: MarkerArguments, args_domain: DomainArguments, boxes: int[:, :], neighbours: int[:, :], holes: bool[:], periodic1: bool, periodic2: bool, periodic3: bool, kernel_type: int, h1: float, h2: float, h3: float)[source]#

Evaluate the \(\boldsymbol \eta\)-gradient of the Hamiltonian

\[H(\mathbf Z_p) = H(\boldsymbol \eta_p, v_{\parallel,p}) = \varepsilon \frac{v_{\parallel,p}^2}{2} + \varepsilon \mu |\hat \mathbf B| (\boldsymbol \eta_p) + \hat \phi(\boldsymbol \eta_p)\,,\]

that is

\[\hat \nabla H(\mathbf Z_p) = \varepsilon \mu \hat \nabla |\hat \mathbf B| (\boldsymbol \eta_p) + \hat \nabla \hat \phi(\boldsymbol \eta_p)\,,\]

where the evaluation point is the weighted average \(Z_{p,i} = \alpha_i Z_{p,i}^{n+1,k} + (1 - \alpha_i) Z_{p,i}^n\), for \(i=1,2,3,4\). Markers must be sorted according to the evaluation point \(\boldsymbol \eta_p\) beforehand.

The components specified in comps are save at column_nr:column_nr + len(comps) in markers array for each particle.

struphy.pic.pushing.eval_kernels_gc.sph_mean_velocity(alpha: float[:], column_nr: int, comps: int[:], args_markers: MarkerArguments, args_domain: DomainArguments, boxes: int[:, :], neighbours: int[:, :], holes: bool[:], periodic1: bool, periodic2: bool, periodic3: bool, kernel_type: int, h1: float, h2: float, h3: float)[source]#

Evaluate the \(\boldsymbol \eta\)-gradient of the Hamiltonian

\[H(\mathbf Z_p) = H(\boldsymbol \eta_p, v_{\parallel,p}) = \varepsilon \frac{v_{\parallel,p}^2}{2} + \varepsilon \mu |\hat \mathbf B| (\boldsymbol \eta_p) + \hat \phi(\boldsymbol \eta_p)\,,\]

that is

\[\hat \nabla H(\mathbf Z_p) = \varepsilon \mu \hat \nabla |\hat \mathbf B| (\boldsymbol \eta_p) + \hat \nabla \hat \phi(\boldsymbol \eta_p)\,,\]

where the evaluation point is the weighted average \(Z_{p,i} = \alpha_i Z_{p,i}^{n+1,k} + (1 - \alpha_i) Z_{p,i}^n\), for \(i=1,2,3,4\). Markers must be sorted according to the evaluation point \(\boldsymbol \eta_p\) beforehand.

The components specified in comps are save at column_nr:column_nr + len(comps) in markers array for each particle.

struphy.pic.pushing.eval_kernels_gc.sph_grad_mean_velocity(alpha: float[:], column_nr: int, comps: int[:], args_markers: MarkerArguments, args_domain: DomainArguments, boxes: int[:, :], neighbours: int[:, :], holes: bool[:], periodic1: bool, periodic2: bool, periodic3: bool, kernel_type: int, h1: float, h2: float, h3: float)[source]#

Evaluate the \(\boldsymbol \eta\)-gradient of the Hamiltonian

\[H(\mathbf Z_p) = H(\boldsymbol \eta_p, v_{\parallel,p}) = \varepsilon \frac{v_{\parallel,p}^2}{2} + \varepsilon \mu |\hat \mathbf B| (\boldsymbol \eta_p) + \hat \phi(\boldsymbol \eta_p)\,,\]

that is

\[\hat \nabla H(\mathbf Z_p) = \varepsilon \mu \hat \nabla |\hat \mathbf B| (\boldsymbol \eta_p) + \hat \nabla \hat \phi(\boldsymbol \eta_p)\,,\]

where the evaluation point is the weighted average \(Z_{p,i} = \alpha_i Z_{p,i}^{n+1,k} + (1 - \alpha_i) Z_{p,i}^n\), for \(i=1,2,3,4\). Markers must be sorted according to the evaluation point \(\boldsymbol \eta_p\) beforehand.

The components specified in comps are save at column_nr:column_nr + len(comps) in markers array for each particle.

struphy.pic.pushing.eval_kernels_gc.sph_viscosity_tensor(alpha: float[:], column_nr: int, comps: int[:], args_markers: MarkerArguments, args_domain: DomainArguments, boxes: int[:, :], neighbours: int[:, :], holes: bool[:], periodic1: bool, periodic2: bool, periodic3: bool, kernel_type: int, h1: float, h2: float, h3: float)[source]#

Evaluate the \(\boldsymbol \eta\)-gradient of the Hamiltonian

\[H(\mathbf Z_p) = H(\boldsymbol \eta_p, v_{\parallel,p}) = \varepsilon \frac{v_{\parallel,p}^2}{2} + \varepsilon \mu |\hat \mathbf B| (\boldsymbol \eta_p) + \hat \phi(\boldsymbol \eta_p)\,,\]

that is

\[\hat \nabla H(\mathbf Z_p) = \varepsilon \mu \hat \nabla |\hat \mathbf B| (\boldsymbol \eta_p) + \hat \nabla \hat \phi(\boldsymbol \eta_p)\,,\]

where the evaluation point is the weighted average \(Z_{p,i} = \alpha_i Z_{p,i}^{n+1,k} + (1 - \alpha_i) Z_{p,i}^n\), for \(i=1,2,3,4\). Markers must be sorted according to the evaluation point \(\boldsymbol \eta_p\) beforehand.

The components specified in comps are save at column_nr:column_nr + len(comps) in markers array for each particle.