Particle propagators#
Only particle variables are updated.
- class struphy.propagators.propagators_markers.PushEta[source]#
Bases:
PropagatorFor each marker \(p\), solves
\[\frac{\textnormal d \mathbf x_p(t)}{\textnormal d t} = \mathbf v_p\,,\]for constant \(\mathbf v_p\) in logical space given by \(\mathbf x = F(\boldsymbol \eta)\):
\[\frac{\textnormal d \boldsymbol \eta_p(t)}{\textnormal d t} = DF^{-1}(\boldsymbol \eta_p(t)) \,\mathbf v_p\,.\]Available algorithms:
Explicit from
ButcherTableau
- class Variables[source]#
Bases:
object- property var: PICVariable | SPHVariable#
- class Options(butcher: struphy.ode.utils.ButcherTableau = None)[source]#
Bases:
object- butcher: ButcherTableau = None#
- class struphy.propagators.propagators_markers.PushVxB[source]#
Bases:
PropagatorFor each marker \(p\), solves
\[\frac{\textnormal d \mathbf v_p(t)}{\textnormal d t} = \frac{1}{\varepsilon} \, \mathbf v_p(t) \times (\mathbf B + \mathbf B_{\text{add}}) \,,\]where \(\varepsilon = 1/(\hat\Omega_c \hat t)\) is a constant scaling factor, and for rotation vector \(\mathbf B\) and optional, additional fixed rotation vector \(\mathbf B_{\text{add}}\), both given as a 2-form:
\[\mathbf B = \frac{DF\, \hat{\mathbf B}^2}{\sqrt g}\,.\]Available algorithms:
analytic,implicit.- class Variables[source]#
Bases:
object- property ions: PICVariable | SPHVariable#
- class Options(algo: Literal['analytic', 'implicit'] = 'analytic', b2_var: struphy.models.variables.FEECVariable = None)[source]#
Bases:
object- OptsAlgo#
alias of
Literal[‘analytic’, ‘implicit’]
- algo: Literal['analytic', 'implicit'] = 'analytic'#
- b2_var: FEECVariable = None#
- class struphy.propagators.propagators_markers.PushVinEfield[source]#
Bases:
PropagatorPush the velocities according to
\[\frac{\text{d} \mathbf{v}_p}{\text{d} t} = \frac{1}{\varepsilon} \, \mathbf{E}(\mathbf{x}_p) \,,\]where \(\varepsilon \in \mathbb R\) is a constant. In logical coordinates, given by \(\mathbf x = F(\boldsymbol \eta)\):
\[\frac{\text{d} \mathbf{v}_p}{\text{d} t} = \frac{1}{\varepsilon} \, DF^{-\top} \hat{\mathbf E}^1(\boldsymbol \eta_p) \,,\]which is solved analytically. \(\mathbf E\) can optionally be defined through a potential, \(\mathbf E = - \nabla \phi\).
- class Variables[source]#
Bases:
object- property var: PICVariable | SPHVariable#
- class Options(e_field: struphy.models.variables.FEECVariable | tuple[Callable] = None, phi: struphy.models.variables.FEECVariable | Callable = None)[source]#
Bases:
object- e_field: FEECVariable | tuple[Callable] = None#
- phi: FEECVariable | Callable = None#
- class struphy.propagators.propagators_markers.PushEtaPC[source]#
Bases:
PropagatorFor each marker \(p\), solves
\[\frac{\textnormal d \mathbf x_p(t)}{\textnormal d t} = \mathbf v_p + \mathbf U (\mathbf x_p(t))\,,\]for constant \(\mathbf v_p\) and \(\mathbf U\) in logical space given by \(\mathbf x = F(\boldsymbol \eta)\):
\[\frac{\textnormal d \boldsymbol \eta_p(t)}{\textnormal d t} = DF^{-1}(\boldsymbol \eta_p(t)) \,\mathbf v_p + \textnormal{vec}(\hat{\mathbf U}) \,,\]where
\[\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}\,, \qquad \textnormal{vec}( \hat{\mathbf U}) = \hat{\mathbf U}\,.\]Available algorithms:
rk4(4th order, default)forward_euler(1st order)heun2(2nd order)rk2(2nd order)heun3(3rd order)
- class Variables[source]#
Bases:
object- property var: PICVariable | SPHVariable#
- class Options(butcher: struphy.ode.utils.ButcherTableau = None, use_perp_model: bool = True, u_tilde: struphy.models.variables.FEECVariable = None, u_space: Literal['Hcurl', 'Hdiv', 'H1vec'] = 'Hdiv')[source]#
Bases:
object- butcher: ButcherTableau = None#
- use_perp_model: bool = True#
- u_tilde: FEECVariable = None#
- u_space: Literal['Hcurl', 'Hdiv', 'H1vec'] = 'Hdiv'#
- class struphy.propagators.propagators_markers.PushGuidingCenterBxEstar[source]#
Bases:
PropagatorFor each marker \(p\), solves
\[\frac{\textnormal d \mathbf X_p(t)}{\textnormal d t} = \frac{\mathbf E^* \times \mathbf b_0}{B_\parallel^*} (\mathbf X_p(t)) \,,\]where
\[\mathbf E^* = -\nabla \phi - \varepsilon \mu_p \nabla |\mathbf B|\,,\qquad \mathbf B^* = \mathbf B + \varepsilon v_\parallel \nabla \times \mathbf b_0\,,\qquad B^*_\parallel = \mathbf B^* \cdot \mathbf b_0\,,\]where \(\mathbf B = \mathbf B_0 + \tilde{\mathbf B}\) can be the full magnetic field (equilibrium + perturbation). The electric potential
phiand/or the magnetic perturbationb_tildecan be ignored by passingNone. In logical space this is given by \(\mathbf X = F(\boldsymbol \eta)\):\[\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)) \,.\]Available algorithms:
Explicit from
ButcherTableau
- class Variables[source]#
Bases:
object- property ions: PICVariable#
- class Options(phi: struphy.models.variables.FEECVariable = None, evaluate_e_field: bool = False, b_tilde: struphy.models.variables.FEECVariable = None, algo: Literal['discrete_gradient_2nd_order', 'discrete_gradient_1st_order', 'discrete_gradient_1st_order_newton', 'explicit'] = 'discrete_gradient_1st_order', butcher: struphy.ode.utils.ButcherTableau = None, maxiter: int = 20, tol: float = 1e-07, mpi_sort: Literal['each', 'last', None] = 'each', verbose: bool = False)[source]#
Bases:
object- OptsAlgo#
alias of
Literal[‘discrete_gradient_2nd_order’, ‘discrete_gradient_1st_order’, ‘discrete_gradient_1st_order_newton’, ‘explicit’]
- phi: FEECVariable = None#
- evaluate_e_field: bool = False#
- b_tilde: FEECVariable = None#
- algo: Literal['discrete_gradient_2nd_order', 'discrete_gradient_1st_order', 'discrete_gradient_1st_order_newton', 'explicit'] = 'discrete_gradient_1st_order'#
- butcher: ButcherTableau = None#
- maxiter: int = 20#
- tol: float = 1e-07#
- mpi_sort: Literal['each', 'last', None] = 'each'#
- verbose: bool = False#
- class struphy.propagators.propagators_markers.PushGuidingCenterParallel[source]#
Bases:
PropagatorFor each marker \(p\), solves
\[\begin{split}\left\{ \begin{aligned} \frac{\textnormal d \mathbf X_p(t)}{\textnormal d t} &= v_{\parallel,p}(t) \frac{\mathbf B^*}{B^*_\parallel}(\mathbf X_p(t)) \,, \\ \frac{\textnormal d v_{\parallel,p}(t)}{\textnormal d t} &= \frac{1}{\varepsilon} \frac{\mathbf B^*}{B^*_\parallel} \cdot \mathbf E^* (\mathbf X_p(t)) \,, \end{aligned} \right.\end{split}\]where
\[\mathbf E^* = -\nabla \phi - \varepsilon \mu_p \nabla |\mathbf B|\,,\qquad \mathbf B^* = \mathbf B + \varepsilon v_\parallel \nabla \times \mathbf b_0\,,\qquad B^*_\parallel = \mathbf B^* \cdot \mathbf b_0\,,\]where \(\mathbf B = \mathbf B_0 + \tilde{\mathbf B}\) can be the full magnetic field (equilibrium + perturbation). The electric potential
phiand/or the magnetic perturbationb_tildecan be ignored by passingNone. In logical space this is given by \(\mathbf X = F(\boldsymbol \eta)\):\[\begin{split}\left\{ \begin{aligned} \frac{\textnormal d \boldsymbol \eta_p(t)}{\textnormal d t} &= v_{\parallel,p}(t) \frac{\hat{\mathbf B}^{*2}}{\hat B^{*3}_\parallel}(\boldsymbol \eta_p(t)) \,, \\ \frac{\textnormal d v_{\parallel,p}(t)}{\textnormal d t} &= \frac{1}{\varepsilon} \frac{\hat{\mathbf B}^{*2}}{\hat B^{*3}_\parallel} \cdot \hat{\mathbf E}^{*1} (\boldsymbol \eta_p(t)) \,. \end{aligned} \right.\end{split}\]Available algorithms:
Explicit from
ButcherTableau
- class Variables[source]#
Bases:
object- property ions: PICVariable#
- class Options(phi: struphy.models.variables.FEECVariable = None, evaluate_e_field: bool = False, b_tilde: struphy.models.variables.FEECVariable = None, algo: Literal['discrete_gradient_2nd_order', 'discrete_gradient_1st_order', 'discrete_gradient_1st_order_newton', 'explicit'] = 'discrete_gradient_1st_order', butcher: struphy.ode.utils.ButcherTableau = None, maxiter: int = 20, tol: float = 1e-07, mpi_sort: Literal['each', 'last', None] = 'each', verbose: bool = False)[source]#
Bases:
object- OptsAlgo#
alias of
Literal[‘discrete_gradient_2nd_order’, ‘discrete_gradient_1st_order’, ‘discrete_gradient_1st_order_newton’, ‘explicit’]
- phi: FEECVariable = None#
- evaluate_e_field: bool = False#
- b_tilde: FEECVariable = None#
- algo: Literal['discrete_gradient_2nd_order', 'discrete_gradient_1st_order', 'discrete_gradient_1st_order_newton', 'explicit'] = 'discrete_gradient_1st_order'#
- butcher: ButcherTableau = None#
- maxiter: int = 20#
- tol: float = 1e-07#
- mpi_sort: Literal['each', 'last', None] = 'each'#
- verbose: bool = False#
- class struphy.propagators.propagators_markers.PushDeterministicDiffusion[source]#
Bases:
PropagatorFor each marker \(p\), solves
\[\frac{\textnormal d \mathbf x_p(t)}{\textnormal d t} = - D \, \frac{\nabla u}{ u}\mathbf (\mathbf x_p(t))\,,\]in logical space given by \(\mathbf x = F(\boldsymbol \eta)\):
\[\frac{\textnormal d \boldsymbol \eta_p(t)}{\textnormal d t} = - G\, D \, \frac{\nabla \Pi^0_{L^2}u_h}{\Pi^0_{L^2} u_h}\mathbf (\boldsymbol \eta_p(t))\,, \qquad [\Pi^0_{L^2, ijk} u_h](\boldsymbol \eta_p) = \frac 1N \sum_{p} w_p \boldsymbol \Lambda^0_{ijk}(\boldsymbol \eta_p)\,,\]where \(D>0\) is a positive diffusion coefficient.
Available algorithms:
Explicit from
ButcherTableau
- class Variables[source]#
Bases:
object- property var: PICVariable#
- class Options(butcher: struphy.ode.utils.ButcherTableau = None, bc_type: tuple = ('periodic', 'periodic', 'periodic'), diff_coeff: float = 1.0)[source]#
Bases:
object- butcher: ButcherTableau = None#
- bc_type: tuple = ('periodic', 'periodic', 'periodic')#
- diff_coeff: float = 1.0#
- class struphy.propagators.propagators_markers.PushRandomDiffusion[source]#
Bases:
PropagatorFor each marker \(p\), solves
\[\textnormal d \mathbf x_p(t) = \sqrt{2 D} \, \textnormal d \mathbf B_{t}\,,\]where \(D>0\) is a positive diffusion coefficient and \(\textnormal d \mathbf B_{t}\) is a Wiener process,
\[\mathbf B_{t + \Delta t} - \mathbf B_{t} = \sqrt{\Delta t} \,\mathcal N(0;1)\,,\]with \(\mathcal N(0;1)\) denoting the standard normal distribution with mean zero and variance one.
Available algorithms:
forward_euler(1st order)
- class Variables[source]#
Bases:
object- property var: PICVariable#
- class Options(butcher: struphy.ode.utils.ButcherTableau = None, bc_type: tuple = ('periodic', 'periodic', 'periodic'), diff_coeff: float = 1.0)[source]#
Bases:
object- butcher: ButcherTableau = None#
- bc_type: tuple = ('periodic', 'periodic', 'periodic')#
- diff_coeff: float = 1.0#
- class struphy.propagators.propagators_markers.PushVinSPHpressure[source]#
Bases:
PropagatorFor each marker \(p\), solves
\[\frac{\textnormal d \mathbf v_p(t)}{\textnormal d t} = \kappa_p \sum_{i=1}^N w_i \left( \frac{1}{\rho^{N,h}(\boldsymbol \eta_p)} + \frac{1}{\rho^{N,h}(\boldsymbol \eta_i)} \right) DF^{-\top}\nabla W_h(\boldsymbol \eta_p - \boldsymbol \eta_i) \,,\]where \(DF^{-\top}\) denotes the inverse transpose Jacobian, and with the smoothed density
\[\rho^{N,h}(\boldsymbol \eta) = \frac 1N \sum_{j=1}^N w_j \, W_h(\boldsymbol \eta - \boldsymbol \eta_j)\,,\]where \(W_h(\boldsymbol \eta)\) is a smoothing kernel from
sph_smoothing_kernels. Time stepping:Explicit from
ButcherTableau
- class Variables[source]#
Bases:
object- property fluid: SPHVariable#
- class Options(kernel_type: Literal['trigonometric_1d', 'gaussian_1d', 'linear_1d', 'trigonometric_2d', 'gaussian_2d', 'linear_2d', 'trigonometric_3d', 'gaussian_3d', 'linear_isotropic_3d', 'linear_3d'] = 'gaussian_2d', kernel_width: tuple = None, algo: Literal['forward_euler'] = 'forward_euler', gravity: tuple = (0.0, 0.0, 0.0), thermodynamics: Literal['isothermal', 'polytropic'] = 'isothermal')[source]#
Bases:
object- OptsAlgo#
alias of
Literal[‘forward_euler’]
- OptsThermo#
alias of
Literal[‘isothermal’, ‘polytropic’]
- kernel_type: Literal['trigonometric_1d', 'gaussian_1d', 'linear_1d', 'trigonometric_2d', 'gaussian_2d', 'linear_2d', 'trigonometric_3d', 'gaussian_3d', 'linear_isotropic_3d', 'linear_3d'] = 'gaussian_2d'#
- kernel_width: tuple = None#
- algo: Literal['forward_euler'] = 'forward_euler'#
- gravity: tuple = (0.0, 0.0, 0.0)#
- thermodynamics: Literal['isothermal', 'polytropic'] = 'isothermal'#
- class struphy.propagators.propagators_markers.PushVinViscousPotential2D(particles: ParticlesSPH, *, kernel_type: str = 'gaussian_2d', kernel_width: tuple | None = None, algo: str = 'forward_euler')[source]#
Bases:
PropagatorFor each marker \(p\), solves
\[\frac{\textnormal d \mathbf v_p(t)}{\textnormal d t} = \kappa_p \sum_{i=1}^N w_i \left( \frac{1}{\rho^{N,h}(\boldsymbol \eta_p)} + \frac{1}{\rho^{N,h}(\boldsymbol \eta_i)} \right) DF^{-\top}\nabla W_h(\boldsymbol \eta_p - \boldsymbol \eta_i) \,,\]where \(DF^{-\top}\) denotes the inverse transpose Jacobian, and with the smoothed density
\[\rho^{N,h}(\boldsymbol \eta) = \frac 1N \sum_{j=1}^N w_j \, W_h(\boldsymbol \eta - \boldsymbol \eta_j)\,,\]where \(W_h(\boldsymbol \eta)\) is a smoothing kernel from
sph_smoothing_kernels. Time stepping:Explicit from
ButcherTableau
- class struphy.propagators.propagators_markers.PushVinViscousPotential3D(particles: ParticlesSPH, *, kernel_type: str = 'gaussian_3d', kernel_width: tuple | None = None, algo: str = 'forward_euler')[source]#
Bases:
PropagatorFor each marker \(p\), solves
\[\frac{\textnormal d \mathbf v_p(t)}{\textnormal d t} = \kappa_p \sum_{i=1}^N w_i \left( \frac{1}{\rho^{N,h}(\boldsymbol \eta_p)} + \frac{1}{\rho^{N,h}(\boldsymbol \eta_i)} \right) DF^{-\top}\nabla W_h(\boldsymbol \eta_p - \boldsymbol \eta_i) \,,\]where \(DF^{-\top}\) denotes the inverse transpose Jacobian, and with the smoothed density
\[\rho^{N,h}(\boldsymbol \eta) = \frac 1N \sum_{j=1}^N w_j \, W_h(\boldsymbol \eta - \boldsymbol \eta_j)\,,\]where \(W_h(\boldsymbol \eta)\) is a smoothing kernel from
sph_smoothing_kernels. Time stepping:Explicit from
ButcherTableau