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
|
# 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)
import glob
import os
import platform
from spack.package import *
class Fplo(MakefilePackage):
"""The FPLO(R) package is a full-potential local-orbital code to solve the
Kohn-Sham equations on a regular lattice or with free boundary conditions
(finite systems). Relativistic effects are treated either in a
scalar-relativistic or a full 4-component formalism. Available
functionals are LSDA, GGA (PBE 96) and LSDA/GGA+U. Orbital polarization
correction can be applied."""
homepage = "https://www.fplo.de/"
url = "file://{0}/FPLO22.00-62.tar.gz".format(os.getcwd())
manual_download = True
version("22.00-62", sha256="0d1d4e9c1e8e41900901e26c3cd08ee39dcfdeb3f2c4c8862055eaf704b6d69e")
# TODO: Try to get LAPACK to work with something other than MKL. The build
# fails even with the fallback/builtin lapack.
# This patch replaces the default builtin lapack with MKL, as MKL is the
# only functioning LAPACK implementation.
patch("lapackconfig.patch")
# This patch does 3 things: (1) Change the order of the src directories so
# the object dependencies are correct; (2) removes interactivity; and (3)
# explicitly sets the configuration.
patch("MMakefile.patch")
# Add '-ltinfo' for linking.
patch("ncurses.patch")
# Set the names for QT and PYTHON.
patch("qt-make.patch")
# Sets the correct python module import order.
patch("fedit_py.patch")
depends_on("mkl")
depends_on("ncurses")
depends_on("perl", type="run")
depends_on("qt@5+opengl")
extends("python")
depends_on("py-numpy")
conflicts("%gcc@12:")
@property
def build_directory(self):
return join_path(self.stage.source_path, "FPLO{0}".format(self.version))
def edit(self, spec, prefix):
# Need to set this to 'gcc' even if using the intel compiler as all of
# the configuration files are named with 'gcc'.
if platform.system() == "Linux":
fplo_cc = "gcc"
else:
fplo_cc = os.path.basename(self.compiler.cc)
fplo_fc = os.path.basename(self.compiler.fc)
conffile = "{0}-{1}-{2}-{3}".format(
fplo_cc, fplo_fc, platform.system(), platform.machine()
)
mmakefile = FileFilter(join_path(self.build_directory, "install", "MMakefile"))
mmakefile.filter(r"(^conffile=\$configdir/)$", r"\1{0}".format(conffile))
mmakefile.filter(r"(^mkl=).*", r"\11")
# use spack compiler
files = glob.glob(join_path(self.build_directory, "install", "conf", "*"))
filter_file(r"^\s*CC\s*=.*", "CC=" + spack_cc, *files)
filter_file(r"^\s*CXX\s*=.*", "CXX=" + spack_cxx, *files)
filter_file(r"^\s*F90\s*=.*", "F90=" + spack_fc, *files)
# patch for 64 bit integers
if spec["mkl"].satisfies("+ilp64"):
setuphelper = FileFilter(join_path(self.build_directory, "PYTHON", "setuphelper.py"))
setuphelper.filter("mkl 64bit integer 32bit", "mkl 64bit integer 64bit")
# setup python build
python_makefile = FileFilter(join_path(self.build_directory, "PYTHON", "Makefile"))
python_makefile.filter(r"(build_ext\s* --inplace)\s*--interactive(\s*.*)", r"\1\2")
def build(self, spec, prefix):
mmakefile = Executable(join_path(self.build_directory, "install", "MMakefile"))
mmakefile_args = ["-f90", spack_fc, "-cc", spack_cc, "-c+", spack_cxx]
with working_dir(self.build_directory):
# copy contents of bin
copy_tree("bin", join_path(self.stage.source_path, "bin"))
# configure the build
with working_dir("install"):
mmakefile(*mmakefile_args)
# build main
make()
make("install")
# build XFBP
with working_dir(join_path("XFBP_rel", "XFBP")):
make()
make("install")
# build XFPLO
with working_dir(join_path("XFPLO_rel", "XFPLO")):
make()
make("install")
# build python
with working_dir("PYTHON"):
make("python3")
def install(self, spec, prefix):
with working_dir(self.stage.source_path):
install_tree("bin", prefix.bin)
with working_dir(self.build_directory):
install_tree("DOC", join_path(prefix.share, "DOC"))
with working_dir("PYTHON"):
install_tree("pyfplo", join_path(python_platlib, "pyfplo"))
@run_after("install")
def perl_interpreter(self):
with working_dir(self.prefix.bin):
pattern = "^#!.*/usr/bin/perl"
repl = "#!{0}".format(self.spec["perl"].command.path)
files = ["fconv2", "fconvdens2", "fdowngrad.pl", "fout2in", "grBhfat", "grpop"]
for file in files:
filter_file(pattern, repl, *files, backup=False)
|