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.
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).
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
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.)
In pyloggrid, simulating equations is done through the Solver class.
A Solver object is initialized with parameters of the simulation:
Geometric parameters (D,l_params,k_min,k0)
l_params is a dict that describes the scaling parameter l of the grid. If the “plastic” key is set to True (l_params={"plastic":True,...}) then l~=1.3 (the plastic number). If plastic is not True, then keys a,b must be specified and have integer values, in which case l is the solution to l**b-l**a=1. In particular if l_params={"a":1,"b":2} then l~=1.6 (the golden number). To get the special case l=2, use l_params={"a":None,"b":None}.
Important
Choosing either "plastic":True, "a":int,"b":int or "a":None,"b":None doesn’t just change the scaling of the grid, but also the number of interactions per point for the convolution (listed here in decreasing order), which affects both the physics and the required computing power.
k0 is a bool that indicates whether the axes \(k_i=0\) are included. Enabling this comes at a significant performance cost, and greatly modifies the interaction between grid points.
k_min is the minimum absolute value of a wavevector on each axis, excluding zeros. This is not the minimum magnitude of a wavevector on the grid, which would be \(\sqrt{D}k_{min}\) in \(D\) dimensions.
For stability and performance reasons, the equation to solve is divided into two parts: one that is proportional to the scalar input equation_l, and the rest equation_nl. If your equation is \(\partial_t u=A(u)−b\cdot u\), then the linear part is \(−b\), and the nonlinear part is \(A(t, u)\).
equation_l,equation_nl expect functions that take as arguments t:float,grid:Grid,simu_params:dict and return a dict {"field_name":d/dt_field_name,...}.
Warning
Note that the linear part must be time-independent.
simu_params are arbitrary (serializable) constants used in the simulation. The fields named by fields_names, on the other hand, are grid-shaped complex scalars., i.e. “the fields being simulated”.
Simulations are ran by calling the solve() method.
Warning
Although in theory you can use the solve method several times on a single Solver object, this isn’t a common use case. Do so at your own risks, but please report unexpected behavior to us.
Solve the solver’s equation with the provided 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.
solver_params – params forwarded to the solver
init_t – initial simulation time
end_simulation – dict of thresholds to end the simulation: {t:maxphysicaltime,elapsed_time:maxrealtimespentcomputing,step:maxsavestep}
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:initialtimestep,dtmin,dtmax}
solver – "ETD35" for ETD35 (default), "ETD4RK" for ETD4RK, "ViscDopri" for ViscDopri
If save_path="<path>/<foldername>" already exists on disk, the existing directory will be renamed to <path>/bk_<foldername>_<TIMESTAMP>. Otherwise, it will be automatically created.
If initial_conditions="loadfromsave" then settings and initial conditions will be loaded from the last step of the existing simulation in save_path. This will override the following arguments: end_simulation,l_params,D,fields_name,simu_params,k_min,k0.
To load from a specific step of a .h5 simulation file, set loadfromsave=(<filepath>:str,<step>:int).
Otherwise, initial_conditions must be a function that takes (fields, grid, simu_params) and returns the initial fields.
update_gridsize_cb is an optional function to dynamically change the grid size. It takes (grid) and returns either None (no change) or a new grid size.