# NeuralPDE.jl: PINN Solvers for ODEs, SDEs and PDEs in Julia

> NeuralPDE.jl builds physics-informed loss functions from a symbolic PDE/ODE description and hands the optimisation to SciML's solver stack. It is a research-grade tool for people who already write Julia and ModelingToolkit code, not a drop-in replacement for a finite-element solver.

**SciML/NeuralPDE.jl** — Physics-Informed Neural Networks (PINN) Solvers of (Partial) Differential Equations for Scientific Machine Learning (SciML) accelerated simulation

- Repository: https://github.com/SciML/NeuralPDE.jl
- Website: https://docs.sciml.ai/NeuralPDE/stable/
- Stars: 1,232 · Forks: 250
- Language: Julia
- License: NOASSERTION
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/sciml-neuralpde-jl

## The problem NeuralPDE.jl exists to solve

Classical PDE solvers need a mesh. Once the dimension climbs past three or four, the number of grid points needed to resolve the domain grows fast enough that mesh generation and assembly dominate the runtime, and for irregular or high-dimensional domains the mesh may not be constructible at all. Physics-informed neural networks take the opposite route: a neural network is the ansatz, the equation residual is evaluated at sampled collocation points, and the boundary and initial conditions become additional penalty terms in a single scalar loss. No mesh is built. The README describes the package as a solver package consisting of neural network solvers for partial differential equations using physics-informed neural networks, and it states that the package uses neural stochastic differential equations to solve PDEs at increased generality compared with classical methods.

The audience is narrow and specific. If you are comfortable writing Julia and ModelingToolkit, and your problem is already expressed as a PDESystem with symbolic variables, parameters and domains, NeuralPDE.jl fits into that description directly. If you are a domain scientist who works in Python or C++ and wants a black-box PDE solver, this is the wrong tool, and the friction is not the API but the surrounding ecosystem: Lux, Optimization, DomainSets and ModelingToolkit all appear in the README example before a single equation is solved.

## How the symbolic interface becomes a training problem

The README's 2D Poisson example shows the data flow end to end. You declare parameters and variables with @parameters and @variables, build the residual with Differential operators, then wrap everything in a PDESystem:

```julia
@named pde_system = PDESystem(eq, bcs, domains, [x, y], [u(x, y)])
prob = discretize(pde_system, discretization)
```

The PDESystem holds the equation, the boundary conditions, the domains and the independent and dependent variables. discretize is where the work happens: it takes the symbolic system and a discretization object, and returns an optimisation problem whose objective is the physics-informed loss. In the example the discretization is PhysicsInformedNN(chain, QuadratureTraining()), so the neural network is a Lux.Chain and the collocation strategy is QuadratureTraining. The README lists quadrature training strategies, adaptive loss functions and neural adapters among the techniques used to accelerate training.

That loss is then minimised with an ordinary optimiser from Optimization.jl. The README calls Optimization.solve(prob, ADAM(0.1); callback = callback, maxiters = 4000) and then remakes the problem with the previous solution as the initial condition for a second, lower-learning-rate run at ADAM(0.01). The discretization object retains a phi field, which is the callable solution: the README evaluates first(phi([x, y], res.u)) over a grid to build the predicted field. This is the part worth internalising. There is no solve call that returns an interpolant; you get a trained parameter vector and a callable network, and any accuracy assessment is something you write yourself.

## Installing NeuralPDE.jl and running the 2D Poisson example

The README assumes Julia is already installed and gives one step: type `] add NeuralPDE` in the Julia REPL. The `]` puts the REPL into Pkg mode; the README notes that you leave it with Backspace or Ctrl+C. The package is not registered under an alternative name and the README documents no other installation path.

A first real use is the 2D Poisson problem from the README. The setup declares the PDE and its boundary conditions, then the domains:

```julia
eq = Dxx(u(x, y)) + Dyy(u(x, y)) ~ -sin(pi * x) * sin(pi * y)
bcs = [
    u(0, y) ~ 0.0, u(1, y) ~ 0,
    u(x, 0) ~ 0.0, u(x, 1) ~ 0,
]
domains = [
    x ∈ Interval(0.0, 1.0),
    y ∈ Interval(0.0, 1.0),
]
```

The network is a two-hidden-layer Lux chain with 16 units per layer and a scalar output, and the discretization pairs it with QuadratureTraining. The solve is two-stage: a coarse run at learning rate 0.1 for 4000 iterations, then a remake of the problem with res.u as the new initial parameters and a finer run at 0.01 for 2000 iterations. The callback prints the current loss and returns false, which is the signal to keep iterating.

What you should see is a loss printed at each callback invocation, and after the second solve a phi you can evaluate on a grid. The README compares the prediction against the analytic solution (sin(pi*x)*sin(pi*y))/(2pi^2) and plots the absolute difference as a third contour. That comparison is the point of the example: the package gives you the machinery to train, and the README's own workflow treats the analytic solution as the check.

## Where NeuralPDE.jl is the wrong choice

The README does not document an error bound, a convergence guarantee, or a stopping criterion tied to residual tolerance. Training stops when maxiters is reached. The example uses 4000 iterations at one learning rate followed by 2000 at another, and the README presents the resulting error contour plot without claiming a particular accuracy. If your application needs a certified discretisation error, or a solution you can defend to a regulator, this is not the tool. A finite-element or finite-volume code with an established convergence theory is the right answer there.

The second limitation is that the loss is a sum of penalty terms, and the relative weighting between the PDE residual and the boundary conditions is not something the README's example tunes. The README lists adaptive loss functions as a feature, which suggests the package has machinery for this, but the introductory example uses the default and does not discuss what happens when the boundary penalty is under- or over-weighted. Practitioners of PINNs generally treat this balancing as the hard part of the method, and the README does not address it in the example.

The third is cost. Every iteration evaluates the network and its derivatives at collocation points, and the README's feature list includes GPU compatibility through Flux.jl and Lux.jl, which implies the intended deployment is accelerator-backed. On CPU, a 4000-iteration run of a small network is not free, and the package makes no claim about how it compares to a classical solver on a problem where a mesh is cheap. For a one-dimensional or two-dimensional problem on a regular box, a spectral or finite-difference method will very likely be faster and more accurate. The README's own example is 2D, and it is a demonstration, not a benchmark.

## NeuralPDE.jl compared with a classical PDE solver and with NeuralOperators.jl

The clearest alternative is any classical discretisation: finite differences, finite elements, finite volumes, spectral methods. The difference in approach is fundamental. A classical solver approximates the solution on a fixed mesh and the error is controlled by the mesh size and the scheme's order. NeuralPDE.jl approximates the solution with a neural network trained on sampled residuals, and the error depends on the network architecture, the sampling, the optimiser and the number of iterations. Classical solvers are the right default when the dimension is low and the geometry is manageable. NeuralPDE.jl becomes interesting when the dimension is high enough that meshing is the obstacle, or when you want to add a data-fitting term to the equation residual, which the README lists as a feature: defining extra loss functions to mix equation solving with data fitting.

The second alternative is NeuralOperators.jl, which the README names as compatible. The distinction is what gets learned. NeuralPDE.jl trains a network to represent one solution of one problem. A neural operator, such as a DeepONet or a Fourier Neural Operator, learns a map from one function to another, so after training it can be evaluated on a new instance of the same family of problems without retraining. The README states that NeuralOperators.jl can be combined with physics-informed loss functions, so the two are not mutually exclusive. If your goal is to solve the same equation many times with different parameters or boundary data, the operator approach is the one that amortises the training cost; if you have one problem, the PINN approach is simpler.

## Maintenance, licence and the cost of upgrading

The repository is not archived, and the last push was on 2026-09-10. Three releases landed in the days before that: v6.3.0 on 2026-09-06, v6.3.1 on 2026-09-07 and v6.3.2 on 2026-09-10. That cadence means the package is moving, and it also means the version you pin today will be behind within weeks. The README points readers to the stable documentation at docs.sciml.ai/NeuralPDE/stable/ and notes that the in-development documentation at docs.sciml.ai/NeuralPDE/dev/ contains unreleased features. Check which one a given API appears in before you build on it, because an API documented only in the dev docs is not something you can rely on across a minor release.

The upgrade cost is structural rather than incidental. A NeuralPDE.jl script pulls in ModelingToolkit, SciMLBase, Lux, Optimization and OptimizationOptimisers, and the README example also uses DomainSets. A breaking change in ModelingToolkit's symbolic interface or in Lux's layer construction propagates into user code even when NeuralPDE.jl itself has not changed its own API. Budget for re-running your training scripts after dependency updates, not just after NeuralPDE.jl version bumps.

The repository's LICENSE.md is present, but GitHub reports the licence as NOASSERTION, meaning the platform could not match the file to a recognised identifier. The README does not state a licence in prose. If you need to redistribute the package or embed it in a product, read LICENSE.md yourself and confirm the terms with whoever handles licensing on your side. This article cannot tell you what those terms are.

## Conclusion

Adopt NeuralPDE.jl if your problem is already written as a ModelingToolkit system, you want to mix data fitting with equation residuals, or the domain is high-dimensional enough that meshing is the bottleneck. Do not adopt it if you need a verified error bound, a conservative discretisation, or a solver you can hand to a team that does not write Julia. Before committing, reproduce the 2D Poisson example from the README on your own hardware, check that the accuracy at maxiters = 4000 plus 2000 is acceptable for your tolerance, and confirm that the Lux chain and QuadratureTraining combination you intend to use appears in the stable docs rather than only in the dev docs.

## FAQ

### How do I install NeuralPDE.jl?

The README assumes Julia is already installed and says to type `] add NeuralPDE` in the Julia REPL. The `]` enters Pkg REPL mode, which you exit with Backspace or Ctrl+C.

### What kinds of equations can NeuralPDE.jl solve?

The README lists physics-informed neural networks for ODE, SDE, RODE and PDE solving, plus handling of partial integro-differential equations and various stochastic equations. It also notes specialized forms for solving ODEProblems with neural networks.

### Does NeuralPDE.jl work with GPU-accelerated neural network layers?

The README states compatibility with Flux.jl and Lux.jl for all of the GPU-powered machine learning layers available from those libraries. The 2D Poisson example uses a Lux.Chain.

### Can NeuralPDE.jl mix equation solving with measured data?

Yes. The README lists the ability to define extra loss functions to mix equation solving with data fitting as a feature, described as scientific machine learning.

## Sources

- [Issues](https://github.com/SciML/NeuralPDE.jl/issues)
- [Project website](https://docs.sciml.ai/NeuralPDE/stable/)
- [README](https://github.com/SciML/NeuralPDE.jl/blob/master/README.md)
- [Releases](https://github.com/SciML/NeuralPDE.jl/releases)
- [SciML/NeuralPDE.jl on GitHub](https://github.com/SciML/NeuralPDE.jl)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/sciml-neuralpde-jl
