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
|
# Copyright 2013-2023 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
from spack.package import *
class Cpmd(MakefilePackage):
"""The CPMD code is a parallelized plane wave / pseudopotential
implementation of Density Functional Theory, particularly
designed for ab-initio molecular dynamics."""
homepage = "https://www.cpmd.org/wordpress/"
url = "https://github.com/CPMD-code/CPMD/archive/refs/tags/4.3.tar.gz"
version("4.3", sha256="e0290f9da0d255f90a612e60662b14a97ca53003f89073c6af84fa7bc8739f65")
variant("omp", description="Enables the use of OMP instructions", default=False)
variant("mpi", description="Build with MPI support", default=False)
depends_on("lapack")
depends_on("mpi", when="+mpi")
conflicts("^openblas threads=none", when="+omp")
conflicts("^openblas threads=pthreads", when="+omp")
def edit(self, spec, prefix):
# patch configure file
cbase = "LINUX-GFORTRAN"
cp = FileFilter(join_path("configure", cbase))
# Compilers
if spec.satisfies("+mpi"):
fc = spec["mpi"].mpifc
cc = spec["mpi"].mpicc
else:
fc = spack_fc
cc = spack_cc
cp.filter(r"FFLAGS='([^']*)'", "FFLAGS='\\1 -fallow-argument-mismatch'")
cp.filter("FC=.+", "FC='{0}'".format(fc))
cp.filter("CC=.+", "CC='{0}'".format(cc))
cp.filter("LD=.+", "LD='{0}'".format(fc))
# MPI flag
if spec.satisfies("+mpi"):
cp.filter("-D__Linux", "-D__Linux -D__PARALLEL")
# OMP flag
if spec.satisfies("+omp"):
cp.filter("-fopenmp", self.compiler.openmp_flag)
# lapack
cp.filter("LIBS=.+", "LIBS='{0}'".format(spec["lapack"].libs.ld_flags))
# LFLAGS
cp.filter("'-static '", "")
# Compiler specific
if spec.satisfies("%fj"):
cp.filter("-ffixed-form", "-Fixed")
cp.filter("-ffree-line-length-none", "")
cp.filter("-falign-commons", "-Kalign_commons")
# create Makefile
bash = which("bash")
if spec.satisfies("+omp"):
bash("./configure.sh", "-omp", cbase)
else:
bash("./configure.sh", cbase)
def install(self, spec, prefix):
install_tree(".", prefix)
def test_cpmd(self):
test_dir = self.test_suite.current_test_data_dir
test_file = join_path(test_dir, "1-h2o-pbc-geoopt.inp")
opts = []
if self.spec.satisfies("+mpi"):
exe_name = self.spec["mpi"].prefix.bin.mpirun
opts.extend(["-n", "2"])
opts.append(join_path(self.prefix.bin, "cpmd.x"))
else:
exe_name = "cpmd.x"
opts.append(test_file)
opts.append(test_dir)
cpmd = which(exe_name)
out = cpmd(*opts, output=str.split, error=str.split)
expected = [
"2 1 H O 1.84444 0.97604",
"3 1 H O 1.84444 0.97604",
"2 1 3 H O H 103.8663",
]
check_outputs(expected, out)
|