diff --git a/README.md b/README.md index 424f78b..7e02f79 100644 --- a/README.md +++ b/README.md @@ -1,111 +1,187 @@ 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. +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. ## Dependencies Here is a list of dependencies for Tamaas: - a //C++ compiler// with full //C++14// and //OpenMP// support -- //SCons// (python build system) -- //FFTW3// compiled with //OpenMP// support -- //boost// (preprocessor) -- //thrust// (1.9.2+) -- //python 3+// (probably works with python 2, but it is not tested) with //numpy// -- //pybind11// (included as submodule) -- //expolit// (included as submodule) +- [//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// (for nonlinear solvers) -- //uvw// (for dumpers) -- //googletest// and //pytest// (for tests) -- //Doxygen// and //Sphinx// (for documentation) +- [//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`). +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): +You should first clone the git submodules that are dependencies to tamaas +(expolit, pybind11 and googletest): - git submodule update --init --recursive + git submodule update --init --recursive -The build system uses SCons. In order to compile Tamaas with the default options: +The build system uses SCons. In order to compile Tamaas with the default +options: - scons + 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: +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 [...] + 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. +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 -Once compiled, you can install the python module with `pip` (preferably in a virtual environment): +Before you can import tamaas in python, you need to install the python package +in some way. - pip install -e build-release/python +### Using pip -Check that everything is working fine with: +You have two choices to install tamaas: - python3 -c 'import tamaas; print(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 + pip install --prefix /your/prefix build-release/python + +Make sure however that `/your/prefix/lib` is in your `LD_LIBRARY_PATH` or is a +standard location, otherwise you may get an `ImportError`. The second +installation choice is equally simple: + + scons dev + + # Equivalent to + pip install --user -e build-release/python + +This time, you should not have to worry about the position of shared libraries. +The python modules knows where to find them in the build directory. 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, execute `pytest build-` if you have compiled Tamaas with tests activated (`scons build_tests=True use_googletest=True`). +To run tests, execute `pytest build-` if you have compiled Tamaas +with tests activated (`scons build_tests=True use_googletest=True`). ## Documentation -Documentation is available on [ReadTheDocs](https://tamaas.readthedocs.io/en/latest/)! +The latest documentation is available on +[ReadTheDocs](https://tamaas.readthedocs.io/en/latest/)! -To build the documentation, activate the `build_doc` option. The compiled indexes for the doxygen C++ API and Sphinx documentation can be found in `doc/build/{doxygen,sphinx}/html/index.html`. +To build the documentation, activate the `build_doc` option. 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. +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) +- `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/). +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: +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: -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). +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). +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). +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). +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 77ce121..b69ed1e 100644 --- a/SConstruct +++ b/SConstruct @@ -1,341 +1,361 @@ # -*- mode:python; coding: utf-8 -*- # vim: set ft=python: # @file # @section LICENSE # # Copyright (©) 2016-19 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 from os.path import join, abspath from version import write_info_file from detect import FindFFTW, FindBoost, FindThrust, FindCuda, FindExpolit # ------------------------------------------------------------------------------ EnsurePythonVersion(2, 7) EnsureSConsVersion(2, 4) +# ------------------------------------------------------------------------------ + +tamaas_info = dict( + version="1.0.0", + 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', + copyright=u"Copyright (©) 2016-20 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) # ------------------------------------------------------------------------------ # 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'), # 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 BoolVariable('strip_info', 'Strip binary of added information', 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(vars.GenerateHelpText(main_env)) # 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'] if main_env['should_configure']: print("Building in " + build_dir) 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['SHCXXCOMSTR'] = \ u'{0}[Compiling ($SHCXX)] {1}$SOURCE'.format(colors['green'], colors['end']) main_env['SHLINKCOMSTR'] = \ u'{0}[Linking] {1}$TARGET'.format(colors['purple'], colors['end']) # 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": main_env['CXX'] = "g++" compiler_aliases = { "c++": "g++", "g++-7": "g++", "g++-6": "g++", "clang++-6.0": "clang++", } def cxx_alias(alias): return compiler_aliases.get(alias, alias) # OpenMP flags - compiler dependent omp_flags = { "g++": ["-fopenmp"], "clang++": ["-fopenmp"], "icpc": ["-qopenmp"] } cxx = cxx_alias(main_env['CXX']) main_env.Append(CXXFLAGS='-std=c++14 -Wall -pedantic') if main_env['backend'] == 'omp': main_env.AppendUnique(CXXFLAGS=omp_flags[cxx]) main_env.AppendUnique(LINKFLAGS=omp_flags[cxx]) # Correct bug in clang? if main_env['CXX'] == "clang++": main_env.AppendUnique(LIBS="atomic") elif main_env['backend'] == 'tbb': main_env.AppendUnique(LIBS=['tbb']) # We have to keep OpenMP for the legacy parts of Tamaas # and for the number of threads given to fftw_omp main_env.AppendUnique(CXXFLAGS=omp_flags[cxx]) main_env.AppendUnique(LINKFLAGS=omp_flags[cxx]) # Flags and options if main_env['build_python']: main_env.AppendUnique(CPPDEFINES=['USE_PYTHON']) if main_env['strip_info']: main_env.AppendUnique(CPPDEFINES=['STRIP_INFO']) # Define the scalar types main_env.AppendUnique(CPPDEFINES={'REAL_TYPE': main_env['real_type'], 'INT_TYPE': main_env['integer_type']}) if main_env['real_type'] == 'long double': main_env.AppendUnique(CPPDEFINES=['LONG_PRECISION']) # Adding compile flags defined in evironment main_env.AppendUnique(CXXFLAGS=Split(os.getenv('CXXFLAGS', ""))) if build_type == 'debug': main_env.AppendUnique(CPPDEFINES=['TAMAAS_DEBUG']) # 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": Split(""), "profiling": Split("-g -O3 -fno-omit-frame-pointer"), "release": [] } if main_env['sanitizer'] != 'none': if main_env['backend'] == 'cuda': print("Sanitizers with cuda are not yet supported!") Exit(1) cxxflags_dict[build_type].append( '-fsanitize={}'.format(main_env['sanitizer'])) shlinkflags_dict[build_type].append( '-fsanitize={}'.format(main_env['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['LIBPATH'] = [abspath(join(build_dir, 'src'))] main_env['RPATH'] = "$LIBPATH" if main_env['should_configure']: detect_dependencies(main_env) # Writing information file write_info_file("src/tamaas_info.cpp", main_env['build_type']) - -def write_env_file(target, source, env): - """Builder to write content to file""" - env_content = """ - export PYTHONPATH=$PYTHONPATH:{0}/python - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:{0}/src - """ - - with open(str(target[0]), 'w') as env_file: - env_file.write(env_content.format(abspath(build_dir))) - - # Saving the env file main_env['gen_print'] = gen_print env_file_env = main_env.Clone( - PRINT_CMD_LINE_FUNC=gen_print("Writing", "cyan", main_env) + PRINT_CMD_LINE_FUNC=gen_print("Writing", "cyan", main_env), + SUBST_DICT={"@build@": abspath(build_dir)}, + tools=['textfile'], ) -# Need to have a command and manage tamaas_environement.sh as target because -# the build directory does not always exist -env_file_env.Command(join(build_dir, 'tamaas_environement.sh'), - None, write_env_file) +# Environment file content +env_content = """ +export PYTHONPATH=$$PYTHONPATH:@build@/python +export LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:@build@/src +""".format(abspath(build_dir)).split('\n') +# Writing environment file +env_file_env.Textfile(join(build_dir, 'tamaas_environment.sh'), env_content) -# Building subdirs + +# 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') # Building Tamaas extra components for dir in ['python', 'tests']: if main_env['build_{}'.format(dir)] and not main_env.GetOption('help'): subdir(dir) # Building API + Sphinx documentation if requested if main_env['build_doc'] and not main_env.GetOption('help'): main_env.Command('dummy_doc_target', '', 'make -C {}'.format(Dir('#/doc'))) + + +main_env.Alias('install', ['install-lib', 'install-python']) +main_env.Alias('dev', 'install-python-local') diff --git a/python/MANIFEST.in b/python/MANIFEST.in new file mode 100644 index 0000000..e61422f --- /dev/null +++ b/python/MANIFEST.in @@ -0,0 +1 @@ +include tamaas/_tamaas*.so diff --git a/python/SConscript b/python/SConscript index bdf86be..f960f51 100644 --- a/python/SConscript +++ b/python/SConscript @@ -1,77 +1,131 @@ # -*- mode:python; coding: utf-8 -*- # vim: set ft=python: # @file # @section LICENSE # # Copyright (©) 2016-19 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 -from SCons.Script import Import, Split, Copy + +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 """) if main_env['CXX'] != 'icpc' and main_env['legacy_bem']: pybind_sources += ["wrap/bem.cpp"] env_pybind.AppendUnique(CPPDEFINES="LEGACY_BEM") # Building the pybind library tamaas_wrap = env_pybind.SharedLibrary( target='tamaas/_tamaas', source=pybind_sources, LIBS=['Tamaas'], RPATH=[abspath('../src')] ) # 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( PRINT_CMD_LINE_FUNC=main_env['gen_print']("Copying", "red", main_env)) -copy_env.Command(Dir('tamaas'), Dir('#python/tamaas'), Copy("$TARGET", "$SOURCE")) -copy_env.Command('setup.py', '#python/setup.py', Copy("$TARGET", "$SOURCE")) + +# Copying additional python files +copy_env.Command('tamaas', '', Mkdir('tamaas')) + +python_files = """ +compute.py +dumpers/__init__.py +dumpers/_helper.py +nonlinear_solvers/__init__.py +""".split() + +targets = [] +for f in python_files: + targets.append( + copy_env.Command(join('tamaas', f), + join(abspath(str(Dir('#python/tamaas'))), f), + Copy("$TARGET", "$SOURCE"))) + +targets.append(copy_env.Command('MANIFEST.in', '#python/MANIFEST.in', + Copy("$TARGET", "$SOURCE"))) + + +subst_env = env_pybind.Clone( + PRINT_CMD_LINE_FUNC=main_env['gen_print']("Generating", "yellow", main_env), + SUBST_DICT={ + '@version@': '$version', + '@authors@': str(copy_env['authors']), + '@email@': '$email', + # 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')) # Cleaning the tamaas python package -main_env.Execute(Delete('tamaas')) +# main_env.Execute(Delete('tamaas')) + +# Specify install target +python_install = main_env.Command(join(main_env['prefix'], 'dummy_target'), + targets, + main_env['py_exec'] + + ' -m pip install --prefix {} {} '.format( + main_env['prefix'], + abspath(str(Dir('.'))))) + +python_install_local = \ + main_env.Command(join(main_env['prefix'], 'dummy_target_local'), + targets, + main_env['py_exec'] + + ' -m pip install --user -e {} '.format( + abspath(str(Dir('.'))))) + +main_env.Alias('install-python', python_install) +main_env.Alias('install-python-local', python_install_local) diff --git a/python/setup.py b/python/setup.py.in similarity index 58% rename from python/setup.py rename to python/setup.py.in index 9e0c3cb..2c15400 100644 --- a/python/setup.py +++ b/python/setup.py.in @@ -1,36 +1,27 @@ import setuptools import sysconfig - -with open("../../README.md", "r") as fh: - long_description = fh.read().replace('lang=', '') +import os setuptools.setup( name="tamaas", - version="1.0.0", + version="@version@", packages=setuptools.find_packages(), - package_data={'tamaas': ['_tamaas.{}'.format( - sysconfig.get_config_vars()['EXT_SUFFIX']) - ]}, - - author=['Lucas Frérot', - 'Guillaume Anciaux', - 'Valentine Rey', - 'Son Pham-Ba'], - author_email="lucas.frerot@epfl.ch", + include_package_data=True, + author=@authors@, + author_email="@email@", description='A fast rough contact library', - long_description=long_description, url="https://c4science.ch/project/view/2036/", install_requires=['numpy'], extra_require={ "VTK": ['uvw'], "FEM": ['akantu'], }, classifiers=( "Intended Audience :: Science/Research", "License :: OSI Approved :: GNU Affero General Public License v3", "Programming Language :: C++", "Programming Language :: Python :: 3", "Topic :: Scientific/Engineering", ) ) diff --git a/python/tamaas/__init__.py b/python/tamaas/__init__.py.in similarity index 83% rename from python/tamaas/__init__.py rename to python/tamaas/__init__.py.in index 7818ba5..d33fef7 100644 --- a/python/tamaas/__init__.py +++ b/python/tamaas/__init__.py.in @@ -1,73 +1,69 @@ # @file # @section LICENSE # # Copyright (©) 2016-19 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 . """ Tamaas is a library dedicated to the fast treatment of rough contact problems. See README.md and examples for guidance as how to use Tamaas. See __authors__, __license__, __copyright__ for extra information about Tamaas. """ -__authors__ = [ - "Guillaume Anciaux ", - "Lucas Frérot ", - "Son Pham-Ba ", - "Valentine Rey ", -] - -__copyright__ = "Copyright (©) 2016-19 EPFL " \ - + "(École Polytechnique Fédérale de Lausanne), " \ - + "Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)" +__version__ = "@version@" +__author__ = @authors@ +# TODO Change copyright when is issue with unicode is found +__copyright__ = u"Copyright (©) 2016-20 EPFL " \ + + u"(École Polytechnique Fédérale de Lausanne), " \ + + u"Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)" __license__ = "AGPLv3" __maintainer__ = "Lucas Frérot" -__email__ = "lucas.frerot@epfl.ch" +__email__ = "@email@" try: from . import _tamaas as _tm # Redefinition of model_type constants (for compatibility) model_type_basic_1d = _tm.model_type.basic_1d model_type_basic_2d = _tm.model_type.basic_2d model_type_surface_1d = _tm.model_type.surface_1d model_type_surface_2d = _tm.model_type.surface_2d model_type_volume_1d = _tm.model_type.volume_1d model_type_volume_2d = _tm.model_type.volume_2d from ._tamaas import * # noqa except ImportError as e: print("Error trying to import _tamaas:\n{}".format(e)) raise e class ParamHelper: """Legacy class to manage parameters/setters/getters""" def __init__(self, obj): self.obj = obj def set(self, params): for key in params: setter_name = 'set' + key try: accessor = getattr(self.obj, setter_name) accessor(params[key]) except Exception: print("Setter '{}({})' does not exist for object {}" .format(setter_name, type(params[key]), self.obj)) diff --git a/src/SConscript b/src/SConscript index 67eb7ca..aecbd15 100644 --- a/src/SConscript +++ b/src/SConscript @@ -1,162 +1,174 @@ # -*- mode:python; coding: utf-8 -*- # vim: set ft=python: # @file # @section LICENSE # # Copyright (©) 2016-19 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 . import os Import('main_env') def prepend(path, list): return [os.path.join(path, x) for x in list] env = main_env.Clone() # Core core_list = """ fft_plan_manager.cpp fftransform.cpp fftransform_fftw.cpp grid.cpp grid_hermitian.cpp statistics.cpp surface.cpp tamaas.cpp legacy_types.cpp loop.cpp computes.cpp logger.cpp """.split() core_list = prepend('core', core_list) if not main_env['strip_info']: core_list.append('tamaas_info.cpp') # Lib roughcontact generator_list = """ surface_generator.cpp surface_generator_filter.cpp surface_generator_filter_fft.cpp surface_generator_random_phase.cpp isopowerlaw.cpp regularized_powerlaw.cpp """.split() generator_list = prepend('surface', generator_list) # Lib PERCOLATION percolation_list = """ flood_fill.cpp """.split() percolation_list = prepend('percolation', percolation_list) # BEM PERCOLATION bem_list = """ bem_kato.cpp bem_polonski.cpp bem_gigi.cpp bem_gigipol.cpp bem_penalty.cpp bem_uzawa.cpp bem_fft_base.cpp bem_functional.cpp bem_meta_functional.cpp elastic_energy_functional.cpp exponential_adhesion_functional.cpp squared_exponential_adhesion_functional.cpp maugis_adhesion_functional.cpp complimentary_term_functional.cpp bem_grid.cpp bem_grid_polonski.cpp bem_grid_kato.cpp bem_grid_teboulle.cpp bem_grid_condat.cpp """.split() bem_list = prepend('bem', bem_list) # Model model_list = """ model.cpp model_factory.cpp model_type.cpp model_template.cpp be_engine.cpp westergaard.cpp elastic_functional.cpp meta_functional.cpp adhesion_functional.cpp volume_potential.cpp kelvin.cpp mindlin.cpp boussinesq.cpp elasto_plastic/isotropic_hardening.cpp elasto_plastic/elasto_plastic_model.cpp elasto_plastic/residual.cpp integration/element.cpp """.split() model_list = prepend('model', model_list) # Solvers solvers_list = """ contact_solver.cpp polonsky_keer_rey.cpp kato_saturated.cpp kato.cpp beck_teboulle.cpp condat.cpp polonsky_keer_tan.cpp ep_solver.cpp epic.cpp """.split() solvers_list = prepend('solvers', solvers_list) # GPU API gpu_list = """ fftransform_cufft.cpp """.split() gpu_list = prepend('gpu', gpu_list) # Assembling total list rough_contact_list = \ core_list + generator_list + percolation_list + model_list + solvers_list # For some reason collapse OMP loops don't compile on intel if env['CXX'] != 'icpc' and env['legacy_bem']: rough_contact_list += bem_list # Adding GPU if needed if env['backend'] == 'cuda': rough_contact_list += gpu_list # Generating dependency files # env.AppendUnique(CXXFLAGS=['-MMD']) # for file_name in rough_contact_list: # obj = file_name.replace('.cpp', '.os') # dep_file_name = file_name.replace('.cpp', '.d') # env.SideEffect(dep_file_name, obj) # env.ParseDepends(dep_file_name) # Adding extra warnings for Tamaas base lib env.AppendUnique(CXXFLAGS=['-Wextra']) -libTamaas = env.SharedLibrary('Tamaas', rough_contact_list) + +# Build library +libTamaas = env.SharedLibrary('Tamaas', + rough_contact_list, + SHLIBVERSION=env['version']) + +# Specify install target to install lib +lib_prefix = os.path.join(env['prefix'], 'lib') +lib_install = env.InstallVersionedLib(target=lib_prefix, + source=libTamaas) +main_env.Alias('install-lib', lib_install) + +# Export target for use in python builds Export('libTamaas')