Get started
Run a small model, then change it and see the difference. You need two files and a Python environment. Install the same source revision as this page so the parser and downloaded model agree; no mesh generator or editor extension is needed.
Install with uv
Section titled “Install with uv”These commands use Linux x86-64 and ordinary-GIL CPython 3.13.
Install Git, Rust stable with Cargo, and a C compiler/linker
before building the Python package from source. On Ubuntu, build-essential
provides the compiler and linker.
Install uv if you do not have it, then open a terminal in a new working folder:
mkdir first-eqiora-modelcd first-eqiora-modelgit init eqiora-sourcegit -C eqiora-source remote add origin https://github.com/nkiyohara/eqiora.gitgit -C eqiora-source fetch --depth 1 origin 9f45b2733cb46f3740aa3d31f99542411bad6c3fgit -C eqiora-source checkout --detach FETCH_HEADuv venv --python 3.13uv pip install --python .venv/bin/python --reinstall-package eqiora ./eqiora-sourceThe checked-out revision
owns both the installed package and the model shown below. Building takes longer
than installing a prebuilt wheel. Keep eqiora-source for the Reference examples.
Keep the following files in this folder, beside .venv. No shell activation is
needed: each run below explicitly selects that environment.
Predict the result
Section titled “Predict the result”Let a dimensionless quantity start at 1 and decay at rate :
The solution is . After one second, predict —about 37% of the initial value.
Save the model
Section titled “Save the model”Download decay.eqi, or copy
this complete source into a file named decay.eqi:
// A minimal implicit ODE: x decays at the rate supplied by the user.model decay() { // `x` is dimensionless and starts at 1. `rate` has inverse-time units. state x: 1; initial { x = 1; } parameter rate: 1 / s = 1;
// Eqiora writes the evolution law as a residual equal to zero. relation flow { derivative(x) + rate * x = 0; }}The .eqi file describes the model. state x declares the evolving unknown and initial { x = 1; } sets its initial condition,
parameter rate has inverse-second units, and the relation states an equation
with two ordered sides of an equality. The numerical method does not belong in this file.
Save the run script
Section titled “Save the run script”Download run.py, or copy this
complete script into run.py in the same folder:
"""Run the decay model shared by Get started and the ODE lesson."""
from __future__ import annotations
import argparsefrom pathlib import Path
import eqiora
OUTPUT_TIMES_S = (0.25, 0.5, 1.0)
def solve(source_path: Path) -> tuple[tuple[float, float], ...]: """Return the requested (time in seconds, dimensionless value) samples."""
model = eqiora.compile(path=source_path) field = model.field(model.field_ids[0]) plan = eqiora.resolve( model, temporal=eqiora.time.Tsitouras45( initial_step_s=0.01, relative_tolerance=1.0e-9, absolute_tolerances={field: 1.0e-11}, ), ) result = eqiora.run( plan, state=eqiora.State.initial(plan), until_s=OUTPUT_TIMES_S[-1], output_times_s=OUTPUT_TIMES_S, ) series = result.series(field) times = series.time.numpy() values = series.values.numpy() return tuple( (float(time_s), float(value)) for time_s, value in zip(times, values, strict=True) )
def main() -> None: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("model", nargs="?", type=Path, default=Path("decay.eqi")) args = parser.parse_args() for time_s, value in solve(args.model): print(f"t={time_s:.2f}, x={value:.10f}")
if __name__ == "__main__": main()The script compiles decay.eqi, chooses an adaptive time method, starts from the
model’s initial state and requests three observations. The returned Result
contains a time series selected by the model’s field handle. The two NumPy arrays
hold times in seconds and the corresponding dimensionless values.
Run and inspect
Section titled “Run and inspect”uv run --no-project --python .venv/bin/python python run.pyYou should see values close to:
t=0.25, x=0.7788007829t=0.50, x=0.6065306597t=1.00, x=0.3678794412The last line agrees with the hand prediction. The result is printed in the terminal; this small script does not create a plot or save a result file.
Change the model
Section titled “Change the model”In decay.eqi, change just the rate declaration to:
parameter rate: 1 / s = 2;Before rerunning, predict : doubling the rate makes
the quantity decay faster. Run the same command and script again. Its last
line should now be close to t=1.00, x=0.1353352833.
You changed the model, not the time method. Restore rate to 1 when following
the ODE lesson.
If something goes wrong
Section titled “If something goes wrong”uv: command not found: install uv using its linked instructions, reopen the terminal and checkuv --version.- Source build fails: check
cargo --versionandcc --version, then repeat the uv install command. Use CPython 3.13 and the checked-out source revision. - Wrong Python or missing
eqiora: runuv run --no-project --python .venv/bin/python python -c "import eqiora; print(eqiora.__version__)". A version number alone does not identify a source build. Checkgit -C eqiora-source rev-parse HEADagainst the revision in the install command, then reinstall from that checkout. Use the same folder and environment for each run. - Model file not found: keep
decay.eqibesiderun.pyand run from their folder, or pass its path:python run.py path/to/decay.eqiinside the selected environment. - A source diagnostic: misspelling
rateasmissing_ratein the relation producesEQ0603: unresolved expression symbol. Correct the name to match the declaration. Changing the rate’s unit tominstead produces an addition/subtraction dimension mismatch: the two terms must both have inverse-time units.
Where next?
Section titled “Where next?”- Learn: derive this ODE and try the exercises.
- Guides: run a model and inspect its result with the same installed source build.
- Gallery: explore complete simulation investigations.
- Reference: look up the public interfaces.
Capabilities describes which problem classes and numerical methods are available when you move beyond this example.