4.4.2 pde.pdes.base module

Base class for defining partial differential equations.

PDEBase

Base class for defining deterministic partial differential equations (PDEs)

SDEBase

Base class for defining stochastic partial differential equations (SDEs)

class PDEBase(*, rng=None)[source]

Bases: object

Base class for defining deterministic partial differential equations (PDEs)

Custom PDEs can be implemented by subclassing PDEBase to specify the evolution rate. In the simplest case, only the PDEBase.evolution_rate() needs to be implemented to support the numpy backend. Other backends require overwriting the PDEBase.make_evolution_rate().

Parameters:

rng (Generator) – Random number generator (default: default_rng()) used for stochastic simulations. Note that this random number generator is only used for numpy functions, while other backends might not use it. Moreover, in simulations using multiprocessing, setting the same generator in all processes might yield unintended correlations in the simulation results.

cache_rhs: bool = False

Flag indicating whether the right hand side of the equation should be cached. If True, the same implementation is used in subsequent calls to solve. Note that the cache is only invalidated when the grid of the underlying state changes. Consequently, the simulation might lead to wrong results if the parameters of the PDE are changed after the first call. This option is thus disabled by default and should be used with care.

Warning: This flag is deprecated since 2025-12-13 and caching is not implemented anymore.

Type:

bool

check_implementation: bool = True

Flag determining whether numba-compiled functions should be checked against their numpy counter-parts. This can help with implementing a correct compiled version for a PDE class.

Warning: This flag is deprecated since 2025-12-13 and this check will not be performed automatically anymore.

Type:

bool

check_rhs_consistency(rhs_implementation, state, t=0, *, tol=1e-07)[source]

Checks an implementation of the right hand side versus the numpy variant.

Parameters:
  • rhs_implementation (callable) – The implementation of the numba variant that is to be checked.

  • state (FieldBase) – The state for which the evolution rates should be compared

  • t (float) – The associated time point

  • tol (float) – Acceptance tolerance. The check passes if the evolution rates differ by less then this value

Return type:

None

complex_valued: bool = False

Flag indicating whether the right hand side is a complex-valued PDE, which requires all involved variables to have complex data type.

Type:

bool

determine_backend(state, backend='auto')[source]

Returns backend that will be chosen automatically for this PDE.

Parameters:
  • state (FieldBase) – An example for the state from which the grid and other information can be extracted.

  • backend (str) – Information about which backend to choose. The special value auto tries various backends and returns one for which the evolution rate is implemented for this PDE.

Returns:

The backend used automatically

Return type:

str

diagnostics: dict[str, Any]

Diagnostic information (available after the PDE has been solved)

Type:

dict

abstractmethod evolution_rate(state, t=0)[source]

Evaluate the right hand side of the PDE.

Parameters:
  • state (FieldBase) – The field at the current time point

  • t (float) – The current time point

Returns:

Field describing the evolution rate of the PDE

Return type:

FieldBase

explicit_time_dependence: bool | None = None

Flag indicating whether the right hand side of the PDE has an explicit time dependence.

Type:

bool

property is_sde: bool

flag indicating whether this is a stochastic differential equation

Type:

bool

make_evolution_rate(state, backend)[source]

Return function evaluating right hand side of the PDE using given backend.

Note

This factory function must return a function that processes fields stored in the native format of the backend. For instance, a function returned for the jax backend must deal with jax.Array objects.

Parameters:
  • state (FieldBase) – An example for the state from which the grid and other information can be extracted.

  • backend (str) – Determines the backend.

Returns:

Function determining the right hand side of the PDE

Return type:

callable

make_pde_rhs(state, backend='auto')[source]

Return a function for evaluating the right hand side of the PDE.

Parameters:
  • state (FieldBase) – An example for the state from which the grid and other information can be extracted.

  • backend (str) – The backend that is used to create the function. The special value numpy uses the method evaluation_rate. Other backends are only available if make_evolution_rate is defined for the PDE. If this is the case, the special value auto selects the numba backend, otherwise it defaults to numpy.

Returns:

Function determining the right hand side of the PDE

Return type:

callable

make_post_step_hook(state, backend='numpy')[source]

Returns a function that is called after each step.

This function receives three arguments: the current state as a numpy array, the current time point, and a numpy array that can store data for the hook function. The function must return the state data and the hook data, which it can both modify in place.

The hook can also be used to abort the simulation when a user-defined condition is met by raising StopIteration. Note that this interrupts the inner-most loop, so that some final information might be still reflect the values they assumed at the last tracker interrupt. Additional information (beside the current state) should be returned by the post_step_data. Note that raising StopIteration only works for some backends.

Example

The following code provides an example that creates a hook function that limits the state to a maximal value of 1 and keeps track of the total correction that is applied. This is achieved using post_step_data, which is initialized with the second value (0) returned by the method and incremented each time the hook is called.

def make_post_step_hook(self, state, backend):
    def post_step_hook(state_data, t, post_step_data):
        i = state_data > 1  # get violating entries
        overshoot = (state_data[i] - 1).sum()  # get total correction
        state_data[i] = 1  # limit data entries
        post_step_data += overshoot  # accumulate total correction
        return state_data, post_step_data

    return post_step_hook, 0.0  # hook function and initial value
Parameters:
  • state (FieldBase) – An example for the state from which the grid and other information can be extracted

  • backend (str) – Determines how the function is created (like ‘numpy’ and ‘numba’)

Returns:

The first entry is the function that implements the hook. The second

entry gives the initial data that is used as auxiliary data in the hook. This can be None if no data is used.

Return type:

tuple

solve(state, t_range, dt=None, tracker='auto', *, backend='auto', solver='euler', ret_info=False, **kwargs)[source]

Solves the partial differential equation.

The method constructs a suitable solver (SolverBase) and controller (Controller) to advance the state over the temporal range specified by t_range. This method only exposes the most common functions, so explicit construction of these classes might offer more flexibility.

Parameters:
  • state (FieldBase) – The initial state (which also defines the spatial grid).

  • t_range (float or tuple) – Sets the time range for which the PDE is solved. This should typically be a tuple of two numbers, (t_start, t_end), specifying the initial and final time of the simulation. If only a single value is given, it is interpreted as t_end and the time range is (0, t_end).

  • dt (float) – Time step of the chosen stepping scheme. If None, a default value based on the stepper will be chosen. If an adaptive stepper is used (e.g., supported by EulerSolver), dt sets the initial time step.

  • tracker (TrackerCollectionDataType) – Defines trackers that process the state of the simulation at specified times. A tracker is either an instance of TrackerBase or a string identifying a tracker (possible identifiers can be obtained by calling registered_trackers()). Multiple trackers can be specified as a list. The default value auto checks the state for consistency (tracker ‘consistency’) and displays a progress bar (tracker ‘progress’) when tqdm is installed. More general trackers are defined in trackers, where all options are explained in detail. In particular, the time points where the tracker analyzes data can be chosen when creating a tracker object explicitly.

  • backend (str) – Determines how the function is created. Accepted values are ‘numpy’ and ‘numba’. Alternatively, ‘auto’ lets the code pick the optimal backend.

  • solver (SolverBase or str) – Specifies the method for solving the differential equation. This can either be an instance of SolverBase or a descriptive name like ‘explicit’ or ‘scipy’. The valid names are given by pde.solvers.registered_solvers(). Details of the solvers and additional features (like adaptive time steps) are explained in solvers.

  • ret_info (bool) – Flag determining whether diagnostic information about the solver process should be returned. Note that the same information is also available as the diagnostics attribute.

  • **kwargs – Additional keyword arguments are forwarded to the solver class chosen with the solver argument. In particular, adaptive stepper can often be enabled using adaptive=True.

Returns:

The state at the final time point. If ret_info == True, a tuple with the final state and a dictionary with additional information is returned. Note that None instead of a field is returned in multiprocessing simulations if the current node is not the main MPI node.

Return type:

FieldBase

class SDEBase(*, noise=0, rng=None)[source]

Bases: PDEBase

Base class for defining stochastic partial differential equations (SDEs)

Custom PDEs can be implemented by subclassing SDEBase to specify the evolution rate and an associated noise realization. Overwrite make_noise_realization() (together with PDEBase.make_evolution_rate()) to support all backends.

Parameters:
  • noise (float or ndarray) – Variance of the additive Gaussian white noise that is supported for all PDEs by default. If set to zero, a deterministic partial differential equation will be solved. Different noise magnitudes can be supplied for each field in coupled PDEs.

  • rng (Generator) – Random number generator (default: default_rng()) used for stochastic simulations. Note that this random number generator is only used for numpy functions, while other backends might not use it. Moreover, in simulations using multiprocessing, setting the same generator in all processes might yield unintended correlations in the simulation results.

Note

If more complicated noise structures are required, overwrite SDEBase.make_noise_realization() to provide a custom noise realization for all backends.

property is_sde: bool

flag indicating whether this is a stochastic differential equation

The SDEBase class supports additive Gaussian white noise, whose magnitude is controlled by the noise property. In this case, is_sde is True if self.noise != 0.

Type:

bool

make_noise_realization(state, backend)[source]

Return a function for determining one realization of the noise term.

These functions generally assume that the field data is provided in the native form of the backend.

Parameters:
  • state (FieldBase) – An example for the state from which the grid and other information can be extracted.

  • backend (BackendBase) – The backend used to build the function. Note that the torch backend seems to have weak random number generators that might lead to spurious correlations.

Returns:

Function calculating the noise realization

Return type:

callable

noise_realization(state, t=0, *, label='Noise realization')[source]

Returns a realization for the noise.

Parameters:
  • state (ScalarField) – The scalar field describing the concentration distribution

  • t (float) – The current time point

  • label (str) – The label for the returned field

Returns:

Scalar field describing the evolution rate of the PDE

Return type:

ScalarField

expr_prod(factor, expression)[source]

Helper function for building an expression with an (optional) pre-factor.

Parameters:
  • factor (float) – The value of the prefactor

  • expression (str) – The remaining expression

Returns:

The expression with the factor appended if necessary

Return type:

str