forked from ahmadia/homebrew-science
-
Notifications
You must be signed in to change notification settings - Fork 0
/
lammps.rb
259 lines (214 loc) · 8.25 KB
/
lammps.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
require 'formula'
class Lammps < Formula
homepage 'http://lammps.sandia.gov'
url 'http://lammps.sandia.gov/tars/lammps-14May13.tar.gz'
sha1 '5e522e9e3d4a4cbbe80c01c36002489777fb65d8'
# lammps releases are named after their release date. We transform it to
# YYYY.MM.DD (year.month.day) so that we get a comparable version numbering (for brew outdated)
version '2013.05.14'
head 'http://git.icms.temple.edu/lammps-ro.git'
# user-submitted packages not considered "standard"
USER_PACKAGES= %W[
user-misc
user-awpmd
user-cg-cmm
user-colvars
user-eff
user-molfile
user-reaxc
user-sph
]
# could not get gpu or user-cuda to install (hardware problem?)
# kim requires openkim software, which is not currently in homebrew.
# user-atc would not install without mpi and then would not link to blas-lapack
# user-omp requires gcc dependency (tricky). clang does not have OMP support, yet.
DISABLED_PACKAGES = %W[
gpu
kim
user-omp
]
DISABLED_USER_PACKAGES = %W[
user-atc
user-cuda
]
# setup user-packages as options
USER_PACKAGES.each do |package|
option "enable-#{package}", "Build lammps with the '#{package}' package"
end
# additional options
option "with-mpi", "Build lammps with MPI support"
depends_on 'fftw'
depends_on 'jpeg'
depends_on 'voro++'
depends_on :mpi => [:cxx, :f90, :optional]
depends_on :fortran
def build_lib(comp, lmp_lib, opts={})
change_compiler_var = opts[:change_compiler_var] # a non-standard compiler name to replace
prefix_make_var = opts[:prefix_make_var] || "" # prepended to makefile variable names
cd "lib/"+lmp_lib do
if comp == "FC"
make_file = "Makefile.gfortran" # make file
compiler_var = "F90" # replace compiler
elsif comp == "CXX"
make_file = "Makefile.g++" # make file
compiler_var = "CC" # replace compiler
elsif comp == "MPICXX"
make_file = "Makefile.openmpi" # make file
compiler_var = "CC" # replace compiler
comp = "CXX" if not ENV["MPICXX"]
end
compiler_var = change_compiler_var if change_compiler_var
# force compiler
inreplace make_file do |s|
s.change_make_var! compiler_var, ENV[comp]
end
system "make", "-f", make_file
if File.exists? "Makefile.lammps"
# empty it to reduce chance of conflicts
inreplace "Makefile.lammps" do |s|
s.change_make_var! prefix_make_var+lmp_lib+"_SYSINC", ""
s.change_make_var! prefix_make_var+lmp_lib+"_SYSLIB", ""
s.change_make_var! prefix_make_var+lmp_lib+"_SYSPATH", ""
end
end
end
end
def install
ENV.j1 # not parallel safe (some packages have race conditions :meam:)
# make sure to optimize the installation
ENV.append "CFLAGS","-O"
ENV.append "LDFLAGS","-O"
if build.include? "with-mpi"
# Simplify by relying on the mpi compilers
ENV["FC"] = ENV["MPIFC"]
ENV["CXX"] = ENV["MPICXX"]
end
# build package libraries
build_lib "FC", "reax"
build_lib "FC", "meam"
build_lib "CXX", "poems"
build_lib "CXX", "colvars", :change_compiler_var => "CXX" if build.include? "enable-user-colvars"
if build.include? "enable-user-awpmd"
build_lib "MPICXX","awpmd", :prefix_make_var => "user-"
ENV.append 'LDFLAGS', "-lblas -llapack"
end
# Assuming gfortran library
ENV.append 'LDFLAGS', "-L#{Formula.factory('gfortran').opt_prefix}/gfortran/lib -lgfortran"
# build the lammps program and library
cd "src" do
# setup the make file variabls for fftw, jpeg, and mpi
inreplace "MAKE/Makefile.mac" do |s|
# We will stick with "make mac" type and forget about
# "make mac_mpi" because it has some unnecessary
# settings. We get a nice clean slate with "mac"
if build.include? "with-mpi"
#-DOMPI_SKIP_MPICXX is to speed up c++ compilation
s.change_make_var! "MPI_INC" , "-DOMPI_SKIP_MPICXX"
s.change_make_var! "MPI_PATH" , ""
s.change_make_var! "MPI_LIB" , ""
end
s.change_make_var! "CC" , ENV["CXX"]
s.change_make_var! "LINK" , ENV["CXX"]
# installing with FFTW and JPEG
s.change_make_var! "FFT_INC" , "-DFFT_FFTW3 -I#{Formula.factory('fftw').opt_prefix}/include"
s.change_make_var! "FFT_PATH" , "-L#{Formula.factory('fftw').opt_prefix}/lib"
s.change_make_var! "FFT_LIB" , "-lfftw3"
s.change_make_var! "JPG_INC" , "-DLAMMPS_JPEG -I#{Formula.factory('jpeg').opt_prefix}/include"
s.change_make_var! "JPG_PATH" , "-L#{Formula.factory('jpeg').opt_prefix}/lib"
s.change_make_var! "JPG_LIB" , "-ljpeg"
s.change_make_var! "CCFLAGS" , ENV["CFLAGS"]
s.change_make_var! "LIB" , ENV["LDFLAGS"]
end
inreplace "VORONOI/Makefile.lammps" do |s|
s.change_make_var! "voronoi_SYSINC", "-I#{HOMEBREW_PREFIX}/include/voro++"
end
# setup standard packages
system "make", "yes-standard"
DISABLED_PACKAGES.each do |pkg|
system "make", "no-" + pkg
end
# setup optional packages
USER_PACKAGES.each do |pkg|
system "make", "yes-" + pkg if build.include? "enable-" + pkg
end
unless build.include? "with-mpi"
# build fake mpi library
cd "STUBS" do
system "make"
end
end
system "make", "mac"
mv "lmp_mac", "lammps" # rename it to make it easier to find
# build the lammps library
system "make", "makeshlib"
system "make", "-f", "Makefile.shlib", "mac"
# install them
bin.install("lammps")
lib.install("liblammps_mac.so")
lib.install("liblammps.so") # this is just a soft-link to liblamps_mac.so
end
# get the python module
cd "python" do
temp_site_packages = lib/which_python/'site-packages'
mkdir_p temp_site_packages
ENV['PYTHONPATH'] = temp_site_packages
system "python", "install.py", lib, temp_site_packages
mv "examples", "python-examples"
prefix.install("python-examples")
end
# install additional materials
(share/'lammps').install(["doc", "potentials", "tools", "bench"])
end
def which_python
"python" + `python -c 'import sys;print(sys.version[:3])'`.strip
end
def test
# to prevent log files, move them to a temporary directory
mktemp do
system "lammps","-in","#{HOMEBREW_PREFIX}/share/lammps/bench/in.lj"
system "python","-c","from lammps import lammps ; lammps().file('#{HOMEBREW_PREFIX}/share/lammps/bench/in.lj')"
end
end
def caveats
<<-EOS.undent
You should run a benchmark test or two. There are plenty available.
cd #{HOMEBREW_PREFIX}/share/lammps/bench
lammps -in in.lj
# with mpi
mpiexec -n 2 lammps -in in.lj
The following directories could come in handy
Documentation:
#{HOMEBREW_PREFIX}/share/lammps/doc/Manual.html
Potential files:
#{HOMEBREW_PREFIX}/share/lammps/potentials
Python examples:
#{HOMEBREW_PREFIX}/share/lammps/python-examples
Additional tools (may require manual installation):
#{HOMEBREW_PREFIX}/share/lammps/tools
To use the Python module with non-homebrew Python, you need to amend your
PYTHONPATH like so:
export PYTHONPATH=#{HOMEBREW_PREFIX}/lib/python2.7/site-packages:$PYTHONPATH
EOS
end
# This fixes the python module to point to the absolute path of the lammps library
# without this the module cannot find the library when homebrew is installed in a
# custom directory.
def patches
DATA
end
end
__END__
diff --git a/python/lammps.py b/python/lammps.py
index c65e84c..b2b28a2 100644
--- a/python/lammps.py
+++ b/python/lammps.py
@@ -23,8 +23,8 @@ class lammps:
# if name = "g++", load liblammps_g++.so
try:
- if not name: self.lib = CDLL("liblammps.so",RTLD_GLOBAL)
- else: self.lib = CDLL("liblammps_%s.so" % name,RTLD_GLOBAL)
+ if not name: self.lib = CDLL("HOMEBREW_PREFIX/lib/liblammps.so",RTLD_GLOBAL)
+ else: self.lib = CDLL("HOMEBREW_PREFIX/lib/liblammps_%s.so" % name,RTLD_GLOBAL)
except:
type,value,tb = sys.exc_info()
traceback.print_exception(type,value,tb)