%global srcname dolfinx %global upver 0.11.0.post0 %global sover 0.11 # DOLFINx compiles heavily templated C++; an LTO link of those objects is the # peak memory consumer and can spike to several GB in a single process. Disable # LTO so this builds on memory-constrained machines. %global _lto_cflags %{nil} # Cap parallelism by available memory (~4GB per job) instead of one job per # core. %%limit_build emits the -jN flag, so it is substituted here rather than # invoked as a standalone command. %global _smp_mflags %{limit_build -m 4096} # Fedora's MPI packaging conventions: build one flavour per MPI implementation # into %%{_libdir}/. Only openmpi is built here; add mpich by duplicating # the build/install/files blocks with the %%{_mpich_*} macros. Name: fenics-dolfinx Version: 0.11.0 Release: %autorelease Summary: Next-generation FEniCS problem solving environment License: LGPL-3.0-or-later URL: https://github.com/FEniCS/dolfinx Source: %{url}/archive/v%{upver}/%{srcname}-%{upver}.tar.gz BuildRequires: cmake >= 3.21 BuildRequires: gcc-c++ BuildRequires: boost-devel >= 1.70 BuildRequires: pugixml-devel BuildRequires: spdlog-devel BuildRequires: fenics-basix-devel >= 0.11.0 BuildRequires: ufcx-devel >= 0.11.0 BuildRequires: openmpi-devel BuildRequires: hdf5-openmpi-devel BuildRequires: petsc-openmpi-devel >= 3.15 BuildRequires: ptscotch-openmpi-devel # ptscotch-openmpi-devel's SCOTCHConfig.cmake unconditionally include()s # scotchmetisTargets.cmake and ptscotchparmetisTargets.cmake, which are shipped # only by the -parmetis subpackage with no dependency declared between them. # Without this, find_package(SCOTCH) fails outright. (Fedora packaging bug.) BuildRequires: ptscotch-openmpi-devel-parmetis BuildRequires: superlu_dist-openmpi-devel BuildRequires: python3-devel BuildRequires: python3-nanobind >= 2.5.0 BuildRequires: python3-scikit-build-core >= 0.11 # Python bindings are built in %%install against the staged C++ library, so the # pyproject tooling is pulled in explicitly (no %%generate_buildrequires here). BuildRequires: python3-pip BuildRequires: python3-wheel BuildRequires: python3-mpi4py-openmpi BuildRequires: python3-petsc-openmpi BuildRequires: python3-fenics-basix >= 0.11.0 BuildRequires: python3-fenics-ffcx >= 0.11.0 BuildRequires: python3-fenics-ufl >= 2026.1.0 BuildRequires: python3-numpy >= 2 %global _description %{expand: DOLFINx is the computational environment of FEniCSx and implements the FEniCS Problem Solving Environment in C++ and Python. It is the successor to the legacy DOLFIN library, providing mesh handling, function spaces, assembly of finite element forms and interfaces to PETSc linear algebra. Note: SLEPc, ADIOS2 and KaHIP support are disabled because those libraries are not currently packaged in Fedora.} %description %_description %package openmpi Summary: %{summary} (openmpi) Requires: openmpi %description openmpi %_description %package openmpi-devel Summary: Development files for DOLFINx (openmpi) Requires: %{name}-openmpi%{?_isa} = %{version}-%{release} Requires: fenics-basix-devel%{?_isa} Requires: ufcx-devel Requires: cmake-filesystem %description openmpi-devel Headers and CMake configuration for building C++ applications against the openmpi build of DOLFINx. %package -n python3-dolfinx-openmpi Summary: Python interface to DOLFINx (openmpi) Requires: %{name}-openmpi%{?_isa} = %{version}-%{release} Requires: python3-mpi4py-openmpi # petsc4py, needed by dolfinx.fem.petsc Requires: python3-petsc-openmpi Requires: python3-fenics-basix >= 0.11.0 Requires: python3-fenics-ffcx >= 0.11.0 Requires: python3-fenics-ufl >= 2026.1.0 %description -n python3-dolfinx-openmpi Python (nanobind) interface to DOLFINx, built against openmpi. Load the openmpi environment module before use: module load mpi/openmpi-%{_arch} %prep %autosetup -n %{srcname}-%{upver} # The extension module sets INSTALL_RPATH_USE_LINK_PATH as a *target property*, # which overrides the -DCMAKE_INSTALL_RPATH_USE_LINK_PATH=OFF cache variable and # appends the staged buildroot lib dir to its RPATH (check-buildroot then # aborts). CMAKE_INSTALL_RPATH already records the correct final location, so # drop the property. sed -i '/INSTALL_RPATH_USE_LINK_PATH TRUE/d' python/CMakeLists.txt # get_petsc_lib() locates libpetsc via petsc4py's petsc.cfg, but Fedora's # petsc4py records PETSC_DIR as the RPM *build* directory # (/builddir/build/BUILD/petsc-*/...), which exists nowhere at runtime -- so # dolfinx.fem.petsc fails to import on any installed system. Add Fedora's real # library as a candidate. Use the versioned runtime soname so this does not # drag in petsc-openmpi-devel at runtime. Only one candidate can match, or # upstream raises "More than one PETSc shared library found" -- the upstream # paths never exist here, so exactly one does. sed -i 's|^ candidate_paths = \[| candidate_paths = [\n "%{_libdir}/openmpi/lib/libpetsc.so.3",|' \ python/dolfinx/fem/petsc.py %build %{_openmpi_load} export CXXFLAGS="%{optflags}" %cmake -S cpp \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=%{_libdir}/openmpi \ -DCMAKE_INSTALL_LIBDIR=lib \ -DDOLFINX_ENABLE_SLEPC=OFF \ -DDOLFINX_ENABLE_ADIOS2=OFF \ -DDOLFINX_ENABLE_KAHIP=OFF \ -DDOLFINX_ENABLE_PETSC=ON \ -DDOLFINX_ENABLE_SCOTCH=ON \ -DDOLFINX_ENABLE_SUPERLU_DIST=ON %cmake_build %{_openmpi_unload} %install %{_openmpi_load} %cmake_install # Python interface, linked against the staged C++ library export CMAKE_PREFIX_PATH="%{buildroot}%{_libdir}/openmpi:${CMAKE_PREFIX_PATH}" export LD_LIBRARY_PATH="%{buildroot}%{_libdir}/openmpi/lib:${LD_LIBRARY_PATH}" # The MPI prefix is not on the default loader path, so the extension module # does need an RPATH -- but it must record the *final* install location, not # the buildroot it links against here (check-buildroot aborts otherwise). export CMAKE_ARGS="-DDOLFINX_DIR=%{buildroot}%{_libdir}/openmpi/lib/cmake/dolfinx \ -DCMAKE_INSTALL_RPATH=%{_libdir}/openmpi/lib \ -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON \ -DCMAKE_INSTALL_RPATH_USE_LINK_PATH=OFF" pushd python %pyproject_wheel %pyproject_install popd # Fedora MPI guidelines: MPI-flavoured Python modules must be namespaced per # implementation (as mpi4py/petsc4py are), otherwise the openmpi and mpich # builds would install the same paths and conflict. mkdir -p %{buildroot}%{python3_sitearch}/openmpi mv %{buildroot}%{python3_sitearch}/dolfinx \ %{buildroot}%{python3_sitearch}/openmpi/ mv %{buildroot}%{python3_sitearch}/fenics_dolfinx-*.dist-info \ %{buildroot}%{python3_sitearch}/openmpi/ %{_openmpi_unload} %check %{_openmpi_load} # The extension's RPATH points at the final install location, which is not # populated yet, so point the loader at the staged library for the import test. export LD_LIBRARY_PATH="%{buildroot}%{_libdir}/openmpi/lib:${LD_LIBRARY_PATH}" export PYTHONPATH="%{buildroot}%{python3_sitearch}/openmpi" python3 -c "import dolfinx, dolfinx.fem, dolfinx.mesh, dolfinx.io; print('dolfinx', dolfinx.__version__)" # Exercises the petsc.cfg workaround applied in %%prep: if the candidate path # is wrong these raise RuntimeError, so this is a real regression test rather # than a smoke check. python3 -c "import dolfinx.fem.petsc; print('fem.petsc OK')" python3 -c "import dolfinx.nls.petsc; print('nls.petsc OK')" %{_openmpi_unload} %files openmpi %license COPYING COPYING.LESSER %doc README.md ChangeLog.rst AUTHORS %{_libdir}/openmpi/lib/libdolfinx.so.%{sover}* # Headers stay under the MPI prefix so the exported CMake target's # INTERFACE_INCLUDE_DIRECTORIES resolves to a path that actually exists. %files openmpi-devel %{_libdir}/openmpi/include/dolfinx/ %{_libdir}/openmpi/include/dolfinx.h %{_libdir}/openmpi/lib/libdolfinx.so %{_libdir}/openmpi/lib/cmake/dolfinx/ %{_libdir}/openmpi/lib/pkgconfig/dolfinx.pc %{_libdir}/openmpi/lib/dolfinx/dolfinx.conf %files -n python3-dolfinx-openmpi %license COPYING COPYING.LESSER %{python3_sitearch}/openmpi/dolfinx/ %{python3_sitearch}/openmpi/fenics_dolfinx-%{upver}.dist-info/ %changelog %autochangelog