Metadata-Version: 2.4
Name: tapis
Version: 0.0.1
Summary: Span an arbitrary loop in space with its surface (the Plateau problem).
Author-email: jac0bandres <jacob@jacobandres.com>
License: MIT
Project-URL: Homepage, https://github.com/jac0bandres/tapis
Project-URL: Repository, https://github.com/jac0bandres/tapis
Keywords: minimal surfaces,plateau problem,differential geometry,computational geometry,mesh
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Mathematics
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: numpy>=1.24
Requires-Dist: scipy>=1.10
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Provides-Extra: plot
Requires-Dist: matplotlib>=3.6; extra == "plot"
Requires-Dist: pyvista>=0.44; extra == "plot"

# tapis

**Span an arbitrary loop in space with its surface.**

`tapis` is a small, focused library for the *Plateau problem*: given a closed
loop Γ ⊂ ℝ³, find a surface that spans it. It implements the full ladder of
methods — from closed-form to variational — behind one API, and scores each
against exact answers. Design values, in order: **generality, simplicity, closed
form.** See [RESEARCH.md](RESEARCH.md) for the method ladder and open directions.

## Install

```bash
pip install -e ".[dev]"    # numpy + scipy; pytest for the suite
```

## Use

One primitive: a loop goes in, a `Surface` comes out, and the surface knows how to
report on itself.

```python
import tapis
from tapis import corpus

# an exact minimal surface hands us a loop whose true spanner we know
scherk = corpus.scherk()
loop   = scherk.loop                     # (N, 3) closed polyline

surf = tapis.solve(loop, method="harmonic")   # rung 0: the harmonic graph
surf.eval(0.5, 0.5)        # points on the surface at parameters (u, v) in [0,1]
surf.area()                # spanning area
surf.certify_minimal()     # dimensionless mean-curvature residual (~0 = minimal)
surf.boundary_error()      # deviation from Γ on the boundary (~0 for rung 0)
surf.kind                  # "harmonic_graph" (linearized) vs "minimal"
```

`tapis.methods()` lists registered solvers. The `corpus` module supplies exact
minimal surfaces (catenoid, helicoid, Enneper, Scherk, and a general Weierstrass
`(f, g)` integrator) as the validation ground truth.

## The distinction that never blurs

- **Harmonic graph** (`kind="harmonic_graph"`) minimizes Dirichlet energy — the
  *small-slope approximation* to a minimal surface. Exact on the boundary,
  linear, bounded by the maximum principle. Its mean curvature is **not** zero.
- **Minimal surface** (`kind="minimal"`) minimizes *area*; mean curvature ≡ 0.

The two agree to first order and diverge as the loop steepens. Rung 0 computes the
first; every higher rung computes the second.

## Status

Scaffolded: unified API, rung 0 (harmonic graph), rung 2 (Weierstrass corpus), one
validation harness. Rung 1 (Douglas–Radó) is next. See [RESEARCH.md](RESEARCH.md).

```bash
python -m pytest        # 22 tests
```

