# Define Equations

> Define PDEs, ODEs, boundary conditions, and custom equations for PINA physics-driven problems. Covers the equation zoo, custom equation functions, and inverse problem equation signatures.

- Skill: `pina-org/define-equations` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add pina-org/define-equations`
- Raw SKILL.md: https://api.skillmd.com/api/skills/pina-org/define-equations/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: MIT
- Author: pina-org (https://skillmd.com/u/pina-org)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/pina-org/define-equations

---


# Define Equations for a PINA Problem

> [!IMPORTANT]
> Read [RULES.md](../RULES.md) before using this skill — it applies to all skills.
> This is a sub-skill of **create-problem**. Load the entry-point skill first.

Use this skill when the problem is **physics-driven** and you need to define
the governing equations and boundary conditions.

## Step 1 — Check the equation zoo

> What physical equations apply?

First check if the equation is available in the built-in zoo:

| Zoo class                     | Equation                         |
|-------------------------------|----------------------------------|
| `FixedValue(value)`           | `u - v = 0` (Dirichlet BC)       |
| `FixedGradient(value)`        | `∂u/∂n - v = 0` (Neumann BC)     |
| `FixedFlux(value)`            | `div(u) - v = 0` (flux BC)       |
| `FixedLaplacian(value)`       | `Δu - v = 0` (Laplacian BC)      |
| `PoissonEquation(forcing_f)`  | `Δu = f`                         |
| `BurgersEquation(nu)`         | `u_t + u u_x = ν u_xx`          |
| `AdvectionEquation(beta)`     | `u_t + β·∇u = 0`                |
| `AllenCahnEquation(ε, α)`     | `u_t = ε u_xx + α (u - u³)`     |
| `DiffusionReactionEquation(λ)`| `u_t = λ Δu + f`                |
| `HelmholtzEquation(k)`        | `Δu + k² u = f`                 |
| `AcousticWaveEquation(c)`     | `u_tt = c² Δu`                  |

If the equation matches one of these, use it directly.

## Step 2 — Unknown equation

If the equation is **not** in the zoo:

1. **Check** if the equation is present in `.opencode/skills/define-equations/famous_odes_pdes.json`,
   if not present **search the web** for the equation form, common PINN implementation, and known
   boundary/initial conditions.
2. Present the found formulation to the user and ask:
   > I found this equation: `<formulation>`. Should I use this or would you
   > like to provide your own?
3. If the user provides their own, use that instead.

## Step 3 — Define boundary conditions

> What boundary conditions apply? (Dirichlet, Neumann, Robin, periodic, etc.)

A well-posed PDE problem needs **both** the PDE and its boundary/initial
conditions. Common types:

- **Dirichlet**: `FixedValue(value)` — imposes `u = value` on the boundary
- **Neumann**: `FixedGradient(value)` — imposes `∂u/∂n = value`
- **Flux**: `FixedFlux(value)` — imposes `div(u) = value`
- **Laplacian**: `FixedLaplacian(value)` — imposes `Δu = value`

For zoo boundary conditions, use `components` and `d` parameters when the
problem has multiple output variables:

```python
FixedGradient(0.0, components=["theta"], d=["t"])
```

## Step 4 — Custom equation functions

Import the required utilities:

```python
from pina.operator import grad
from pina.equation import Equation
```

### Standard PDE (2 arguments)

```python
def my_pde(input_, output_):
    u_x = grad(output_, input_, components=["u"], d=["x"])
    u = output_.extract(["u"])
    return u_x - u
```

### Inverse problem (3 arguments)

When the problem is also an `InverseProblem`, the equation function receives a
third argument `params_` (a dict of unknown parameters):

```python
def my_pde_inverse(input_, output_, params_):
    f = torch.exp(-2 * (input_["x"] - params_["mu1"])**2)
    return laplacian(output_, input_, components=["u"], d=["x"]) - f
```

## Step 5 — Build conditions

Wrap equations in `Condition` objects. Return to the **condition-setup** or
**create-problem** skill for this step.

```python
from pina import Condition

conditions = {
    "interior": Condition(domain="D", equation=Equation(my_pde)),
    "dirichlet_bc": Condition(domain="boundary", equation=FixedValue(0.0)),
    "neumann_bc": Condition(domain="boundary", equation=FixedGradient(0.0)),
    "ic": Condition(domain="t0", equation=Equation(initial_cond)),
}
```

## Checklist

- [ ] Equation identified (zoo class or custom `Equation`)
- [ ] If equation was unknown: searched the web, presented the found
      formulation to the user, and confirmed before using
- [ ] Both the PDE and boundary/initial conditions are defined
- [ ] Custom equations use correct function signature:
      `(input_, output_)` for standard, `(input_, output_, params_)` for inverse
- [ ] Operator calls use `LabelTensor` with correct `components` and `d` parameter names

