Build a notebook from an empty canvas
Ten blocks, thirteen wires, one problem with a known answer. Build the 1D Poisson problem block by block, generate the script, run it, and check the result against the exact solution.
The problem is the smallest one with a known answer:
$$ u''(x) = -\pi^2 \sin(\pi x), \qquad x \in [0, 1], \qquad u(0) = u(1) = 0, $$
whose exact solution is $u(x) = \sin(\pi x)$. We choose it because you can tell at once whether the network got it right. The mathematics of this example, and what the network is doing, are in the textbook: the 1D Poisson equation. This page is about the clicks.
The sign
The Lab's Poisson block solves $\nabla^2 u = f$. Our equation is $u'' = f$ with $f = -\pi^2\sin(\pi x)$, so that is what we type as the source. If you typed $+\pi^2\sin(\pi x)$, you would get the mirror image of the answer.
1. Start
Open the Lab. On the Start a notebook card, type the name Poisson 1D, choose An empty canvas under Start from, and press Create notebook. The canvas is empty and the Graph check says: The canvas is empty. Drag a Domain block in to begin.
2. Place the ten blocks
Drag these from the palette, or click them (see Blocks on the canvas). Arrange them left to right as you place them: it makes the wiring much easier to follow.
| Block | How many |
|---|---|
| Domain | 1 |
| PDE | 1 |
| Boundary condition | 2 |
| Network | 1 |
| Loss | 1 |
| Optimiser | 1 |
| Train | 1 |
| Visualisation | 1 |
| Report | 1 |
That is ten blocks, counting the two boundary-condition blocks separately. We will call those BC 1 and BC 2; the studio numbers them in the order you place them.
Your screenshot · the ten blocks placed on the canvas, not yet wired.
3. Set each block
Click a block to select it and use the panel on the right.
Domain. The defaults are right: Geometry type Line, x min 0, x max 1, Time dimension off. Press Detect boundaries. It reports: Detected 2 boundaries, and the block shows two outputs, BC1 and BC2.
PDE. Set Equation type to Elliptic, then Equation to Poisson. In Source f(x, y) type:
-pi**2*sin(pi*x)
A power is **, and pi is built in (the formula rules are on Read and change a block's settings). The block's summary now reads poisson (elliptic).
BC 1 and BC 2. The defaults are right: Condition type Dirichlet, u = 0.0.
Network, Loss, Optimiser, Train, Visualisation, Report. Leave every one at its default. That is a network with four hidden layers of 40 neurons and tanh, equal loss weights, Adam at a learning rate of 0.001 for 5000 epochs, a seed of 0, a field plot, a loss curve and a results table.
4. Wire them
Press on a dot, drag to a lit dot of the same colour, release. The full list, working left to right:
| # | From | To |
|---|---|---|
| 1 | Domain Coords | PDE Coords |
| 2 | Domain Interior | PDE Interior |
| 3 | Domain Coords | Network Coords |
| 4 | Domain BC1 | BC 1 Boundary |
| 5 | Domain BC2 | BC 2 Boundary |
| 6 | PDE PDE residual | Loss PDE residual |
| 7 | Network Network | Loss Network |
| 8 | BC 1 output | Loss BC / IC |
| 9 | BC 2 output | Loss BC / IC |
| 10 | Loss Loss | Train Loss |
| 11 | Optimiser Optimiser | Train Optimiser |
| 12 | Train Model | Visualisation Model |
| 13 | Train Model | Report Model |
Rows 8 and 9 go to the same input, which accepts many wires. Rows 1 and 3 start from the same output, which can feed many inputs. The picture is the one on Wiring blocks together.
Your screenshot · the finished graph, all thirteen wires in place, with Graph check: nothing to flag. underneath.
5. Check
Look at the strip under the canvas. If the build is right it reads Graph check: nothing to flag. If it lists notes, read them against the table in When the Graph check complains. The usual causes are a missed wire (a No condition on BC2… note) and a forgotten Domain-to-Network wire.
6. Generate and run
Press Generate code, then Download .py in the window (or Copy code for Colab). From a terminal in the folder where the file landed:
python poisson-1d.py
Five thousand epochs of this network took about a minute on the plain CPU we used. You can stop early with Ctrl+C. The details of running and the other options are on Run the script.
7. Judge the result
Open figures/field.png. You should see one half-wave of a sine, starting and ending at zero, with a peak of about 1 in the middle. Open figures/loss.png: the total loss should fall steeply in the first few hundred epochs and keep falling more slowly. Then compare numerically. The table results.csv holds the network's value at each of the 2000 interior points, and the exact value is $\sin(\pi x)$. This short script measures the relative error:
import csv, math
xs, us = [], []
with open("results.csv") as f:
for row in csv.reader(f):
if not row or row[0].startswith("#"):
continue # the blank line and the summary block
if row[0] == "x":
continue # the header
xs.append(float(row[0]))
us.append(float(row[1]))
exact = [math.sin(math.pi * x) for x in xs]
num = math.sqrt(sum((u - e) ** 2 for u, e in zip(us, exact)))
den = math.sqrt(sum(e ** 2 for e in exact))
print(f"{len(xs)} points, relative L2 error = {num / den:.2e}")
What to expect: we ran this exact notebook four times from different starting weights. The relative error ended at $2.6\times10^{-4}$, $4.9\times10^{-4}$, $6.2\times10^{-4}$ and, once, $3.7\times10^{-3}$. That last run was not worse during training: its loss had reached about $10^{-5}$, and then it ended on a late spike, and the script saves the weights from the end. The range is typical of Adam on a PINN. Your run will land somewhere in it, not on any one of these numbers.
If you see an error of 0.1 or more, something is wrong, and the usual suspect is the sign of the source. That error is wrong in the shape: the field plot would show a trough where a hump should be.
To get a calmer result, tick Second stage on the Optimiser block (Adam, then L-BFGS), regenerate and run again. In our three runs of that version the error was between $6\times10^{-6}$ and $1.3\times10^{-5}$. See the optimiser and the Train block.
Your screenshot · figures/field.png and figures/loss.png side by side for your own run.
8. Save your work
The notebook is stored in your browser as you build it. To keep a copy outside the browser, press Download notebook at the top of the notebook page. It saves poisson-1d.omega-notebook.json. On the Lab page, Open a notebook file… reads such a file back in as a new notebook.
Where next
You have now built, wired, generated, run and checked a complete problem. Change a starter shows the faster way to your own problem: start from a working notebook and alter it one block at a time. For the same problem in a square, and what changes when the loss has to balance four boundaries, see Poisson on a square.