Metadata-Version: 2.4
Name: vcti-derived
Version: 2.0.0
Summary: An extensible, catalog-driven library for computing derived fields from multi-component engineering data arrays
Author: Visual Collaboration Technologies Inc.
License-Expression: LicenseRef-Proprietary
Project-URL: Repository, https://github.com/vcollab/vcti-python-derived
Project-URL: Changelog, https://github.com/vcollab/vcti-python-derived/blob/main/CHANGELOG.md
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Python: <3.15,>=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=2.3
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Requires-Dist: pytest-cov; extra == "test"
Provides-Extra: lint
Requires-Dist: ruff; extra == "lint"
Provides-Extra: typecheck
Requires-Dist: mypy; extra == "typecheck"
Dynamic: license-file

# Derived Fields

An extensible, catalog-driven library for computing derived fields from multi-component engineering data arrays

## Overview

`vcti.derived` turns multi-component engineering result arrays — vectors,
6-DOF, symmetric stress/strain tensors — into derived fields such as
magnitude, von Mises, principal values and directions, and traction vectors.
It is pure numpy: plain arrays in, plain arrays out, with output dtype
following the input. Two faces sit over one implementation — bulk-first
**kernels** you call directly, and a **catalog** that enumerates which derived
fields exist per data family (with stable ids, display names, and parameters)
for driving menus and pipelines. Component order is handled explicitly, so
data from any solver (Abaqus, Nastran, Ansys, LS-Dyna) computes correctly
without reshuffling.

## Installation

```bash
pip install vcti-derived
```

### In `requirements.txt`

```
vcti-derived>=2.0.0
```

### In `pyproject.toml` dependencies

```toml
dependencies = [
    "vcti-derived>=2.0.0",
]
```

---

## Quick Start

```python
import numpy as np
from vcti.derived import ComponentOrder, DataFamily, catalogs, symtensor

stress = np.array([[100.0, 20.0, 5.0, 15.0, 0.0, 0.0]])  # (N, 6): xx yy zz xy yz xz

# Kernels directly:
vm = symtensor.von_mises(stress)                 # (N,) von Mises stress
s1 = symtensor.principals(stress)[:, -1]         # (N,) max principal

# Data from a solver with a different component order (zero-copy):
vm = symtensor.von_mises(stress, order=ComponentOrder.ABAQUS)

# Or through the catalogs (organized by output kind):
entry = catalogs.get("symtensor3d.von_mises")
vm = entry.compute(stress)
for entry in catalogs.scalar.by_family(DataFamily.SYMTENSOR3D):  # scalar-producing
    print(entry.id, entry.display_name)
```

---

## Dependencies

[numpy](https://numpy.org) only.

---

## Documentation

| If you want to… | Read |
|---|---|
| Understand the architecture and design decisions | [docs/design.md](docs/design.md) |
| Navigate and understand the source | [docs/source-guide.md](docs/source-guide.md) |
| See practical, real-world usage | [docs/patterns.md](docs/patterns.md) |
| Extend the library | [docs/extending.md](docs/extending.md) |
