diff --git a/Jenkinsfile b/Jenkinsfile
index d3b08fe..3293b72 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -1,120 +1,119 @@
pipeline {
parameters {string(defaultValue: '', description: 'api-token', name: 'API_TOKEN')
string(defaultValue: '', description: 'Token for readthedocs', name: 'RTD_TOKEN')
string(defaultValue: '', description: 'buildable phid', name: 'BUILD_TARGET_PHID')
string(defaultValue: '', description: 'Commit id', name: 'COMMIT_ID')
string(defaultValue: '', description: 'Diff id', name: 'DIFF_ID')
string(defaultValue: 'PHID-PROJ-gbo56hpf2y5bi7t5jusk', description: 'ID of the project', name: 'PROJECT_ID')
}
environment {
PHABRICATOR_HOST = 'https://c4science.ch/api/'
PYTHONPATH = sh returnStdout: true, script: 'echo ${WORKSPACE}/tests/ci/script/'
}
agent {
dockerfile { additionalBuildArgs '--tag tamaas-environment'}
}
stages {
stage('SCM Checkout') {
steps {
checkout scm: [
$class: 'GitSCM',
branches: scm.branches,
extensions: [[
$class: 'SubmoduleOption',
recursiveSubmodules: true,
]],
userRemoteConfigs: scm.userRemoteConfigs
]
}
}
stage('Configure') {
steps {
sh '''#!/usr/bin/env bash
echo "py_exec = \'python3\'" > build-setup.conf
echo "build_python = \'true\'" >> build-setup.conf
echo "build_tests = \'true\'" >> build-setup.conf
echo "use_googletest = \'true\'" >> build-setup.conf
- echo "legacy_bem = \'true\'" >> build-setup.conf
echo "use_mpi = \'true\'" >> build-setup.conf'''
}
}
stage('Compile') {
steps {
sh '''#!/usr/bin/env bash
set -o pipefail
rm -rf .sconf_temp .sconsign.dblite build-release
scons | tee compilation.txt'''
}
post {
failure {
uploadArtifact('compilation.txt', 'Compilation')
}
}
}
stage('Run tests') {
steps {
sh 'PYTHONPATH=build-release/python/ python3 -m pytest --durations=0 --junitxml=results.xml build-release'
}
}
}
post {
always {
createArtifact("results.xml")
junit 'results.xml'
step([$class: 'XUnitBuilder',
thresholds: [
[$class: 'SkippedThreshold', failureThreshold: '0'],
[$class: 'FailedThreshold', failureThreshold: '0']],
tools: [[$class: 'GoogleTestType', pattern: 'build-release/tests/gtest_results.xml']]])
}
success {
trigger_rtd()
passed_hbm()
}
failure {
failed_hbm()
emailext(
body: '''${SCRIPT, template="groovy-html.template"}''',
mimeType: 'text/html',
subject: "[Jenkins] ${currentBuild.fullDisplayName} Failed",
recipientProviders: [[$class: 'CulpritsRecipientProvider']],
to: 'lucas.frerot@protonmail.com',
attachLog: true,
compressLog: true)
}
}
}
def createArtifact(filename) {
sh "./tests/ci/scripts/hbm send-uri -k 'Jenkins URI' -u ${BUILD_URL} -l 'View Jenkins result'"
sh "./tests/ci/scripts/hbm send-junit-results -f ${filename}"
}
def uploadArtifact(artifact, name) {
sh "./test/ci/scripts/hbm upload-file -f ${artifact} -n \"${name}\" -v ${PROJECT_ID}"
}
def failed_hbm() {
sh "./tests/ci/scripts/hbm failed"
}
def passed_hbm() {
sh "./tests/ci/scripts/hbm passed"
}
def trigger_rtd() {
sh """
set -x
curl -X POST -d "token=${RTD_TOKEN}" https://readthedocs.org/api/v2/webhook/tamaas/106141/
"""
}
diff --git a/SConstruct b/SConstruct
index 8668567..806d6ba 100644
--- a/SConstruct
+++ b/SConstruct
@@ -1,477 +1,469 @@
# -*- 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
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.1.4",
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-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"""
fftw_comp = {
'omp': ['omp'],
'cpp': [],
'tbb': ['threads']
}
fftw_components = fftw_comp[env['backend']]
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('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', "")),
- # 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),
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("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'])
-# 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
-
# 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/examples/legacy/adhesion.py b/examples/legacy/adhesion.py
deleted file mode 100644
index 8bc9036..0000000
--- a/examples/legacy/adhesion.py
+++ /dev/null
@@ -1,161 +0,0 @@
-#!/usr/bin/env 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 .
-
-import sys
-import tamaas as tm
-import numpy as np
-import matplotlib.pyplot as plt
-
-def plotSurface(surface):
- fig = plt.figure()
- ax = fig.add_subplot(111)
- img = ax.imshow(surface)
- #fig.colorbar(img)
-
-def constructHertzProfile(size, curvature):
- radius = 1. / curvature
- x = np.linspace(-0.5, 0.5, size)
- y = np.linspace(-0.5, 0.5, size)
- x, y = np.meshgrid(x, y)
- surface = np.sqrt(radius**2 - x**2 - y**2)
- surface -= surface.min()
- return surface.copy()
-
-def computeHertzDisplacement(e_star, contact_size, max_pressure, size):
- x = np.linspace(-0.5, 0.5, size)
- y = np.linspace(-0.5, 0.5, size)
- x, y = np.meshgrid(x, y)
- disp = np.pi * max_pressure / (4 * contact_size * e_star) * (2 * contact_size**2 - (x**2 + y**2))
- return disp.copy()
-
-def main():
- grid_size = 128
- curvature = 0.5
- effective_modulus = 1.
- load = 0.1
-
- surface_energy = 0
- rho = 2.071e-7
-
- surface = constructHertzProfile(grid_size, curvature)
- # SG = tm.SurfaceGeneratorFilterFFT()
- # SG.getGridSize().assign(grid_size)
- # SG.getHurst().assign(0.8)
- # SG.getRMS().assign(0.002);
- # SG.getQ0().assign(8);
- # SG.getQ1().assign(8);
- # SG.getQ2().assign(16);
- # SG.getRandomSeed().assign(156);
- # SG.Init()
- # surface = SG.buildSurface()
- print "Max height {}".format(surface.max())
- print "Min height {}".format(surface.min())
-
- bem = tm.BemGigi(surface)
- bem.setDumpFreq(1)
- functional = tm.ExponentialAdhesionFunctional(bem)
- functional.setParameter('rho', rho)
- functional.setParameter('surface_energy', surface_energy)
- bem.setEffectiveModulus(effective_modulus)
- bem.addFunctional(functional)
- bem.computeEquilibrium(1e-6, load)
-
- tractions = bem.getTractions()
- print "Average pressure = {}".format(tractions.mean())
- # bem.computeTrueDisplacements()
- t_displacements = bem.getTrueDisplacements()
- t_gap = bem.getGap()
-
- plotSurface(tractions)
-
- plt.figure()
- plt.plot(surface[grid_size/2, :])
- plt.title("Surface")
- plt.figure()
- plt.plot(tractions[grid_size/2, :])
- plt.title("Pressure")
- plt.figure()
- plt.plot(t_gap[grid_size/2, :])
- plt.title("Gap")
- plt.figure()
- plt.plot(t_displacements[grid_size/2, :])
- plt.title("Displacement")
- plt.figure()
- plt.plot(t_displacements[grid_size/2, :] - surface[grid_size/2, :])
- plt.title("Disp-surf")
- plotSurface(t_displacements)
-
- plt.show()
- return 0
-
- # Testing contact area against Hertz solution for solids of revolution
- contact_area = tm.SurfaceStatistics.computeContactArea(tractions)
- hertz_contact_size = (3 * load / (4 * curvature * effective_modulus))**(1. / 3.)
- hertz_area = np.pi * hertz_contact_size**2
- area_error = np.abs(hertz_area - contact_area) / hertz_area
- print "Area error: {}".format(area_error)
-
- # Testing maximum pressure
- max_pressure = tractions.max()
- hertz_max_pressure = (6 * load * effective_modulus**2 * curvature ** 2)**(1. / 3.) / np.pi
- pressure_error = np.abs(hertz_max_pressure - max_pressure) / hertz_max_pressure
- print "Max pressure error: {}".format(pressure_error)
-
- # Testing displacements
- hertz_displacements = computeHertzDisplacement(effective_modulus,
- hertz_contact_size,
- hertz_max_pressure,
- grid_size)
-
- # Selecing only the points that are in contact
- contact_indexes = [(i, j, tractions[i, j] > 0) for i in range(grid_size) for j in range(grid_size)]
- contact_indexes = map(lambda x: x[0:2], filter(lambda x: x[2], contact_indexes))
-
- # Displacements of bem are centered around the mean of the whole surface
- # and Hertz displacements are not centered, so we need to compute mean
- # on the contact zone for both arrays
- bem_mean = 0.
- hertz_mean = 0.
- for index in contact_indexes:
- bem_mean += displacements[index]
- hertz_mean += hertz_displacements[index]
-
- bem_mean /= len(contact_indexes)
- hertz_mean /= len(contact_indexes)
- # Correction applied when computing error
- correction = hertz_mean - bem_mean
-
- # Computation of error of displacement in contact zone
- error = 0.
- hertz_norm = 0.
- for index in contact_indexes:
- error += (hertz_displacements[index] - displacements[index] - correction)**2
- hertz_norm += (hertz_displacements[index] - hertz_mean)**2
-
- displacement_error = np.sqrt(error / hertz_norm)
- print "Displacement error (in contact zone): {}".format(displacement_error)
-
- if area_error > 1e-2 or pressure_error > 1e-2 or displacement_error > 1e-4:
- return 1
-
- return 0
-
-if __name__ == "__main__":
- sys.exit(main())
diff --git a/examples/legacy/cluster_statistics.py b/examples/legacy/cluster_statistics.py
deleted file mode 100644
index a03370b..0000000
--- a/examples/legacy/cluster_statistics.py
+++ /dev/null
@@ -1,104 +0,0 @@
-#!/usr/bin/env 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 .
-
-import numpy as np
-
-
-def plotSurface(surf):
- fig = plt.figure()
- axe = fig.add_subplot(111)
- img = axe.imshow(surf)
- cbar = fig.colorbar(img)
-
-
-################################################################
-# surface generation
-################################################################
-
-from tamaas import *
-
-n = 128
-SG = SurfaceGeneratorFilterFFT()
-SG.getGridSize().assign(n)
-SG.getHurst().assign(0.8)
-SG.getRMS().assign(1.);
-SG.getQ0().assign(4);
-SG.getQ1().assign(4);
-SG.getQ2().assign(64);
-SG.getRandomSeed().assign(20);
-SG.Init()
-s = SG.buildSurface()
-rms_slopes_spectral = SurfaceStatistics.computeSpectralRMSSlope(s)
-s *= 1./rms_slopes_spectral
-s -= s.max()
-
-################################################################
-# surface plot
-################################################################
-
-import matplotlib.pyplot as plt
-
-#fig1 = plotSurface(s)
-
-################################################################
-# contact contact
-################################################################
-
-bem = BemPolonski(s)
-bem.setEffectiveModulus(1.)
-
-load = 0.1
-bem.computeEquilibrium(1e-13,load)
-
-tractions = bem.getTractions()
-displacements = bem.getDisplacements()
-
-#fig2 = plotSurface(tractions)
-#fig3 = plotSurface(displacements)
-
-################################################################
-# cluster statistics
-################################################################
-
-
-area = ContactArea(tractions.shape[0],1.);
-area.getSurface()[tractions > 0.] = 1
-# Cluster detection
-print "==============================="
-print "Detect contact clusters: "
-area.detectContactClusters()
-print "Found " + str(area.getNumClusters())
-clusters = ContactClusterCollection(area);
-cluster_list = area.getContactClusters();
-cluster_areas = [float(c.getA())/float(n)**2 for c in cluster_list]
-cluster_perimeters = [c.getP() for c in cluster_list]
-print "cluster_areas",cluster_areas
-print "cluster_perimeters",cluster_perimeters
-print "cluster_total_area",clusters.getTotalArea()
-print "cluster_total_perimeter",clusters.getTotalPerimeter()
-print "nb_clusters_with_hole",clusters.getNbClustersWithHole()
-print "nb_clusters",clusters.getNbClusters()
-################################################################
-value,bins = np.histogram(cluster_areas,bins=50)
-fig = plt.figure()
-axe = fig.add_subplot(111)
-axe.loglog(bins[:-1],value,'-o')
-################################################################
-plt.show()
diff --git a/examples/legacy/contact.py b/examples/legacy/contact.py
deleted file mode 100644
index 25abd57..0000000
--- a/examples/legacy/contact.py
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/usr/bin/env 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 .
-
-
-def plotSurface(surf):
- fig = plt.figure()
- axe = fig.add_subplot(111)
- img = axe.imshow(surf)
- cbar = fig.colorbar(img)
-
-
-################################################################
-# surface generation
-################################################################
-
-from tamaas import *
-
-
-SG = SurfaceGeneratorFilterFFT()
-SG.getGridSize().assign(128)
-SG.getHurst().assign(0.8)
-SG.getRMS().assign(1.);
-SG.getQ0().assign(4);
-SG.getQ1().assign(4);
-SG.getQ2().assign(64);
-SG.getRandomSeed().assign(20);
-SG.Init()
-s = SG.buildSurface()
-rms_slopes_spectral = SurfaceStatistics.computeSpectralRMSSlope(s)
-s *= 1./rms_slopes_spectral
-s -= s.max()
-
-################################################################
-# surface plot
-################################################################
-
-import matplotlib.pyplot as plt
-
-fig1 = plotSurface(s)
-
-################################################################
-# contact contact
-################################################################
-
-bem = BemPolonski(s)
-bem.setEffectiveModulus(1.)
-
-load = 0.1
-bem.computeEquilibrium(1e-13,load)
-
-tractions = bem.getTractions()
-displacements = bem.getDisplacements()
-
-fig2 = plotSurface(tractions)
-fig3 = plotSurface(displacements)
-plt.show()
diff --git a/examples/legacy/fractal_surface.py b/examples/legacy/fractal_surface.py
deleted file mode 100644
index b68fb4c..0000000
--- a/examples/legacy/fractal_surface.py
+++ /dev/null
@@ -1,102 +0,0 @@
-#!/usr/bin/env 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 tamaas import *
-import argparse
-
-parser = argparse.ArgumentParser()
-parser.add_argument("--rescale", help="Rescale surface for RMS(slopes) = 1", action='store_true')
-parser.add_argument("--N", help="Number of points", type=int, default=512)
-parser.add_argument("--k0", help="Roll-off wave number", type=int, default=4)
-parser.add_argument("--k1", help="Low cutoff wave number", type=int, default=4)
-parser.add_argument("--k2", help="High cutoff wave number", type=int, default=32)
-parser.add_argument("--rms", help="RMS(heights)", default=1.)
-parser.add_argument("--H", help="Hurst exponent", default=0.8)
-
-args = parser.parse_args()
-
-#generate surface
-SG = SurfaceGeneratorFilterFFT()
-SG.getGridSize().assign(args.N)
-SG.getHurst().assign(args.H)
-SG.getRMS().assign(args.rms);
-SG.getQ0().assign(args.k0);
-SG.getQ1().assign(args.k1);
-SG.getQ2().assign(args.k2);
-SG.getRandomSeed().assign(156);
-SG.Init()
-a = SG.buildSurface()
-
-if args.rescale:
- rms_slopes = SurfaceStatistics.computeSpectralRMSSlope(a)
- a /= rms_slopes
-
-#compute and print surface statistics
-class Stats:
-
- def __getitem__(self,key):
- return self.__dict__[key]
-
-
-stats = Stats()
-
-stats.size = SG.getGridSize()
-stats.hurst = SG.getHurst().value()
-stats.rms = SG.getRMS()
-stats.k0 = SG.getQ0()
-stats.k1 = SG.getQ1().value()
-stats.k2 = SG.getQ2().value()
-stats.seed = SG.getRandomSeed()
-stats.rms_spectral = SurfaceStatistics.computeSpectralStdev(a);
-stats.rms_slopes_spectral = SurfaceStatistics.computeSpectralRMSSlope(a);
-stats.rms_geometric = a.std(ddof=1)
-stats.rms_slopes_geometric = SurfaceStatistics.computeRMSSlope(a);
-stats.moments = SurfaceStatistics.computeMoments(a);
-stats.m0 = stats['rms_spectral']**2
-stats.m2 = stats.moments[0]
-stats.m4 = stats.moments[1]
-stats.alpha = stats['m0']*stats['m4']/(stats['m2']**2)
-stats.L = 1.
-stats.m0prime = SurfaceStatistics.computeAnalyticFractalMoment(0,stats.k1,stats.k2,stats.hurst,1. , stats.L)
-stats.moment_A = stats.m0/stats.m0prime
-stats.analytic_m0 = SurfaceStatistics.computeAnalyticFractalMoment(0,stats.k1,stats.k2,stats.hurst,stats.moment_A,stats.L);
-stats.analytic_m2 = SurfaceStatistics.computeAnalyticFractalMoment(2,stats.k1,stats.k2,stats.hurst,stats.moment_A,stats.L);
-stats.analytic_m4 = SurfaceStatistics.computeAnalyticFractalMoment(4,stats.k1,stats.k2,stats.hurst,stats.moment_A,stats.L);
-stats.analytic_alpha = stats.analytic_m0*stats.analytic_m4/(stats.analytic_m2*stats.analytic_m2);
-
-print """
-[N] {size}
-[rms] {rms}
-[rmsSpectral] {rms_spectral}
-[rmsSlopeSpectral] {rms_slopes_spectral}
-[rmsSlopeGeometric] {rms_slopes_geometric}
-[Hurst] {hurst}
-[k1] {k1}
-[k2] {k2}
-[moment A] {moment_A}
-[m0] {m0}
-[analytic m0] {analytic_m0}
-[m2] {m2}
-[analytic m2] {analytic_m2}
-[m4] {m4}
-[analytic m4] {analytic_m4}
-[alpha] {alpha}
-[analytic_alpha] {analytic_alpha}
-[seed] {seed}
diff --git a/examples/legacy/hertz.py b/examples/legacy/hertz.py
deleted file mode 100644
index cb5bfaa..0000000
--- a/examples/legacy/hertz.py
+++ /dev/null
@@ -1,116 +0,0 @@
-#!/usr/bin/env 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 .
-
-import tamaas
-
-
-def dumpHertzPrediction(file, bem, pressure, r, E ):
- A = tamaas.SurfaceStatistics.computeContactArea(bem.getTractions())
- Aratio = tamaas.SurfaceStatistics.computeContactAreaRatio(bem.getTractions())
- radius = np.sqrt(A/np.pi)
- #L = bem.getSurface().getL()
- L = 1.
- load = pressure * L*L
- radius_hertz = pow(0.75*load*r/E,1./3.)
- p0_hertz = 1./np.pi*pow(6.*E*E*load/r/r,1./3.)
- p0 = tamaas.SurfaceStatistics.computeMaximum(bem.getTractions())
- n = bem.getTractions().shape[0]
- computed_load = bem.getTractions().sum()/n/n*L*L
- file.write("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\t{9}\n".format(pressure,load,computed_load,Aratio,A,radius,radius_hertz,radius_hertz/radius,p0,p0_hertz))
-
-
-################################################################
-
-def main(argv):
-
- parser = argparse.ArgumentParser(description='Hertz test for the Boundary element method of Stanley and Kato')
-
- parser.add_argument("--N",type=int, help="Surface size", required=True)
- parser.add_argument("--r",type=float, help="radius of hertz sphere", required=True)
- parser.add_argument("--steps",type=int, help="number of steps within which the pressure is applied.", required=True)
- parser.add_argument("--precision",type=float, help="relative precision, convergence if | (f_i - f_{i-1})/f_i | < Precision.", required=True)
- parser.add_argument("--e_star",type=float, help="effective elastic modulus" , required=True)
- parser.add_argument("--L",type=float, help="size of the surface" , required=True)
- parser.add_argument("--max_pressure",type=float, help="maximal load requested" , required=True)
- parser.add_argument("--plot_surface",type=bool, help="request output of text files containing the contact pressures on the surface" , default=False)
- parser.add_argument("--nthreads",type=int, help="request a number of threads to use via openmp to compute" , default=1)
-
- args = parser.parse_args()
- arguments = vars(args)
-
- n = arguments["N"]
- r = arguments["r"]
- max_pressure = arguments["max_pressure"]
- Ninc = arguments["steps"]
- epsilon = arguments["precision"]
- Estar = arguments["e_star"]
- L = arguments["L"]
- plot_surface = arguments["plot_surface"]
- nthreads = arguments["nthreads"]
-
- pressure = 0.
- dp = max_pressure/float(Ninc)
-
- s = np.zeros((n,n))
- print s.shape
- for i in range(0,n):
- for j in range(0,n):
- x = 1.*i - n/2
- y = 1.*j - n/2
- d = (x*x + y*y)*1./n/n*L*L
-
- if d < r*r: s[i,j] = - r + np.sqrt(r*r-d)
- else: s[i,j] = - r
-
-
- print "\n::: DATA ::::::::::::::::::::::::::::::\n"
- print " [N] {0}\n".format(n)
- print " [r] {0}\n".format(r)
- print " [Pext] {0}\n".format(max_pressure)
- print " [Steps] {0}\n".format(Ninc)
- print " [Precision] {0}\n".format(epsilon)
-
- bem = tamaas.BemPolonski(s)
- bem.setEffectiveModulus(Estar)
-
- file = open("hertz-prediction",'w')
-
- file.write("#pressure\tload\tcomputed-load\tarea_ratio\tarea\tradius\tradius-hertz\tradius/radius-hertz\tp0\tp0-hertz\n")
-
- for i in range(0,Ninc):
-
- pressure += dp
-
- bem.computeEquilibrium(epsilon,pressure)
- A = tamaas.SurfaceStatistics.computeContactAreaRatio(bem.getTractions())
-
- dumpHertzPrediction(file,bem,pressure,r,Estar)
-
- if A == 1.0:
- file.close()
- break
-
- tamaas.dumpTimes()
-
-################################################################
-import sys
-import argparse
-import numpy as np
-main(sys.argv)
diff --git a/examples/legacy/surface_1d.py b/examples/legacy/surface_1d.py
deleted file mode 100644
index 8cdd108..0000000
--- a/examples/legacy/surface_1d.py
+++ /dev/null
@@ -1,83 +0,0 @@
-#!/usr/bin/env 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 division
-import tamaas as tm
-from numpy.fft import fft, fftshift, fftfreq
-import matplotlib.pyplot as plt
-
-tm.initialize()
-
-
-def draw_triangle(pos, w, ax, style, alpha=1.5, base=10):
- h = alpha * w
- ax.loglog([base**pos[0], base**(pos[0]+w)],
- [base**pos[1], base**pos[1]], style)
- ax.loglog([base**pos[0], base**pos[0]],
- [base**pos[1], base**(pos[1]+h)], style)
- ax.loglog([base**(pos[0]+w), base**pos[0]],
- [base**pos[1], base**(pos[1]+h)], style)
- # ax.text(base**(pos[0]+w/3), base**(pos[1]+h/3), "$-{}$".format(alpha),
- # horizontalalignment='center',
- # verticalalignment='center')
- ax.text(base**(pos[0]+w/2), base**(pos[1]-0.2), '$1$',
- horizontalalignment='center',
- verticalalignment='top')
- ax.text(base**(pos[0]-0.15), base**(pos[1]+h/2), '${}$'.format(alpha),
- horizontalalignment='right',
- verticalalignment='center')
-
-
-iso = tm.Isopowerlaw1D()
-helper = tm.ParamHelper(iso)
-
-params = {
- "Q0": 16,
- "Q1": 16,
- "Q2": 512,
- "Hurst": 0.8
-}
-
-helper.set(params)
-
-gen = tm.SurfaceGeneratorFilter1D()
-gen.setFilter(iso)
-gen.setSizes([2048])
-# gen.setRandomSeed(0) # uncomment for fixed seed
-
-surf = gen.buildSurface()
-
-plt.plot(surf)
-
-surf_fft = fft(surf)
-psd = surf_fft*surf_fft.conj()
-psd = fftshift(psd)
-
-plt.figure()
-freqs = fftshift(fftfreq(psd.size, d=1/psd.size))
-plt.plot(freqs[psd.size/2+1:], psd.real[psd.size/2+1:])
-draw_triangle([5, -4], 2, plt.gca(), '-k', 2*(params["Hurst"]+1), 2)
-plt.yscale('log')
-plt.xscale('log', basex=2)
-plt.ylim([10**(-2), 10**8])
-
-plt.show()
-
-tm.finalize()
diff --git a/python/SConscript b/python/SConscript
index 123a023..46e75eb 100644
--- a/python/SConscript
+++ b/python/SConscript
@@ -1,162 +1,157 @@
# -*- 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/mpi.cpp
wrap/test_features.cpp
""")
-# Adding legacy wrap code
-if env_pybind['legacy_bem']:
- env_pybind.AppendUnique(CPPDEFINES=['TAMAAS_LEGACY_BEM'])
- pybind_sources += ["wrap/bem.cpp"]
-
# Setting paths to find libTamaas
env_pybind.AppendUnique(LIBPATH=[Dir(join('#${build_dir}', 'src'))])
# Link against a static libTamaas
if env_pybind['build_static_lib']:
env_pybind.PrependUnique(LIBS=['Tamaas']) # keep other libs for link
env_pybind['RPATH'] = "" # no need for rpath w/ static lib
# Link against a dynamic libTamaas
else:
env_pybind.AppendUnique(RPATH=[
- "'$$$$ORIGIN/../../src'", #< path to lib in build_dir
- "'$$$$ORIGIN/../../..'", #< path to lib in install prefix
+ "'$$$$ORIGIN/../../src'", # path to lib in build_dir
+ "'$$$$ORIGIN/../../..'", # path to lib in install prefix
])
env_pybind['LIBS'] = ['Tamaas'] # discard other libs for link
# Building the pybind library
tamaas_wrap = env_pybind.Pybind11Module(
target='tamaas/_tamaas',
source=pybind_sources,
)
# 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',
# 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 .[all]'
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/cast.hh b/python/cast.hh
index c672217..27ca4de 100644
--- a/python/cast.hh
+++ b/python/cast.hh
@@ -1,211 +1,182 @@
/**
* @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 .
*
*/
/* -------------------------------------------------------------------------- */
-#ifndef __CAST_HH__
-#define __CAST_HH__
+#ifndef CAST_HH
+#define CAST_HH
/* -------------------------------------------------------------------------- */
#include "grid_base.hh"
+#include "grid.hh"
#include "numpy.hh"
-#include "surface.hh"
/* -------------------------------------------------------------------------- */
#include
#include
/* -------------------------------------------------------------------------- */
namespace pybind11 {
// Format descriptor necessary for correct wrap of tamaas complex type
template
struct format_descriptor<
tamaas::complex, detail::enable_if_t::value>> {
static constexpr const char c = format_descriptor::c;
static constexpr const char value[3] = {'Z', c, '\0'};
static std::string format() { return std::string(value); }
};
#ifndef PYBIND11_CPP17
template
constexpr const char format_descriptor<
tamaas::complex,
detail::enable_if_t::value>>::value[3];
#endif
namespace detail {
// declare tamaas complex as a complex type for pybind11
template
struct is_complex> : std::true_type {};
template
struct is_fmt_numeric,
detail::enable_if_t::value>>
: std::true_type {
static constexpr int index = is_fmt_numeric::index + 3;
};
static inline handle policy_switch(return_value_policy policy, handle parent) {
switch (policy) {
case return_value_policy::copy:
case return_value_policy::move:
return handle();
case return_value_policy::automatic_reference: // happens in python-derived
// classes
case return_value_policy::reference:
return none();
case return_value_policy::reference_internal:
return parent;
default:
TAMAAS_EXCEPTION("Policy is not handled");
}
}
template
handle grid_to_python(const tamaas::Grid& grid,
return_value_policy policy, handle parent) {
parent = policy_switch(policy, parent); // reusing variable
std::vector sizes(dim);
std::copy(grid.sizes().begin(), grid.sizes().end(), sizes.begin());
if (grid.getNbComponents() != 1)
sizes.push_back(grid.getNbComponents());
return array(sizes, grid.getInternalData(), parent).release();
}
/**
* Type caster for grid classes
* inspired by https://tinyurl.com/y8m47qh3 from T. De Geus
* and pybind11/eigen.h
*/
template class G, typename T,
tamaas::UInt dim>
struct type_caster> {
using type = G;
using array_type =
array_t;
public:
PYBIND11_TYPE_CASTER(type, _("GridWrap"));
/**
* Conversion part 1 (Python->C++): convert a PyObject into a grid
* instance or return false upon failure. The second argument
* indicates whether implicit conversions should be applied.
*/
bool load(handle src, bool convert) {
if (!array_type::check_(src) or !convert)
return false;
auto buf = array_type::ensure(src);
if (!buf) return false;
value.move(tamaas::wrap::GridNumpy>(buf));
return true;
}
/**
* Conversion part 2 (C++ -> Python): convert a grid instance into
* a Python object. The second and third arguments are used to
* indicate the return value policy and parent object (for
* ``return_value_policy::reference_internal``) and are generally
* ignored by implicit casters.
*/
static handle cast(const type& src, return_value_policy policy,
handle parent) {
return grid_to_python(src, policy, parent);
}
};
/**
* Type caster for GridBase classes
*/
template
struct type_caster> {
using type = tamaas::GridBase;
using array_type =
array_t;
public:
PYBIND11_TYPE_CASTER(type, _("GridBaseWrap"));
bool load(handle src, bool convert) {
if (!array_type::check_(src) or !convert)
return false;
auto buf = array_type::ensure(src);
if (!buf) return false;
value.move(tamaas::wrap::GridBaseNumpy(buf));
return true;
}
static handle cast(const type& src, return_value_policy policy,
handle parent) {
#define GRID_BASE_CASE(unused1, unused2, dim) \
case dim: { \
const auto& conv = dynamic_cast&>(src); \
return grid_to_python(conv, policy, parent); \
}
switch (src.getDimension()) {
BOOST_PP_SEQ_FOR_EACH(GRID_BASE_CASE, ~, (1)(2)(3));
default:
return nullptr;
}
#undef GRID_BASE_CASE
}
};
-
-/**
- * Type caster for surface class
- */
-template
-struct type_caster> {
- using type = tamaas::Surface;
- using array_type =
- array_t;
-
-public:
- PYBIND11_TYPE_CASTER(type, _("SurfaceWrap"));
-
- bool load(handle src, bool convert) {
- if (!array_type::check_(src) or !convert)
- return false;
-
- auto buf = array_type::ensure(src);
- if (!buf) return false;
- value.move(tamaas::wrap::SurfaceNumpy(buf));
-
- return true;
- }
-
- static handle cast(const type& src, return_value_policy policy,
- handle parent) {
- return grid_to_python(src, policy, parent);
- }
-};
} // namespace detail
} // namespace pybind11
#endif // __CAST_HH__
diff --git a/python/tamaas_module.cpp b/python/tamaas_module.cpp
index 60d2fc6..2213200 100644
--- a/python/tamaas_module.cpp
+++ b/python/tamaas_module.cpp
@@ -1,92 +1,80 @@
/**
* @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 .
*
*/
/* -------------------------------------------------------------------------- */
#include "tamaas.hh"
#include "tamaas_info.hh"
#include "wrap.hh"
/* -------------------------------------------------------------------------- */
#include
/* -------------------------------------------------------------------------- */
namespace tamaas {
namespace py = pybind11;
namespace detail {
template
struct dtype_helper {
static const py::dtype dtype;
};
template <>
const py::dtype dtype_helper::dtype("=f8");
template <>
const py::dtype dtype_helper::dtype("=f16");
} // namespace detail
/// Creating the tamaas python module
PYBIND11_MODULE(_tamaas, mod) {
mod.doc() = "Tamaas module for python";
// Wrapping the base methods
mod.def("initialize", &initialize, py::arg("num_threads") = 0,
"Initialize tamaas with desired number of threads");
mod.def("finalize", &finalize, "Final cleanup");
// Default dtype of numpy arrays
mod.attr("dtype") = detail::dtype_helper::dtype;
// Wrapping release information
auto info = py::class_(mod, "TamaasInfo");
info.attr("version") = TamaasInfo::version;
info.attr("build_type") = TamaasInfo::build_type;
info.attr("branch") = TamaasInfo::branch;
info.attr("commit") = TamaasInfo::commit;
info.attr("diff") = TamaasInfo::diff;
info.attr("remotes") = TamaasInfo::remotes;
info.attr("has_mpi") = TamaasInfo::has_mpi;
// Wrapping tamaas components
wrap::wrapCore(mod);
wrap::wrapPercolation(mod);
wrap::wrapSurface(mod);
wrap::wrapModel(mod);
wrap::wrapSolvers(mod);
wrap::wrapCompute(mod);
wrap::wrapMPI(mod);
/// Wrapping test features
wrap::wrapTestFeatures(mod);
-
-#if defined(TAMAAS_LEGACY_BEM)
- // Legacy wrap
- py::class_>(mod, "smart_pointer_UInt")
- .def("assign", &wrap::smart_pointer::assign);
- py::class_>(mod, "smart_pointer_Real")
- .def("assign", &wrap::smart_pointer::assign);
- py::class_>(mod, "smart_pointer_long")
- .def("assign", &wrap::smart_pointer::assign);
-
- wrap::wrapBEM(mod);
-#endif
}
} // namespace tamaas
diff --git a/python/wrap.hh b/python/wrap.hh
index d1d1d11..77419ba 100644
--- a/python/wrap.hh
+++ b/python/wrap.hh
@@ -1,91 +1,77 @@
/**
* @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 .
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __WRAP_HH__
#define __WRAP_HH__
/* -------------------------------------------------------------------------- */
#include "cast.hh"
#include "numpy.hh"
#include "tamaas.hh"
/* -------------------------------------------------------------------------- */
#include
/* -------------------------------------------------------------------------- */
namespace tamaas {
namespace wrap {
namespace py = pybind11;
/// For naming classes templated with dimension
inline std::string makeDimensionName(const std::string& name, UInt dim) {
std::stringstream str;
str << name << dim << "D";
return str.str();
}
-template
-class smart_pointer {
-public:
- smart_pointer(T* ptr) : ptr(ptr) {}
- void assign(T val) { *ptr = val; }
-
-private:
- T* ptr;
-};
-
/* -------------------------------------------------------------------------- */
/* Prototypes for wrapping of tamaas components */
/* -------------------------------------------------------------------------- */
void wrapCore(py::module& mod);
void wrapPercolation(py::module& mod);
void wrapSurface(py::module& mod);
void wrapModel(py::module& mod);
void wrapSolvers(py::module& mod);
void wrapTestFeatures(py::module& mod);
void wrapCompute(py::module& mod);
void wrapMPI(py::module& mod);
-#if defined(TAMAAS_LEGACY_BEM)
-void wrapBEM(py::module& mod);
-#endif
-
/* -------------------------------------------------------------------------- */
/* Deprecation macro */
/* -------------------------------------------------------------------------- */
#define TAMAAS_DEPRECATE(olds, news) \
do { \
PyErr_WarnEx(PyExc_DeprecationWarning, \
olds " is deprecated, use " news " instead.", 1); \
} while (0)
#define TAMAAS_DEPRECATE_ACCESSOR(acc, type, property) \
- #acc, [](const type& m) -> decltype(m.acc()) { \
+#acc, [](const type& m) -> decltype(m.acc()) { \
TAMAAS_DEPRECATE(#acc "()", "the " property " property"); \
return m.acc(); \
}
} // namespace wrap
} // namespace tamaas
#endif // __WRAP_HH__
diff --git a/python/wrap/bem.cpp b/python/wrap/bem.cpp
deleted file mode 100644
index 1b83d3f..0000000
--- a/python/wrap/bem.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-/**
- * @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 .
- *
- */
-/* -------------------------------------------------------------------------- */
-#include "bem_fft_base.hh"
-#include "bem_gigipol.hh"
-#include "bem_grid.hh"
-#include "bem_grid_condat.hh"
-#include "bem_grid_polonski.hh"
-#include "bem_kato.hh"
-#include "bem_polonski.hh"
-#include "wrap.hh"
-/* -------------------------------------------------------------------------- */
-
-namespace tamaas {
-
-namespace wrap {
-
-using namespace py::literals;
-
-/* -------------------------------------------------------------------------- */
-void wrapBEM(py::module& mod) {
- py::class_(mod, "BemFFTBase")
- .def("computeDisplacementsFromTractions",
- &BemFFTBase::computeDisplacementsFromTractions)
- .def("computeTractionsFromDisplacements",
- &BemFFTBase::computeTractionsFromDisplacements)
- .def("applyInfluenceFunctions", &BemFFTBase::applyInfluenceFunctions)
- .def("applyInverseInfluenceFunctions",
- &BemFFTBase::applyInverseInfluenceFunctions)
- .def("computeSpectralInfluenceOverDisplacements",
- &BemFFTBase::computeSpectralInfluenceOverDisplacement)
- .def("computeTrueDisplacements", &BemFFTBase::computeTrueDisplacements)
- .def("computeGaps", &BemFFTBase::computeGaps)
- .def("getSpectralInfluenceOverDisplacement",
- &BemFFTBase::getSpectralInfluenceOverDisplacement)
- .def("getTractions", &BemFFTBase::getTractions,
- py::return_value_policy::reference_internal)
- .def("getDisplacements", &BemFFTBase::getDisplacements,
- py::return_value_policy::reference_internal)
- .def("getTrueDisplacements", &BemFFTBase::getTrueDisplacements,
- py::return_value_policy::reference_internal)
- .def("getGap", &BemFFTBase::getGap,
- py::return_value_policy::reference_internal)
- .def("setEffectiveModulus", &BemFFTBase::setEffectiveModulus, "E_star"_a)
- .def("getEffectiveModulus", &BemFFTBase::getEffectiveModulus)
- .def("setMaxIterations", &BemFFTBase::setMaxIterations)
- .def("getMaxIterations", &BemFFTBase::getMaxIterations)
- .def("setDumpFreq", &BemFFTBase::setDumpFreq)
- .def("getDumpFreq", &BemFFTBase::getDumpFreq);
-
- py::class_(mod, "BemPolonski")
- .def(py::init&>())
- .def("computeEquilibrium", &BemPolonski::computeEquilibrium)
- .def("computeEquilibriuminit", &BemPolonski::computeEquilibriuminit)
- .def("computeMeanGapsInContact", &BemPolonski::computeMeanGapsInContact)
- .def("setMaxPressure", &BemPolonski::setMaxPressure)
- .def("getNbIterations", &BemPolonski::getNbIterations);
-
- py::class_(mod, "BemKato")
- .def(py::init&>())
- .def("computeEquilibrium", &BemKato::computeEquilibrium)
- .def("setMaxPressure", &BemKato::setMaxPressure);
-
- py::class_(mod, "BemGigiPol")
- .def(py::init&>())
- .def("computeEquilibrium", &BemGigipol::computeEquilibrium)
- .def("computeEquilibrium2", &BemGigipol::computeEquilibrium2)
- .def("computeEquilibriuminit", &BemGigipol::computeEquilibriuminit)
- .def("computeEquilibrium2init", &BemGigipol::computeEquilibrium2init)
- .def("computeTractionsFromDisplacements",
- &BemGigipol::computeTractionsFromDisplacements);
-
- py::class_(mod, "BemGrid")
- .def("computeDisplacementsFromTractions",
- &BemGrid::computeDisplacementsFromTractions)
- .def("computeSurfaceNormals", &BemGrid::computeSurfaceNormals)
- .def("computeInfluence", &BemGrid::computeInfluence)
- .def("setElasticity", &BemGrid::setElasticity)
- .def("getTractions", &BemGrid::getTractions,
- py::return_value_policy::reference_internal)
- .def("getDisplacements", &BemGrid::getDisplacements,
- py::return_value_policy::reference_internal)
- .def("getSurfaceNormals", &BemGrid::getSurfaceNormals,
- py::return_value_policy::reference_internal);
-
- py::class_(mod, "BemGridPolonski")
- .def(py::init&>());
-
- py::class_(mod, "BemGridCondat")
- .def(py::init&>())
- .def("computeEquilibrium", &BemGridCondat::computeEquilibrium);
-}
-
-} // namespace wrap
-
-} // namespace tamaas
diff --git a/python/wrap/core.cpp b/python/wrap/core.cpp
index d0f8562..52dd388 100644
--- a/python/wrap/core.cpp
+++ b/python/wrap/core.cpp
@@ -1,138 +1,105 @@
/**
* @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 .
*
*/
/* -------------------------------------------------------------------------- */
#include "logger.hh"
#include "statistics.hh"
-#include "surface_statistics.hh"
#include "wrap.hh"
#include
/* -------------------------------------------------------------------------- */
namespace tamaas {
/* -------------------------------------------------------------------------- */
namespace wrap {
using namespace py::literals;
/* -------------------------------------------------------------------------- */
template
void wrapStatistics(py::module& mod) {
auto name = makeDimensionName("Statistics", dim);
py::class_>(mod, name.c_str())
.def_static("computePowerSpectrum",
&Statistics::computePowerSpectrum,
py::return_value_policy::move)
.def_static("computeAutocorrelation",
&Statistics::computeAutocorrelation,
py::return_value_policy::move)
.def_static("computeMoments", &Statistics::computeMoments)
.def_static("computeSpectralRMSSlope",
&Statistics::computeSpectralRMSSlope)
.def_static("computeRMSHeights", &Statistics::computeRMSHeights)
.def_static("contact", &Statistics::contact, "tractions"_a,
"perimeter"_a = 0,
"Compute the (corrected) contact area. Permieter is the "
"total contact perimeter in number of segments.");
}
/* -------------------------------------------------------------------------- */
void wrapCore(py::module& mod) {
// Exposing logging facility
py::enum_(mod, "LogLevel")
.value("debug", LogLevel::debug)
.value("info", LogLevel::info)
.value("warning", LogLevel::warning)
.value("error", LogLevel::error);
mod.def("set_log_level", [](LogLevel level) { Logger::setLevel(level); });
py::class_(mod, "Logger")
.def(py::init<>())
.def("get",
[](Logger& logger, LogLevel level) -> Logger& {
logger.get(level);
return logger;
})
.def("__lshift__", [](Logger& logger, std::string msg) -> Logger& {
auto level = logger.getWishLevel();
if (level >= Logger::getCurrentLevel() and
not(mpi::rank() != 0 and level == LogLevel::info)) {
py::print(msg, "file"_a = py::module::import("sys").attr("stderr"));
}
return logger;
});
- // Exposing SurfaceStatistics (legacy)
-#if defined(TAMAAS_LEGACY_BEM)
- py::class_(mod, "SurfaceStatistics")
- .def_static("computeMaximum", &SurfaceStatistics::computeMaximum)
- .def_static("computeMinimum", &SurfaceStatistics::computeMinimum)
- .def_static("computeSpectralRMSSlope",
- &SurfaceStatistics::computeSpectralRMSSlope)
- .def_static("computeRMSSlope", &SurfaceStatistics::computeRMSSlope)
- .def_static("computeMoments", &SurfaceStatistics::computeMoments)
- .def_static("computeSkewness", &SurfaceStatistics::computeSkewness)
- .def_static("computeKurtosis", &SurfaceStatistics::computeKurtosis)
- .def_static("computeSpectralMeanCurvature",
- &SurfaceStatistics::computeSpectralMeanCurvature)
- .def_static("computeSpectralStdev",
- &SurfaceStatistics::computeSpectralStdev)
- .def_static("computeAnalyticFractalMoment",
- &SurfaceStatistics::computeAnalyticFractalMoment)
- .def_static("computePerimeter", &SurfaceStatistics::computePerimeter)
- .def_static("computeContactArea", &SurfaceStatistics::computeContactArea)
- .def_static("computeContactAreaRatio",
- &SurfaceStatistics::computeContactAreaRatio)
- .def_static("computeSpectralDistribution",
- &SurfaceStatistics::computeSpectralDistribution)
- .def_static("computeSum", &SurfaceStatistics::computeSum)
- .def_static("computeAutocorrelation",
- &SurfaceStatistics::computeAutocorrelation,
- py::return_value_policy::copy)
- .def_static("computePowerSpectrum",
- &SurfaceStatistics::computePowerSpectrum,
- py::return_value_policy::copy);
-#endif
-
wrapStatistics<1>(mod);
wrapStatistics<2>(mod);
mod.def("to_voigt",
[](const Grid& field) {
Logger().get(LogLevel::warning)
<< "tamaas.to_voigt deprecated. Use tamaas.compute.to_voigt\n";
if (field.getNbComponents() == 9) {
Grid voigt(field.sizes(), 6);
Loop::loop([](auto in, auto out) { out.symmetrize(in); },
range>(field),
range>(voigt));
return voigt;
} else
TAMAAS_EXCEPTION("Wrong number of components to symmetrize");
},
"Convert a 3D tensor field to voigt notation",
py::return_value_policy::copy);
}
} // namespace wrap
/* -------------------------------------------------------------------------- */
} // namespace tamaas
diff --git a/python/wrap/surface.cpp b/python/wrap/surface.cpp
index f5bad72..84967b5 100644
--- a/python/wrap/surface.cpp
+++ b/python/wrap/surface.cpp
@@ -1,215 +1,170 @@
/**
* @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 .
*
*/
/* -------------------------------------------------------------------------- */
#include "isopowerlaw.hh"
#include "regularized_powerlaw.hh"
#include "surface_generator_filter.hh"
-#include "surface_generator_filter_fft.hh"
#include "surface_generator_random_phase.hh"
#include "wrap.hh"
#include
/* -------------------------------------------------------------------------- */
namespace tamaas {
/* -------------------------------------------------------------------------- */
namespace wrap {
using namespace py::literals;
/* -------------------------------------------------------------------------- */
template
class PyFilter : public Filter {
public:
using Filter::Filter;
// Overriding pure virtual functions
void
computeFilter(GridHermitian& filter_coefficients) const override {
PYBIND11_OVERLOAD_PURE(void, Filter, computeFilter,
filter_coefficients);
}
};
template
void wrapFilter(py::module& mod) {
auto name = makeDimensionName("Filter", dim);
py::class_, std::shared_ptr>, PyFilter>(
mod, name.c_str())
.def(py::init<>())
.def("computeFilter",
(void (Filter::*)(GridHermitian&) const) &
Filter::computeFilter);
}
/* -------------------------------------------------------------------------- */
template
void wrapIsopowerlaw(py::module& mod) {
std::string name = makeDimensionName("Isopowerlaw", dim);
py::class_, Filter, std::shared_ptr>>(
mod, name.c_str())
.def(py::init<>())
.def_property("q0", &Isopowerlaw::getQ0, &Isopowerlaw::setQ0,
"Long wavelength cutoff")
.def_property("q1", &Isopowerlaw::getQ1, &Isopowerlaw::setQ1,
"Rolloff wavelength")
.def_property("q2", &Isopowerlaw::getQ2, &Isopowerlaw::setQ2,
"Short wavelength cutoff")
.def_property("hurst", &Isopowerlaw::getHurst,
&Isopowerlaw::setHurst, "Hurst exponent")
.def("rmsHeights", &Isopowerlaw::rmsHeights,
"Theoretical RMS of heights")
.def("moments", &Isopowerlaw::moments,
"Theoretical first 3 moments of spectrum")
.def("alpha", &Isopowerlaw::alpha, "Nayak's bandwidth parameter")
.def("rmsSlopes", &Isopowerlaw::rmsSlopes,
"Theoretical RMS of slopes");
name = makeDimensionName("RegularizedPowerlaw", dim);
py::class_, Filter,
std::shared_ptr>>(mod, name.c_str())
.def(py::init<>())
.def_property("q1", &RegularizedPowerlaw::getQ1,
&RegularizedPowerlaw::setQ1, "Long wavelength cutoff")
.def_property("q2", &RegularizedPowerlaw::getQ2,
&RegularizedPowerlaw::setQ2, "Short wavelength cutoff")
.def_property("hurst", &RegularizedPowerlaw::getHurst,
&RegularizedPowerlaw::setHurst, "Hurst exponent");
}
/* -------------------------------------------------------------------------- */
template
void wrapSurfaceGenerators(py::module& mod) {
std::string generator_name = makeDimensionName("SurfaceGenerator", dim);
py::class_>(mod, generator_name.c_str())
.def("buildSurface", &SurfaceGenerator::buildSurface,
py::return_value_policy::reference_internal)
.def("setSizes",
[](SurfaceGenerator& m, std::array s) {
TAMAAS_DEPRECATE("setSizes()", "the shape property");
m.setSizes(std::move(s));
})
.def("setRandomSeed",
[](SurfaceGenerator& m, long s) {
TAMAAS_DEPRECATE("setRandomSeed()", "the random_seed property");
m.setRandomSeed(s);
})
.def_property("random_seed", &SurfaceGenerator::getRandomSeed,
&SurfaceGenerator::setRandomSeed,
"Random generator seed")
.def_property("shape", &SurfaceGenerator::getSizes,
py::overload_cast>(
&SurfaceGenerator::setSizes),
"Global shape of surfaces");
std::string filter_name = makeDimensionName("SurfaceGeneratorFilter", dim);
py::class_, SurfaceGenerator>(
mod, filter_name.c_str())
.def(py::init<>(), "Default constructor")
.def(py::init>(),
"Initialize with global surface shape")
.def("setFilter",
[](SurfaceGeneratorFilter& m, std::shared_ptr> s) {
TAMAAS_DEPRECATE("setFilter()", "the spectrum property");
m.setSpectrum(std::move(s));
},
"Set PSD filter", "filter"_a)
.def("setSpectrum",
[](SurfaceGeneratorFilter& m, std::shared_ptr> s) {
TAMAAS_DEPRECATE("setSpectrum()", "the spectrum property");
m.setSpectrum(std::move(s));
},
"Set PSD filter", "filter"_a)
.def_property("spectrum", &SurfaceGeneratorFilter::getSpectrum,
&SurfaceGeneratorFilter::setSpectrum,
"Power spectrum object");
std::string random_name =
makeDimensionName("SurfaceGeneratorRandomPhase", dim);
py::class_, SurfaceGeneratorFilter>(
mod, random_name.c_str())
.def(py::init<>(), "Default constructor")
.def(py::init>(),
"Initialize with global surface shape");
}
-/* -------------------------------------------------------------------------- */
-// TODO [legacy] remove wrap
-void wrapSurfaceGeneratorFilterFFT(py::module& mod) {
- py::class_(mod, "SurfaceGeneratorFilterFFT")
- .def(py::init<>())
- .def("getQ0",
- [](SurfaceGeneratorFilterFFT& f) {
- return smart_pointer(&f.getQ0());
- })
- .def("getQ1",
- [](SurfaceGeneratorFilterFFT& f) {
- return smart_pointer(&f.getQ1());
- })
- .def("getQ2",
- [](SurfaceGeneratorFilterFFT& f) {
- return smart_pointer(&f.getQ2());
- })
- .def("getHurst",
- [](SurfaceGeneratorFilterFFT& f) {
- return smart_pointer(&f.getHurst());
- })
- .def("analyticalRMS", &SurfaceGeneratorFilterFFT::analyticalRMS)
- .def("buildSurface", &SurfaceGeneratorFilterFFT::buildSurface,
- py::return_value_policy::reference_internal)
- .def("getGridSize",
- [](SurfaceGeneratorFilterFFT& f) {
- return smart_pointer(&f.getGridSize());
- })
- .def("getRandomSeed",
- [](SurfaceGeneratorFilterFFT& f) {
- return smart_pointer(&f.getRandomSeed());
- })
- .def("getRMS",
- [](SurfaceGeneratorFilterFFT& f) {
- return smart_pointer(&f.getRMS());
- })
- .def("Init", &SurfaceGeneratorFilterFFT::Init);
-}
-
/* -------------------------------------------------------------------------- */
void wrapSurface(py::module& mod) {
wrapFilter<1>(mod);
wrapFilter<2>(mod);
wrapIsopowerlaw<1>(mod);
wrapIsopowerlaw<2>(mod);
wrapSurfaceGenerators<1>(mod);
wrapSurfaceGenerators<2>(mod);
-
- // legacy wrap
-#if defined(TAMAAS_LEGACY_BEM)
- wrapSurfaceGeneratorFilterFFT(mod);
-#endif
}
} // namespace wrap
/* -------------------------------------------------------------------------- */
} // namespace tamaas
diff --git a/src/SConscript b/src/SConscript
index 853ca6c..43d7bb7 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -1,189 +1,156 @@
# -*- 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 .
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_engine.cpp
fftw_engine.cpp
grid.cpp
grid_hermitian.cpp
statistics.cpp
-surface.cpp
tamaas.cpp
-legacy_types.cpp
loop.cpp
computes.cpp
logger.cpp
""".split()
-if env['legacy_bem']:
- core_list.append('surface_statistics.cpp')
core_list = prepend('core', core_list)
info_file = main_env.Substfile('tamaas_info.cpp', 'tamaas_info.cpp.in')
core_list.append(info_file)
# 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
integral_operator.cpp
be_engine.cpp
westergaard.cpp
elastic_functional.cpp
meta_functional.cpp
adhesion_functional.cpp
volume_potential.cpp
kelvin.cpp
mindlin.cpp
boussinesq.cpp
hooke.cpp
elasto_plastic/isotropic_hardening.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
dfsane_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)
# MPI API
mpi_list = """
fftw_mpi_engine.cpp
mpi_interface.cpp
""".split()
mpi_list = prepend('mpi', mpi_list)
# Assembling total list
rough_contact_list = \
core_list + generator_list + percolation_list + model_list + solvers_list
-# Adding legacy code
-if env['legacy_bem']:
- rough_contact_list += bem_list
-
# Adding GPU if needed
if env['backend'] == 'cuda':
rough_contact_list += gpu_list
# Adding MPI if needed
if env['use_mpi']:
rough_contact_list += mpi_list
# Adding extra warnings for Tamaas base lib
env.AppendUnique(CXXFLAGS=['-Wextra'])
# Allowing libTamaas.so to find libs in the same directory
env.AppendUnique(RPATH=["'$$$$ORIGIN'"])
# Build static library for packaging
if env['build_static_lib']:
env.AppendUnique(CXXFLAGS='-fPIC')
libTamaas = env.StaticLibrary('Tamaas', rough_contact_list)
# Build shared library (default)
else:
libTamaas = env.SharedLibrary('Tamaas', rough_contact_list,
SHLIBVERSION=env['version'])
# Defining alias for cpp builds
main_env.Alias('build-cpp', libTamaas)
# 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')
diff --git a/src/bem/bem_fft_base.cpp b/src/bem/bem_fft_base.cpp
deleted file mode 100644
index de00540..0000000
--- a/src/bem/bem_fft_base.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/**
- * @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 .
- *
- */
-/* -------------------------------------------------------------------------- */
-
-#include "bem_fft_base.hh"
-/* -------------------------------------------------------------------------- */
-#include "bem_meta_functional.hh"
-#include "elastic_energy_functional.hh"
-#include "legacy_types.hh"
-#include "surface_statistics.hh"
-/* -------------------------------------------------------------------------- */
-
-namespace tamaas {
-
-/* -------------------------------------------------------------------------- */
-BemFFTBase::BemFFTBase(Surface& p)
- : BemInterface(p), functional(new MetaFunctional(*this)),
- surface_tractions(p.size(), p.getL()),
- surface_displacements(p.size(), p.getL()),
- surface_spectral_input(p.size(), p.getL()),
- surface_spectral_output(p.size(), p.getL()),
- surface_spectral_influence_disp(p.size(), p.getL()),
- true_displacements(p.size(), p.getL()),
- old_displacements(p.size(), p.getL()), gap(p.size(), p.getL()),
- e_star(std::nan("")), tmp_coeff(1. / M_PI) {
- // this->setNumberOfThreads(this->nthreads);
- max_iterations = 5000;
- dump_freq = 100;
- this->functional->addFunctionalTerm(new ElasticEnergyFunctional(*this));
- std::cerr << this << " is setting up the surfaces";
- std::cerr << &p << " has size " << p.size() << std::endl;
-}
-
-/* -------------------------------------------------------------------------- */
-
-const Surface& BemFFTBase::getTractions() const {
- return surface_tractions;
-}
-/* -------------------------------------------------------------------------- */
-const Surface& BemFFTBase::getDisplacements() const {
- return surface_displacements;
-}
-/* -------------------------------------------------------------------------- */
-const Surface& BemFFTBase::getSpectralInfluenceOverDisplacement() {
- return surface_spectral_influence_disp;
-}
-/* -------------------------------------------------------------------------- */
-void BemFFTBase::setEffectiveModulus(Real e_star) {
- this->e_star = e_star;
- this->computeSpectralInfluenceOverDisplacement();
-}
-/* -------------------------------------------------------------------------- */
-Real BemFFTBase::getEffectiveModulus() { return this->e_star; }
-/* -------------------------------------------------------------------------- */
-void BemFFTBase::computeSpectralInfluenceOverDisplacement() {
- // if (std::isnan(tmp_coeff)) SURFACE_FATAL("constant tmp_coeff is nan");
- // if (std::isnan(e_star)) SURFACE_FATAL("constant e_star is nan");
-
- const Real L = surface.getL();
-
- auto wavevectors = FFTEngine::template computeFrequencies(
- surface_spectral_influence_disp.sizes());
-
- auto inf_it = surface_spectral_influence_disp.begin(),
- inf_begin = surface_spectral_influence_disp.begin();
- auto end = wavevectors.end(2);
- //#pragma omp parallel for firstprivate(inf_it)
- for (auto it = wavevectors.begin(2); it < end; ++it) {
- inf_it = inf_begin;
- inf_it += it - wavevectors.begin(2);
- legacy::VectorProxy q_vec(&(*it), 2);
- q_vec *= 2 * M_PI / L;
- Real q = q_vec.l2norm();
-
- // Influence function
- *inf_it = 2. / (q * e_star);
- }
-
- surface_spectral_influence_disp(0) = 0.;
-}
-
-/* -------------------------------------------------------------------------- */
-
-void BemFFTBase::computeDisplacementsFromTractions() {
- this->applyInfluenceFunctions(surface_tractions, surface_displacements);
-}
-
-/* -------------------------------------------------------------------------- */
-void BemFFTBase::computeTractionsFromDisplacements() {
- this->applyInverseInfluenceFunctions(surface_displacements,
- surface_tractions);
-}
-/* -------------------------------------------------------------------------- */
-
-void BemFFTBase::applyInfluenceFunctions(Surface& input,
- Surface& output) {
- this->engine.forward(input, surface_spectral_output);
- surface_spectral_output *= surface_spectral_influence_disp;
- this->engine.backward(output, surface_spectral_output);
-}
-
-/* -------------------------------------------------------------------------- */
-
-void BemFFTBase::applyInverseInfluenceFunctions(Surface& input,
- Surface& output) {
- this->engine.forward(input, surface_spectral_output);
- surface_spectral_output /= surface_spectral_influence_disp;
- surface_spectral_output(0) = 0;
- this->engine.backward(output, surface_spectral_output);
-}
-
-/* -------------------------------------------------------------------------- */
-
-void BemFFTBase::computeGaps() {
- UInt size = surface.size();
-
-#pragma omp parallel for
- for (UInt i = 0; i < size * size; i++) {
- gap(i) = true_displacements(i) - surface(i);
- }
-}
-
-/* -------------------------------------------------------------------------- */
-
-void BemFFTBase::computeTrueDisplacements() {
- this->true_displacements = this->surface_displacements;
-
- UInt n = surface.size();
- UInt size = n * n;
-
- Real shift = 1e300;
-
- for (UInt i = 0; i < size; ++i) {
- if (surface_displacements(i) - shift - surface(i) < 0.) {
- shift = surface_displacements(i) - surface(i);
- }
- }
-
- for (UInt i = 0; i < size; ++i) {
- true_displacements(i) = surface_displacements(i) - shift;
- }
-}
-
-/* -------------------------------------------------------------------------- */
-
-void BemFFTBase::addFunctional(Functional* new_funct) {
- this->functional->addFunctionalTerm(new_funct);
-}
-
-/* -------------------------------------------------------------------------- */
-
-} // namespace tamaas
diff --git a/src/bem/bem_fft_base.hh b/src/bem/bem_fft_base.hh
deleted file mode 100644
index f489bb1..0000000
--- a/src/bem/bem_fft_base.hh
+++ /dev/null
@@ -1,148 +0,0 @@
-/**
- * @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 .
- *
- */
-/* -------------------------------------------------------------------------- */
-
-#ifndef BEM_FFT_BASE_H
-#define BEM_FFT_BASE_H
-/* -------------------------------------------------------------------------- */
-#include "bem_functional.hh"
-#include "bem_interface.hh"
-#include "bem_meta_functional.hh"
-#include "surface_statistics.hh"
-/* -------------------------------------------------------------------------- */
-
-namespace tamaas {
-
-class BemFFTBase : public BemInterface {
- /* ------------------------------------------------------------------------ */
- /* Constructors/Destructors */
- /* ------------------------------------------------------------------------ */
-public:
- BemFFTBase(Surface& p);
-
- /* ------------------------------------------------------------------------ */
- /* Methods */
- /* ------------------------------------------------------------------------ */
-public:
- //! compute the displacement from traction input
- virtual void computeDisplacementsFromTractions();
- //! compute the tractions from displacement input
- virtual void computeTractionsFromDisplacements();
- //! apply influence funtions
- virtual void applyInfluenceFunctions(Surface& input,
- Surface& output);
- //! apply inverse influence funtions
- virtual void applyInverseInfluenceFunctions(Surface& input,
- Surface& output);
- //! compute the influcence coefficients of pressure over displacement
- virtual void computeSpectralInfluenceOverDisplacement();
- //! compute the displacements
- virtual void computeTrueDisplacements();
- //! compute the gap
- virtual void computeGaps();
-
- //! get the number of iterations
- virtual UInt getNbIterations() const = 0;
- //! get the convergence steps of iterations
- virtual const std::vector& getConvergenceIterations() const = 0;
-
- /* ------------------------------------------------------------------------ */
- /* Accessors */
- /* ------------------------------------------------------------------------ */
-public:
- //! return the influcence coefficients
- virtual const Surface& getSpectralInfluenceOverDisplacement();
- //! return the actual tractions
- virtual const Surface& getTractions() const;
- //! return the actual displacements
- virtual const Surface& getDisplacements() const;
- //! get the computed true displacement
- const Surface& getTrueDisplacements() { return true_displacements; };
- //! get the computed gap
- const Surface& getGap() { return gap; };
- //! set the elastic effective modulus
- void setEffectiveModulus(Real e_star);
- //! set the elastic effective modulus
- Real getEffectiveModulus();
- //! set the maximal number of iterations
- void setMaxIterations(UInt max_iter) { this->max_iterations = max_iter; };
- //! get the maximal number of iterations
- UInt getMaxIterations() { return this->max_iterations; };
- //! set dump freq
- void setDumpFreq(UInt dump_freq) { this->dump_freq = dump_freq; };
- //! get dump freq
- UInt getDumpFreq() { return this->dump_freq; };
- //! set functional
- void addFunctional(::tamaas::Functional* new_funct);
-
- /* ------------------------------------------------------------------------ */
- /* Class Members */
- /* ------------------------------------------------------------------------ */
-protected:
- //! Functional for optimization
- MetaFunctional* functional;
- //! surface tractions
- Surface surface_tractions;
- //! surface displacement
- Surface surface_displacements;
- //! surface input in spectral
- SurfaceComplex surface_spectral_input;
- //! surface output in spectral
- SurfaceComplex surface_spectral_output;
- //! surface influence coefficient over displacement
- Surface surface_spectral_influence_disp;
- //! shifted displacement in order to get the true displacement
- Surface true_displacements;
- //! old displacements (for stopping criterion)
- Surface old_displacements;
- //! computing of the gap
- Surface gap;
- //! Effective young modulus
- Real e_star;
- //! maximum of iterations
- UInt max_iterations;
- //! number of iterations
- UInt nb_iterations;
- //! number of iterations
- std::vector convergence_iterations;
- //! frequency at which to dump iteration info
- UInt dump_freq;
-
- /* ------------------------------------------------------------------------ */
- /* temporary trick about some obscure scaling factor */
- /* ------------------------------------------------------------------------ */
- /*
- 0 2 = 2*1
- 1 4 = 2*2
- 2 10 = 2*5
- 3 20 = 2*10
- 4 34 = 2*12
- */
-
- //#define tmp_coeff (2.*n/M_PI)
- //#define tmp_coeff (n/M_PI)
- const Real tmp_coeff;
-};
-
-} // namespace tamaas
-
-#endif /* BEM_FFT_BASE_H */
diff --git a/src/bem/bem_functional.cpp b/src/bem/bem_functional.cpp
deleted file mode 100644
index feff111..0000000
--- a/src/bem/bem_functional.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- *
- * @author Lucas Frérot
- *
- * @section LICENSE
- *
- * Copyright (©) 2016 EPFL (Ecole Polytechnique Fédérale de
- * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
- * Solides)
- *
- * Tamaas is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Tamaas 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 Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Tamaas. If not, see .
- *
- */
-
-/* -------------------------------------------------------------------------- */
-#include "bem_functional.hh"
-/* -------------------------------------------------------------------------- */
-
-namespace tamaas {
-
-Functional::Functional(BemFFTBase& bem) : parameters(), bem(bem), gradF(nullptr) {}
-
-Functional::~Functional() {}
-
-void Functional::setGradFPointer(Surface* p) { this->gradF = p; }
-
-void Functional::copyParameters(const std::map& /*params*/) {
- // auto it = params.begin();
- // auto end = params.end();
- // for (; it != end ; ++it) this->parameters.insert(*it);
-}
-
-} // namespace tamaas
diff --git a/src/bem/bem_functional.hh b/src/bem/bem_functional.hh
deleted file mode 100644
index 8ea30c8..0000000
--- a/src/bem/bem_functional.hh
+++ /dev/null
@@ -1,91 +0,0 @@
-/**
- *
- * @author Lucas Frérot
- *
- * @section LICENSE
- *
- * Copyright (©) 2016 EPFL (Ecole Polytechnique Fédérale de
- * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
- * Solides)
- *
- * Tamaas is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Tamaas 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 Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Tamaas. If not, see .
- *
- */
-
-/* -------------------------------------------------------------------------- */
-
-#ifndef __BEM_FUNCTIONAL_HH__
-#define __BEM_FUNCTIONAL_HH__
-
-#include "surface.hh"
-#include