Metadata-Version: 2.4
Name: fem-core
Version: 0.1.16
Summary: NGSolve/Netgen FEM model-building core — headless, no PySide6
Home-page: https://github.com/gcmartins/fem-core
License-Expression: LicenseRef-Proprietary
Keywords: fem,fea,ngsolve,netgen,finite-element,simulation
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: Microsoft :: Windows
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Requires-Dist: h5py>=3.10
Requires-Dist: ngsolve>=6.2.2404
Requires-Dist: numpy>=1.24.0
Requires-Dist: scipy>=1.11.0
Provides-Extra: viz
Requires-Dist: fem-post; extra == "viz"
Provides-Extra: pardiso
Requires-Dist: mkl; ((sys_platform == "linux" and platform_machine == "x86_64") or (sys_platform == "win32" and platform_machine == "AMD64")) and extra == "pardiso"
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: keywords
Dynamic: license-file
Dynamic: license-expression
Dynamic: provides-extra
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# FEM Core

NGSolve/Netgen finite-element model-building core — no PySide6 or Qt dependency. Runs
headlessly (no display required).

![Python Version](https://img.shields.io/badge/python-3.12+-blue.svg)
![License](https://img.shields.io/badge/license-proprietary-lightgrey.svg)

## Features

- 🧱 **Layered FEM pipeline** — mesh → function space → weak-form assembly, each stage a swappable service
- 🧩 **Typed, serializable models** — `FemModel`, `FemFormulation`, `BoundaryCondition`, ... with `to_dict()`/`from_dict()`
- 🌊 **Physics formulations** — linear elasticity, (complex) Helmholtz, Reissner-Mindlin plates, Naghdi shells, and `CUSTOM` symbolic weak forms
- 🎯 **Domain facades** — `AcousticModel`, `PlateModel`, `ShellModel` builders in physics vocabulary
- 🧮 **Studies** — static, modal and frequency-sweep analyses through one `StudyManager`
- 📐 **Stress** — stresses, membrane forces, moments and shear forces as CoefficientFunctions
- 🗂️ **Geometry import** — STEP/IGES/BREP with deterministic, geometry-sorted region indices
- 💾 **Results and projects** — HDF5 result files and shared `FemProject` documents, with the `fem-core-run` / `fem-core-view` CLIs
- 🔒 **Safe expressions** — boundary and custom-form expressions parsed by a restricted AST walker, never `eval()`
- 🧪 **Dependency-injectable services** — every service behind a `Protocol`, so tests can mock NGSolve/Netgen
- 📊 **Visualization** — VTK post-processing (`.vtu`, `.png`, interactive) via the companion package [fem-post](https://github.com/gcmartins/fem-core/blob/main/packages/fem-post/README.md)

## Scope

`fem-core` builds the mesh, function space and forms, and solves them with static, modal or
frequency-sweep studies. Transient (time-stepping) analysis is out of scope for now.

## Installation

```bash
pip install fem-core            # from PyPI
pip install "fem-core[viz]"     # plus fem-post (VTK post-processing)
pip install "fem-core[pardiso]" # plus MKL, for the PARDISO solver (x86-64 Linux/Windows)
```

fem-core is proprietary software (see License below). The optional `pardiso` extra installs
Intel's MKL (with `tbb` and `intel-openmp`), which is governed by Intel's own licences, not
fem-core's; fem-core works without it.

For development, from the repo root:

```bash
uv sync
source .venv/bin/activate
```

## Quick Start

```python
from netgen.occ import Box, OCCGeometry, Pnt

from fem_core.enums import BoundaryConditionType, FemDimension, FormulationType, FunctionSpaceType, StudyType
from fem_core.managers.fem_model_manager import FemModelManager
from fem_core.managers.study_manager import StudyManager
from fem_core.models.boundary_condition import BoundaryCondition
from fem_core.models.fem_formulation import FemFormulation
from fem_core.models.fem_model import FemModel
from fem_core.models.formulation_parameters import LinearElasticityParameters
from fem_core.models.function_space_config import FunctionSpaceConfig
from fem_core.models.mesh_config import MeshConfig
from fem_core.models.study import Study
from fem_core.models.study_parameters import ModalStudyParameters, StaticStudyParameters

geo = OCCGeometry(Box(Pnt(0, 0, 0), Pnt(100, 20, 10)))

model = FemModel(
    name="Bracket",
    dimension=FemDimension.DIM_3D,
    formulation=FemFormulation(
        formulation_type=FormulationType.LINEAR_ELASTICITY,
        parameters=LinearElasticityParameters(E=210e9, nu=0.3, body_force_y=-9.81),
    ),
    function_space=FunctionSpaceConfig(space_type=FunctionSpaceType.VECTOR_H1, order=2),
    mesh_config=MeshConfig(maxh=5.0),
    boundary_conditions=[BoundaryCondition(bc_type=BoundaryConditionType.DIRICHLET, region="fixed_face")],
)

manager = FemModelManager()
managed = manager.build_model(model, geo=geo.shape)  # mesh -> function space -> forms

studies = StudyManager(manager)
static = studies.create_study(managed.model_id, Study(parameters=StaticStudyParameters()))
studies.run_study(static.study_id)
static.result.gridfunction

modal = studies.create_study(
    managed.model_id, Study(study_type=StudyType.MODAL, parameters=ModalStudyParameters(num_modes=6))
)
studies.run_study(modal.study_id)
modal.result.eigenvalues  # omega^2, ascending
```

Facades build the same `FemModel` from domain vocabulary:

```python
from fem_core.facades.acoustic_model import AcousticModel

fem_model = (
    AcousticModel(name="Cabin Acoustics", speed_of_sound=343.0, density=1.225)
    .add_sound_hard_wall("rigid_walls")
    .add_impedance_boundary("absorber_panel", impedance=415.0 + 50.0j)
    .to_fem_model()
)
```

Saved projects and results can be solved or viewed from the command line:

```bash
fem-core-run beam.cadw
fem-core-view beam.results.h5 --study Modes --png modes.png
```

## Documentation

- [User Guide](https://github.com/gcmartins/fem-core/blob/main/docs/user-guide.md) — studies, undo/redo,
  result storage, projects, geometry import, 2D/shell/plate models, stress, subdomains, visualization
- [Architecture](https://github.com/gcmartins/fem-core/blob/main/docs/architecture.md) — layers,
  services, managers, facades and key design decisions
- [Development](https://github.com/gcmartins/fem-core/blob/main/docs/development.md) — testing and releasing
- [fem-post](https://github.com/gcmartins/fem-core/blob/main/packages/fem-post/README.md) — VTK post-processing
- [Examples](https://github.com/gcmartins/fem-core/tree/main/examples) and
  [validations](https://github.com/gcmartins/fem-core/tree/main/validations)

## License

Proprietary — see [LICENSE](https://github.com/gcmartins/fem-core/blob/main/LICENSE). Third-party
libraries keep their own licences, listed in [NOTICE](https://github.com/gcmartins/fem-core/blob/main/NOTICE).
