Metadata-Version: 2.4
Name: ansh
Version: 0.1.1
Summary: A python package to define scalar and vector finite-element fields.
Project-URL: Documentation, https://codeberg.org/Sankhya/Ansh/-/blob/main/README.md
Project-URL: Issues, https://codeberg.org/Sankhya/Ansh/-/issues
Project-URL: Source, https://codeberg.org/Sankhya/Ansh
Author-email: Swapneel Amit Pathak <swapneelap@gmail.com>
License-Expression: MIT
License-File: LICENSE.txt
Classifier: Development Status :: 4 - Beta
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: Implementation :: CPython
Requires-Python: >=3.11
Requires-Dist: beartype>=0.22.4
Requires-Dist: h5py>=3.16.0
Requires-Dist: jinja2>=3.1.6
Requires-Dist: pyvista[all]>=0.46.3
Requires-Dist: scikit-fem>=12
Description-Content-Type: text/markdown

# Ansh

[![PyPI - Version](https://img.shields.io/pypi/v/ansh.svg)](https://pypi.org/project/ansh)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/ansh.svg)](https://pypi.org/project/ansh)

Numerical approximation of finite-element scalar and vector fields in Python.

`ansh` is a thin wrapper around [`meshio`](https://github.com/nschloe/meshio), [`pyvista`](https://pyvista.org/), and [`skfem`](https://github.com/kinnala/scikit-fem). `meshio` is used for reading and writing meshes. `skfem` is used for finite-element field definition. `pyvista` is used for plotting both meshes and fields.

-----

## Table of Contents

- [Installation](#installation)
- [Quick Start](#quick-start)
  - [Meshes](#meshes)
  - [Scalar fields](#scalar-fields)
  - [Vector fields](#vector-fields)
- [I/O](#io)
- [License](#license)

## Installation

```console
pip install ansh
```

## Quick Start

### Meshes

Load a mesh from file and inspect its properties:

```python
import ansh
import numpy as np

m = ansh.Mesh.from_file("tests/meshes/med/omega.med")
m.info = {"name": "shell", "about": "one of the unit test meshes"}
```

```python
m.points          # float64 array of shape (n_points, 3)
m.cells           # list of CellBlock objects (type + connectivity)
m.cell_centres    # list of cell centre arrays per cell block
m.subregions      # dict mapping region names to cell index arrays
m.scale           # mesh scaling factor
m.info            # user-attached metadata dict
```

**Subregions** can be added via cell indices or selector functions:

```python
def select_unit_cube(centres):
    return (
        ((centres[:, 0] < 1.) & (centres[:, 0] > -1.)) &
        ((centres[:, 1] < 1.) & (centres[:, 1] > -1.)) &
        ((centres[:, 2] < 1.) & (centres[:, 2] > -1.))
    )

m.add_subregion(
    subregion_name="cube",
    value=[np.array([], dtype=np.int_), select_unit_cube, np.array([], dtype=np.int_)],
)
```

Convert to PyVista or scikit-fem for further use:

```python
m.to_pyvista()        # returns pyvista.MultiBlock with one block per subregion
m.to_meshio()         # returns meshio.Mesh
m.to_skfem()          # returns skfem MeshTet1
m.plot()              # interactive 3D plot via PyVista
```

> See the [full mesh demo](docs/mesh-demo.ipynb) for more details.

### Scalar fields

Define a scalar field on a mesh by specifying the element type and initial value:

```python
f = ansh.ScalarField(mesh=m, element_type=ansh.element_types.TetP1(), value=42.)
```

```python
f.element_type     # skfem element (e.g. ElementTetP1)
f.value            # 1D float64 array of DOF values, shape (n_dofs,)
f.dof_locations    # coordinates of the DOF points, shape (n_dofs, 3)
```

The field is callable — evaluate it at arbitrary points inside the mesh:

```python
f([0, 0, 0])                              # array([42.])
f(np.array([[0, 2., -1.], [0, 0, 0]]))   # array([42., 42.])
```

Update the value with a callable (receives DOF locations, returns values):

```python
def norm_val(dofs):
    return np.linalg.norm(dofs, axis=-1)

f.value = norm_val
```

Set values on a specific subregion:

```python
f.set_subregion_value(name="boundary", input_value=0.)
```

Export for matrix assembly or visualisation:

```python
f.to_skfem()       # returns skfem DiscreteField
f.skfem_basis      # returns skfem CellBasis
f.to_pyvista()     # returns pyvista MultiBlock with field data attached
f.plot()           # interactive 3D plot with a clip widget
```

> See the [full scalar field demo](docs/scalar-field-demo.ipynb) for more details.

### Vector fields

Define a vector field similarly, passing a 3-component value:

```python
f = ansh.VectorField(
    mesh=m,
    element_type=ansh.element_types.TetP1(),
    value=[42., 42., 42.],
)
```

```python
f.element_type     # skfem ElementVector (wrapping ElementTetP1)
f.value            # 2D float64 array of DOF values, shape (n_dofs, 3)
f.dof_locations    # coordinates of the DOF points, shape (n_dofs, 3)
```

Evaluate at arbitrary points:

```python
f([0, 0, 0])                              # array([[42., 42., 42.]])
f(np.array([[0, 2., -1.], [0, 0, 0]]))   # array([[42., 42., 42.], ...])
```

Set value via callable (receives DOF locations, returns array of shape `(n_dofs, 3)`):

```python
f.value = lambda dofs: dofs
```

Set subregion values:

```python
f.set_subregion_value(name="shell", input_value=[0., 0., 0.])
```

Plot with glyphs coloured by component or magnitude:

```python
f.plot(colour_with="z", factor=3e-3, cmap="RdBu")
f.plot(colour_with="magnitude", factor=3e-3, cmap="viridis")
```

> See the [full vector field demo](docs/vector-field-demo.ipynb) for more details.

## I/O

**Mesh** — read any format supported by `meshio` (`.med`, `.vol`, `.vtk`, `.msh`, etc.)
and write to Abaqus `.inp` or Ansh HDF5 `.h5`:

```python
m.to_file("mesh.inp")
m.to_file("mesh.h5")
ansh.Mesh.from_file("mesh.inp")
ansh.Mesh.from_file("mesh.h5")
```

**Scalar/vector field** — read/write HDF5 (`.h5`) or ParaView multiblock (`.vtm`):

```python
f.to_file("field.h5")
f.to_file("field.vtm")
ansh.ScalarField.from_file("field.h5")
ansh.VectorField.from_file("field.h5")
```

## License

`ansh` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.
