diff --git a/examples/contact_mechanics/contact_explicit_static.cc b/examples/contact_mechanics/contact_explicit_static.cc new file mode 100644 index 000000000..3df2e58c3 --- /dev/null +++ b/examples/contact_mechanics/contact_explicit_static.cc @@ -0,0 +1,97 @@ +/** + * @file test_contact_mechanics_model.cc + * + * @author Mohit Pundir + * + * @date creation: Tue Apr 30 2019 + * @date last modification: Tue Apr 30 2019 + * + * @brief Test for contact mechanics model class + * + * @section LICENSE + * + * Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) + * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) + * + * Akantu 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. + * + * Akantu 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 Akantu. If not, see . + * + */ + +/* -------------------------------------------------------------------------- */ +#include "solid_mechanics_model.hh" +#include "contact_mechanics_model.hh" +#include "coupler_solid_contact.hh" +#include "non_linear_solver.hh" +#include "surface_selector.hh" +/* -------------------------------------------------------------------------- */ + +using namespace akantu; + +/* -------------------------------------------------------------------------- */ +int main(int argc, char *argv[]) { + + + const UInt spatial_dimension = 2; + initialize("material.dat", argc, argv); + + Mesh mesh(spatial_dimension); + mesh.read("hertz.msh"); + + CouplerSolidContact coupler(mesh); + + auto & solid = coupler.getSolidMechanicsModel(); + auto & contact = coupler.getContactMechanicsModel(); + + auto && selector = std::make_shared>( + "physical_names",solid); + solid.setMaterialSelector(selector); + + solid.initFull( _analysis_method = _static); + contact.initFull(_analysis_method = _implicit_contact); + + auto && surface_selector = std::make_shared(mesh); + contact.getContactDetector().setSurfaceSelector(surface_selector); + + solid.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "bottom"); + solid.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "bottom"); + solid.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "top"); + + coupler.initFull(_analysis_method = _implicit_contact); + + coupler.setBaseName("contact-explicit-static"); + coupler.addDumpFieldVector("displacement"); + coupler.addDumpFieldVector("velocity"); + coupler.addDumpFieldVector("normals"); + coupler.addDumpFieldVector("contact_force"); + coupler.addDumpFieldVector("external_force"); + coupler.addDumpFieldVector("internal_force"); + coupler.addDumpField("gaps"); + coupler.addDumpField("areas"); + coupler.addDumpField("blocked_dofs"); + coupler.addDumpField("grad_u"); + coupler.addDumpField("stress"); + + for (auto i : arange(max_steps)) { + + auto increment = 1e-4; + solid.applyBC(BC::Dirichlet::IncrementValue(-increment, _y), "top"); + + coupler.solveStep(); + coupler.dump(); + } + + finalize(); + return EXIT_SUCCESS; +} + diff --git a/test/test_model/test_contact_mechanics_model/flat_on_flat.geo b/test/test_model/test_contact_mechanics_model/flat_on_flat.geo new file mode 100644 index 000000000..62e58fb90 --- /dev/null +++ b/test/test_model/test_contact_mechanics_model/flat_on_flat.geo @@ -0,0 +1,40 @@ +h = 4.0; +height = 1.0; +length = 1.0; +epsilon=1e-3; + +Point(1) = {0, 0, 0, h*0.1}; +Point(2) = {length, 0, 0, h*0.1}; +Point(3) = {length, height/2-epsilon, 0, h*0.1}; +Point(4) = {length, height, 0, h*0.2}; +Point(5) = {0, height, 0, h*0.2}; +Point(6) = {0, height/2+epsilon, 0, h*0.2}; +Point(7) = {length, height/2+epsilon, 0, h*0.2}; +Point(8) = {0, height/2-epsilon, 0, h*0.1}; + +Line(1) = {1, 2}; +Line(2) = {2, 3}; +Line(3) = {7, 4}; +Line(4) = {4, 5}; +Line(5) = {5, 6}; +Line(6) = {6, 7}; +Line(7) = {8, 1}; +Line(8) = {3, 8}; + +Line Loop(1) = {1, 2, 8, 7}; +Line Loop(2) = {3, 4, 5, 6}; + +Plane Surface(1) = {1}; +Plane Surface(2) = {2}; + +Physical Line ("top") = {4}; +Physical Line ("bottom") = {1}; + +Physical Line ("contact_top") = {6}; +Physical Line ("contact_bottom") = {8}; + +Physical Surface("bot_body") = {1}; +Physical Surface("top_body") = {2}; + +Transfinite Surface{1, 2}; +Recombine Surface{1, 2}; \ No newline at end of file diff --git a/test/test_model/test_contact_mechanics_model/test_detector/data/cohesive_1D.geo b/test/test_model/test_contact_mechanics_model/test_detector/data/cohesive_1D.geo new file mode 100644 index 000000000..ce535838e --- /dev/null +++ b/test/test_model/test_contact_mechanics_model/test_detector/data/cohesive_1D.geo @@ -0,0 +1,18 @@ +h = 0.5; + +Point(1) = { 1., 0., 0., h}; +Point(3) = { 0., 0., 0., h}; +Point(4) = { 0., 0., 0., h}; +Point(2) = {-1., 0., 0., h}; + +Line(1) = {2, 3}; +Line(2) = {4, 1}; + +Physical Point ("loading") = {1}; +Physical Point ("fixed") = {2}; + +Physical Point ("master") = {3}; +Physical Point ("slave") = {4}; + +Physical Line ("master_body") = {1}; +Physical Line ("slave_body") = {2}; \ No newline at end of file diff --git a/test/test_model/test_contact_mechanics_model/test_detector/data/cohesive_strait_2D.geo b/test/test_model/test_contact_mechanics_model/test_detector/data/cohesive_strait_2D.geo new file mode 100644 index 000000000..29491a861 --- /dev/null +++ b/test/test_model/test_contact_mechanics_model/test_detector/data/cohesive_strait_2D.geo @@ -0,0 +1,39 @@ +h = 0.4; + +y = 1; +x = 2; + +Point(1) = { x/2., y/2, 0, h}; +Point(2) = {-x/2., y/2, 0, h}; +Point(3) = {-x/2.,-y/2, 0, h}; +Point(4) = { x/2.,-y/2, 0, h}; +Point(5) = {-x/2., 0, 0, h}; +Point(6) = { x/2., 0, 0, h}; +Point(7) = {-x/2., 0, 0, h}; +Point(8) = { x/2., 0, 0, h}; + +Line(1) = {1, 2}; +Line(2) = {2, 5}; +Line(3) = {5, 6}; +Line(4) = {6, 1}; + +Line(5) = {7, 3}; +Line(6) = {3, 4}; +Line(7) = {4, 8}; +Line(8) = {8, 7}; + +Line Loop(1) = {1, 2, 3, 4}; +Line Loop(2) = {5, 6, 7, 8}; + +Plane Surface(1) = {1}; +Plane Surface(2) = {2}; + +Physical Line("fixed") = {6}; +Physical Line("loading") = {1}; +Physical Line("master") = {3}; +Physical Line("slave") = {8}; + +Physical Line("sides") = {2, 5, 7, 4}; + +Physical Surface("master_body") = {1}; +Physical Surface("slave_body") = {2}; diff --git a/test/test_model/test_contact_mechanics_model/test_detector/data/cohesive_strait_2D.msh b/test/test_model/test_contact_mechanics_model/test_detector/data/cohesive_strait_2D.msh new file mode 100644 index 000000000..f9a6e5773 --- /dev/null +++ b/test/test_model/test_contact_mechanics_model/test_detector/data/cohesive_strait_2D.msh @@ -0,0 +1,51 @@ +$MeshFormat +2.2 0 8 +$EndMeshFormat +$PhysicalNames +4 +1 1 "fixed" +1 2 "loading" +1 3 "insertion" +2 4 "body" +$EndPhysicalNames +$Nodes +13 +1 1 1 0 +2 -1 1 0 +3 -1 -1 0 +4 1 -1 0 +5 -1 0 0 +6 1 0 0 +7 2.752797989558076e-12 1 0 +8 -2.752797989558076e-12 0 0 +9 -2.752797989558076e-12 -1 0 +10 -0.4999999999986235 0.5000000000027528 0 +11 0.5000000000013765 0.5 0 +12 0.4999999999986235 -0.5 0 +13 -0.5000000000013765 -0.5 0 +$EndNodes +$Elements +22 +1 1 4 2 1 1 1 1 7 +2 1 4 2 1 1 1 7 2 +3 1 2 3 3 5 8 +4 1 2 3 3 8 6 +5 1 4 1 6 1 3 3 9 +6 1 4 1 6 1 3 9 4 +7 2 5 4 1 2 1 -2 11 7 10 +8 2 5 4 1 2 2 -1 8 11 10 +9 2 5 4 1 2 1 -2 2 10 7 +10 2 6 4 1 3 2 -1 -3 6 11 8 +11 2 6 4 1 3 1 -2 -3 1 11 6 +12 2 6 4 1 3 1 -2 -3 2 5 10 +13 2 6 4 1 3 2 -1 -3 5 8 10 +14 2 5 4 1 2 1 -2 1 7 11 +15 2 5 4 2 2 2 -3 12 8 13 +16 2 5 4 2 2 3 -2 9 12 13 +17 2 5 4 2 2 3 -2 4 12 9 +18 2 6 4 2 3 2 -1 -3 6 8 12 +19 2 6 4 2 3 3 -1 -2 3 13 5 +20 2 6 4 2 3 3 -1 -2 4 6 12 +21 2 5 4 2 2 3 -2 3 9 13 +22 2 6 4 2 3 2 -1 -3 5 13 8 +$EndElements diff --git a/test/test_model/test_contact_mechanics_model/test_detector/data/cohesive_strait_2D_mixte.geo b/test/test_model/test_contact_mechanics_model/test_detector/data/cohesive_strait_2D_mixte.geo new file mode 100644 index 000000000..eac33c855 --- /dev/null +++ b/test/test_model/test_contact_mechanics_model/test_detector/data/cohesive_strait_2D_mixte.geo @@ -0,0 +1,43 @@ +h = 0.4; + +y = 1; +x = 2; + +Point(1) = { x/2., y/2, 0, h}; +Point(2) = {-x/2., y/2, 0, h}; +Point(3) = {-x/2.,-y/2, 0, h}; +Point(4) = { x/2.,-y/2, 0, h}; +Point(5) = {-x/2., 0, 0, h}; +Point(6) = { x/2., 0, 0, h}; +Point(7) = {-x/2., 0, 0, h}; +Point(8) = { x/2., 0, 0, h}; + +Line(1) = {1, 2}; +Line(2) = {2, 5}; +Line(3) = {5, 6}; +Line(4) = {6, 1}; + +Line(5) = {7, 3}; +Line(6) = {3, 4}; +Line(7) = {4, 8}; +Line(8) = {8, 7}; + +Line Loop(1) = {1, 2, 3, 4}; +Line Loop(2) = {5, 6, 7, 8}; + +Plane Surface(1) = {1}; +Plane Surface(2) = {2}; + +Physical Line("fixed") = {6}; +Physical Line("loading") = {1}; +Physical Line("master") = {3}; +Physical Line("slave") = {8}; + +Physical Line("sides") = {2, 5, 7, 4}; + +Physical Surface("master_body") = {1}; +Physical Surface("slave_body") = {2}; + +Recombine Surface {2}; +Transfinite Surface {2}; +Mesh.SecondOrderIncomplete = 1; diff --git a/test/test_model/test_contact_mechanics_model/test_detector/data/cohesive_strait_2D_structured.geo b/test/test_model/test_contact_mechanics_model/test_detector/data/cohesive_strait_2D_structured.geo new file mode 100644 index 000000000..07974bcd7 --- /dev/null +++ b/test/test_model/test_contact_mechanics_model/test_detector/data/cohesive_strait_2D_structured.geo @@ -0,0 +1,43 @@ +h = 0.2; + +y = 1; +x = 2; + +Point(1) = { x/2., y/2, 0, h}; +Point(2) = {-x/2., y/2, 0, h}; +Point(3) = {-x/2.,-y/2, 0, h}; +Point(4) = { x/2.,-y/2, 0, h}; +Point(5) = {-x/2., 0, 0, h}; +Point(6) = { x/2., 0, 0, h}; +Point(7) = {-x/2., 0, 0, h}; +Point(8) = { x/2., 0, 0, h}; + +Line(1) = {1, 2}; +Line(2) = {2, 5}; +Line(3) = {5, 6}; +Line(4) = {6, 1}; + +Line(5) = {7, 3}; +Line(6) = {3, 4}; +Line(7) = {4, 8}; +Line(8) = {8, 7}; + +Line Loop(1) = {1, 2, 3, 4}; +Line Loop(2) = {5, 6, 7, 8}; + +Plane Surface(1) = {1}; +Plane Surface(2) = {2}; + +Physical Line("fixed") = {6}; +Physical Line("loading") = {1}; +Physical Line("master") = {3}; +Physical Line("slave") = {8}; + +Physical Line("sides") = {2, 5, 7, 4}; + +Physical Surface("master_body") = {1}; +Physical Surface("slave_body") = {2}; + +Recombine Surface "*"; +Transfinite Surface "*"; +Mesh.SecondOrderIncomplete = 1; diff --git a/test/test_model/test_contact_mechanics_model/test_detector/data/cohesive_strait_3D.geo b/test/test_model/test_contact_mechanics_model/test_detector/data/cohesive_strait_3D.geo new file mode 100644 index 000000000..3242a10d2 --- /dev/null +++ b/test/test_model/test_contact_mechanics_model/test_detector/data/cohesive_strait_3D.geo @@ -0,0 +1,37 @@ +h = 0.7; + +z = 1; +y = 2; +x = 2; + +Point(1) = { x/2, y/2, -z/2, h}; +Point(2) = {-x/2, y/2, -z/2, h}; +Point(3) = {-x/2,-y/2, -z/2, h}; +Point(4) = { x/2,-y/2, -z/2, h}; + +Point(5) = {-x/2, 0, -z/2, h}; +Point(6) = { x/2, 0, -z/2, h}; + +Line(1) = {1, 2}; +Line(2) = {2, 5}; +Line(3) = {5, 6}; +Line(4) = {6, 1}; + +Line(5) = {5, 3}; +Line(6) = {3, 4}; +Line(7) = {4, 6}; + +Line Loop(1) = {1, 2, 3, 4}; +Line Loop(2) = {-3, 5, 6, 7}; +Plane Surface(1) = {1}; +Plane Surface(2) = {2}; +Extrude {0, 0, z} { + Surface{1}; Surface{2}; +} + +Physical Surface("fixed") = {46}; +Physical Surface("insertion") = {24}; +Physical Surface("loading") = {16}; +Physical Surface("sides") = {1, 20, 29, 28, 50, 2, 51, 42}; + +Physical Volume("body") = {1, 2}; diff --git a/test/test_model/test_contact_mechanics_model/test_detector/data/cohesive_strait_3D_structured.geo b/test/test_model/test_contact_mechanics_model/test_detector/data/cohesive_strait_3D_structured.geo new file mode 100644 index 000000000..c54ed8705 --- /dev/null +++ b/test/test_model/test_contact_mechanics_model/test_detector/data/cohesive_strait_3D_structured.geo @@ -0,0 +1,40 @@ +h = 0.5; + +Point(1) = { 1, 1, -.5, h}; +Point(2) = {-1, 1, -.5, h}; +Point(3) = {-1,-1, -.5, h}; +Point(4) = { 1,-1, -.5, h}; + +Point(5) = {-1, 0, -.5, h}; +Point(6) = { 1, 0, -.5, h}; + +Line(1) = {1, 2}; +Line(2) = {2, 5}; +Line(3) = {5, 6}; +Line(4) = {6, 1}; + +Line(5) = {5, 3}; +Line(6) = {3, 4}; +Line(7) = {4, 6}; + +Line Loop(1) = {1, 2, 3, 4}; +Line Loop(2) = {-3, 5, 6, 7}; +Plane Surface(1) = {1}; +Plane Surface(2) = {2}; +Extrude {0, 0, 1} { + Surface{1}; Surface{2}; +} + +Physical Surface("fixed") = {46}; +Physical Surface("insertion") = {24}; +Physical Surface("loading") = {16}; +Physical Surface("sides") = {1, 20, 29, 28, 50, 2, 51, 42}; + +Physical Volume("body") = {1, 2}; + +Transfinite Surface "*"; +Transfinite Volume "*"; + +Recombine Surface "*"; + +Mesh.SecondOrderIncomplete = 1; diff --git a/test/test_model/test_contact_mechanics_model/test_detector/data/test.msh b/test/test_model/test_contact_mechanics_model/test_detector/data/test.msh new file mode 100644 index 000000000..1d659722f --- /dev/null +++ b/test/test_model/test_contact_mechanics_model/test_detector/data/test.msh @@ -0,0 +1,51 @@ +$MeshFormat +2.2 0 8 +$EndMeshFormat +$PhysicalNames +4 +1 1 "fixed" +1 2 "loading" +1 3 "insertion" +2 4 "body" +$EndPhysicalNames +$Nodes +13 +1 1 1 0 +2 -1 1 0 +3 -1 -1 0 +4 1 -1 0 +5 -1 0 0 +6 1 0 0 +7 2.752797989558076e-12 1 0 +8 -2.752797989558076e-12 0 0 +9 -2.752797989558076e-12 -1 0 +10 -0.4999999999986235 0.5000000000027528 0 +11 0.5000000000013765 0.5 0 +12 0.4999999999986235 -0.5 0 +13 -0.5000000000013765 -0.5 0 +$EndNodes +$Elements +22 +1 1 2 2 1 1 7 +2 1 2 2 1 7 2 +3 1 2 3 3 5 8 +4 1 2 3 3 8 6 +5 1 2 1 6 3 9 +6 1 2 1 6 9 4 +7 2 2 4 1 11 7 10 +8 2 2 4 1 8 11 10 +9 2 2 4 1 2 10 7 +10 2 2 4 1 6 11 8 +11 2 2 4 1 1 11 6 +12 2 2 4 1 2 5 10 +13 2 2 4 1 5 8 10 +14 2 2 4 1 1 7 11 +15 2 2 4 2 12 8 13 +16 2 2 4 2 9 12 13 +17 2 2 4 2 4 12 9 +18 2 2 4 2 6 8 12 +19 2 2 4 2 3 13 5 +20 2 2 4 2 4 6 12 +21 2 2 4 2 3 9 13 +22 2 2 4 2 5 13 8 +$EndElements diff --git a/test/test_model/test_contact_mechanics_model/test_detector/test_detection.cc b/test/test_model/test_contact_mechanics_model/test_detector/test_detection.cc new file mode 100644 index 000000000..4e5ba3fee --- /dev/null +++ b/test/test_model/test_contact_mechanics_model/test_detector/test_detection.cc @@ -0,0 +1,61 @@ +/** + * @file test_detection.cc + * + * @author Mohit Pundir + * + * @date creation: Sat Feb 29 2020 + * @date last modification: Sat Feb 29 2020 + * + * @brief Generic test for detection between different element types + * + * @section LICENSE + * + * Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) + * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) + * + * Akantu 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. + * + * Akantu 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 Akantu. If not, see . + * + */ + +/* -------------------------------------------------------------------------- */ +#include "aka_iterators.hh" +#include "communicator.hh" +#include "test_detection_fixture.hh" +/* -------------------------------------------------------------------------- */ + + +TYPED_TEST(TestCMMDFixture, Implicit) { + + this->analysis_method = _static; + this->detection_type = _implicit_contact; + + this->testImplicit(); + + this->checkGap(); + +} + + +TYPED_TEST(TestCMMDFixture, Explicit) { + + this->analysis_method = _static; + this->detection_type = _explicit_contact; + + this->testExplicit(); + + this->checkGap(); + +} + + diff --git a/test/test_model/test_contact_mechanics_model/test_detector/test_detection_fixture.hh b/test/test_model/test_contact_mechanics_model/test_detector/test_detection_fixture.hh new file mode 100644 index 000000000..779295793 --- /dev/null +++ b/test/test_model/test_contact_mechanics_model/test_detector/test_detection_fixture.hh @@ -0,0 +1,224 @@ +/** + * @file test_detection_fixture.hh + * + * @author Mohit Pundir + * + * @date creation: Sat Feb 29 2020 + * @date last modification: Sat Feb 29 2020 + * + * @brief Contact detection test fixture + * + * @section LICENSE + * + * Copyright (©) 2016-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) + * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) + * + * Akantu 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. + * + * Akantu 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 Akantu. If not, see . + * + */ +/* -------------------------------------------------------------------------- */ +#include "contact_mechanics_mdoel.hh" +#include "solid_mechanics_model.hh" +#include "test_gtest_utils.hh" +/* -------------------------------------------------------------------------- */ +#include +#include +/* -------------------------------------------------------------------------- */ + +#ifndef __AKANTU_TEST_DETECTION_FIXTURE_HH__ +#define __AKANTU_TEST_DETECTION_FIXTURE_HH__ + +using namespace akantu; + +template <::akantu::AnalysisMethod t> +using analysis_method_t std::integral_constant<::akantu::AnalysisMethod, t>; + +class StrainIncrement : public BC::Functor { +public: + StrainIncrement(const Matrix & strain, BC::Axis dir) + : strain_inc(strain), dir(dir) {} + + void operator()(UInt /*node*/, Vector & flags, Vector & primal, + const Vector & coord) const { + if (std::abs(coord(dir)) < 1e-8) { + return; + } + + flags.set(true); + primal += strain_inc * coord; + } + + static const BC::Functor::Type type = BC::Functor::_dirichlet; + +private: + Matrix strain_inc; + BC::Axis dir; +}; + +template class TestCMMDFixture : public ::testing::Test { +public: + + static constexpr ElementType type_1 = std::tuple_element_t<1, param_>::value; + static constexpr ElementType type_2 = std::tuple_element_t<2, param_>::value; + + void Setup() override { + mesh = std::make_unique(this->dim); + if (Communicator::getStaticCommunicator().whoAmI() == 0) { + ASSERT_NO_THROW({ mesh->read(this->mesh_name); }); + } + mesh->distribute(); + } + + void TearDown() override { + solid.reset(nullptr); + contact.reset(nullptr); + mesh.reset(nullptr); + } + + void createModel() { + solid = std::make_unique(*mesh); + solid->initFull(_analysis_method = this->analysis_method); + + contact = std::make_unique(*mesh); + contact->initFull(_analysis_method = this->detection_type); + auto && surface_selector = std::make_shared(*mesh); + contact->getContactDetector().setSurfaceSelector(surface_selector); + } + + void setInitialCondition(const Matrix & strain) { + for (auto && data : + zip(make_view(this->mesh->getNodes(), this->dim), + make_view(this->solid->getDisplacement(), this->dim))) { + const auto & pos = std::get<0>(data); + auto & disp = std::get<1>(data); + disp = strain * pos; + } + } + + void steps(const Matrix & strain) { + StrainIncrement functor((1. / 300) * strain, this->dim == 1 ? _x : _y); + + for (auto _ [[gnu::unused]] : arange(nb_steps)) { + this->solid->applyBC(functor, "loading"); + this->solid->applyBC(functor, "fixed"); + this->solid->solveStep(); + } + } + + void testImplicit() { + this->createModel(); + auto & mat_el = this->solid->getMaterial("body"); + + SCOPED_TRACE(std::to_string(this->dim) + "D - " + std::to_string(type_1) + + ":" + std::to_string(type_2)); + + if (this->dim > 1) + this->model->applyBC(BC::Dirichlet::FlagOnly(_y), "sides"); + if (this->dim > 2) + this->model->applyBC(BC::Dirichlet::FlagOnly(_z), "sides"); + + Real E = mat_el.get("E"); + Real nu = mat_el.get("nu"); + + + Matrix strain; + if (dim == 1) { + strain = {{1.}}; + } else if (dim == 2) { + strain = {{-nu, 0.}, {0., 1. - nu}}; + strain *= (1. + nu); + } else if (dim == 3) { + strain = {{-nu, 0., 0.}, {0., 1., 0.}, {0., 0., -nu}}; + } + + this->setInitialCondition((1 - 1e-5) * strain); + this->steps(1e-2 * strain); + + this->contact->search(); + } + + void testExplicit() { + this->createModel(); + auto & mat_el = this->solid->getMaterial("body"); + + SCOPED_TRACE(std::to_string(this->dim) + "D - " + std::to_string(type_1) + + ":" + std::to_string(type_2)); + + if (this->dim > 1) + this->model->applyBC(BC::Dirichlet::FlagOnly(_y), "sides"); + if (this->dim > 2) + this->model->applyBC(BC::Dirichlet::FlagOnly(_z), "sides"); + + Real E = mat_el.get("E"); + Real nu = mat_el.get("nu"); + + + Matrix strain; + if (dim == 1) { + strain = {{-1.}}; + } else if (dim == 2) { + strain = {{-nu, 0.}, {0., 1. - nu}}; + strain *= (1. + nu); + } else if (dim == 3) { + strain = {{-nu, 0., 0.}, {0., 1., 0.}, {0., 0., -nu}}; + } + + this->setInitialCondition((1 - 1e-5) * strain); + this->steps(1e-2 * strain); + + this->contact->search(); + + } + + bool checkGap() { + + } + + bool checkNormal() { + + } + + bool checkCovariantBasis() { + + } + + + +protected: + std::unique_ptr mesh; + std::unique_ptr solid; + std::unique_ptr contact; + + std::string mesh_name{std::to_string(detection_type) + std::to_string(type_1) + + (type_1 == type_2 ? "" : std::to_string(type_2)) + + ".msh"}; + + AnalysisMethod analysis_method; + DetectionType detection_type; +}; + +/* -------------------------------------------------------------------------- */ + + +using element_types = gtest_list_t, + std::tuple< _element_type_triangle_3, _element_type_triangle_3>, + std::tuple<_element_type_triangle_3, _element_type_quadrangle_4>, + std::tuple<_element_type_quadrangle_4, _element_type_quadrange_4>, + std::tuple<_element_type_tetrahedron_6, _element_type_tetrahedron_6> >>; + + +TYPED_TEST_SUITE(TestCMMDFixture, detection_types) + +#endif diff --git a/test/test_model/test_contact_mechanics_model/test_explicit_dynamic.cc b/test/test_model/test_contact_mechanics_model/test_explicit_dynamic.cc new file mode 100644 index 000000000..10ca5c71b --- /dev/null +++ b/test/test_model/test_contact_mechanics_model/test_explicit_dynamic.cc @@ -0,0 +1,114 @@ +/* -------------------------------------------------------------------------- */ +#include "contact_mechanics_model.hh" +#include "coupler_solid_contact.hh" +#include "non_linear_solver.hh" +#include "solid_mechanics_model.hh" +#include "surface_selector.hh" +/* -------------------------------------------------------------------------- */ + +using namespace akantu; + +int main(int argc, char * argv[]) { + + UInt max_steps = 20000; + Real max_weight = 0.02; + UInt damping_interval = 10; + Real damping_ratio = 0.9; + + std::string mesh_file = "flat_on_flat.msh"; + std::string material_file = "material.dat"; + + const UInt spatial_dimension = 2; + + initialize(material_file, argc, argv); + + Mesh mesh(spatial_dimension); + mesh.read(mesh_file); + + CouplerSolidContact coupler(mesh); + + auto & solid = coupler.getSolidMechanicsModel(); + auto & contact = coupler.getContactMechanicsModel(); + + auto && material_selector = + std::make_shared>("physical_names", + solid); + solid.setMaterialSelector(material_selector); + + solid.initFull(_analysis_method = _explicit_lumped_mass); + contact.initFull(_analysis_method = _explicit_dynamic_contact); + + auto && surface_selector = std::make_shared(mesh); + contact.getContactDetector().setSurfaceSelector(surface_selector); + + solid.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "bottom"); + solid.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "bottom"); + + Vector weight = {0, -max_weight}; + solid.applyBC(BC::Neumann::FromSameDim(weight), "top"); + + coupler.initFull(_analysis_method = _explicit_dynamic_contact); + + Real time_step = solid.getStableTimeStep(); + time_step *= 0.1; + + coupler.setTimeStep(time_step); + + coupler.setBaseName("flat-on-flat"); + coupler.addDumpFieldVector("displacement"); + coupler.addDumpFieldVector("normals"); + coupler.addDumpFieldVector("contact_force"); + coupler.addDumpFieldVector("external_force"); + coupler.addDumpFieldVector("internal_force"); + coupler.addDumpField("gaps"); + coupler.addDumpField("areas"); + coupler.addDumpField("blocked_dofs"); + coupler.addDumpField("strain"); + coupler.addDumpField("stress"); + + auto & velocity = solid.getVelocity(); + + for (UInt s : arange(max_steps)) { + + coupler.solveStep(); + + if (s % damping_interval == 0) { + for (auto & v : make_view(velocity)) + v *= damping_ratio; + } + + if (s % 100 == 0) { + coupler.dump(); + } + } + + const ElementType element_type = _quad_4; + const Array & stress_vect = model.getMaterial("top_body").getStress(element_type); + + auto stress_it = stress_vect.begin(spatial_dimension, spatial_dimension); + auto stress_end = stress_vect.end(spatial_dimension, spatial_dimension); + + Real stress_tolerance = 1e-13; + + Matrix presc_stress; + + for (; stress_it != stress_end; ++stress_it) { + const auto & stress = *stress_it; + Matrix diff(spatial_dimension, spatial_dimension); + + diff = stress; + diff -= presc_stress; + Real stress_error = diff.norm() / stress.norm(); + + if (stress_error > stress_tolerance) { + std::cerr << "stress error: " << stress_error << " > " << stress_tolerance + << std::endl; + std::cerr << "stress: " << stress << std::endl + << "prescribed stress: " << presc_stress << std::endl; + return EXIT_FAILURE; + } + } + + finalize(); + return EXIT_SUCCESS; +} diff --git a/test/test_model/test_contact_mechanics_model/test_selector/CMakeLists.txt b/test/test_model/test_contact_mechanics_model/test_selector/CMakeLists.txt new file mode 100644 index 000000000..530b5d7cf --- /dev/null +++ b/test/test_model/test_contact_mechanics_model/test_selector/CMakeLists.txt @@ -0,0 +1,47 @@ +#=============================================================================== +# @file CMakeLists.txt +# +# @author Mohit Pundir +# +# @date creation: Sat Feb 29 2020 +# @date last modification: Sat feb 29 2020 +# +# @brief configuration for node selection tests +# +# @section LICENSE +# +# Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) +# +# Akantu 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. +# +# Akantu 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 Akantu. If not, see . +# +# @section DESCRIPTION +# +#=============================================================================== + +set(_meshes) + +add_mesh(selection_seg data/selection_1D.geo + DIM 2 ORDER 1 + OUTPUT _selection_segment_2.msh) +list(APPEND _meshes selection_2D) + +add_mesh(selection_tri data/selection_2D.geo + DIM 2 ORDER 1 + OUTPUT _selection_triangle_3.msh) +list(APPEND _meshes selection_2D) + +add_mesh(detection_tet data/selection_3D.geo + DIM 3 ORDER 1 + OUTPUT _selection_tetrahedron_4.msh) +list(APPEND _meshes selection_3D) + +register_gtest_sources( + SOURCES test_selection.cc + PACKAGE contact_mechanics + DEPENDS ${_meshes} + FILES_TO_COPY material.dat + ) diff --git a/test/test_model/test_contact_mechanics_model/test_selector/data/selection_1D.geo b/test/test_model/test_contact_mechanics_model/test_selector/data/selection_1D.geo new file mode 100644 index 000000000..ce535838e --- /dev/null +++ b/test/test_model/test_contact_mechanics_model/test_selector/data/selection_1D.geo @@ -0,0 +1,18 @@ +h = 0.5; + +Point(1) = { 1., 0., 0., h}; +Point(3) = { 0., 0., 0., h}; +Point(4) = { 0., 0., 0., h}; +Point(2) = {-1., 0., 0., h}; + +Line(1) = {2, 3}; +Line(2) = {4, 1}; + +Physical Point ("loading") = {1}; +Physical Point ("fixed") = {2}; + +Physical Point ("master") = {3}; +Physical Point ("slave") = {4}; + +Physical Line ("master_body") = {1}; +Physical Line ("slave_body") = {2}; \ No newline at end of file diff --git a/test/test_model/test_contact_mechanics_model/test_selector/data/selection_2D.geo b/test/test_model/test_contact_mechanics_model/test_selector/data/selection_2D.geo new file mode 100644 index 000000000..29491a861 --- /dev/null +++ b/test/test_model/test_contact_mechanics_model/test_selector/data/selection_2D.geo @@ -0,0 +1,39 @@ +h = 0.4; + +y = 1; +x = 2; + +Point(1) = { x/2., y/2, 0, h}; +Point(2) = {-x/2., y/2, 0, h}; +Point(3) = {-x/2.,-y/2, 0, h}; +Point(4) = { x/2.,-y/2, 0, h}; +Point(5) = {-x/2., 0, 0, h}; +Point(6) = { x/2., 0, 0, h}; +Point(7) = {-x/2., 0, 0, h}; +Point(8) = { x/2., 0, 0, h}; + +Line(1) = {1, 2}; +Line(2) = {2, 5}; +Line(3) = {5, 6}; +Line(4) = {6, 1}; + +Line(5) = {7, 3}; +Line(6) = {3, 4}; +Line(7) = {4, 8}; +Line(8) = {8, 7}; + +Line Loop(1) = {1, 2, 3, 4}; +Line Loop(2) = {5, 6, 7, 8}; + +Plane Surface(1) = {1}; +Plane Surface(2) = {2}; + +Physical Line("fixed") = {6}; +Physical Line("loading") = {1}; +Physical Line("master") = {3}; +Physical Line("slave") = {8}; + +Physical Line("sides") = {2, 5, 7, 4}; + +Physical Surface("master_body") = {1}; +Physical Surface("slave_body") = {2}; diff --git a/test/test_model/test_contact_mechanics_model/test_selector/data/selection_3D.geo b/test/test_model/test_contact_mechanics_model/test_selector/data/selection_3D.geo new file mode 100644 index 000000000..3242a10d2 --- /dev/null +++ b/test/test_model/test_contact_mechanics_model/test_selector/data/selection_3D.geo @@ -0,0 +1,37 @@ +h = 0.7; + +z = 1; +y = 2; +x = 2; + +Point(1) = { x/2, y/2, -z/2, h}; +Point(2) = {-x/2, y/2, -z/2, h}; +Point(3) = {-x/2,-y/2, -z/2, h}; +Point(4) = { x/2,-y/2, -z/2, h}; + +Point(5) = {-x/2, 0, -z/2, h}; +Point(6) = { x/2, 0, -z/2, h}; + +Line(1) = {1, 2}; +Line(2) = {2, 5}; +Line(3) = {5, 6}; +Line(4) = {6, 1}; + +Line(5) = {5, 3}; +Line(6) = {3, 4}; +Line(7) = {4, 6}; + +Line Loop(1) = {1, 2, 3, 4}; +Line Loop(2) = {-3, 5, 6, 7}; +Plane Surface(1) = {1}; +Plane Surface(2) = {2}; +Extrude {0, 0, z} { + Surface{1}; Surface{2}; +} + +Physical Surface("fixed") = {46}; +Physical Surface("insertion") = {24}; +Physical Surface("loading") = {16}; +Physical Surface("sides") = {1, 20, 29, 28, 50, 2, 51, 42}; + +Physical Volume("body") = {1, 2}; diff --git a/test/test_model/test_contact_mechanics_model/test_selector/material.dat b/test/test_model/test_contact_mechanics_model/test_selector/material.dat new file mode 100644 index 000000000..2c44b1584 --- /dev/null +++ b/test/test_model/test_contact_mechanics_model/test_selector/material.dat @@ -0,0 +1,5 @@ +contact_detector [ + type = implicit + master = master + slave = master +] diff --git a/test/test_model/test_contact_mechanics_model/test_selector/test_selection.cc b/test/test_model/test_contact_mechanics_model/test_selector/test_selection.cc new file mode 100644 index 000000000..c8cd6cf87 --- /dev/null +++ b/test/test_model/test_contact_mechanics_model/test_selector/test_selection.cc @@ -0,0 +1,46 @@ +/** + * @file test_selection.cc + * + * @author Mohit Pundir + * + * @date creation: Sun Mar 01 2020 + * @date last modification: Sun Mar 01 2020 + * + * @brief Generic test for surface selection + * + * @section LICENSE + * + * Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) + * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) + * + * Akantu 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. + * + * Akantu 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 Akantu. If not, see . + * + */ + +/* -------------------------------------------------------------------------- */ +#include "test_selection_fixture.hh" +/* -------------------------------------------------------------------------- */ + +using namespace akantu; + +TYPED_TEST(TestSurfaceSelectionFixture, PhysicalSurface) { + + auto & actual_slave_nodes = this->mesh.getElementgroup("slave").getNodes(); + auto nb_slave_nodes = actual_slave_nodes.size(); + this->checkNbSlaveNodes(nb_slave_nodes); + + auto & actual_master_nodes = this->mesh.getElementgroup("master").getNodes(); + auto nb_master_nodes = actual_master_nodes.size(); + this->checkNbMasterNodes(nb_master_nodes); +} diff --git a/test/test_model/test_contact_mechanics_model/test_selector/test_selection_fixture.hh b/test/test_model/test_contact_mechanics_model/test_selector/test_selection_fixture.hh new file mode 100644 index 000000000..55c8afeab --- /dev/null +++ b/test/test_model/test_contact_mechanics_model/test_selector/test_selection_fixture.hh @@ -0,0 +1,85 @@ +/** + * @file test_selection.cc + * + * @author Mohit Pundir + * + * @date creation: Sat Feb 29 2020 + * @date last modification: Sat Feb 29 2020 + * + * @brief Generic test for selection of nodes across different surfaces + * + * @section LICENSE + * + * Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) + * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) + * + * Akantu 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. + * + * Akantu 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 Akantu. If not, see . + * + */ + +/* -------------------------------------------------------------------------- */ +#include "aka_iterators.hh" +#include "communicator.hh" +#include "surface_selector.hh" +/* -------------------------------------------------------------------------- */ +#include "test_gtest_utils.hh" +/* -------------------------------------------------------------------------- */ +#include +#include +/* -------------------------------------------------------------------------- */ + + +using namespace akantu; + +template +class TestSurfaceSelecionFixture : public ::testing::Test { +public: + static constexpr size_t spatial_dimension = dim_::value; + + void Setup() override { + mesh = std::make_unique(spatial_dimension); + mesh->read("selection_" + std::string(spatial_dimension) + "D.msh"); + selector = make_unique(*mesh); + } + + void TearDown() { + mesh.reset(nullptr); + selector.reset(nullptr); + } + + + bool checkNbSlaveNodes(UInt & act_slave_nodes) { + auto & slave_list = this->selectior->getSlaveList(); + auto nb_slave_nodes = slave_list.size(); + EXCEP_EQ(nb_slave_nodes, act_slave_nodes) + } + + + bool checkNbmasterNodes(UInt & act_master_nodes) { + auto & master_list = this->selectior->getMasterList(); + auto nb_master_nodes = master_list.size(); + EXCEP_EQ(nb_master_nodes, act_master_nodes) + } + + + protected: + std::unique_ptr mesh; + std::unique_ptr selector +}; + + +using dim_types = gtest_list_t>; + + +TYPED_TEST_SUITE(TestSurfaceSelectionFixture, dim_types);