
MFEM is a free, lightweight, scalable C++ library for finite element methods. Includes lapack, hypre, metis, suite-sparse, mpi variants & tests for serial and parallel versions.
126 lines
5.1 KiB
Python
126 lines
5.1 KiB
Python
from spack import *
|
|
import glob, string
|
|
|
|
class Mfem(Package):
|
|
"""Free, lightweight, scalable C++ library for finite element methods."""
|
|
|
|
homepage = 'http://www.mfem.org'
|
|
url = 'https://github.com/mfem/mfem'
|
|
|
|
# version('3.1', git='https://github.com/mfem/mfem.git',
|
|
# commit='dbae60fe32e071989b52efaaf59d7d0eb2a3b574')
|
|
|
|
version('3.1', '841ea5cf58de6fae4de0f553b0e01ebaab9cd9c67fa821e8a715666ecf18fc57',
|
|
url='http://goo.gl/xrScXn', expand=False)
|
|
|
|
variant('metis', default=False, description='Activate support for metis')
|
|
variant('hypre', default=False, description='Activate support for hypre')
|
|
variant('suite-sparse', default=False,
|
|
description='Activate support for SuiteSparse')
|
|
variant('mpi', default=False, description='Activate support for MPI')
|
|
variant('lapack', default=False, description='Activate support for LAPACK')
|
|
variant('debug', default=False, description='Build debug version')
|
|
|
|
depends_on('blas', when='+lapack')
|
|
depends_on('lapack', when='+lapack')
|
|
|
|
depends_on('mpi', when='+mpi')
|
|
depends_on('metis', when='+mpi')
|
|
depends_on('hypre', when='+mpi')
|
|
|
|
depends_on('hypre', when='+hypre')
|
|
|
|
depends_on('metis@4:', when='+metis')
|
|
|
|
depends_on('suite-sparse', when='+suite-sparse')
|
|
depends_on('blas', when='+suite-sparse')
|
|
depends_on('lapack', when='+suite-sparse')
|
|
depends_on('metis@5:', when='+suite-sparse ^suite-sparse@4.5:')
|
|
depends_on('cmake', when='^metis@5:')
|
|
|
|
def check_variants(self, spec):
|
|
if '+mpi' in spec and ('+hypre' not in spec or '+metis' not in spec):
|
|
raise InstallError('mfem+mpi must be built with +hypre ' +
|
|
'and +metis!')
|
|
if '+suite-sparse' in spec and ('+metis' not in spec or
|
|
'+lapack' not in spec):
|
|
raise InstallError('mfem+suite-sparse must be built with ' +
|
|
'+metis and +lapack!')
|
|
if 'metis@5:' in spec and '%clang' in spec and ('^cmake %gcc' not in spec):
|
|
raise InstallError('To work around CMake bug with clang, must ' +
|
|
'build mfem with mfem[+variants] %clang ' +
|
|
'^cmake %gcc to force CMake to build with gcc')
|
|
return
|
|
|
|
def install(self, spec, prefix):
|
|
self.check_variants(spec)
|
|
|
|
options = ['PREFIX=%s' % prefix]
|
|
|
|
if '+lapack' in spec:
|
|
lapack_lib = '-L{0} -llapack -L{1} -lblas'.format(
|
|
spec['lapack'].prefix.lib, spec['blas'].prefix.lib)
|
|
options.extend(['MFEM_USE_LAPACK=YES',
|
|
'LAPACK_OPT=-I%s' % spec['lapack'].prefix.include,
|
|
'LAPACK_LIB=%s' % lapack_lib])
|
|
|
|
if '+hypre' in spec:
|
|
options.extend(['HYPRE_DIR=%s' % spec['hypre'].prefix,
|
|
'HYPRE_OPT=-I%s' % spec['hypre'].prefix.include,
|
|
'HYPRE_LIB=-L%s' % spec['hypre'].prefix.lib +
|
|
' -lHYPRE'])
|
|
|
|
if '+metis' in spec:
|
|
metis_lib = '-L%s -lmetis' % spec['metis'].prefix.lib
|
|
if spec['metis'].satisfies('@5:'):
|
|
metis_str = 'MFEM_USE_METIS_5=YES'
|
|
else:
|
|
metis_str = 'MFEM_USE_METIS_5=NO'
|
|
options.extend([metis_str,
|
|
'METIS_DIR=%s' % spec['metis'].prefix,
|
|
'METIS_OPT=-I%s' % spec['metis'].prefix.include,
|
|
'METIS_LIB=%s' % metis_lib])
|
|
|
|
if '+mpi' in spec: options.extend(['MFEM_USE_MPI=YES'])
|
|
|
|
if '+suite-sparse' in spec:
|
|
ssp = spec['suite-sparse'].prefix
|
|
ss_lib = '-L%s' % ssp.lib
|
|
ss_lib += (' -lumfpack -lcholmod -lcolamd -lamd -lcamd' +
|
|
' -lccolamd -lsuitesparseconfig')
|
|
|
|
no_librt_archs = ['darwin-i686', 'darwin-x86_64']
|
|
no_rt = any(map(lambda a: spec.satisfies('='+a), no_librt_archs))
|
|
if not no_rt: ss_lib += ' -lrt'
|
|
ss_lib += (' ' + metis_lib + ' ' + lapack_lib)
|
|
|
|
options.extend(['MFEM_USE_SUITESPARSE=YES',
|
|
'SUITESPARSE_DIR=%s' % ssp,
|
|
'SUITESPARSE_OPT=-I%s' % ssp.include,
|
|
'SUITESPARSE_LIB=%s' % ss_lib])
|
|
|
|
if '+debug' in spec: options.extend(['MFEM_DEBUG=YES'])
|
|
|
|
# Dirty hack to cope with URL redirect
|
|
tgz_file = string.split(self.url,'/')[-1]
|
|
tar = which('tar')
|
|
tar('xzvf', tgz_file)
|
|
cd(glob.glob('mfem*')[0])
|
|
# End dirty hack to cope with URL redirect
|
|
|
|
make('config', *options)
|
|
make('all')
|
|
|
|
# Run a small test before installation
|
|
args = ['-m', join_path('data','star.mesh'), '--no-visualization']
|
|
if '+mpi' in spec:
|
|
Executable(join_path(spec['mpi'].prefix.bin,
|
|
'mpirun'))('-np',
|
|
'4',
|
|
join_path('examples','ex1p'),
|
|
*args)
|
|
else:
|
|
Executable(join_path('examples', 'ex1'))(*args)
|
|
|
|
make('install')
|