diff --git a/tests/SConscript b/tests/SConscript
index 8258cd9..a4f0f9e 100644
--- a/tests/SConscript
+++ b/tests/SConscript
@@ -1,200 +1,201 @@
# -*- 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 join
from SCons.Script import Split, Copy, Dir, Import
from detect import FindGTest, FindPybind11
# ------------------------------------------------------------------------------
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_westergaard.py
test_patch_westergaard.py
test_patch_plasticity.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_epic.py
fftfreq.py
conftest.py
""")
if env['legacy_bem']:
test_files += ['test_bem_grid.py', 'test_autocorrelation.py']
src_dir = "#/tests"
targets = [
test_env.Command(file, join(src_dir, file),
Copy("$TARGET", "$SOURCE"))
for file in test_files
]
test_env = env.Clone(tools=[pybind11])
# Helper module for integral operators
test_env['SHLIBPREFIX'] = ''
register = test_env.Pybind11Module(
target="register_integral_operators",
source=["register_integral_operators.cpp"],
LIBS=['Tamaas'])
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', [join(gtest_path, "src/gtest-all.cc")])
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',
join(str(gtest_dir), "include")])
colors = env['COLOR_DICT']
if not env['verbose']:
gtest_env['ARCOMSTR'] = u'{}[Ar]{} $TARGET'.format(colors['purple'],
colors['end'])
gtest_env['RANLIBCOMSTR'] = \
u'{}[Randlib]{} $TARGET'.format(colors['purple'],
colors['end'])
FindGTest(gtest_env)
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(LIBS=['Tamaas'],
CXXFLAGS=gtest_env['CXXFLAGS'])
google_test_files = Split("""
test_fft.cpp
test_grid.cpp
test_loop.cpp
test_model.cpp
test_static_types.cpp
test_integration.cpp
""")
# Some tests require pybind11
gtest_main = env.Object("tamaas_gtest_main.o", 'tamaas_gtest_main.cc')
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)
return [gtest_all]
# ------------------------------------------------------------------------------
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(LIBS=['Tamaas'], LIBPATH=['.'])
# 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
if test_env['use_googletest']:
targets += make_google_tests(test_env)
targets.append(test_env.Command('test_gtest.py', '#tests/test_gtest.py',
Copy('$TARGET', '$SOURCE')))
# Target alias to build tests
main_env.Alias('build-tests', targets)
# Check if pytest is installed
conf = Configure(main_env,
custom_tests={'CheckPythonModule': CheckPythonModule})
has_pytest = conf.CheckPythonModule('pytest')
conf.Finish()
# Define a command to execute tests
if has_pytest:
pytest_env = main_env.Clone()
pytest_env.PrependENVPath('PYTHONPATH',
pytest_env.subst('${build_dir}/python'))
test_target = pytest_env.Command('#/.phony_test', targets,
'${py_exec} -m pytest ${build_dir}/tests')
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/conftest.py b/tests/conftest.py
index befe1a6..d098de0 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -1,220 +1,234 @@
# -*- coding: utf-8 -*-
# @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, print_function
import numpy as np
import tamaas as tm
import pytest
from numpy.linalg import norm
def profile(func, size, mode, amplitude):
x = np.linspace(0, 1, size[0], endpoint=False, dtype=tm.dtype)
y = np.linspace(0, 1, size[1], endpoint=False, dtype=tm.dtype)
x, y = np.meshgrid(x, y, indexing='ij')
surface = amplitude * func(2*np.pi*x*mode[0]) * func(2*np.pi*y*mode[1])
return surface.copy()
@pytest.fixture(scope="session")
def tamaas_fixture():
tm.initialize()
yield None
tm.finalize()
class HertzFixture:
def __init__(self, n, load):
self.domain_size = 1
self.n = n
self.load = load
self.curvature = 0.1
self.radius = 1. / self.curvature
self.e_star = 1.
self.a = (3 * load / (4 * self.curvature * self.e_star))**(1. / 3.)
self.x = np.linspace(-self.domain_size / 2.,
self.domain_size / 2.,
self.n, dtype=tm.dtype)
self.y = self.x.copy()
self.x, self.y = np.meshgrid(self.x, self.y)
self._computeSurface()
self._computePressure()
self._computeDisplacement()
def _computeDisplacement(self):
r = np.sqrt(self.x**2 + self.y**2)
self.displacement = np.zeros_like(r)
contact = r < self.a
self.displacement[contact] = self.surface[contact]
self.displacement[~contact] = \
(self.surface[~contact]
+ self.a / (np.pi * self.radius) * np.sqrt(r[~contact]**2
- self.a**2)
+ (r[~contact]**2 - 2 * self.a**2) / (np.pi * self.radius)
* np.arccos(self.a / r[~contact]))
def _computePressure(self):
r = np.sqrt(self.x**2 + self.y**2)
self.pressure = np.zeros_like(r)
contact = np.where(r < self.a)
self.pressure[contact] = \
2 * self.e_star / (np.pi * self.radius) \
* np.sqrt(self.a**2 - r[contact]**2)
def _computeSurface(self):
self.surface = -1. / (2 * self.radius) * (self.x**2 + self.y**2)
@pytest.fixture(scope="module")
def hertz(tamaas_fixture):
return HertzFixture(1024, 0.00001)
@pytest.fixture(scope="module")
def hertz_coarse(tamaas_fixture):
return HertzFixture(512, 0.0001)
+@pytest.fixture(scope="module",
+ params=[tm.PolonskyKeerRey.pressure])
+def pkr(hertz, request):
+ model = tm.ModelFactory.createModel(tm.model_type.basic_2d,
+ [hertz.domain_size, hertz.domain_size],
+ [hertz.n, hertz.n])
+ model.setElasticity(hertz.e_star, 0)
+ solver = tm.PolonskyKeerRey(model, hertz.surface, 1e-12,
+ request.param,
+ request.param)
+ solver.solve(hertz.load)
+
+ return model, hertz
+
class WestergaardFixture:
def __init__(self, n, load):
self.domain_size = 1.
self.lamda = 1.
self.delta = 0.1
self.e_star = 1.
self.n = n
self.p_star = np.pi * self.e_star * self.delta / self.lamda
self.load = load * self.p_star
self.a = self.lamda / np.pi \
* np.arcsin(np.sqrt(self.load / self.p_star))
self.x = np.linspace(-self.domain_size / 2.,
self.domain_size / 2.,
self.n, endpoint=False, dtype=tm.dtype)
self._computeSurface()
self._computePressure()
self._computeDisplacement()
def _computeSurface(self):
self.surface = self.delta * np.cos(2 * np.pi * self.x / self.lamda)
def _computePressure(self):
self.pressure = np.zeros_like(self.surface)
contact = np.where(np.abs(self.x) < self.a)
self.pressure[contact] = 2 * self.load \
* (np.cos(np.pi * self.x[contact] / self.lamda)
/ np.sin(np.pi * self.a / self.lamda)**2) \
* np.sqrt(np.sin(np.pi * self.a / self.lamda)**2 -
np.sin(np.pi * self.x[contact] / self.lamda)**2)
def _computeDisplacement(self):
psi = np.pi * np.abs(self.x) / self.lamda
psi_a = np.pi * self.a / self.lamda
with np.errstate(invalid='ignore'): # get some warnings out of the way
self.displacement = (np.cos(2*psi) + 2 * np.sin(psi)
* np.sqrt(np.sin(psi)**2 - np.sin(psi_a)**2)
- 2 * np.sin(psi_a)**2 *
np.log((np.sin(psi) +
np.sqrt(np.sin(psi)**2
- np.sin(psi_a)**2))
/ np.sin(psi_a)))
contact = np.where(np.abs(self.x) < self.a)
self.displacement[contact] = np.cos(2*psi[contact])
self.displacement *= self.load * self.lamda / (np.pi * self.e_star
* np.sin(psi_a)**2)
@pytest.fixture(scope="module")
def westergaard(tamaas_fixture):
return WestergaardFixture(19683, 0.1)
class PatchWestergaard:
def __init__(self, model_type, domain, modes, size):
self.E = 3.
self.nu = 0.
self.e_star = self.E / (1 - self.nu**2)
self.n = size
self.domain = domain
self.model = tm.ModelFactory.createModel(model_type, domain,
size)
self.model.setElasticity(self.E, self.nu)
self.pressure = profile(np.cos, size, modes, 1)
self.solution = profile(np.cos, size, modes,
1 / (np.pi * self.e_star * norm(modes)))
@pytest.fixture(scope="module", params=[tm.model_type.basic_2d])
def patch_westergaard(tamaas_fixture, request):
return PatchWestergaard(request.param, [1., 1.], [3, 1], [6, 6])
class UniformPlasticity:
def __init__(self, model_type, domain, sizes):
self.n = sizes
self.domain = domain
self.model = tm.ModelFactory.createModel(model_type, domain,
sizes)
self.E_h = 0.1
self.sigma_y = 0.01
self.residual = tm.ModelFactory.createResidual(self.model,
sigma_y=self.sigma_y,
hardening=self.E_h)
self.model.E = 1.
self.model.nu = 0.
def solution(self, p):
E, nu = self.model.E, self.model.nu
E_h, sigma_y = self.E_h, self.sigma_y
mu = E / (2 * (1 + nu))
strain = -1 / (mu + E_h) * (p * (3 * mu + E_h) / (2 * mu)
- np.sign(p) * sigma_y)
dep = (2 * mu * np.abs(strain) - sigma_y) / (3 * mu + E_h)
plastic_strain = np.sign(strain) / 2 * dep * np.array([
-1, -1, 2, 0, 0, 0,
], dtype=tm.dtype)
stress = 2 * mu * (np.array([
0, 0, strain, 0, 0, 0
], dtype=tm.dtype) - plastic_strain)
return {
"stress": stress,
"plastic_strain": plastic_strain,
"cumulated_plastic_strain": dep
}
@pytest.fixture(scope="module", params=[tm.model_type.volume_2d])
def patch_isotropic_plasticity(tamaas_fixture, request):
return UniformPlasticity(request.param, [1., 1., 1.], [4, 4, 4])
diff --git a/tests/test_epic.py b/tests/test_epic.py
new file mode 100644
index 0000000..cf0aa08
--- /dev/null
+++ b/tests/test_epic.py
@@ -0,0 +1,57 @@
+# -*- coding: utf-8 -*-
+# @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, print_function
+
+import tamaas as tm
+
+from numpy.linalg import norm
+from tamaas.nonlinear_solvers import DFSANESolver
+
+
+def test_epic(pkr):
+ """Test the full elastic-plastic solve step in elasticity"""
+ # We use computed values from basic PKR to test
+ model_elastic, hertz = pkr
+
+ model = tm.ModelFactory.createModel(
+ tm.model_type.volume_2d,
+ [0.001, hertz.domain_size, hertz.domain_size],
+ [3, hertz.n, hertz.n]
+ )
+
+ model.setElasticity(hertz.e_star, 0)
+ residual = tm.ModelFactory.createResidual(
+ model,
+ sigma_y=1e2 * model.E,
+ hardening=0
+ )
+
+ epsolver = DFSANESolver(residual, model)
+ csolver = tm.PolonskyKeerRey(model, hertz.surface, 1e-12)
+
+ epic = tm.EPICSolver(csolver, epsolver, 1e-12)
+ epic.solve(hertz.load)
+
+ error = norm((model['traction'][..., 2] - model_elastic['traction'])
+ * (model['displacement'][0, ..., 2]
+ - model_elastic['displacement']))
+ error /= norm(hertz.pressure * hertz.displacement)
+ assert error < 1e-16
diff --git a/tests/test_hertz.py b/tests/test_hertz.py
index f5a9f40..867b097 100644
--- a/tests/test_hertz.py
+++ b/tests/test_hertz.py
@@ -1,68 +1,47 @@
# -*- coding: utf-8 -*-
# @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, print_function
import numpy as np
-import tamaas as tm
-import pytest
from numpy.linalg import norm
-@pytest.fixture(scope="module",
- params=[tm.PolonskyKeerRey.pressure])
-def pkr(hertz, request):
- model = tm.ModelFactory.createModel(tm.model_type.basic_2d,
- [hertz.domain_size, hertz.domain_size],
- [hertz.n, hertz.n])
- model.setElasticity(hertz.e_star, 0)
- solver = tm.PolonskyKeerRey(model, hertz.surface, 1e-12,
- request.param,
- request.param)
- solver.solve(hertz.load)
-
- return model, hertz
-
-
def test_contact_area(pkr):
# Testing contact area against Hertz solution for solids of revolution
model, hertz = pkr
- contact_area = np.sum(model.getTraction() > 0) / float(hertz.n**2)
- hertz_area = np.sum(hertz.pressure > 0) / float(hertz.n**2)
+ contact_area = np.mean(model.getTraction() > 0)
+ hertz_area = np.mean(hertz.pressure > 0)
area_error = np.abs(hertz_area - contact_area) / hertz_area
assert area_error < 1e-2
def test_pressure(pkr):
model, hertz = pkr
error = norm(model.getTraction() - hertz.pressure) / norm(hertz.pressure)
assert error < 5e-3
def test_displacement(pkr):
model, hertz = pkr
error = norm(model.getDisplacement() - hertz.displacement)\
/ norm(hertz.displacement)
assert error < 8e-3
-
-
-if __name__ == "__main__":
- print("Test meant to be run with pytest")
diff --git a/tests/test_integration.cpp b/tests/test_integration.cpp
index cd5fb97..253df49 100644
--- a/tests/test_integration.cpp
+++ b/tests/test_integration.cpp
@@ -1,165 +1,164 @@
/**
* @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 "fftransform.hh"
#include "integration/accumulator.hh"
#include "test.hh"
#include
#include
/* -------------------------------------------------------------------------- */
using namespace tamaas;
namespace ex = expolit;
static Real tol = 1e-13;
class AccumulatorTest : public ::testing::Test {
protected:
void SetUp() override {
nodal_values.resize(n);
for (auto&& grid : nodal_values) {
grid.setNbComponents(6);
grid.resize({nh, nh});
grid = 1;
}
accumulator.makeUniformMesh(nodal_values.size(), size);
wavevectors = FFTransform::computeFrequencies({nh, nh});
}
UInt n = 10, nh = 10;
Real size = 3;
std::vector> nodal_values;
Grid wavevectors;
Accumulator> accumulator;
};
TEST_F(AccumulatorTest, uniformMesh) {
auto& pos = this->accumulator.nodePositions();
std::vector sol(pos.size());
std::iota(sol.begin(), sol.end(), 0);
std::transform(sol.begin(), sol.end(), sol.begin(),
[&](auto& x) { return size * x / (sol.size() - 1); });
ASSERT_TRUE(compare(sol, pos, AreFloatEqual())) << "Uniform mesh fail";
}
// Litteral type
using Q = ex::Litteral;
TEST_F(AccumulatorTest, forward) {
// Setup for layer checking
std::vector layers_seen, layers_to_see(n);
std::iota(layers_to_see.begin(), layers_to_see.end(), 0);
// Setup for integral checking
constexpr Q q;
constexpr auto z = ex::Polynomial({0, 1});
constexpr auto g0 = ex::exp(q * z);
constexpr auto g1 = q * z * ex::exp(q * z);
for (auto&& tuple :
accumulator.forward(this->nodal_values, this->wavevectors)) {
auto&& l = std::get<0>(tuple);
auto&& xl_ = std::get<1>(tuple);
auto&& acc_g0 = std::get<2>(tuple);
auto&& acc_g1 = std::get<3>(tuple);
layers_seen.push_back(l);
// fundamental mode
auto testing = acc_g0(0, 0, 0);
ASSERT_NEAR(testing.real(), xl_, tol) << "Fundamental mode G0 fail";
testing = acc_g1(0, 0, 0);
ASSERT_NEAR(testing.real(), 0, tol) << "Fundamental mode G1 fail";
// other modes
testing = acc_g0(1, 0, 0);
ASSERT_NEAR(testing.real(), acc_g0(0, 1, 0).real(), tol) << "Symmetry fail";
ASSERT_NEAR(testing.imag(), acc_g0(0, 1, 0).imag(), tol) << "Symmetry fail";
testing = acc_g0(1, 1, 0);
Real sqrt_two = std::sqrt(Real(2));
auto ref_value = ex::definite_integral(
std::pair(0, xl_),
ex::substitute(ex::Constant({sqrt_two}), g0));
ASSERT_NEAR(testing.real(), ref_value, tol)
<< "Integration of exp(qy)*ϕ(y) fail";
testing = acc_g1(1, 1, 0);
ref_value = ex::definite_integral(
std::pair(0, xl_),
ex::substitute(ex::Constant({sqrt_two}), g1));
ASSERT_NEAR(testing.real(), ref_value, tol)
<< "Integration of qy*exp(qy)*ϕ(y) fail";
}
ASSERT_TRUE(compare(layers_seen, layers_to_see))
<< "Did not see correct layers";
}
TEST_F(AccumulatorTest, backward) {
// Setup for layer checking
std::vector layers_seen, layers_to_see(n);
std::iota(layers_to_see.rbegin(), layers_to_see.rend(), 0);
// Setup for integral checking
constexpr Q q;
constexpr auto z = ex::Polynomial({0, 1});
constexpr auto g0 = ex::exp(q * (z * (-1)));
constexpr auto g1 = q * z * ex::exp(q * ((-1) * z));
for (auto&& tuple : accumulator.backward(nodal_values, wavevectors)) {
auto&& l = std::get<0>(tuple);
auto&& xl_ = std::get<1>(tuple);
auto&& acc_g0 = std::get<2>(tuple);
auto&& acc_g1 = std::get<3>(tuple);
layers_seen.push_back(l);
- // fundamental mode
// fundamental mode
auto testing = acc_g0(0, 0, 0);
ASSERT_NEAR(testing.real(), size - xl_, tol) << "Fundamental mode G0 fail";
testing = acc_g1(0, 0, 0);
ASSERT_NEAR(testing.real(), 0, tol) << "Fundamental mode G1 fail";
// other modes
testing = acc_g0(1, 0, 0);
ASSERT_NEAR(testing.real(), acc_g0(0, 1, 0).real(), tol) << "Symmetry fail";
ASSERT_NEAR(testing.imag(), acc_g0(0, 1, 0).imag(), tol) << "Symmetry fail";
testing = acc_g0(1, 1, 0);
auto ref_value = ex::definite_integral(
std::make_pair(xl_, size),
ex::substitute(ex::Constant({std::sqrt(2)}), g0));
ASSERT_NEAR(testing.real(), ref_value, tol)
<< "Integration of exp(-qy)*ϕ(y) fail";
testing = acc_g1(1, 1, 0);
ref_value = ex::definite_integral(
std::make_pair(xl_, size),
ex::substitute(ex::Constant({std::sqrt(2)}), g1));
ASSERT_NEAR(testing.real(), ref_value, tol)
<< "Integration of qy*exp(-qy)*ϕ(y) fail";
}
ASSERT_TRUE(compare(layers_seen, layers_to_see))
<< "Did not see correct layers";
}
diff --git a/tests/test_westergaard.py b/tests/test_westergaard.py
index 7715487..79d4b65 100644
--- a/tests/test_westergaard.py
+++ b/tests/test_westergaard.py
@@ -1,78 +1,79 @@
# -*- coding: utf-8 -*-
# @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, print_function
-from numpy.linalg import norm
import tamaas as tm
import pytest
+from numpy.linalg import norm
+
@pytest.fixture(scope="module",
params=[tm.PolonskyKeerRey.pressure,
tm.PolonskyKeerRey.gap])
def pkr(westergaard, request):
loads = {
tm.PolonskyKeerRey.pressure: westergaard.load,
tm.PolonskyKeerRey.gap: 0.06697415181446396
}
model = tm.ModelFactory.createModel(tm.model_type.basic_1d, [1.],
[westergaard.n])
model.setElasticity(westergaard.e_star, 0)
solver = tm.PolonskyKeerRey(model, westergaard.surface, 1e-12,
request.param,
request.param)
solver.setMaxIterations(5000)
solver.solve(loads[request.param])
return model, westergaard
def test_energy(pkr):
model, sol = pkr
traction, displacement = model.getTraction(), model.getDisplacement()
error = norm((traction - sol.pressure)*(displacement - sol.displacement))
error /= norm(sol.pressure * sol.displacement)
assert error < 4e-6
def test_pkr_multi(westergaard):
model_basic = tm.ModelFactory.createModel(tm.model_type.basic_1d, [1.],
[westergaard.n])
model_volume = tm.ModelFactory.createModel(tm.model_type.volume_1d,
[1., 1.],
[20, westergaard.n])
pressures = {}
for model in [model_basic, model_volume]:
print(model)
solver = tm.PolonskyKeerRey(model, westergaard.surface, 1e-12,
tm.PolonskyKeerRey.pressure,
tm.PolonskyKeerRey.pressure)
solver.solve(westergaard.load)
pressures[model] = model.getTraction()
error = norm(pressures[model_basic] - pressures[model_volume][:, 1])\
/ westergaard.load
assert error < 1e-16
if __name__ == "__main__":
print("Test is meant to run with pytest")