PDEs¶
Every PDE is registered once in pdes.registry, and both the CLI and the dashboard read it from there.
create_pde ¶
get_pde_spec ¶
Resolve a config key or display name (case-insensitive) to its spec.
Raises:
| Type | Description |
|---|---|
KeyError
|
If |
Source code in pinnrl/pdes/registry.py
PDESpec
dataclass
¶
A registered PDE.
Attributes:
| Name | Type | Description |
|---|---|---|
key |
str
|
Config key under |
display_name |
str
|
Human-readable name shown by the dashboard and CLI. |
cls |
type[PDEBase]
|
The :class: |
PDEConfig
dataclass
¶
PDEConfig(
name,
domain,
time_domain,
parameters,
boundary_conditions,
initial_condition,
exact_solution,
dimension=1,
input_dim=None,
output_dim=None,
architecture=None,
device=None,
training=None,
trainable_parameters=list(),
parameter_initial_guesses=dict(),
observation_data=None,
)
Configuration dataclass for PDE parameters.
PDEBase ¶
Base class for PDEs solved by PINNs.
A subclass provides the physics:
- :meth:
compute_residual— the PDE operator applied to the network. - :meth:
_create_initial_condition—u(x, t0)for its IC types. - :meth:
_exact_solution— a closed-form solution, when one exists. time_order = 2for second-order-in-time PDEs; the initial loss then also enforcesu_t(x, t0) = initial_condition["velocity"](default 0).
The base class owns everything else: derivatives, collocation sampling,
boundary conditions and the composite loss. boundary_conditions in the
config maps a kind to its options; every spatial axis gets the condition
on both faces:
dirichlet:{"value": v}or{"left": a, "right": b}(the lower / upper face), or{"type": "exact"}to take values from the exact solution;neumann:{"value": g}—du/dx_axis = gon both faces;periodic:{}—uanddu/dx_axisagree on opposite faces.
exact_solution: {} in the config means the problem has no closed-form
solution; :meth:exact_solution then returns None.
Initialize PDE with given configuration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
PDEConfig
|
Configuration dataclass. |
required |
bandit_sampler
|
Optional :class: |
None
|
Source code in pinnrl/pdes/pde_base.py
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | |
get_parameter ¶
Safely get a parameter value with validation.
When name has been registered as a trainable parameter (inverse
problem mode), the live nn.Parameter tensor is returned so that
downstream residual computations build the autograd graph through it.
Otherwise the plain float from config.parameters is returned.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Parameter name |
required |
default
|
Default value if parameter not found |
None
|
|
required
|
bool
|
Whether parameter is required (raises error if missing) |
False
|
Returns:
| Type | Description |
|---|---|
|
Parameter value ( |
Raises:
| Type | Description |
|---|---|
ValueError
|
If required parameter is missing |
Source code in pinnrl/pdes/pde_base.py
trainable_parameters_iter ¶
Iterator over registered trainable PDE parameters (for the optimizer).
get_trainable_parameter_values ¶
Snapshot of current trainable parameter values as plain floats.
Source code in pinnrl/pdes/pde_base.py
generate_synthetic_observations ¶
Sample noisy observations from the analytical solution.
Useful for inverse-problem demos and CI tests: pick uniform points in
the domain, evaluate self.exact_solution, optionally add Gaussian
noise, and store the result on self.observation_data so the next
compute_loss call automatically picks it up.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_points
|
int
|
Number of observations. |
200
|
noise_std
|
float
|
Standard deviation of the additive Gaussian noise. |
0.0
|
seed
|
int | None
|
Seed for the points and the noise; |
0
|
Returns:
| Type | Description |
|---|---|
dict[str, Tensor]
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If the PDE has no exact solution configured. |
Source code in pinnrl/pdes/pde_base.py
compute_residual ¶
Compute the PDE residual. Must be implemented by subclasses.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Module
|
Neural network model. |
required |
x
|
Tensor
|
Spatial coordinates, shape |
required |
t
|
Tensor
|
Time coordinates, shape |
required |
Returns:
| Type | Description |
|---|---|
Tensor
|
Residual tensor, shape |
Source code in pinnrl/pdes/pde_base.py
laplacian ¶
Sum of the pure second derivatives of f along each column of x.
x must be the leaf tensor f was computed from (requires_grad).
Differentiating with respect to the whole tensor and then taking a column
is what makes this correct in more than one dimension; a column slice
x[:, d:d+1] is not part of the graph.
Source code in pinnrl/pdes/pde_base.py
compute_derivatives ¶
Evaluate u = model([x, t]) and the requested derivatives.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Module
|
Neural network model. |
required |
x
|
Tensor
|
Spatial coordinates, shape |
required |
t
|
Tensor
|
Time coordinates, shape |
required |
temporal_derivatives
|
list[int]
|
Orders of |
None
|
spatial_derivatives
|
set[int]
|
Orders of the pure |
None
|
Returns a dict with "u" and, for the requested orders only:
- time:
"dt","dt2"; - space, 1-D:
"dx","dx2","dx3","dx4"; - space, n-D: pure derivatives per axis,
"dx1","dx1x1", ..."dx2x2"; "laplacian"whenever order 2 is requested.
Raises:
| Type | Description |
|---|---|
ValueError
|
For temporal orders above 2 or spatial orders above 4. |
Source code in pinnrl/pdes/pde_base.py
exact_solution ¶
Closed-form u(x, t), or None when exact_solution is not configured.
Source code in pinnrl/pdes/pde_base.py
generate_collocation_points ¶
Generate collocation points for training.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num_points
|
int
|
Number of points to generate. |
required |
strategy
|
str
|
Sampling strategy, one of:
|
'uniform'
|
**kwargs
|
Strategy options listed above. |
{}
|
Returns:
| Type | Description |
|---|---|
tuple[Tensor, Tensor]
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
For an unknown strategy, or |
Source code in pinnrl/pdes/pde_base.py
compute_loss ¶
Loss components and their weighted total.
Returns residual (at the collocation points x, t), boundary,
initial, data (observations; zero without any) and total.
training.mode selects the objective (see :meth:weighted_total):
data_only keeps only the data term; every other mode adds the
weighted physics terms to the data term. Weights come from
training.loss_weights (residual/pde, boundary,
initial, data; 1, 10, 10 and 1 when a key is absent). With
adaptive weighting enabled the physics weights here are 1 and the
trainer re-weights the total.
Source code in pinnrl/pdes/pde_base.py
weighted_total ¶
Combine loss components under training.mode.
data_only drops the physics terms; outside forward the data term
always counts (its weight is at least 1).
Source code in pinnrl/pdes/pde_base.py
validate ¶
Error of model against the exact solution on a jittered grid.
Returns l2_error (relative L2, ||u - u*|| / ||u*||), mse,
max_error and mean_error.
Raises:
| Type | Description |
|---|---|
ValueError
|
If the PDE has no exact solution configured. |
Source code in pinnrl/pdes/pde_base.py
HeatEquation ¶
Bases: PDEBase
Heat equation u_t = alpha * ∇²u.
Parameters: alpha (thermal diffusivity, required).
Initial conditions, each with the exact solution of the same type
(amplitude A, frequency k; L_d is the length of spatial axis d):
-
sin_exp_decay(aliassine)::u = A · Π_d sin(2π k x_d / L_d) · exp(-alpha · Σ_d (2π k / L_d)² · t)
Each factor is an eigenfunction of ∂²/∂x_d² with eigenvalue
-(2π k / L_d)², so the product decays at the summed rate.
* sine_2d (2-D; frequency_x kx, frequency_y ky)::
u = A · sin(kx π x) · sin(ky π y) · exp(-alpha π² (kx² + ky²) t)
Source code in pinnrl/pdes/heat_equation.py
compute_residual ¶
u_t - alpha ∇²u.
Source code in pinnrl/pdes/heat_equation.py
WaveEquation ¶
Bases: PDEBase
Wave equation u_tt = c² ∇²u.
Parameters: c (wave speed, default 1).
Second order in time: the initial loss also enforces
u_t(x, 0) = initial_condition["velocity"] (default 0).
Initial conditions, each with the exact solution of the same type —
standing waves that vanish on the faces of [0, 1]^d for integer
frequencies (amplitude A, frequency k):
sine:u = A Π_d sin(kπ x_d) · cos(ω t)withω = c k π √d, since∇²of the product is-d (kπ)²times itself.sine_2d(frequency_xkx,frequency_yky):u = A sin(kx π x) sin(ky π y) cos(ω t)withω = c π √(kx² + ky²).
Both start at rest (u_t(x, 0) = 0).
Source code in pinnrl/pdes/wave_equation.py
compute_residual ¶
u_tt - c² ∇²u.
Source code in pinnrl/pdes/wave_equation.py
BurgersEquation ¶
Bases: PDEBase
Viscous Burgers equation u_t + u (Σ_d u_{x_d}) = nu ∇²u.
Parameters: nu (viscosity, default 0.01; viscosity is accepted as
an alias).
Initial conditions: sine — u0 = A Π_d sin(kπ x_d) (amplitude A,
default -1; frequency k, default 1).
Exact solution (1-D): cole_hopf — the Cole-Hopf integral for the
configured sine initial condition and nu, evaluated by
:func:pinnrl.benchmarks.reference.burgers_cole_hopf.
Source code in pinnrl/pdes/burgers_equation.py
compute_residual ¶
u_t + u Σ_d u_{x_d} - nu ∇²u.
Source code in pinnrl/pdes/burgers_equation.py
KdVEquation ¶
Bases: PDEBase
Korteweg-de Vries equation u_t + alpha u u_x + beta u_xxx = 0 (1-D).
Parameters: alpha (nonlinearity, default 6), beta (dispersion,
default 1).
Initial condition and exact solution: soliton with speed c (default 1)
and optional position x0::
u = (3c / alpha) · sech²( ½ √(c / beta) · (x - x0 - c t) )
Substituting u = f(x - c t) and integrating twice shows this travels at
exactly c and decays to zero away from its crest at x0 + c t.
Source code in pinnrl/pdes/kdv_equation.py
compute_residual ¶
u_t + alpha u u_x + beta u_xxx.
Source code in pinnrl/pdes/kdv_equation.py
ConvectionEquation ¶
Bases: PDEBase
Linear advection u_t + v · ∇u = 0.
Parameters: velocity (a number, or one entry per spatial axis).
Initial conditions: sine (alias sin) — the plane wave
u0 = A sin(kπ Σ_d x_d) (amplitude A, frequency k).
Exact solution: sine (alias sin) — the initial profile transported
with the flow, u(x, t) = u0(x - v t).
Source code in pinnrl/pdes/convection_equation.py
compute_residual ¶
u_t + Σ_d v_d u_{x_d}.
Source code in pinnrl/pdes/convection_equation.py
AllenCahnEquation ¶
Bases: PDEBase
Allen-Cahn equation u_t = epsilon² ∇²u + r (u - u³).
Parameters: epsilon (interface width, default 0.1), reaction_rate
r (default 1).
Initial conditions:
tanh— the planar kink normal to(1, ..., 1)/√d,u = tanh(√r · Σ_d x_d / (√(2d) · epsilon)). It solvesepsilon² φ'' + r (φ - φ³) = 0, so it is stationary.x2_cos— the benchmarku0 = x² cos(π x)(no closed form; score it against :func:pinnrl.benchmarks.reference.allen_cahn_reference).
Exact solution: tanh — the stationary kink above.
Source code in pinnrl/pdes/allen_cahn.py
compute_residual ¶
u_t - epsilon² ∇²u - r (u - u³).
Source code in pinnrl/pdes/allen_cahn.py
CahnHilliardEquation ¶
Bases: PDEBase
Cahn-Hilliard equation u_t = M ∇²μ with μ = u³ - u - kappa ∇²u.
Parameters: mobility M (alias M, default 1) and kappa (gradient
energy; if absent, epsilon² with epsilon default 0.1).
Initial conditions:
tanh— the planar kinktanh(Σ_d x_d / √(2 d kappa)). It makesμ ≡ 0, so it is a stationary solution.random(from the base class) — a smooth, reproducible perturbation for spinodal-decomposition runs. No closed form.
Exact solution: tanh — the stationary kink above.
Source code in pinnrl/pdes/cahn_hilliard.py
compute_residual ¶
u_t - M ∇²(u³ - u - kappa ∇²u).
Source code in pinnrl/pdes/cahn_hilliard.py
BlackScholesEquation ¶
Bases: PDEBase
Black-Scholes equation in time to maturity τ (the t input).
The PDE is::
V_τ = ½ σ² Σ_d S_d² V_{S_d S_d} + r Σ_d S_d V_{S_d} - r V
(in more than one dimension the assets are uncorrelated: no cross terms).
Writing it in τ = T - t turns the payoff at maturity into the initial
condition at τ = 0, which is what the PINN loss imposes.
Parameters: sigma (volatility, default 0.2), r (risk-free rate,
default 0.05).
Initial condition: option (alias call_option) — the payoff
max(S - K, 0) for option_type: call (the default) or max(K - S, 0)
for put, with strike K (alias strike_price, default 100) on
S = Σ_d S_d.
Exact solution (1-D): black_scholes — the closed-form European price
S Φ(d1) - K e^{-rτ} Φ(d2) (call) or K e^{-rτ} Φ(-d2) - S Φ(-d1) (put)
for the configured option.
Source code in pinnrl/pdes/black_scholes.py
compute_residual ¶
V_τ - ½σ² Σ S² V_SS - r Σ S V_S + r V.
Source code in pinnrl/pdes/black_scholes.py
PendulumEquation ¶
Bases: PDEBase
Damped nonlinear pendulum θ'' + b θ' + (g/L) sin θ = 0.
The angle θ(t) is the network output; the spatial input is a dummy
coordinate the solution does not depend on.
Parameters: g (default 9.81), L (default 1), damping b (default 0).
Second order in time: the initial loss enforces θ(0) = initial_angle and
θ'(0) = velocity (default 0).
Initial condition: small_angle (alias fixed) with initial_angle
(alias value, default 0.5).
Exact solution: ode — the full nonlinear damped trajectory from the
configured initial angle and velocity, integrated with scipy to 1e-11
relative tolerance (there is no elementary closed form; the small-angle
formula θ0 cos(ωt) is only an approximation).
Source code in pinnrl/pdes/pendulum_equation.py
compute_residual ¶
θ'' + b θ' + (g/L) sin θ.
Source code in pinnrl/pdes/pendulum_equation.py
compute_energy ¶
Mechanical energy per unit mass, ½ L² θ'² + g L (1 - cos θ).
Source code in pinnrl/pdes/pendulum_equation.py
compute_phase_space ¶
Phase-space coordinates (θ, θ').