diff --git a/README.md b/README.md index a45c3b8..2f90413 100644 --- a/README.md +++ b/README.md @@ -1,186 +1,197 @@ Tamaas --- A blazingly fast rough contact library ================================================= Tamaas is a C++/Python library that implements a number of numerical methods based on integral equations to efficiently solve contact problems with rough surfaces. The word تماس (tamaas) means "contact" in Arabic and Farsi. +## Quick Start + +If you have a Linux system with Python 3.7+ installed, you can simply run `pip3 +install tamaas`. Note however that there may be incompatibilities between Linux +distributions (the PyPI package was built on Debian Buster), so if you encounter +an issue, please compile from source. + ## Dependencies -Here is a list of dependencies for Tamaas: +Here is a list of dependencies to compile Tamaas: - a //C++ compiler// with full //C++14// and //OpenMP// support - [SCons](https://scons.org/) (python build system) - [FFTW3](http://www.fftw.org/) compiled with //OpenMP// support - [boost](https://www.boost.org/) (preprocessor) - [thrust](https://github.com/thrust/thrust) (1.9.2+) - [python 3+](https://www.python.org/) (probably works with python 2, but it is not tested) with [numpy](https://numpy.org/) - [pybind11](https://github.com/pybind/pybind11) (included as submodule) - [expolit](https://c4science.ch/source/expolit/) (included as submodule) Optional dependencies are: - [scipy](https://scipy.org) (for nonlinear solvers) - [uvw](https://pypi.org/project/uvw/) (for dumpers) - [googletest](https://github.com/google/googletest) and [pytest](https://docs.pytest.org/en/latest/) (for tests) - [Doxygen](http://doxygen.nl/) and [Sphinx](https://www.sphinx-doc.org/en/stable/) (for documentation) Note that a Debian distribution should have the right packages for all these dependencies (they package the right version of thrust extracted from CUDA in `stretch-backports non-free` and `buster non-free`). ## Compiling You should first clone the git submodules that are dependencies to tamaas (expolit, pybind11 and googletest): git submodule update --init --recursive The build system uses SCons. In order to compile Tamaas with the default options: scons After compiling a first time, you can edit the compilation options in the file `build-setup.conf`, or alternatively supply the options directly in the command line: scons option=value [...] To get a list of //all// build options and their possible values, you can run `scons -h`. You can run `scons -H` to see the SCons-specific options (among them `-j n` executes the build with `n` threads and `-c` cleans the build). Note that the build is aware of the `CXX` and `CXXFLAGS` environment variables. ## Installing Before you can import tamaas in python, you need to install the python package in some way. ### Using pip You have two choices to install tamaas: - An out-of-repository installation to a given prefix (e.g. `/usr/local`, or a python virtual environment) - A development installation to `~/.local` which links to the build directory The former is simply achieved with: scons prefix=/your/prefix install # Equivalent to (if you build in release) install build-release/src/libTamaas.so* /your/prefix/lib pip3 install --prefix /your/prefix build-release/python The compiled parts of the python module should automatically know where to find the Tamaas shared library, so no need to tinker with `LD_LIBRARY_PATH`. The second installation choice is equally simple: scons dev # Equivalent to pip3 install --user -e build-release/python You can check that everything is working fine with: python3 -c 'import tamaas; print(tamaas)' ### Using environment variables (not recommended) You can source (e.g. in your `~/.bashrc` file) the file `build-release/tamaas_environment.sh` to modify the `PYTHONPATH` and `LD_LIBRARY_PATH` environment variables. This is however not recommended because these variables may conflict in a python virtual environment (i.e. if you use `virtualenv` with tamaas). ## Tests To run tests, make sure to have [pytest](https://docs.pytest.org/en/latest/) installed and run `scons test` if you have compiled Tamaas with tests activated (`scons build_tests=True use_googletest=True`). ## Documentation The latest documentation is available on -[ReadTheDocs](https://tamaas.readthedocs.io/en/latest/)! +[ReadTheDocs](https://tamaas.readthedocs.io/en/latest/)! Note however that due +to technical limitations, the Python API documentation is not available online. +You'll need to compile the documentation locally. -To build the documentation, activate the `build_doc` option. Make sure you have +To build the documentation, activate the `build_doc` option and run `scons doc`. +Make sure you have [sphinx-rtd-theme](https://pypi.org/project/sphinx-rtd-theme/) and [breath](https://pypi.org/project/breathe/) installed. The compiled indexes for the doxygen C++ API and Sphinx documentation can be found in `doc/build/{doxygen,sphinx}/html/index.html`. Beware however that manually compiling documentation leads to a lot of warnings. ## Examples Example simulations can be found in the `examples/` directory. There is no guarantee that the examples in `examples/legacy/` all work however. - `rough_contact.py` shows a typical normal rough contact simulation - `adhesion.py` shows how you can derive some classes from Tamaas in python, here to implement a custom adhesion potential - `plasticity.py` computes an elastoplastic Hertz simulation and dumps the result in `examples/paraview/` in VTK format - `stresses.py` shows how you can compute stresses from a boundary traction distribution - the scripts in `pipe_tools` allow to execute elastic contact simulations without the need to code a custom script (see documentation for more details) ## Contributing Contributions to Tamaas are welcome! Please follow the guidelines below. ### Report an issue If you have an account on [c4science](https://c4science.ch), you can [submit an issue](https://c4science.ch/maniphest/task/edit/?owner=frerot&projectPHIDs=tamaas&view=public). All open issues are visible on the [workboard](https://c4science.ch/project/board/2036/), and the full list of issues is available [here](https://c4science.ch/maniphest/query/1jDBkIDDxCAP/). ### Submit a patch / pull-request C4Science runs [Phabricator](https://www.phacility.com/phabricator/) to host the code. The procedure to submit changes to repositories is described in this [guide](https://secure.phabricator.com/book/phabricator/article/arcanist_diff/). In a nutshell: ```lang=bash # Make changes git commit # Any number of times arc diff # Pushes all new commits for review # Wait for review... -arc land # Once the changes are accepted ``` ## Citing -Please cite Tamaas as: +Tamaas is the result of a science research project. To give proper credit to +Tamaas and the researchers who have developed the numerical methods that it +implements, please cite Tamaas as: Frérot, L., Anciaux, G., Rey, V., Pham-Ba, S., J.-F., Molinari (2019). Tamaas, a high-performance library for periodic rough surface contact, [doi:10.5281/zenodo.3479237](https://doi.org/10.5281/zenodo.3479237). If you use the elastic-plastic contact capabilities of Tamaas, please cite: Frérot, L., Bonnet, M., Molinari, J.-F. & Anciaux, G. A Fourier-accelerated volume integral method for elastoplastic contact. Computer Methods in Applied Mechanics and Engineering 351, 951–976 (2019) [doi:10.1016/j.cma.2019.04.006](https://doi.org/10.1016/j.cma.2019.04.006). If you use the adhesive contact capabilities of Tamaas, please cite: Rey, V., Anciaux, G. & Molinari, J.-F. Normal adhesive contact on rough surfaces: efficient algorithm for FFT-based BEM resolution. Comput Mech 1–13 (2017) [doi:10.1007/s00466-017-1392-5](https://doi.org/10.1007/s00466-017-1392-5). ## License Tamaas is distributed under the terms of the [GNU Affero General Public License v3.0](https://www.gnu.org/licenses/agpl.html). diff --git a/SConstruct b/SConstruct index defa813..4668e7f 100644 --- a/SConstruct +++ b/SConstruct @@ -1,441 +1,438 @@ # -*- mode:python; coding: utf-8 -*- # vim: set ft=python: # @file # @section LICENSE # # Copyright (©) 2016-2020 EPFL (École Polytechnique Fédérale de Lausanne), # Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published # by the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # ------------------------------------------------------------------------------ # Imports # ------------------------------------------------------------------------------ from __future__ import print_function import os import SCons from os.path import join, abspath # Import below not strictly necessary, but good for pep8 from SCons.Script import ( EnsurePythonVersion, EnsureSConsVersion, Help, Environment, Variables, EnumVariable, PathVariable, BoolVariable, Split, SConscript, Export, Dir ) from version import get_git_subst from detect import ( FindFFTW, FindBoost, FindThrust, FindCuda, FindExpolit, FindPybind11 ) # ------------------------------------------------------------------------------ EnsurePythonVersion(2, 7) EnsureSConsVersion(2, 4) # ------------------------------------------------------------------------------ tamaas_info = dict( - version="2.1.1", + version="2.1.2", authors=[ u'Lucas Frérot', 'Guillaume Anciaux', 'Valentine Rey', 'Son Pham-Ba', u'Jean-François Molinari' ], maintainer=u'Lucas Frérot', - email='lucas.frerot@epfl.ch', + email='lucas.frerot@protonmail.com', copyright=u"Copyright (©) 2016-2020 EPFL " + u"(École Polytechnique Fédérale de Lausanne), " + u"Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)" ) # ------------------------------------------------------------------------------ def detect_dependencies(env): """Detect all dependencies""" FindFFTW(env, ['omp'], precision=env['real_type']) FindBoost(env, ['boost/preprocessor/seq.hpp']) FindExpolit(env) thrust_var = 'THRUST_ROOT' # Take cuda version of thrust if available if 'CUDA_ROOT' in env['ENV']: thrust_var = 'CUDA_ROOT' FindThrust(env, env['backend'], thrust_var) # Activate cuda if needed if env['backend'] == 'cuda': FindCuda(env) if env['build_python']: FindPybind11(env) # ------------------------------------------------------------------------------ # Main compilation # ------------------------------------------------------------------------------ # Compilation colors colors = { 'cyan': '\033[96m', 'purple': '\033[95m', 'blue': '\033[94m', 'green': '\033[92m', 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' } # Inherit all environment variables (for CXX detection, etc.) main_env = Environment( ENV=os.environ, ) # Set tamaas information for k, v in tamaas_info.items(): main_env[k] = v main_env['COLOR_DICT'] = colors # Compiler detection compiler_default = os.getenv('CXX', 'g++') # Build variables vars = Variables('build-setup.conf') vars.AddVariables( EnumVariable('build_type', 'Build type', 'release', allowed_values=('release', 'profiling', 'debug'), ignorecase=2), EnumVariable('backend', 'Thrust backend', 'omp', allowed_values=('omp', 'tbb'), # allowed_values=('omp', 'cuda'), ignorecase=2), EnumVariable('sanitizer', 'Sanitizer type', 'none', allowed_values=('none', 'memory', 'leaks', 'address'), ignorecase=2), PathVariable('prefix', 'Prefix where to install', '/usr/local'), # Dependencies paths PathVariable('FFTW_ROOT', 'FFTW custom path', os.getenv('FFTW_ROOT', ''), PathVariable.PathAccept), PathVariable('THRUST_ROOT', 'Thrust custom path', os.getenv('THRUST_ROOT', ''), PathVariable.PathAccept), PathVariable('BOOST_ROOT', 'Boost custom path', os.getenv('BOOST_ROOT', ''), PathVariable.PathAccept), PathVariable('CUDA_ROOT', 'Cuda custom path', os.getenv('CUDA_ROOT', ''), PathVariable.PathAccept), # Dependencies provided as submodule get different default PathVariable('GTEST_ROOT', 'Googletest custom path', os.getenv('GTEST_ROOT', '#third-party/googletest/googletest'), PathVariable.PathAccept), PathVariable('PYBIND11_ROOT', 'Pybind11 custom path', os.getenv('PYBIND11_ROOT', '#third-party/pybind11/include'), PathVariable.PathAccept), PathVariable('EXPOLIT_ROOT', 'Expolit custom path', os.getenv('EXPOLIT_ROOT', '#third-party/expolit/include'), PathVariable.PathAccept), # Executables ('CXX', 'Compiler', compiler_default), ('py_exec', 'Python executable', 'python3'), # Compiler flags ('CXXFLAGS', 'C++ compiler flags', os.getenv('CXXFLAGS', "")), # Compile legacy code BoolVariable('legacy_bem', 'Compile legacy BEM code', False), # Cosmetic BoolVariable('verbose', 'Activate verbosity', False), BoolVariable('color', 'Color the non-verbose compilation output', False), # Tamaas components BoolVariable('build_doc', 'Build documentation', False), BoolVariable('build_tests', 'Build test suite', False), BoolVariable('build_python', 'Build python wrapper', True), # Dependencies BoolVariable('use_googletest', 'Build tests using GTest', False), - # Strip binary of extra info + # Distribution options BoolVariable('strip_info', 'Strip binary of added information', False), + BoolVariable('packaging_setup', "Modify setup.py and python wrapper " + "RPATHs for packaging to PyPI (maintainer only)", False), # Type variables EnumVariable('real_type', 'Type for real precision variables', 'double', allowed_values=('double', 'long double')), EnumVariable('integer_type', 'Type for integer variables', 'int', allowed_values=('int', 'long')), ) # Set variables of environment vars.Update(main_env) help_text = vars.GenerateHelpText(main_env) help_text += """ Commands: scons [build] [options]... Compile Tamaas (and additional modules/tests) scons install [prefix=/your/prefix] [options]... Install Tamaas to prefix scons dev Install symlink to Tamaas python module (useful to development purposes) scons test Run tests with pytest scons doc Compile documentation with Doxygen and Sphinx+Breathe scons archive Create a gzipped archive from source """ # noqa Help(help_text) # Save all options, not just those that differ from default with open('build-setup.conf', 'w') as setup: for option in vars.options: setup.write("# " + option.help + "\n") setup.write("{} = '{}'\n".format(option.key, main_env[option.key])) main_env['should_configure'] = \ not main_env.GetOption('clean') and not main_env.GetOption('help') build_type = main_env['build_type'] build_dir = 'build-' + main_env['build_type'] main_env['build_dir'] = build_dir if main_env['should_configure']: print("Building in " + build_dir) +if main_env['packaging_setup']: + main_env['strip_info'] = True + verbose = main_env['verbose'] # Remove colors if not set if not main_env['color']: for key in colors: colors[key] = '' if not verbose: main_env['CXXCOMSTR'] = main_env['SHCXXCOMSTR'] = \ u'{0}[Compiling ($SHCXX)] {1}$SOURCE'.format(colors['green'], colors['end']) main_env['LINKCOMSTR'] = main_env['SHLINKCOMSTR'] = \ u'{0}[Linking] {1}$TARGET'.format(colors['purple'], colors['end']) main_env['PRINT_CMD_LINE_FUNC'] = pretty_cmd_print # Include paths main_env.AppendUnique(CPPPATH=['#/src', '#/src/core', '#/src/bem', '#/src/surface', '#/src/python', '#/src/percolation', '#/src/model', '#/src/model/elasto_plastic', '#/src/solvers', '#/src/gpu', '#/python']) # Changing the shared object extension main_env['SHOBJSUFFIX'] = '.o' # Back to gcc if cuda is activated if main_env['backend'] == "cuda" and "g++" not in main_env['CXX']: raise SCons.Errors.StopError('GCC should be used when compiling with CUDA') # OpenMP flags - compiler dependent omp_flags = { "g++": ["-fopenmp"], "clang++": ["-fopenmp"], "icpc": ["-qopenmp"] } def cxx_alias(cxx): for k in omp_flags.keys(): if k in cxx: return k raise SCons.Errors.StopError('Unsupported compiler: ' + cxx) cxx = cxx_alias(main_env['CXX']) main_env['CXXFLAGS'] = Split(main_env['CXXFLAGS']) main_env.AppendUnique(CXXFLAGS='-std=c++14 -Wall -Wextra -pedantic'.split()) # Append openmp flags regardless of backend for fftw_omp main_env.AppendUnique(CXXFLAGS=omp_flags[cxx]) main_env.AppendUnique(LINKFLAGS=omp_flags[cxx]) # Correct bug in clang? if main_env['backend'] == 'omp' and cxx == "clang++": main_env.AppendUnique(LIBS=["atomic"]) elif main_env['backend'] == 'tbb': main_env.AppendUnique(LIBS=['tbb']) # Force deactivate legacy when using intel # Intel does not like old openmp loops if cxx == 'icpc' and main_env['legacy_bem']: print("Using intel compiler => deactivating legacy code") main_env['legacy_bem'] = False # Flags and options if main_env['build_type'] == 'debug': main_env.AppendUnique(CPPDEFINES=['TAMAAS_DEBUG']) # Define the scalar types main_env.AppendUnique(CPPDEFINES={'REAL_TYPE': '${real_type}', 'INT_TYPE': '${integer_type}'}) # Compilation flags cxxflags_dict = { "debug": Split("-g -O0"), "profiling": Split("-g -O3 -fno-omit-frame-pointer"), "release": Split("-O3") } -# Link flags for shared libs -shlinkflags_dict = { - "debug": [], - "profiling": Split("-g -O3 -fno-omit-frame-pointer"), - "release": [] -} - if main_env['sanitizer'] != 'none': if main_env['backend'] == 'cuda': raise SCons.Errors.StopError( "Sanitizers with cuda are not yet supported!") cxxflags_dict[build_type].append('-fsanitize=${sanitizer}') - shlinkflags_dict[build_type].append('-fsanitize=${sanitizer}') main_env.AppendUnique(CXXFLAGS=cxxflags_dict[build_type]) -main_env.AppendUnique(SHLINKFLAGS=shlinkflags_dict[build_type]) -main_env.AppendUnique(LINKFLAGS=shlinkflags_dict[build_type]) +main_env.AppendUnique(SHLINKFLAGS=cxxflags_dict[build_type]) +main_env.AppendUnique(LINKFLAGS=cxxflags_dict[build_type]) if main_env['should_configure']: detect_dependencies(main_env) # Writing information file main_env.Tool('textfile') main_env['SUBST_DICT'] = get_git_subst() # Empty values if requested if main_env['strip_info']: for k in main_env['SUBST_DICT']: main_env['SUBST_DICT'][k] = "" # Substitution of environment file main_env['SUBST_DICT'].update({ '@build_type@': '$build_type', '@build_dir@': abspath(build_dir), }) # Environment file content env_content = """export PYTHONPATH=@build_dir@/python:$$PYTHONPATH export LD_LIBRARY_PATH=@build_dir@/src:$$LD_LIBRARY_PATH """ # Writing environment file env_file = main_env.Textfile(join(build_dir, 'tamaas_environment.sh'), env_content) # Building sub-directories def subdir(dir): return SConscript(join(dir, 'SConscript'), variant_dir=join(build_dir, dir), duplicate=True) # Building Tamaas library Export('main_env') subdir('src') build_targets = ['build-cpp', env_file] install_targets = ['install-lib'] # Building Tamaas extra components for dir in ['python', 'tests']: if main_env['build_{}'.format(dir)] and not main_env.GetOption('help'): subdir(dir) build_targets.append('build-{}'.format(dir)) # Building API + Sphinx documentation if requested if main_env['build_doc']: doc_env = main_env.Clone() doc = doc_env.Command('#.phony_doc', '', 'make -C {doc} clean && make -C {doc}' .format(doc=Dir('#/doc'))) if doc_env['build_python']: doc_env.PrependENVPath('PYTHONPATH', doc_env.subst('../${build_dir}/python')) doc_env.Depends(doc, 'build-python') main_env.Alias('doc', doc) else: dummy_command(main_env, 'doc', 'Command "doc" does not do anything' ' without documentation activated ("build_doc=True")') # Define dummy dev command when python is deactivated if not main_env['build_python']: dummy_command(main_env, 'dev', 'Command "dev" does not do anything' + ' without python activated ("build_python=True")') else: install_targets.append('install-python') # Define dummy test command when tests are deactivated if not main_env['build_tests']: dummy_command(main_env, 'test', 'Command "test" does not do anything' + ' without tests activated ("build_tests=True")') # Definition of target aliases, a.k.a. sub-commands main_env.Alias('build', build_targets) # Define proper install targets main_env.Alias('install', install_targets) # Default target is to build stuff main_env.Default('build') # Building a tar archive archive = main_env.Command( '../tamaas-{}.tar.gz'.format(main_env['version']), '', ('tar --exclude-vcs --exclude-vcs-ignores ' '--exclude=third-party/googletest ' '--exclude=third-party/pybind11 ' '--exclude=joss ' '-czf $TARGET .'), ) main_env.Alias('archive', archive) diff --git a/python/MANIFEST.in b/python/MANIFEST.in index e61422f..3adb996 100644 --- a/python/MANIFEST.in +++ b/python/MANIFEST.in @@ -1 +1,2 @@ include tamaas/_tamaas*.so +include tamaas/libTamaas.so* diff --git a/python/SConscript b/python/SConscript index ed088af..254c6c9 100644 --- a/python/SConscript +++ b/python/SConscript @@ -1,153 +1,159 @@ # -*- mode:python; coding: utf-8 -*- # vim: set ft=python: # @file # @section LICENSE # # Copyright (©) 2016-2020 EPFL (École Polytechnique Fédérale de Lausanne), # Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published # by the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . from __future__ import print_function from os.path import abspath, join from SCons.Script import Import, Split, Copy, Dir Import('main_env') # Pybind11 wrapper env_pybind = main_env.Clone(SHLIBPREFIX='') # Remove pedantic warnings cxx_flags = env_pybind['CXXFLAGS'] try: del cxx_flags[cxx_flags.index('-pedantic')] except ValueError: pass env_pybind.Tool(pybind11) pybind_sources = Split(""" tamaas_module.cpp wrap/core.cpp wrap/percolation.cpp wrap/surface.cpp wrap/model.cpp wrap/solvers.cpp wrap/compute.cpp wrap/test_features.cpp """) # Adding legacy wrap code if env_pybind['legacy_bem']: env_pybind.AppendUnique(CPPDEFINES=['LEGACY_BEM']) pybind_sources += ["wrap/bem.cpp"] # Setting paths to find libTamaas -env_pybind.AppendUnique( - LIBPATH=[Dir(join('#${build_dir}', 'src'))], - RPATH=[ - "'$$$$ORIGIN/../../src'", #< path to lib in build_dir - "'$$$$ORIGIN/../../..'", #< path to lib in install prefix -]) +env_pybind.AppendUnique(LIBPATH=[Dir(join('#${build_dir}', 'src'))]) + +if env_pybind['packaging_setup']: + env_pybind.AppendUnique(RPATH=[ + "'$$$$ORIGIN'", #< path to lib in python module (install from pypi) + ]) +else: + env_pybind.AppendUnique(RPATH=[ + "'$$$$ORIGIN/../../src'", #< path to lib in build_dir + "'$$$$ORIGIN/../../..'", #< path to lib in install prefix + ]) # Building the pybind library tamaas_wrap = env_pybind.Pybind11Module( target='tamaas/_tamaas', source=pybind_sources, LIBS=['Tamaas'], ) # For some reason link happens too early Import('libTamaas') env_pybind.Depends(tamaas_wrap, libTamaas) # Copying the __init__.py file with extra python classes copy_env = env_pybind.Clone() # Copying additional python files python_files = """ compute.py dumpers/__init__.py dumpers/_helper.py nonlinear_solvers/__init__.py """.split() targets = [tamaas_wrap] targets += [ copy_env.Command(join('tamaas', f), join(abspath(str(Dir('#python/tamaas'))), f), Copy("$TARGET", "$SOURCE")) for f in python_files ] targets.append(copy_env.Command('MANIFEST.in', '#python/MANIFEST.in', Copy("$TARGET", "$SOURCE"))) subst_env = env_pybind.Clone( SUBST_DICT={ '@version@': '$version', '@authors@': str(copy_env['authors']), '@email@': '$email', + '@packaging_setup@': '${packaging_setup}', # TODO change when issue with unicode fixed # '@copyright@': '$copyright', # '@maintainer@': '$maintainer', } ) subst_env.Tool('textfile') targets.append(subst_env.Substfile('setup.py.in')) targets.append(subst_env.Substfile('tamaas/__init__.py.in')) # Defining alias for python builds main_env.Alias('build-python', targets) # Checking if we can use pip to install (more convenient for end-user) conf = Configure(main_env, custom_tests={'CheckPythonModule': CheckPythonModule}) has_pip = conf.CheckPythonModule('pip') install_env = conf.Finish() # Current build directory install_env['PYDIR'] = Dir('.') # Setting command line for installation if has_pip: install_env['PYINSTALLCOM'] = '${py_exec} -m pip install -U $PYOPTIONS .' install_env['PYDEVELOPCOM'] = \ '${py_exec} -m pip install $PYOPTIONS -e .[solvers,dumpers]' else: install_env['PYINSTALLCOM'] = '${py_exec} setup.py install $PYOPTIONS' install_env['PYDEVELOPCOM'] = '${py_exec} setup.py develop $PYOPTIONS' install_env['py_version'] = get_python_version(install_env) install_env.PrependENVPath( 'PYTHONPATH', install_env.subst('${prefix}/lib/python${py_version}/site-packages')) # Specify install target python_install = install_env.Command( join('$prefix', 'dummy_target'), targets, install_env['PYINSTALLCOM'], PYOPTIONS='--prefix ${prefix}', chdir=install_env['PYDIR']) python_install_dev = install_env.Command( join('$prefix', 'dummy_target_local'), targets, install_env['PYDEVELOPCOM'], PYOPTIONS='--user', chdir=install_env['PYDIR']) main_env.Alias('install-python', python_install) main_env.Alias('dev', python_install_dev) diff --git a/python/setup.py.in b/python/setup.py.in index cb35335..bf0a978 100644 --- a/python/setup.py.in +++ b/python/setup.py.in @@ -1,27 +1,93 @@ import setuptools +import shutil import sysconfig import os +long_description = """ +# Tamaas — A fast rough contact library + +[![status](https://joss.theoj.org/papers/86903c51f3c66964eef7776d8aeaf17d/status.svg)](https://joss.theoj.org/papers/86903c51f3c66964eef7776d8aeaf17d) + +Tamaas (from تماس meaning “contact” in Arabic and Farsi) is a +high-performance rough-surface periodic contact code based on boundary and +volume integral equations. The clever mathematical formulation of the underlying +numerical methods allows the use of the fast-Fourier Transform, a great help in +achieving peak performance: Tamaas is consistently two orders of magnitude +faster (and lighter) than traditional FEM! Tamaas is aimed at researchers and +practitioners wishing to compute realistic contact solutions for the study of +interface phenomena. + +## Disclaimer + +This package is intended for ease of installation for Linux platforms, but comes +with NO WARRANTY of compatibility. If you experience any issue, please install +Tamaas from [source](https://c4science.ch/source/tamaas/). We provide a Docker +image for non-Linux systems. This package contains unsigned binary blobs: if you +are concerned about security, please build Tamaas from source (the commits are +signed). + +Tamaas is the result of a science research project. To give proper credit to +Tamaas and the researchers who have developed the numerical methods that it +implements, please cite the [JOSS +paper](https://joss.theoj.org/papers/86903c51f3c66964eef7776d8aeaf17d) and the +appropriate references therein. + +## Dependencies + +Essentials: + +- FFTW with OpenMP support (needs to be installed separately, + e.g. with your system's package manager) +- Numpy + +Optional: + +- Scipy (for non-linear solvers) +- UVW (for dumpers) +- h5py (for dumpers) +- netCDF4 (for dumpers) + +To install with all dependencies (except FFTW), run ``pip install +tamaas[solvers,dumpers]``. + +## Documentation + +Documentation can be found on [tamaas.readthedocs.io](https://tamaas.readthedocs.io/en/latest/). +""" + +version = "@version@" +major = version.split('.')[0] + +if @packaging_setup@: + shutil.copyfile('../../README.md', 'README.md') + shutil.copyfile('../src/libTamaas.so.{}'.format(version), + 'tamaas/libTamaas.so.{}'.format(major)) + setuptools.setup( name="tamaas", version="@version@", packages=setuptools.find_packages(), include_package_data=True, - author=@authors@, + author=', '.join(@authors@), author_email="@email@", - description='A fast rough contact library', + description='A fast library for periodic elastic ' + 'and elasto-plastic rough contact', + long_description=long_description, + long_description_content_type="text/markdown", url="https://c4science.ch/project/view/2036/", install_requires=['numpy'], extras_require={ "dumpers": ['uvw', 'h5py', 'netCDF4'], "solvers": ['scipy'], }, classifiers=[ "Intended Audience :: Science/Research", "License :: OSI Approved :: GNU Affero General Public License v3", "Programming Language :: C++", "Programming Language :: Python :: 3", "Topic :: Scientific/Engineering", + "Intended Audience :: Science/Research", + "Operating System :: POSIX :: Linux", ] )