pyloggrid.LogGrid.Framework

Solver for the log grids.

Module Contents

Classes

CustIntegrator

Abstract integrator class

ViscDopri

DOPRI5-based solver made specifically for log grids.

ETD4RK

Based on Exponential Time Differencing for Stiff Systems | Elsevier Enhanced Reader, Cox & Matthews, 2001, equations (26)-(29).

ETD35

Based on https://github.com/whalenpt/rkstiff

Solver

Generic top-level object to handle solving log-grid equations

Functions

fields_to_1D(→ numpy.ndarray)

Convert N-dimensional fields to 1D arrays

D1_to_fields() → dict[str, numpy.ndarray])

Reverse of fields_to_1D()

fields_to_1D(fields: dict[str, ndarray], field_names: list[str]) ndarray

Convert N-dimensional fields to 1D arrays

Parameters:
  • field_names – [name1, …] name of the fields (order is important, as it it used to convert back from 1D)

  • fields – N-dimensional named fields, grid-shaped

Returns:

1D ndarray containing all the appended 1D fields, as ordered by field_names

D1_to_fields(linear: ndarray, field_names: list[str], field_shape: int, Ellipsis) dict[str, ndarray]

Reverse of fields_to_1D()

Converts one 1D array to a dict of the encoded fields in their original shape

Parameters:
  • linear – 1D ndarray of fields

  • field_names – [name1, …] name of the fields (order is important)

  • field_shape – shape of the grid / fields

Returns:

the fields with their full shape

class CustIntegrator(equation_nl: Callable[[float, ndarray], ndarray], equation_l: Callable[[float, ndarray], ndarray], save_step: Callable[[float, float, ndarray], bool], init_t: float, solver_params: dict, y0: ndarray)

Abstract integrator class

select_initial_step(t0: float, y0: ndarray, order: int, rtol: float = 1e-06, atol: float = 1e-06) float

Empirically select a good initial step. The algorithm is described in [1].

Parameters:
  • t0 – Initial value of the independent variable.

  • y0 – Initial value of the dependent variable.

  • order – Error estimator order. It means that the error controlled by the algorithm is proportional to step_size ** (order + 1).

  • rtol – Desired relative tolerance.

  • atol – Desired absolute tolerance.

Returns:

h_abs = Absolute value of the suggested initial step.

References

abstract solve()
class ViscDopri(equation_nl: Callable[[float, ndarray], ndarray], equation_l: Callable[[float, ndarray], ndarray], save_step: Callable[[float, float, ndarray], bool], init_t: float, solver_params: dict, y0: ndarray, dt_params: dict[str, float | None])

Bases: CustIntegrator

DOPRI5-based solver made specifically for log grids.

A nonlinear update step is decoupled from the linear update step. Special care is given to handling numerical (float-induced) random numerical errors which yield huge gradients. Based on scipy’s DOPRI5 implementation

Parameters:
  • equation_nl – linear-less update step

  • equation_l – linear update step

  • init_t – initial time

  • y0 – initial 1D array

  • solver_params – = {"atol"[absolute tolerance]: 1e-6, "rtol"[relative tolerance]: 1e-4, "exact_viscous_splitting"[if True, use exact viscous splitting]: False}

  • dt_params{dt0 = initial time step, dtmin, dtmax}

rk_step(fun: Callable[[float, ndarray], ndarray], t: float, y: ndarray, h: float, A: ndarray, B: ndarray, C: ndarray, K: ndarray) tuple[ndarray, ndarray]

Perform a single Runge-Kutta step. This function computes a prediction of an explicit Runge-Kutta method and also estimates the error of a less accurate method. Notation for Butcher tableau is as in [2].

Parameters:
  • fun – Right-hand side of the system.

  • t – Current time.

  • y – Current state.

  • h – Step to use.

  • A – Coefficients for combining previous RK stages to compute the next stage. For explicit methods the coefficients at and above the main diagonal are zeros.

  • B – Coefficients for combining RK stages for computing the final prediction.

  • C – Coefficients for incrementing time for consecutive RK stages. The value for the first stage is always zero.

  • K – Storage array for putting RK stages here. Stages are stored in rows. The last row is a linear combination of the previous rows with coefficients

Returns: tuple (y_new, f_new) where y_new is the solution at t + h computed with a higher accuracy, and f_new is the derivative fun(t + h, y_new).

References

rkdp(force_step: bool = False) tuple[ndarray, float, float]

Performs one RKDP step

solve() None

Main solving loop.

The solver runs until an interruption is fired by the update.

class ETD4RK(equation_nl: Callable[[float, ndarray], ndarray], equation_l: Callable[[float, ndarray], ndarray], save_step: Callable[[float, float, ndarray], bool], init_t: float, y0: ndarray, dt_params: dict[str, float | None])

Bases: CustIntegrator

Based on Exponential Time Differencing for Stiff Systems | Elsevier Enhanced Reader, Cox & Matthews, 2001, equations (26)-(29).

Warning

Only designed for constant-in-time viscosities

Parameters:
  • equation_nl – linear-less update step

  • equation_l – linear update step

  • init_t – initial time

  • y0 – initial 1D array

  • dt_params{dt0 = initial time step, dtmin, dtmax}

static dopri_step(fun: Callable[[float, ndarray], ndarray], t: float, y: ndarray, h: float, A: ndarray, B: ndarray, C: ndarray, K: ndarray) tuple[ndarray, ndarray]

Perform a single Runge-Kutta step. This function computes a prediction of an explicit Runge-Kutta method and also estimates the error of a less accurate method. Notation for Butcher tableau is as in [3].

Parameters:
  • fun – Right-hand side of the system.

  • t – Current time.

  • y – Current state.

  • h – Step to use.

  • A – Coefficients for combining previous RK stages to compute the next stage. For explicit methods the coefficients at and above the main diagonal are zeros.

  • B – Coefficients for combining RK stages for computing the final prediction.

  • C – Coefficients for incrementing time for consecutive RK stages. The value for the first stage is always zero.

  • K – Storage array for putting RK stages here. Stages are stored in rows. The last row is a linear combination of the previous rows with coefficients

Returns: tuple (y_new, f_new) where y_new is the solution at t + h computed with a higher accuracy, and f_new is the derivative fun(t + h, y_new). .. rubric:: References

rk() ndarray

Performs one Rk step

solve() None

Main solving loop. The solver runs until an interruption is fired by the update.

class ETD35(equation_nl: Callable[[float, ndarray], ndarray], equation_l: Callable[[float, ndarray], ndarray], save_step: Callable[[float, float, ndarray], bool], init_t: float, solver_params: dict, y0: ndarray, dt_params: dict[str, float | None])

Bases: CustIntegrator

Based on https://github.com/whalenpt/rkstiff

Warning

Only supports diagonal (and constant-in-time) linear terms for now

Parameters:
  • equation_nl – linear-less update step

  • equation_l – linear update step

  • init_t – initial time

  • solver_params{"rtol"[relative tolerance]: 1e-2, "adapt_cutoff"[Limits values used in the computation of the suggested step size to those with |u| > adapt_cutoff*max(|u|)]: 1e-2, "minh"[minimum time step]: 1e-16}

  • y0 – initial 1D array

  • dt_params{dt0 = initial time step, dtmin, dtmax}

rk() tuple[ndarray, float, float]

Performs one Rk step

Returns:

tuple (y_new, h, h_new_suggested)

solve() None

Main solving loop. The solver runs until an interruption is fired by the update.

exception SolverInterruptedError

Bases: InterruptedError

custom error thrown to change grid size

class Solver(fields_names: list[str], equation_nl: Callable[[float, Grid, dict], dict], D: int, l_params: dict[str, float | bool], equation_l: Callable[[float, Grid, dict], dict[str, ndarray]], k_min: float = None, simu_params: dict = None, n_threads: int = None, k0: bool = False)

Generic top-level object to handle solving log-grid equations

Parameters:
  • fields_names – the names of the grid-shaped fields

  • equation_nl – the function that performs the linear-less update step. Returns the time derivative of the fields

  • D – space dimension

  • l_params – parameters that define the grid parameter ̀`l` as a dict with keys {"a", "b", "plastic"}. “plastic” supercedes all other. For l=2, chose a=b=None

  • k_min – minimum k of the grid. Default is defined by Grid.

  • simu_params – physical quantities relevant to the simulation, fixed for the whole simulation.

  • n_threads – Number of threads to use, default is max/2 (not recommended, run benchmarking for better results. If running batch simulations, 1 is optimal.)

  • equation_l – implicit visocsity update step, called after the RK step has ended. Returns the new fields and their new time derivative

  • k0 – whether there’s a k0 mode

load_parameters(path: str) tuple[float, float]

Loads simulation parameters from settings.json.

Overwrites instance variables

Parameters:

path – directory to load the settings from

Returns:

physical time of the simulation’s last step and timestep

save_step_all(t: float, dt: float, path: str) None

Save the current step. Saves both fields and settings.

Parameters:
  • t – current time

  • dt – timestep

  • path – folder to save to. Will override any existing file.

solve(save_path: str, initial_conditions: str | Callable[[dict[str, ndarray], Grid, dict], dict[str, ndarray]] | tuple | list, solver_params: dict = None, init_t: float = 0, end_simulation=None, save_one_in: float = 1, update_gridsize_cb: Callable[[Grid], int | None] | None = None, dt_params: dict[str, float | None] = None, solver: Literal[ViscDopri, ETD4RK, ETD35] = 'ETD35') None

Solve the solver’s equation with the required numerical parameters.

Parameters:
  • save_path – where to save the fields and simulation parameters. Will backup if exists, will create otherwise

  • initial_conditions – if str: either "loadfromsave" to resume simulation, [legacy: or the path of the .npz save file whence to initialize the fields]. If tuple (name, step): load step step from .h5 name. Otherwise: function that returns the initial fields. If “loadfromsave”, it will override all dependant settings: end_simulation, rtol, atol, l_params, D, fields_name, simu_params, grid, k_min

  • solver_params – params forwarded to the solver

  • init_t – initial simulation time

  • end_simulation – dict of thresholds to end the simulation: {t: max physical time, elapsed_time: max real time spent computing, step: max save step}

  • save_one_in – save one step to file every X ode_step

  • update_gridsize_cb – optional callback to change the grid size after a step. Returns None if no change is to be made, returns the new grid size otherwise.

  • dt_params{dt0: initial timestep, dtmin, dtmax}

  • solver – among "ETD35" (default), "ETD4RK", "ViscDopri"