1{
2 stdenv,
3 lib,
4 buildPythonPackage,
5 fetchFromGitHub,
6 pythonOlder,
7 setuptools,
8 autoreconfHook,
9 pkg-config,
10 mpiCheckPhaseHook,
11 gfortran,
12 mpi,
13 blas,
14 lapack,
15 fftw,
16 hdf5-mpi,
17 swig,
18 gsl,
19 harminv,
20 libctl,
21 libGDSII,
22 openssh,
23 guile,
24 python,
25 numpy,
26 scipy,
27 matplotlib,
28 h5py-mpi,
29 cython,
30 autograd,
31 mpi4py,
32}:
33
34assert !blas.isILP64;
35assert !lapack.isILP64;
36
37buildPythonPackage rec {
38 pname = "meep";
39 version = "1.28.0";
40
41 src = fetchFromGitHub {
42 owner = "NanoComp";
43 repo = pname;
44 rev = "refs/tags/v${version}";
45 hash = "sha256-o/Xrd/Gn1RsbB+ZfggGH6/ugdsGtfTe2RgaHdpY5AyE=";
46 };
47
48 format = "other";
49
50 # https://github.com/NanoComp/meep/issues/2819
51 postPatch = lib.optionalString (!pythonOlder "3.12") ''
52 substituteInPlace configure.ac doc/docs/setup.py python/visualization.py \
53 --replace-fail "distutils" "setuptools._distutils"
54 '';
55
56 # MPI is needed in nativeBuildInputs too, otherwise MPI libs will be missing
57 # at runtime
58 nativeBuildInputs = [
59 autoreconfHook
60 gfortran
61 pkg-config
62 swig
63 mpi
64 ];
65
66 buildInputs = [
67 gsl
68 blas
69 lapack
70 fftw
71 hdf5-mpi
72 harminv
73 libctl
74 libGDSII
75 guile
76 gsl
77 ];
78
79 propagatedBuildInputs =
80 [
81 mpi
82 numpy
83 scipy
84 matplotlib
85 h5py-mpi
86 cython
87 autograd
88 mpi4py
89 ]
90 ++ lib.optionals (!pythonOlder "3.12") [
91 setuptools # used in python/visualization.py
92 ];
93
94 propagatedUserEnvPkgs = [ mpi ];
95
96 dontUseSetuptoolsBuild = true;
97 dontUsePipInstall = true;
98 dontUseSetuptoolsCheck = true;
99
100 enableParallelBuilding = true;
101
102 preConfigure = ''
103 export HDF5_MPI=ON
104 export PYTHON=${python}/bin/${python.executable};
105 '';
106
107 configureFlags = [
108 "--without-libctl"
109 "--enable-shared"
110 "--with-mpi"
111 "--with-openmp"
112 "--enable-maintainer-mode"
113 ];
114
115 passthru = {
116 inherit mpi;
117 };
118
119 /*
120 This test is taken from the MEEP tutorial "Fields in a Waveguide" at
121 <https://meep.readthedocs.io/en/latest/Python_Tutorials/Basics/>.
122 It is important, that the test actually performs a calculation
123 (calls `sim.run()`), as only then MPI will be initialised and MPI linking
124 errors can be caught.
125 */
126 doCheck = true;
127 nativeCheckInputs = [
128 mpiCheckPhaseHook
129 openssh
130 ];
131 checkPhase = ''
132 runHook preCheck
133
134 export PYTHONPATH="$out/${python.sitePackages}:$PYTHONPATH"
135
136 # Generate a python test script
137 cat > test.py << EOF
138 import meep as mp
139 cell = mp.Vector3(16,8,0)
140 geometry = [mp.Block(mp.Vector3(mp.inf,1,mp.inf),
141 center=mp.Vector3(),
142 material=mp.Medium(epsilon=12))]
143 sources = [mp.Source(mp.ContinuousSource(frequency=0.15),
144 component=mp.Ez,
145 center=mp.Vector3(-7,0))]
146 pml_layers = [mp.PML(1.0)]
147 resolution = 10
148 sim = mp.Simulation(cell_size=cell,
149 boundary_layers=pml_layers,
150 geometry=geometry,
151 sources=sources,
152 resolution=resolution)
153 sim.run(until=200)
154 EOF
155
156 ${mpi}/bin/mpiexec -np 2 python3 test.py
157
158 runHook postCheck
159 '';
160
161 meta = with lib; {
162 description = "Free finite-difference time-domain (FDTD) software for electromagnetic simulations";
163 homepage = "https://meep.readthedocs.io/en/latest/";
164 license = licenses.gpl2Only;
165 platforms = platforms.linux;
166 maintainers = with maintainers; [
167 sheepforce
168 markuskowa
169 ];
170 };
171}