diff --git a/README.md b/README.md
index e58af7d..87b37ad 100644
--- a/README.md
+++ b/README.md
@@ -1,204 +1,203 @@
Tamaas --- A high-performance library for periodic rough surface contact
========================================================================
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, you can simply run `pip(3) install tamaas`. Note
however that there due to compatibility reasons, this version of Tamaas is not
built with parallel/multi-threading capabilities. So if you want parallelism, or
encounter an issue with the [PyPI package](https://pypi.org/project/tamaas/),
please compile from source.
## Dependencies
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
+- [FFTW3](http://www.fftw.org/)
- [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/)
+- [python 3+](https://www.python.org/) 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:
- an MPI implmentation
-- [FFTW3](http://www.fftw.org/) with MPI support
+- [FFTW3](http://www.fftw.org/) with MPI/threads///OpenMP// support
- [scipy](https://scipy.org) (for nonlinear solvers)
- [uvw](https://pypi.org/project/uvw/),
[netCDF4](https://unidata.github.io/netcdf4-python/netCDF4/index.html#section1),
[h5py](https://www.h5py.org/) (for various 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/)! Note however that due
to technical limitations, the Python API documentation reflects the latest
version of the [PyPI package](https://pypi.org/project/tamaas/), which may be
sligthly out of sync with the master branch.
To build the documentation locally, 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...
```
## Citing
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., & Molinari, J.-F. Tamaas: a
library for elastic-plastic contact of periodic rough surfaces. Journal of Open
Source Software, 5(51), 2121 (2020).
[doi:10.21105/joss.02121](https://doi.org/10.21105/joss.02121)
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 472da6b..e2c8c6f 100644
--- a/SConstruct
+++ b/SConstruct
@@ -1,474 +1,474 @@
# -*- mode:python; coding: utf-8 -*-
# vim: set ft=python:
# @file
# @section LICENSE
#
# Copyright (©) 2016-2021 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 subprocess import check_output
import SCons
from os.path import join, abspath, basename
# 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.2.0",
+ version="2.2.1",
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@protonmail.com',
copyright=u"Copyright (©) 2016-2021 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"""
fftw_comp = {
'omp': ['omp'],
'threads': ['threads'],
'none': [],
}
fftw_components = fftw_comp[env['fftw_threads']]
if main_env['use_mpi']:
fftw_components.append('mpi')
FindFFTW(env, fftw_components, 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',
'gray': '\033[38;5;8m',
'orange': '\033[38;5;208m',
'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
# 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=('cpp', 'omp', 'tbb'),
ignorecase=2),
EnumVariable('fftw_threads', 'Threads FFTW library preference', 'omp',
allowed_values=('omp', 'threads', 'none'),
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', os.getenv('CXX', 'g++')),
('MPICXX', 'MPI Compiler wrapper', os.getenv('MPICXX', 'mpicxx')),
('py_exec', 'Python executable', 'python3'),
# Compiler flags
('CXXFLAGS', 'C++ compiler flags', os.getenv('CXXFLAGS', "")),
# 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),
BoolVariable('use_mpi', 'Builds multi-process parallelism', False),
# Distribution options
BoolVariable('strip_info', 'Strip binary of added information', False),
BoolVariable('build_static_lib', "Build a static libTamaas", 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(main_env.subst("Build type: ${build_type}, Backend: ${backend}, "
"FFTW threads: ${fftw_threads}, MPI: ${use_mpi}"))
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['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['ARCOMSTR'] = u'{}[Ar]{} $TARGET'.format(colors['purple'],
colors['end'])
main_env['RANLIBCOMSTR'] = \
u'{}[Randlib]{} $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/mpi',
'#/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'])
# Setting main compilation flags
main_env['CXXFLAGS'] = Split(main_env['CXXFLAGS'])
main_env.AppendUnique(
CXXFLAGS=Split('-std=c++14 -Wall -Wextra -pedantic'),
CPPDEFINES=['TAMAAS_BACKEND=TAMAAS_BACKEND_{}'.format(
main_env['backend'].upper()
)],
)
# Adding OpenMP flags
if main_env['backend'] == 'omp':
main_env.AppendUnique(CXXFLAGS=omp_flags[cxx])
main_env.AppendUnique(LINKFLAGS=omp_flags[cxx])
else:
main_env.AppendUnique(CXXFLAGS=['-Wno-unknown-pragmas'])
# 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'])
# Manage MPI compiler
if main_env['use_mpi']:
main_env['CXX'] = '$MPICXX'
main_env.AppendUnique(CPPDEFINES=['TAMAAS_USE_MPI'])
main_env.AppendUnique(CXXFLAGS=['-Wno-cast-function-type'])
# Flags and options
if main_env['build_type'] == 'debug':
main_env.AppendUnique(CPPDEFINES=['TAMAAS_DEBUG'])
# Define the scalar types
main_env.AppendUnique(CPPDEFINES={'TAMAAS_REAL_TYPE': '${real_type}',
'TAMAAS_INT_TYPE': '${integer_type}'})
# Compilation flags
cxxflags_dict = {
"debug": Split("-g -O0"),
"profiling": Split("-g -O3 -fno-omit-frame-pointer"),
"release": Split("-O3")
}
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}')
main_env.AppendUnique(CXXFLAGS=cxxflags_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)
# Setting up the python name with version
if main_env['build_python']:
args = (main_env.subst("${py_exec} -c").split()
+ ["from distutils.sysconfig import get_python_version;"
"print(get_python_version())"])
main_env['py_version'] = bytes(check_output(args)).decode()
# 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),
'@build_version@': '$version',
})
# 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 '
'--exclude=".*" '
'-czf $TARGET {}'.format(basename(os.getcwd()))),
chdir='..',
)
main_env.Alias('archive', archive)
diff --git a/doc/sphinx/source/conf.py b/doc/sphinx/source/conf.py
index 69fdd99..1a03e5c 100644
--- a/doc/sphinx/source/conf.py
+++ b/doc/sphinx/source/conf.py
@@ -1,211 +1,210 @@
# -*- coding: utf-8 -*-
#
# Configuration file for the Sphinx documentation builder.
#
# This file does only contain a selection of the most common options. For a
# full list see the documentation:
# http://www.sphinx-doc.org/en/master/config
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import re
# import sys
# sys.path.insert(0, os.path.abspath('.'))
import subprocess
# -- Project information -----------------------------------------------------
project = 'Tamaas'
copyright = "2019-2021, EPFL (École Polytechnique Fédérale de Lausanne)," \
+ " Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)"
-author = 'Lucas Frérot, Guillaume Anciaux, Valentine Rey, Son Pham-ba, ' \
- 'Jean Fraçois Molinari'
+author = 'Lucas Frérot'
# Extracting version info
with open('../../../SConstruct', 'r') as sconstruct:
version_re = re.compile('version=["\']((\d+\.\d+)\.\d+-?(\d+)?)["\']')
match = version_re.search(sconstruct.read())
# The short X.Y version
version = match.group(2)
# The full version, including alpha/beta/rc tags
release = match.group(1)
# -- General configuration ---------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.mathjax',
'sphinx.ext.viewcode',
'sphinx.ext.intersphinx',
'breathe',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['.templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
# The master toctree document.
master_doc = 'index'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = []
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = None
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {}
html_logo = '../../icon.svg'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['.static']
+html_static_path = []
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
#
# The default sidebars (for documents that don't match any pattern) are
# defined by theme itself. Builtin themes are using these templates by
# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
# 'searchbox.html']``.
#
# html_sidebars = {}
# -- Options for HTMLHelp output ---------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'Tamaasdoc'
# -- Options for LaTeX output ------------------------------------------------
latex_engine = 'lualatex'
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'Tamaas.tex', 'Tamaas Documentation',
author, 'manual'),
]
# -- Options for manual page output ------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'tamaas', 'Tamaas Documentation',
[author], 1)
]
# -- Options for Texinfo output ----------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'Tamaas', 'Tamaas Documentation',
author, 'Tamaas', 'One line description of project.',
'Miscellaneous'),
]
# -- Options for Epub output -------------------------------------------------
# Bibliographic Dublin Core info.
epub_title = project
# The unique identifier of the text. This can be a ISBN number
# or the project homepage.
#
# epub_identifier = ''
# A unique identification for the text.
#
# epub_uid = ''
# A list of files that should not be packed into the epub file.
epub_exclude_files = ['search.html']
# -- Extension configuration -------------------------------------------------
# If on RTD build, run doxygen
on_read_the_docs = os.environ.get('READTHEDOCS') == 'True'
if on_read_the_docs:
subprocess.call('cd ../../; mkdir -p build/doxygen; '
+ 'doxygen doxygen/Doxyfile', shell=True)
breathe_projects = {
'tamaas': '../../build/doxygen/xml'
}
breathe_default_project = 'tamaas'
intersphinx_mapping = {
'numpy': ('https://numpy.org/doc/stable/', None),
'scipy': ('https://docs.scipy.org/doc/scipy/reference', None),
}
diff --git a/doc/sphinx/source/examples.rst b/doc/sphinx/source/examples.rst
index 152b0ea..a631d12 100644
--- a/doc/sphinx/source/examples.rst
+++ b/doc/sphinx/source/examples.rst
@@ -1,44 +1,43 @@
Examples
========
The directory ``examples/`` in Tamaas' root repository contains example scripts
dedicated to various aspects of Tamaas:
``statistics.py``
This script generates a rough surface and computes its power spectrum
density as well as its autocorrelation function.
``rough_contact.py``
This script generates a rough surface and solves an adhesion-less elastic
contact problem.
``adhesion.py``
This script solves a rough contact problem with an exponential energy
functional for adhesion. It also shows how to derive an energy functional in
python.
``saturation.py``
This script solves a saturated contact problem (i.e. pseudo-plasticity) with
a rough surface.
``stresses.py``
This script solves an equilibrium problem with an eigenstrain distribution
and a surface traction distribution and writes the output to a VTK file. It
demonstrates how the integral operators that Tamaas uses internally for
elastic-plastic contact can be used directly in Python.
``plasticity.py``
This script solves an elastoplastic Hertz contact problem with three load
steps and writes the result to VTK files.
``pipe_tools/``
-
This directory contains scripts that provide a simple interface to elastic
contact:
- Rough surface generation (``surface``)
- Elastic contact solve (``contact``)
- Plotting contact solution (``plot``)
These can be composed together via standard UNIX pipes. Running them with
the ``-h`` option describes all the options and required arguments.
diff --git a/doc/sphinx/source/model.rst b/doc/sphinx/source/model.rst
index 9ffbd20..7f75ba6 100644
--- a/doc/sphinx/source/model.rst
+++ b/doc/sphinx/source/model.rst
@@ -1,156 +1,165 @@
Model and integral operators
============================
The class :cpp:class:`tamaas::Model` (and its counterpart :py:class:`Model `) is both a central class in Tamaas and one of the simplest. It mostly serves as holder for material properties, fields and integral operators, and apart from a linear elastic behavior does not perform any computation on its own.
Model types
-----------
:cpp:class:`tamaas::Model` has a concrete subclass :cpp:class:`tamaas::ModelTemplate` which implements the model function for a given :cpp:type:`tamaas::model_type`:
:cpp:enumerator:`tamaas::basic_2d`
Model type used in normal frictionless contact: traction and displacement are 2D fields with only one component.
:cpp:enumerator:`tamaas::surface_2d`
Model type used in frictional contact: traction and displacement are 2D fields with three components.
:cpp:enumerator:`tamaas::volume_2d`
Model type used in elastoplastic contact: tractions are the same as with :cpp:enumerator:`tamaas::surface_2d` but the displacement is a 3D field.
The enumeration values suffixed with ``_1d`` are the one dimensional (line contact) counterparts of the above model types. The domain physical dimension and number of components are encoded in the class :cpp:class:`tamaas::model_type_traits`.
Model creation and basic functionality
--------------------------------------
The instanciation of a :py:class:`Model ` is done with the :py:class:`ModelFactory ` class and its :py:func:`createModel ` function::
physical_size = [1., 1.]
discretization = [512, 512]
model = tm.ModelFactory.createModel(tm.model_type.basic_2d, physical_size, discretization)
.. warning::
For models of type ``volume_*d``, the first component of the ``physical_size`` and ``discretization`` arrays corresponds to the depth dimension (:math:`z` in most cases). For example::
tm.ModelFactory.createModel(tm.model_type.basic_2d, [0.3, 1, 1], [64, 81, 81])
creates a model of depth 0.3 and surface size 1\ :superscript:`2`, while the number of points is 64 in depth and 81\ :sup:`2` on the surface. This is done for data contiguity reasons, as we do discrete Fourier transforms in the horizontal plane.
.. note::
If ran in an MPI context, the method :py:meth:`createModel
` expects the *global* system sizes
and discretization of the model.
The properties ``E`` and ``nu`` can be used to set the Young's modulus and Poisson ratio respectively::
model.E = 1
model.nu = 0.3
Fields can be easlily accessed with the ``[]`` operator, similar to Python's dictionaries::
surface_traction = model['traction']
# surface_traction is a numpy array
To know what fields are available, you can call the :py:class:`list` function on
a model (``list(model)``). You can add new fields to a model object with the
``[]`` operator:``model['new_field'] = new_field``, which is convenient for
dumping fields that are computed outside of Tamaas.
.. note::
The fields ``traction`` and ``displacement`` are always registered in models,
and are accessible via :py:attr:`model.traction
` and :py:attr:`model.displacement
`.
A model can also be used to compute stresses from a strain field::
import numpy as np
strain = np.zeros(model.shape + [6]) # Mandel--Voigt notation
stress = np.zeros_like(strain)
model.applyElasticity(stress, strain)
.. tip::
``print(model)`` gives a lot of information about the model: the model type,
shape, registered fields, and more!
Integral operators
------------------
Integral operators are a central part of Tamaas: they are carefully designed for
performance in periodic system. When a :py:class:`Model `
object is used with contact solvers or with a residual object (for plasticty),
the objects using the model register integral operators with the model, so the
user typically does not have to worry about creating integral operators.
Integral operators are accessed through the :py:attr:`operators
` property of a model object. The ``[]``
operator gives access to the operators, and ``list(model.operators)`` gives the
list of registered operators::
# Accessing operator
elasticity = model.operators['hooke']
# Applying operator
elasticity(strain, stress)
# Print all registered operators
print(list(model.operators))
.. note::
At model creation, these operators are automatically registered:
- ``hooke``: Hooke's elasticity law
- ``von_mises``: computes Von Mises stresses
- ``deviatoric``: computes the deviatoric part of a stress tensor
- ``eigenvalues``: computes the eigenvalues of a symetric tensor field
:cpp:class:`Westergaard ` operators are automatically
registered when :py:meth:`solveNeumann
` or :py:meth:`solveDirichlet
` are called.
Model dumpers
-------------
The submodule `tamaas.dumpers` contains a number of classes to save model data into different formats:
:py:class:`UVWDumper `
Dumps a model to `VTK `_ format. Requires the `UVW `_ python package which you can install with pip::
pip install uvw
This dumper is made for visualization with VTK based software like `Paraview `_.
:py:class:`NumpyDumper `
Dumps a model to a compressed Numpy file.
:py:class:`H5Dumper `
- Dumps a model to a compressed `HDF5 `_ file. Requires the `h5py `_ package.
+ Dumps a model to a compressed `HDF5 `_
+ file. Requires the `h5py `_ package. Saves separate
+ files for each dump of a model.
+
+:py:class:`NetCDFDumper `
+ Dumps a model to a compressed `NetCDF
+ `_ file. Requires the `netCDF4
+ `_ package. Saves sequential
+ dumps of a model into a single file, with the ``frame`` dimension containing
+ the model dumps.
The dumpers are initialzed with a basename and the fields that you wish to write to file (optionally you can set ``all_fields`` to ``True`` to dump all fields in the model). By default, each write operation creates a new file in a separate directory (e.g. :py:class:`UVWDumper ` creates a ``paraview`` directory). To write to a specific file you can use the `dump_to_file` method. Here is a usage example::
from tamaas.dumpers import UVWDumper, H5Dumper
# Create dumper
uvw_dumper = UVWDumper('rough_contact_example', 'stress', 'plastic_strain')
# Dump model
uvw_dumper << model
# Or alternatively
model.addDumper(H5Dumper('rough_contact_archive', all_fields=True))
model.addDumper(uvw_dumper)
model.dump()
-The last ``model.dump()`` call will call both dumpers. The resulting files will have the following hierachy::
+The last ``model.dump()`` call will trigger all dumpers. The resulting files will have the following hierachy::
./paraview/rough_contact_example_0000.vtr
./paraview/rough_contact_example_0001.vtr
./hdf5/rough_contact_archive_0000.h5
-.. note::
+.. important::
Currently, only :py:class:`H5Dumper ` supports
parallel output with MPI.
diff --git a/doc/sphinx/source/performance.rst b/doc/sphinx/source/performance.rst
index 5fb0e3f..973c400 100644
--- a/doc/sphinx/source/performance.rst
+++ b/doc/sphinx/source/performance.rst
@@ -1,181 +1,207 @@
Performance
===========
Parallelism
-----------
Tamaas implements shared-memory parallelism using `thrust
-`_ and `OpenMP `_
-[1]_. The number of threads can be controlled with
-the ``OMP_NUM_THREADS`` environment variable, or alternatively to call the
-:func:`initialize ` function with the desired number
-of threads. The default behavior is to use as many threads as available cores on
-the system.
+`_. The Thrust backend can be controlled with
+the following values of the ``backend`` build option:
+
+``omp``
+ Thrust uses its OpenMP backend. The number of threads is controlled by
+ OpenMP.
+
+``cpp``
+ Thurst does not run in threads (i.e. sequential). This is the recommanded
+ option if running multiple MPI tasks.
+
+``tbb``
+ Thrust uses its `TBB
+ `_ backend. Note
+ that this option is not fully supported by Tamaas.
+
+.. tip:: When using the OpenMP or TBB backend, the number of threads can be
+ manually controlled by the :py:func:`initialize `
+ function. When OpenMP is select for the backend, the environment variable
+ ``OMP_NUM_THREADS`` can also be used to set the number of threads.
+
+FFTW has its own system for thread-level parallelism, which can be controlled
+via the ``fftw_threads`` option:
+
+``none``
+ FFTW does not use threads.
+
+``threads``
+ FFTW uses POSIX/Win32 threads for parallelism.
+
+``omp``
+ FFTW uses OpenMP.
+
+.. note:: As with the Thrust backend, the number of threads for FFTW can be
+ controlled with :py:func:`initialize `.
+
+Finally, the boolean variable ``use_mpi`` controls wheter Tamaas is compiled
+with MPI-parallelism. If yes, Tamaas will be linked against ``libfftw3_mpi``
+regardless of the thread model.
Multi-process parallelism
^^^^^^^^^^^^^^^^^^^^^^^^^
Distributed memory parallelism in Tamaas is implemented with `MPI
`_. Due to the bottleneck role of the fast-Fourier
transform in Tamaas' core routines, the data layout of Tamaas is that of `FFTW
`_.
Tamaas is somewhat affected by limitations of FFTW, and MPI only works on
systems with a 2D boundary, i.e. ``basic_2d``, ``surface_2d`` and ``volume_2d``
model types (which are the most important anyways, since rough contact mechanics
can yield different scaling laws in 1D).
MPI support in Tamaas is still experimental, but the following parts are tested:
- Rough surface generation
- Surface statistics computation
- Elastic normal contact
- Elastic-plastic contact (with :py:class:`DFSANECXXSolver
`).
Adapting existing scripts to work in an MPI context can require some work,
especially if said scripts rely on numpy and scipy for pre- and post-processing
(e.g. constructing a parabolic surface for hertzian contact, computing the total
contact area). It is the user's responsibility to make the changes necessary,
but Tamaas provides some convenience functions to make this task easier. In the
module :py:mod:`mpi `, the function :py:func:`local_shape
` gives the 2D shape of the local data if given
the global 2D shape (its counterpart :py:func:`global_shape
` does the exact opposite), while
:py:func:`local_offset ` gives the offset of
the local data in the global :math:`x` dimension. These two functions mirror
FFTW's own data distribution `functions
`_.
.. figure:: figures/mpi_data_distribution.svg
:align: center
:width: 75%
2D Data distribution scheme from FFTW. ``N0`` and ``N1`` are the
number of points in the :math:`x` and :math:`y` directions
respectively. The array ``local_N0``, indexed by the process rank,
give the local size of the :math:`x` dimension. The
:py:func:`local_offset ` function
gives the offset in :math:`x` for each process rank.
The :py:mod:`mpi ` module also contains a function
:py:func:`sequential ` whose return value is
meant to be used as a context manager. Within the sequential context the default
communicator is ``MPI_COMM_SELF`` instead of ``MPI_COMM_WORLD``.
In addition to the low-level functions in :py:mod:`mpi `,
many functions in Tamaas do not require special treatment, e.g. the statistics
functions.
Integration algorithm
---------------------
In its implementation of the volume integral operators necessary for
elastic-plastic solutions, Tamaas differenciates two way of computing the
intermediate integral along :math:`z` in the partial Fourier domain:
- Cutoff integration: because the intermediate integral involves kernels of the
form :math:`\exp(q(x-y))`, it is easy to truncate the integral when :math:`x`
and :math:`y` are far apart, especially for large values of :math:`q`. This
changes the complexity of the intermediate integral from
:math:`O(N_1N_2N_3^2)` (the naive implementation) to :math:`O(\sqrt{N_1^2 +
N_2^2}N_3^2)`.
- Linear integration: this method relies on a separation of variables
:math:`\exp(q(x-y)) = \exp(qx)\cdot\exp(-qy)`. This allows to break the
dependency in :math:`N_3^2` of the number of operations, so that the overall
complexity of the intermediate integral is :math:`O(N_1N_2N_3)`.
-Details on both algorithms can be found in [2]_. Tamaas uses linear integration
+Details on both algorithms can be found in [1]_. Tamaas uses linear integration
by default because it is faster in many cases without introducing a truncation
error. Unfortunatly, it has a severe drawback when considering systems with a
fine surface discretization: due to :math:`q` increasing with the number of
points on the surface, the separated terms :math:`\exp(qx)` and
:math:`\exp(-qy)` may overflow and underflow respectively. Tamaas will warn
if that is the case, and users have two options to remedy the situation:
- Change the integration method by calling :func:`setIntegrationMethod
` with the desired
:class:`integration_method ` on the
:class:`Residual ` object you use in the computation.
- Compile Tamaas with the option ``real_type='long double'``. To make
manipulation of numpy arrays easier, a :class:`dtype` is provided in the
:py:mod:`tamaas` module which can be used to create numpy arrays compatible
with Tamaas' floating point type (e.g. ``x = np.linspace(0, 1,
dtype=tamaas.dtype)``)
Both these options negatively affect the performance, and it is up to the user
to select the optimal solution for their particular use case.
Computational methods
---------------------
Tamaas uses specialized numerical methods to efficiently solve elastic and
elastoplastic periodic contact problems. Using a boundary integral formulation
and a half-space geometry for the former allow (a) the focus of computational
power to the contact interface since the bulk response can be represented
exactly, (b) the use of the fast-Fourier transform for the computation of
convolution integrals. In conjunction with a boundary integral formulation of
the bulk state equations, a conjugate gradient approach is used to solve the
contact problem.
-.. note::
-
- The above methods are state-of-the-art in the domain of rough surface
+.. note:: The above methods are state-of-the-art in the domain of rough surface
contact. Below are selected publications detailing the methods used in
elastic contact with and without adhesion:
- Boundary integral formulation:
- Stanley and Kato (`J. of Tribology, 1997
`_)
+
- Conjugate Gradient:
- Polonsky and Keer (`Wear, 1999
`_)
- Rey, Anciaux and Molinari (`Computational Mechanics, 2017
`_)
+
- Frictional contact:
- Condat (`J. of Optimization Theory and Applications, 2012
`_)
+
For elastic-plastic contact, Tamaas uses a similar approach by implementing a
*volume* integral formulation of the bulk equilibrium equations. Thanks to
kernel expressions that are directly formulated in the Fourier domain, the
method reduces the algorithmic complexity, memory requirements and sampling
errors compared to traditional volume integral methods (Frérot, Bonnet, Anciaux
and Molinari, `Computer Methods in Applied Mechanics and Engineering, 2019
`_, `arXiv:1811.11558
`_). The figure below shows a comparison
of run times for an elasticity problem (only a single solve step) between Tamaas
and `Akantu `_, a high-performance FEM code
using the direct solver `MUMPS `_.
.. figure:: figures/complexity.svg
:align: center
:width: 75%
Comparison of run times between the volume integral implementation
(with cutoff integration) of Tamaas and an FEM solve step with a
Cholesky factorization performed by Akantu+MUMPS. :math:`N` is the
total number of points.
Further discussion about the elastic-plastic solver implemented in Tamaas can be
found in Frérot, Bonnet, Anciaux and Molinari, (`Computer Methods in Applied
Mechanics and Engineering, 2019 `_,
`arXiv:1811.11558 `_).
-.. [1] Thrust uses a backend system for thread-level parallelism, which can be
- changed to use `TBB
- `_
- in the build options (``build-setup.conf``). You can experiment with it,
- but we do not formally support this backend. Note that this does not
- affect FFTW, which always uses OpenMP.
-
-
-.. [2] L. Frérot, “Bridging scales in wear modeling with volume integral
+.. [1] L. Frérot, “Bridging scales in wear modeling with volume integral
methods for elastic-plastic contact,” École Polytechnique Fédérale de
Lausanne, 2020 (Section 2.3.2). `10.5075/epfl-thesis-7640
`_
diff --git a/doc/sphinx/source/quickstart.rst b/doc/sphinx/source/quickstart.rst
index fa8e46d..13f1420 100644
--- a/doc/sphinx/source/quickstart.rst
+++ b/doc/sphinx/source/quickstart.rst
@@ -1,140 +1,183 @@
Quickstart
----------
Here is a quick introduction to get you started with Tamaas.
Installation from PyPI
^^^^^^^^^^^^^^^^^^^^^^
If you have a Linux system, you can simply run ``pip(3) install tamaas``. Note
however that there may be due to compatibility reasons, this version of Tamaas
is not built with parallel capabilities. So if you want parallelism, or
encounter an issue with the `PyPI package `_,
please compile from source.
Installation from source
^^^^^^^^^^^^^^^^^^^^^^^^
First make sure the following dependencies are installed for Tamaas:
- a **C++ compiler** with full **C++14** and **OpenMP** support
- **SCons** (python build system)
-- **FFTW3** compiled with **OpenMP** support
+- **FFTW3**
- **thrust** (1.9.2+)
- **boost** (pre-processor)
-- **python 3+** (probably works with python 2, but it is not tested) with
- **numpy**
+- **python 3+** with **numpy**
- **pybind11** (included as submodule)
- **expolit** (included as submodule)
Optional dependencies are:
+- an MPI implementation
+- **FFTW3** with MPI/threads/OpenMP (your pick) support
- **scipy** (for nonlinear solvers)
-- **uvw** (for dumpers)
+- **uvw**, **h5py**, **netCDF4** (for dumpers)
- **googletest** and **pytest** (for tests)
- **Doxygen** and **Sphinx** (for documentation)
.. tip:: On a HPC environment, use the following variables to specify where the
dependencies are located:
- ``FFTW_ROOT``
- ``THRUST_ROOT``
- ``BOOST_ROOT``
- ``PYBIND11_ROOT``
- ``GTEST_ROOT``
.. note:: You can use the provided Dockerfile to build an image with the
external dependencies installed.
You should first clone the git repository with the submodules that are
dependencies to tamaas (`expolit `_,
`pybind11 `_ and `googletest
`_)::
git clone --recursive https://c4science.ch/source/tamaas.git
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::
+command line:
+
+.. code-block:: bash
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.
-Once compiled, you can install the python module with::
+Once compiled, you can install the python module with:
+
+.. code-block:: bash
scons install prefix=/your/prefix
The above command automatically calls ``pip(3)`` if it is installed, and falls
back on ``setuptools`` otherwise. If you do not want to install Tamaas, you can
use the following command::
scons dev
This creates a symlink in ``~/.local/lib//site-packages`` and
is equivalent to ``pip(3) install -e`` or ``./setup.py develop``. You can check
-that everything is working fine with::
+that everything is working fine with:
+
+.. code-block:: bash
python3 -c 'import tamaas; print(tamaas)'
Using Docker
............
The Tamaas repository provides a `Dockerfile` that describes an appropriate
-build environment. You can use it in the following way::
+build environment. You can use it in the following way:
- # Build the image, run it and mount the tamaas repository
- docker build -t tamaas_build .
- docker run -v $PWD:/app/tamaas -it tamaas_build bash
+.. code-block:: bash
- # Once in the image shell: compile and install
- cd /app/tamaas
- scons
- scons dev
+ # Build the image, run it and mount the tamaas repository
+ docker build -t tamaas_build .
+ docker run -v $PWD:/app/tamaas -it tamaas_build bash
+
+ # Once in the image shell: compile and install
+ cd /app/tamaas
+ scons
+ scons dev
The image also has some of the dependencies required to run the examples below
(matplotlib, uvw).
+Important build options
+.......................
+
+Here are a selected few important compilation options:
+
+``build_type``
+ Controls the type of build, which essentially changes the optimisation level
+ (``-O0`` for ``debug``, ``-O2`` for ``profiling`` and ``-O3`` for
+ ``release``) and the amount of debug information. Default type is ``release``.
+
+``CXX``
+ Compiler (uses the environment variable ``CXX`` by default).
+
+``CXXFLAGS``
+ Compiler flags (uses the environment variable ``CXXFLAGS`` by
+ default). Useful to add tuning flags (e.g. ``-march=native -mtune=native``
+ for GCC or ``-xHOST`` for Intel), or additional optimisation flags (e.g.
+ ``-flto`` for link-time optimization).
+
+``backend``
+ Controls the Thrust parallelism backend. Defaults to ``omp`` for OpenMP.
+
+``fftw_threads``
+ Controls the FFTW thread model. Defaults to ``omp`` for OpenMP.
+
+``use_mpi``
+ Activates MPI-parallelism.
+
+More details on the above options can be found in :doc:`performance`.
+
Building the docs
^^^^^^^^^^^^^^^^^
Documentation is built using ``scons doc``. Make sure to have the correct
dependencies installed (they are already provided in the Docker image).
Running the contact pipe tools
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In the ``examples/pipe_tools`` folder, you will find three scripts that can be
used to explore the mechanics of elastic rough contact:
- ``surface`` generates randomly rough surfaces (see :doc:`rough_surfaces`)
- ``contact`` solves a contact problem with a surface read from ``stdin`` (see
:doc:`contact`)
- ``plot`` simply plots the surface tractions and displacements read from
``stdin``
-Here's a sample command line for you to try out::
+Here's a sample command line for you to try out:
+
+.. code-block:: bash
./surface --cutoffs 2 4 64 --size 512 512 --hurst 0.8 | ./contact 1 | ./plot
Check out the help of each script for a description of the arguments.
Running the tests
^^^^^^^^^^^^^^^^^
-You need to activate the ``build_tests`` option to compile the tests::
+You need to activate the ``build_tests`` option to compile the tests:
+
+.. code-block:: bash
scons build_tests=True
Tests can then be run with the ``scons test`` command. Make sure you have
`pytest `_ installed.
diff --git a/third-party/expolit b/third-party/expolit
index a31a8ec..5f68da4 160000
--- a/third-party/expolit
+++ b/third-party/expolit
@@ -1 +1 @@
-Subproject commit a31a8ecdb3cd8f903744d2c39bd282f18cf0bada
+Subproject commit 5f68da4ee972156d8676cd645e25fab984ecc75a