Metadata-Version: 2.4
Name: fatcuda
Version: 0.1.1
Summary: Optical Tweezers Force Engine — Python port of the OTS toolbox (Phase 1: Mie sphere, non-paraxial focused-beam force)
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: numpy
Requires-Dist: scipy
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Requires-Dist: matplotlib; extra == "test"
Provides-Extra: demo
Requires-Dist: matplotlib; extra == "demo"
Provides-Extra: cuda12
Requires-Dist: cupy-cuda12x<14.0,>=13.3; extra == "cuda12"
Provides-Extra: metal
Requires-Dist: mlx<0.32,>=0.31; extra == "metal"

# fatcuda

`fatcuda` is an intent-first optical tweezers force and field engine. It starts
from physical declarations - beam intent, optical system, particle or task, and
device policy - then lowers them into auditable intermediate representations and
verified CPU/CUDA/Metal execution paths.

The current production package lives in `fatcuda/`. The historical direct-port
implementation is archived in `fatcuda_old/` and is kept only as an oracle,
comparison source, and history bundle.

## Status

This project is still early. The current verified path focuses on homogeneous
Mie spheres, non-paraxial Debye-Wolf focusing, multipole coefficients, field
slices, force maps, and CPU/Metal/CUDA interface parity. APIs may still move
while the package is prepared for a first public PyPI release.

## Installation

After publication:

```bash
python -m pip install fatcuda
python -m pip install "fatcuda[metal]"   # Apple Silicon / MLX path
python -m pip install "fatcuda[cuda12]"  # CUDA 12 / CuPy path
```

For local development from this checkout:

```bash
python -m pip install -e ".[test,demo]"
python -m pip install -e ".[test,demo,metal]"
python -m pip install -e ".[test,demo,cuda12]"
```

The default portable execution path is CPU-only and depends on NumPy and SciPy.

## Minimal Example

```python
import numpy as np

from fatcuda import (
    ForceAtPositions,
    GaussianBeam,
    OpticalSystem,
    PupilGrid,
    Sphere,
    solve,
)

system = OpticalSystem(grid=PupilGrid(Nphi=32, Nr=16), power=1.0e-3)
beam = GaussianBeam(Ex0=1.0, Ey0=0.0)
sphere = Sphere(radius=0.2e-6, n_p=1.59, L=8)
task = ForceAtPositions(
    positions=np.array(
        [
            [0.0, 0.0, 0.0],
            [0.1e-6, 0.0, 0.0],
        ]
    ),
    particle=sphere,
)

result = solve(
    beam=beam,
    system=system,
    task=task,
    strategy="auto",
    device="cpu",
)

print(result.force)
print(result.torque)
print(result.audit.operator_plan)
```

## Public API Shape

The recommended user flow is:

```text
beam intent + optical system + particle/task + device/strategy -> auditable IR -> kernels
```

Common public declarations include:

| Concept | Examples |
|---|---|
| Beams | `GaussianBeam`, `LaguerreGaussBeam`, `HermiteGaussBeam`, `AiryBeam`, `VortexBeam`, `SLMPhaseBeam` |
| System | `OpticalSystem`, `PupilGrid` |
| Particles | `Sphere` |
| Tasks | `ForceAtPositions`, `FieldSlice` |
| Execution | `solve`, `compile_problem`, `DevicePolicy`, `OperatorStrategy`, `PrecisionPolicy` |

## Verification

The repository uses MATLAB OTS fixtures, the current CPU NumPy path, and
closed-form physics sanity checks as oracles. Typical local verification:

```bash
python -m pytest -q -p no:cacheprovider
```

CUDA numerical validation requires a CUDA machine. On macOS without CUDA, CUDA
tests are limited to import, collection, skip behavior, and shared-interface
non-breakage. Metal validation requires Apple Silicon with the `metal` extra
installed and MLX reporting Metal availability.

## Documentation

- [Documentation index](doc/index.md)
- [Quickstart](doc/project/quickstart.md)
- [Structure review](CODEX_PONYTAIL_STRUCTURE_REVIEW.md)
- [Structure execution plan](CODEX_FATCUDA_STRUCTURE_EXECUTION_PLAN.md)

The detailed code-layer notes live under `doc/obsidian/fatcuda/代码层/`.
