1{
2 lib,
3 buildPythonPackage,
4 fetchFromGitHub,
5 pythonOlder,
6 setuptools,
7 autoreconfHook,
8 pkg-config,
9 mpiCheckPhaseHook,
10 gfortran,
11 mpi,
12 blas,
13 lapack,
14 fftw,
15 hdf5-mpi,
16 swig,
17 gsl,
18 harminv,
19 libctl,
20 libGDSII,
21 guile,
22 mpb,
23 python,
24 numpy,
25 scipy,
26 matplotlib,
27 h5py-mpi,
28 cython,
29 autograd,
30 mpi4py,
31}:
32
33assert !blas.isILP64;
34assert !lapack.isILP64;
35
36buildPythonPackage rec {
37 pname = "meep";
38 version = "1.29.0";
39
40 src = fetchFromGitHub {
41 owner = "NanoComp";
42 repo = pname;
43 rev = "refs/tags/v${version}";
44 hash = "sha256-TB85obdk8pSWRaz3+3I6P6+dQtCHosWHRnKGck/wG9Q=";
45 };
46
47 format = "other";
48
49 # https://github.com/NanoComp/meep/issues/2819
50 postPatch = lib.optionalString (!pythonOlder "3.12") ''
51 substituteInPlace configure.ac doc/docs/setup.py python/visualization.py \
52 --replace-fail "distutils" "setuptools._distutils"
53 '';
54
55 # MPI is needed in nativeBuildInputs too, otherwise MPI libs will be missing
56 # at runtime
57 nativeBuildInputs = [
58 autoreconfHook
59 gfortran
60 pkg-config
61 swig
62 mpi
63 ];
64
65 buildInputs = [
66 gsl
67 blas
68 lapack
69 fftw
70 hdf5-mpi
71 harminv
72 libctl
73 libGDSII
74 guile
75 gsl
76 mpb
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 nativeCheckInputs = [
127 mpiCheckPhaseHook
128 ];
129 pythonImportCheck = [
130 "meep.mpb"
131 ];
132 checkPhase = ''
133 runHook preCheck
134
135 export PYTHONPATH="$out/${python.sitePackages}:$PYTHONPATH"
136
137 # Generate a python test script
138 cat > test.py << EOF
139 import meep as mp
140 cell = mp.Vector3(16,8,0)
141 geometry = [mp.Block(mp.Vector3(mp.inf,1,mp.inf),
142 center=mp.Vector3(),
143 material=mp.Medium(epsilon=12))]
144 sources = [mp.Source(mp.ContinuousSource(frequency=0.15),
145 component=mp.Ez,
146 center=mp.Vector3(-7,0))]
147 pml_layers = [mp.PML(1.0)]
148 resolution = 10
149 sim = mp.Simulation(cell_size=cell,
150 boundary_layers=pml_layers,
151 geometry=geometry,
152 sources=sources,
153 resolution=resolution)
154 sim.run(until=200)
155 EOF
156
157 ${mpi}/bin/mpiexec -np 2 python3 test.py
158
159 runHook postCheck
160 '';
161
162 meta = {
163 description = "Free finite-difference time-domain (FDTD) software for electromagnetic simulations";
164 homepage = "https://meep.readthedocs.io/en/latest/";
165 license = lib.licenses.gpl2Only;
166 platforms = lib.platforms.linux;
167 maintainers = with lib.maintainers; [
168 sheepforce
169 markuskowa
170 ];
171 };
172}