diff --git a/tests/SConscript b/tests/SConscript index 63bae69..c6d38b3 100644 --- a/tests/SConscript +++ b/tests/SConscript @@ -1,233 +1,232 @@ # -*- mode:python; coding: utf-8 -*- # vim: set ft=python: # # Copyright (©) 2016-2024 EPFL (École Polytechnique Fédérale de Lausanne), # Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) # Copyright (©) 2020-2024 Lucas Frérot # # 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 SCons.Script import Split, Copy, Dir, Import from detect import FindGTest, FindPybind11 from collections.abc import Iterable # ------------------------------------------------------------------------------ def copyComStr(env, main): if 'SHCXXCOMSTR' in main: env['CXXCOMSTR'] = main['SHCXXCOMSTR'] if 'SHLINKCOMSTR' in main: env['LINKCOMSTR'] = main['SHLINKCOMSTR'] # ------------------------------------------------------------------------------ def make_python_tests(env): """Copy python tests to build directory""" test_env = env.Clone() test_files = Split(""" test_hertz.py test_matvec.py test_westergaard.py test_patch_westergaard.py test_patch_materials.py test_patch_nonperiodic.py test_surface.py test_hertz_disp.py - test_hertz_kato.py test_saturated_pressure.py test_flood_fill.py test_integral_operators.py test_dumper.py test_tangential.py test_boussinesq_surface.py test_voigt.py test_memory.py test_copy.py test_epic.py test_publications.py test_restart.py fftfreq.py conftest.py pytest.ini IsotropicLinearHardeningPlasticity.mfront """) if env['use_mpi']: test_files += ['test_mpi_routines.py', 'mpi_routines.py'] src_dir = "#/tests" targets = [ test_env.Command(file, test_env.File(file, src_dir), Copy("$TARGET", "$SOURCE")) for file in test_files ] test_env = env.Clone(tools=[pybind11]) # Helper module for integral operators test_env['SHLIBPREFIX'] = '' test_env.PrependUnique(LIBS=['Tamaas']) register = test_env.Pybind11Module( target="register_integral_operators", source=["register_integral_operators.cpp"]) Import('libTamaas') test_env.Depends(register, libTamaas) targets.append(register) return targets # ------------------------------------------------------------------------------ def compile_google_test(env, gtest_path): gtest_obj = env.Object('gtest.o', [env.File("src/gtest-all.cc", gtest_path)]) return env.StaticLibrary('gtest', gtest_obj) # ------------------------------------------------------------------------------ def make_google_tests(env): gtest_dir = Dir(env['GTEST_ROOT']) gtest_env = env.Clone(CPPPATH=[gtest_dir], CXXFLAGS=['-pthread', '-isystem', env.Dir('include', gtest_dir).path]) FindGTest(gtest_env) if not gtest_env.get('has_gtest'): return [] libgtest = None # Hugly hack to detect if we need to compile gtest submodule if env['GTEST_ROOT'] == '#third-party/googletest/googletest': gtest_path = str(gtest_dir) libgtest = compile_google_test(gtest_env, gtest_path) env.AppendUnique(CXXFLAGS=gtest_env['CXXFLAGS']) env.PrependUnique(LIBS=['Tamaas', env.subst('python${py_version}')]) google_test_files = Split(""" test_grid.cpp test_loop.cpp test_model.cpp test_static_types.cpp test_integration.cpp """) if env['use_fftw']: google_test_files += ['test_fftw.cpp'] if env['use_cuda']: google_test_files += ['test_cufft.cpp'] # Necessary for the tests that use pybind11 calls to python uses = [] if env['build_python']: google_test_files.append('test_fftfreq.cpp') uses = ['TAMAAS_USE_PYTHON'] if env['use_mpi']: google_test_files.append('test_mpi.cpp') defines = env['CPPDEFINES'] if not isinstance(defines, Iterable): defines = [defines] else: defines = list(defines) gtest_main = env.Object("tamaas_gtest_main.o", 'tamaas_gtest_main.cc', CPPDEFINES=defines + uses) env.AppendUnique(LIBPATH=[env.Dir('lib', gtest_dir).path, env.Dir('lib64', gtest_dir).path]) gtest_all = env.Program('test_gtest_all', google_test_files + [gtest_main], LIBS=(env['LIBS'] + ['gtest'])) Import('libTamaas') env.Depends(gtest_all, libTamaas) env.Depends(gtest_all, libgtest) copy_gtest = gtest_env.Command('test_gtest.py', '#tests/test_gtest.py', Copy('$TARGET', '$SOURCE')) return [gtest_all, copy_gtest] # ------------------------------------------------------------------------------ def make_bare_tests(env): rough = env.Program("test_rough_surface.cpp") Import('libTamaas') env.Depends(rough, libTamaas) return [rough] # ------------------------------------------------------------------------------ Import('main_env') # Setup of test environment test_env = main_env.Clone() test_env.AppendUnique( LIBPATH=['.', '../src'], RPATH=["'$$$$ORIGIN/../src'"], LINKFLAGS=['-pthread'], ) test_env.PrependUnique(LIBS=['Tamaas']) # Building tests that do not require any third party targets = make_bare_tests(test_env) # Build tests that required python bindings if test_env['build_python']: FindPybind11(test_env) test_env.Tool(pybind11) test_env.ParseConfig("${py_exec}-config --ldflags") test_env['CCFLAGS'] = [] targets += make_python_tests(test_env) # Building google tests targets += make_google_tests(test_env) # Target alias to build tests main_env.Alias('build-tests', targets) # Check if pytest is installed conf = Configure(test_env, custom_tests={'CheckPythonModule': CheckPythonModule}) has_pytest = conf.CheckPythonModule('pytest') conf.Finish() # Define a command to execute tests if has_pytest: pytest_env = test_env.Clone() pytest_env['pythonpath'] = pytest_env.subst('${build_dir}/python') pytest_env['ld_library_path'] = pytest_env.subst('${build_dir}/src') pytest_env.PrependENVPath('PYTHONPATH', pytest_env['pythonpath']) pytest_env.PrependENVPath('LD_LIBRARY_PATH', pytest_env['ld_library_path']) # Setting a moderate thread number pytest_env['ENV']['OMP_NUM_THREADS'] = "1" pytest_env['PYTESTOPTS'] = ['${"-v" if verbose else "-q"}'] test_target = pytest_env.Command( '.phony_test', targets, 'echo $$PYTHONPATH; echo $$LD_LIBRARY_PATH; ' '${py_exec} -m pytest $PYTESTOPTS ${TARGET.dir}') main_env.Alias('test', test_target) else: # We still define a target here so that `scons test` still works dummy_command(main_env, 'test', 'Cannot run tests: pytest is not installed') diff --git a/tests/test_hertz_kato.py b/tests/test_hertz_kato.py deleted file mode 100644 index a4e94bf..0000000 --- a/tests/test_hertz_kato.py +++ /dev/null @@ -1,61 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (©) 2016-2024 EPFL (École Polytechnique Fédérale de Lausanne), -# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) -# Copyright (©) 2020-2024 Lucas Frérot -# -# 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, print_function - -import numpy as np -import tamaas as tm -import pytest - -from numpy.linalg import norm - - -@pytest.fixture(scope="module") -def kato(hertz_coarse): - hertz = hertz_coarse - model = tm.ModelFactory.createModel(tm.model_type.basic_2d, - [hertz.domain_size, hertz.domain_size], - [hertz.n, hertz.n]) - model.E, model.nu = hertz.e_star, 0 - solver = tm.KatoSaturated(model, hertz.surface, 1e-12, 1e30) - solver.max_iter = 10000 - solver.solve(hertz.load) - return model, hertz - - -def test_contact_area(kato): - # Testing contact area against Hertz solution for solids of revolution - model, hertz = kato - contact_area = tm.Statistics2D.contact(model.traction) - hertz_area = tm.Statistics2D.contact(hertz.pressure) - area_error = np.abs(hertz_area - contact_area) / hertz_area - assert area_error < 1e-2 - - -def test_pressure(kato): - model, hertz = kato - error = norm(model['traction'] - hertz.pressure) / norm(hertz.pressure) - assert error < 5e-3 - - -def test_displacement(kato): - model, hertz = kato - error = norm(model['displacement'] - hertz.displacement)\ - / norm(hertz.displacement) - assert error < 2e-2