# Hertzon runs from its source tree: the GUI starts solver processes with
# PYTHONPATH set to the tree, and the warm-up, optimizer, MCP and help code
# find examples/ and docs/ next to the package (Path(__file__).parents[2]).
# Install the tree as a private application directory, as upstream's own
# Linux installer does, with the hzmesh library built from source.
%global appdir %{_libdir}/%{name}
Name: hertzon
Version: 0.1.16
Release: 1%{?dist}
Summary: 3D full-wave electromagnetic FEM simulator with adaptive meshing
# hertzon: GPL-2.0-or-later
# hertzon/mesher/src/predicates.c (Shewchuk's robust predicates): LicenseRef-Fedora-Public-Domain
License: GPL-2.0-or-later AND LicenseRef-Fedora-Public-Domain
URL: https://github.com/c8501024/Hertzon
Source0: %{url}/archive/v%{version}/Hertzon-%{version}.tar.gz
# Use the distribution's mmg3d (package mmg3d) when pymmg is not installed.
Patch0: hertzon-system-mmg3d.patch
ExclusiveArch: x86_64 aarch64
BuildRequires: gcc
BuildRequires: gcc-c++
BuildRequires: python3-devel
BuildRequires: desktop-file-utils
BuildRequires: libappstream-glib
# %%check: unit tests and the system-mmg3d lookup
BuildRequires: python3dist(pytest)
BuildRequires: python3dist(numpy)
BuildRequires: python3dist(scipy)
BuildRequires: python3dist(matplotlib)
BuildRequires: python3dist(gmsh)
BuildRequires: python3dist(numba)
BuildRequires: python3dist(emerge) = 2.8.9
BuildRequires: python3dist(pyside6)
BuildRequires: python3dist(pyvista)
BuildRequires: python3dist(pyvistaqt)
BuildRequires: python3dist(fast-simplification)
BuildRequires: python3dist(hfsynpy)
BuildRequires: mmg3d
Requires: python3
# pyproject.toml pins emerge==2.8.9
Requires: python3dist(emerge) = 2.8.9
Requires: python3dist(pyside6)
Requires: python3dist(pyvista)
Requires: python3dist(pyvistaqt)
Requires: python3dist(matplotlib)
Requires: python3dist(numpy)
Requires: python3dist(scipy)
Requires: python3dist(numba)
Requires: python3dist(gmsh)
Requires: python3dist(fast-simplification)
Requires: python3dist(hfsynpy)
# "Mmg" adaptive refinement runs the mmg3d executable
Requires: mmg3d
Requires: hicolor-icon-theme
Requires: shared-mime-info
Provides: bundled(robust-predicates)
%description
Hertzon is a desktop 3D full-wave electromagnetic simulator with a classic
engineering workflow: draw the model (or import STEP/STL), assign boundaries
(perfect E/H, finite conductivity, impedance, lumped RLC, radiation, PML,
symmetry) and excitations (wave, lumped and Floquet ports), add an analysis
setup with adaptive meshing and frequency sweeps, solve, then inspect
S-parameters, fields, radiation patterns and RCS. Modal, terminal and
eigenmode solutions are supported, with parametric sweeps, optimization and
filter and antenna design tools.
The finite-element solver underneath is EMerge (2nd-order Nedelec
elements). Hertzon adds the Qt/VTK interface, its own hzmesh mesher, local
Delaunay, bisection and Mmg adaptive refinement, an error estimator, fast
sweeps, curved elements, far-field and RCS post-processing, and an MCP
server (hertzon-mcp) through which AI assistants can build and run models.
%prep
%autosetup -n Hertzon-%{version} -p1
# Prebuilt Windows launcher, Windows DLL and Linux library: rebuilt or unused.
rm -f Hertzon.exe packaging/Hertzon.exe packaging/launcher.res
rm -f hertzon/mesher/_bin/hzmesh.dll hertzon/mesher/_bin/libhzmesh.so
%build
# hertzon/mesher/src/build.sh, with Fedora's flags and a soname-less private library
pushd hertzon/mesher/src
gcc %{optflags} -fPIC -ffp-contract=off -c predicates.c -o predicates.o
g++ %{optflags} -std=c++17 -fPIC -ffp-contract=off -c hzmesh.cpp -o hzmesh.o
g++ %{build_ldflags} -shared -o ../_bin/libhzmesh.so hzmesh.o predicates.o
rm -f predicates.o hzmesh.o
popd
%install
install -d %{buildroot}%{appdir}
cp -pr hertzon examples docs %{buildroot}%{appdir}/
rm -rf %{buildroot}%{appdir}/hertzon/mesher/src
find %{buildroot}%{appdir} -name '__pycache__' -prune -exec rm -rf {} +
chmod 0755 %{buildroot}%{appdir}/hertzon/mesher/_bin/libhzmesh.so
%py_byte_compile %{python3} %{buildroot}%{appdir}/hertzon
install -d %{buildroot}%{_bindir}
cat > %{buildroot}%{_bindir}/hertzon <<'EOF'
#!/bin/sh
export PYTHONPATH=%{appdir}${PYTHONPATH:+:$PYTHONPATH}
exec %{python3} -m hertzon "$@"
EOF
cat > %{buildroot}%{_bindir}/hertzon-mcp <<'EOF'
#!/bin/sh
export PYTHONPATH=%{appdir}${PYTHONPATH:+:$PYTHONPATH}
exec %{python3} -m hertzon.mcp "$@"
EOF
chmod 0755 %{buildroot}%{_bindir}/hertzon %{buildroot}%{_bindir}/hertzon-mcp
# Desktop entry, icon and .hzn MIME type, as packaging/linux/install.sh writes them
install -Dpm 0644 hertzon/gui/hertzon.png \
%{buildroot}%{_datadir}/icons/hicolor/256x256/apps/hertzon.png
install -d %{buildroot}%{_datadir}/applications
cat > %{buildroot}%{_datadir}/applications/hertzon.desktop <<'EOF'
[Desktop Entry]
Type=Application
Name=Hertzon
GenericName=3D Full-Wave FEM Solver
Comment=3D full-wave electromagnetic FEM simulation
Exec=hertzon %f
Icon=hertzon
Terminal=false
Categories=Science;Engineering;Physics;
MimeType=application/x-hertzon-project;
StartupWMClass=Hertzon
EOF
install -d %{buildroot}%{_datadir}/mime/packages
cat > %{buildroot}%{_datadir}/mime/packages/hertzon.xml <<'EOF'
Hertzon project
EOF
%check
desktop-file-validate %{buildroot}%{_datadir}/applications/hertzon.desktop
export PYTHONPATH=%{buildroot}%{appdir} QT_QPA_PLATFORM=offscreen MPLBACKEND=Agg
export NUMBA_CACHE_DIR=$PWD/numba-cache HOME=$PWD/home
mkdir -p $HOME
# The installed tree: hzmesh loads, Mmg refinement finds the system mmg3d,
# the package version matches and the launcher's module imports.
%{python3} - <<'PYEOF'
import hertzon
assert hertzon.__version__ == "%{version}", hertzon.__version__
from hertzon.mesher import core
core.lib()
from hertzon.solver.mmg_refine import mmg_binary, available
assert str(mmg_binary()) == "/usr/bin/mmg3d_O3", mmg_binary()
assert available()
import hertzon.gui.app, hertzon.mcp.__main__
print("hertzon tree ok")
PYEOF
# Upstream's fast tests (no FEM solve). The others solve full models and
# take far longer than a build should.
%pytest -v tests/test_core.py tests/test_mcp.py tests/test_facetrack.py
%files
%license LICENSE
%doc README.md CITATION.cff
%{_bindir}/hertzon
%{_bindir}/hertzon-mcp
%{appdir}/
%{_datadir}/applications/hertzon.desktop
%{_datadir}/icons/hicolor/256x256/apps/hertzon.png
%{_datadir}/mime/packages/hertzon.xml
%changelog
* Wed Oct 21 2026 Morgan Hough - 0.1.16-1
- Initial package.