Metadata-Version: 2.4
Name: ansh
Version: 0.2.0
Summary: A python package to define scalar and vector finite-element fields.
Project-URL: Documentation, https://sankhya.codeberg.page/AnshPustak
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
Keywords: fem,finite-element,finite-element-method,scalar-field,unstructured-mesh,vector-field
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
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
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Scientific/Engineering :: Mathematics
Classifier: Topic :: Scientific/Engineering :: Physics
Classifier: Topic :: Scientific/Engineering :: Visualization
Requires-Python: >=3.11
Requires-Dist: beartype>=0.22.4
Requires-Dist: h5py>=3.16
Requires-Dist: jinja2>=3.1.6
Requires-Dist: numpy<2.5
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)

**Ansh (अंश)**, which means *a part* or *an element*, is a Python library to define numerical approximation of scalar and vector fields ideal for finite-element analysis. It 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)
- [Developers](#developers)
- [License](#license)

## Installation

```console
pip install ansh       # pip
uv add ansh            # uv
pixi add --pypi ansh   # pixi
```

## 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.))
    )

# value has one entry per cell block. So no cells from block 0 and 2.
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", 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", 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.

> An advanced example combining meshes with scalar and vector fields is available in the [demagnetisation truncation notebook](docs/demag-truncation.ipynb).

## 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")
```

## Developers

Set up a development environment with [Pixi](https://pixi.prefix.dev/latest/):

```console
git clone https://codeberg.org/Sankhya/Ansh.git
cd Ansh
pixi install
pixi shell -e dev   # activates the environment
```

Run tests with pytest:

```console
pixi run pytest
```

Lint the source with Ruff:

```console
pixi run ruff check src/ansh/
```

Build the package with Hatchling:

```console
pixi run hatch build -t wheel
```

Publish to PyPI:

```console
pixi run hatch publish
```

Explore the Jupyter notebooks for ad-hoc testing and demos:

```console
pixi run jupyter lab docs/
```

**Key conventions:**
- Source lives under `src/ansh/` (src layout).
- Public API is exported from `src/ansh/__init__.py` — symbols: `Mesh`, `CellBlock`, `ScalarField`, `VectorField`, `element_types`.
- Runtime type validation is enforced by `beartype` decorators wherever it makes sense.
- Docstrings follow Google style (Args/Returns/Raises/Notes).
- HDF5 I/O uses the `.h5` extension.
- The remote is on [Codeberg](https://codeberg.org/Sankhya/Ansh).

## License

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