|
| 1 | +# Copyright 2013-2022 Lawrence Livermore National Security, LLC and other |
| 2 | +# Spack Project Developers. See the top-level COPYRIGHT file for details. |
| 3 | +# |
| 4 | +# SPDX-License-Identifier: (Apache-2.0 OR MIT) |
| 5 | + |
| 6 | +import glob |
| 7 | +import os |
| 8 | +import platform |
| 9 | + |
| 10 | +from spack.package import * |
| 11 | + |
| 12 | + |
| 13 | +class Fplo(MakefilePackage): |
| 14 | + """The FPLO(R) package is a full-potential local-orbital code to solve the |
| 15 | + Kohn-Sham equations on a regular lattice or with free boundary conditions |
| 16 | + (finite systems). Relativistic effects are treated either in a |
| 17 | + scalar-relativistic or a full 4-component formalism. Available |
| 18 | + functionals are LSDA, GGA (PBE 96) and LSDA/GGA+U. Orbital polarization |
| 19 | + correction can be applied.""" |
| 20 | + |
| 21 | + homepage = "https://www.fplo.de/" |
| 22 | + url = "file://{0}/FPLO22.00-62.tar.gz".format(os.getcwd()) |
| 23 | + manual_download = True |
| 24 | + |
| 25 | + maintainers = ["glennpj"] |
| 26 | + |
| 27 | + version("22.00-62", sha256="0d1d4e9c1e8e41900901e26c3cd08ee39dcfdeb3f2c4c8862055eaf704b6d69e") |
| 28 | + |
| 29 | + # TODO: Try to get LAPACK to work with something other than MKL. The build |
| 30 | + # fails even with the fallback/builtin lapack. |
| 31 | + |
| 32 | + # This patch replaces the default builtin lapack with MKL, as MKL is the |
| 33 | + # only functioning LAPACK implementation. |
| 34 | + patch("lapackconfig.patch") |
| 35 | + |
| 36 | + # This patch does 3 things: (1) Change the order of the src directories so |
| 37 | + # the object dependencies are correct; (2) removes interactivity; and (3) |
| 38 | + # explicitly sets the configuration. |
| 39 | + patch("MMakefile.patch") |
| 40 | + |
| 41 | + # Add '-ltinfo' for linking. |
| 42 | + patch("ncurses.patch") |
| 43 | + |
| 44 | + # Set the names for QT and PYTHON. |
| 45 | + patch("qt-make.patch") |
| 46 | + |
| 47 | + # Sets the correct python module import order. |
| 48 | + patch("fedit_py.patch") |
| 49 | + |
| 50 | + depends_on("mkl") |
| 51 | + depends_on("ncurses") |
| 52 | + depends_on("perl", type="run") |
| 53 | + depends_on("qt@5+opengl") |
| 54 | + |
| 55 | + extends("python") |
| 56 | + depends_on("py-numpy") |
| 57 | + |
| 58 | + conflicts("%gcc@12:") |
| 59 | + |
| 60 | + @property |
| 61 | + def build_directory(self): |
| 62 | + return join_path(self.stage.source_path, "FPLO{0}".format(self.version)) |
| 63 | + |
| 64 | + def edit(self, spec, prefix): |
| 65 | + # Need to set this to 'gcc' even if using the intel compiler as all of |
| 66 | + # the configuration files are named with 'gcc'. |
| 67 | + if platform.system() == "Linux": |
| 68 | + fplo_cc = "gcc" |
| 69 | + else: |
| 70 | + fplo_cc = os.path.basename(self.compiler.cc) |
| 71 | + |
| 72 | + fplo_fc = os.path.basename(self.compiler.fc) |
| 73 | + |
| 74 | + conffile = "{0}-{1}-{2}-{3}".format( |
| 75 | + fplo_cc, fplo_fc, platform.system(), platform.machine() |
| 76 | + ) |
| 77 | + mmakefile = FileFilter(join_path(self.build_directory, "install", "MMakefile")) |
| 78 | + mmakefile.filter(r"(^conffile=\$configdir/)$", r"\1{0}".format(conffile)) |
| 79 | + mmakefile.filter(r"(^mkl=).*", r"\11") |
| 80 | + |
| 81 | + # use spack compiler |
| 82 | + files = glob.glob(join_path(self.build_directory, "install", "conf", "*")) |
| 83 | + filter_file(r"^\s*CC\s*=.*", "CC=" + spack_cc, *files) |
| 84 | + filter_file(r"^\s*CXX\s*=.*", "CXX=" + spack_cxx, *files) |
| 85 | + filter_file(r"^\s*F90\s*=.*", "F90=" + spack_fc, *files) |
| 86 | + |
| 87 | + # patch for 64 bit integers |
| 88 | + if "^mkl+ilp64" in spec: |
| 89 | + setuphelper = FileFilter(join_path(self.build_directory, "PYTHON", "setuphelper.py")) |
| 90 | + setuphelper.filter("mkl 64bit integer 32bit", "mkl 64bit integer 64bit") |
| 91 | + |
| 92 | + # setup python build |
| 93 | + python_makefile = FileFilter(join_path(self.build_directory, "PYTHON", "Makefile")) |
| 94 | + python_makefile.filter(r"(build_ext\s* --inplace)\s*--interactive(\s*.*)", r"\1\2") |
| 95 | + |
| 96 | + def build(self, spec, prefix): |
| 97 | + mmakefile = Executable(join_path(self.build_directory, "install", "MMakefile")) |
| 98 | + mmakefile_args = [ |
| 99 | + "-f90", |
| 100 | + spack_fc, |
| 101 | + "-cc", |
| 102 | + spack_cc, |
| 103 | + "-c+", |
| 104 | + spack_cxx, |
| 105 | + ] |
| 106 | + |
| 107 | + with working_dir(self.build_directory): |
| 108 | + # copy contents of bin |
| 109 | + copy_tree("bin", join_path(self.stage.source_path, "bin")) |
| 110 | + |
| 111 | + # configure the build |
| 112 | + with working_dir("install"): |
| 113 | + mmakefile(*mmakefile_args) |
| 114 | + |
| 115 | + # build main |
| 116 | + make() |
| 117 | + make("install") |
| 118 | + |
| 119 | + # build XFBP |
| 120 | + with working_dir(join_path("XFBP_rel", "XFBP")): |
| 121 | + make() |
| 122 | + make("install") |
| 123 | + |
| 124 | + # build XFPLO |
| 125 | + with working_dir(join_path("XFPLO_rel", "XFPLO")): |
| 126 | + make() |
| 127 | + make("install") |
| 128 | + |
| 129 | + # build python |
| 130 | + with working_dir("PYTHON"): |
| 131 | + if "^python@:2" in self.spec: |
| 132 | + make() |
| 133 | + else: |
| 134 | + make("python3") |
| 135 | + |
| 136 | + def install(self, spec, prefix): |
| 137 | + with working_dir(self.stage.source_path): |
| 138 | + install_tree("bin", prefix.bin) |
| 139 | + |
| 140 | + with working_dir(self.build_directory): |
| 141 | + install_tree("DOC", join_path(prefix.share, "DOC")) |
| 142 | + with working_dir("PYTHON"): |
| 143 | + install_tree("pyfplo", join_path(python_platlib, "pyfplo")) |
| 144 | + |
| 145 | + @run_after("install") |
| 146 | + def perl_interpreter(self): |
| 147 | + with working_dir(self.prefix.bin): |
| 148 | + pattern = "^#!.*/usr/bin/perl" |
| 149 | + repl = "#!{0}".format(self.spec["perl"].command.path) |
| 150 | + files = [ |
| 151 | + "fconv2", |
| 152 | + "fconvdens2", |
| 153 | + "fdowngrad.pl", |
| 154 | + "fout2in", |
| 155 | + "grBhfat", |
| 156 | + "grpop", |
| 157 | + ] |
| 158 | + for file in files: |
| 159 | + filter_file(pattern, repl, *files, backup=False) |
0 commit comments