fluidsim.base.time_stepping.pseudo_spect

Time stepping (fluidsim.base.time_stepping.pseudo_spect)

Provides:

class fluidsim.base.time_stepping.pseudo_spect.TimeSteppingPseudoSpectral(sim)[source]

Bases: TimeSteppingBase

Time stepping class for pseudo-spectral solvers.

static _complete_params_with_default(params)[source]

This static method is used to complete the params container.

one_time_step_computation()[source]

One time step.

_time_step_Euler()[source]

Forward Euler method.

Notes

We consider an equation of the form

\[\partial_t S = \sigma S + N(S),\]

The forward Euler method computes an approximation of the solution after a time increment \(\mathop{dt}\). We denote the initial time \(t = 0\).

Euler approximation :

\[\partial_t \log S = \sigma + \frac{N_0}{S_0},\]

Integrating from \(t\) to \(t+\mathop{dt}\), it gives:

\[S_{\mathop{dt}} = (S_0 + N_0 \mathop{dt}) e^{\sigma \mathop{dt}}.\]
_get_phaseshift()[source]

Compute the phase shift term.

_get_phaseshift_random()[source]

Compute two random phase shift terms.

_time_step_Euler_phaseshift()[source]

Forward Euler method, dealiasing with phase-shifting.

Notes

We consider an equation of the form

\[\partial_t S = \sigma S + N(S),\]

The forward Euler method computes an approximation of the solution after a time increment \(\mathop{dt}\). We denote the initial time \(t = 0\).

  • Euler approximation:

    \[\partial_t \log S = \sigma + \frac{N_\mathrm{dealias}}{S_0},\]

    Integrating from \(t\) to \(t+\mathop{dt}\), it gives:

    \[S_{\mathop{dt}} = (S_0 + N_\mathrm{dealias} \mathop{dt}) e^{\sigma \mathop{dt}}.\]

    where the dealiased non-linear term is \(N_\mathrm{dealias} = (N_0 + \tilde N_0)/2\) and the phase-shifted nonlinear term \(\tilde N_0\) is given by

    \[\tilde N_0 = e^{-\frac{1}{2}k\mathop{dx}}N\left(e^{\frac{1}{2}k\mathop{dx}}S_0\right).\]
_time_step_Euler_phaseshift_random()[source]

Forward Euler method, dealiasing with phase-shifting.

Notes

We consider an equation of the form

\[\partial_t S = \sigma S + N(S),\]

The forward Euler method computes an approximation of the solution after a time increment \(\mathop{dt}\). We denote the initial time \(t = 0\).

  • Euler approximation:

    \[\partial_t \log S = \sigma + \frac{N_\mathrm{dealias}}{S_0},\]

    Integrating from \(t\) to \(t+\mathop{dt}\), it gives:

    \[S_{\mathop{dt}} = (S_0 + N_\mathrm{dealias} \mathop{dt}) e^{\sigma \mathop{dt}}.\]

    where the dealiased non-linear term \(N_\mathrm{dealias} = (\tilde N_{0\alpha} + \tilde N_{0\beta})/2\) is computed as the average of two terms shifted with dependant phases \(\phi_\alpha = \alpha \mathop{dx} k\) and \(\phi_\beta = \beta \mathop{dx} k\) with \(\alpha\) taken randomly between -1 and 1 and \(|\alpha - \beta| = 0.5\).

_time_step_RK2()[source]

Runge-Kutta 2 method.

Notes

We consider an equation of the form

\[\partial_t S = \sigma S + N(S),\]

The Runge-Kutta 2 method computes an approximation of the solution after a time increment \(\mathop{dt}\). We denote the initial time \(t = 0\).

  • Approximation 1:

    \[\partial_t \log S = \sigma + \frac{N_0}{S_0},\]

    Integrating from \(t\) to \(t+\mathop{dt}/2\), it gives:

    \[S_1 = (S_0 + \frac{\mathop{dt}}{2} N_0) e^{\sigma \frac{\mathop{dt}}{2}}.\]
  • Approximation 2:

    \[\partial_t \log S = \sigma + \frac{N_1}{S_1},\]

    Integrating from \(t\) to \(t+\mathop{dt}\) and retaining only the terms in \((N\mathop{dt}/S)^1\) gives:

    \[S_2 = S_0 e^{\sigma \mathop{dt}} + \mathop{dt} N_1 e^{\sigma \frac{\mathop{dt}}{2}}.\]
_time_step_RK2_trapezoid()[source]

Runge-Kutta 2 method with trapezoidal rule (Heun’s method).

Notes

We consider an equation of the form

\[\partial_t S = \sigma S + N(S),\]

Heun’s method computes an approximation of the solution after a time increment \(\mathop{dt}\). We denote the initial time \(t = 0\).

  • Approximation 1:

    \[\partial_t \log S = \sigma + \frac{N(S_0)}{S_0},\]

    Integrating from \(t\) to \(t+\mathop{dt}\), it gives:

    \[S_1 = (S_0 + N_0 \mathop{dt}) e^{\sigma \mathop{dt}}.\]
  • Approximation 2:

    \[\partial_t \log S = \sigma + \frac{1}{2}\left( \frac{N_0}{S_0} + \frac{N_1}{S_1}\right),\]

    Integrating from \(t\) to \(t+\mathop{dt}\) and retaining only the terms in \((N\mathop{dt}/S)^1\) gives:

    \[S_2 = S_0 e^{\sigma \mathop{dt}} + \frac{\mathop{dt}}{2} (N_0 e^{\sigma \mathop{dt}} + N_1).\]
_time_step_RK2_phaseshift()[source]

Runge-Kutta 2 method with phase-shifting.

Notes

We consider an equation of the form

\[\partial_t S = \sigma S + N(S),\]

Heun’s method computes an approximation of the solution after a time increment \(\mathop{dt}\). We denote the initial time \(t = 0\).

  • Approximation 1:

    \[\partial_t \log S = \sigma + \frac{N_0}{S_0},\]

    Integrating from \(t\) to \(t+\mathop{dt}\), it gives:

    \[S_1 = (S_0 + N_0 \mathop{dt}) e^{\sigma \mathop{dt}}.\]
  • Approximation 2:

    \[\partial_t \log S = \sigma + \frac{N_d}{S_0 e^{\sigma \frac{\mathop{dt}}{2}}},\]

    where the dealiased non-linear term is \(N_\mathrm{dealias} = (N_0 + \tilde N_1)/2\) and the phase-shifted nonlinear term \(\tilde N_1\) is given by

    \[\tilde N_1 = e^{-\frac{1}{2}k\mathop{dx}}N\left(e^{\frac{1}{2}k\mathop{dx}}S_1\right).\]

    Integrating from \(t\) to \(t+\mathop{dt}\) and retaining only the terms in \((N\mathop{dt}/S)^1\) gives:

    \[S_2 = S_0 e^{\sigma \mathop{dt}} + \mathop{dt} N_d e^{\sigma \frac{\mathop{dt}}{2}}.\]
_time_step_RK2_phaseshift_random()[source]

Runge-Kutta 2 method with phase-shifting (random).

Notes

We consider an equation of the form

\[\partial_t S = \sigma S + N(S),\]

Heun’s method computes an approximation of the solution after a time increment \(\mathop{dt}\). We denote the initial time \(t = 0\).

  • Approximation 1:

    \[\partial_t \log S = \sigma + \frac{\tilde N_{0\alpha}}{S_0},\]

    Integrating from \(t\) to \(t+\mathop{dt}\), it gives:

    \[S_1 = (S_0 + \tilde N_{0\alpha} \mathop{dt}) e^{\sigma \mathop{dt}}.\]
  • Approximation 2:

    \[\partial_t \log S = \sigma + \frac{N_d}{S_0 e^{\sigma \frac{\mathop{dt}}{2}}},\]

    where the dealiased non-linear term is \(N_d = (\tilde N_{0\alpha} + \tilde N_{1\beta})/2\).

    Integrating from \(t\) to \(t+\mathop{dt}\) and retaining only the terms in \((N\mathop{dt}/S)^1\) gives:

    \[S_2 = S_0 e^{\sigma \mathop{dt}} + \mathop{dt} N_d e^{\sigma \frac{\mathop{dt}}{2}}.\]
_time_step_RK2_phaseshift_exact()[source]

Runge-Kutta 2 method with phase-shifting for exact dealiasing.

Notes

It requires 4 evaluations of the nonlinear terms (as RK4).

We consider an equation of the form

\[\partial_t S = \sigma S + N(S),\]

Heun’s method computes an approximation of the solution after a time increment \(\mathop{dt}\). We denote the initial time \(t = 0\).

  • Approximation 1:

    \[\partial_t \log S = \sigma + \frac{N_{d0}}{S_0},\]

    Integrating from \(t\) to \(t+\mathop{dt}\), it gives:

    \[S_1 = (S_0 + N_{d0} \mathop{dt}) e^{\sigma \mathop{dt}}.\]
  • Approximation 2:

    \[\partial_t \log S = \sigma + \frac{N_d}{S_0 e^{\sigma \frac{\mathop{dt}}{2}}},\]

    where the dealiased non-linear term is \(N_d = (N_{d0} + N_{d1})/2\).

    Integrating from \(t\) to \(t+\mathop{dt}\) and retaining only the terms in \((N\mathop{dt}/S)^1\) gives:

    \[S_2 = S_0 e^{\sigma \mathop{dt}} + \mathop{dt} N_d e^{\sigma \frac{\mathop{dt}}{2}}.\]
_time_step_RK4()[source]

Runge-Kutta 4 method.

Notes

We consider an equation of the form

\[\partial_t S = \sigma S + N(S),\]

The Runge-Kutta 4 method computes an approximation of the solution after a time increment \(\mathop{dt}\). We denote the initial time as \(t = 0\). This time scheme uses 4 approximations. Only the terms in \(\mathop{dt}^1\) are retained.

  • Approximation 1:

    \[\partial_t \log S = \sigma + \frac{N_0}{S_0},\]

    Integrating from \(t\) to \(t+\mathop{dt}/2\) gives:

    \[S_{A1 \mathop{dt}/2} = (S_0 + N_0 \mathop{dt}/2) e^{\sigma \frac{\mathop{dt}}{2}}.\]

    Integrating from \(t\) to \(t+\mathop{dt}\) gives:

    \[S_{A1\mathop{dt}} = (S_0 + N_0 \mathop{dt}) e^{\sigma \mathop{dt}}.\]
  • Approximation 2:

    \[\partial_t \log S = \sigma + \frac{N(S_{A1 \mathop{dt}/2})}{ S_{A1 \mathop{dt}/2} },\]

    Integrating from \(t\) to \(t+\mathop{dt}/2\) gives:

    \[S_{A2 \mathop{dt}/2} = S_0 e^{\sigma \frac{\mathop{dt}}{2}} + N(S_{A1 \mathop{dt}/2}) \frac{\mathop{dt}}{2}.\]

    Integrating from \(t\) to \(t+\mathop{dt}\) gives:

    \[S_{A2\mathop{dt}} = S_0 e^{\sigma \mathop{dt}} + N(S_{A1 \mathop{dt}/2}) e^{\sigma \frac{\mathop{dt}}{2}} \mathop{dt}.\]
  • Approximation 3:

    \[\partial_t \log S = \sigma + \frac{N(S_{A2 \mathop{dt}/2})}{ S_{A2 \mathop{dt}/2} },\]

    Integrating from \(t\) to \(t+\mathop{dt}\) gives:

    \[S_{A3\mathop{dt}} = S_0 e^{\sigma \mathop{dt}} + N(S_{A2 \mathop{dt}/2}) e^{\sigma \frac{\mathop{dt}}{2}} \mathop{dt}.\]
  • Approximation 4:

    \[\partial_t \log S = \sigma + \frac{N(S_{A3\mathop{dt}})}{ S_{A3\mathop{dt}} },\]

    Integrating from \(t\) to \(t+\mathop{dt}\) gives:

    \[S_{A4\mathop{dt}} = S_0 e^{\sigma \mathop{dt}} + N(S_{A3\mathop{dt}}) \mathop{dt}.\]

The final result is a pondered average of the results of 4 approximations for the time \(t+\mathop{dt}\):

\[\frac{1}{3} \left[ \frac{1}{2} S_{A1\mathop{dt}} + S_{A2\mathop{dt}} + S_{A3\mathop{dt}} + \frac{1}{2} S_{A4\mathop{dt}} \right],\]

which is equal to:

\[S_0 e^{\sigma \mathop{dt}} + \frac{\mathop{dt}}{3} \left[ \frac{1}{2} N_0 e^{\sigma \mathop{dt}} + N(S_{A1 \mathop{dt}/2}) e^{\sigma \frac{\mathop{dt}}{2}} + N(S_{A2 \mathop{dt}/2}) e^{\sigma \frac{\mathop{dt}}{2}} + \frac{1}{2} N(S_{A3\mathop{dt}})\right].\]

Todo

It would be interesting to also implement the Adams-Bashforth (leapfrog) scheme with phase-shifting. It is very close to _time_step_RK2_phaseshift() with 2 evaluations of the non-linear terms per time step (but with 2 symmetrical and equivalent steps).

Note

For a theoretical presentation of phase-shifting, see the book Numerical Experiments in Homogeneous Turbulence (Robert S. Rogallo, https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19810022965.pdf).

Functions

compute_phaseshift_terms(phase_alpha, ...)

div_inplace(arr, phaseshift)

mean_with_phaseshift(tendencies_0, ...)

mul(phaseshift, state_spect, output)

step_Euler(state_spect, dt, tendencies, ...)

step_Euler_inplace(state_spect, dt, ...)

step_like_RK2(state_spect, dt, tendencies, ...)

Classes

ExactLinearCoefs(time_stepping)

Handle the computation of the exact coefficient for the RK4.

TimeSteppingPseudoSpectral(sim)

Time stepping class for pseudo-spectral solvers.