diff --git a/README.md b/README.md index 72c7e13..35b52b4 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,9 @@ spack install additivefoam See the [installation instructions](https://ornl.github.io/AdditiveFOAM/docs/installation/#installation) in the [documentation](https://ornl.github.io/AdditiveFOAM/) for other options for building `AdditiveFOAM`. +An alternative installation mechanism is using Nix. See +[Nix.md](./envs/nix/NIX.md) for more details. + ## Citing [![DOI](https://joss.theoj.org/papers/10.21105/joss.07770/status.svg)](https://doi.org/10.21105/joss.07770) [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.8034097.svg)](https://doi.org/10.5281/zenodo.8034097) diff --git a/envs/nix/NIX.md b/envs/nix/NIX.md new file mode 100644 index 0000000..dd7ea59 --- /dev/null +++ b/envs/nix/NIX.md @@ -0,0 +1,30 @@ +## Nix + +First install the [Nix package manager][NIX] and then enable +[Flakes][Flakes]. Alternatively, check out the [Determinate Systems +Installer][Determinate] for an out of the box experience. See +[nix.dev][nix.dev] for more help with Nix. + +To get an environment with both AdditiveFOAM and ExaCA use + + $ nix develop github:ORNL/AdditiveFOAM?dir=envs/nix --accept-flake-config + # AdditiveFOAM and ExaCA now available + $ additiveFoam --help + $ ExaCA --help + +To get a specific release, use: + + $ nix develop github:ORNL/AdditiveFOAM/?dir=envs/nix --accept-flake-config + +In principle the build should be fast (on x86-64-linux) as the +binaries are downloaded from Cachix. You will be prompted to `allow +configuration setting 'extra-substituters'`. + +See the main [README](../../README.md) for more details on building +AdditiveFOAM. + +[NIX]: https://nixos.org/download.html +[Flakes]: https://nixos.wiki/wiki/Flakes +[nix.dev]: https://nix.dev +[Determinate]: https://github.com/DeterminateSystems/nix-installer + diff --git a/envs/nix/additivefoam.nix b/envs/nix/additivefoam.nix new file mode 100644 index 0000000..3f1fed0 --- /dev/null +++ b/envs/nix/additivefoam.nix @@ -0,0 +1,106 @@ +{ + stdenv, + makeWrapper, + openfoam, + openmpi, + exaca, + src, + version, + glibc, + zlib +}: +stdenv.mkDerivation rec { + pname = "additivefoam"; + inherit version; + inherit src; + + nativeBuildInputs = [ + makeWrapper + ]; + + buildInputs = [ + openfoam + openmpi + zlib + ]; + + propagatedBuildInputs = [ + exaca + openmpi + ]; + + buildPhase = '' + runHook preBuild + + mkdir -p builduser/.OpenFOAM + mkdir -p builduser/OpenFOAM + export HOME=$(pwd)/builduser + export USER=builduser + + source ${openfoam.BASHRC} || true + + APPS_DIR=$(pwd)/applications/solvers/additiveFoam + + cd $APPS_DIR/movingHeatSource + wmake libso + + cd $APPS_DIR/functionObjects/ExaCA + wmake libso + + cd $APPS_DIR + wmake + + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + + mkdir -p $out + + cp -r $FOAM_USER_APPBIN $out + cp -r $FOAM_USER_LIBBIN $out + + cp -r ${src}/applications $out/ + cp -r ${src}/tutorials $out/ + + runHook postInstall + ''; + + postInstall = '' + wrapProgram $out/bin/additiveFoam \ + --suffix LD_LIBRARY_PATH : "$out/lib:${openmpi}/lib:${stdenv.cc.cc.lib}/lib:${zlib}/lib" + + LINKER=${glibc}/lib/ld-linux-x86-64.so.2; + patchelf --set-interpreter $LINKER $out/bin/.additiveFoam-wrapped + ''; + + doCheck = false; + doInstallCheck = true; + + installCheckPhase = '' + + cd $HOME + mkdir -p app + cp -r ${src}/tutorials/AMB2018-02-B/* app/ + chmod u+w -R app + cd app + + # Ensure ExaCA is found + substituteInPlace $HOME/app/Allrun --replace-fail "~/install/exaca/bin/ExaCA" "ExaCA" + + ./Allrun -withExaCA + + if [ -f "ExaCA/Output.vtk" ]; then + echo "Check PASSED: Output.vtk generated." + else + echo "Check FAILED: Output.vtk not found." + exit 1 + fi + + cd .. + rm -rf app + + ''; + +} diff --git a/envs/nix/dev.nix b/envs/nix/dev.nix new file mode 100644 index 0000000..81a8bd8 --- /dev/null +++ b/envs/nix/dev.nix @@ -0,0 +1,41 @@ +{ self', pkgs, lib, ...}: + +{ + devShells = with self'.packages; rec { + default = pkgs.mkShell { + name = "additivefoam-env"; + + packages = [ + openfoam + exaca + self'.packages.default + ]; + + shellHook = '' + source ${openfoam.BASHRC} + ''; + + }; + + devel = pkgs.mkShell { + name = "additivefoam-dev"; + + packages = [ + openfoam + exaca + ]; + + inputsFrom = [ + self'.packages.default + ]; + + shellHook = '' + source ${openfoam.BASHRC} + ''; + + LOCALE_ARCHIVE = pkgs.lib.optional (pkgs.stdenv.hostPlatform.isLinux) ( + "${pkgs.glibcLocales}/lib/locale/locale-archive" + ); + }; + }; +} diff --git a/envs/nix/flake.lock b/envs/nix/flake.lock new file mode 100644 index 0000000..8c1626d --- /dev/null +++ b/envs/nix/flake.lock @@ -0,0 +1,132 @@ +{ + "nodes": { + "exaca": { + "inputs": { + "nixpkgs": "nixpkgs", + "parts": "parts" + }, + "locked": { + "dir": "envs/nix", + "lastModified": 1757080339, + "narHash": "sha256-OwphXRWa4v11R81l1gABhzEaeBWtTyi5u6R1Uf1oMhA=", + "owner": "LLNL", + "repo": "ExaCA", + "rev": "562eedc4db2306572ad6dedf6f9e69ea6ecca722", + "type": "github" + }, + "original": { + "dir": "envs/nix", + "owner": "LLNL", + "repo": "ExaCA", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1748026580, + "narHash": "sha256-rWtXrcIzU5wm/C8F9LWvUfBGu5U5E7cFzPYT1pHIJaQ=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "11cb3517b3af6af300dd6c055aeda73c9bf52c48", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "25.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1753579242, + "narHash": "sha256-zvaMGVn14/Zz8hnp4VWT9xVnhc8vuL3TStRqwk22biA=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "0f36c44e01a6129be94e3ade315a5883f0228a6e", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "nixpkgs-lib_2": { + "locked": { + "lastModified": 1753579242, + "narHash": "sha256-zvaMGVn14/Zz8hnp4VWT9xVnhc8vuL3TStRqwk22biA=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "0f36c44e01a6129be94e3ade315a5883f0228a6e", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1754292888, + "narHash": "sha256-1ziydHSiDuSnaiPzCQh1mRFBsM2d2yRX9I+5OPGEmIE=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "ce01daebf8489ba97bd1609d185ea276efdeb121", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-25.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1754487366, + "narHash": "sha256-pHYj8gUBapuUzKV/kN/tR3Zvqc7o6gdFB9XKXIp1SQ8=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "af66ad14b28a127c5c0f3bbb298218fc63528a18", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "parts_2": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib_2" + }, + "locked": { + "lastModified": 1754487366, + "narHash": "sha256-pHYj8gUBapuUzKV/kN/tR3Zvqc7o6gdFB9XKXIp1SQ8=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "af66ad14b28a127c5c0f3bbb298218fc63528a18", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "root": { + "inputs": { + "exaca": "exaca", + "nixpkgs": "nixpkgs_2", + "parts": "parts_2" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/envs/nix/flake.nix b/envs/nix/flake.nix new file mode 100644 index 0000000..d34192d --- /dev/null +++ b/envs/nix/flake.nix @@ -0,0 +1,46 @@ +## See NIX.md for help getting started with Nix + +{ + description = "An open-source CFD code for additive manufacturing built on OpenFOAM."; + + nixConfig = { + extra-substituters = [ "https://additivefoam.cachix.org" ]; + extra-trusted-public-keys = [ "additivefoam.cachix.org-1:T65eaaS9ruHWDuAohShjknS95viBv9QTCYcZrCHNXzU=" ]; + }; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05"; + exaca.url = "github:LLNL/ExaCA?dir=envs/nix"; + parts.url = "github:hercules-ci/flake-parts"; + }; + + outputs = inputs @ { self, parts, ... }: ( + parts.lib.mkFlake { inherit inputs; } { + systems = [ + "x86_64-linux" + "aarch64-linux" + ]; + + perSystem = { pkgs, inputs', ... }: { + packages = rec { + default = additivefoam; + + openfoam = pkgs.callPackage ./openfoam.nix { scotch = scotch; }; + scotch = pkgs.callPackage ./scotch.nix { }; + exaca = inputs'.exaca.packages.default; + + additivefoam = pkgs.callPackage ./additivefoam.nix { + src = ../..; + version = "master"; + exaca = exaca; + openfoam = openfoam; + }; + }; + + imports = [ + ./dev.nix + ]; + }; + } + ); +} diff --git a/envs/nix/openfoam.nix b/envs/nix/openfoam.nix new file mode 100644 index 0000000..c657767 --- /dev/null +++ b/envs/nix/openfoam.nix @@ -0,0 +1,159 @@ +# Based on this build for OpenFOAM 12 +# - https://github.com/NixOS/nixpkgs/blob/07ba4b68bad1931618851055077ed20d677b81ed/pkgs/by-name/op/openfoam-org/package.nix +# Useful as well +# - https://git.computecanada.ca/nix/ccpkgs/-/blob/cc-20.09/pkgs/openfoam.nix + +{ + stdenv, + bash, + m4, + flex, + bison, + fftw, + scotch, + boost, + openmpi, + cgal, + zlib, + fetchFromGitHub, + lib, + trilinos-mpi +}: +let + openfoamDrv = stdenv.mkDerivation rec { + pname = "openfoam-org"; + version = "10"; + src = fetchFromGitHub { + owner = "OpenFOAM"; + repo = "OpenFOAM-12"; + rev = "refs/tags/version-${version}"; + hash = "sha256-1vcBZELsThlfSJeW3iFm8sTh+uOgKKEYU0g+XlxczdA="; + + }; + + nativeBuildInputs = [ + bash + flex + bison + ]; + + + buildInputs = [ + m4 + fftw + boost + cgal + zlib + trilinos-mpi + openmpi + scotch + ]; + + propagatedBuildInputs = [ + openmpi + ]; + + sourceRoot = "."; + + patchPhase = '' + runHook prePatch + + mkdir -p builduser/OpenFOAM + mkdir -p builduser/.OpenFOAM + export HOME=$(pwd)/builduser + export FOAM_DIR=$HOME/OpenFOAM/OpenFOAM-${version} + mv source $FOAM_DIR + mkdir -p $FOAM_DIR/paraviewout + + set +e + for f in \ + $FOAM_DIR/wmake/scripts/* \ + $FOAM_DIR/wmake/* + do + substituteInPlace $f --replace-quiet /bin/bash ${bash}/bin/bash + done + set -e + + rm $FOAM_DIR/etc/config.sh/bash_completion + touch $FOAM_DIR/etc/config.sh/bash_completion + + echo "set +e" | cat $FOAM_DIR/etc/bashrc > tmp + rm $FOAM_DIR/etc/bashrc + mv tmp $FOAM_DIR/etc/bashrc + + echo "set +e" | cat $FOAM_DIR/Allwmake > tmp + rm $FOAM_DIR/Allwmake + mv tmp $FOAM_DIR/Allwmake + + alias wmRefresh="placeholder" + chmod +x $FOAM_DIR/Allwmake + chmod +x $FOAM_DIR/applications/utilities/postProcessing/graphics/PVReaders/Allwmake + touch $HOME/.OpenFOAM/prefs.sh + + # only if version 10 + substituteInPlace $FOAM_DIR/etc/bashrc --replace-fail "export WM_PROJECT_VERSION=dev" "export WM_PROJECT_VERSION=10" + sed -i '47 i libDir=${openmpi.dev}/lib' $FOAM_DIR/etc/config.sh/mpi + sed -ie 's|SCOTCH_ARCH_PATH=.*$|SCOTCH_ARCH_PATH=${scotch.dev}|' $FOAM_DIR/etc/config.sh/scotch + + set +e + for f in \ + $FOAM_DIR/src/parallel/decompose/*/Make/options + do + substituteInPlace $f --replace-quiet /usr/include/scotch ${scotch.dev}/include + substituteInPlace $f --replace-quiet "\$(SCOTCH_ARCH_PATH)/lib" ${scotch.out}/lib + done + set -e + + substituteInPlace $FOAM_DIR/wmake/rules/General/mplibOPENMPI --replace-fail "\$(MPI_ARCH_PATH)/include" "${openmpi.dev}/include" + substituteInPlace $FOAM_DIR/wmake/rules/General/mplibOPENMPI --replace-fail "\$(MPI_ARCH_PATH)/lib" "${openmpi.out}/lib" + + # This has a broken link + rm $FOAM_DIR/tutorials/mesh/snappyHexMesh/iglooWithFridges + + runHook postPatch + + ''; + + buildPhase = '' + runHook preBuild + + cd $FOAM_DIR + source ./etc/bashrc + + # Can't get it working without these paths. + # Shouldn't be required + export LD_LIBRARY_PATH="${flex}/lib''${LD_LIBRARY_PATH}" + export C_INCLUDE_PATH="${flex}/include''${C_INCLUDE_PATH}" + export CPLUS_INCLUDE_PATH="${flex}/include''${CPLUS_INCLUDE_PATH}" + + wmakeLnIncludeAll + + ./Allwmake -j $NIX_BUILD_CORES -q + + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + + FOAM_OUT=$out/opt/OpenFOAM-${version} + mkdir -p $FOAM_OUT + + cp -r bin $FOAM_OUT + cp -r platforms $FOAM_OUT + cp -r etc $FOAM_OUT + cp -r applications $FOAM_OUT + cp -r src $FOAM_OUT + cp -r doc $FOAM_OUT + cp -r tutorials $FOAM_OUT + cp -r wmake $FOAM_OUT + + runHook postInstall + ''; + + passthru = { + BASHRC = "${openfoamDrv}/opt/OpenFOAM-${version}/etc/bashrc"; + }; + }; +in + openfoamDrv diff --git a/envs/nix/scotch.nix b/envs/nix/scotch.nix new file mode 100644 index 0000000..85106a6 --- /dev/null +++ b/envs/nix/scotch.nix @@ -0,0 +1,39 @@ +# Taken from https://github.com/NixOS/nixpkgs/blob/5ee46705af97c806817aa41dbb2914a4bf431ee3/pkgs/by-name/op/openfoam-com/generic.nix + +{ + flex, + bison, + scotch, + zlib, + fetchFromGitLab, + mpi +}: +scotch.overrideAttrs (prev: rec { + version = "6.0.9"; + + src = fetchFromGitLab { + domain = "gitlab.inria.fr"; + owner = "scotch"; + repo = "scotch"; + rev = "v${version}"; + hash = "sha256-YR2Evj7VnDNGQVNlHovj6CfvPJgAoHeTKu4EW5cXtdg="; + }; + + nativeBuildInputs = [ ]; + + buildInputs = [ + bison + mpi + flex + zlib + ]; + + preConfigure = '' + cd src + ln -s Make.inc/Makefile.inc.x86-64_pc_linux2 Makefile.inc + ''; + + buildFlags = [ "scotch ptscotch" ]; + + installFlags = [ "prefix=\${out}" ]; +})