Custom implementation guidelines¶
pySDC solves (non-)linear ODE of the form
$$ frac{du}{dt} = f(u, t), quad u(0)=u_0, quad t in [0, T]. $$
where $u$ a vector or scalar, representing one or more variables.
The type of variable, the definition of the right-hand side $f(u,t)$ and initial solution value $u_0$ are defined in a given Problem class.
… to be continued …
Implementing a custom problem class¶
Any problem class inherit from the same base class, that is (currently) the ptype class from the module pySDC.code.Problem.
Each custom problem should inherit from this base class, like for the following example template :
right-hand side $f(u,t)=lambda u + ct$ with
$lambda$ one or more complex values (in vector form)
$c$ one scalar value
import numpy as np
from pySDC.core.Problem import ptype
from pySDC.core.Errors import ProblemError
from pySDC.implementations.datatype_classes.mesh import mesh
class MyCustomProblem(ptype):
# 1) Provide datatype class as class attribute
dtype_u = mesh # -> used for u values
dtype_f = mesh # -> used for f(u,t) values
# 2) Define constructor
def __init__(self, lam, c):
# Store lambda values into a numpy array (with copy) + check
lam = np.array(lam)
if len(lam.shape) > 1:
raise ProblemError(f"lambda values must be given as 1D vector, got shape {lam.shape}")
# Call base constructor
super().__init__(init=(lam.size, None, lam.dtype))
# Register parameters
self._makeAttributeAndRegister('lam', 'c', localVars=locals(), readOnly=True)
# 3) Define RHS function
def eval_f(self, u, t):
f = self.f_init # Generate new datatype to store result
f[:] = self.lam*u + self.c*t # Compute RHS value
return f
🔔 The _makeAttributeAndRegister automatically add lam and c, and register them in a list of parameters that are printed in the outputs of pySDC.
If you set readOnly=True, then those parameters cannot be changed after initializing the problem (if not specifies, use readOnly=False).
⬅️ Back to Naming Conventions — ⬆️ Contributing Summary — ➡️ Next to Documenting Code